Integrate Waku service (#1759)
This commit is contained in:
parent
86dcbcd90e
commit
37a508a97b
|
@ -271,6 +271,7 @@ func makeNodeConfig() (*params.NodeConfig, error) {
|
||||||
nodeConfig.LogFile = *logFile
|
nodeConfig.LogFile = *logFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeConfig.EnableNTPSync = true
|
||||||
nodeConfig.NoDiscovery = true
|
nodeConfig.NoDiscovery = true
|
||||||
nodeConfig.ListenAddr = ""
|
nodeConfig.ListenAddr = ""
|
||||||
if *staticEnodeAddr != "" {
|
if *staticEnodeAddr != "" {
|
||||||
|
@ -291,7 +292,6 @@ func whisperConfig(nodeConfig *params.NodeConfig) (*params.NodeConfig, error) {
|
||||||
whisperConfig.LightClient = true
|
whisperConfig.LightClient = true
|
||||||
whisperConfig.MinimumPoW = *minPow
|
whisperConfig.MinimumPoW = *minPow
|
||||||
whisperConfig.TTL = *ttl
|
whisperConfig.TTL = *ttl
|
||||||
whisperConfig.EnableNTPSync = true
|
|
||||||
|
|
||||||
return nodeConfig, nil
|
return nodeConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,29 +2,102 @@ package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/waku"
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/whisper/v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gethEnvelopeWrapper struct {
|
type whisperEnvelope struct {
|
||||||
envelope *whisper.Envelope
|
env *whisper.Envelope
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethEnvelopeWrapper returns an object that wraps Geth's Envelope in a types interface
|
// NewWhisperEnvelope returns an object that wraps Geth's Whisper Envelope in a types interface.
|
||||||
func NewGethEnvelopeWrapper(e *whisper.Envelope) types.Envelope {
|
func NewWhisperEnvelope(e *whisper.Envelope) types.Envelope {
|
||||||
return &gethEnvelopeWrapper{
|
return &whisperEnvelope{env: e}
|
||||||
envelope: e,
|
}
|
||||||
|
|
||||||
|
func UnwrapWhisperEnvelope(e types.Envelope) (*whisper.Envelope, bool) {
|
||||||
|
if env, ok := e.(*whisperEnvelope); ok {
|
||||||
|
return env.env, true
|
||||||
}
|
}
|
||||||
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGethEnvelopeFrom retrieves the underlying whisper Envelope struct from a wrapped Envelope interface
|
func MustUnwrapWhisperEnvelope(e types.Envelope) *whisper.Envelope {
|
||||||
func GetGethEnvelopeFrom(f types.Envelope) *whisper.Envelope {
|
return e.(*whisperEnvelope).env
|
||||||
return f.(*gethEnvelopeWrapper).envelope
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Hash() types.Hash {
|
func (w *whisperEnvelope) Hash() types.Hash {
|
||||||
return types.Hash(w.envelope.Hash())
|
return types.Hash(w.env.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Bloom() []byte {
|
func (w *whisperEnvelope) Bloom() []byte {
|
||||||
return w.envelope.Bloom()
|
return w.env.Bloom()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) PoW() float64 {
|
||||||
|
return w.env.PoW()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Expiry() uint32 {
|
||||||
|
return w.env.Expiry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) TTL() uint32 {
|
||||||
|
return w.env.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Topic() types.TopicType {
|
||||||
|
return types.TopicType(w.env.Topic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Size() int {
|
||||||
|
return len(w.env.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
type wakuEnvelope struct {
|
||||||
|
env *waku.Envelope
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWakuEnvelope returns an object that wraps Geth's Waku Envelope in a types interface.
|
||||||
|
func NewWakuEnvelope(e *waku.Envelope) types.Envelope {
|
||||||
|
return &wakuEnvelope{env: e}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnwrapWakuEnvelope(e types.Envelope) (*waku.Envelope, bool) {
|
||||||
|
if env, ok := e.(*wakuEnvelope); ok {
|
||||||
|
return env.env, true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustUnwrapWakuEnvelope(e types.Envelope) *waku.Envelope {
|
||||||
|
return e.(*wakuEnvelope).env
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Hash() types.Hash {
|
||||||
|
return types.Hash(w.env.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Bloom() []byte {
|
||||||
|
return w.env.Bloom()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) PoW() float64 {
|
||||||
|
return w.env.PoW()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Expiry() uint32 {
|
||||||
|
return w.env.Expiry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) TTL() uint32 {
|
||||||
|
return w.env.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Topic() types.TopicType {
|
||||||
|
return types.TopicType(w.env.Topic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Size() int {
|
||||||
|
return len(w.env.Data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r types.Messages
|
||||||
// which are not supposed to be forwarded any further.
|
// which are not supposed to be forwarded any further.
|
||||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||||
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||||
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, GetGethEnvelopeFrom(envelope), timeout)
|
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, MustUnwrapWhisperEnvelope(envelope), timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||||
|
|
|
@ -8,13 +8,16 @@ replace github.com/status-im/status-go/extkeys => ../extkeys
|
||||||
|
|
||||||
replace github.com/status-im/status-go/whisper/v6 => ../whisper
|
replace github.com/status-im/status-go/whisper/v6 => ../whisper
|
||||||
|
|
||||||
|
replace github.com/status-im/status-go/waku => ../waku
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ethereum/go-ethereum v1.9.5
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f
|
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f
|
||||||
github.com/status-im/doubleratchet v3.0.0+incompatible
|
github.com/status-im/doubleratchet v3.0.0+incompatible
|
||||||
|
github.com/status-im/status-go/waku v1.0.0
|
||||||
github.com/status-im/status-go/whisper/v6 v6.0.1 // indirect
|
github.com/status-im/status-go/whisper/v6 v6.0.1 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/wealdtech/go-ens/v3 v3.0.9
|
github.com/wealdtech/go-ens/v3 v3.0.9
|
||||||
go.uber.org/zap v1.13.0
|
go.uber.org/zap v1.13.0
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
||||||
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
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-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
@ -16,11 +20,15 @@ github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc
|
||||||
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
|
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
|
||||||
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
||||||
|
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||||
|
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7 h1:6TQIK3K21/HnYLp+TAI6fjQ1YeH+KgLZbrFJwUjVrnQ=
|
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7 h1:6TQIK3K21/HnYLp+TAI6fjQ1YeH+KgLZbrFJwUjVrnQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
|
||||||
|
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
@ -44,6 +52,7 @@ github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
|
||||||
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -56,12 +65,16 @@ github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
|
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
|
||||||
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
|
@ -69,6 +82,7 @@ github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a h1:1znxn4+q2MrEdTk1eCk
|
||||||
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||||
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||||
|
@ -83,6 +97,8 @@ github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||||
|
@ -93,6 +109,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
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.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
@ -101,6 +118,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4=
|
github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
@ -113,9 +131,12 @@ github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7
|
||||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
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.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
@ -127,6 +148,8 @@ github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8u
|
||||||
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||||
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.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
|
@ -135,6 +158,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
||||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||||
|
@ -177,6 +201,8 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||||
|
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||||
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
|
github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
|
||||||
|
@ -184,27 +210,33 @@ github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7ir
|
||||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e h1:+RHxT/gm0O3UF7nLJbdNzAmULvCFt4XfXHWzh3XI/zs=
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e h1:+RHxT/gm0O3UF7nLJbdNzAmULvCFt4XfXHWzh3XI/zs=
|
||||||
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/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.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
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-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.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
|
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
|
||||||
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
|
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||||
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
|
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
|
||||||
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
||||||
|
@ -213,7 +245,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
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.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
@ -247,6 +281,9 @@ github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2 h1:GnOzE5fEFN3b2z
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||||
|
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||||
|
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||||
|
@ -261,6 +298,10 @@ github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOF
|
||||||
github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4=
|
github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4=
|
||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
||||||
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
|
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||||
|
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
||||||
|
@ -274,12 +315,15 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M=
|
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M=
|
||||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
|
@ -293,12 +337,15 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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 h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -306,22 +353,32 @@ golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190912185636-87d9f09c5d89/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -330,11 +387,17 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||||
|
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||||
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
|
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
@ -344,5 +407,6 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
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 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
|
|
@ -5,6 +5,11 @@ package types
|
||||||
type Envelope interface {
|
type Envelope interface {
|
||||||
Hash() Hash // Cached hash of the envelope to avoid rehashing every time.
|
Hash() Hash // Cached hash of the envelope to avoid rehashing every time.
|
||||||
Bloom() []byte
|
Bloom() []byte
|
||||||
|
PoW() float64
|
||||||
|
Expiry() uint32
|
||||||
|
TTL() uint32
|
||||||
|
Topic() TopicType
|
||||||
|
Size() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventType used to define known envelope events.
|
// EventType used to define known envelope events.
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (h Hash) Bytes() []byte { return h[:] }
|
||||||
|
|
||||||
// String implements the stringer interface and is used also by the logger when
|
// String implements the stringer interface and is used also by the logger when
|
||||||
// doing full logging into a file.
|
// doing full logging into a file.
|
||||||
func (h *Hash) String() string {
|
func (h Hash) String() string {
|
||||||
return h.Hex()
|
return h.Hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -18,6 +18,8 @@ replace github.com/status-im/status-go/eth-node => ./eth-node
|
||||||
|
|
||||||
replace github.com/status-im/status-go/whisper/v6 => ./whisper
|
replace github.com/status-im/status-go/whisper/v6 => ./whisper
|
||||||
|
|
||||||
|
replace github.com/status-im/status-go/waku => ./waku
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beevik/ntp v0.2.0
|
github.com/beevik/ntp v0.2.0
|
||||||
github.com/ethereum/go-ethereum v1.9.5
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
|
@ -41,14 +43,14 @@ require (
|
||||||
github.com/status-im/status-go/eth-node v1.0.0
|
github.com/status-im/status-go/eth-node v1.0.0
|
||||||
github.com/status-im/status-go/extkeys v1.0.0
|
github.com/status-im/status-go/extkeys v1.0.0
|
||||||
github.com/status-im/status-go/protocol v1.0.1
|
github.com/status-im/status-go/protocol v1.0.1
|
||||||
|
github.com/status-im/status-go/waku v1.0.0
|
||||||
github.com/status-im/status-go/whisper/v6 v6.0.1
|
github.com/status-im/status-go/whisper/v6 v6.0.1
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
|
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
go.uber.org/zap v1.13.0
|
go.uber.org/zap v1.13.0
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 // indirect
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 // indirect
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
|
|
||||||
golang.org/x/tools v0.0.0-20191213032237-7093a17b0467 // indirect
|
golang.org/x/tools v0.0.0-20191213032237-7093a17b0467 // indirect
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1
|
gopkg.in/go-playground/validator.v9 v9.29.1
|
||||||
|
|
59
go.sum
59
go.sum
|
@ -12,6 +12,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||||
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
|
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
|
||||||
|
@ -19,23 +20,31 @@ github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
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-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/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-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
|
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
|
||||||
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
||||||
|
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||||
|
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 h1:ZdRuixFqR3mfx4FHzclG3COrRgWrYq0VhNgIoYoObcM=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
|
||||||
|
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||||
|
@ -130,6 +139,8 @@ github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa h1:o8OuEkracbk3qH6
|
||||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
|
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
|
||||||
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=
|
||||||
|
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||||
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
|
@ -141,6 +152,7 @@ github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||||
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||||
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||||
|
@ -169,6 +181,7 @@ github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
|
||||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k=
|
github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k=
|
||||||
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
|
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -216,6 +229,7 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
|
@ -231,6 +245,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms=
|
github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms=
|
||||||
|
@ -253,6 +268,8 @@ github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQ
|
||||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
||||||
github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
|
github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
|
||||||
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
||||||
|
@ -261,6 +278,7 @@ github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod
|
||||||
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
||||||
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
|
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
|
||||||
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
||||||
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
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/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
||||||
|
@ -282,6 +300,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||||
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.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
@ -295,6 +315,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
@ -496,9 +517,15 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||||
github.com/onsi/ginkgo v1.7.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.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||||
|
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||||
|
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||||
|
@ -515,17 +542,20 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/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 v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
||||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
@ -536,12 +566,14 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
|
@ -558,6 +590,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||||
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
||||||
|
@ -622,7 +656,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||||
|
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
|
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||||
|
@ -656,6 +693,8 @@ github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVT
|
||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||||
|
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
@ -683,6 +722,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -692,6 +732,8 @@ golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
@ -719,6 +761,7 @@ golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -745,11 +788,14 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
||||||
|
@ -772,7 +818,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190912185636-87d9f09c5d89/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-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-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
||||||
|
@ -797,7 +845,11 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
@ -810,6 +862,11 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||||
|
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||||
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
|
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
|
@ -818,6 +875,7 @@ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5 h1:VWXVtmkY4Y
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
||||||
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
||||||
|
@ -833,5 +891,6 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
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-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-20190106161140-3f1c8253044a/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 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestCleaner(t *testing.T) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
server := setupTestServer(t)
|
server := setupTestServer(t)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
cleaner := newDBCleaner(server.db, time.Hour)
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
||||||
|
|
||||||
archiveEnvelope(t, now.Add(-10*time.Second), server)
|
archiveEnvelope(t, now.Add(-10*time.Second), server)
|
||||||
archiveEnvelope(t, now.Add(-3*time.Second), server)
|
archiveEnvelope(t, now.Add(-3*time.Second), server)
|
||||||
|
@ -27,9 +27,9 @@ func TestCleaner(t *testing.T) {
|
||||||
|
|
||||||
testMessagesCount(t, 3, server)
|
testMessagesCount(t, 3, server)
|
||||||
|
|
||||||
testPrune(t, now.Add(-5*time.Second), 1, cleaner, server)
|
testPrune(t, now.Add(-5*time.Second), 1, cleaner)
|
||||||
testPrune(t, now.Add(-2*time.Second), 1, cleaner, server)
|
testPrune(t, now.Add(-2*time.Second), 1, cleaner)
|
||||||
testPrune(t, now, 1, cleaner, server)
|
testPrune(t, now, 1, cleaner)
|
||||||
|
|
||||||
testMessagesCount(t, 0, server)
|
testMessagesCount(t, 0, server)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func TestCleanerSchedule(t *testing.T) {
|
||||||
server := setupTestServer(t)
|
server := setupTestServer(t)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
cleaner := newDBCleaner(server.db, time.Hour)
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
||||||
cleaner.period = time.Millisecond * 10
|
cleaner.period = time.Millisecond * 10
|
||||||
cleaner.Start()
|
cleaner.Start()
|
||||||
defer cleaner.Stop()
|
defer cleaner.Stop()
|
||||||
|
@ -60,7 +60,7 @@ func benchmarkCleanerPrune(b *testing.B, messages int, batchSize int) {
|
||||||
server := setupTestServer(t)
|
server := setupTestServer(t)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
cleaner := newDBCleaner(server.db, time.Hour)
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
||||||
cleaner.batchSize = batchSize
|
cleaner.batchSize = batchSize
|
||||||
|
|
||||||
for i := 0; i < messages; i++ {
|
for i := 0; i < messages; i++ {
|
||||||
|
@ -68,7 +68,7 @@ func benchmarkCleanerPrune(b *testing.B, messages int, batchSize int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
testPrune(t, now, 0, cleaner, server)
|
testPrune(t, now, 0, cleaner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,16 +88,19 @@ func BenchmarkCleanerPruneM100_000_B100(b *testing.B) {
|
||||||
benchmarkCleanerPrune(b, 100000, 100)
|
benchmarkCleanerPrune(b, 100000, 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTestServer(t *testing.T) *WMailServer {
|
func setupTestServer(t *testing.T) *WhisperMailServer {
|
||||||
var s WMailServer
|
var s WhisperMailServer
|
||||||
db, _ := leveldb.Open(storage.NewMemStorage(), nil)
|
db, _ := leveldb.Open(storage.NewMemStorage(), nil)
|
||||||
|
|
||||||
s.db = &LevelDB{ldb: db}
|
s.ms = &mailServer{
|
||||||
s.pow = powRequirement
|
db: &LevelDB{ldb: db},
|
||||||
|
adapter: &whisperAdapter{},
|
||||||
|
}
|
||||||
|
s.minRequestPoW = powRequirement
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
func archiveEnvelope(t *testing.T, sentTime time.Time, server *WMailServer) *whisper.Envelope {
|
func archiveEnvelope(t *testing.T, sentTime time.Time, server *WhisperMailServer) *whisper.Envelope {
|
||||||
env, err := generateEnvelope(sentTime)
|
env, err := generateEnvelope(sentTime)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
server.Archive(env)
|
server.Archive(env)
|
||||||
|
@ -105,14 +108,14 @@ func archiveEnvelope(t *testing.T, sentTime time.Time, server *WMailServer) *whi
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPrune(t *testing.T, u time.Time, expected int, c *dbCleaner, s *WMailServer) {
|
func testPrune(t *testing.T, u time.Time, expected int, c *dbCleaner) {
|
||||||
n, err := c.PruneEntriesOlderThan(u)
|
n, err := c.PruneEntriesOlderThan(u)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, expected, n)
|
require.Equal(t, expected, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMessagesCount(t *testing.T, expected int, s *WMailServer) {
|
func testMessagesCount(t *testing.T, expected int, s *WhisperMailServer) {
|
||||||
count := countMessages(t, s.db)
|
count := countMessages(t, s.ms.db)
|
||||||
require.Equal(t, expected, count, fmt.Sprintf("expected %d message, got: %d", expected, count))
|
require.Equal(t, expected, count, fmt.Sprintf("expected %d message, got: %d", expected, count))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,15 +3,15 @@ package mailserver
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DB is an interface to abstract interactions with the db so that the mailserver
|
// DB is an interface to abstract interactions with the db so that the mailserver
|
||||||
// is agnostic to the underlaying technology used
|
// is agnostic to the underlying technology used
|
||||||
type DB interface {
|
type DB interface {
|
||||||
Close() error
|
Close() error
|
||||||
// SaveEnvelope stores an envelope
|
// SaveEnvelope stores an envelope
|
||||||
SaveEnvelope(*whisper.Envelope) error // TODO: Migrate to types.Envelope
|
SaveEnvelope(types.Envelope) error
|
||||||
// GetEnvelope returns an rlp encoded envelope from the datastore
|
// GetEnvelope returns an rlp encoded envelope from the datastore
|
||||||
GetEnvelope(*DBKey) ([]byte, error)
|
GetEnvelope(*DBKey) ([]byte, error)
|
||||||
// Prune removes envelopes older than time
|
// Prune removes envelopes older than time
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
||||||
|
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/params"
|
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/whisper/v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,12 +58,12 @@ func (i *LevelDBIterator) GetEnvelope(bloom []byte) ([]byte, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLevelDB(config *params.WhisperConfig) (*LevelDB, error) {
|
func NewLevelDB(dataDir string) (*LevelDB, error) {
|
||||||
// Open opens an existing leveldb database
|
// Open opens an existing leveldb database
|
||||||
db, err := leveldb.OpenFile(config.DataDir, nil)
|
db, err := leveldb.OpenFile(dataDir, nil)
|
||||||
if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted {
|
if _, corrupted := err.(*errors.ErrCorrupted); corrupted {
|
||||||
log.Info("database is corrupted trying to recover", "path", config.DataDir)
|
log.Info("database is corrupted trying to recover", "path", dataDir)
|
||||||
db, err = leveldb.RecoverFile(config.DataDir, nil)
|
db, err = leveldb.RecoverFile(dataDir, nil)
|
||||||
}
|
}
|
||||||
return &LevelDB{ldb: db}, err
|
return &LevelDB{ldb: db}, err
|
||||||
}
|
}
|
||||||
|
@ -138,11 +138,22 @@ func (db *LevelDB) Prune(t time.Time, batchSize int) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveEnvelope stores an envelope in leveldb and increments the metrics
|
// SaveEnvelope stores an envelope in leveldb and increments the metrics
|
||||||
func (db *LevelDB) SaveEnvelope(env *whisper.Envelope) error {
|
func (db *LevelDB) SaveEnvelope(env types.Envelope) error {
|
||||||
defer recoverLevelDBPanics("SaveEnvelope")
|
defer recoverLevelDBPanics("SaveEnvelope")
|
||||||
|
|
||||||
key := NewDBKey(env.Expiry-env.TTL, types.TopicType(env.Topic), types.Hash(env.Hash()))
|
key := NewDBKey(env.Expiry()-env.TTL(), env.Topic(), env.Hash())
|
||||||
rawEnvelope, err := rlp.EncodeToBytes(env)
|
|
||||||
|
var (
|
||||||
|
rawEnvelope []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if whisperEnv, ok := gethbridge.UnwrapWhisperEnvelope(env); ok {
|
||||||
|
rawEnvelope, err = rlp.EncodeToBytes(whisperEnv)
|
||||||
|
} else if wakuEnv, ok := gethbridge.UnwrapWakuEnvelope(env); ok {
|
||||||
|
rawEnvelope, err = rlp.EncodeToBytes(wakuEnv)
|
||||||
|
} else {
|
||||||
|
return errors.New("unsupported underlying types.Envelope type")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
||||||
archivedErrorsCounter.Inc()
|
archivedErrorsCounter.Inc()
|
||||||
|
@ -154,7 +165,7 @@ func (db *LevelDB) SaveEnvelope(env *whisper.Envelope) error {
|
||||||
archivedErrorsCounter.Inc()
|
archivedErrorsCounter.Inc()
|
||||||
}
|
}
|
||||||
archivedEnvelopesCounter.Inc()
|
archivedEnvelopesCounter.Inc()
|
||||||
archivedEnvelopeSizeMeter.Observe(float64(whisper.EnvelopeHeaderLength + len(env.Data)))
|
archivedEnvelopeSizeMeter.Observe(float64(whisper.EnvelopeHeaderLength + env.Size()))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
bindata "github.com/status-im/migrate/v4/source/go_bindata"
|
bindata "github.com/status-im/migrate/v4/source/go_bindata"
|
||||||
|
|
||||||
"github.com/status-im/status-go/mailserver/migrations"
|
"github.com/status-im/status-go/mailserver/migrations"
|
||||||
"github.com/status-im/status-go/params"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
@ -21,8 +20,8 @@ import (
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/whisper/v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPostgresDB(config *params.WhisperConfig) (*PostgresDB, error) {
|
func NewPostgresDB(uri string) (*PostgresDB, error) {
|
||||||
db, err := sql.Open("postgres", config.DatabaseConfig.PGConfig.URI)
|
db, err := sql.Open("postgres", uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -179,9 +178,9 @@ func (i *PostgresDB) Prune(t time.Time, batch int) (int, error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *PostgresDB) SaveEnvelope(env *whisper.Envelope) error {
|
func (i *PostgresDB) SaveEnvelope(env types.Envelope) error {
|
||||||
topic := types.TopicType(env.Topic)
|
topic := env.Topic()
|
||||||
key := NewDBKey(env.Expiry-env.TTL, topic, types.Hash(env.Hash()))
|
key := NewDBKey(env.Expiry()-env.TTL(), topic, env.Hash())
|
||||||
rawEnvelope, err := rlp.EncodeToBytes(env)
|
rawEnvelope, err := rlp.EncodeToBytes(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
||||||
|
@ -210,7 +209,7 @@ func (i *PostgresDB) SaveEnvelope(env *whisper.Envelope) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
archivedEnvelopesCounter.Inc()
|
archivedEnvelopesCounter.Inc()
|
||||||
archivedEnvelopeSizeMeter.Observe(float64(whisper.EnvelopeHeaderLength + len(env.Data)))
|
archivedEnvelopeSizeMeter.Observe(float64(whisper.EnvelopeHeaderLength + env.Size()))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
@ -61,16 +59,16 @@ func TestMailserverSuite(t *testing.T) {
|
||||||
|
|
||||||
type MailserverSuite struct {
|
type MailserverSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
server *WMailServer
|
server *WhisperMailServer
|
||||||
shh *whisper.Whisper
|
shh *whisper.Whisper
|
||||||
config *params.WhisperConfig
|
config *params.WhisperConfig
|
||||||
dataDir string
|
dataDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) SetupTest() {
|
func (s *MailserverSuite) SetupTest() {
|
||||||
s.server = &WMailServer{}
|
s.server = &WhisperMailServer{}
|
||||||
s.shh = whisper.New(&whisper.DefaultConfig)
|
s.shh = whisper.New(&whisper.DefaultConfig)
|
||||||
s.shh.RegisterServer(s.server)
|
s.shh.RegisterMailServer(s.server)
|
||||||
|
|
||||||
tmpDir, err := ioutil.TempDir("", "mailserver-test")
|
tmpDir, err := ioutil.TempDir("", "mailserver-test")
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -152,9 +150,9 @@ func (s *MailserverSuite) TestInit() {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.T().Run(tc.info, func(*testing.T) {
|
s.T().Run(tc.info, func(*testing.T) {
|
||||||
mailServer := &WMailServer{}
|
mailServer := &WhisperMailServer{}
|
||||||
shh := whisper.New(&whisper.DefaultConfig)
|
shh := whisper.New(&whisper.DefaultConfig)
|
||||||
shh.RegisterServer(mailServer)
|
shh.RegisterMailServer(mailServer)
|
||||||
|
|
||||||
err := mailServer.Init(shh, &tc.config)
|
err := mailServer.Init(shh, &tc.config)
|
||||||
s.Equal(tc.expectedError, err)
|
s.Equal(tc.expectedError, err)
|
||||||
|
@ -162,13 +160,13 @@ func (s *MailserverSuite) TestInit() {
|
||||||
|
|
||||||
// db should be open only if there was no error
|
// db should be open only if there was no error
|
||||||
if tc.expectedError == nil {
|
if tc.expectedError == nil {
|
||||||
s.NotNil(mailServer.db)
|
s.NotNil(mailServer.ms.db)
|
||||||
} else {
|
} else {
|
||||||
s.Nil(mailServer.db)
|
s.Nil(mailServer.ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tc.config.MailServerRateLimit > 0 {
|
if tc.config.MailServerRateLimit > 0 {
|
||||||
s.NotNil(mailServer.rateLimiter)
|
s.NotNil(mailServer.ms.rateLimiter)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -228,7 +226,7 @@ func (s *MailserverSuite) TestOpenEnvelopeWithSymKey() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) TestOpenEnvelopeWithAsymKey() {
|
func (s *MailserverSuite) TestOpenEnvelopeWithAsymKey() {
|
||||||
// Setup the server with an asymetric key
|
// Setup the server with an asymmetric key
|
||||||
config := *s.config
|
config := *s.config
|
||||||
config.MailServerPassword = "" // clear password field
|
config.MailServerPassword = "" // clear password field
|
||||||
s.NoError(s.server.Init(s.shh, &config))
|
s.NoError(s.server.Init(s.shh, &config))
|
||||||
|
@ -239,7 +237,7 @@ func (s *MailserverSuite) TestOpenEnvelopeWithAsymKey() {
|
||||||
env, err := generateEnvelopeWithKeys(time.Now(), nil, &pubKey)
|
env, err := generateEnvelopeWithKeys(time.Now(), nil, &pubKey)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Test openEnvelope with a valid asymetric key
|
// Test openEnvelope with a valid asymmetric key
|
||||||
d := s.server.openEnvelope(env)
|
d := s.server.openEnvelope(env)
|
||||||
s.NotNil(d)
|
s.NotNil(d)
|
||||||
s.Equal(testPayload, d.Payload)
|
s.Equal(testPayload, d.Payload)
|
||||||
|
@ -261,22 +259,24 @@ func (s *MailserverSuite) TestArchive() {
|
||||||
|
|
||||||
s.server.Archive(env)
|
s.server.Archive(env)
|
||||||
key := NewDBKey(env.Expiry-env.TTL, types.TopicType(env.Topic), types.Hash(env.Hash()))
|
key := NewDBKey(env.Expiry-env.TTL, types.TopicType(env.Topic), types.Hash(env.Hash()))
|
||||||
archivedEnvelope, err := s.server.db.GetEnvelope(key)
|
archivedEnvelope, err := s.server.ms.db.GetEnvelope(key)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
s.Equal(rawEnvelope, archivedEnvelope)
|
s.Equal(rawEnvelope, archivedEnvelope)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) TestManageLimits() {
|
func (s *MailserverSuite) TestManageLimits() {
|
||||||
s.server.rateLimiter = newRateLimiter(time.Duration(5) * time.Millisecond)
|
err := s.server.Init(s.shh, s.config)
|
||||||
s.False(s.server.exceedsPeerRequests([]byte("peerID")))
|
s.NoError(err)
|
||||||
s.Equal(1, len(s.server.rateLimiter.db))
|
s.server.ms.rateLimiter = newRateLimiter(time.Duration(5) * time.Millisecond)
|
||||||
firstSaved := s.server.rateLimiter.db["peerID"]
|
s.False(s.server.ms.exceedsPeerRequests(types.BytesToHash([]byte("peerID"))))
|
||||||
|
s.Equal(1, len(s.server.ms.rateLimiter.db))
|
||||||
|
firstSaved := s.server.ms.rateLimiter.db["peerID"]
|
||||||
|
|
||||||
// second call when limit is not accomplished does not store a new limit
|
// second call when limit is not accomplished does not store a new limit
|
||||||
s.True(s.server.exceedsPeerRequests([]byte("peerID")))
|
s.True(s.server.ms.exceedsPeerRequests(types.BytesToHash([]byte("peerID"))))
|
||||||
s.Equal(1, len(s.server.rateLimiter.db))
|
s.Equal(1, len(s.server.ms.rateLimiter.db))
|
||||||
s.Equal(firstSaved, s.server.rateLimiter.db["peerID"])
|
s.Equal(firstSaved, s.server.ms.rateLimiter.db["peerID"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) TestDBKey() {
|
func (s *MailserverSuite) TestDBKey() {
|
||||||
|
@ -317,31 +317,28 @@ func (s *MailserverSuite) TestRequestPaginationLimit() {
|
||||||
reqLimit := uint32(6)
|
reqLimit := uint32(6)
|
||||||
peerID, request, err := s.prepareRequest(sentEnvelopes, reqLimit)
|
peerID, request, err := s.prepareRequest(sentEnvelopes, reqLimit)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
lower, upper, bloom, limit, cursor, err := s.server.validateRequest(peerID, request)
|
payload, err := s.server.decompositeRequest(peerID, request)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
s.Nil(cursor)
|
s.Nil(payload.Cursor)
|
||||||
s.Equal(reqLimit, limit)
|
s.Equal(reqLimit, payload.Limit)
|
||||||
|
|
||||||
receivedHashes, cursor, _ = processRequestAndCollectHashes(
|
receivedHashes, cursor, _ := processRequestAndCollectHashes(s.server, payload)
|
||||||
s.server, lower, upper, cursor, bloom, int(limit),
|
|
||||||
)
|
|
||||||
|
|
||||||
// 10 envelopes sent
|
// 10 envelopes sent
|
||||||
s.Equal(count, uint32(len(sentEnvelopes)))
|
s.Equal(count, uint32(len(sentEnvelopes)))
|
||||||
// 6 envelopes received
|
// 6 envelopes received
|
||||||
s.Len(receivedHashes, int(limit))
|
s.Len(receivedHashes, int(payload.Limit))
|
||||||
// the 6 envelopes received should be in forward order
|
// the 6 envelopes received should be in forward order
|
||||||
s.Equal(sentHashes[:limit], receivedHashes)
|
s.Equal(sentHashes[:payload.Limit], receivedHashes)
|
||||||
// cursor should be the key of the last envelope of the last page
|
// cursor should be the key of the last envelope of the last page
|
||||||
s.Equal(archiveKeys[limit-1], fmt.Sprintf("%x", cursor))
|
s.Equal(archiveKeys[payload.Limit-1], fmt.Sprintf("%x", cursor))
|
||||||
|
|
||||||
// second page
|
// second page
|
||||||
receivedHashes, cursor, _ = processRequestAndCollectHashes(
|
payload.Cursor = cursor
|
||||||
s.server, lower, upper, cursor, bloom, int(limit),
|
receivedHashes, cursor, _ = processRequestAndCollectHashes(s.server, payload)
|
||||||
)
|
|
||||||
|
|
||||||
// 4 envelopes received
|
// 4 envelopes received
|
||||||
s.Equal(int(count-limit), len(receivedHashes))
|
s.Equal(int(count-payload.Limit), len(receivedHashes))
|
||||||
// cursor is nil because there are no other pages
|
// cursor is nil because there are no other pages
|
||||||
s.Nil(cursor)
|
s.Nil(cursor)
|
||||||
}
|
}
|
||||||
|
@ -418,17 +415,17 @@ func (s *MailserverSuite) TestMailServer() {
|
||||||
s.T().Run(tc.info, func(*testing.T) {
|
s.T().Run(tc.info, func(*testing.T) {
|
||||||
request := s.createRequest(tc.params)
|
request := s.createRequest(tc.params)
|
||||||
src := crypto.FromECDSAPub(&tc.params.key.PublicKey)
|
src := crypto.FromECDSAPub(&tc.params.key.PublicKey)
|
||||||
lower, upper, bloom, limit, _, err := s.server.validateRequest(src, request)
|
payload, err := s.server.decompositeRequest(src, request)
|
||||||
s.Equal(tc.isOK, err == nil)
|
s.Equal(tc.isOK, err == nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
s.Equal(tc.params.low, lower)
|
s.Equal(tc.params.low, payload.Lower)
|
||||||
s.Equal(tc.params.upp, upper)
|
s.Equal(tc.params.upp, payload.Upper)
|
||||||
s.Equal(tc.params.limit, limit)
|
s.Equal(tc.params.limit, payload.Limit)
|
||||||
s.Equal(types.TopicToBloom(tc.params.topic), bloom)
|
s.Equal(types.TopicToBloom(tc.params.topic), payload.Bloom)
|
||||||
s.Equal(tc.expect, s.messageExists(env, tc.params.low, tc.params.upp, bloom, tc.params.limit))
|
s.Equal(tc.expect, s.messageExists(env, tc.params.low, tc.params.upp, payload.Bloom, tc.params.limit))
|
||||||
|
|
||||||
src[0]++
|
src[0]++
|
||||||
_, _, _, _, _, err = s.server.validateRequest(src, request)
|
_, err = s.server.decompositeRequest(src, request)
|
||||||
s.True(err == nil)
|
s.True(err == nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -509,7 +506,7 @@ func (s *MailserverSuite) TestProcessRequestDeadlockHandling() {
|
||||||
// Prepare a request.
|
// Prepare a request.
|
||||||
peerID, request, err := s.prepareRequest(archievedEnvelopes, 5)
|
peerID, request, err := s.prepareRequest(archievedEnvelopes, 5)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
lower, upper, bloom, limit, cursor, err := s.server.validateRequest(peerID, request)
|
payload, err := s.server.decompositeRequest(peerID, request)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -533,7 +530,7 @@ func (s *MailserverSuite) TestProcessRequestDeadlockHandling() {
|
||||||
processFinished := make(chan struct{})
|
processFinished := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
s.server.processRequestInBundles(iter, bloom, int(limit), timeout, "req-01", bundles, done)
|
s.server.ms.processRequestInBundles(iter, payload.Bloom, int(payload.Limit), timeout, "req-01", bundles, done)
|
||||||
close(processFinished)
|
close(processFinished)
|
||||||
}()
|
}()
|
||||||
go close(done)
|
go close(done)
|
||||||
|
@ -557,7 +554,7 @@ func (s *MailserverSuite) TestProcessRequestDeadlockHandling() {
|
||||||
processFinished := make(chan struct{})
|
processFinished := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
s.server.processRequestInBundles(iter, bloom, int(limit), time.Second, "req-01", bundles, done)
|
s.server.ms.processRequestInBundles(iter, payload.Bloom, int(payload.Limit), time.Second, "req-01", bundles, done)
|
||||||
close(processFinished)
|
close(processFinished)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -572,7 +569,7 @@ func (s *MailserverSuite) TestProcessRequestDeadlockHandling() {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.T().Run(tc.Name, func(t *testing.T) {
|
s.T().Run(tc.Name, func(t *testing.T) {
|
||||||
iter, err := s.server.createIterator(lower, upper, cursor, nil, 0)
|
iter, err := s.server.ms.createIterator(payload)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
|
@ -587,9 +584,12 @@ func (s *MailserverSuite) TestProcessRequestDeadlockHandling() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) messageExists(envelope *whisper.Envelope, low, upp uint32, bloom []byte, limit uint32) bool {
|
func (s *MailserverSuite) messageExists(envelope *whisper.Envelope, low, upp uint32, bloom []byte, limit uint32) bool {
|
||||||
receivedHashes, _, _ := processRequestAndCollectHashes(
|
receivedHashes, _, _ := processRequestAndCollectHashes(s.server, MessagesRequestPayload{
|
||||||
s.server, low, upp, nil, bloom, int(limit),
|
Lower: low,
|
||||||
)
|
Upper: upp,
|
||||||
|
Bloom: bloom,
|
||||||
|
Limit: limit,
|
||||||
|
})
|
||||||
for _, hash := range receivedHashes {
|
for _, hash := range receivedHashes {
|
||||||
if hash == envelope.Hash() {
|
if hash == envelope.Hash() {
|
||||||
return true
|
return true
|
||||||
|
@ -634,11 +634,11 @@ func (s *MailserverSuite) TestBloomFromReceivedMessage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MailserverSuite) setupServer(server *WMailServer) {
|
func (s *MailserverSuite) setupServer(server *WhisperMailServer) {
|
||||||
const password = "password_for_this_test"
|
const password = "password_for_this_test"
|
||||||
|
|
||||||
s.shh = whisper.New(&whisper.DefaultConfig)
|
s.shh = whisper.New(&whisper.DefaultConfig)
|
||||||
s.shh.RegisterServer(server)
|
s.shh.RegisterMailServer(server)
|
||||||
|
|
||||||
err := server.Init(s.shh, ¶ms.WhisperConfig{
|
err := server.Init(s.shh, ¶ms.WhisperConfig{
|
||||||
DataDir: s.dataDir,
|
DataDir: s.dataDir,
|
||||||
|
@ -770,10 +770,8 @@ func generateEnvelope(sentTime time.Time) (*whisper.Envelope, error) {
|
||||||
return generateEnvelopeWithKeys(sentTime, h[:], nil)
|
return generateEnvelopeWithKeys(sentTime, h[:], nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func processRequestAndCollectHashes(
|
func processRequestAndCollectHashes(server *WhisperMailServer, payload MessagesRequestPayload) ([]common.Hash, []byte, types.Hash) {
|
||||||
server *WMailServer, lower, upper uint32, cursor []byte, bloom []byte, limit int,
|
iter, _ := server.ms.createIterator(payload)
|
||||||
) ([]common.Hash, []byte, types.Hash) {
|
|
||||||
iter, _ := server.createIterator(lower, upper, cursor, nil, 0)
|
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
bundles := make(chan []rlp.RawValue, 10)
|
bundles := make(chan []rlp.RawValue, 10)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
@ -782,34 +780,19 @@ func processRequestAndCollectHashes(
|
||||||
go func() {
|
go func() {
|
||||||
for bundle := range bundles {
|
for bundle := range bundles {
|
||||||
for _, rawEnvelope := range bundle {
|
for _, rawEnvelope := range bundle {
|
||||||
|
|
||||||
var env *whisper.Envelope
|
var env *whisper.Envelope
|
||||||
if err := rlp.DecodeBytes(rawEnvelope, &env); err != nil {
|
if err := rlp.DecodeBytes(rawEnvelope, &env); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes = append(hashes, env.Hash())
|
hashes = append(hashes, env.Hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cursor, lastHash := server.processRequestInBundles(iter, bloom, limit, time.Minute, "req-01", bundles, done)
|
cursor, lastHash := server.ms.processRequestInBundles(iter, payload.Bloom, int(payload.Limit), time.Minute, "req-01", bundles, done)
|
||||||
|
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
return hashes, cursor, lastHash
|
return hashes, cursor, lastHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// mockPeerWithID is a struct that conforms to peerWithID interface.
|
|
||||||
type mockPeerWithID struct {
|
|
||||||
id []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p mockPeerWithID) ID() []byte { return p.id }
|
|
||||||
|
|
||||||
func TestPeerIDString(t *testing.T) {
|
|
||||||
a := []byte{0x01, 0x02, 0x03}
|
|
||||||
require.Equal(t, "010203", peerIDString(&mockPeerWithID{a}))
|
|
||||||
require.Equal(t, "010203", peerIDBytesString(a))
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
package mailserver
|
package mailserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
maxMessagesRequestPayloadLimit = 1000
|
||||||
|
)
|
||||||
|
|
||||||
// MessagesRequestPayload is a payload sent to the Mail Server.
|
// MessagesRequestPayload is a payload sent to the Mail Server.
|
||||||
type MessagesRequestPayload struct {
|
type MessagesRequestPayload struct {
|
||||||
// Lower is a lower bound of time range for which messages are requested.
|
// Lower is a lower bound of time range for which messages are requested.
|
||||||
|
@ -15,3 +24,29 @@ type MessagesRequestPayload struct {
|
||||||
// Batch set to true indicates that the client supports batched response.
|
// Batch set to true indicates that the client supports batched response.
|
||||||
Batch bool
|
Batch bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *MessagesRequestPayload) SetDefaults() {
|
||||||
|
if r.Limit == 0 {
|
||||||
|
r.Limit = maxQueryLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Upper == 0 {
|
||||||
|
r.Upper = uint32(time.Now().Unix() + whisperTTLSafeThreshold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r MessagesRequestPayload) Validate() error {
|
||||||
|
if r.Upper < r.Lower {
|
||||||
|
return errors.New("query range is invalid: lower > upper")
|
||||||
|
}
|
||||||
|
if r.Upper-r.Lower > uint32(maxQueryRange.Seconds()) {
|
||||||
|
return errors.New("query range must be smaller or equal to 24 hours")
|
||||||
|
}
|
||||||
|
if len(r.Bloom) == 0 {
|
||||||
|
return errors.New("bloom filter is empty")
|
||||||
|
}
|
||||||
|
if r.Limit > maxMessagesRequestPayloadLimit {
|
||||||
|
return errors.New("limit exceeds the maximum allowed value")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
151
node/node.go
151
node/node.go
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/status-im/status-go/services/status"
|
"github.com/status-im/status-go/services/status"
|
||||||
"github.com/status-im/status-go/static"
|
"github.com/status-im/status-go/static"
|
||||||
"github.com/status-im/status-go/timesource"
|
"github.com/status-im/status-go/timesource"
|
||||||
|
"github.com/status-im/status-go/waku"
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/whisper/v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ import (
|
||||||
var (
|
var (
|
||||||
ErrNodeMakeFailureFormat = "error creating p2p node: %s"
|
ErrNodeMakeFailureFormat = "error creating p2p node: %s"
|
||||||
ErrWhisperServiceRegistrationFailure = errors.New("failed to register the Whisper service")
|
ErrWhisperServiceRegistrationFailure = errors.New("failed to register the Whisper service")
|
||||||
|
ErrWakuServiceRegistrationFailure = errors.New("failed to register the Waku service")
|
||||||
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
|
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
|
||||||
ErrLightEthRegistrationFailureUpstreamEnabled = errors.New("failed to register the LES service, upstream is also configured")
|
ErrLightEthRegistrationFailureUpstreamEnabled = errors.New("failed to register the LES service, upstream is also configured")
|
||||||
ErrPersonalServiceRegistrationFailure = errors.New("failed to register the personal api service")
|
ErrPersonalServiceRegistrationFailure = errors.New("failed to register the personal api service")
|
||||||
|
@ -81,6 +83,14 @@ func MakeNode(config *params.NodeConfig, accs *accounts.Manager, db *leveldb.DB)
|
||||||
return nil, fmt.Errorf(ErrNodeMakeFailureFormat, err.Error())
|
return nil, fmt.Errorf(ErrNodeMakeFailureFormat, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.EnableNTPSync {
|
||||||
|
if err = stack.Register(func(*node.ServiceContext) (node.Service, error) {
|
||||||
|
return timesource.Default(), nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to register NTP time source: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = activateServices(stack, config, accs, db)
|
err = activateServices(stack, config, accs, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -119,11 +129,24 @@ func activateServices(stack *node.Node, config *params.NodeConfig, accs *account
|
||||||
}
|
}
|
||||||
|
|
||||||
func activateNodeServices(stack *node.Node, config *params.NodeConfig, db *leveldb.DB) error {
|
func activateNodeServices(stack *node.Node, config *params.NodeConfig, db *leveldb.DB) error {
|
||||||
|
// Register eth-node node bridge
|
||||||
|
err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
|
return &nodebridge.NodeService{Node: gethbridge.NewNodeBridge(stack)}, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to register NodeBridhe: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// start Whisper service.
|
// start Whisper service.
|
||||||
if err := activateShhService(stack, config, db); err != nil {
|
if err := activateShhService(stack, config, db); err != nil {
|
||||||
return fmt.Errorf("%v: %v", ErrWhisperServiceRegistrationFailure, err)
|
return fmt.Errorf("%v: %v", ErrWhisperServiceRegistrationFailure, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start Waku service
|
||||||
|
if err := activateWakuService(stack, config, db); err != nil {
|
||||||
|
return fmt.Errorf("%v: %v", ErrWakuServiceRegistrationFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
// start incentivisation service
|
// start incentivisation service
|
||||||
if err := activateIncentivisationService(stack, config); err != nil {
|
if err := activateIncentivisationService(stack, config); err != nil {
|
||||||
return fmt.Errorf("%v: %v", ErrIncentivisationServiceRegistrationFailure, err)
|
return fmt.Errorf("%v: %v", ErrIncentivisationServiceRegistrationFailure, err)
|
||||||
|
@ -290,26 +313,26 @@ func activatePeerService(stack *node.Node) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerMailServer(whisperService *whisper.Whisper, config *params.WhisperConfig) (err error) {
|
func registerWhisperMailServer(whisperService *whisper.Whisper, config *params.WhisperConfig) (err error) {
|
||||||
var mailServer mailserver.WMailServer
|
var mailServer mailserver.WhisperMailServer
|
||||||
whisperService.RegisterServer(&mailServer)
|
whisperService.RegisterMailServer(&mailServer)
|
||||||
|
|
||||||
return mailServer.Init(whisperService, config)
|
return mailServer.Init(whisperService, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerWakuMailServer(wakuService *waku.Waku, config *params.WakuConfig) (err error) {
|
||||||
|
var mailServer mailserver.WakuMailServer
|
||||||
|
wakuService.RegisterMailServer(&mailServer)
|
||||||
|
|
||||||
|
return mailServer.Init(wakuService, config)
|
||||||
|
}
|
||||||
|
|
||||||
// activateShhService configures Whisper and adds it to the given node.
|
// activateShhService configures Whisper and adds it to the given node.
|
||||||
func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb.DB) (err error) {
|
func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb.DB) (err error) {
|
||||||
if !config.WhisperConfig.Enabled {
|
if !config.WhisperConfig.Enabled {
|
||||||
logger.Info("SHH protocol is disabled")
|
logger.Info("SHH protocol is disabled")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.WhisperConfig.EnableNTPSync {
|
|
||||||
if err = stack.Register(func(*node.ServiceContext) (node.Service, error) {
|
|
||||||
return timesource.Default(), nil
|
|
||||||
}); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
return createShhService(ctx, &config.WhisperConfig, &config.ClusterConfig)
|
return createShhService(ctx, &config.WhisperConfig, &config.ClusterConfig)
|
||||||
|
@ -318,14 +341,6 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register eth-node node bridge
|
|
||||||
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
|
||||||
return &nodebridge.NodeService{Node: gethbridge.NewNodeBridge(stack)}, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register Whisper eth-node bridge
|
// Register Whisper eth-node bridge
|
||||||
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
var ethnode *nodebridge.NodeService
|
var ethnode *nodebridge.NodeService
|
||||||
|
@ -352,6 +367,25 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// activateWakuService configures Waku and adds it to the given node.
|
||||||
|
func activateWakuService(stack *node.Node, config *params.NodeConfig, db *leveldb.DB) (err error) {
|
||||||
|
if !config.WakuConfig.Enabled {
|
||||||
|
logger.Info("Waku protocol is disabled")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
|
return createWakuService(ctx, &config.WakuConfig, &config.ClusterConfig)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: what to do with shhext?
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperConfig, clusterConfig *params.ClusterConfig) (*whisper.Whisper, error) {
|
func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperConfig, clusterConfig *params.ClusterConfig) (*whisper.Whisper, error) {
|
||||||
whisperServiceConfig := &whisper.Config{
|
whisperServiceConfig := &whisper.Config{
|
||||||
MaxMessageSize: whisper.DefaultMaxMessageSize,
|
MaxMessageSize: whisper.DefaultMaxMessageSize,
|
||||||
|
@ -372,17 +406,13 @@ func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperCon
|
||||||
whisperService.SetRateLimiter(r)
|
whisperService.SetRateLimiter(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if whisperConfig.EnableNTPSync {
|
if timesource, err := timeSource(ctx); err == nil {
|
||||||
timesource, err := whisperTimeSource(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
whisperService.SetTimeSource(timesource)
|
whisperService.SetTimeSource(timesource)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable mail service
|
// enable mail service
|
||||||
if whisperConfig.EnableMailServer {
|
if whisperConfig.EnableMailServer {
|
||||||
if err := registerMailServer(whisperService, whisperConfig); err != nil {
|
if err := registerWhisperMailServer(whisperService, whisperConfig); err != nil {
|
||||||
return nil, fmt.Errorf("failed to register MailServer: %v", err)
|
return nil, fmt.Errorf("failed to register MailServer: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,6 +427,48 @@ func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperCon
|
||||||
return whisperService, nil
|
return whisperService, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createWakuService(ctx *node.ServiceContext, wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) (*waku.Waku, error) {
|
||||||
|
cfg := &waku.Config{
|
||||||
|
MaxMessageSize: waku.DefaultMaxMessageSize,
|
||||||
|
MinimumAcceptedPoW: params.WakuMinimumPoW,
|
||||||
|
}
|
||||||
|
|
||||||
|
if wakuCfg.MaxMessageSize > 0 {
|
||||||
|
cfg.MaxMessageSize = wakuCfg.MaxMessageSize
|
||||||
|
}
|
||||||
|
if wakuCfg.MinimumPoW > 0 {
|
||||||
|
cfg.MinimumAcceptedPoW = wakuCfg.MinimumPoW
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: provide a logger
|
||||||
|
w := waku.New(cfg, nil)
|
||||||
|
|
||||||
|
if wakuCfg.EnableRateLimiter {
|
||||||
|
r := wakuRateLimiter(wakuCfg, clusterCfg)
|
||||||
|
w.RegisterRateLimiter(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if timesource, err := timeSource(ctx); err == nil {
|
||||||
|
w.SetTimeSource(timesource)
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable mail service
|
||||||
|
if wakuCfg.EnableMailServer {
|
||||||
|
if err := registerWakuMailServer(w, wakuCfg); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to register WakuMailServer: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if wakuCfg.LightClient {
|
||||||
|
emptyBloomFilter := make([]byte, 64)
|
||||||
|
if err := w.SetBloomFilter(emptyBloomFilter); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return w, nil
|
||||||
|
}
|
||||||
|
|
||||||
// activateIncentivisationService configures Whisper and adds it to the given node.
|
// activateIncentivisationService configures Whisper and adds it to the given node.
|
||||||
func activateIncentivisationService(stack *node.Node, config *params.NodeConfig) (err error) {
|
func activateIncentivisationService(stack *node.Node, config *params.NodeConfig) (err error) {
|
||||||
if !config.WhisperConfig.Enabled {
|
if !config.WhisperConfig.Enabled {
|
||||||
|
@ -478,8 +550,8 @@ func parseNodesToNodeID(enodes []string) []enode.ID {
|
||||||
return nodeIDs
|
return nodeIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// whisperTimeSource get timeSource to be used by whisper
|
// timeSource get timeSource to be used by whisper
|
||||||
func whisperTimeSource(ctx *node.ServiceContext) (func() time.Time, error) {
|
func timeSource(ctx *node.ServiceContext) (func() time.Time, error) {
|
||||||
var timeSource *timesource.NTPTimeSource
|
var timeSource *timesource.NTPTimeSource
|
||||||
if err := ctx.Service(&timeSource); err != nil {
|
if err := ctx.Service(&timeSource); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -513,3 +585,30 @@ func whisperRateLimiter(whisperConfig *params.WhisperConfig, clusterConfig *para
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wakuRateLimiter(wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) *waku.PeerRateLimiter {
|
||||||
|
enodes := append(
|
||||||
|
parseNodes(clusterCfg.StaticNodes),
|
||||||
|
parseNodes(clusterCfg.TrustedMailServers)...,
|
||||||
|
)
|
||||||
|
var (
|
||||||
|
ips []string
|
||||||
|
peerIDs []enode.ID
|
||||||
|
)
|
||||||
|
for _, item := range enodes {
|
||||||
|
ips = append(ips, item.IP().String())
|
||||||
|
peerIDs = append(peerIDs, item.ID())
|
||||||
|
}
|
||||||
|
return waku.NewPeerRateLimiter(
|
||||||
|
&waku.PeerRateLimiterConfig{
|
||||||
|
LimitPerSecIP: wakuCfg.RateLimitIP,
|
||||||
|
LimitPerSecPeerID: wakuCfg.RateLimitPeerID,
|
||||||
|
WhitelistedIPs: ips,
|
||||||
|
WhitelistedPeerIDs: peerIDs,
|
||||||
|
},
|
||||||
|
&whisper.MetricsRateLimiterHandler{},
|
||||||
|
&whisper.DropPeerRateLimiterHandler{
|
||||||
|
Tolerance: wakuCfg.RateLimitTolerance,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
func TestWhisperLightModeEnabledSetsEmptyBloomFilter(t *testing.T) {
|
func TestWhisperLightModeEnabledSetsEmptyBloomFilter(t *testing.T) {
|
||||||
config := params.NodeConfig{
|
config := params.NodeConfig{
|
||||||
|
EnableNTPSync: true,
|
||||||
WhisperConfig: params.WhisperConfig{
|
WhisperConfig: params.WhisperConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
LightClient: true,
|
LightClient: true,
|
||||||
|
@ -35,6 +36,7 @@ func TestWhisperLightModeEnabledSetsEmptyBloomFilter(t *testing.T) {
|
||||||
|
|
||||||
func TestWhisperLightModeEnabledSetsNilBloomFilter(t *testing.T) {
|
func TestWhisperLightModeEnabledSetsNilBloomFilter(t *testing.T) {
|
||||||
config := params.NodeConfig{
|
config := params.NodeConfig{
|
||||||
|
EnableNTPSync: true,
|
||||||
WhisperConfig: params.WhisperConfig{
|
WhisperConfig: params.WhisperConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
LightClient: false,
|
LightClient: false,
|
||||||
|
|
|
@ -90,6 +90,7 @@ func TestStatusNodeWithDataDir(t *testing.T) {
|
||||||
|
|
||||||
func TestStatusNodeServiceGetters(t *testing.T) {
|
func TestStatusNodeServiceGetters(t *testing.T) {
|
||||||
config := params.NodeConfig{
|
config := params.NodeConfig{
|
||||||
|
EnableNTPSync: true,
|
||||||
WhisperConfig: params.WhisperConfig{
|
WhisperConfig: params.WhisperConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
},
|
},
|
||||||
|
|
105
params/config.go
105
params/config.go
|
@ -43,6 +43,25 @@ type LightEthConfig struct {
|
||||||
MinTrustedFraction int
|
MinTrustedFraction int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// DatabaseConfig
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
type DatabaseConfig struct {
|
||||||
|
PGConfig PGConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// PGConfig
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
type PGConfig struct {
|
||||||
|
// Enabled whether we should use a Postgres instance
|
||||||
|
Enabled bool
|
||||||
|
// The URI of the server
|
||||||
|
URI string
|
||||||
|
}
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// WhisperConfig
|
// WhisperConfig
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -81,9 +100,6 @@ type WhisperConfig struct {
|
||||||
// TTL time to live for messages, in seconds
|
// TTL time to live for messages, in seconds
|
||||||
TTL int
|
TTL int
|
||||||
|
|
||||||
// EnableNTPSync enables NTP synchronizations
|
|
||||||
EnableNTPSync bool
|
|
||||||
|
|
||||||
// MaxMessageSize is a maximum size of a devp2p packet handled by the Whisper protocol,
|
// MaxMessageSize is a maximum size of a devp2p packet handled by the Whisper protocol,
|
||||||
// not only the size of envelopes sent in that packet.
|
// not only the size of envelopes sent in that packet.
|
||||||
MaxMessageSize uint32
|
MaxMessageSize uint32
|
||||||
|
@ -108,23 +124,71 @@ type WhisperConfig struct {
|
||||||
RateLimitTolerance int64
|
RateLimitTolerance int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type DatabaseConfig struct {
|
|
||||||
PGConfig PGConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
type PGConfig struct {
|
|
||||||
// Enabled whether we should use a Postgres instance
|
|
||||||
Enabled bool
|
|
||||||
// The URI of the server
|
|
||||||
URI string
|
|
||||||
}
|
|
||||||
|
|
||||||
// String dumps config object as nicely indented JSON
|
// String dumps config object as nicely indented JSON
|
||||||
func (c *WhisperConfig) String() string {
|
func (c *WhisperConfig) String() string {
|
||||||
data, _ := json.MarshalIndent(c, "", " ") // nolint: gas
|
data, _ := json.MarshalIndent(c, "", " ") // nolint: gas
|
||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// WakuConfig
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
// WakuConfig provides a configuration for Waku service.
|
||||||
|
type WakuConfig struct {
|
||||||
|
// Enabled set to true enables Waku subprotocol.
|
||||||
|
Enabled bool
|
||||||
|
|
||||||
|
// LightClient should be true if the node should start with an empty bloom filter and not forward messages from other nodes
|
||||||
|
LightClient bool
|
||||||
|
|
||||||
|
// EnableMailServer is mode when node is capable of delivering expired messages on demand
|
||||||
|
EnableMailServer bool
|
||||||
|
|
||||||
|
// DataDir is the file system folder Whisper should use for any data storage needs.
|
||||||
|
// For instance, MailServer will use this directory to store its data.
|
||||||
|
DataDir string
|
||||||
|
|
||||||
|
// MinimumPoW minimum PoW for Whisper messages
|
||||||
|
MinimumPoW float64
|
||||||
|
|
||||||
|
// MailServerPassword for symmetric encryption of whisper message history requests.
|
||||||
|
// (if no account file selected, then this password is used for symmetric encryption).
|
||||||
|
MailServerPassword string
|
||||||
|
|
||||||
|
// MailServerRateLimit minimum time between queries to mail server per peer.
|
||||||
|
MailServerRateLimit int
|
||||||
|
|
||||||
|
// MailServerDataRetention is a number of days data should be stored by MailServer.
|
||||||
|
MailServerDataRetention int
|
||||||
|
|
||||||
|
// TTL time to live for messages, in seconds
|
||||||
|
TTL int
|
||||||
|
|
||||||
|
// MaxMessageSize is a maximum size of a devp2p packet handled by the Whisper protocol,
|
||||||
|
// not only the size of envelopes sent in that packet.
|
||||||
|
MaxMessageSize uint32
|
||||||
|
|
||||||
|
// DatabaseConfig is configuration for which data store we use.
|
||||||
|
DatabaseConfig DatabaseConfig
|
||||||
|
|
||||||
|
// EnableRateLimiter set to true enables IP and peer ID rate limiting.
|
||||||
|
EnableRateLimiter bool
|
||||||
|
|
||||||
|
// RateLimitIP sets the limit on the number of messages per second
|
||||||
|
// from a given IP.
|
||||||
|
RateLimitIP int64
|
||||||
|
|
||||||
|
// RateLimitPeerID sets the limit on the number of messages per second
|
||||||
|
// from a given peer ID.
|
||||||
|
RateLimitPeerID int64
|
||||||
|
|
||||||
|
// RateLimitTolerance is a number of how many a limit must be exceeded
|
||||||
|
// in order to drop a peer.
|
||||||
|
// If equal to 0, the peers are never dropped.
|
||||||
|
RateLimitTolerance int64
|
||||||
|
}
|
||||||
|
|
||||||
// IncentivisationConfig holds incentivisation-related configuration
|
// IncentivisationConfig holds incentivisation-related configuration
|
||||||
type IncentivisationConfig struct {
|
type IncentivisationConfig struct {
|
||||||
// Enabled flag specifies whether protocol is enabled
|
// Enabled flag specifies whether protocol is enabled
|
||||||
|
@ -343,6 +407,9 @@ type NodeConfig struct {
|
||||||
// EnableStatusService should be true to enable methods under status namespace.
|
// EnableStatusService should be true to enable methods under status namespace.
|
||||||
EnableStatusService bool
|
EnableStatusService bool
|
||||||
|
|
||||||
|
// EnableNTPSync enables NTP synchronizations
|
||||||
|
EnableNTPSync bool
|
||||||
|
|
||||||
// UpstreamConfig extra config for providing upstream infura server.
|
// UpstreamConfig extra config for providing upstream infura server.
|
||||||
UpstreamConfig UpstreamRPCConfig `json:"UpstreamConfig"`
|
UpstreamConfig UpstreamRPCConfig `json:"UpstreamConfig"`
|
||||||
|
|
||||||
|
@ -355,6 +422,9 @@ type NodeConfig struct {
|
||||||
// WhisperConfig extra configuration for SHH
|
// WhisperConfig extra configuration for SHH
|
||||||
WhisperConfig WhisperConfig `json:"WhisperConfig," validate:"structonly"`
|
WhisperConfig WhisperConfig `json:"WhisperConfig," validate:"structonly"`
|
||||||
|
|
||||||
|
// WakuConfig provides a configuration for Waku subprotocol.
|
||||||
|
WakuConfig WakuConfig `json:"WakuConfig" validate:"structonly"`
|
||||||
|
|
||||||
// IncentivisationConfig extra configuration for incentivisation service
|
// IncentivisationConfig extra configuration for incentivisation service
|
||||||
IncentivisationConfig IncentivisationConfig `json:"IncentivisationConfig," validate:"structonly"`
|
IncentivisationConfig IncentivisationConfig `json:"IncentivisationConfig," validate:"structonly"`
|
||||||
|
|
||||||
|
@ -505,8 +575,8 @@ func NewNodeConfigWithDefaults(dataDir string, networkID uint64, opts ...Option)
|
||||||
c.LogCompressRotated = true
|
c.LogCompressRotated = true
|
||||||
c.LogMaxBackups = 3
|
c.LogMaxBackups = 3
|
||||||
c.LogToStderr = true
|
c.LogToStderr = true
|
||||||
|
c.EnableNTPSync = true
|
||||||
c.WhisperConfig.Enabled = true
|
c.WhisperConfig.Enabled = true
|
||||||
c.WhisperConfig.EnableNTPSync = true
|
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(c); err != nil {
|
if err := opt(c); err != nil {
|
||||||
|
@ -591,6 +661,7 @@ func NewNodeConfig(dataDir string, networkID uint64) (*NodeConfig, error) {
|
||||||
LogFile: "",
|
LogFile: "",
|
||||||
LogLevel: "ERROR",
|
LogLevel: "ERROR",
|
||||||
NoDiscovery: true,
|
NoDiscovery: true,
|
||||||
|
EnableNTPSync: true,
|
||||||
UpstreamConfig: UpstreamRPCConfig{
|
UpstreamConfig: UpstreamRPCConfig{
|
||||||
URL: getUpstreamURL(networkID),
|
URL: getUpstreamURL(networkID),
|
||||||
},
|
},
|
||||||
|
@ -691,6 +762,10 @@ func (c *NodeConfig) Validate() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.WhisperConfig.Enabled && c.WakuConfig.Enabled && c.WhisperConfig.DataDir == c.WakuConfig.DataDir {
|
||||||
|
return fmt.Errorf("both Whisper and Waku are enabled and use the same data dir")
|
||||||
|
}
|
||||||
|
|
||||||
// Whisper's data directory must be relative to the main data directory
|
// Whisper's data directory must be relative to the main data directory
|
||||||
// if EnableMailServer is true.
|
// if EnableMailServer is true.
|
||||||
if c.WhisperConfig.Enabled && c.WhisperConfig.EnableMailServer {
|
if c.WhisperConfig.Enabled && c.WhisperConfig.EnableMailServer {
|
||||||
|
|
|
@ -29,10 +29,10 @@ func TestNewNodeConfigWithDefaults(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "/some/data/path", c.DataDir)
|
assert.Equal(t, "/some/data/path", c.DataDir)
|
||||||
assert.Equal(t, "/some/data/path/keystore", c.KeyStoreDir)
|
assert.Equal(t, "/some/data/path/keystore", c.KeyStoreDir)
|
||||||
|
assert.Equal(t, true, c.EnableNTPSync)
|
||||||
// assert Whisper
|
// assert Whisper
|
||||||
assert.Equal(t, true, c.WhisperConfig.Enabled)
|
assert.Equal(t, true, c.WhisperConfig.Enabled)
|
||||||
assert.Equal(t, "/some/data/path/wnode", c.WhisperConfig.DataDir)
|
assert.Equal(t, "/some/data/path/wnode", c.WhisperConfig.DataDir)
|
||||||
assert.Equal(t, true, c.WhisperConfig.EnableNTPSync)
|
|
||||||
// assert MailServer
|
// assert MailServer
|
||||||
assert.Equal(t, true, c.WhisperConfig.EnableMailServer)
|
assert.Equal(t, true, c.WhisperConfig.EnableMailServer)
|
||||||
assert.NotEmpty(t, c.WhisperConfig.MailServerPassword)
|
assert.NotEmpty(t, c.WhisperConfig.MailServerPassword)
|
||||||
|
|
|
@ -27,6 +27,12 @@ const (
|
||||||
// WhisperTTL is time to live for messages, in seconds
|
// WhisperTTL is time to live for messages, in seconds
|
||||||
WhisperTTL = 120
|
WhisperTTL = 120
|
||||||
|
|
||||||
|
// WakuMinimumPoW amount of work for Whisper message to be added to sending queue
|
||||||
|
WakuMinimumPoW = 0.001
|
||||||
|
|
||||||
|
// WakuTTL is time to live for messages, in seconds
|
||||||
|
WakuTTL = 120
|
||||||
|
|
||||||
// MainnetEthereumNetworkURL is URL where the upstream ethereum network is loaded to
|
// MainnetEthereumNetworkURL is URL where the upstream ethereum network is loaded to
|
||||||
// allow us avoid syncing node.
|
// allow us avoid syncing node.
|
||||||
MainnetEthereumNetworkURL = "https://mainnet.infura.io/nKmXgiFgc2KqtoQ8BCGJ"
|
MainnetEthereumNetworkURL = "https://mainnet.infura.io/nKmXgiFgc2KqtoQ8BCGJ"
|
||||||
|
|
|
@ -11,12 +11,14 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||||
|
@ -30,12 +32,16 @@ github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85Sx
|
||||||
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
||||||
|
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||||
|
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
|
||||||
|
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||||
|
@ -137,6 +143,7 @@ github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||||
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
|
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
|
||||||
|
@ -209,6 +216,7 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
|
@ -224,6 +232,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
|
@ -241,11 +250,13 @@ github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQ
|
||||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
||||||
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
||||||
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
||||||
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
||||||
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
||||||
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
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/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
||||||
|
@ -268,6 +279,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||||
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.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
||||||
|
@ -279,6 +292,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
@ -428,6 +442,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||||
|
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
@ -440,17 +456,20 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/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 v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
||||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
@ -461,12 +480,14 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
|
@ -482,6 +503,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
||||||
|
@ -531,6 +553,7 @@ github.com/status-im/status-go v0.37.3/go.mod h1:9qHQ2+8NS6ivPJS5YbsI3gWkr0t6DWm
|
||||||
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
|
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
|
||||||
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
||||||
github.com/status-im/status-go/protocol v1.0.1/go.mod h1:LpA7BsaNmj6EOdq7BwuqncewjPqIRHCletZOb2wlWrY=
|
github.com/status-im/status-go/protocol v1.0.1/go.mod h1:LpA7BsaNmj6EOdq7BwuqncewjPqIRHCletZOb2wlWrY=
|
||||||
|
github.com/status-im/status-go/waku v1.0.0/go.mod h1:1bjvQAL4cJYtxCsm6DnKdJbxcZwnvvZmxb6pmoUDtuY=
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
||||||
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
|
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
|
||||||
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
||||||
|
@ -553,7 +576,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||||
|
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
|
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||||
|
@ -583,6 +609,8 @@ github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVT
|
||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||||
|
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
@ -609,6 +637,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -620,6 +649,7 @@ golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIo
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
@ -647,6 +677,7 @@ golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -673,12 +704,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
|
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
|
||||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
||||||
|
@ -700,7 +734,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190912185636-87d9f09c5d89/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-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-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
||||||
|
@ -721,7 +757,9 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
@ -733,6 +771,11 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||||
|
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||||
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
|
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
|
@ -740,6 +783,7 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHN
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
||||||
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
||||||
|
@ -754,5 +798,6 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
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-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-20190106161140-3f1c8253044a/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 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
|
|
@ -737,7 +737,7 @@ func makeEnvelop(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return gethbridge.NewGethEnvelopeWrapper(envelope), nil
|
return gethbridge.NewWhisperEnvelope(envelope), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeMessagesRequestPayload makes a specific payload for MailServer
|
// makeMessagesRequestPayload makes a specific payload for MailServer
|
||||||
|
|
|
@ -344,7 +344,7 @@ func (filter BloomFilterOption) ToMessagesRequestPayload() ([]byte, error) {
|
||||||
// Client must tell the MailServer if it supports batch responses.
|
// Client must tell the MailServer if it supports batch responses.
|
||||||
// This can be removed in the future.
|
// This can be removed in the future.
|
||||||
Batch: true,
|
Batch: true,
|
||||||
Limit: 10000,
|
Limit: 1000,
|
||||||
}
|
}
|
||||||
return rlp.EncodeToBytes(payload)
|
return rlp.EncodeToBytes(payload)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ func TestBloomFilterToMessageRequestPayload(t *testing.T) {
|
||||||
Upper: end,
|
Upper: end,
|
||||||
Bloom: filter,
|
Bloom: filter,
|
||||||
Batch: true,
|
Batch: true,
|
||||||
Limit: 10000,
|
Limit: 1000,
|
||||||
}
|
}
|
||||||
bloomOption = BloomFilterOption{
|
bloomOption = BloomFilterOption{
|
||||||
Filter: filter,
|
Filter: filter,
|
||||||
|
|
|
@ -566,7 +566,7 @@ type RequestWithTrackingHistorySuite struct {
|
||||||
localContext Context
|
localContext Context
|
||||||
mailSymKey string
|
mailSymKey string
|
||||||
|
|
||||||
remoteMailserver *mailserver.WMailServer
|
remoteMailserver *mailserver.WhisperMailServer
|
||||||
remoteNode *enode.Node
|
remoteNode *enode.Node
|
||||||
remoteWhisper *whisper.Whisper
|
remoteWhisper *whisper.Whisper
|
||||||
}
|
}
|
||||||
|
@ -602,8 +602,8 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() {
|
||||||
remoteSHH := whisper.New(conf)
|
remoteSHH := whisper.New(conf)
|
||||||
s.remoteWhisper = remoteSHH
|
s.remoteWhisper = remoteSHH
|
||||||
s.Require().NoError(remoteSHH.Start(nil))
|
s.Require().NoError(remoteSHH.Start(nil))
|
||||||
s.remoteMailserver = &mailserver.WMailServer{}
|
s.remoteMailserver = &mailserver.WhisperMailServer{}
|
||||||
remoteSHH.RegisterServer(s.remoteMailserver)
|
remoteSHH.RegisterMailServer(s.remoteMailserver)
|
||||||
password := "test"
|
password := "test"
|
||||||
tmpdir, err = ioutil.TempDir("", "tracking-history-tests-")
|
tmpdir, err = ioutil.TempDir("", "tracking-history-tests-")
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
|
@ -488,10 +488,10 @@ func (s *WhisperMailboxSuite) TestSyncBetweenTwoMailServers() {
|
||||||
publicChatSymKey, err := mailboxWhisperService.GetSymKey(symKeyID)
|
publicChatSymKey, err := mailboxWhisperService.GetSymKey(symKeyID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
var mailServer mailserver.WMailServer
|
var mailServer mailserver.WhisperMailServer
|
||||||
err = mailServer.Init(mailboxWhisperService, &mailbox.StatusNode().Config().WhisperConfig)
|
err = mailServer.Init(mailboxWhisperService, &mailbox.StatusNode().Config().WhisperConfig)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
mailboxWhisperService.RegisterServer(&mailServer)
|
mailboxWhisperService.RegisterMailServer(&mailServer)
|
||||||
|
|
||||||
// envelopes to archive
|
// envelopes to archive
|
||||||
envelopesCount := 5
|
envelopesCount := 5
|
||||||
|
@ -548,7 +548,7 @@ func (s *WhisperMailboxSuite) TestSyncBetweenTwoMailServers() {
|
||||||
"shhext_syncMessages",
|
"shhext_syncMessages",
|
||||||
shhext.SyncMessagesRequest{
|
shhext.SyncMessagesRequest{
|
||||||
MailServerPeer: mailbox.StatusNode().Server().Self().URLv4(),
|
MailServerPeer: mailbox.StatusNode().Server().Self().URLv4(),
|
||||||
From: 0,
|
From: uint32(time.Now().Add(-time.Hour).Unix()),
|
||||||
To: uint32(time.Now().Unix()),
|
To: uint32(time.Now().Unix()),
|
||||||
Limit: 1,
|
Limit: 1,
|
||||||
},
|
},
|
||||||
|
@ -567,7 +567,7 @@ func (s *WhisperMailboxSuite) TestSyncBetweenTwoMailServers() {
|
||||||
"shhext_syncMessages",
|
"shhext_syncMessages",
|
||||||
shhext.SyncMessagesRequest{
|
shhext.SyncMessagesRequest{
|
||||||
MailServerPeer: mailbox.StatusNode().Server().Self().URLv4(),
|
MailServerPeer: mailbox.StatusNode().Server().Self().URLv4(),
|
||||||
From: 0,
|
From: uint32(time.Now().Add(-time.Hour).Unix()),
|
||||||
To: uint32(time.Now().Unix()),
|
To: uint32(time.Now().Unix()),
|
||||||
Limit: 10,
|
Limit: 10,
|
||||||
Cursor: syncMessagesResponse.Cursor,
|
Cursor: syncMessagesResponse.Cursor,
|
||||||
|
|
|
@ -290,10 +290,10 @@ func MakeTestNodeConfigWithDataDir(name, dataDir string, networkID uint64) (*par
|
||||||
} else {
|
} else {
|
||||||
cfg.Name = name
|
cfg.Name = name
|
||||||
}
|
}
|
||||||
|
cfg.EnableNTPSync = true
|
||||||
cfg.NoDiscovery = true
|
cfg.NoDiscovery = true
|
||||||
cfg.LightEthConfig.Enabled = false
|
cfg.LightEthConfig.Enabled = false
|
||||||
cfg.WhisperConfig.Enabled = true
|
cfg.WhisperConfig.Enabled = true
|
||||||
cfg.WhisperConfig.EnableNTPSync = false
|
|
||||||
if dataDir != "" {
|
if dataDir != "" {
|
||||||
cfg.KeyStoreDir = path.Join(dataDir, "keystore")
|
cfg.KeyStoreDir = path.Join(dataDir, "keystore")
|
||||||
cfg.WhisperConfig.DataDir = path.Join(dataDir, "wnode")
|
cfg.WhisperConfig.DataDir = path.Join(dataDir, "wnode")
|
||||||
|
|
|
@ -12,6 +12,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
## [0.10.5]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed uptime calculation under Windows. #126
|
||||||
|
- Fixed compilation issue for darwin/386. #128
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Load DLLs only from Windows system directory. #132
|
||||||
|
|
||||||
## [0.10.4]
|
## [0.10.4]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -37,6 +37,7 @@ The features vary by operating system.
|
||||||
| ProcMem | X | X | X | | X |
|
| ProcMem | X | X | X | | X |
|
||||||
| ProcState | X | X | X | | X |
|
| ProcState | X | X | X | | X |
|
||||||
| ProcTime | X | X | X | | X |
|
| ProcTime | X | X | X | | X |
|
||||||
|
| Rusage | X | | X | | |
|
||||||
| Swap | X | X | | X | X |
|
| Swap | X | X | | X | X |
|
||||||
| Uptime | X | X | | X | X |
|
| Uptime | X | X | | X | X |
|
||||||
|
|
||||||
|
|
|
@ -40,18 +40,6 @@ func (self *LoadAverage) Get() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Uptime) Get() error {
|
|
||||||
tv := syscall.Timeval32{}
|
|
||||||
|
|
||||||
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Mem) Get() error {
|
func (self *Mem) Get() error {
|
||||||
var vmstat C.vm_statistics_data_t
|
var vmstat C.vm_statistics_data_t
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package gosigar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (self *Uptime) Get() error {
|
||||||
|
tv := syscall.Timeval{}
|
||||||
|
|
||||||
|
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package gosigar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (self *Uptime) Get() error {
|
||||||
|
tv := syscall.Timeval32{}
|
||||||
|
|
||||||
|
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrNotImplemented is returned when a particular statistic isn't implemented on the host OS.
|
||||||
type ErrNotImplemented struct {
|
type ErrNotImplemented struct {
|
||||||
OS string
|
OS string
|
||||||
}
|
}
|
||||||
|
@ -12,6 +13,7 @@ func (e ErrNotImplemented) Error() string {
|
||||||
return "not implemented on " + e.OS
|
return "not implemented on " + e.OS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNotImplemented returns true if the error is ErrNotImplemented
|
||||||
func IsNotImplemented(err error) bool {
|
func IsNotImplemented(err error) bool {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case ErrNotImplemented, *ErrNotImplemented:
|
case ErrNotImplemented, *ErrNotImplemented:
|
||||||
|
@ -21,6 +23,7 @@ func IsNotImplemented(err error) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sigar is an interface for gathering system host stats
|
||||||
type Sigar interface {
|
type Sigar interface {
|
||||||
CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
|
CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
|
||||||
GetLoadAverage() (LoadAverage, error)
|
GetLoadAverage() (LoadAverage, error)
|
||||||
|
@ -32,6 +35,7 @@ type Sigar interface {
|
||||||
GetRusage(who int) (Rusage, error)
|
GetRusage(who int) (Rusage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cpu contains CPU time stats
|
||||||
type Cpu struct {
|
type Cpu struct {
|
||||||
User uint64
|
User uint64
|
||||||
Nice uint64
|
Nice uint64
|
||||||
|
@ -43,11 +47,13 @@ type Cpu struct {
|
||||||
Stolen uint64
|
Stolen uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total returns total CPU time
|
||||||
func (cpu *Cpu) Total() uint64 {
|
func (cpu *Cpu) Total() uint64 {
|
||||||
return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
|
return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
|
||||||
cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
|
cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delta returns the difference between two Cpu stat objects
|
||||||
func (cpu Cpu) Delta(other Cpu) Cpu {
|
func (cpu Cpu) Delta(other Cpu) Cpu {
|
||||||
return Cpu{
|
return Cpu{
|
||||||
User: cpu.User - other.User,
|
User: cpu.User - other.User,
|
||||||
|
@ -61,14 +67,17 @@ func (cpu Cpu) Delta(other Cpu) Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadAverage reports standard load averages
|
||||||
type LoadAverage struct {
|
type LoadAverage struct {
|
||||||
One, Five, Fifteen float64
|
One, Five, Fifteen float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uptime reports system uptime
|
||||||
type Uptime struct {
|
type Uptime struct {
|
||||||
Length float64
|
Length float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mem contains host memory stats
|
||||||
type Mem struct {
|
type Mem struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
|
@ -77,12 +86,14 @@ type Mem struct {
|
||||||
ActualUsed uint64
|
ActualUsed uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap contains stats on swap space
|
||||||
type Swap struct {
|
type Swap struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
Free uint64
|
Free uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HugeTLBPages contains HugePages stats
|
||||||
type HugeTLBPages struct {
|
type HugeTLBPages struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Free uint64
|
Free uint64
|
||||||
|
@ -92,16 +103,19 @@ type HugeTLBPages struct {
|
||||||
TotalAllocatedSize uint64
|
TotalAllocatedSize uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CpuList contains a list of CPUs on the host system
|
||||||
type CpuList struct {
|
type CpuList struct {
|
||||||
List []Cpu
|
List []Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FDUsage contains stats on filesystem usage
|
||||||
type FDUsage struct {
|
type FDUsage struct {
|
||||||
Open uint64
|
Open uint64
|
||||||
Unused uint64
|
Unused uint64
|
||||||
Max uint64
|
Max uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystem contains basic information about a given mounted filesystem
|
||||||
type FileSystem struct {
|
type FileSystem struct {
|
||||||
DirName string
|
DirName string
|
||||||
DevName string
|
DevName string
|
||||||
|
@ -111,10 +125,12 @@ type FileSystem struct {
|
||||||
Flags uint32
|
Flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystemList gets a list of mounted filesystems
|
||||||
type FileSystemList struct {
|
type FileSystemList struct {
|
||||||
List []FileSystem
|
List []FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystemUsage contains basic stats for the specified filesystem
|
||||||
type FileSystemUsage struct {
|
type FileSystemUsage struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
|
@ -124,21 +140,30 @@ type FileSystemUsage struct {
|
||||||
FreeFiles uint64
|
FreeFiles uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcList contains a list of processes found on the host system
|
||||||
type ProcList struct {
|
type ProcList struct {
|
||||||
List []int
|
List []int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunState is a byte-long code used to specify the current runtime state of a process
|
||||||
type RunState byte
|
type RunState byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RunStateSleep = 'S'
|
// RunStateSleep corresponds to a sleep state
|
||||||
RunStateRun = 'R'
|
RunStateSleep = 'S'
|
||||||
RunStateStop = 'T'
|
// RunStateRun corresponds to a running state
|
||||||
RunStateZombie = 'Z'
|
RunStateRun = 'R'
|
||||||
RunStateIdle = 'D'
|
// RunStateStop corresponds to a stopped state
|
||||||
|
RunStateStop = 'T'
|
||||||
|
// RunStateZombie marks a zombie process
|
||||||
|
RunStateZombie = 'Z'
|
||||||
|
// RunStateIdle corresponds to an idle state
|
||||||
|
RunStateIdle = 'D'
|
||||||
|
// RunStateUnknown corresponds to a process in an unknown state
|
||||||
RunStateUnknown = '?'
|
RunStateUnknown = '?'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ProcState contains basic metadata and process ownership info for the specified process
|
||||||
type ProcState struct {
|
type ProcState struct {
|
||||||
Name string
|
Name string
|
||||||
Username string
|
Username string
|
||||||
|
@ -151,6 +176,7 @@ type ProcState struct {
|
||||||
Processor int
|
Processor int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcMem contains memory statistics for a specified process
|
||||||
type ProcMem struct {
|
type ProcMem struct {
|
||||||
Size uint64
|
Size uint64
|
||||||
Resident uint64
|
Resident uint64
|
||||||
|
@ -160,6 +186,7 @@ type ProcMem struct {
|
||||||
PageFaults uint64
|
PageFaults uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcTime contains run time statistics for a specified process
|
||||||
type ProcTime struct {
|
type ProcTime struct {
|
||||||
StartTime uint64
|
StartTime uint64
|
||||||
User uint64
|
User uint64
|
||||||
|
@ -167,26 +194,31 @@ type ProcTime struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcArgs contains a list of args for a specified process
|
||||||
type ProcArgs struct {
|
type ProcArgs struct {
|
||||||
List []string
|
List []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcEnv contains a map of environment variables for specified process
|
||||||
type ProcEnv struct {
|
type ProcEnv struct {
|
||||||
Vars map[string]string
|
Vars map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcExe contains basic data about a specified process
|
||||||
type ProcExe struct {
|
type ProcExe struct {
|
||||||
Name string
|
Name string
|
||||||
Cwd string
|
Cwd string
|
||||||
Root string
|
Root string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcFDUsage contains data on file limits and usage
|
||||||
type ProcFDUsage struct {
|
type ProcFDUsage struct {
|
||||||
Open uint64
|
Open uint64
|
||||||
SoftLimit uint64
|
SoftLimit uint64
|
||||||
HardLimit uint64
|
HardLimit uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rusage contains data on resource usage for a specified process
|
||||||
type Rusage struct {
|
type Rusage struct {
|
||||||
Utime time.Duration
|
Utime time.Duration
|
||||||
Stime time.Duration
|
Stime time.Duration
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -24,11 +23,6 @@ var (
|
||||||
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
|
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
|
||||||
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
|
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
|
||||||
processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
|
processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
|
||||||
|
|
||||||
// bootTime is the time when the OS was last booted. This value may be nil
|
|
||||||
// on operating systems that do not support the WMI query used to obtain it.
|
|
||||||
bootTime *time.Time
|
|
||||||
bootTimeLock sync.Mutex
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -63,19 +57,11 @@ func (self *Uptime) Get() error {
|
||||||
if !version.IsWindowsVistaOrGreater() {
|
if !version.IsWindowsVistaOrGreater() {
|
||||||
return ErrNotImplemented{runtime.GOOS}
|
return ErrNotImplemented{runtime.GOOS}
|
||||||
}
|
}
|
||||||
|
uptimeMs, err := windows.GetTickCount64()
|
||||||
bootTimeLock.Lock()
|
if err != nil {
|
||||||
defer bootTimeLock.Unlock()
|
return errors.Wrap(err, "failed to get boot time using GetTickCount64 api")
|
||||||
if bootTime == nil {
|
|
||||||
uptime, err := windows.GetTickCount64()
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to get boot time using win32 api")
|
|
||||||
}
|
|
||||||
var boot = time.Unix(int64(uptime), 0)
|
|
||||||
bootTime = &boot
|
|
||||||
}
|
}
|
||||||
|
self.Length = float64(time.Duration(uptimeMs)*time.Millisecond) / float64(time.Second)
|
||||||
self.Length = time.Since(*bootTime).Seconds()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,8 @@
|
||||||
// Package windows contains various Windows system call.
|
// Package windows contains various Windows system call.
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
// Use "go generate -v -x ." to generate the source.
|
||||||
|
|
||||||
|
// Add -trace to enable debug prints around syscalls.
|
||||||
|
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output zsyscall_windows.go syscall_windows.go
|
||||||
|
//go:generate go run fix_generated.go -input zsyscall_windows.go
|
||||||
|
|
|
@ -580,11 +580,6 @@ func GetTickCount64() (uptime uint64, err error) {
|
||||||
return uptime, nil
|
return uptime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use "GOOS=windows go generate -v -x ." to generate the source.
|
|
||||||
|
|
||||||
// Add -trace to enable debug prints around syscalls.
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=false -output zsyscall_windows.go syscall_windows.go
|
|
||||||
|
|
||||||
// Windows API calls
|
// Windows API calls
|
||||||
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
|
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
|
||||||
//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
|
//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
|
||||||
|
|
|
@ -5,6 +5,8 @@ package windows
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
@ -35,10 +37,10 @@ func errnoErr(e syscall.Errno) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
modpsapi = syscall.NewLazyDLL("psapi.dll")
|
modpsapi = windows.NewLazySystemDLL("psapi.dll")
|
||||||
modntdll = syscall.NewLazyDLL("ntdll.dll")
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
|
||||||
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||||
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
|
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.6.2
|
- 1.13.4
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
allowed_failures:
|
allowed_failures:
|
||||||
|
@ -11,10 +11,3 @@ install:
|
||||||
- go get -d -v ./... && go install -race -v ./...
|
- go get -d -v ./... && go install -race -v ./...
|
||||||
|
|
||||||
script: go test -race -v ./...
|
script: go test -race -v ./...
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- iproute2
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ IP address of a firewall.
|
||||||
|
|
||||||
NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT.
|
NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT.
|
||||||
|
|
||||||
See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
|
See https://tools.ietf.org/rfc/rfc6886.txt
|
||||||
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp)
|
[![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp)
|
||||||
|
@ -14,27 +14,53 @@ See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
|
||||||
Get the package
|
Get the package
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
# Get the go-nat-pmp package.
|
||||||
go get -u github.com/jackpal/go-nat-pmp
|
go get -u github.com/jackpal/go-nat-pmp
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
Get one more package, used by the example code:
|
||||||
|
|
||||||
|
go get -u github.com/jackpal/gateway
|
||||||
|
|
||||||
|
Create a directory:
|
||||||
|
|
||||||
|
cd ~/go
|
||||||
|
mkdir -p src/hello
|
||||||
|
cd src/hello
|
||||||
|
|
||||||
|
Create a file hello.go with these contents:
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/jackpal/gateway"
|
"github.com/jackpal/gateway"
|
||||||
natpmp "github.com/jackpal/go-nat-pmp"
|
natpmp "github.com/jackpal/go-nat-pmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
gatewayIP, err = gateway.DiscoverGateway()
|
func main() {
|
||||||
if err != nil {
|
gatewayIP, err := gateway.DiscoverGateway()
|
||||||
return
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client := natpmp.NewClient(gatewayIP)
|
||||||
|
response, err := client.GetExternalAddress()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("External IP address: %v\n", response.ExternalIPAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := natpmp.NewClient(gatewayIP)
|
Build the example
|
||||||
response, err := client.GetExternalAddress()
|
|
||||||
if err != nil {
|
go build
|
||||||
return
|
./hello
|
||||||
}
|
|
||||||
print("External IP address:", response.ExternalIPAddress)
|
External IP address: [www xxx yyy zzz]
|
||||||
|
|
||||||
Clients
|
Clients
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -3,34 +3,43 @@ package natpmp
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
|
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
|
||||||
// routers such as DD-WRT and Tomato.
|
// routers such as DD-WRT and Tomato.
|
||||||
//
|
//
|
||||||
// See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
|
// See https://tools.ietf.org/rfc/rfc6886.txt
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
//
|
//
|
||||||
// client := natpmp.NewClient(gatewayIP)
|
// client := natpmp.NewClient(gatewayIP)
|
||||||
// response, err := client.GetExternalAddress()
|
// response, err := client.GetExternalAddress()
|
||||||
|
|
||||||
// The recommended mapping lifetime for AddPortMapping
|
// The recommended mapping lifetime for AddPortMapping.
|
||||||
const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600
|
const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600
|
||||||
|
|
||||||
// Interface used to make remote procedure calls.
|
// Interface used to make remote procedure calls.
|
||||||
type caller interface {
|
type caller interface {
|
||||||
call(msg []byte) (result []byte, err error)
|
call(msg []byte, timeout time.Duration) (result []byte, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is a NAT-PMP protocol client.
|
// Client is a NAT-PMP protocol client.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
caller caller
|
caller caller
|
||||||
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a NAT-PMP client for the NAT-PMP server at the gateway.
|
// Create a NAT-PMP client for the NAT-PMP server at the gateway.
|
||||||
|
// Uses default timeout which is around 128 seconds.
|
||||||
func NewClient(gateway net.IP) (nat *Client) {
|
func NewClient(gateway net.IP) (nat *Client) {
|
||||||
return &Client{&network{gateway}}
|
return &Client{&network{gateway}, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a NAT-PMP client for the NAT-PMP server at the gateway, with a timeout.
|
||||||
|
// Timeout defines the total amount of time we will keep retrying before giving up.
|
||||||
|
func NewClientWithTimeout(gateway net.IP, timeout time.Duration) (nat *Client) {
|
||||||
|
return &Client{&network{gateway}, timeout}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Results of the NAT-PMP GetExternalAddress operation.
|
// Results of the NAT-PMP GetExternalAddress operation.
|
||||||
|
@ -40,6 +49,8 @@ type GetExternalAddressResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the external address of the router.
|
// Get the external address of the router.
|
||||||
|
//
|
||||||
|
// Note that this call can take up to 128 seconds to return.
|
||||||
func (n *Client) GetExternalAddress() (result *GetExternalAddressResult, err error) {
|
func (n *Client) GetExternalAddress() (result *GetExternalAddressResult, err error) {
|
||||||
msg := make([]byte, 2)
|
msg := make([]byte, 2)
|
||||||
msg[0] = 0 // Version 0
|
msg[0] = 0 // Version 0
|
||||||
|
@ -62,7 +73,8 @@ type AddPortMappingResult struct {
|
||||||
PortMappingLifetimeInSeconds uint32
|
PortMappingLifetimeInSeconds uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0
|
// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0.
|
||||||
|
// Note that this call can take up to 128 seconds to return.
|
||||||
func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) {
|
func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) {
|
||||||
var opcode byte
|
var opcode byte
|
||||||
if protocol == "udp" {
|
if protocol == "udp" {
|
||||||
|
@ -76,6 +88,7 @@ func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternal
|
||||||
msg := make([]byte, 12)
|
msg := make([]byte, 12)
|
||||||
msg[0] = 0 // Version 0
|
msg[0] = 0 // Version 0
|
||||||
msg[1] = opcode
|
msg[1] = opcode
|
||||||
|
// [2:3] is reserved.
|
||||||
writeNetworkOrderUint16(msg[4:6], uint16(internalPort))
|
writeNetworkOrderUint16(msg[4:6], uint16(internalPort))
|
||||||
writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort))
|
writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort))
|
||||||
writeNetworkOrderUint32(msg[8:12], uint32(lifetime))
|
writeNetworkOrderUint32(msg[8:12], uint32(lifetime))
|
||||||
|
@ -92,7 +105,7 @@ func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
|
func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
|
||||||
result, err = n.caller.call(msg)
|
result, err = n.caller.call(msg, n.timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package natpmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -16,7 +15,7 @@ type network struct {
|
||||||
gateway net.IP
|
gateway net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) call(msg []byte) (result []byte, err error) {
|
func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err error) {
|
||||||
var server net.UDPAddr
|
var server net.UDPAddr
|
||||||
server.IP = n.gateway
|
server.IP = n.gateway
|
||||||
server.Port = nAT_PMP_PORT
|
server.Port = nAT_PMP_PORT
|
||||||
|
@ -29,12 +28,18 @@ func (n *network) call(msg []byte) (result []byte, err error) {
|
||||||
// 16 bytes is the maximum result size.
|
// 16 bytes is the maximum result size.
|
||||||
result = make([]byte, 16)
|
result = make([]byte, 16)
|
||||||
|
|
||||||
|
var finalTimeout time.Time
|
||||||
|
if timeout != 0 {
|
||||||
|
finalTimeout = time.Now().Add(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
needNewDeadline := true
|
needNewDeadline := true
|
||||||
|
|
||||||
var tries uint
|
var tries uint
|
||||||
for tries = 0; tries < nAT_TRIES; {
|
for tries = 0; (tries < nAT_TRIES && finalTimeout.IsZero()) || time.Now().Before(finalTimeout); {
|
||||||
if needNewDeadline {
|
if needNewDeadline {
|
||||||
err = conn.SetDeadline(time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond))
|
nextDeadline := time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond)
|
||||||
|
err = conn.SetDeadline(minTime(nextDeadline, finalTimeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -56,7 +61,6 @@ func (n *network) call(msg []byte) (result []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !remoteAddr.IP.Equal(n.gateway) {
|
if !remoteAddr.IP.Equal(n.gateway) {
|
||||||
log.Printf("Ignoring packet because IPs differ:", remoteAddr, n.gateway)
|
|
||||||
// Ignore this packet.
|
// Ignore this packet.
|
||||||
// Continue without increasing retransmission timeout or deadline.
|
// Continue without increasing retransmission timeout or deadline.
|
||||||
continue
|
continue
|
||||||
|
@ -70,3 +74,16 @@ func (n *network) call(msg []byte) (result []byte, err error) {
|
||||||
err = fmt.Errorf("Timed out trying to contact gateway")
|
err = fmt.Errorf("Timed out trying to contact gateway")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func minTime(a, b time.Time) time.Time {
|
||||||
|
if a.IsZero() {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
if b.IsZero() {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
if a.Before(b) {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package natpmp
|
package natpmp
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type callObserver interface {
|
type callObserver interface {
|
||||||
observeCall(msg []byte, result []byte, err error)
|
observeCall(msg []byte, result []byte, err error)
|
||||||
}
|
}
|
||||||
|
@ -10,8 +12,8 @@ type recorder struct {
|
||||||
observer callObserver
|
observer callObserver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *recorder) call(msg []byte) (result []byte, err error) {
|
func (n *recorder) call(msg []byte, timeout time.Duration) (result []byte, err error) {
|
||||||
result, err = n.child.call(msg)
|
result, err = n.child.call(msg, timeout)
|
||||||
n.observer.observeCall(msg, result, err)
|
n.observer.observeCall(msg, result, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.9
|
|
||||||
- "1.10"
|
- "1.10"
|
||||||
|
- "1.11"
|
||||||
|
- "1.12"
|
||||||
- tip
|
- tip
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
|
|
@ -5,8 +5,8 @@ as defined by http://www.w3.org/TR/cors/
|
||||||
You can configure it by passing an option struct to cors.New:
|
You can configure it by passing an option struct to cors.New:
|
||||||
|
|
||||||
c := cors.New(cors.Options{
|
c := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"foo.com"},
|
AllowedOrigins: []string{"foo.com"},
|
||||||
AllowedMethods: []string{"GET", "POST", "DELETE"},
|
AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodDelete},
|
||||||
AllowCredentials: true,
|
AllowCredentials: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -69,10 +69,15 @@ type Options struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger generic interface for logger
|
||||||
|
type Logger interface {
|
||||||
|
Printf(string, ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
// Cors http handler
|
// Cors http handler
|
||||||
type Cors struct {
|
type Cors struct {
|
||||||
// Debug logger
|
// Debug logger
|
||||||
Log *log.Logger
|
Log Logger
|
||||||
// Normalized list of plain allowed origins
|
// Normalized list of plain allowed origins
|
||||||
allowedOrigins []string
|
allowedOrigins []string
|
||||||
// List of allowed origins containing wildcards
|
// List of allowed origins containing wildcards
|
||||||
|
@ -106,7 +111,7 @@ func New(options Options) *Cors {
|
||||||
maxAge: options.MaxAge,
|
maxAge: options.MaxAge,
|
||||||
optionPassthrough: options.OptionsPassthrough,
|
optionPassthrough: options.OptionsPassthrough,
|
||||||
}
|
}
|
||||||
if options.Debug {
|
if options.Debug && c.Log == nil {
|
||||||
c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags)
|
c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +166,7 @@ func New(options Options) *Cors {
|
||||||
// Allowed Methods
|
// Allowed Methods
|
||||||
if len(options.AllowedMethods) == 0 {
|
if len(options.AllowedMethods) == 0 {
|
||||||
// Default is spec's "simple" methods
|
// Default is spec's "simple" methods
|
||||||
c.allowedMethods = []string{"GET", "POST", "HEAD"}
|
c.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead}
|
||||||
} else {
|
} else {
|
||||||
c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper)
|
c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper)
|
||||||
}
|
}
|
||||||
|
@ -178,8 +183,15 @@ func Default() *Cors {
|
||||||
// origins with all standard methods with any header and credentials.
|
// origins with all standard methods with any header and credentials.
|
||||||
func AllowAll() *Cors {
|
func AllowAll() *Cors {
|
||||||
return New(Options{
|
return New(Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
AllowedMethods: []string{"HEAD", "GET", "POST", "PUT", "PATCH", "DELETE"},
|
AllowedMethods: []string{
|
||||||
|
http.MethodHead,
|
||||||
|
http.MethodGet,
|
||||||
|
http.MethodPost,
|
||||||
|
http.MethodPut,
|
||||||
|
http.MethodPatch,
|
||||||
|
http.MethodDelete,
|
||||||
|
},
|
||||||
AllowedHeaders: []string{"*"},
|
AllowedHeaders: []string{"*"},
|
||||||
AllowCredentials: false,
|
AllowCredentials: false,
|
||||||
})
|
})
|
||||||
|
@ -304,10 +316,6 @@ func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
headers := w.Header()
|
headers := w.Header()
|
||||||
origin := r.Header.Get("Origin")
|
origin := r.Header.Get("Origin")
|
||||||
|
|
||||||
if r.Method == http.MethodOptions {
|
|
||||||
c.logf(" Actual request no headers added: method == %s", r.Method)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Always set Vary, see https://github.com/rs/cors/issues/10
|
// Always set Vary, see https://github.com/rs/cors/issues/10
|
||||||
headers.Add("Vary", "Origin")
|
headers.Add("Vary", "Origin")
|
||||||
if origin == "" {
|
if origin == "" {
|
||||||
|
@ -342,7 +350,7 @@ func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
c.logf(" Actual response added headers: %v", headers)
|
c.logf(" Actual response added headers: %v", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// convenience method. checks if debugging is turned on before printing
|
// convenience method. checks if a logger is set.
|
||||||
func (c *Cors) logf(format string, a ...interface{}) {
|
func (c *Cors) logf(format string, a ...interface{}) {
|
||||||
if c.Log != nil {
|
if c.Log != nil {
|
||||||
c.Log.Printf(format, a...)
|
c.Log.Printf(format, a...)
|
||||||
|
|
|
@ -12,7 +12,7 @@ type wildcard struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w wildcard) match(s string) bool {
|
func (w wildcard) match(s string) bool {
|
||||||
return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)
|
return len(s) >= len(w.prefix)+len(w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert converts a list of string using the passed converter function
|
// convert converts a list of string using the passed converter function
|
||||||
|
|
|
@ -2,29 +2,102 @@ package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/waku"
|
||||||
"github.com/status-im/status-go/whisper/v6"
|
"github.com/status-im/status-go/whisper/v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gethEnvelopeWrapper struct {
|
type whisperEnvelope struct {
|
||||||
envelope *whisper.Envelope
|
env *whisper.Envelope
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethEnvelopeWrapper returns an object that wraps Geth's Envelope in a types interface
|
// NewWhisperEnvelope returns an object that wraps Geth's Whisper Envelope in a types interface.
|
||||||
func NewGethEnvelopeWrapper(e *whisper.Envelope) types.Envelope {
|
func NewWhisperEnvelope(e *whisper.Envelope) types.Envelope {
|
||||||
return &gethEnvelopeWrapper{
|
return &whisperEnvelope{env: e}
|
||||||
envelope: e,
|
}
|
||||||
|
|
||||||
|
func UnwrapWhisperEnvelope(e types.Envelope) (*whisper.Envelope, bool) {
|
||||||
|
if env, ok := e.(*whisperEnvelope); ok {
|
||||||
|
return env.env, true
|
||||||
}
|
}
|
||||||
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGethEnvelopeFrom retrieves the underlying whisper Envelope struct from a wrapped Envelope interface
|
func MustUnwrapWhisperEnvelope(e types.Envelope) *whisper.Envelope {
|
||||||
func GetGethEnvelopeFrom(f types.Envelope) *whisper.Envelope {
|
return e.(*whisperEnvelope).env
|
||||||
return f.(*gethEnvelopeWrapper).envelope
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Hash() types.Hash {
|
func (w *whisperEnvelope) Hash() types.Hash {
|
||||||
return types.Hash(w.envelope.Hash())
|
return types.Hash(w.env.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Bloom() []byte {
|
func (w *whisperEnvelope) Bloom() []byte {
|
||||||
return w.envelope.Bloom()
|
return w.env.Bloom()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) PoW() float64 {
|
||||||
|
return w.env.PoW()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Expiry() uint32 {
|
||||||
|
return w.env.Expiry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) TTL() uint32 {
|
||||||
|
return w.env.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Topic() types.TopicType {
|
||||||
|
return types.TopicType(w.env.Topic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whisperEnvelope) Size() int {
|
||||||
|
return len(w.env.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
type wakuEnvelope struct {
|
||||||
|
env *waku.Envelope
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWakuEnvelope returns an object that wraps Geth's Waku Envelope in a types interface.
|
||||||
|
func NewWakuEnvelope(e *waku.Envelope) types.Envelope {
|
||||||
|
return &wakuEnvelope{env: e}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnwrapWakuEnvelope(e types.Envelope) (*waku.Envelope, bool) {
|
||||||
|
if env, ok := e.(*wakuEnvelope); ok {
|
||||||
|
return env.env, true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustUnwrapWakuEnvelope(e types.Envelope) *waku.Envelope {
|
||||||
|
return e.(*wakuEnvelope).env
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Hash() types.Hash {
|
||||||
|
return types.Hash(w.env.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Bloom() []byte {
|
||||||
|
return w.env.Bloom()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) PoW() float64 {
|
||||||
|
return w.env.PoW()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Expiry() uint32 {
|
||||||
|
return w.env.Expiry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) TTL() uint32 {
|
||||||
|
return w.env.TTL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Topic() types.TopicType {
|
||||||
|
return types.TopicType(w.env.Topic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wakuEnvelope) Size() int {
|
||||||
|
return len(w.env.Data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r types.Messages
|
||||||
// which are not supposed to be forwarded any further.
|
// which are not supposed to be forwarded any further.
|
||||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||||
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||||
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, GetGethEnvelopeFrom(envelope), timeout)
|
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, MustUnwrapWhisperEnvelope(envelope), timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||||
|
|
|
@ -5,6 +5,11 @@ package types
|
||||||
type Envelope interface {
|
type Envelope interface {
|
||||||
Hash() Hash // Cached hash of the envelope to avoid rehashing every time.
|
Hash() Hash // Cached hash of the envelope to avoid rehashing every time.
|
||||||
Bloom() []byte
|
Bloom() []byte
|
||||||
|
PoW() float64
|
||||||
|
Expiry() uint32
|
||||||
|
TTL() uint32
|
||||||
|
Topic() TopicType
|
||||||
|
Size() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventType used to define known envelope events.
|
// EventType used to define known envelope events.
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (h Hash) Bytes() []byte { return h[:] }
|
||||||
|
|
||||||
// String implements the stringer interface and is used also by the logger when
|
// String implements the stringer interface and is used also by the logger when
|
||||||
// doing full logging into a file.
|
// doing full logging into a file.
|
||||||
func (h *Hash) String() string {
|
func (h Hash) String() string {
|
||||||
return h.Hex()
|
return h.Hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,14 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||||
|
@ -30,12 +32,16 @@ github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85Sx
|
||||||
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
|
||||||
|
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||||
|
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 h1:tS7jSmwRqSxTnonTRlDD1oHo6Q9YOK4xHS9/v4L56eg=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
|
||||||
|
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||||
|
@ -137,6 +143,7 @@ github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
|
||||||
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
|
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
|
||||||
|
@ -209,6 +216,7 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
|
@ -224,6 +232,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||||
|
@ -241,11 +250,13 @@ github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQ
|
||||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
||||||
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
||||||
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
||||||
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
||||||
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
||||||
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
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/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
||||||
|
@ -268,6 +279,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||||
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.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
|
||||||
|
@ -279,6 +292,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
@ -428,6 +442,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||||
|
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
@ -440,17 +456,20 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/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 v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
||||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
@ -461,12 +480,14 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
|
@ -482,6 +503,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ=
|
||||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU=
|
||||||
|
@ -531,6 +553,7 @@ github.com/status-im/status-go v0.37.3/go.mod h1:9qHQ2+8NS6ivPJS5YbsI3gWkr0t6DWm
|
||||||
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
|
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
|
||||||
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
||||||
github.com/status-im/status-go/protocol v1.0.1/go.mod h1:LpA7BsaNmj6EOdq7BwuqncewjPqIRHCletZOb2wlWrY=
|
github.com/status-im/status-go/protocol v1.0.1/go.mod h1:LpA7BsaNmj6EOdq7BwuqncewjPqIRHCletZOb2wlWrY=
|
||||||
|
github.com/status-im/status-go/waku v1.0.0/go.mod h1:1bjvQAL4cJYtxCsm6DnKdJbxcZwnvvZmxb6pmoUDtuY=
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
||||||
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
|
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
|
||||||
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
||||||
|
@ -553,7 +576,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||||
|
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
|
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
||||||
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||||
|
@ -583,6 +609,8 @@ github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVT
|
||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||||
|
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
@ -609,6 +637,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -620,6 +649,7 @@ golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIo
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
@ -647,6 +677,7 @@ golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
|
||||||
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -673,12 +704,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
|
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
|
||||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
||||||
|
@ -700,7 +734,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190912185636-87d9f09c5d89/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-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-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
||||||
|
@ -721,7 +757,9 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
@ -733,6 +771,11 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||||
|
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||||
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
|
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
|
@ -740,6 +783,7 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHN
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
||||||
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
||||||
|
@ -754,5 +798,6 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
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-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-20190106161140-3f1c8253044a/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 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
|
|
@ -0,0 +1,600 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// List of errors
|
||||||
|
var (
|
||||||
|
ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key")
|
||||||
|
ErrInvalidSymmetricKey = errors.New("invalid symmetric key")
|
||||||
|
ErrInvalidPublicKey = errors.New("invalid public key")
|
||||||
|
ErrInvalidSigningPubKey = errors.New("invalid signing public key")
|
||||||
|
ErrTooLowPoW = errors.New("message rejected, PoW too low")
|
||||||
|
ErrNoTopics = errors.New("missing topic(s)")
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicWakuAPI provides the waku RPC service that can be
|
||||||
|
// use publicly without security implications.
|
||||||
|
type PublicWakuAPI struct {
|
||||||
|
w *Waku
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
lastUsed map[string]time.Time // keeps track when a filter was polled for the last time.
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPublicWakuAPI create a new RPC waku service.
|
||||||
|
func NewPublicWakuAPI(w *Waku) *PublicWakuAPI {
|
||||||
|
api := &PublicWakuAPI{
|
||||||
|
w: w,
|
||||||
|
lastUsed: make(map[string]time.Time),
|
||||||
|
}
|
||||||
|
return api
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns the Waku sub-protocol version.
|
||||||
|
func (api *PublicWakuAPI) Version(ctx context.Context) string {
|
||||||
|
return ProtocolVersionStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info contains diagnostic information.
|
||||||
|
type Info struct {
|
||||||
|
Messages int `json:"messages"` // Number of floating messages.
|
||||||
|
MinPow float64 `json:"minPow"` // Minimal accepted PoW
|
||||||
|
MaxMessageSize uint32 `json:"maxMessageSize"` // Maximum accepted message size
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info returns diagnostic information about the waku node.
|
||||||
|
func (api *PublicWakuAPI) Info(ctx context.Context) Info {
|
||||||
|
return Info{
|
||||||
|
Messages: len(api.w.msgQueue) + len(api.w.p2pMsgQueue),
|
||||||
|
MinPow: api.w.MinPow(),
|
||||||
|
MaxMessageSize: api.w.MaxMessageSize(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMaxMessageSize sets the maximum message size that is accepted.
|
||||||
|
// Upper limit is defined by MaxMessageSize.
|
||||||
|
func (api *PublicWakuAPI) SetMaxMessageSize(ctx context.Context, size uint32) (bool, error) {
|
||||||
|
return true, api.w.SetMaxMessageSize(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMinPoW sets the minimum PoW, and notifies the peers.
|
||||||
|
func (api *PublicWakuAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) {
|
||||||
|
return true, api.w.SetMinimumPoW(pow, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBloomFilter sets the new value of bloom filter, and notifies the peers.
|
||||||
|
func (api *PublicWakuAPI) SetBloomFilter(ctx context.Context, bloom hexutil.Bytes) (bool, error) {
|
||||||
|
return true, api.w.SetBloomFilter(bloom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkTrustedPeer marks a peer trusted, which will allow it to send historic (expired) messages.
|
||||||
|
// Note: This function is not adding new nodes, the node needs to exists as a peer.
|
||||||
|
func (api *PublicWakuAPI) MarkTrustedPeer(ctx context.Context, url string) (bool, error) {
|
||||||
|
n, err := enode.Parse(enode.ValidSchemes, url)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, api.w.AllowP2PMessagesFromPeer(n.ID().Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyPair generates a new public and private key pair for message decryption and encryption.
|
||||||
|
// It returns an ID that can be used to refer to the keypair.
|
||||||
|
func (api *PublicWakuAPI) NewKeyPair(ctx context.Context) (string, error) {
|
||||||
|
return api.w.NewKeyPair()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPrivateKey imports the given private key.
|
||||||
|
func (api *PublicWakuAPI) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) {
|
||||||
|
key, err := crypto.ToECDSA(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return api.w.AddKeyPair(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKeyPair removes the key with the given key if it exists.
|
||||||
|
func (api *PublicWakuAPI) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
|
||||||
|
if ok := api.w.DeleteKeyPair(key); ok {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, fmt.Errorf("key pair %s not found", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasKeyPair returns an indication if the node has a key pair that is associated with the given id.
|
||||||
|
func (api *PublicWakuAPI) HasKeyPair(ctx context.Context, id string) bool {
|
||||||
|
return api.w.HasKeyPair(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPublicKey returns the public key associated with the given key. The key is the hex
|
||||||
|
// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
|
||||||
|
func (api *PublicWakuAPI) GetPublicKey(ctx context.Context, id string) (hexutil.Bytes, error) {
|
||||||
|
key, err := api.w.GetPrivateKey(id)
|
||||||
|
if err != nil {
|
||||||
|
return hexutil.Bytes{}, err
|
||||||
|
}
|
||||||
|
return crypto.FromECDSAPub(&key.PublicKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPrivateKey returns the private key associated with the given key. The key is the hex
|
||||||
|
// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
|
||||||
|
func (api *PublicWakuAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) {
|
||||||
|
key, err := api.w.GetPrivateKey(id)
|
||||||
|
if err != nil {
|
||||||
|
return hexutil.Bytes{}, err
|
||||||
|
}
|
||||||
|
return crypto.FromECDSA(key), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSymKey generate a random symmetric key.
|
||||||
|
// It returns an ID that can be used to refer to the key.
|
||||||
|
// Can be used encrypting and decrypting messages where the key is known to both parties.
|
||||||
|
func (api *PublicWakuAPI) NewSymKey(ctx context.Context) (string, error) {
|
||||||
|
return api.w.GenerateSymKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSymKey import a symmetric key.
|
||||||
|
// It returns an ID that can be used to refer to the key.
|
||||||
|
// Can be used encrypting and decrypting messages where the key is known to both parties.
|
||||||
|
func (api *PublicWakuAPI) AddSymKey(ctx context.Context, key hexutil.Bytes) (string, error) {
|
||||||
|
return api.w.AddSymKeyDirect([]byte(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateSymKeyFromPassword derive a key from the given password, stores it, and returns its ID.
|
||||||
|
func (api *PublicWakuAPI) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||||
|
return api.w.AddSymKeyFromPassword(passwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasSymKey returns an indication if the node has a symmetric key associated with the given key.
|
||||||
|
func (api *PublicWakuAPI) HasSymKey(ctx context.Context, id string) bool {
|
||||||
|
return api.w.HasSymKey(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSymKey returns the symmetric key associated with the given id.
|
||||||
|
func (api *PublicWakuAPI) GetSymKey(ctx context.Context, id string) (hexutil.Bytes, error) {
|
||||||
|
return api.w.GetSymKey(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSymKey deletes the symmetric key that is associated with the given id.
|
||||||
|
func (api *PublicWakuAPI) DeleteSymKey(ctx context.Context, id string) bool {
|
||||||
|
return api.w.DeleteSymKey(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeLightClient turns the node into light client, which does not forward
|
||||||
|
// any incoming messages, and sends only messages originated in this node.
|
||||||
|
func (api *PublicWakuAPI) MakeLightClient(ctx context.Context) bool {
|
||||||
|
api.w.SetLightClientMode(true)
|
||||||
|
return api.w.LightClientMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelLightClient cancels light client mode.
|
||||||
|
func (api *PublicWakuAPI) CancelLightClient(ctx context.Context) bool {
|
||||||
|
api.w.SetLightClientMode(false)
|
||||||
|
return !api.w.LightClientMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go
|
||||||
|
|
||||||
|
// NewMessage represents a new waku message that is posted through the RPC.
|
||||||
|
type NewMessage struct {
|
||||||
|
SymKeyID string `json:"symKeyID"`
|
||||||
|
PublicKey []byte `json:"pubKey"`
|
||||||
|
Sig string `json:"sig"`
|
||||||
|
TTL uint32 `json:"ttl"`
|
||||||
|
Topic TopicType `json:"topic"`
|
||||||
|
Payload []byte `json:"payload"`
|
||||||
|
Padding []byte `json:"padding"`
|
||||||
|
PowTime uint32 `json:"powTime"`
|
||||||
|
PowTarget float64 `json:"powTarget"`
|
||||||
|
TargetPeer string `json:"targetPeer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type newMessageOverride struct {
|
||||||
|
PublicKey hexutil.Bytes
|
||||||
|
Payload hexutil.Bytes
|
||||||
|
Padding hexutil.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post posts a message on the Waku network.
|
||||||
|
// returns the hash of the message in case of success.
|
||||||
|
func (api *PublicWakuAPI) Post(ctx context.Context, req NewMessage) (hexutil.Bytes, error) {
|
||||||
|
var (
|
||||||
|
symKeyGiven = len(req.SymKeyID) > 0
|
||||||
|
pubKeyGiven = len(req.PublicKey) > 0
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// user must specify either a symmetric or an asymmetric key
|
||||||
|
if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
|
||||||
|
return nil, ErrSymAsym
|
||||||
|
}
|
||||||
|
|
||||||
|
params := &MessageParams{
|
||||||
|
TTL: req.TTL,
|
||||||
|
Payload: req.Payload,
|
||||||
|
Padding: req.Padding,
|
||||||
|
WorkTime: req.PowTime,
|
||||||
|
PoW: req.PowTarget,
|
||||||
|
Topic: req.Topic,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set key that is used to sign the message
|
||||||
|
if len(req.Sig) > 0 {
|
||||||
|
if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set symmetric key that is used to encrypt the message
|
||||||
|
if symKeyGiven {
|
||||||
|
if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption
|
||||||
|
return nil, ErrNoTopics
|
||||||
|
}
|
||||||
|
if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !validateDataIntegrity(params.KeySym, aesKeyLength) {
|
||||||
|
return nil, ErrInvalidSymmetricKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set asymmetric key that is used to encrypt the message
|
||||||
|
if pubKeyGiven {
|
||||||
|
if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil {
|
||||||
|
return nil, ErrInvalidPublicKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt and sent message
|
||||||
|
msg, err := NewSentMessage(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []byte
|
||||||
|
env, err := msg.Wrap(params, api.w.CurrentTime())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// send to specific node (skip PoW check)
|
||||||
|
if len(req.TargetPeer) > 0 {
|
||||||
|
n, err := enode.Parse(enode.ValidSchemes, req.TargetPeer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse target peer: %s", err)
|
||||||
|
}
|
||||||
|
err = api.w.SendP2PMessages(n.ID().Bytes(), env)
|
||||||
|
if err == nil {
|
||||||
|
hash := env.Hash()
|
||||||
|
result = hash[:]
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the message PoW meets the node's minimum accepted PoW
|
||||||
|
if req.PowTarget < api.w.MinPow() {
|
||||||
|
return nil, ErrTooLowPoW
|
||||||
|
}
|
||||||
|
|
||||||
|
err = api.w.Send(env)
|
||||||
|
if err == nil {
|
||||||
|
hash := env.Hash()
|
||||||
|
result = hash[:]
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UninstallFilter is alias for Unsubscribe
|
||||||
|
func (api *PublicWakuAPI) UninstallFilter(id string) {
|
||||||
|
api.w.Unsubscribe(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsubscribe disables and removes an existing filter.
|
||||||
|
func (api *PublicWakuAPI) Unsubscribe(id string) {
|
||||||
|
api.w.Unsubscribe(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go
|
||||||
|
|
||||||
|
// Criteria holds various filter options for inbound messages.
|
||||||
|
type Criteria struct {
|
||||||
|
SymKeyID string `json:"symKeyID"`
|
||||||
|
PrivateKeyID string `json:"privateKeyID"`
|
||||||
|
Sig []byte `json:"sig"`
|
||||||
|
MinPow float64 `json:"minPow"`
|
||||||
|
Topics []TopicType `json:"topics"`
|
||||||
|
AllowP2P bool `json:"allowP2P"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type criteriaOverride struct {
|
||||||
|
Sig hexutil.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Messages set up a subscription that fires events when messages arrive that match
|
||||||
|
// the given set of criteria.
|
||||||
|
func (api *PublicWakuAPI) Messages(ctx context.Context, crit Criteria) (*rpc.Subscription, error) {
|
||||||
|
var (
|
||||||
|
symKeyGiven = len(crit.SymKeyID) > 0
|
||||||
|
pubKeyGiven = len(crit.PrivateKeyID) > 0
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// ensure that the RPC connection supports subscriptions
|
||||||
|
notifier, supported := rpc.NotifierFromContext(ctx)
|
||||||
|
if !supported {
|
||||||
|
return nil, rpc.ErrNotificationsUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
// user must specify either a symmetric or an asymmetric key
|
||||||
|
if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
|
||||||
|
return nil, ErrSymAsym
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := Filter{
|
||||||
|
PoW: crit.MinPow,
|
||||||
|
Messages: NewMemoryMessageStore(),
|
||||||
|
AllowP2P: crit.AllowP2P,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(crit.Sig) > 0 {
|
||||||
|
if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil {
|
||||||
|
return nil, ErrInvalidSigningPubKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, bt := range crit.Topics {
|
||||||
|
if len(bt) == 0 || len(bt) > 4 {
|
||||||
|
return nil, fmt.Errorf("subscribe: topic %d has wrong size: %d", i, len(bt))
|
||||||
|
}
|
||||||
|
filter.Topics = append(filter.Topics, bt[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// listen for message that are encrypted with the given symmetric key
|
||||||
|
if symKeyGiven {
|
||||||
|
if len(filter.Topics) == 0 {
|
||||||
|
return nil, ErrNoTopics
|
||||||
|
}
|
||||||
|
key, err := api.w.GetSymKey(crit.SymKeyID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !validateDataIntegrity(key, aesKeyLength) {
|
||||||
|
return nil, ErrInvalidSymmetricKey
|
||||||
|
}
|
||||||
|
filter.KeySym = key
|
||||||
|
filter.SymKeyHash = crypto.Keccak256Hash(filter.KeySym)
|
||||||
|
}
|
||||||
|
|
||||||
|
// listen for messages that are encrypted with the given public key
|
||||||
|
if pubKeyGiven {
|
||||||
|
filter.KeyAsym, err = api.w.GetPrivateKey(crit.PrivateKeyID)
|
||||||
|
if err != nil || filter.KeyAsym == nil {
|
||||||
|
return nil, ErrInvalidPublicKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := api.w.Subscribe(&filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create subscription and start waiting for message events
|
||||||
|
rpcSub := notifier.CreateSubscription()
|
||||||
|
go func() {
|
||||||
|
// for now poll internally, refactor waku internal for channel support
|
||||||
|
ticker := time.NewTicker(250 * time.Millisecond)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
if filter := api.w.GetFilter(id); filter != nil {
|
||||||
|
for _, rpcMessage := range toMessage(filter.Retrieve()) {
|
||||||
|
if err := notifier.Notify(rpcSub.ID, rpcMessage); err != nil {
|
||||||
|
log.Error("Failed to send notification", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-rpcSub.Err():
|
||||||
|
_ = api.w.Unsubscribe(id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return rpcSub, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:generate gencodec -type Message -field-override messageOverride -out gen_message_json.go
|
||||||
|
|
||||||
|
// Message is the RPC representation of a waku message.
|
||||||
|
type Message struct {
|
||||||
|
Sig []byte `json:"sig,omitempty"`
|
||||||
|
TTL uint32 `json:"ttl"`
|
||||||
|
Timestamp uint32 `json:"timestamp"`
|
||||||
|
Topic TopicType `json:"topic"`
|
||||||
|
Payload []byte `json:"payload"`
|
||||||
|
Padding []byte `json:"padding"`
|
||||||
|
PoW float64 `json:"pow"`
|
||||||
|
Hash []byte `json:"hash"`
|
||||||
|
Dst []byte `json:"recipientPublicKey,omitempty"`
|
||||||
|
P2P bool `json:"bool,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageOverride struct {
|
||||||
|
Sig hexutil.Bytes
|
||||||
|
Payload hexutil.Bytes
|
||||||
|
Padding hexutil.Bytes
|
||||||
|
Hash hexutil.Bytes
|
||||||
|
Dst hexutil.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToWakuMessage converts an internal message into an API version.
|
||||||
|
func ToWakuMessage(message *ReceivedMessage) *Message {
|
||||||
|
msg := Message{
|
||||||
|
Payload: message.Payload,
|
||||||
|
Padding: message.Padding,
|
||||||
|
Timestamp: message.Sent,
|
||||||
|
TTL: message.TTL,
|
||||||
|
PoW: message.PoW,
|
||||||
|
Hash: message.EnvelopeHash.Bytes(),
|
||||||
|
Topic: message.Topic,
|
||||||
|
P2P: message.P2P,
|
||||||
|
}
|
||||||
|
|
||||||
|
if message.Dst != nil {
|
||||||
|
b := crypto.FromECDSAPub(message.Dst)
|
||||||
|
if b != nil {
|
||||||
|
msg.Dst = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isMessageSigned(message.Raw[0]) {
|
||||||
|
b := crypto.FromECDSAPub(message.SigToPubKey())
|
||||||
|
if b != nil {
|
||||||
|
msg.Sig = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// toMessage converts a set of messages to its RPC representation.
|
||||||
|
func toMessage(messages []*ReceivedMessage) []*Message {
|
||||||
|
msgs := make([]*Message, len(messages))
|
||||||
|
for i, msg := range messages {
|
||||||
|
msgs[i] = ToWakuMessage(msg)
|
||||||
|
}
|
||||||
|
return msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFilterMessages returns the messages that match the filter criteria and
|
||||||
|
// are received between the last poll and now.
|
||||||
|
func (api *PublicWakuAPI) GetFilterMessages(id string) ([]*Message, error) {
|
||||||
|
api.mu.Lock()
|
||||||
|
f := api.w.GetFilter(id)
|
||||||
|
if f == nil {
|
||||||
|
api.mu.Unlock()
|
||||||
|
return nil, fmt.Errorf("filter not found")
|
||||||
|
}
|
||||||
|
api.lastUsed[id] = time.Now()
|
||||||
|
api.mu.Unlock()
|
||||||
|
|
||||||
|
receivedMessages := f.Retrieve()
|
||||||
|
messages := make([]*Message, 0, len(receivedMessages))
|
||||||
|
for _, msg := range receivedMessages {
|
||||||
|
messages = append(messages, ToWakuMessage(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMessageFilter deletes a filter.
|
||||||
|
func (api *PublicWakuAPI) DeleteMessageFilter(id string) (bool, error) {
|
||||||
|
api.mu.Lock()
|
||||||
|
defer api.mu.Unlock()
|
||||||
|
|
||||||
|
delete(api.lastUsed, id)
|
||||||
|
return true, api.w.Unsubscribe(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessageFilter creates a new filter that can be used to poll for
|
||||||
|
// (new) messages that satisfy the given criteria.
|
||||||
|
func (api *PublicWakuAPI) NewMessageFilter(req Criteria) (string, error) {
|
||||||
|
var (
|
||||||
|
src *ecdsa.PublicKey
|
||||||
|
keySym []byte
|
||||||
|
keyAsym *ecdsa.PrivateKey
|
||||||
|
topics [][]byte
|
||||||
|
|
||||||
|
symKeyGiven = len(req.SymKeyID) > 0
|
||||||
|
asymKeyGiven = len(req.PrivateKeyID) > 0
|
||||||
|
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// user must specify either a symmetric or an asymmetric key
|
||||||
|
if (symKeyGiven && asymKeyGiven) || (!symKeyGiven && !asymKeyGiven) {
|
||||||
|
return "", ErrSymAsym
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Sig) > 0 {
|
||||||
|
if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil {
|
||||||
|
return "", ErrInvalidSigningPubKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if symKeyGiven {
|
||||||
|
if keySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !validateDataIntegrity(keySym, aesKeyLength) {
|
||||||
|
return "", ErrInvalidSymmetricKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if asymKeyGiven {
|
||||||
|
if keyAsym, err = api.w.GetPrivateKey(req.PrivateKeyID); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Topics) > 0 {
|
||||||
|
topics = make([][]byte, len(req.Topics))
|
||||||
|
for i, topic := range req.Topics {
|
||||||
|
topics[i] = make([]byte, TopicLength)
|
||||||
|
copy(topics[i], topic[:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f := &Filter{
|
||||||
|
Src: src,
|
||||||
|
KeySym: keySym,
|
||||||
|
KeyAsym: keyAsym,
|
||||||
|
PoW: req.MinPow,
|
||||||
|
AllowP2P: req.AllowP2P,
|
||||||
|
Topics: topics,
|
||||||
|
Messages: NewMemoryMessageStore(),
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := api.w.Subscribe(f)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
api.mu.Lock()
|
||||||
|
api.lastUsed[id] = time.Now()
|
||||||
|
api.mu.Unlock()
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
// Config represents the configuration state of a waku node.
|
||||||
|
type Config struct {
|
||||||
|
MaxMessageSize uint32 `toml:",omitempty"`
|
||||||
|
MinimumAcceptedPoW float64 `toml:",omitempty"`
|
||||||
|
LightClient bool `toml:",omitempty"` // when true, it does not forward messages
|
||||||
|
FullNode bool `toml:",omitempty"` // when true, it forwards all messages
|
||||||
|
RestrictLightClientsConn bool `toml:",omitempty"` // when true, do not accept light client as peers if it is a light client itself
|
||||||
|
EnableConfirmations bool `toml:",omitempty"` // when true, sends message confirmations
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultConfig = Config{
|
||||||
|
MaxMessageSize: DefaultMaxMessageSize,
|
||||||
|
MinimumAcceptedPoW: DefaultMinimumPoW,
|
||||||
|
RestrictLightClientsConn: true,
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Waku protocol parameters
|
||||||
|
const (
|
||||||
|
ProtocolVersion = uint64(0) // Protocol version number
|
||||||
|
ProtocolVersionStr = "0" // The same, as a string
|
||||||
|
ProtocolName = "waku" // Nickname of the protocol
|
||||||
|
|
||||||
|
// Waku protocol message codes, according to https://github.com/vacp2p/specs/blob/master/waku.md
|
||||||
|
statusCode = 0 // used in the handshake
|
||||||
|
messagesCode = 1 // regular message
|
||||||
|
powRequirementCode = 2 // node's PoW requirement
|
||||||
|
bloomFilterExCode = 3 // bloom filter exchange
|
||||||
|
batchAcknowledgedCode = 11 // confirmation that batch of envelopes was received
|
||||||
|
messageResponseCode = 12 // includes confirmation for delivery and information about errors
|
||||||
|
rateLimitingCode = 20 // includes peer's rate limiting settings
|
||||||
|
p2pRequestCompleteCode = 125 // peer-to-peer message, used by Dapp protocol
|
||||||
|
p2pRequestCode = 126 // peer-to-peer message, used by Dapp protocol
|
||||||
|
p2pMessageCode = 127 // peer-to-peer message (to be consumed by the peer, but not forwarded any further)
|
||||||
|
NumberOfMessageCodes = 128
|
||||||
|
|
||||||
|
SizeMask = byte(3) // mask used to extract the size of payload size field from the flags
|
||||||
|
signatureFlag = byte(4)
|
||||||
|
|
||||||
|
TopicLength = 4 // in bytes
|
||||||
|
signatureLength = crypto.SignatureLength // in bytes
|
||||||
|
aesKeyLength = 32 // in bytes
|
||||||
|
aesNonceLength = 12 // in bytes; for more info please see cipher.gcmStandardNonceSize & aesgcm.NonceSize()
|
||||||
|
keyIDSize = 32 // in bytes
|
||||||
|
BloomFilterSize = 64 // in bytes
|
||||||
|
flagsLength = 1
|
||||||
|
|
||||||
|
EnvelopeHeaderLength = 20
|
||||||
|
|
||||||
|
MaxMessageSize = uint32(10 * 1024 * 1024) // maximum accepted size of a message.
|
||||||
|
DefaultMaxMessageSize = uint32(1024 * 1024)
|
||||||
|
DefaultMinimumPoW = 0.2
|
||||||
|
|
||||||
|
padSizeLimit = 256 // just an arbitrary number, could be changed without breaking the protocol
|
||||||
|
messageQueueLimit = 1024
|
||||||
|
|
||||||
|
expirationCycle = time.Second
|
||||||
|
transmissionCycle = 300 * time.Millisecond
|
||||||
|
|
||||||
|
DefaultTTL = 50 // seconds
|
||||||
|
DefaultSyncAllowance = 10 // seconds
|
||||||
|
|
||||||
|
MaxLimitInSyncMailRequest = 1000
|
||||||
|
|
||||||
|
EnvelopeTimeNotSynced uint = iota + 1
|
||||||
|
EnvelopeOtherError
|
||||||
|
|
||||||
|
MaxLimitInMessagesRequest = 1000
|
||||||
|
)
|
||||||
|
|
||||||
|
// MailServer represents a mail server, capable of
|
||||||
|
// archiving the old messages for subsequent delivery
|
||||||
|
// to the peers. Any implementation must ensure that both
|
||||||
|
// functions are thread-safe. Also, they must return ASAP.
|
||||||
|
// DeliverMail should use p2pMessageCode for delivery,
|
||||||
|
// in order to bypass the expiry checks.
|
||||||
|
type MailServer interface {
|
||||||
|
Archive(env *Envelope)
|
||||||
|
DeliverMail(peerID []byte, request *Envelope) // DEPRECATED; use Deliver()
|
||||||
|
Deliver(peerID []byte, request MessagesRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessagesRequest contains details of a request of historic messages.
|
||||||
|
type MessagesRequest struct {
|
||||||
|
// ID of the request. The current implementation requires ID to be 32-byte array,
|
||||||
|
// however, it's not enforced for future implementation.
|
||||||
|
ID []byte `json:"id"`
|
||||||
|
|
||||||
|
// From is a lower bound of time range.
|
||||||
|
From uint32 `json:"from"`
|
||||||
|
|
||||||
|
// To is a upper bound of time range.
|
||||||
|
To uint32 `json:"to"`
|
||||||
|
|
||||||
|
// Limit determines the number of messages sent by the mail server
|
||||||
|
// for the current paginated request.
|
||||||
|
Limit uint32 `json:"limit"`
|
||||||
|
|
||||||
|
// Cursor is used as starting point for paginated requests.
|
||||||
|
Cursor []byte `json:"cursor"`
|
||||||
|
|
||||||
|
// Bloom is a filter to match requested messages.
|
||||||
|
Bloom []byte `json:"bloom"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r MessagesRequest) Validate() error {
|
||||||
|
if len(r.ID) != common.HashLength {
|
||||||
|
return errors.New("invalid 'ID', expected a 32-byte slice")
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.From > r.To {
|
||||||
|
return errors.New("invalid 'From' value which is greater than To")
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Limit > MaxLimitInMessagesRequest {
|
||||||
|
return fmt.Errorf("invalid 'Limit' value, expected value lower than %d", MaxLimitInMessagesRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.Bloom) == 0 {
|
||||||
|
return errors.New("invalid 'Bloom' provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessagesResponse sent as a response after processing batch of envelopes.
|
||||||
|
type MessagesResponse struct {
|
||||||
|
// Hash is a hash of all envelopes sent in the single batch.
|
||||||
|
Hash common.Hash
|
||||||
|
// Per envelope error.
|
||||||
|
Errors []EnvelopeError
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvelopeError code and optional description of the error.
|
||||||
|
type EnvelopeError struct {
|
||||||
|
Hash common.Hash
|
||||||
|
Code uint
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiVersionResponse allows to decode response into chosen version.
|
||||||
|
type MultiVersionResponse struct {
|
||||||
|
Version uint
|
||||||
|
Response rlp.RawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeResponse1 decodes response into first version of the messages response.
|
||||||
|
func (m MultiVersionResponse) DecodeResponse1() (resp MessagesResponse, err error) {
|
||||||
|
return resp, rlp.DecodeBytes(m.Response, &resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version1MessageResponse first version of the message response.
|
||||||
|
type Version1MessageResponse struct {
|
||||||
|
Version uint
|
||||||
|
Response MessagesResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessagesResponse returns instance of the version messages response.
|
||||||
|
func NewMessagesResponse(batch common.Hash, errors []EnvelopeError) Version1MessageResponse {
|
||||||
|
return Version1MessageResponse{
|
||||||
|
Version: 1,
|
||||||
|
Response: MessagesResponse{
|
||||||
|
Hash: batch,
|
||||||
|
Errors: errors,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorToEnvelopeError converts common golang error into EnvelopeError with a code.
|
||||||
|
func ErrorToEnvelopeError(hash common.Hash, err error) EnvelopeError {
|
||||||
|
code := EnvelopeOtherError
|
||||||
|
switch err.(type) {
|
||||||
|
case TimeSyncError:
|
||||||
|
code = EnvelopeTimeNotSynced
|
||||||
|
}
|
||||||
|
return EnvelopeError{
|
||||||
|
Hash: hash,
|
||||||
|
Code: code,
|
||||||
|
Description: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MailServerResponse is the response payload sent by the mailserver.
|
||||||
|
type MailServerResponse struct {
|
||||||
|
LastEnvelopeHash common.Hash
|
||||||
|
Cursor []byte
|
||||||
|
Error error
|
||||||
|
}
|
||||||
|
|
||||||
|
// RateLimits contains information about rate limit settings.
|
||||||
|
// It is exchanged using rateLimitingCode packet or in the handshake.
|
||||||
|
type RateLimits struct {
|
||||||
|
IPLimits uint64 // messages per second from a single IP (default 0, no limits)
|
||||||
|
PeerIDLimits uint64 // messages per second from a single peer ID (default 0, no limits)
|
||||||
|
TopicLimits uint64 // messages per second from a single topic (default 0, no limits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RateLimits) IsZero() bool {
|
||||||
|
return r == (RateLimits{})
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/ecies"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Envelope represents a clear-text data packet to transmit through the Waku
|
||||||
|
// network. Its contents may or may not be encrypted and signed.
|
||||||
|
type Envelope struct {
|
||||||
|
Expiry uint32
|
||||||
|
TTL uint32
|
||||||
|
Topic TopicType
|
||||||
|
Data []byte
|
||||||
|
Nonce uint64
|
||||||
|
|
||||||
|
pow float64 // Message-specific PoW as described in the Waku specification.
|
||||||
|
|
||||||
|
// the following variables should not be accessed directly, use the corresponding function instead: Hash(), Bloom()
|
||||||
|
hash common.Hash // Cached hash of the envelope to avoid rehashing every time.
|
||||||
|
bloom []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// size returns the size of envelope as it is sent (i.e. public fields only)
|
||||||
|
func (e *Envelope) size() int {
|
||||||
|
return EnvelopeHeaderLength + len(e.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
|
||||||
|
func (e *Envelope) rlpWithoutNonce() []byte {
|
||||||
|
res, _ := rlp.EncodeToBytes([]interface{}{e.Expiry, e.TTL, e.Topic, e.Data})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEnvelope wraps a Waku message with expiration and destination data
|
||||||
|
// included into an envelope for network forwarding.
|
||||||
|
func NewEnvelope(ttl uint32, topic TopicType, msg *sentMessage, now time.Time) *Envelope {
|
||||||
|
env := Envelope{
|
||||||
|
Expiry: uint32(now.Add(time.Second * time.Duration(ttl)).Unix()),
|
||||||
|
TTL: ttl,
|
||||||
|
Topic: topic,
|
||||||
|
Data: msg.Raw,
|
||||||
|
Nonce: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &env
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seal closes the envelope by spending the requested amount of time as a proof
|
||||||
|
// of work on hashing the data.
|
||||||
|
func (e *Envelope) Seal(options *MessageParams) error {
|
||||||
|
if options.PoW == 0 {
|
||||||
|
// PoW is not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var target, bestLeadingZeros int
|
||||||
|
if options.PoW < 0 {
|
||||||
|
// target is not set - the function should run for a period
|
||||||
|
// of time specified in WorkTime param. Since we can predict
|
||||||
|
// the execution time, we can also adjust Expiry.
|
||||||
|
e.Expiry += options.WorkTime
|
||||||
|
} else {
|
||||||
|
target = e.powToFirstBit(options.PoW)
|
||||||
|
}
|
||||||
|
|
||||||
|
rlp := e.rlpWithoutNonce()
|
||||||
|
buf := make([]byte, len(rlp)+8)
|
||||||
|
copy(buf, rlp)
|
||||||
|
asAnInt := new(big.Int)
|
||||||
|
|
||||||
|
finish := time.Now().Add(time.Duration(options.WorkTime) * time.Second).UnixNano()
|
||||||
|
for nonce := uint64(0); time.Now().UnixNano() < finish; {
|
||||||
|
for i := 0; i < 1024; i++ {
|
||||||
|
binary.BigEndian.PutUint64(buf[len(rlp):], nonce)
|
||||||
|
h := crypto.Keccak256(buf)
|
||||||
|
asAnInt.SetBytes(h)
|
||||||
|
leadingZeros := 256 - asAnInt.BitLen()
|
||||||
|
if leadingZeros > bestLeadingZeros {
|
||||||
|
e.Nonce, bestLeadingZeros = nonce, leadingZeros
|
||||||
|
if target > 0 && bestLeadingZeros >= target {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nonce++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if target > 0 && bestLeadingZeros < target {
|
||||||
|
return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PoW computes (if necessary) and returns the proof of work target
|
||||||
|
// of the envelope.
|
||||||
|
func (e *Envelope) PoW() float64 {
|
||||||
|
if e.pow == 0 {
|
||||||
|
e.calculatePoW(0)
|
||||||
|
}
|
||||||
|
return e.pow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Envelope) calculatePoW(diff uint32) {
|
||||||
|
rlp := e.rlpWithoutNonce()
|
||||||
|
buf := make([]byte, len(rlp)+8)
|
||||||
|
copy(buf, rlp)
|
||||||
|
binary.BigEndian.PutUint64(buf[len(rlp):], e.Nonce)
|
||||||
|
powHash := new(big.Int).SetBytes(crypto.Keccak256(buf))
|
||||||
|
leadingZeroes := 256 - powHash.BitLen()
|
||||||
|
x := math.Pow(2, float64(leadingZeroes))
|
||||||
|
x /= float64(len(rlp))
|
||||||
|
x /= float64(e.TTL + diff)
|
||||||
|
e.pow = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Envelope) powToFirstBit(pow float64) int {
|
||||||
|
x := pow
|
||||||
|
x *= float64(e.size())
|
||||||
|
x *= float64(e.TTL)
|
||||||
|
bits := math.Log2(x)
|
||||||
|
bits = math.Ceil(bits)
|
||||||
|
res := int(bits)
|
||||||
|
if res < 1 {
|
||||||
|
res = 1
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
|
||||||
|
func (e *Envelope) Hash() common.Hash {
|
||||||
|
if (e.hash == common.Hash{}) {
|
||||||
|
encoded, _ := rlp.EncodeToBytes(e)
|
||||||
|
e.hash = crypto.Keccak256Hash(encoded)
|
||||||
|
}
|
||||||
|
return e.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRLP decodes an Envelope from an RLP data stream.
|
||||||
|
func (e *Envelope) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
raw, err := s.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// The decoding of Envelope uses the struct fields but also needs
|
||||||
|
// to compute the hash of the whole RLP-encoded envelope. This
|
||||||
|
// type has the same structure as Envelope but is not an
|
||||||
|
// rlp.Decoder (does not implement DecodeRLP function).
|
||||||
|
// Only public members will be encoded.
|
||||||
|
type rlpenv Envelope
|
||||||
|
if err := rlp.DecodeBytes(raw, (*rlpenv)(e)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.hash = crypto.Keccak256Hash(raw)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenAsymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
|
||||||
|
func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error) {
|
||||||
|
message := &ReceivedMessage{Raw: e.Data}
|
||||||
|
err := message.decryptAsymmetric(key)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return message, nil
|
||||||
|
case ecies.ErrInvalidPublicKey: // addressed to somebody else
|
||||||
|
return nil, err
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenSymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
|
||||||
|
func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error) {
|
||||||
|
msg = &ReceivedMessage{Raw: e.Data}
|
||||||
|
err = msg.decryptSymmetric(key)
|
||||||
|
if err != nil {
|
||||||
|
msg = nil
|
||||||
|
}
|
||||||
|
return msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open tries to decrypt an envelope, and populates the message fields in case of success.
|
||||||
|
func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
|
||||||
|
if watcher == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The API interface forbids filters doing both symmetric and asymmetric encryption.
|
||||||
|
if watcher.expectsAsymmetricEncryption() && watcher.expectsSymmetricEncryption() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if watcher.expectsAsymmetricEncryption() {
|
||||||
|
msg, _ = e.OpenAsymmetric(watcher.KeyAsym)
|
||||||
|
if msg != nil {
|
||||||
|
msg.Dst = &watcher.KeyAsym.PublicKey
|
||||||
|
}
|
||||||
|
} else if watcher.expectsSymmetricEncryption() {
|
||||||
|
msg, _ = e.OpenSymmetric(watcher.KeySym)
|
||||||
|
if msg != nil {
|
||||||
|
msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg != nil {
|
||||||
|
ok := msg.ValidateAndParse()
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
msg.Topic = e.Topic
|
||||||
|
msg.PoW = e.PoW()
|
||||||
|
msg.TTL = e.TTL
|
||||||
|
msg.Sent = e.Expiry - e.TTL
|
||||||
|
msg.EnvelopeHash = e.Hash()
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bloom maps 4-bytes Topic into 64-byte bloom filter with 3 bits set (at most).
|
||||||
|
func (e *Envelope) Bloom() []byte {
|
||||||
|
if e.bloom == nil {
|
||||||
|
e.bloom = TopicToBloom(e.Topic)
|
||||||
|
}
|
||||||
|
return e.bloom
|
||||||
|
}
|
||||||
|
|
||||||
|
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
|
||||||
|
func TopicToBloom(topic TopicType) []byte {
|
||||||
|
b := make([]byte, BloomFilterSize)
|
||||||
|
var index [3]int
|
||||||
|
for j := 0; j < 3; j++ {
|
||||||
|
index[j] = int(topic[j])
|
||||||
|
if (topic[3] & (1 << uint(j))) != 0 {
|
||||||
|
index[j] += 256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < 3; j++ {
|
||||||
|
byteIndex := index[j] / 8
|
||||||
|
bitIndex := index[j] % 8
|
||||||
|
b[byteIndex] = (1 << uint(bitIndex))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EventType used to define known envelope events.
|
||||||
|
type EventType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EventEnvelopeSent fires when envelope was sent to a peer.
|
||||||
|
EventEnvelopeSent EventType = "envelope.sent"
|
||||||
|
// EventEnvelopeExpired fires when envelop expired
|
||||||
|
EventEnvelopeExpired EventType = "envelope.expired"
|
||||||
|
// EventEnvelopeReceived is sent once envelope was received from a peer.
|
||||||
|
// EventEnvelopeReceived must be sent to the feed even if envelope was previously in the cache.
|
||||||
|
// And event, ideally, should contain information about peer that sent envelope to us.
|
||||||
|
EventEnvelopeReceived EventType = "envelope.received"
|
||||||
|
// EventBatchAcknowledged is sent when batch of envelopes was acknowleged by a peer.
|
||||||
|
EventBatchAcknowledged EventType = "batch.acknowleged"
|
||||||
|
// EventEnvelopeAvailable fires when envelop is available for filters
|
||||||
|
EventEnvelopeAvailable EventType = "envelope.available"
|
||||||
|
// EventMailServerRequestSent fires when such request is sent.
|
||||||
|
EventMailServerRequestSent EventType = "mailserver.request.sent"
|
||||||
|
// EventMailServerRequestCompleted fires after mailserver sends all the requested messages
|
||||||
|
EventMailServerRequestCompleted EventType = "mailserver.request.completed"
|
||||||
|
// EventMailServerRequestExpired fires after mailserver the request TTL ends.
|
||||||
|
// This event is independent and concurrent to EventMailServerRequestCompleted.
|
||||||
|
// Request should be considered as expired only if expiry event was received first.
|
||||||
|
EventMailServerRequestExpired EventType = "mailserver.request.expired"
|
||||||
|
// EventMailServerEnvelopeArchived fires after an envelope has been archived
|
||||||
|
EventMailServerEnvelopeArchived EventType = "mailserver.envelope.archived"
|
||||||
|
// EventMailServerSyncFinished fires when the sync of messages is finished.
|
||||||
|
EventMailServerSyncFinished EventType = "mailserver.sync.finished"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnvelopeEvent used for envelopes events.
|
||||||
|
type EnvelopeEvent struct {
|
||||||
|
Event EventType
|
||||||
|
Topic TopicType
|
||||||
|
Hash common.Hash
|
||||||
|
Batch common.Hash
|
||||||
|
Peer enode.ID
|
||||||
|
Data interface{}
|
||||||
|
}
|
|
@ -0,0 +1,296 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessageStore defines interface for temporary message store.
|
||||||
|
type MessageStore interface {
|
||||||
|
Add(*ReceivedMessage) error
|
||||||
|
Pop() ([]*ReceivedMessage, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMemoryMessageStore returns pointer to an instance of the MemoryMessageStore.
|
||||||
|
func NewMemoryMessageStore() *MemoryMessageStore {
|
||||||
|
return &MemoryMessageStore{
|
||||||
|
messages: map[common.Hash]*ReceivedMessage{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryMessageStore stores massages in memory hash table.
|
||||||
|
type MemoryMessageStore struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
messages map[common.Hash]*ReceivedMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds message to store.
|
||||||
|
func (store *MemoryMessageStore) Add(msg *ReceivedMessage) error {
|
||||||
|
store.mu.Lock()
|
||||||
|
defer store.mu.Unlock()
|
||||||
|
if _, exist := store.messages[msg.EnvelopeHash]; !exist {
|
||||||
|
store.messages[msg.EnvelopeHash] = msg
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop returns all avaiable messages and cleans the store.
|
||||||
|
func (store *MemoryMessageStore) Pop() ([]*ReceivedMessage, error) {
|
||||||
|
store.mu.Lock()
|
||||||
|
defer store.mu.Unlock()
|
||||||
|
all := make([]*ReceivedMessage, 0, len(store.messages))
|
||||||
|
for hash, msg := range store.messages {
|
||||||
|
delete(store.messages, hash)
|
||||||
|
all = append(all, msg)
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter represents a Waku message filter
|
||||||
|
type Filter struct {
|
||||||
|
Src *ecdsa.PublicKey // Sender of the message
|
||||||
|
KeyAsym *ecdsa.PrivateKey // Private Key of recipient
|
||||||
|
KeySym []byte // Key associated with the Topic
|
||||||
|
Topics [][]byte // Topics to filter messages with
|
||||||
|
PoW float64 // Proof of work as described in the Waku spec
|
||||||
|
AllowP2P bool // Indicates whether this filter is interested in direct peer-to-peer messages
|
||||||
|
SymKeyHash common.Hash // The Keccak256Hash of the symmetric key, needed for optimization
|
||||||
|
id string // unique identifier
|
||||||
|
|
||||||
|
Messages MessageStore
|
||||||
|
mutex sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters represents a collection of filters
|
||||||
|
type Filters struct {
|
||||||
|
watchers map[string]*Filter
|
||||||
|
|
||||||
|
topicMatcher map[TopicType]map[*Filter]struct{} // map a topic to the filters that are interested in being notified when a message matches that topic
|
||||||
|
allTopicsMatcher map[*Filter]struct{} // list all the filters that will be notified of a new message, no matter what its topic is
|
||||||
|
|
||||||
|
waku *Waku
|
||||||
|
mutex sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFilters returns a newly created filter collection
|
||||||
|
func NewFilters(w *Waku) *Filters {
|
||||||
|
return &Filters{
|
||||||
|
watchers: make(map[string]*Filter),
|
||||||
|
topicMatcher: make(map[TopicType]map[*Filter]struct{}),
|
||||||
|
allTopicsMatcher: make(map[*Filter]struct{}),
|
||||||
|
waku: w,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install will add a new filter to the filter collection
|
||||||
|
func (fs *Filters) Install(watcher *Filter) (string, error) {
|
||||||
|
if watcher.KeySym != nil && watcher.KeyAsym != nil {
|
||||||
|
return "", fmt.Errorf("filters must choose between symmetric and asymmetric keys")
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := GenerateRandomID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.mutex.Lock()
|
||||||
|
defer fs.mutex.Unlock()
|
||||||
|
|
||||||
|
if fs.watchers[id] != nil {
|
||||||
|
return "", fmt.Errorf("failed to generate unique ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
if watcher.expectsSymmetricEncryption() {
|
||||||
|
watcher.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher.id = id
|
||||||
|
fs.watchers[id] = watcher
|
||||||
|
fs.addTopicMatcher(watcher)
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninstall will remove a filter whose id has been specified from
|
||||||
|
// the filter collection
|
||||||
|
func (fs *Filters) Uninstall(id string) bool {
|
||||||
|
fs.mutex.Lock()
|
||||||
|
defer fs.mutex.Unlock()
|
||||||
|
if fs.watchers[id] != nil {
|
||||||
|
fs.removeFromTopicMatchers(fs.watchers[id])
|
||||||
|
delete(fs.watchers, id)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// addTopicMatcher adds a filter to the topic matchers.
|
||||||
|
// If the filter's Topics array is empty, it will be tried on every topic.
|
||||||
|
// Otherwise, it will be tried on the topics specified.
|
||||||
|
func (fs *Filters) addTopicMatcher(watcher *Filter) {
|
||||||
|
if len(watcher.Topics) == 0 {
|
||||||
|
fs.allTopicsMatcher[watcher] = struct{}{}
|
||||||
|
} else {
|
||||||
|
for _, t := range watcher.Topics {
|
||||||
|
topic := BytesToTopic(t)
|
||||||
|
if fs.topicMatcher[topic] == nil {
|
||||||
|
fs.topicMatcher[topic] = make(map[*Filter]struct{})
|
||||||
|
}
|
||||||
|
fs.topicMatcher[topic][watcher] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeFromTopicMatchers removes a filter from the topic matchers
|
||||||
|
func (fs *Filters) removeFromTopicMatchers(watcher *Filter) {
|
||||||
|
delete(fs.allTopicsMatcher, watcher)
|
||||||
|
for _, topic := range watcher.Topics {
|
||||||
|
delete(fs.topicMatcher[BytesToTopic(topic)], watcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getWatchersByTopic returns a slice containing the filters that
|
||||||
|
// match a specific topic
|
||||||
|
func (fs *Filters) getWatchersByTopic(topic TopicType) []*Filter {
|
||||||
|
res := make([]*Filter, 0, len(fs.allTopicsMatcher))
|
||||||
|
for watcher := range fs.allTopicsMatcher {
|
||||||
|
res = append(res, watcher)
|
||||||
|
}
|
||||||
|
for watcher := range fs.topicMatcher[topic] {
|
||||||
|
res = append(res, watcher)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns a filter from the collection with a specific ID
|
||||||
|
func (fs *Filters) Get(id string) *Filter {
|
||||||
|
fs.mutex.RLock()
|
||||||
|
defer fs.mutex.RUnlock()
|
||||||
|
return fs.watchers[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyWatchers notifies any filter that has declared interest
|
||||||
|
// for the envelope's topic.
|
||||||
|
func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) {
|
||||||
|
var msg *ReceivedMessage
|
||||||
|
|
||||||
|
fs.mutex.RLock()
|
||||||
|
defer fs.mutex.RUnlock()
|
||||||
|
|
||||||
|
candidates := fs.getWatchersByTopic(env.Topic)
|
||||||
|
for _, watcher := range candidates {
|
||||||
|
if p2pMessage && !watcher.AllowP2P {
|
||||||
|
log.Trace(fmt.Sprintf("msg [%x], filter [%s]: p2p messages are not allowed", env.Hash(), watcher.id))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var match bool
|
||||||
|
if msg != nil {
|
||||||
|
match = watcher.MatchMessage(msg)
|
||||||
|
} else {
|
||||||
|
match = watcher.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
msg = env.Open(watcher)
|
||||||
|
if msg == nil {
|
||||||
|
log.Trace("processing message: failed to open", "message", env.Hash().Hex(), "filter", watcher.id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Trace("processing message: does not match", "message", env.Hash().Hex(), "filter", watcher.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if match && msg != nil {
|
||||||
|
msg.P2P = p2pMessage
|
||||||
|
log.Trace("processing message: decrypted", "hash", env.Hash().Hex())
|
||||||
|
if watcher.Src == nil || IsPubKeyEqual(msg.Src, watcher.Src) {
|
||||||
|
watcher.Trigger(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Filter) expectsAsymmetricEncryption() bool {
|
||||||
|
return f.KeyAsym != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Filter) expectsSymmetricEncryption() bool {
|
||||||
|
return f.KeySym != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger adds a yet-unknown message to the filter's list of
|
||||||
|
// received messages.
|
||||||
|
func (f *Filter) Trigger(msg *ReceivedMessage) {
|
||||||
|
err := f.Messages.Add(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to add msg into the filters store", "hash", msg.EnvelopeHash, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve will return the list of all received messages associated
|
||||||
|
// to a filter.
|
||||||
|
func (f *Filter) Retrieve() []*ReceivedMessage {
|
||||||
|
msgs, err := f.Messages.Pop()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to retrieve messages from filter store", "error", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchMessage checks if the filter matches an already decrypted
|
||||||
|
// message (i.e. a Message that has already been handled by
|
||||||
|
// MatchEnvelope when checked by a previous filter).
|
||||||
|
// Topics are not checked here, since this is done by topic matchers.
|
||||||
|
func (f *Filter) MatchMessage(msg *ReceivedMessage) bool {
|
||||||
|
if f.PoW > 0 && msg.PoW < f.PoW {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() {
|
||||||
|
return IsPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst)
|
||||||
|
} else if f.expectsSymmetricEncryption() && msg.isSymmetricEncryption() {
|
||||||
|
return f.SymKeyHash == msg.SymKeyHash
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchEnvelope checks if it's worth decrypting the message. If
|
||||||
|
// it returns `true`, client code is expected to attempt decrypting
|
||||||
|
// the message and subsequently call MatchMessage.
|
||||||
|
// Topics are not checked here, since this is done by topic matchers.
|
||||||
|
func (f *Filter) MatchEnvelope(envelope *Envelope) bool {
|
||||||
|
return f.PoW <= 0 || envelope.pow >= f.PoW
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPubKeyEqual checks that two public keys are equal
|
||||||
|
func IsPubKeyEqual(a, b *ecdsa.PublicKey) bool {
|
||||||
|
if !ValidatePublicKey(a) {
|
||||||
|
return false
|
||||||
|
} else if !ValidatePublicKey(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// the curve is always the same, just compare the points
|
||||||
|
return a.X.Cmp(b.X) == 0 && a.Y.Cmp(b.Y) == 0
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
module github.com/status-im/status-go/waku
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 // indirect
|
||||||
|
github.com/deckarep/golang-set v1.7.1
|
||||||
|
github.com/elastic/gosigar v0.10.5 // indirect
|
||||||
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
|
github.com/gorilla/websocket v1.4.1 // indirect
|
||||||
|
github.com/huin/goupnp v1.0.0 // indirect
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.2.1
|
||||||
|
github.com/prometheus/common v0.7.0
|
||||||
|
github.com/rs/cors v1.7.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.4.0
|
||||||
|
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||||
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9
|
||||||
|
go.uber.org/zap v1.13.0
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||||
|
)
|
|
@ -0,0 +1,304 @@
|
||||||
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
||||||
|
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
|
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
|
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 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
|
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 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
|
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||||
|
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 h1:ZdRuixFqR3mfx4FHzclG3COrRgWrYq0VhNgIoYoObcM=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
|
||||||
|
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||||
|
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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/btcsuite/btcd v0.20.0-beta h1:DnZGUjFbRkpytojHWwy6nfUSA7vFrzWXDLpFNzt74ZA=
|
||||||
|
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
|
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/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/snappy-go v0.0.0-20151229074030-0bdef8d06723/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/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
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/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||||
|
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||||
|
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||||
|
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=
|
||||||
|
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||||
|
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-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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
|
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||||
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||||
|
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
|
||||||
|
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||||
|
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||||
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||||
|
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
||||||
|
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
|
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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||||
|
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
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.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||||
|
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||||
|
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||||
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||||
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
|
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.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.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
|
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
|
||||||
|
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||||
|
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 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
|
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
|
||||||
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
|
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.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
|
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||||
|
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||||
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/status-im/extkeys v1.0.0/go.mod h1:wNx0pnvGTgyKz/S8hBNesAHKKKI9beF+BuVLIuBJuQI=
|
||||||
|
github.com/status-im/go-ethereum v1.9.5-status.5 h1:d2RJC6ltNZJM2mrAW6kDWYdzewF8+us4qYaIH5gvyaM=
|
||||||
|
github.com/status-im/go-ethereum v1.9.5-status.5/go.mod h1:g2+E89NWtyA+55p6XEl5Sdt7Mtez3V0T3+Y7mJNb+tI=
|
||||||
|
github.com/status-im/go-ethereum v1.9.5-status.6 h1:ytuTO1yBIAuTVRtRQoc2mrdyngtP+XOQ9IHIibbz7/I=
|
||||||
|
github.com/status-im/go-ethereum v1.9.5-status.6/go.mod h1:08JvQWE+IOnAFSe4UD4ACLNe2fDd9XmWMCq5Yzy9mk0=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||||
|
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||||
|
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||||
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 h1:kjbwitOGH46vD01f2s3leBfrMnePQa3NSAIlW35MvY8=
|
||||||
|
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I=
|
||||||
|
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
|
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
|
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||||
|
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||||
|
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||||
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
||||||
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
|
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||||
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
|
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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
|
||||||
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
|
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-20181114220301-adae6a3d119a/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
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-20190912160710-24e19bdeb0f2 h1:4dVFTC832rPn4pomLSz1vA+are2+dU19w1H8OngV7nc=
|
||||||
|
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
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-20181116152217-5ac8a444bdc5/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-20190403152447-81d4e9dc473e/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-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
||||||
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190912185636-87d9f09c5d89/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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||||
|
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||||
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
|
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||||
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
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=
|
158
vendor/github.com/status-im/status-go/waku/mailserver_response.go
generated
vendored
Normal file
158
vendor/github.com/status-im/status-go/waku/mailserver_response.go
generated
vendored
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mailServerFailedPayloadPrefix = "ERROR="
|
||||||
|
cursorSize = 36
|
||||||
|
)
|
||||||
|
|
||||||
|
func invalidResponseSizeError(size int) error {
|
||||||
|
return fmt.Errorf("unexpected payload size: %d", size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMailServerRequestCompletedPayload creates a payload representing
|
||||||
|
// a successful request to mailserver
|
||||||
|
func CreateMailServerRequestCompletedPayload(requestID, lastEnvelopeHash common.Hash, cursor []byte) []byte {
|
||||||
|
payload := make([]byte, len(requestID))
|
||||||
|
copy(payload, requestID[:])
|
||||||
|
payload = append(payload, lastEnvelopeHash[:]...)
|
||||||
|
payload = append(payload, cursor...)
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMailServerRequestFailedPayload creates a payload representing
|
||||||
|
// a failed request to a mailserver
|
||||||
|
func CreateMailServerRequestFailedPayload(requestID common.Hash, err error) []byte {
|
||||||
|
payload := []byte(mailServerFailedPayloadPrefix)
|
||||||
|
payload = append(payload, requestID[:]...)
|
||||||
|
payload = append(payload, []byte(err.Error())...)
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMailServerEvent returns EnvelopeEvent with correct data
|
||||||
|
// if payload corresponds to any of the know mailserver events:
|
||||||
|
// * request completed successfully
|
||||||
|
// * request failed
|
||||||
|
// If the payload is unknown/unparseable, it returns `nil`
|
||||||
|
func CreateMailServerEvent(nodeID enode.ID, payload []byte) (*EnvelopeEvent, error) {
|
||||||
|
if len(payload) < common.HashLength {
|
||||||
|
return nil, invalidResponseSizeError(len(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := tryCreateMailServerRequestFailedEvent(nodeID, payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if event != nil {
|
||||||
|
return event, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return tryCreateMailServerRequestCompletedEvent(nodeID, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryCreateMailServerRequestFailedEvent(nodeID enode.ID, payload []byte) (*EnvelopeEvent, error) {
|
||||||
|
if len(payload) < common.HashLength+len(mailServerFailedPayloadPrefix) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix, remainder := extractPrefix(payload, len(mailServerFailedPayloadPrefix))
|
||||||
|
|
||||||
|
if !bytes.Equal(prefix, []byte(mailServerFailedPayloadPrefix)) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
requestID common.Hash
|
||||||
|
errorMsg string
|
||||||
|
)
|
||||||
|
|
||||||
|
requestID, remainder = extractHash(remainder)
|
||||||
|
errorMsg = string(remainder)
|
||||||
|
|
||||||
|
event := EnvelopeEvent{
|
||||||
|
Peer: nodeID,
|
||||||
|
Hash: requestID,
|
||||||
|
Event: EventMailServerRequestCompleted,
|
||||||
|
Data: &MailServerResponse{
|
||||||
|
Error: errors.New(errorMsg),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &event, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryCreateMailServerRequestCompletedEvent(nodeID enode.ID, payload []byte) (*EnvelopeEvent, error) {
|
||||||
|
// check if payload is
|
||||||
|
// - requestID or
|
||||||
|
// - requestID + lastEnvelopeHash or
|
||||||
|
// - requestID + lastEnvelopeHash + cursor
|
||||||
|
// requestID is the hash of the request envelope.
|
||||||
|
// lastEnvelopeHash is the last envelope sent by the mail server
|
||||||
|
// cursor is the db key, 36 bytes: 4 for the timestamp + 32 for the envelope hash.
|
||||||
|
if len(payload) > common.HashLength*2+cursorSize {
|
||||||
|
return nil, invalidResponseSizeError(len(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
requestID common.Hash
|
||||||
|
lastEnvelopeHash common.Hash
|
||||||
|
cursor []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
requestID, remainder := extractHash(payload)
|
||||||
|
|
||||||
|
if len(remainder) >= common.HashLength {
|
||||||
|
lastEnvelopeHash, remainder = extractHash(remainder)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(remainder) >= cursorSize {
|
||||||
|
cursor = remainder
|
||||||
|
}
|
||||||
|
|
||||||
|
event := EnvelopeEvent{
|
||||||
|
Peer: nodeID,
|
||||||
|
Hash: requestID,
|
||||||
|
Event: EventMailServerRequestCompleted,
|
||||||
|
Data: &MailServerResponse{
|
||||||
|
LastEnvelopeHash: lastEnvelopeHash,
|
||||||
|
Cursor: cursor,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &event, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractHash(payload []byte) (common.Hash, []byte) {
|
||||||
|
prefix, remainder := extractPrefix(payload, common.HashLength)
|
||||||
|
return common.BytesToHash(prefix), remainder
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractPrefix(payload []byte, size int) ([]byte, []byte) {
|
||||||
|
return payload[:size], payload[size:]
|
||||||
|
}
|
|
@ -0,0 +1,361 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
crand "crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
mrand "math/rand"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/ecies"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessageParams specifies the exact way a message should be wrapped
|
||||||
|
// into an Envelope.
|
||||||
|
type MessageParams struct {
|
||||||
|
TTL uint32
|
||||||
|
Src *ecdsa.PrivateKey
|
||||||
|
Dst *ecdsa.PublicKey
|
||||||
|
KeySym []byte
|
||||||
|
Topic TopicType
|
||||||
|
WorkTime uint32
|
||||||
|
PoW float64
|
||||||
|
Payload []byte
|
||||||
|
Padding []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SentMessage represents an end-user data packet to transmit through the
|
||||||
|
// Waku protocol. These are wrapped into Envelopes that need not be
|
||||||
|
// understood by intermediate nodes, just forwarded.
|
||||||
|
type sentMessage struct {
|
||||||
|
Raw []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceivedMessage represents a data packet to be received through the
|
||||||
|
// Waku protocol and successfully decrypted.
|
||||||
|
type ReceivedMessage struct {
|
||||||
|
Raw []byte
|
||||||
|
|
||||||
|
Payload []byte
|
||||||
|
Padding []byte
|
||||||
|
Signature []byte
|
||||||
|
Salt []byte
|
||||||
|
|
||||||
|
PoW float64 // Proof of work as described in the Waku spec
|
||||||
|
Sent uint32 // Time when the message was posted into the network
|
||||||
|
TTL uint32 // Maximum time to live allowed for the message
|
||||||
|
Src *ecdsa.PublicKey // Message recipient (identity used to decode the message)
|
||||||
|
Dst *ecdsa.PublicKey // Message recipient (identity used to decode the message)
|
||||||
|
Topic TopicType
|
||||||
|
|
||||||
|
SymKeyHash common.Hash // The Keccak256Hash of the key
|
||||||
|
EnvelopeHash common.Hash // Message envelope hash to act as a unique id
|
||||||
|
|
||||||
|
P2P bool // is set to true if this message was received from mail server.
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMessageSigned(flags byte) bool {
|
||||||
|
return (flags & signatureFlag) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *ReceivedMessage) isSymmetricEncryption() bool {
|
||||||
|
return msg.SymKeyHash != common.Hash{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *ReceivedMessage) isAsymmetricEncryption() bool {
|
||||||
|
return msg.Dst != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSentMessage creates and initializes a non-signed, non-encrypted Waku message.
|
||||||
|
func NewSentMessage(params *MessageParams) (*sentMessage, error) {
|
||||||
|
const payloadSizeFieldMaxSize = 4
|
||||||
|
msg := sentMessage{}
|
||||||
|
msg.Raw = make([]byte, 1,
|
||||||
|
flagsLength+payloadSizeFieldMaxSize+len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit)
|
||||||
|
msg.Raw[0] = 0 // set all the flags to zero
|
||||||
|
msg.addPayloadSizeField(params.Payload)
|
||||||
|
msg.Raw = append(msg.Raw, params.Payload...)
|
||||||
|
err := msg.appendPadding(params)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// addPayloadSizeField appends the auxiliary field containing the size of payload
|
||||||
|
func (msg *sentMessage) addPayloadSizeField(payload []byte) {
|
||||||
|
fieldSize := getSizeOfPayloadSizeField(payload)
|
||||||
|
field := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(field, uint32(len(payload)))
|
||||||
|
field = field[:fieldSize]
|
||||||
|
msg.Raw = append(msg.Raw, field...)
|
||||||
|
msg.Raw[0] |= byte(fieldSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSizeOfPayloadSizeField returns the number of bytes necessary to encode the size of payload
|
||||||
|
func getSizeOfPayloadSizeField(payload []byte) int {
|
||||||
|
s := 1
|
||||||
|
for i := len(payload); i >= 256; i /= 256 {
|
||||||
|
s++
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendPadding appends the padding specified in params.
|
||||||
|
// If no padding is provided in params, then random padding is generated.
|
||||||
|
func (msg *sentMessage) appendPadding(params *MessageParams) error {
|
||||||
|
if len(params.Padding) != 0 {
|
||||||
|
// padding data was provided by the Dapp, just use it as is
|
||||||
|
msg.Raw = append(msg.Raw, params.Padding...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rawSize := flagsLength + getSizeOfPayloadSizeField(params.Payload) + len(params.Payload)
|
||||||
|
if params.Src != nil {
|
||||||
|
rawSize += signatureLength
|
||||||
|
}
|
||||||
|
odd := rawSize % padSizeLimit
|
||||||
|
paddingSize := padSizeLimit - odd
|
||||||
|
pad := make([]byte, paddingSize)
|
||||||
|
_, err := crand.Read(pad)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !validateDataIntegrity(pad, paddingSize) {
|
||||||
|
return errors.New("failed to generate random padding of size " + strconv.Itoa(paddingSize))
|
||||||
|
}
|
||||||
|
msg.Raw = append(msg.Raw, pad...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// sign calculates and sets the cryptographic signature for the message,
|
||||||
|
// also setting the sign flag.
|
||||||
|
func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error {
|
||||||
|
if isMessageSigned(msg.Raw[0]) {
|
||||||
|
// this should not happen, but no reason to panic
|
||||||
|
log.Error("failed to sign the message: already signed")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Raw[0] |= signatureFlag // it is important to set this flag before signing
|
||||||
|
hash := crypto.Keccak256(msg.Raw)
|
||||||
|
signature, err := crypto.Sign(hash, key)
|
||||||
|
if err != nil {
|
||||||
|
msg.Raw[0] &= (0xFF ^ signatureFlag) // clear the flag
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
msg.Raw = append(msg.Raw, signature...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryptAsymmetric encrypts a message with a public key.
|
||||||
|
func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error {
|
||||||
|
if !ValidatePublicKey(key) {
|
||||||
|
return errors.New("invalid public key provided for asymmetric encryption")
|
||||||
|
}
|
||||||
|
encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
msg.Raw = encrypted
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryptSymmetric encrypts a message with a topic key, using AES-GCM-256.
|
||||||
|
// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
|
||||||
|
func (msg *sentMessage) encryptSymmetric(key []byte) (err error) {
|
||||||
|
if !validateDataIntegrity(key, aesKeyLength) {
|
||||||
|
return errors.New("invalid key provided for symmetric encryption, size: " + strconv.Itoa(len(key)))
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
salt, err := generateSecureRandomData(aesNonceLength) // never use more than 2^32 random nonces with a given key
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
encrypted := aesgcm.Seal(nil, salt, msg.Raw, nil)
|
||||||
|
msg.Raw = append(encrypted, salt...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateSecureRandomData generates random data where extra security is required.
|
||||||
|
// The purpose of this function is to prevent some bugs in software or in hardware
|
||||||
|
// from delivering not-very-random data. This is especially useful for AES nonce,
|
||||||
|
// where true randomness does not really matter, but it is very important to have
|
||||||
|
// a unique nonce for every message.
|
||||||
|
func generateSecureRandomData(length int) ([]byte, error) {
|
||||||
|
x := make([]byte, length)
|
||||||
|
y := make([]byte, length)
|
||||||
|
res := make([]byte, length)
|
||||||
|
|
||||||
|
_, err := crand.Read(x)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if !validateDataIntegrity(x, length) {
|
||||||
|
return nil, errors.New("crypto/rand failed to generate secure random data")
|
||||||
|
}
|
||||||
|
_, err = mrand.Read(y)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if !validateDataIntegrity(y, length) {
|
||||||
|
return nil, errors.New("math/rand failed to generate secure random data")
|
||||||
|
}
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
res[i] = x[i] ^ y[i]
|
||||||
|
}
|
||||||
|
if !validateDataIntegrity(res, length) {
|
||||||
|
return nil, errors.New("failed to generate secure random data")
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap bundles the message into an Envelope to transmit over the network.
|
||||||
|
func (msg *sentMessage) Wrap(options *MessageParams, now time.Time) (envelope *Envelope, err error) {
|
||||||
|
if options.TTL == 0 {
|
||||||
|
options.TTL = DefaultTTL
|
||||||
|
}
|
||||||
|
if options.Src != nil {
|
||||||
|
if err = msg.sign(options.Src); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if options.Dst != nil {
|
||||||
|
err = msg.encryptAsymmetric(options.Dst)
|
||||||
|
} else if options.KeySym != nil {
|
||||||
|
err = msg.encryptSymmetric(options.KeySym)
|
||||||
|
} else {
|
||||||
|
err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
envelope = NewEnvelope(options.TTL, options.Topic, msg, now)
|
||||||
|
if err = envelope.Seal(options); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return envelope, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decryptSymmetric decrypts a message with a topic key, using AES-GCM-256.
|
||||||
|
// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
|
||||||
|
func (msg *ReceivedMessage) decryptSymmetric(key []byte) error {
|
||||||
|
// symmetric messages are expected to contain the 12-byte nonce at the end of the payload
|
||||||
|
if len(msg.Raw) < aesNonceLength {
|
||||||
|
return errors.New("missing salt or invalid payload in symmetric message")
|
||||||
|
}
|
||||||
|
salt := msg.Raw[len(msg.Raw)-aesNonceLength:]
|
||||||
|
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
decrypted, err := aesgcm.Open(nil, salt, msg.Raw[:len(msg.Raw)-aesNonceLength], nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
msg.Raw = decrypted
|
||||||
|
msg.Salt = salt
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decryptAsymmetric decrypts an encrypted payload with a private key.
|
||||||
|
func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error {
|
||||||
|
decrypted, err := ecies.ImportECDSA(key).Decrypt(msg.Raw, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
msg.Raw = decrypted
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateAndParse checks the message validity and extracts the fields in case of success.
|
||||||
|
func (msg *ReceivedMessage) ValidateAndParse() bool {
|
||||||
|
end := len(msg.Raw)
|
||||||
|
if end < 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if isMessageSigned(msg.Raw[0]) {
|
||||||
|
end -= signatureLength
|
||||||
|
if end <= 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
msg.Signature = msg.Raw[end : end+signatureLength]
|
||||||
|
msg.Src = msg.SigToPubKey()
|
||||||
|
if msg.Src == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beg := 1
|
||||||
|
payloadSize := 0
|
||||||
|
sizeOfPayloadSizeField := int(msg.Raw[0] & SizeMask) // number of bytes indicating the size of payload
|
||||||
|
if sizeOfPayloadSizeField != 0 {
|
||||||
|
if end < beg+sizeOfPayloadSizeField {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
payloadSize = int(bytesToUintLittleEndian(msg.Raw[beg : beg+sizeOfPayloadSizeField]))
|
||||||
|
beg += sizeOfPayloadSizeField
|
||||||
|
if beg+payloadSize > end {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
msg.Payload = msg.Raw[beg : beg+payloadSize]
|
||||||
|
}
|
||||||
|
|
||||||
|
beg += payloadSize
|
||||||
|
msg.Padding = msg.Raw[beg:end]
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigToPubKey returns the public key associated to the message's
|
||||||
|
// signature.
|
||||||
|
func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey {
|
||||||
|
defer func() { recover() }() // in case of invalid signature
|
||||||
|
|
||||||
|
pub, err := crypto.SigToPub(msg.hash(), msg.Signature)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to recover public key from signature", "err", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return pub
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash calculates the SHA3 checksum of the message flags, payload size field, payload and padding.
|
||||||
|
func (msg *ReceivedMessage) hash() []byte {
|
||||||
|
if isMessageSigned(msg.Raw[0]) {
|
||||||
|
sz := len(msg.Raw) - signatureLength
|
||||||
|
return crypto.Keccak256(msg.Raw[:sz])
|
||||||
|
}
|
||||||
|
return crypto.Keccak256(msg.Raw)
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
prom "github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
envelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
|
Name: "waku_envelopes_received_total",
|
||||||
|
Help: "Number of envelopes received.",
|
||||||
|
})
|
||||||
|
envelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
|
Name: "waku_envelopes_validated_total",
|
||||||
|
Help: "Number of envelopes processed successfully.",
|
||||||
|
})
|
||||||
|
envelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
|
Name: "waku_envelopes_rejected_total",
|
||||||
|
Help: "Number of envelopes rejected.",
|
||||||
|
}, []string{"reason"})
|
||||||
|
envelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
|
Name: "waku_envelopes_cache_failures_total",
|
||||||
|
Help: "Number of envelopes which failed to be cached.",
|
||||||
|
}, []string{"type"})
|
||||||
|
envelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
|
Name: "waku_envelopes_cached_total",
|
||||||
|
Help: "Number of envelopes cached.",
|
||||||
|
}, []string{"cache"})
|
||||||
|
envelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{
|
||||||
|
Name: "waku_envelopes_size_bytes",
|
||||||
|
Help: "Size of processed Waku envelopes in bytes.",
|
||||||
|
Buckets: prom.ExponentialBuckets(256, 4, 10),
|
||||||
|
})
|
||||||
|
// rate limiter metrics
|
||||||
|
rateLimitsProcessed = prom.NewCounter(prom.CounterOpts{
|
||||||
|
Name: "waku_rate_limits_processed_total",
|
||||||
|
Help: "Number of packets Waku rate limiter processed.",
|
||||||
|
})
|
||||||
|
rateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{
|
||||||
|
Name: "waku_rate_limits_exceeded_total",
|
||||||
|
Help: "Number of times the Waku rate limits were exceeded",
|
||||||
|
}, []string{"type"})
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
prom.MustRegister(envelopesReceivedCounter)
|
||||||
|
prom.MustRegister(envelopesRejectedCounter)
|
||||||
|
prom.MustRegister(envelopesCacheFailedCounter)
|
||||||
|
prom.MustRegister(envelopesCachedCounter)
|
||||||
|
prom.MustRegister(envelopesSizeMeter)
|
||||||
|
prom.MustRegister(rateLimitsProcessed)
|
||||||
|
prom.MustRegister(rateLimitsExceeded)
|
||||||
|
}
|
|
@ -0,0 +1,321 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
mapset "github.com/deckarep/golang-set"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Peer represents a waku protocol peer connection.
|
||||||
|
type Peer struct {
|
||||||
|
host *Waku
|
||||||
|
peer *p2p.Peer
|
||||||
|
ws p2p.MsgReadWriter
|
||||||
|
logger *zap.Logger
|
||||||
|
|
||||||
|
trusted bool
|
||||||
|
powRequirement float64
|
||||||
|
bloomMu sync.Mutex
|
||||||
|
bloomFilter []byte
|
||||||
|
fullNode bool
|
||||||
|
confirmationsEnabled bool
|
||||||
|
rateLimitsMu sync.Mutex
|
||||||
|
rateLimits RateLimits
|
||||||
|
|
||||||
|
known mapset.Set // Messages already known by the peer to avoid wasting bandwidth
|
||||||
|
|
||||||
|
quit chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// newPeer creates a new waku peer object, but does not run the handshake itself.
|
||||||
|
func newPeer(host *Waku, remote *p2p.Peer, rw p2p.MsgReadWriter, logger *zap.Logger) *Peer {
|
||||||
|
if logger == nil {
|
||||||
|
logger = zap.NewNop()
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Peer{
|
||||||
|
host: host,
|
||||||
|
peer: remote,
|
||||||
|
ws: rw,
|
||||||
|
logger: logger,
|
||||||
|
trusted: false,
|
||||||
|
powRequirement: 0.0,
|
||||||
|
known: mapset.NewSet(),
|
||||||
|
quit: make(chan struct{}),
|
||||||
|
bloomFilter: MakeFullNodeBloom(),
|
||||||
|
fullNode: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start initiates the peer updater, periodically broadcasting the waku packets
|
||||||
|
// into the network.
|
||||||
|
func (p *Peer) start() {
|
||||||
|
go p.update()
|
||||||
|
p.logger.Debug("starting peer", zap.Binary("peerID", p.ID()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop terminates the peer updater, stopping message forwarding to it.
|
||||||
|
func (p *Peer) stop() {
|
||||||
|
close(p.quit)
|
||||||
|
p.logger.Debug("stopping peer", zap.Binary("peerID", p.ID()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// handshake sends the protocol initiation status message to the remote peer and
|
||||||
|
// verifies the remote status too.
|
||||||
|
func (p *Peer) handshake() error {
|
||||||
|
// Send the handshake status message asynchronously
|
||||||
|
errc := make(chan error, 1)
|
||||||
|
isLightNode := p.host.LightClientMode()
|
||||||
|
isRestrictedLightNodeConnection := p.host.LightClientModeConnectionRestricted()
|
||||||
|
go func() {
|
||||||
|
pow := p.host.MinPow()
|
||||||
|
powConverted := math.Float64bits(pow)
|
||||||
|
bloom := p.host.BloomFilter()
|
||||||
|
confirmationsEnabled := p.host.ConfirmationsEnabled()
|
||||||
|
rateLimits := p.host.RateLimits()
|
||||||
|
|
||||||
|
errc <- p2p.SendItems(p.ws, statusCode, ProtocolVersion, powConverted, bloom, isLightNode, confirmationsEnabled, rateLimits)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Fetch the remote status packet and verify protocol match
|
||||||
|
packet, err := p.ws.ReadMsg()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if packet.Code != statusCode {
|
||||||
|
return fmt.Errorf("p [%x] sent packet %x before status packet", p.ID(), packet.Code)
|
||||||
|
}
|
||||||
|
s := rlp.NewStream(packet.Payload, uint64(packet.Size))
|
||||||
|
_, err = s.List()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("p [%x] sent bad status message: %v", p.ID(), err)
|
||||||
|
}
|
||||||
|
peerVersion, err := s.Uint()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("p [%x] sent bad status message (unable to decode version): %v", p.ID(), err)
|
||||||
|
}
|
||||||
|
if peerVersion != ProtocolVersion {
|
||||||
|
return fmt.Errorf("p [%x]: protocol version mismatch %d != %d", p.ID(), peerVersion, ProtocolVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// only version is mandatory, subsequent parameters are optional
|
||||||
|
powRaw, err := s.Uint()
|
||||||
|
if err == nil {
|
||||||
|
pow := math.Float64frombits(powRaw)
|
||||||
|
if math.IsInf(pow, 0) || math.IsNaN(pow) || pow < 0.0 {
|
||||||
|
return fmt.Errorf("p [%x] sent bad status message: invalid pow", p.ID())
|
||||||
|
}
|
||||||
|
p.powRequirement = pow
|
||||||
|
|
||||||
|
var bloom []byte
|
||||||
|
err = s.Decode(&bloom)
|
||||||
|
if err == nil {
|
||||||
|
sz := len(bloom)
|
||||||
|
if sz != BloomFilterSize && sz != 0 {
|
||||||
|
return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), sz)
|
||||||
|
}
|
||||||
|
p.setBloomFilter(bloom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isRemotePeerLightNode, _ := s.Bool()
|
||||||
|
if isRemotePeerLightNode && isLightNode && isRestrictedLightNodeConnection {
|
||||||
|
return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID())
|
||||||
|
}
|
||||||
|
confirmationsEnabled, err := s.Bool()
|
||||||
|
if err != nil || !confirmationsEnabled {
|
||||||
|
p.logger.Info("confirmations are disabled for peer", zap.Binary("peer", p.ID()))
|
||||||
|
} else {
|
||||||
|
p.confirmationsEnabled = confirmationsEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
var rateLimits RateLimits
|
||||||
|
if err := s.Decode(&rateLimits); err != nil {
|
||||||
|
p.logger.Info("rate limiting is disabled for peer", zap.Binary("peer", p.ID()))
|
||||||
|
} else {
|
||||||
|
p.setRateLimits(rateLimits)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := <-errc; err != nil {
|
||||||
|
return fmt.Errorf("p [%x] failed to send status packet: %v", p.ID(), err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// update executes periodic operations on the peer, including message transmission
|
||||||
|
// and expiration.
|
||||||
|
func (p *Peer) update() {
|
||||||
|
// Start the tickers for the updates
|
||||||
|
expire := time.NewTicker(expirationCycle)
|
||||||
|
transmit := time.NewTicker(transmissionCycle)
|
||||||
|
|
||||||
|
// Loop and transmit until termination is requested
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-expire.C:
|
||||||
|
p.expire()
|
||||||
|
|
||||||
|
case <-transmit.C:
|
||||||
|
if err := p.broadcast(); err != nil {
|
||||||
|
p.logger.Debug("broadcasting failed", zap.Binary("peer", p.ID()), zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case <-p.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark marks an envelope known to the peer so that it won't be sent back.
|
||||||
|
func (p *Peer) mark(envelope *Envelope) {
|
||||||
|
p.known.Add(envelope.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
// marked checks if an envelope is already known to the remote peer.
|
||||||
|
func (p *Peer) marked(envelope *Envelope) bool {
|
||||||
|
return p.known.Contains(envelope.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
// expire iterates over all the known envelopes in the host and removes all
|
||||||
|
// expired (unknown) ones from the known list.
|
||||||
|
func (p *Peer) expire() {
|
||||||
|
unmark := make(map[common.Hash]struct{})
|
||||||
|
p.known.Each(func(v interface{}) bool {
|
||||||
|
if !p.host.isEnvelopeCached(v.(common.Hash)) {
|
||||||
|
unmark[v.(common.Hash)] = struct{}{}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
// Dump all known but no longer cached
|
||||||
|
for hash := range unmark {
|
||||||
|
p.known.Remove(hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// broadcast iterates over the collection of envelopes and transmits yet unknown
|
||||||
|
// ones over the network.
|
||||||
|
func (p *Peer) broadcast() error {
|
||||||
|
envelopes := p.host.Envelopes()
|
||||||
|
bundle := make([]*Envelope, 0, len(envelopes))
|
||||||
|
for _, envelope := range envelopes {
|
||||||
|
if !p.marked(envelope) && envelope.PoW() >= p.powRequirement && p.bloomMatch(envelope) {
|
||||||
|
bundle = append(bundle, envelope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(bundle) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
batchHash, err := sendBundle(p.ws, bundle)
|
||||||
|
if err != nil {
|
||||||
|
p.logger.Debug("failed to deliver envelopes", zap.Binary("peer", p.ID()), zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark envelopes only if they were successfully sent
|
||||||
|
for _, e := range bundle {
|
||||||
|
p.mark(e)
|
||||||
|
event := EnvelopeEvent{
|
||||||
|
Event: EventEnvelopeSent,
|
||||||
|
Hash: e.Hash(),
|
||||||
|
Peer: p.peer.ID(),
|
||||||
|
}
|
||||||
|
if p.confirmationsEnabled {
|
||||||
|
event.Batch = batchHash
|
||||||
|
}
|
||||||
|
p.host.envelopeFeed.Send(event)
|
||||||
|
}
|
||||||
|
p.logger.Debug("broadcasted bundles successfully", zap.Binary("peer", p.ID()), zap.Int("count", len(bundle)))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns a peer's id
|
||||||
|
func (p *Peer) ID() []byte {
|
||||||
|
id := p.peer.ID()
|
||||||
|
return id[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Peer) notifyAboutPowRequirementChange(pow float64) error {
|
||||||
|
i := math.Float64bits(pow)
|
||||||
|
return p2p.Send(p.ws, powRequirementCode, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Peer) notifyAboutBloomFilterChange(bloom []byte) error {
|
||||||
|
return p2p.Send(p.ws, bloomFilterExCode, bloom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Peer) bloomMatch(env *Envelope) bool {
|
||||||
|
p.bloomMu.Lock()
|
||||||
|
defer p.bloomMu.Unlock()
|
||||||
|
return p.fullNode || BloomFilterMatch(p.bloomFilter, env.Bloom())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Peer) setBloomFilter(bloom []byte) {
|
||||||
|
p.bloomMu.Lock()
|
||||||
|
defer p.bloomMu.Unlock()
|
||||||
|
p.bloomFilter = bloom
|
||||||
|
p.fullNode = isFullNode(bloom)
|
||||||
|
if p.fullNode && p.bloomFilter == nil {
|
||||||
|
p.bloomFilter = MakeFullNodeBloom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Peer) setRateLimits(r RateLimits) {
|
||||||
|
p.rateLimitsMu.Lock()
|
||||||
|
p.rateLimits = r
|
||||||
|
p.rateLimitsMu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeFullNodeBloom() []byte {
|
||||||
|
bloom := make([]byte, BloomFilterSize)
|
||||||
|
for i := 0; i < BloomFilterSize; i++ {
|
||||||
|
bloom[i] = 0xFF
|
||||||
|
}
|
||||||
|
return bloom
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendBundle(rw p2p.MsgWriter, bundle []*Envelope) (rst common.Hash, err error) {
|
||||||
|
data, err := rlp.EncodeToBytes(bundle)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = rw.WriteMsg(p2p.Msg{
|
||||||
|
Code: messagesCode,
|
||||||
|
Size: uint32(len(data)),
|
||||||
|
Payload: bytes.NewBuffer(data),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return crypto.Keccak256Hash(data), nil
|
||||||
|
}
|
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tsenart/tb"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
)
|
||||||
|
|
||||||
|
type runLoop func(p *Peer, rw p2p.MsgReadWriter) error
|
||||||
|
|
||||||
|
type RateLimiterHandler interface {
|
||||||
|
ExceedPeerLimit() error
|
||||||
|
ExceedIPLimit() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetricsRateLimiterHandler struct{}
|
||||||
|
|
||||||
|
func (MetricsRateLimiterHandler) ExceedPeerLimit() error {
|
||||||
|
rateLimitsExceeded.WithLabelValues("peer_id").Inc()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (MetricsRateLimiterHandler) ExceedIPLimit() error {
|
||||||
|
rateLimitsExceeded.WithLabelValues("ip").Inc()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrRateLimitExceeded = errors.New("rate limit has been exceeded")
|
||||||
|
|
||||||
|
type DropPeerRateLimiterHandler struct {
|
||||||
|
// Tolerance is a number of how many a limit must be exceeded
|
||||||
|
// in order to drop a peer.
|
||||||
|
Tolerance int64
|
||||||
|
|
||||||
|
peerLimitExceeds int64
|
||||||
|
ipLimitExceeds int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *DropPeerRateLimiterHandler) ExceedPeerLimit() error {
|
||||||
|
h.peerLimitExceeds++
|
||||||
|
if h.Tolerance > 0 && h.peerLimitExceeds >= h.Tolerance {
|
||||||
|
return ErrRateLimitExceeded
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *DropPeerRateLimiterHandler) ExceedIPLimit() error {
|
||||||
|
h.ipLimitExceeds++
|
||||||
|
if h.Tolerance > 0 && h.ipLimitExceeds >= h.Tolerance {
|
||||||
|
return ErrRateLimitExceeded
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type PeerRateLimiterConfig struct {
|
||||||
|
LimitPerSecIP int64
|
||||||
|
LimitPerSecPeerID int64
|
||||||
|
WhitelistedIPs []string
|
||||||
|
WhitelistedPeerIDs []enode.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultPeerRateLimiterConfig = PeerRateLimiterConfig{
|
||||||
|
LimitPerSecIP: 10,
|
||||||
|
LimitPerSecPeerID: 5,
|
||||||
|
WhitelistedIPs: nil,
|
||||||
|
WhitelistedPeerIDs: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
type PeerRateLimiter struct {
|
||||||
|
peerIDThrottler *tb.Throttler
|
||||||
|
ipThrottler *tb.Throttler
|
||||||
|
|
||||||
|
limitPerSecIP int64
|
||||||
|
limitPerSecPeerID int64
|
||||||
|
|
||||||
|
whitelistedPeerIDs []enode.ID
|
||||||
|
whitelistedIPs []string
|
||||||
|
|
||||||
|
handlers []RateLimiterHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPeerRateLimiter(cfg *PeerRateLimiterConfig, handlers ...RateLimiterHandler) *PeerRateLimiter {
|
||||||
|
if cfg == nil {
|
||||||
|
copy := defaultPeerRateLimiterConfig
|
||||||
|
cfg = ©
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PeerRateLimiter{
|
||||||
|
peerIDThrottler: tb.NewThrottler(time.Millisecond * 100),
|
||||||
|
ipThrottler: tb.NewThrottler(time.Millisecond * 100),
|
||||||
|
limitPerSecIP: cfg.LimitPerSecIP,
|
||||||
|
limitPerSecPeerID: cfg.LimitPerSecPeerID,
|
||||||
|
whitelistedPeerIDs: cfg.WhitelistedPeerIDs,
|
||||||
|
whitelistedIPs: cfg.WhitelistedIPs,
|
||||||
|
handlers: handlers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PeerRateLimiter) decorate(p *Peer, rw p2p.MsgReadWriter, runLoop runLoop) error {
|
||||||
|
in, out := p2p.MsgPipe()
|
||||||
|
defer in.Close()
|
||||||
|
defer out.Close()
|
||||||
|
errC := make(chan error, 1)
|
||||||
|
|
||||||
|
// Read from the original reader and write to the message pipe.
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
packet, err := rw.ReadMsg()
|
||||||
|
if err != nil {
|
||||||
|
errC <- fmt.Errorf("failed to read packet: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rateLimitsProcessed.Inc()
|
||||||
|
|
||||||
|
var ip string
|
||||||
|
if p != nil && p.peer != nil {
|
||||||
|
ip = p.peer.Node().IP().String()
|
||||||
|
}
|
||||||
|
if halted := r.throttleIP(ip); halted {
|
||||||
|
for _, h := range r.handlers {
|
||||||
|
if err := h.ExceedIPLimit(); err != nil {
|
||||||
|
errC <- fmt.Errorf("exceed rate limit by IP: %w", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var peerID []byte
|
||||||
|
if p != nil {
|
||||||
|
peerID = p.ID()
|
||||||
|
}
|
||||||
|
if halted := r.throttlePeer(peerID); halted {
|
||||||
|
for _, h := range r.handlers {
|
||||||
|
if err := h.ExceedPeerLimit(); err != nil {
|
||||||
|
errC <- fmt.Errorf("exceeded rate limit by peer: %w", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := in.WriteMsg(packet); err != nil {
|
||||||
|
errC <- fmt.Errorf("failed to write packet to pipe: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Read from the message pipe and write to the original writer.
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
packet, err := in.ReadMsg()
|
||||||
|
if err != nil {
|
||||||
|
errC <- fmt.Errorf("failed to read packet from pipe: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := rw.WriteMsg(packet); err != nil {
|
||||||
|
errC <- fmt.Errorf("failed to write packet: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
errC <- runLoop(p, out)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return <-errC
|
||||||
|
}
|
||||||
|
|
||||||
|
// throttleIP throttles a number of messages incoming from a given IP.
|
||||||
|
// It allows 10 packets per second.
|
||||||
|
func (r *PeerRateLimiter) throttleIP(ip string) bool {
|
||||||
|
if r.limitPerSecIP == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if stringSliceContains(r.whitelistedIPs, ip) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return r.ipThrottler.Halt(ip, 1, r.limitPerSecIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
// throttlePeer throttles a number of messages incoming from a peer.
|
||||||
|
// It allows 3 packets per second.
|
||||||
|
func (r *PeerRateLimiter) throttlePeer(peerID []byte) bool {
|
||||||
|
if r.limitPerSecIP == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var id enode.ID
|
||||||
|
copy(id[:], peerID)
|
||||||
|
if enodeIDSliceContains(r.whitelistedPeerIDs, id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return r.peerIDThrottler.Halt(id.String(), 1, r.limitPerSecPeerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringSliceContains(s []string, searched string) bool {
|
||||||
|
for _, item := range s {
|
||||||
|
if item == searched {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func enodeIDSliceContains(s []enode.ID, searched enode.ID) bool {
|
||||||
|
for _, item := range s {
|
||||||
|
if bytes.Equal(item.Bytes(), searched.Bytes()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2019 The Waku Library Authors.
|
||||||
|
//
|
||||||
|
// The Waku library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The Waku library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty off
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This software uses the go-ethereum library, which is licensed
|
||||||
|
// under the GNU Lesser General Public Library, version 3 or any later.
|
||||||
|
|
||||||
|
package waku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TopicType represents a cryptographically secure, probabilistic partial
|
||||||
|
// classifications of a message, determined as the first (left) 4 bytes of the
|
||||||
|
// SHA3 hash of some arbitrary data given by the original author of the message.
|
||||||
|
type TopicType [TopicLength]byte
|
||||||
|
|
||||||
|
// BytesToTopic converts from the byte array representation of a topic
|
||||||
|
// into the TopicType type.
|
||||||
|
func BytesToTopic(b []byte) (t TopicType) {
|
||||||
|
sz := TopicLength
|
||||||
|
if x := len(b); x < TopicLength {
|
||||||
|
sz = x
|
||||||
|
}
|
||||||
|
for i := 0; i < sz; i++ {
|
||||||
|
t[i] = b[i]
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// String converts a topic byte array to a string representation.
|
||||||
|
func (t *TopicType) String() string {
|
||||||
|
return hexutil.Encode(t[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText returns the hex representation of t.
|
||||||
|
func (t TopicType) MarshalText() ([]byte, error) {
|
||||||
|
return hexutil.Bytes(t[:]).MarshalText()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText parses a hex representation to a topic.
|
||||||
|
func (t *TopicType) UnmarshalText(input []byte) error {
|
||||||
|
return hexutil.UnmarshalFixedText("Topic", input, t[:])
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -105,10 +105,9 @@ const (
|
||||||
// in order to bypass the expiry checks.
|
// in order to bypass the expiry checks.
|
||||||
type MailServer interface {
|
type MailServer interface {
|
||||||
Archive(env *Envelope)
|
Archive(env *Envelope)
|
||||||
// DEPRECATED
|
DeliverMail(peerID []byte, req *Envelope) // DEPRECATED; user Deliver instead
|
||||||
DeliverMail(whisperPeer *Peer, request *Envelope)
|
Deliver(peerID []byte, req MessagesRequest)
|
||||||
Deliver(whisperPeer *Peer, request MessagesRequest)
|
SyncMail(peerID []byte, req SyncMailRequest) error
|
||||||
SyncMail(*Peer, SyncMailRequest) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessagesRequest contains details of a request of historic messages.
|
// MessagesRequest contains details of a request of historic messages.
|
||||||
|
|
|
@ -6,37 +6,37 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
envelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{
|
envelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_received_total",
|
Name: "whisper_envelopes_received_total",
|
||||||
Help: "Number of envelopes received.",
|
Help: "Number of envelopes received.",
|
||||||
})
|
})
|
||||||
envelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{
|
envelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_validated_total",
|
Name: "whisper_envelopes_validated_total",
|
||||||
Help: "Number of envelopes processed successfully.",
|
Help: "Number of envelopes processed successfully.",
|
||||||
})
|
})
|
||||||
envelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_rejected_total",
|
Name: "whisper_envelopes_rejected_total",
|
||||||
Help: "Number of envelopes rejected.",
|
Help: "Number of envelopes rejected.",
|
||||||
}, []string{"reason"})
|
}, []string{"reason"})
|
||||||
envelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_cache_failures_total",
|
Name: "whisper_envelopes_cache_failures_total",
|
||||||
Help: "Number of envelopes which failed to be cached.",
|
Help: "Number of envelopes which failed to be cached.",
|
||||||
}, []string{"type"})
|
}, []string{"type"})
|
||||||
envelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_cached_total",
|
Name: "whisper_envelopes_cached_total",
|
||||||
Help: "Number of envelopes cached.",
|
Help: "Number of envelopes cached.",
|
||||||
}, []string{"cache"})
|
}, []string{"cache"})
|
||||||
envelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{
|
envelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{
|
||||||
Name: "waku_envelopes_size_bytes",
|
Name: "whisper_envelopes_size_bytes",
|
||||||
Help: "Size of processed Waku envelopes in bytes.",
|
Help: "Size of processed Waku envelopes in bytes.",
|
||||||
Buckets: prom.ExponentialBuckets(256, 4, 10),
|
Buckets: prom.ExponentialBuckets(256, 4, 10),
|
||||||
})
|
})
|
||||||
// rate limiter metrics
|
// rate limiter metrics
|
||||||
rateLimitsProcessed = prom.NewCounter(prom.CounterOpts{
|
rateLimitsProcessed = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_rate_limits_processed_total",
|
Name: "whisper_rate_limits_processed_total",
|
||||||
Help: "Number of packets Waku rate limiter processed.",
|
Help: "Number of packets Waku rate limiter processed.",
|
||||||
})
|
})
|
||||||
rateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{
|
rateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_rate_limits_exceeded_total",
|
Name: "whisper_rate_limits_exceeded_total",
|
||||||
Help: "Number of times the Waku rate limits were exceeded",
|
Help: "Number of times the Waku rate limits were exceeded",
|
||||||
}, []string{"type"})
|
}, []string{"type"})
|
||||||
)
|
)
|
||||||
|
|
|
@ -104,7 +104,7 @@ type Whisper struct {
|
||||||
statsMu sync.Mutex // guard stats
|
statsMu sync.Mutex // guard stats
|
||||||
stats Statistics // Statistics of whisper node
|
stats Statistics // Statistics of whisper node
|
||||||
|
|
||||||
mailServer MailServer // MailServer interface
|
mailServer MailServer
|
||||||
|
|
||||||
rateLimiter *PeerRateLimiter
|
rateLimiter *PeerRateLimiter
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ func (whisper *Whisper) GetCurrentTime() time.Time {
|
||||||
|
|
||||||
// RegisterServer registers MailServer interface.
|
// RegisterServer registers MailServer interface.
|
||||||
// MailServer will process all the incoming messages with p2pRequestCode.
|
// MailServer will process all the incoming messages with p2pRequestCode.
|
||||||
func (whisper *Whisper) RegisterServer(server MailServer) {
|
func (whisper *Whisper) RegisterMailServer(server MailServer) {
|
||||||
whisper.mailServer = server
|
whisper.mailServer = server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,12 +502,15 @@ func (whisper *Whisper) expireRequestHistoricMessages(peer enode.ID, hash common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (whisper *Whisper) SendHistoricMessageResponse(peer *Peer, payload []byte) error {
|
func (whisper *Whisper) SendHistoricMessageResponse(peerID []byte, payload []byte) error {
|
||||||
size, r, err := rlp.EncodeToReader(payload)
|
size, r, err := rlp.EncodeToReader(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,29 +533,37 @@ func (whisper *Whisper) SyncMessages(peerID []byte, req SyncMailRequest) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
// SendSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
||||||
func (whisper *Whisper) SendSyncResponse(p *Peer, data SyncResponse) error {
|
func (whisper *Whisper) SendSyncResponse(peerID []byte, data SyncResponse) error {
|
||||||
return p2p.Send(p.ws, p2pSyncResponseCode, data)
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p2p.Send(peer.ws, p2pSyncResponseCode, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
// SendRawSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
||||||
func (whisper *Whisper) SendRawSyncResponse(p *Peer, data RawSyncResponse) error {
|
func (whisper *Whisper) SendRawSyncResponse(peerID []byte, data RawSyncResponse) error {
|
||||||
return p2p.Send(p.ws, p2pSyncResponseCode, data)
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p2p.Send(peer.ws, p2pSyncResponseCode, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendP2PMessage sends a peer-to-peer message to a specific peer.
|
// SendP2PMessage sends a peer-to-peer message to a specific peer.
|
||||||
func (whisper *Whisper) SendP2PMessage(peerID []byte, envelopes ...*Envelope) error {
|
func (whisper *Whisper) SendP2PMessage(peerID []byte, envelopes ...*Envelope) error {
|
||||||
p, err := whisper.getPeer(peerID)
|
return whisper.SendP2PDirect(peerID, envelopes...)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return whisper.SendP2PDirect(p, envelopes...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
||||||
// If only a single envelope is given, data is sent as a single object
|
// If only a single envelope is given, data is sent as a single object
|
||||||
// rather than a slice. This is important to keep this method backward compatible
|
// rather than a slice. This is important to keep this method backward compatible
|
||||||
// as it used to send only single envelopes.
|
// as it used to send only single envelopes.
|
||||||
func (whisper *Whisper) SendP2PDirect(peer *Peer, envelopes ...*Envelope) error {
|
func (whisper *Whisper) SendP2PDirect(peerID []byte, envelopes ...*Envelope) error {
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if len(envelopes) == 1 {
|
if len(envelopes) == 1 {
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
||||||
}
|
}
|
||||||
|
@ -563,7 +574,11 @@ func (whisper *Whisper) SendP2PDirect(peer *Peer, envelopes ...*Envelope) error
|
||||||
// If only a single envelope is given, data is sent as a single object
|
// If only a single envelope is given, data is sent as a single object
|
||||||
// rather than a slice. This is important to keep this method backward compatible
|
// rather than a slice. This is important to keep this method backward compatible
|
||||||
// as it used to send only single envelopes.
|
// as it used to send only single envelopes.
|
||||||
func (whisper *Whisper) SendRawP2PDirect(peer *Peer, envelopes ...rlp.RawValue) error {
|
func (whisper *Whisper) SendRawP2PDirect(peerID []byte, envelopes ...rlp.RawValue) error {
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if len(envelopes) == 1 {
|
if len(envelopes) == 1 {
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
||||||
}
|
}
|
||||||
|
@ -1099,13 +1114,13 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
return fmt.Errorf("sync mail request was invalid: %v", err)
|
return fmt.Errorf("sync mail request was invalid: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := whisper.mailServer.SyncMail(p, request); err != nil {
|
if err := whisper.mailServer.SyncMail(p.ID(), request); err != nil {
|
||||||
log.Error(
|
log.Error(
|
||||||
"failed to sync envelopes",
|
"failed to sync envelopes",
|
||||||
"peer", p.peer.ID().String(),
|
"peer", p.peer.ID().String(),
|
||||||
)
|
)
|
||||||
_ = whisper.SendSyncResponse(
|
_ = whisper.SendSyncResponse(
|
||||||
p,
|
p.ID(),
|
||||||
SyncResponse{Error: err.Error()},
|
SyncResponse{Error: err.Error()},
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
|
@ -1157,7 +1172,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
var requestDeprecated Envelope
|
var requestDeprecated Envelope
|
||||||
errDepReq := packet.Decode(&requestDeprecated)
|
errDepReq := packet.Decode(&requestDeprecated)
|
||||||
if errDepReq == nil {
|
if errDepReq == nil {
|
||||||
whisper.mailServer.DeliverMail(p, &requestDeprecated)
|
whisper.mailServer.DeliverMail(p.ID(), &requestDeprecated)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Info("failed to decode p2p request message (deprecated)", "peer", p.peer.ID(), "err", errDepReq)
|
log.Info("failed to decode p2p request message (deprecated)", "peer", p.peer.ID(), "err", errDepReq)
|
||||||
|
@ -1172,7 +1187,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
var request MessagesRequest
|
var request MessagesRequest
|
||||||
errReq := packet.Decode(&request)
|
errReq := packet.Decode(&request)
|
||||||
if errReq == nil {
|
if errReq == nil {
|
||||||
whisper.mailServer.Deliver(p, request)
|
whisper.mailServer.Deliver(p.ID(), request)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Info("failed to decode p2p request message", "peer", p.peer.ID(), "err", errReq)
|
log.Info("failed to decode p2p request message", "peer", p.peer.ID(), "err", errReq)
|
||||||
|
|
|
@ -3,7 +3,7 @@ github.com/BurntSushi/toml
|
||||||
# github.com/allegro/bigcache v1.2.0
|
# github.com/allegro/bigcache v1.2.0
|
||||||
github.com/allegro/bigcache
|
github.com/allegro/bigcache
|
||||||
github.com/allegro/bigcache/queue
|
github.com/allegro/bigcache/queue
|
||||||
# github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708
|
# github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40
|
||||||
github.com/aristanetworks/goarista/monotime
|
github.com/aristanetworks/goarista/monotime
|
||||||
# github.com/beevik/ntp v0.2.0
|
# github.com/beevik/ntp v0.2.0
|
||||||
github.com/beevik/ntp
|
github.com/beevik/ntp
|
||||||
|
@ -28,7 +28,7 @@ github.com/davecgh/go-spew/spew
|
||||||
github.com/deckarep/golang-set
|
github.com/deckarep/golang-set
|
||||||
# github.com/edsrzf/mmap-go v1.0.0
|
# github.com/edsrzf/mmap-go v1.0.0
|
||||||
github.com/edsrzf/mmap-go
|
github.com/edsrzf/mmap-go
|
||||||
# github.com/elastic/gosigar v0.10.4
|
# github.com/elastic/gosigar v0.10.5
|
||||||
github.com/elastic/gosigar
|
github.com/elastic/gosigar
|
||||||
github.com/elastic/gosigar/sys/windows
|
github.com/elastic/gosigar/sys/windows
|
||||||
# github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.7
|
# github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.7
|
||||||
|
@ -167,7 +167,7 @@ github.com/ipfs/go-log/tracer/wire
|
||||||
github.com/ipfs/go-log/writer
|
github.com/ipfs/go-log/writer
|
||||||
# github.com/jackpal/gateway v1.0.5
|
# github.com/jackpal/gateway v1.0.5
|
||||||
github.com/jackpal/gateway
|
github.com/jackpal/gateway
|
||||||
# github.com/jackpal/go-nat-pmp v1.0.1
|
# github.com/jackpal/go-nat-pmp v1.0.2
|
||||||
github.com/jackpal/go-nat-pmp
|
github.com/jackpal/go-nat-pmp
|
||||||
# github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2
|
# github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2
|
||||||
github.com/jbenet/go-temp-err-catcher
|
github.com/jbenet/go-temp-err-catcher
|
||||||
|
@ -343,7 +343,7 @@ github.com/prometheus/procfs/internal/util
|
||||||
github.com/prometheus/tsdb/fileutil
|
github.com/prometheus/tsdb/fileutil
|
||||||
# github.com/rjeczalik/notify v0.9.2
|
# github.com/rjeczalik/notify v0.9.2
|
||||||
github.com/rjeczalik/notify
|
github.com/rjeczalik/notify
|
||||||
# github.com/rs/cors v1.6.0
|
# github.com/rs/cors v1.7.0
|
||||||
github.com/rs/cors
|
github.com/rs/cors
|
||||||
# github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
|
# github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
|
||||||
github.com/russolsen/transit
|
github.com/russolsen/transit
|
||||||
|
@ -397,6 +397,8 @@ github.com/status-im/status-go/protocol/transport/whisper
|
||||||
github.com/status-im/status-go/protocol/transport/whisper/migrations
|
github.com/status-im/status-go/protocol/transport/whisper/migrations
|
||||||
github.com/status-im/status-go/protocol/v1
|
github.com/status-im/status-go/protocol/v1
|
||||||
github.com/status-im/status-go/protocol/zaputil
|
github.com/status-im/status-go/protocol/zaputil
|
||||||
|
# github.com/status-im/status-go/waku v1.0.0 => ./waku
|
||||||
|
github.com/status-im/status-go/waku
|
||||||
# github.com/status-im/status-go/whisper/v6 v6.0.1 => ./whisper
|
# github.com/status-im/status-go/whisper/v6 v6.0.1 => ./whisper
|
||||||
github.com/status-im/status-go/whisper/v6
|
github.com/status-im/status-go/whisper/v6
|
||||||
# github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
|
# github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
|
||||||
|
@ -487,7 +489,7 @@ go.uber.org/zap/internal/bufferpool
|
||||||
go.uber.org/zap/internal/color
|
go.uber.org/zap/internal/color
|
||||||
go.uber.org/zap/internal/exit
|
go.uber.org/zap/internal/exit
|
||||||
go.uber.org/zap/zapcore
|
go.uber.org/zap/zapcore
|
||||||
# golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
|
# golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
|
||||||
golang.org/x/crypto/blake2s
|
golang.org/x/crypto/blake2s
|
||||||
golang.org/x/crypto/curve25519
|
golang.org/x/crypto/curve25519
|
||||||
golang.org/x/crypto/ed25519
|
golang.org/x/crypto/ed25519
|
||||||
|
|
|
@ -26,10 +26,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/common/log"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
|
@ -89,8 +89,8 @@ const (
|
||||||
// in order to bypass the expiry checks.
|
// in order to bypass the expiry checks.
|
||||||
type MailServer interface {
|
type MailServer interface {
|
||||||
Archive(env *Envelope)
|
Archive(env *Envelope)
|
||||||
DeliverMail(wakuPeer *Peer, request *Envelope) // DEPRECATED
|
DeliverMail(peerID []byte, request *Envelope) // DEPRECATED; use Deliver()
|
||||||
Deliver(wakuPeer *Peer, request MessagesRequest)
|
Deliver(peerID []byte, request MessagesRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessagesRequest contains details of a request of historic messages.
|
// MessagesRequest contains details of a request of historic messages.
|
||||||
|
|
|
@ -29,11 +29,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/common/log"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/ecies"
|
"github.com/ethereum/go-ethereum/crypto/ecies"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessageParams specifies the exact way a message should be wrapped
|
// MessageParams specifies the exact way a message should be wrapped
|
||||||
|
|
24
waku/waku.go
24
waku/waku.go
|
@ -87,7 +87,7 @@ type Waku struct {
|
||||||
settings settings // Holds configuration settings that can be dynamically changed
|
settings settings // Holds configuration settings that can be dynamically changed
|
||||||
settingsMu sync.RWMutex // Mutex to sync the settings access
|
settingsMu sync.RWMutex // Mutex to sync the settings access
|
||||||
|
|
||||||
mailServer MailServer // MailServer interface
|
mailServer MailServer
|
||||||
|
|
||||||
rateLimiter *PeerRateLimiter
|
rateLimiter *PeerRateLimiter
|
||||||
|
|
||||||
|
@ -480,11 +480,15 @@ func (w *Waku) expireRequestHistoricMessages(peer enode.ID, hash common.Hash, ti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Waku) SendHistoricMessageResponse(peer *Peer, payload []byte) error {
|
func (w *Waku) SendHistoricMessageResponse(peerID []byte, payload []byte) error {
|
||||||
size, r, err := rlp.EncodeToReader(payload)
|
size, r, err := rlp.EncodeToReader(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
peer, err := w.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,13 +504,21 @@ func (w *Waku) SendP2PMessages(peerID []byte, envelopes ...*Envelope) error {
|
||||||
|
|
||||||
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
||||||
// It sends one or more envelopes in a single batch.
|
// It sends one or more envelopes in a single batch.
|
||||||
func (w *Waku) SendP2PDirect(peer *Peer, envelopes ...*Envelope) error {
|
func (w *Waku) SendP2PDirect(peerID []byte, envelopes ...*Envelope) error {
|
||||||
|
peer, err := w.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes)
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawP2PDirect sends a peer-to-peer message to a specific peer.
|
// SendRawP2PDirect sends a peer-to-peer message to a specific peer.
|
||||||
// It sends one or more envelopes in a single batch.
|
// It sends one or more envelopes in a single batch.
|
||||||
func (w *Waku) SendRawP2PDirect(peer *Peer, envelopes ...rlp.RawValue) error {
|
func (w *Waku) SendRawP2PDirect(peerID []byte, envelopes ...rlp.RawValue) error {
|
||||||
|
peer, err := w.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes)
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,7 +1062,7 @@ func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger)
|
||||||
var requestDeprecated Envelope
|
var requestDeprecated Envelope
|
||||||
errDepReq := packet.Decode(&requestDeprecated)
|
errDepReq := packet.Decode(&requestDeprecated)
|
||||||
if errDepReq == nil {
|
if errDepReq == nil {
|
||||||
w.mailServer.DeliverMail(p, &requestDeprecated)
|
w.mailServer.DeliverMail(p.ID(), &requestDeprecated)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
logger.Info("failed to decode p2p request message (deprecated)", zap.Binary("peer", peerID[:]), zap.Error(errDepReq))
|
logger.Info("failed to decode p2p request message (deprecated)", zap.Binary("peer", peerID[:]), zap.Error(errDepReq))
|
||||||
|
@ -1065,7 +1077,7 @@ func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger)
|
||||||
var request MessagesRequest
|
var request MessagesRequest
|
||||||
errReq := packet.Decode(&request)
|
errReq := packet.Decode(&request)
|
||||||
if errReq == nil {
|
if errReq == nil {
|
||||||
w.mailServer.Deliver(p, request)
|
w.mailServer.Deliver(p.ID(), request)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
logger.Info("failed to decode p2p request message", zap.Binary("peer", peerID[:]), zap.Error(errDepReq))
|
logger.Info("failed to decode p2p request message", zap.Binary("peer", peerID[:]), zap.Error(errDepReq))
|
||||||
|
|
|
@ -105,10 +105,9 @@ const (
|
||||||
// in order to bypass the expiry checks.
|
// in order to bypass the expiry checks.
|
||||||
type MailServer interface {
|
type MailServer interface {
|
||||||
Archive(env *Envelope)
|
Archive(env *Envelope)
|
||||||
// DEPRECATED
|
DeliverMail(peerID []byte, req *Envelope) // DEPRECATED; user Deliver instead
|
||||||
DeliverMail(whisperPeer *Peer, request *Envelope)
|
Deliver(peerID []byte, req MessagesRequest)
|
||||||
Deliver(whisperPeer *Peer, request MessagesRequest)
|
SyncMail(peerID []byte, req SyncMailRequest) error
|
||||||
SyncMail(*Peer, SyncMailRequest) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessagesRequest contains details of a request of historic messages.
|
// MessagesRequest contains details of a request of historic messages.
|
||||||
|
|
|
@ -6,37 +6,37 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
envelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{
|
envelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_received_total",
|
Name: "whisper_envelopes_received_total",
|
||||||
Help: "Number of envelopes received.",
|
Help: "Number of envelopes received.",
|
||||||
})
|
})
|
||||||
envelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{
|
envelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_validated_total",
|
Name: "whisper_envelopes_validated_total",
|
||||||
Help: "Number of envelopes processed successfully.",
|
Help: "Number of envelopes processed successfully.",
|
||||||
})
|
})
|
||||||
envelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_rejected_total",
|
Name: "whisper_envelopes_rejected_total",
|
||||||
Help: "Number of envelopes rejected.",
|
Help: "Number of envelopes rejected.",
|
||||||
}, []string{"reason"})
|
}, []string{"reason"})
|
||||||
envelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_cache_failures_total",
|
Name: "whisper_envelopes_cache_failures_total",
|
||||||
Help: "Number of envelopes which failed to be cached.",
|
Help: "Number of envelopes which failed to be cached.",
|
||||||
}, []string{"type"})
|
}, []string{"type"})
|
||||||
envelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{
|
envelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_envelopes_cached_total",
|
Name: "whisper_envelopes_cached_total",
|
||||||
Help: "Number of envelopes cached.",
|
Help: "Number of envelopes cached.",
|
||||||
}, []string{"cache"})
|
}, []string{"cache"})
|
||||||
envelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{
|
envelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{
|
||||||
Name: "waku_envelopes_size_bytes",
|
Name: "whisper_envelopes_size_bytes",
|
||||||
Help: "Size of processed Waku envelopes in bytes.",
|
Help: "Size of processed Waku envelopes in bytes.",
|
||||||
Buckets: prom.ExponentialBuckets(256, 4, 10),
|
Buckets: prom.ExponentialBuckets(256, 4, 10),
|
||||||
})
|
})
|
||||||
// rate limiter metrics
|
// rate limiter metrics
|
||||||
rateLimitsProcessed = prom.NewCounter(prom.CounterOpts{
|
rateLimitsProcessed = prom.NewCounter(prom.CounterOpts{
|
||||||
Name: "waku_rate_limits_processed_total",
|
Name: "whisper_rate_limits_processed_total",
|
||||||
Help: "Number of packets Waku rate limiter processed.",
|
Help: "Number of packets Waku rate limiter processed.",
|
||||||
})
|
})
|
||||||
rateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{
|
rateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{
|
||||||
Name: "waku_rate_limits_exceeded_total",
|
Name: "whisper_rate_limits_exceeded_total",
|
||||||
Help: "Number of times the Waku rate limits were exceeded",
|
Help: "Number of times the Waku rate limits were exceeded",
|
||||||
}, []string{"type"})
|
}, []string{"type"})
|
||||||
)
|
)
|
||||||
|
|
|
@ -104,7 +104,7 @@ type Whisper struct {
|
||||||
statsMu sync.Mutex // guard stats
|
statsMu sync.Mutex // guard stats
|
||||||
stats Statistics // Statistics of whisper node
|
stats Statistics // Statistics of whisper node
|
||||||
|
|
||||||
mailServer MailServer // MailServer interface
|
mailServer MailServer
|
||||||
|
|
||||||
rateLimiter *PeerRateLimiter
|
rateLimiter *PeerRateLimiter
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ func (whisper *Whisper) GetCurrentTime() time.Time {
|
||||||
|
|
||||||
// RegisterServer registers MailServer interface.
|
// RegisterServer registers MailServer interface.
|
||||||
// MailServer will process all the incoming messages with p2pRequestCode.
|
// MailServer will process all the incoming messages with p2pRequestCode.
|
||||||
func (whisper *Whisper) RegisterServer(server MailServer) {
|
func (whisper *Whisper) RegisterMailServer(server MailServer) {
|
||||||
whisper.mailServer = server
|
whisper.mailServer = server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,12 +502,15 @@ func (whisper *Whisper) expireRequestHistoricMessages(peer enode.ID, hash common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (whisper *Whisper) SendHistoricMessageResponse(peer *Peer, payload []byte) error {
|
func (whisper *Whisper) SendHistoricMessageResponse(peerID []byte, payload []byte) error {
|
||||||
size, r, err := rlp.EncodeToReader(payload)
|
size, r, err := rlp.EncodeToReader(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
return peer.ws.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,29 +533,37 @@ func (whisper *Whisper) SyncMessages(peerID []byte, req SyncMailRequest) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
// SendSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
||||||
func (whisper *Whisper) SendSyncResponse(p *Peer, data SyncResponse) error {
|
func (whisper *Whisper) SendSyncResponse(peerID []byte, data SyncResponse) error {
|
||||||
return p2p.Send(p.ws, p2pSyncResponseCode, data)
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p2p.Send(peer.ws, p2pSyncResponseCode, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
// SendRawSyncResponse sends a response to a Mail Server with a slice of envelopes.
|
||||||
func (whisper *Whisper) SendRawSyncResponse(p *Peer, data RawSyncResponse) error {
|
func (whisper *Whisper) SendRawSyncResponse(peerID []byte, data RawSyncResponse) error {
|
||||||
return p2p.Send(p.ws, p2pSyncResponseCode, data)
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p2p.Send(peer.ws, p2pSyncResponseCode, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendP2PMessage sends a peer-to-peer message to a specific peer.
|
// SendP2PMessage sends a peer-to-peer message to a specific peer.
|
||||||
func (whisper *Whisper) SendP2PMessage(peerID []byte, envelopes ...*Envelope) error {
|
func (whisper *Whisper) SendP2PMessage(peerID []byte, envelopes ...*Envelope) error {
|
||||||
p, err := whisper.getPeer(peerID)
|
return whisper.SendP2PDirect(peerID, envelopes...)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return whisper.SendP2PDirect(p, envelopes...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
// SendP2PDirect sends a peer-to-peer message to a specific peer.
|
||||||
// If only a single envelope is given, data is sent as a single object
|
// If only a single envelope is given, data is sent as a single object
|
||||||
// rather than a slice. This is important to keep this method backward compatible
|
// rather than a slice. This is important to keep this method backward compatible
|
||||||
// as it used to send only single envelopes.
|
// as it used to send only single envelopes.
|
||||||
func (whisper *Whisper) SendP2PDirect(peer *Peer, envelopes ...*Envelope) error {
|
func (whisper *Whisper) SendP2PDirect(peerID []byte, envelopes ...*Envelope) error {
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if len(envelopes) == 1 {
|
if len(envelopes) == 1 {
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
||||||
}
|
}
|
||||||
|
@ -563,7 +574,11 @@ func (whisper *Whisper) SendP2PDirect(peer *Peer, envelopes ...*Envelope) error
|
||||||
// If only a single envelope is given, data is sent as a single object
|
// If only a single envelope is given, data is sent as a single object
|
||||||
// rather than a slice. This is important to keep this method backward compatible
|
// rather than a slice. This is important to keep this method backward compatible
|
||||||
// as it used to send only single envelopes.
|
// as it used to send only single envelopes.
|
||||||
func (whisper *Whisper) SendRawP2PDirect(peer *Peer, envelopes ...rlp.RawValue) error {
|
func (whisper *Whisper) SendRawP2PDirect(peerID []byte, envelopes ...rlp.RawValue) error {
|
||||||
|
peer, err := whisper.getPeer(peerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if len(envelopes) == 1 {
|
if len(envelopes) == 1 {
|
||||||
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
return p2p.Send(peer.ws, p2pMessageCode, envelopes[0])
|
||||||
}
|
}
|
||||||
|
@ -1099,13 +1114,13 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
return fmt.Errorf("sync mail request was invalid: %v", err)
|
return fmt.Errorf("sync mail request was invalid: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := whisper.mailServer.SyncMail(p, request); err != nil {
|
if err := whisper.mailServer.SyncMail(p.ID(), request); err != nil {
|
||||||
log.Error(
|
log.Error(
|
||||||
"failed to sync envelopes",
|
"failed to sync envelopes",
|
||||||
"peer", p.peer.ID().String(),
|
"peer", p.peer.ID().String(),
|
||||||
)
|
)
|
||||||
_ = whisper.SendSyncResponse(
|
_ = whisper.SendSyncResponse(
|
||||||
p,
|
p.ID(),
|
||||||
SyncResponse{Error: err.Error()},
|
SyncResponse{Error: err.Error()},
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
|
@ -1157,7 +1172,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
var requestDeprecated Envelope
|
var requestDeprecated Envelope
|
||||||
errDepReq := packet.Decode(&requestDeprecated)
|
errDepReq := packet.Decode(&requestDeprecated)
|
||||||
if errDepReq == nil {
|
if errDepReq == nil {
|
||||||
whisper.mailServer.DeliverMail(p, &requestDeprecated)
|
whisper.mailServer.DeliverMail(p.ID(), &requestDeprecated)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Info("failed to decode p2p request message (deprecated)", "peer", p.peer.ID(), "err", errDepReq)
|
log.Info("failed to decode p2p request message (deprecated)", "peer", p.peer.ID(), "err", errDepReq)
|
||||||
|
@ -1172,7 +1187,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
var request MessagesRequest
|
var request MessagesRequest
|
||||||
errReq := packet.Decode(&request)
|
errReq := packet.Decode(&request)
|
||||||
if errReq == nil {
|
if errReq == nil {
|
||||||
whisper.mailServer.Deliver(p, request)
|
whisper.mailServer.Deliver(p.ID(), request)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Info("failed to decode p2p request message", "peer", p.peer.ID(), "err", errReq)
|
log.Info("failed to decode p2p request message", "peer", p.peer.ID(), "err", errReq)
|
||||||
|
|
Loading…
Reference in New Issue