From 849492fda9035c8a82a9a1ec8bb5a96634aeea78 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Fri, 21 Feb 2020 15:48:53 +0100 Subject: [PATCH] Add statusUpdate code (#1861) * Add status-option code This commits changes the behavior of waku introducing a new status-code, `2`, that replaces the current single options codes. * linting --- appdatabase/migrations/bindata.go | 90 +- .../migrations/sql/0005_waku_mode.down.sql | 0 .../migrations/sql/0005_waku_mode.up.sql | 2 + bridge/bridge.go | 4 +- bridge/bridge_test.go | 4 +- extkeys/go.mod | 5 +- extkeys/go.sum | 345 ++++ extkeys/mnemonic.go | 32 +- go.mod | 3 +- go.sum | 67 +- mailserver/migrations/bindata.go | 12 +- multiaccounts/accounts/database.go | 15 + multiaccounts/migrations/bindata.go | 12 +- node/geth_node.go | 1 + params/config.go | 4 + protocol/message_handler.go | 12 +- protocol/messenger_test.go | 67 +- protocol/persistence_legacy_test.go | 6 +- protocol/sqlite/db.go | 2 +- static/bindata.go | 28 +- t/bindata.go | 10 +- .../github.com/elastic/gosigar/CHANGELOG.md | 11 - vendor/github.com/elastic/gosigar/README.md | 1 - .../elastic/gosigar/sigar_darwin.go | 12 + .../elastic/gosigar/sigar_darwin_386.go | 18 - .../elastic/gosigar/sigar_darwin_amd64.go | 18 - .../elastic/gosigar/sigar_interface.go | 42 +- .../elastic/gosigar/sigar_windows.go | 22 +- .../elastic/gosigar/sys/windows/doc.go | 6 - .../gosigar/sys/windows/syscall_windows.go | 5 + .../gosigar/sys/windows/zsyscall_windows.go | 10 +- .../github.com/jackpal/go-nat-pmp/.travis.yml | 9 +- .../github.com/jackpal/go-nat-pmp/README.md | 48 +- .../github.com/jackpal/go-nat-pmp/natpmp.go | 27 +- .../github.com/jackpal/go-nat-pmp/network.go | 27 +- .../github.com/jackpal/go-nat-pmp/recorder.go | 6 +- vendor/github.com/rs/cors/.travis.yml | 3 +- vendor/github.com/rs/cors/cors.go | 32 +- vendor/github.com/rs/cors/utils.go | 2 +- .../status-im/status-go/waku/api.go | 600 ------- .../status-im/status-go/waku/config.go | 35 - .../status-im/status-go/waku/doc.go | 217 --- .../status-im/status-go/waku/envelope.go | 272 --- .../status-im/status-go/waku/events.go | 64 - .../status-im/status-go/waku/filter.go | 296 ---- .../status-im/status-go/waku/go.mod | 24 - .../status-im/status-go/waku/go.sum | 309 ---- .../status-im/status-go/waku/handshake.go | 125 -- .../status-go/waku/mailserver_response.go | 158 -- .../status-im/status-go/waku/message.go | 361 ---- .../status-im/status-go/waku/metrics.go | 70 - .../status-im/status-go/waku/peer.go | 318 ---- .../status-im/status-go/waku/rate_limiter.go | 236 --- .../status-im/status-go/waku/topic.go | 56 - .../status-im/status-go/waku/waku.go | 1555 ----------------- vendor/golang.org/x/sync/syncmap/go19.go | 17 - vendor/golang.org/x/sync/syncmap/map.go | 370 +++- vendor/golang.org/x/sync/syncmap/pre_go19.go | 370 ---- vendor/modules.txt | 14 +- waku/api.go | 14 +- waku/config.go | 1 + waku/doc.go | 19 +- waku/envelope_test.go | 4 +- waku/events.go | 4 +- waku/filter.go | 3 +- waku/filter_test.go | 22 +- waku/go.mod | 24 - waku/go.sum | 309 ---- waku/handshake.go | 77 +- waku/handshake_test.go | 20 +- waku/message.go | 5 +- waku/message_test.go | 14 +- waku/peer.go | 157 +- waku/peer_test.go | 70 +- waku/rate_limiter.go | 4 +- waku/rate_limiter_test.go | 8 +- waku/waku.go | 372 ++-- waku/waku_test.go | 318 ++-- whisper/events.go | 4 +- whisper/filter.go | 2 +- whisper/peer_test.go | 4 +- whisper/rate_limiter.go | 4 +- whisper/rate_limiter_test.go | 8 +- whisper/whisper_test.go | 1 - 84 files changed, 1787 insertions(+), 6168 deletions(-) create mode 100644 appdatabase/migrations/sql/0005_waku_mode.down.sql create mode 100644 appdatabase/migrations/sql/0005_waku_mode.up.sql delete mode 100644 vendor/github.com/elastic/gosigar/sigar_darwin_386.go delete mode 100644 vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go delete mode 100644 vendor/github.com/status-im/status-go/waku/api.go delete mode 100644 vendor/github.com/status-im/status-go/waku/config.go delete mode 100644 vendor/github.com/status-im/status-go/waku/doc.go delete mode 100644 vendor/github.com/status-im/status-go/waku/envelope.go delete mode 100644 vendor/github.com/status-im/status-go/waku/events.go delete mode 100644 vendor/github.com/status-im/status-go/waku/filter.go delete mode 100644 vendor/github.com/status-im/status-go/waku/go.mod delete mode 100644 vendor/github.com/status-im/status-go/waku/go.sum delete mode 100644 vendor/github.com/status-im/status-go/waku/handshake.go delete mode 100644 vendor/github.com/status-im/status-go/waku/mailserver_response.go delete mode 100644 vendor/github.com/status-im/status-go/waku/message.go delete mode 100644 vendor/github.com/status-im/status-go/waku/metrics.go delete mode 100644 vendor/github.com/status-im/status-go/waku/peer.go delete mode 100644 vendor/github.com/status-im/status-go/waku/rate_limiter.go delete mode 100644 vendor/github.com/status-im/status-go/waku/topic.go delete mode 100644 vendor/github.com/status-im/status-go/waku/waku.go delete mode 100644 vendor/golang.org/x/sync/syncmap/go19.go delete mode 100644 vendor/golang.org/x/sync/syncmap/pre_go19.go delete mode 100644 waku/go.mod delete mode 100644 waku/go.sum diff --git a/appdatabase/migrations/bindata.go b/appdatabase/migrations/bindata.go index ed063c1a4..859480c3a 100644 --- a/appdatabase/migrations/bindata.go +++ b/appdatabase/migrations/bindata.go @@ -8,6 +8,8 @@ // 0003_settings.up.sql (1.311kB) // 0004_pending_stickers.down.sql (0) // 0004_pending_stickers.up.sql (61B) +// 0005_waku_mode.down.sql (0) +// 0005_waku_mode.up.sql (146B) // doc.go (74B) package migrations @@ -92,7 +94,7 @@ func _0001_appDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(0644), modTime: time.Unix(1579789333, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0x25, 0xa0, 0xf8, 0x7d, 0x2d, 0xd, 0xcf, 0x18, 0xe4, 0x73, 0xc3, 0x95, 0xf5, 0x24, 0x20, 0xa9, 0xe6, 0x9e, 0x1d, 0x93, 0xe5, 0xc5, 0xad, 0x93, 0x8f, 0x5e, 0x40, 0xb5, 0x30, 0xaa, 0x25}} return a, nil } @@ -112,7 +114,7 @@ func _0001_appUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(0644), modTime: time.Unix(1579789333, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0x3a, 0xa7, 0xf2, 0x8f, 0xfa, 0x82, 0x7c, 0xc5, 0x49, 0xac, 0xac, 0xf, 0xc, 0x77, 0xe2, 0xba, 0xe8, 0x4d, 0xe, 0x6f, 0x5d, 0x2c, 0x2c, 0x18, 0x80, 0xc2, 0x1d, 0xe, 0x25, 0xe, 0x18}} return a, nil } @@ -132,7 +134,7 @@ func _0002_tokensDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(0644), modTime: time.Unix(1576226192, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0x31, 0x2, 0xcc, 0x2f, 0x38, 0x90, 0xf7, 0x58, 0x37, 0x47, 0xf4, 0x18, 0xf7, 0x72, 0x74, 0x67, 0x14, 0x7e, 0xf3, 0xb1, 0xd6, 0x5f, 0xb0, 0xd5, 0xe7, 0x91, 0xf4, 0x26, 0x77, 0x8e, 0x68}} return a, nil } @@ -152,7 +154,7 @@ func _0002_tokensUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(0644), modTime: time.Unix(1576226192, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcc, 0xd6, 0xde, 0xd3, 0x7b, 0xee, 0x92, 0x11, 0x38, 0xa4, 0xeb, 0x84, 0xca, 0xcb, 0x37, 0x75, 0x5, 0x77, 0x7f, 0x14, 0x39, 0xee, 0xa1, 0x8b, 0xd4, 0x5c, 0x6e, 0x55, 0x6, 0x50, 0x16, 0xd4}} return a, nil } @@ -172,7 +174,7 @@ func _0003_settingsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(0644), modTime: time.Unix(1578050942, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0xa6, 0xf5, 0xc0, 0x60, 0x64, 0x77, 0xe2, 0xe7, 0x3c, 0x9b, 0xb1, 0x52, 0xa9, 0x95, 0x16, 0xf8, 0x60, 0x2f, 0xa5, 0xeb, 0x46, 0xb9, 0xb9, 0x8f, 0x4c, 0xf4, 0xfd, 0xbb, 0xe7, 0xe5, 0xe5}} return a, nil } @@ -192,7 +194,7 @@ func _0003_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(0644), modTime: time.Unix(1580381202, 0)} + info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(0644), modTime: time.Unix(1578050942, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x35, 0x0, 0xeb, 0xe2, 0x33, 0x68, 0xb9, 0xf4, 0xf6, 0x8e, 0x9e, 0x10, 0xe9, 0x58, 0x68, 0x28, 0xb, 0xcd, 0xec, 0x74, 0x71, 0xa7, 0x9a, 0x5a, 0x77, 0x59, 0xb1, 0x13, 0x1c, 0xa1, 0x5b}} return a, nil } @@ -212,7 +214,7 @@ func _0004_pending_stickersDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1580381133, 0)} + info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1581952751, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -232,11 +234,51 @@ func _0004_pending_stickersUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1580381236, 0)} + info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1581952751, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3c, 0xed, 0x25, 0xdf, 0x75, 0x2, 0x6c, 0xf0, 0xa2, 0xa8, 0x37, 0x62, 0x65, 0xad, 0xfd, 0x98, 0xa0, 0x9d, 0x63, 0x94, 0xdf, 0x6b, 0x46, 0xe0, 0x68, 0xec, 0x9c, 0x7f, 0x77, 0xdd, 0xb3, 0x6}} return a, nil } +var __0005_waku_modeDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00") + +func _0005_waku_modeDownSqlBytes() ([]byte, error) { + return bindataRead( + __0005_waku_modeDownSql, + "0005_waku_mode.down.sql", + ) +} + +func _0005_waku_modeDownSql() (*asset, error) { + bytes, err := _0005_waku_modeDownSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "0005_waku_mode.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1582295057, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} + return a, nil +} + +var __0005_waku_modeUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x28\x4e\x2d\x29\xc9\xcc\x4b\x2f\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\x4f\xcc\x2e\x8d\x4f\xcd\x4b\x4c\xca\x49\x4d\x51\x70\xf2\xf7\xf7\x71\x75\xf4\x53\x70\x71\x75\x73\x0c\xf5\x09\x51\x48\x4b\xcc\x29\x4e\xb5\xe6\x22\xca\x8c\xa4\x9c\xfc\xfc\xdc\xf8\xb4\xcc\x9c\x92\xd4\xa2\xf8\xdc\xfc\x94\x54\x5c\xa6\x01\x02\x00\x00\xff\xff\x00\x97\x79\x75\x92\x00\x00\x00") + +func _0005_waku_modeUpSqlBytes() ([]byte, error) { + return bindataRead( + __0005_waku_modeUpSql, + "0005_waku_mode.up.sql", + ) +} + +func _0005_waku_modeUpSql() (*asset, error) { + bytes, err := _0005_waku_modeUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "0005_waku_mode.up.sql", size: 146, mode: os.FileMode(0644), modTime: time.Unix(1582295057, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa6, 0x91, 0xc, 0xd7, 0x89, 0x61, 0x2e, 0x4c, 0x5a, 0xb6, 0x67, 0xd1, 0xc1, 0x42, 0x24, 0x38, 0xd6, 0x1b, 0x75, 0x41, 0x9c, 0x23, 0xb0, 0xca, 0x5c, 0xf1, 0x5c, 0xd0, 0x13, 0x92, 0x3e, 0xe1}} + return a, nil +} + var _docGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00") func docGoBytes() ([]byte, error) { @@ -252,7 +294,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}} return a, nil } @@ -348,15 +390,27 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "0001_app.down.sql": _0001_appDownSql, - "0001_app.up.sql": _0001_appUpSql, - "0002_tokens.down.sql": _0002_tokensDownSql, - "0002_tokens.up.sql": _0002_tokensUpSql, - "0003_settings.down.sql": _0003_settingsDownSql, - "0003_settings.up.sql": _0003_settingsUpSql, + "0001_app.down.sql": _0001_appDownSql, + + "0001_app.up.sql": _0001_appUpSql, + + "0002_tokens.down.sql": _0002_tokensDownSql, + + "0002_tokens.up.sql": _0002_tokensUpSql, + + "0003_settings.down.sql": _0003_settingsDownSql, + + "0003_settings.up.sql": _0003_settingsUpSql, + "0004_pending_stickers.down.sql": _0004_pending_stickersDownSql, - "0004_pending_stickers.up.sql": _0004_pending_stickersUpSql, - "doc.go": docGo, + + "0004_pending_stickers.up.sql": _0004_pending_stickersUpSql, + + "0005_waku_mode.down.sql": _0005_waku_modeDownSql, + + "0005_waku_mode.up.sql": _0005_waku_modeUpSql, + + "doc.go": docGo, } // AssetDir returns the file names below a certain @@ -408,6 +462,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "0003_settings.up.sql": &bintree{_0003_settingsUpSql, map[string]*bintree{}}, "0004_pending_stickers.down.sql": &bintree{_0004_pending_stickersDownSql, map[string]*bintree{}}, "0004_pending_stickers.up.sql": &bintree{_0004_pending_stickersUpSql, map[string]*bintree{}}, + "0005_waku_mode.down.sql": &bintree{_0005_waku_modeDownSql, map[string]*bintree{}}, + "0005_waku_mode.up.sql": &bintree{_0005_waku_modeUpSql, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}}, }} diff --git a/appdatabase/migrations/sql/0005_waku_mode.down.sql b/appdatabase/migrations/sql/0005_waku_mode.down.sql new file mode 100644 index 000000000..e69de29bb diff --git a/appdatabase/migrations/sql/0005_waku_mode.up.sql b/appdatabase/migrations/sql/0005_waku_mode.up.sql new file mode 100644 index 000000000..fa006f2be --- /dev/null +++ b/appdatabase/migrations/sql/0005_waku_mode.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE settings ADD COLUMN waku_enabled BOOLEAN DEFAULT false; +ALTER TABLE settings ADD COLUMN waku_bloom_filter_mode BOOLEAN DEFAULT false; diff --git a/bridge/bridge.go b/bridge/bridge.go index 96641759d..0e6c3c4a8 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -66,7 +66,7 @@ func (b *Bridge) Start() { case <-b.cancel: return case env := <-b.wakuIn: - shhEnvelope := (*whisper.Envelope)(unsafe.Pointer(env)) + shhEnvelope := (*whisper.Envelope)(unsafe.Pointer(env)) // nolint: gosec b.logger.Info("received whisper envelope from waku", zap.Any("envelope", shhEnvelope)) b.whisperOut <- shhEnvelope } @@ -81,7 +81,7 @@ func (b *Bridge) Start() { case <-b.cancel: return case env := <-b.whisperIn: - wakuEnvelope := (*waku.Envelope)(unsafe.Pointer(env)) + wakuEnvelope := (*waku.Envelope)(unsafe.Pointer(env)) // nolint: gosec b.logger.Info("received whisper envelope from waku", zap.Any("envelope", wakuEnvelope)) b.wakuOut <- wakuEnvelope } diff --git a/bridge/bridge_test.go b/bridge/bridge_test.go index 0c5ca3724..0df6b4db5 100644 --- a/bridge/bridge_test.go +++ b/bridge/bridge_test.go @@ -20,13 +20,13 @@ func TestEnvelopesBeingIdentical(t *testing.T) { // whisper.Envelope --> waku.Envelope whisperEnvelope, err := createWhisperEnvelope() require.NoError(t, err) - wakuEnvelope := (*waku.Envelope)(unsafe.Pointer(whisperEnvelope)) + wakuEnvelope := (*waku.Envelope)(unsafe.Pointer(whisperEnvelope)) // nolint: gosec require.Equal(t, whisperEnvelope.Hash(), wakuEnvelope.Hash()) // waku.Envelope --> whisper.Envelope wakuEnvelope, err = createWakuEnvelope() require.NoError(t, err) - whisperEnvelope = (*whisper.Envelope)(unsafe.Pointer(wakuEnvelope)) + whisperEnvelope = (*whisper.Envelope)(unsafe.Pointer(wakuEnvelope)) // nolint: gosec require.Equal(t, wakuEnvelope.Hash(), whisperEnvelope.Hash()) } diff --git a/extkeys/go.mod b/extkeys/go.mod index b3a2301e2..00683d553 100644 --- a/extkeys/go.mod +++ b/extkeys/go.mod @@ -8,6 +8,9 @@ require ( github.com/btcsuite/btcd v0.20.1-beta github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d github.com/ethereum/go-ethereum v1.9.5 - golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba + github.com/status-im/status-go/waku v1.3.0 // indirect + github.com/status-im/status-go/whisper/v6 v6.2.0 // indirect + github.com/vacp2p/mvds v0.0.25 // indirect + golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c golang.org/x/text v0.3.2 ) diff --git a/extkeys/go.sum b/extkeys/go.sum index 2102646b3..42a6cf995 100644 --- a/extkeys/go.sum +++ b/extkeys/go.sum @@ -1,10 +1,38 @@ 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= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= 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/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +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/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/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/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/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +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/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -17,86 +45,403 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku 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/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= +github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= +github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= +github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= +github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= +github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= +github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= +github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= +github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= +github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= 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 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 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/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= +github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +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-20170320065105-0bce6a688712/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/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +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/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-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +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/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/mock v1.2.0/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/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +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/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +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/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.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/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/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= 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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 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/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +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/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/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/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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +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/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f h1:hd3r+uv9DNLScbOrnlj82rBldHQf3XWmCeXAWbw8euQ= +github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f/go.mod h1:MyUWrZlB1aI5bs7j9/pJ8ckLLZ4QcCYcNiSbsAW32D4= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= 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/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/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/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/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= 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/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.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 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.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-20190115171406-56726106282f/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.2.0/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/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-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.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/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 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/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q= github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g= +github.com/status-im/migrate v3.4.0+incompatible h1:TeZJKy7o6EwttvXyAmWG9IMB4pLKIWwXjzQExNIuWIQ= +github.com/status-im/migrate/v4 v4.6.2-status.2 h1:SdC+sMDl/aI7vUlwD2qj2p7KsK4T60IS9z4/rYCCbI8= +github.com/status-im/migrate/v4 v4.6.2-status.2/go.mod h1:c/kc90n47GZu/58nnz1OMLTf7uE4Da4gZP5qmU+A/v8= +github.com/status-im/status-go v0.45.1 h1:xCw0IdzH+ttFqLrFLWskwF6KCt1O4VSMhvzyU09xQ6s= github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= +github.com/status-im/status-go/waku v1.3.0 h1:sULZzzz8fV3Ufn8HI5BmQaqWxyJiH8P/8Z9I920sGPk= +github.com/status-im/status-go/waku v1.3.0/go.mod h1:hmq99wlA8qKyYEYalqMz1FieIWhq7pl9zDlkw/jsd4M= +github.com/status-im/status-go/whisper/v6 v6.2.0 h1:7QB5Ztlcn7n5WO3gKa4KnIoCvnIa0rVMM810lHCK2ws= +github.com/status-im/status-go/whisper/v6 v6.2.0/go.mod h1:csqMoPMkCPW1NJO56HJzNTWAl9UMdetnQzkPbPjsAC4= +github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= +github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 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.3.1-0.20190712000136-221dbe5ed467/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +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/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/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/vacp2p/mvds v0.0.25 h1:ODdGa1hdeZ08/5bmGkMIUfPMGfFoXESxPsAHfvZ3rOU= +github.com/vacp2p/mvds v0.0.25/go.mod h1:m4bMOcpv18709MopEtug6mEnhQgR9NnrzS2SC6zWQnI= +github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= +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= +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.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +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.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +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-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-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-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-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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181108082009-03003ca0c849/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-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832/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-20190424112056-4829fb13d2c6/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/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e 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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/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 h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= 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-20190426135247-a129542de9ae/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/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +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-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/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +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/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +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/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/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= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/extkeys/mnemonic.go b/extkeys/mnemonic.go index 2d4396b87..0dfe4d2cc 100644 --- a/extkeys/mnemonic.go +++ b/extkeys/mnemonic.go @@ -268,7 +268,10 @@ func (m *Mnemonic) ValidateMnemonic(mnemonic string, language Language) error { // Calculate checksum from entropy derived above hasher := sha256.New() - hasher.Write(entropy) + if err := hasher.Write(entropy); err != nil { + return err + } + computedChecksumBytes := hasher.Sum(nil) computedChecksum := big.NewInt(int64(computedChecksumBytes[0])) @@ -297,33 +300,6 @@ func (m *Mnemonic) WordList(language Language) (*WordList, error) { return m.wordLists[language], nil } -func contains(wordList *WordList, e string) bool { - // tries binary search first, then resorts to full list traversal - i, j := 0, len(wordList) - for i < j { - h := i + (j-i)/2 - - // i < h < j - if wordList[h] >= e { - j = h - } else { - i = h + 1 - } - } - - if j > 0 && j < len(wordList) && wordList[j] == e { - return true - } - - // traverse list - for _, a := range wordList { - if a == e { - return true - } - } - return false -} - func padByteSlice(slice []byte, length int) []byte { //nolint: unparam newSlice := make([]byte, length-len(slice)) return append(newSlice, slice...) diff --git a/go.mod b/go.mod index 8e1563a91..b72b68966 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/beevik/ntp v0.2.0 github.com/btcsuite/btcd v0.20.1-beta github.com/cenkalti/backoff/v3 v3.2.2 + github.com/deckarep/golang-set v1.7.1 github.com/ethereum/go-ethereum v1.9.5 github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect @@ -42,11 +43,11 @@ require ( github.com/status-im/migrate/v4 v4.6.2-status.2 github.com/status-im/rendezvous v1.3.0 github.com/status-im/status-go/extkeys v1.1.0 - github.com/status-im/status-go/waku v1.3.0 github.com/status-im/status-go/whisper/v6 v6.2.0 github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 github.com/stretchr/testify v1.4.0 github.com/syndtr/goleveldb v1.0.0 + github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 github.com/vacp2p/mvds v0.0.23 github.com/wealdtech/go-ens/v3 v3.3.0 go.uber.org/zap v1.13.0 diff --git a/go.sum b/go.sum index 921e4afd5..6bb18b919 100644 --- a/go.sum +++ b/go.sum @@ -11,7 +11,6 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= -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/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q= @@ -19,7 +18,6 @@ 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/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.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= @@ -33,14 +31,10 @@ github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85Sx 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/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-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/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/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw= @@ -137,9 +131,8 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= 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.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo= 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/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= @@ -151,7 +144,6 @@ 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/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= @@ -233,7 +225,6 @@ 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/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-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.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= @@ -249,7 +240,6 @@ 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/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/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.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= @@ -274,9 +264,8 @@ github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGk github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= 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/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.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -285,7 +274,6 @@ 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.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= 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 v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= @@ -310,8 +298,6 @@ 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/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/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/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -326,7 +312,6 @@ 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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -519,15 +504,11 @@ github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8u github.com/olekukonko/tablewriter v0.0.1/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.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= 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.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= 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/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= @@ -544,20 +525,17 @@ 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/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/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/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 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 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= @@ -568,14 +546,12 @@ 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.2.0/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/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-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.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= @@ -591,9 +567,8 @@ github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C 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.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= 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/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 h1:H3hCXwP92pH/hSgNrCLtjxvsKJ50sq26nICbZuoR1tQ= github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315/go.mod h1:ZbKa3zlLnhGF1dAeJtMSoNtM5LgFQnqzq8eYH3uYYkU= @@ -642,8 +617,6 @@ github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcw github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= github.com/status-im/status-go/extkeys v1.1.0 h1:QgnXlMvhlFyRu+GdpPn1Ve22IidnDdslFB/Py6HWj78= github.com/status-im/status-go/extkeys v1.1.0/go.mod h1:nT/T2+G4L/6qPVIIfI3oT8dQSVyn7fQYY8G3yL3PIGY= -github.com/status-im/status-go/waku v1.3.0 h1:sULZzzz8fV3Ufn8HI5BmQaqWxyJiH8P/8Z9I920sGPk= -github.com/status-im/status-go/waku v1.3.0/go.mod h1:hmq99wlA8qKyYEYalqMz1FieIWhq7pl9zDlkw/jsd4M= github.com/status-im/status-go/whisper/v6 v6.2.0 h1:7QB5Ztlcn7n5WO3gKa4KnIoCvnIa0rVMM810lHCK2ws= github.com/status-im/status-go/whisper/v6 v6.2.0/go.mod h1:csqMoPMkCPW1NJO56HJzNTWAl9UMdetnQzkPbPjsAC4= github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 h1:oa0KU5jJRNtXaM/P465MhvSFo/HM2O8qi2DDuPcd7ro= @@ -666,10 +639,7 @@ 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 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/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/go.mod h1:EcGP24b8DY+bWHnpfJDP7fM+o8Nmz4fYH0l2xTtNr3I= github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= @@ -702,8 +672,6 @@ 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/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/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= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -729,7 +697,6 @@ 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-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-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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -767,9 +734,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/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 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-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/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -778,9 +744,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= 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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -793,14 +758,11 @@ 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-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-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-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-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-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk= @@ -823,9 +785,7 @@ 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-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-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/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0= @@ -850,11 +810,9 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8 google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 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/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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -867,11 +825,6 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8 gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 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/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= @@ -880,7 +833,6 @@ 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-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs= 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/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= @@ -896,7 +848,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-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-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/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg= diff --git a/mailserver/migrations/bindata.go b/mailserver/migrations/bindata.go index 4b7a5c194..684df9ce4 100644 --- a/mailserver/migrations/bindata.go +++ b/mailserver/migrations/bindata.go @@ -86,7 +86,7 @@ func _1557732988_initialize_dbDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1557732988_initialize_db.down.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "1557732988_initialize_db.down.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0x40, 0x78, 0xb7, 0x71, 0x3c, 0x20, 0x3b, 0xc9, 0xb, 0x2f, 0x49, 0xe4, 0xff, 0x1c, 0x84, 0x54, 0xa1, 0x30, 0xe3, 0x90, 0xf8, 0x73, 0xda, 0xb0, 0x2a, 0xea, 0x8e, 0xf1, 0x82, 0xe7, 0xd2}} return a, nil } @@ -106,7 +106,7 @@ func _1557732988_initialize_dbUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1557732988_initialize_db.up.sql", size: 234, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "1557732988_initialize_db.up.sql", size: 234, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xa, 0x31, 0xf, 0x94, 0xe, 0xd7, 0xd6, 0xaa, 0x22, 0xd6, 0x6c, 0x7a, 0xbc, 0xad, 0x6a, 0xed, 0x2e, 0x7a, 0xf0, 0x24, 0x81, 0x87, 0x14, 0xe, 0x1c, 0x8a, 0xf1, 0x45, 0xaf, 0x9e, 0x85}} return a, nil } @@ -126,7 +126,7 @@ func staticGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static.go", size: 178, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "static.go", size: 178, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x8a, 0xf4, 0x27, 0x24, 0x9d, 0x2a, 0x1, 0x7b, 0x54, 0xea, 0xae, 0x4a, 0x35, 0x40, 0x92, 0xb5, 0xf9, 0xb3, 0x54, 0x3e, 0x3a, 0x1a, 0x2b, 0xae, 0xfb, 0x9e, 0x82, 0xeb, 0x4c, 0xf, 0x6}} return a, nil } @@ -223,8 +223,10 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "1557732988_initialize_db.down.sql": _1557732988_initialize_dbDownSql, - "1557732988_initialize_db.up.sql": _1557732988_initialize_dbUpSql, - "static.go": staticGo, + + "1557732988_initialize_db.up.sql": _1557732988_initialize_dbUpSql, + + "static.go": staticGo, } // AssetDir returns the file names below a certain diff --git a/multiaccounts/accounts/database.go b/multiaccounts/accounts/database.go index 8a097b639..239c40144 100644 --- a/multiaccounts/accounts/database.go +++ b/multiaccounts/accounts/database.go @@ -75,6 +75,8 @@ type Settings struct { WalletRootAddress types.Address `json:"wallet-root-address,omitempty"` WalletSetUpPassed bool `json:"wallet-set-up-passed?,omitempty"` WalletVisibleTokens *json.RawMessage `json:"wallet/visible-tokens,omitempty"` + WakuEnabled bool `json:"waku-enabled,omitempty"` + WakuBloomFilterMode bool `json:"waku-bloom-filter-mode,omitempty"` } func NewDB(db *sql.DB) *Database { @@ -266,6 +268,19 @@ func (db *Database) SaveSetting(setting string, value interface{}) error { case "wallet/visible-tokens": value = &sqlite.JSONBlob{value} update, err = db.db.Prepare("UPDATE settings SET wallet_visible_tokens = ? WHERE synthetic_id = 'id'") + case "waku-enabled": + _, ok := value.(bool) + if !ok { + return ErrInvalidConfig + } + update, err = db.db.Prepare("UPDATE settings SET waku_enabled = ? WHERE synthetic_id = 'id'") + case "waku-bloom-filter-mode": + _, ok := value.(bool) + if !ok { + return ErrInvalidConfig + } + update, err = db.db.Prepare("UPDATE settings SET waku_bloom_filter_mode = ? WHERE synthetic_id = 'id'") + default: return ErrInvalidConfig } diff --git a/multiaccounts/migrations/bindata.go b/multiaccounts/migrations/bindata.go index 34a5b1c3b..2bbf13e53 100644 --- a/multiaccounts/migrations/bindata.go +++ b/multiaccounts/migrations/bindata.go @@ -86,7 +86,7 @@ func _0001_accountsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_accounts.down.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "0001_accounts.down.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0x61, 0x4c, 0x18, 0xfc, 0xc, 0xdf, 0x5c, 0x1f, 0x5e, 0xd3, 0xbd, 0xfa, 0x12, 0x5e, 0x8d, 0x8d, 0x8b, 0xb9, 0x5f, 0x99, 0x46, 0x63, 0xa5, 0xe3, 0xa6, 0x8a, 0x4, 0xf1, 0x73, 0x8a, 0xe9}} return a, nil } @@ -106,7 +106,7 @@ func _0001_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_accounts.up.sql", size: 163, mode: os.FileMode(0644), modTime: time.Unix(1580303056, 0)} + info := bindataFileInfo{name: "0001_accounts.up.sql", size: 163, mode: os.FileMode(0644), modTime: time.Unix(1575903446, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf2, 0xfa, 0x99, 0x8e, 0x96, 0xb3, 0x13, 0x6c, 0x1f, 0x6, 0x27, 0xc5, 0xd2, 0xd4, 0xe0, 0xa5, 0x26, 0x82, 0xa7, 0x26, 0xf2, 0x68, 0x9d, 0xed, 0x9c, 0x3d, 0xbb, 0xdc, 0x37, 0x28, 0xbc, 0x1}} return a, nil } @@ -126,7 +126,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}} return a, nil } @@ -223,8 +223,10 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "0001_accounts.down.sql": _0001_accountsDownSql, - "0001_accounts.up.sql": _0001_accountsUpSql, - "doc.go": docGo, + + "0001_accounts.up.sql": _0001_accountsUpSql, + + "doc.go": docGo, } // AssetDir returns the file names below a certain diff --git a/node/geth_node.go b/node/geth_node.go index 25604062f..ded1dad5b 100644 --- a/node/geth_node.go +++ b/node/geth_node.go @@ -457,6 +457,7 @@ func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperCon func createWakuService(ctx *node.ServiceContext, wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) (*waku.Waku, error) { cfg := &waku.Config{ MaxMessageSize: waku.DefaultMaxMessageSize, + BloomFilterMode: wakuCfg.BloomFilterMode, MinimumAcceptedPoW: params.WakuMinimumPoW, } diff --git a/params/config.go b/params/config.go index 2be38471d..e3e78d277 100644 --- a/params/config.go +++ b/params/config.go @@ -187,6 +187,10 @@ type WakuConfig struct { // in order to drop a peer. // If equal to 0, the peers are never dropped. RateLimitTolerance int64 + + // BloomFilterMode tells us whether we should be sending a bloom + // filter rather than TopicInterest + BloomFilterMode bool } // IncentivisationConfig holds incentivisation-related configuration diff --git a/protocol/message_handler.go b/protocol/message_handler.go index 361772e07..214712956 100644 --- a/protocol/message_handler.go +++ b/protocol/message_handler.go @@ -14,6 +14,12 @@ import ( v1protocol "github.com/status-im/status-go/protocol/v1" ) +const ( + transactionRequestDeclinedMessage = "Transaction request declined" + requestAddressForTransactionAcceptedMessage = "Request address for transaction accepted" + requestAddressForTransactionDeclinedMessage = "Request address for transaction declined" +) + type MessageHandler struct { identity *ecdsa.PrivateKey persistence *sqlitePersistence @@ -434,7 +440,7 @@ func (m *MessageHandler) HandleAcceptRequestAddressForTransaction(messageState * initialMessage.Clock = command.Clock initialMessage.Timestamp = messageState.CurrentMessageState.WhisperTimestamp - initialMessage.Text = "Request address for transaction accepted" + initialMessage.Text = requestAddressForTransactionAcceptedMessage initialMessage.CommandParameters.Address = command.Address initialMessage.CommandParameters.CommandState = CommandStateRequestAddressForTransactionAccepted @@ -503,7 +509,7 @@ func (m *MessageHandler) HandleDeclineRequestAddressForTransaction(messageState oldMessage.Clock = command.Clock oldMessage.Timestamp = messageState.CurrentMessageState.WhisperTimestamp - oldMessage.Text = "Request address for transaction declined" + oldMessage.Text = requestAddressForTransactionDeclinedMessage oldMessage.CommandParameters.CommandState = CommandStateRequestAddressForTransactionDeclined // Hide previous message @@ -543,7 +549,7 @@ func (m *MessageHandler) HandleDeclineRequestTransaction(messageState *ReceivedM oldMessage.Clock = command.Clock oldMessage.Timestamp = messageState.CurrentMessageState.WhisperTimestamp - oldMessage.Text = "Transaction request declined" + oldMessage.Text = transactionRequestDeclinedMessage oldMessage.CommandParameters.CommandState = CommandStateRequestTransactionDeclined // Hide previous message diff --git a/protocol/messenger_test.go b/protocol/messenger_test.go index a79aac621..99140e807 100644 --- a/protocol/messenger_test.go +++ b/protocol/messenger_test.go @@ -30,6 +30,16 @@ import ( "github.com/status-im/status-go/whisper/v6" ) +const ( + testPK = "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1" + testPublicChatID = "super-chat" + testContract = "0x314159265dd8dbb310642f98f50c066173c1259b" + testValue = "2000" + testTransactionHash = "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799" + testIdenticon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAnElEQVR4nOzXQaqDMBRG4bZkLR10e12H23PgZuJUjJAcE8kdnG/44IXDhZ9iyjm/4vnMDrhmFmEWYRZhFpH6n1jW7fSX/+/b+WbQa5lFmEVUljhqZfSdoNcyizCLeNMvn3JTLeh+g17LLMIsorLElt2VK7v3X0dBr2UWYRaBfxNLfifOZhYRNGvAEp8Q9FpmEWYRZhFmEXsAAAD//5K5JFhu0M0nAAAAAElFTkSuQmCC" + testAlias = "Concrete Lavender Xiphias" +) + func TestMessengerSuite(t *testing.T) { suite.Run(t, new(MessengerSuite)) } @@ -970,7 +980,7 @@ func (s *MessengerSuite) TestChatPersistenceUpdate() { s.Require().Equal(expectedChat, actualChat) - chat.Name = "updated-name" + chat.Name = "updated-name-1" s.Require().NoError(s.m.SaveChat(&chat)) updatedChats := s.m.Chats() s.Require().Equal(1, len(updatedChats)) @@ -982,10 +992,9 @@ func (s *MessengerSuite) TestChatPersistenceUpdate() { } func (s *MessengerSuite) TestChatPersistenceOneToOne() { - pkStr := "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1" chat := Chat{ - ID: pkStr, - Name: pkStr, + ID: testPK, + Name: testPK, Color: "#fffff", Active: true, ChatType: ChatTypeOneToOne, @@ -995,7 +1004,7 @@ func (s *MessengerSuite) TestChatPersistenceOneToOne() { UnviewedMessagesCount: 40, LastMessage: []byte("test"), } - publicKeyBytes, err := hex.DecodeString(pkStr[2:]) + publicKeyBytes, err := hex.DecodeString(testPK[2:]) s.Require().NoError(err) pk, err := crypto.UnmarshalPubkey(publicKeyBytes) @@ -1088,10 +1097,8 @@ func (s *MessengerSuite) TestChatPersistencePrivateGroupChat() { } func (s *MessengerSuite) TestBlockContact() { - pk := "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1" - contact := Contact{ - ID: pk, + ID: testPK, Name: "contact-name", Photo: "contact-photo", LastUpdated: 20, @@ -1278,7 +1285,7 @@ func (s *MessengerSuite) TestBlockContact() { func (s *MessengerSuite) TestContactPersistence() { contact := Contact{ - ID: "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1", + ID: testPK, Name: "contact-name", Photo: "contact-photo", @@ -1305,13 +1312,13 @@ func (s *MessengerSuite) TestContactPersistence() { actualContact := savedContacts[0] expectedContact := &contact - expectedContact.Alias = "Concrete Lavender Xiphias" - expectedContact.Identicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAnElEQVR4nOzXQaqDMBRG4bZkLR10e12H23PgZuJUjJAcE8kdnG/44IXDhZ9iyjm/4vnMDrhmFmEWYRZhFpH6n1jW7fSX/+/b+WbQa5lFmEVUljhqZfSdoNcyizCLeNMvn3JTLeh+g17LLMIsorLElt2VK7v3X0dBr2UWYRaBfxNLfifOZhYRNGvAEp8Q9FpmEWYRZhFmEXsAAAD//5K5JFhu0M0nAAAAAElFTkSuQmCC" + expectedContact.Alias = testAlias + expectedContact.Identicon = testIdenticon s.Require().Equal(expectedContact, actualContact) } func (s *MessengerSuite) TestContactPersistenceUpdate() { - contactID := "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1" + contactID := testPK contact := Contact{ ID: contactID, @@ -1341,12 +1348,12 @@ func (s *MessengerSuite) TestContactPersistenceUpdate() { actualContact := savedContacts[0] expectedContact := &contact - expectedContact.Alias = "Concrete Lavender Xiphias" - expectedContact.Identicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAnElEQVR4nOzXQaqDMBRG4bZkLR10e12H23PgZuJUjJAcE8kdnG/44IXDhZ9iyjm/4vnMDrhmFmEWYRZhFpH6n1jW7fSX/+/b+WbQa5lFmEVUljhqZfSdoNcyizCLeNMvn3JTLeh+g17LLMIsorLElt2VK7v3X0dBr2UWYRaBfxNLfifOZhYRNGvAEp8Q9FpmEWYRZhFmEXsAAAD//5K5JFhu0M0nAAAAAElFTkSuQmCC" + expectedContact.Alias = testAlias + expectedContact.Identicon = testIdenticon s.Require().Equal(expectedContact, actualContact) - contact.Name = "updated-name" + contact.Name = "updated-name-2" s.Require().NoError(s.m.SaveContact(&contact)) updatedContact := s.m.Contacts() s.Require().Equal(1, len(updatedContact)) @@ -1363,7 +1370,7 @@ func (s *MessengerSuite) TestSharedSecretHandler() { } func (s *MessengerSuite) TestCreateGroupChatWithMembers() { - members := []string{"0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1"} + members := []string{testPK} response, err := s.m.CreateGroupChatWithMembers(context.Background(), "test", members) s.NoError(err) s.Require().Len(response.Chats, 1) @@ -1401,8 +1408,8 @@ func (s *MessengerSuite) TestAddMembersToChat() { } func (s *MessengerSuite) TestDeclineRequestAddressForTransaction() { - value := "0.01" - contract := "some-contract" + value := testValue + contract := testContract theirMessenger := s.newMessenger(s.shh) theirPkString := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) @@ -1495,8 +1502,8 @@ func (s *MessengerSuite) TestDeclineRequestAddressForTransaction() { } func (s *MessengerSuite) TestSendEthTransaction() { - value := "2000" - contract := "some-contract" + value := testValue + contract := testContract theirMessenger := s.newMessenger(s.shh) theirPkString := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) @@ -1508,7 +1515,7 @@ func (s *MessengerSuite) TestSendEthTransaction() { err := s.m.SaveChat(&chat) s.Require().NoError(err) - transactionHash := "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799" + transactionHash := testTransactionHash signature, err := buildSignature(s.m.identity, &s.m.identity.PublicKey, transactionHash) s.Require().NoError(err) @@ -1596,8 +1603,8 @@ func (s *MessengerSuite) TestSendEthTransaction() { } func (s *MessengerSuite) TestSendTokenTransaction() { - value := "2000" - contract := "0x314159265dd8dbb310642f98f50c066173c1259b" + value := testValue + contract := testContract theirMessenger := s.newMessenger(s.shh) theirPkString := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) @@ -1609,7 +1616,7 @@ func (s *MessengerSuite) TestSendTokenTransaction() { err := s.m.SaveChat(&chat) s.Require().NoError(err) - transactionHash := "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799" + transactionHash := testTransactionHash signature, err := buildSignature(s.m.identity, &s.m.identity.PublicKey, transactionHash) s.Require().NoError(err) @@ -1697,8 +1704,8 @@ func (s *MessengerSuite) TestSendTokenTransaction() { } func (s *MessengerSuite) TestAcceptRequestAddressForTransaction() { - value := "0.01" - contract := "some-contract" + value := testValue + contract := testContract theirMessenger := s.newMessenger(s.shh) theirPkString := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) @@ -1793,8 +1800,8 @@ func (s *MessengerSuite) TestAcceptRequestAddressForTransaction() { } func (s *MessengerSuite) TestDeclineRequestTransaction() { - value := "2000" - contract := "0x314159265dd8dbb310642f98f50c066173c1259b" + value := testValue + contract := testContract receiverAddress := crypto.PubkeyToAddress(s.m.identity.PublicKey) receiverAddressString := strings.ToLower(receiverAddress.Hex()) theirMessenger := s.newMessenger(s.shh) @@ -1886,8 +1893,8 @@ func (s *MessengerSuite) TestDeclineRequestTransaction() { } func (s *MessengerSuite) TestRequestTransaction() { - value := "2000" - contract := "0x314159265dd8dbb310642f98f50c066173c1259b" + value := testValue + contract := testContract receiverAddress := crypto.PubkeyToAddress(s.m.identity.PublicKey) receiverAddressString := strings.ToLower(receiverAddress.Hex()) theirMessenger := s.newMessenger(s.shh) diff --git a/protocol/persistence_legacy_test.go b/protocol/persistence_legacy_test.go index ac9cdf619..f1481804f 100644 --- a/protocol/persistence_legacy_test.go +++ b/protocol/persistence_legacy_test.go @@ -79,7 +79,7 @@ func TestMessageByChatID(t *testing.T) { db, err := openTestDB() require.NoError(t, err) p := sqlitePersistence{db: db} - chatID := "super-chat" + chatID := testPublicChatID count := 1000 pageSize := 50 @@ -162,7 +162,7 @@ func TestMessageReplies(t *testing.T) { db, err := openTestDB() require.NoError(t, err) p := sqlitePersistence{db: db} - chatID := "super-chat" + chatID := testPublicChatID message1 := &Message{ ID: "id-1", LocalChatID: chatID, @@ -217,7 +217,7 @@ func TestMessageByChatIDWithTheSameClocks(t *testing.T) { db, err := openTestDB() require.NoError(t, err) p := sqlitePersistence{db: db} - chatID := "super-chat" + chatID := testPublicChatID clockValues := []uint64{10, 10, 9, 9, 9, 11, 12, 11, 100000, 6, 4, 5, 5, 5, 5} count := len(clockValues) pageSize := 2 diff --git a/protocol/sqlite/db.go b/protocol/sqlite/db.go index 87d4b783a..89d935b9a 100644 --- a/protocol/sqlite/db.go +++ b/protocol/sqlite/db.go @@ -53,7 +53,7 @@ func OpenWithIter(path, key string, kdfIter int) (*sql.DB, error) { func open(path string, key string, kdfIter int) (*sql.DB, error) { if path != inMemoryPath { - _, err := os.OpenFile(path, os.O_CREATE, 0644) + _, err := os.OpenFile(path, os.O_CREATE, 0600) if err != nil { return nil, err } diff --git a/static/bindata.go b/static/bindata.go index c2f16bd48..bd2aa8ed8 100644 --- a/static/bindata.go +++ b/static/bindata.go @@ -97,7 +97,7 @@ func ConfigReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/README.md", size: 3132, mode: os.FileMode(0644), modTime: time.Unix(1582203713, 0)} + info := bindataFileInfo{name: "../config/README.md", size: 3132, mode: os.FileMode(0644), modTime: time.Unix(1582295056, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd0, 0x71, 0x14, 0x3e, 0x9d, 0x9c, 0x11, 0x40, 0xe1, 0xe9, 0x8b, 0xcc, 0x38, 0x17, 0x69, 0xb, 0xa7, 0xf2, 0x91, 0xa6, 0x4a, 0x9f, 0xd2, 0xc6, 0xf4, 0xff, 0x37, 0x5d, 0xd3, 0xed, 0x7c, 0xbd}} return a, nil } @@ -117,7 +117,7 @@ func ConfigCliFleetEthProdJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.prod.json", size: 3232, mode: os.FileMode(0644), modTime: time.Unix(1582203948, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.prod.json", size: 3232, mode: os.FileMode(0644), modTime: time.Unix(1582295056, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4d, 0xc3, 0xae, 0xf2, 0x48, 0x6c, 0x5, 0x81, 0xbb, 0x48, 0x51, 0x44, 0x82, 0xef, 0xe4, 0x68, 0xb4, 0xb6, 0x6, 0xbb, 0xf9, 0x76, 0x76, 0x1b, 0x54, 0xfa, 0xda, 0x7b, 0xd2, 0x49, 0xd, 0xe4}} return a, nil } @@ -137,7 +137,7 @@ func ConfigCliFleetEthStagingJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 1846, mode: os.FileMode(0644), modTime: time.Unix(1582203948, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 1846, mode: os.FileMode(0644), modTime: time.Unix(1582295056, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x87, 0x84, 0x88, 0xaa, 0x22, 0xdd, 0x82, 0xc4, 0x48, 0x29, 0x2c, 0x7d, 0x69, 0x98, 0x45, 0x47, 0x44, 0x8a, 0x75, 0x99, 0xac, 0x12, 0x7, 0x2d, 0x65, 0xc9, 0xc, 0xe7, 0x52, 0x4e, 0xb0, 0xbc}} return a, nil } @@ -157,7 +157,7 @@ func ConfigCliFleetEthTestJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 1527, mode: os.FileMode(0644), modTime: time.Unix(1582203948, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 1527, mode: os.FileMode(0644), modTime: time.Unix(1582295056, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x94, 0x84, 0xa8, 0x1a, 0x79, 0x23, 0xd0, 0x4, 0xb7, 0x98, 0xd9, 0xeb, 0x5b, 0x5, 0x23, 0x7a, 0xcb, 0xf9, 0x57, 0xf9, 0xa, 0xe3, 0x27, 0xe2, 0xaf, 0xc1, 0xdf, 0xf5, 0x58, 0xda, 0xb9, 0x64}} return a, nil } @@ -177,7 +177,7 @@ func ConfigCliLesEnabledJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/les-enabled.json", size: 58, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "../config/cli/les-enabled.json", size: 58, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7e, 0xee, 0x27, 0xa7, 0x74, 0xa0, 0x46, 0xa1, 0x41, 0xed, 0x4d, 0x16, 0x5b, 0xf3, 0xf0, 0x7c, 0xc8, 0x2f, 0x6f, 0x47, 0xa4, 0xbb, 0x5f, 0x43, 0x33, 0xd, 0x9, 0x9d, 0xea, 0x9e, 0x15, 0xee}} return a, nil } @@ -197,7 +197,7 @@ func ConfigCliMailserverEnabledJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/mailserver-enabled.json", size: 176, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "../config/cli/mailserver-enabled.json", size: 176, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0xec, 0x81, 0x8b, 0x99, 0xb6, 0xdb, 0xc0, 0x8b, 0x46, 0x97, 0x96, 0xc7, 0x58, 0x30, 0x33, 0xef, 0x54, 0x25, 0x87, 0x7b, 0xb9, 0x94, 0x6b, 0x18, 0xa4, 0x5b, 0x58, 0x67, 0x7c, 0x44, 0xa6}} return a, nil } @@ -217,7 +217,7 @@ func ConfigStatusChainGenesisJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/status-chain-genesis.json", size: 612, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "../config/status-chain-genesis.json", size: 612, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb, 0xf0, 0xc, 0x1, 0x95, 0x65, 0x6, 0x55, 0x48, 0x8f, 0x83, 0xa0, 0xb4, 0x81, 0xda, 0xad, 0x30, 0x6d, 0xb2, 0x78, 0x1b, 0x26, 0x4, 0x13, 0x12, 0x9, 0x6, 0xae, 0x3a, 0x2c, 0x1, 0x71}} return a, nil } @@ -237,7 +237,7 @@ func keysBootnodeKey() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/bootnode.key", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/bootnode.key", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x31, 0xcf, 0x27, 0xd4, 0x96, 0x2e, 0x32, 0xcd, 0x58, 0x96, 0x2a, 0xe5, 0x8c, 0xa0, 0xf1, 0x73, 0x1f, 0xd6, 0xd6, 0x8b, 0xb, 0x73, 0xd3, 0x2c, 0x84, 0x1a, 0x56, 0xa4, 0x74, 0xb6, 0x95, 0x20}} return a, nil } @@ -257,7 +257,7 @@ func keysFirebaseauthkey() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(0644), modTime: time.Unix(1574347314, 0)} + info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(0644), modTime: time.Unix(1536843582, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe, 0x69, 0x23, 0x64, 0x7d, 0xf9, 0x14, 0x37, 0x6f, 0x2b, 0x1, 0xf0, 0xb0, 0xa4, 0xb2, 0xd0, 0x18, 0xcd, 0xf9, 0xeb, 0x57, 0xa3, 0xfd, 0x79, 0x25, 0xa7, 0x9c, 0x3, 0xce, 0x26, 0xec, 0xe1}} return a, nil } @@ -277,7 +277,7 @@ func keysTestAccount1StatusChainPk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xba, 0x35, 0x1, 0x2b, 0x9d, 0xad, 0xf0, 0x2d, 0x3c, 0x4d, 0x6, 0xb5, 0x22, 0x2, 0x47, 0xd4, 0x1c, 0xf4, 0x31, 0x2f, 0xb, 0x5b, 0x27, 0x5d, 0x43, 0x97, 0x58, 0x2d, 0xf0, 0xe1, 0xbe}} return a, nil } @@ -297,7 +297,7 @@ func keysTestAccount1Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9, 0x43, 0xc2, 0xf4, 0x8c, 0xc6, 0x64, 0x25, 0x8c, 0x7, 0x8c, 0xa8, 0x89, 0x2b, 0x7b, 0x9b, 0x4f, 0x81, 0xcb, 0xce, 0x3d, 0xef, 0x82, 0x9c, 0x27, 0x27, 0xa9, 0xc5, 0x46, 0x70, 0x30, 0x38}} return a, nil } @@ -317,7 +317,7 @@ func keysTestAccount2StatusChainPk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9, 0xf8, 0x5c, 0xe9, 0x92, 0x96, 0x2d, 0x88, 0x2b, 0x8e, 0x42, 0x3f, 0xa4, 0x93, 0x6c, 0xad, 0xe9, 0xc0, 0x1b, 0x8a, 0x8, 0x8c, 0x5e, 0x7a, 0x84, 0xa2, 0xf, 0x9f, 0x77, 0x58, 0x2c, 0x2c}} return a, nil } @@ -337,7 +337,7 @@ func keysTestAccount2Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9f, 0x72, 0xd5, 0x95, 0x5c, 0x5a, 0x99, 0x9d, 0x2f, 0x21, 0x83, 0xd7, 0x10, 0x17, 0x4a, 0x3d, 0x65, 0xc9, 0x26, 0x1a, 0x2c, 0x9d, 0x65, 0x63, 0xd2, 0xa0, 0xfc, 0x7c, 0x0, 0x87, 0x38, 0x9f}} return a, nil } @@ -357,7 +357,7 @@ func keysTestAccount3BeforeEip55Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1576772083, 0)} + info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x40, 0x56, 0xc1, 0x5e, 0x10, 0x6e, 0x28, 0x15, 0x3, 0x4e, 0xc4, 0xc4, 0x71, 0x4d, 0x16, 0x99, 0xcc, 0x1b, 0x63, 0xee, 0x10, 0x20, 0xe4, 0x59, 0x52, 0x3f, 0xc0, 0xad, 0x15, 0x13, 0x72}} return a, nil } diff --git a/t/bindata.go b/t/bindata.go index d73f999a6..6b84c0772 100644 --- a/t/bindata.go +++ b/t/bindata.go @@ -86,7 +86,7 @@ func configPublicChainAccountsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 307, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 307, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x76, 0x5d, 0xc0, 0xfe, 0x57, 0x50, 0x18, 0xec, 0x2d, 0x61, 0x1b, 0xa9, 0x81, 0x11, 0x5f, 0x77, 0xf7, 0xb6, 0x67, 0x82, 0x1, 0x40, 0x68, 0x9d, 0xc5, 0x41, 0xaf, 0xce, 0x43, 0x81, 0x92, 0x96}} return a, nil } @@ -106,7 +106,7 @@ func configStatusChainAccountsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0xb3, 0x61, 0x51, 0x70, 0x3c, 0x12, 0x3e, 0xf1, 0x1c, 0x81, 0xfb, 0x9a, 0x7c, 0xe3, 0x63, 0xd0, 0x8f, 0x12, 0xc5, 0x2d, 0xf4, 0xea, 0x27, 0x33, 0xef, 0xca, 0xf9, 0x3f, 0x72, 0x44, 0xbf}} return a, nil } @@ -126,7 +126,7 @@ func configTestDataJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1574771268, 0)} + info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xce, 0x9d, 0x80, 0xf5, 0x87, 0xfa, 0x57, 0x1d, 0xa1, 0xd5, 0x7a, 0x10, 0x3, 0xac, 0xd7, 0xf4, 0x64, 0x32, 0x96, 0x2b, 0xb7, 0x21, 0xb7, 0xa6, 0x80, 0x40, 0xe9, 0x65, 0xe3, 0xd6, 0xbd, 0x40}} return a, nil } @@ -223,8 +223,10 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "config/public-chain-accounts.json": configPublicChainAccountsJson, + "config/status-chain-accounts.json": configStatusChainAccountsJson, - "config/test-data.json": configTestDataJson, + + "config/test-data.json": configTestDataJson, } // AssetDir returns the file names below a certain diff --git a/vendor/github.com/elastic/gosigar/CHANGELOG.md b/vendor/github.com/elastic/gosigar/CHANGELOG.md index ae848ffb1..9377542ab 100644 --- a/vendor/github.com/elastic/gosigar/CHANGELOG.md +++ b/vendor/github.com/elastic/gosigar/CHANGELOG.md @@ -12,17 +12,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### 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] ### Fixed diff --git a/vendor/github.com/elastic/gosigar/README.md b/vendor/github.com/elastic/gosigar/README.md index ca1854bf2..ecdfc1c3c 100644 --- a/vendor/github.com/elastic/gosigar/README.md +++ b/vendor/github.com/elastic/gosigar/README.md @@ -37,7 +37,6 @@ The features vary by operating system. | ProcMem | X | X | X | | X | | ProcState | X | X | X | | X | | ProcTime | X | X | X | | X | -| Rusage | X | | X | | | | Swap | X | X | | X | X | | Uptime | X | X | | X | X | diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin.go b/vendor/github.com/elastic/gosigar/sigar_darwin.go index 4a8309521..a90b998c2 100644 --- a/vendor/github.com/elastic/gosigar/sigar_darwin.go +++ b/vendor/github.com/elastic/gosigar/sigar_darwin.go @@ -40,6 +40,18 @@ func (self *LoadAverage) Get() error { 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 { var vmstat C.vm_statistics_data_t diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin_386.go b/vendor/github.com/elastic/gosigar/sigar_darwin_386.go deleted file mode 100644 index 92c7ff040..000000000 --- a/vendor/github.com/elastic/gosigar/sigar_darwin_386.go +++ /dev/null @@ -1,18 +0,0 @@ -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 -} diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go b/vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go deleted file mode 100644 index 29e5b604a..000000000 --- a/vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go +++ /dev/null @@ -1,18 +0,0 @@ -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 -} diff --git a/vendor/github.com/elastic/gosigar/sigar_interface.go b/vendor/github.com/elastic/gosigar/sigar_interface.go index 57501b969..df79ae08d 100644 --- a/vendor/github.com/elastic/gosigar/sigar_interface.go +++ b/vendor/github.com/elastic/gosigar/sigar_interface.go @@ -4,7 +4,6 @@ import ( "time" ) -// ErrNotImplemented is returned when a particular statistic isn't implemented on the host OS. type ErrNotImplemented struct { OS string } @@ -13,7 +12,6 @@ func (e ErrNotImplemented) Error() string { return "not implemented on " + e.OS } -// IsNotImplemented returns true if the error is ErrNotImplemented func IsNotImplemented(err error) bool { switch err.(type) { case ErrNotImplemented, *ErrNotImplemented: @@ -23,7 +21,6 @@ func IsNotImplemented(err error) bool { } } -// Sigar is an interface for gathering system host stats type Sigar interface { CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) GetLoadAverage() (LoadAverage, error) @@ -35,7 +32,6 @@ type Sigar interface { GetRusage(who int) (Rusage, error) } -// Cpu contains CPU time stats type Cpu struct { User uint64 Nice uint64 @@ -47,13 +43,11 @@ type Cpu struct { Stolen uint64 } -// Total returns total CPU time func (cpu *Cpu) Total() uint64 { return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle + cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen } -// Delta returns the difference between two Cpu stat objects func (cpu Cpu) Delta(other Cpu) Cpu { return Cpu{ User: cpu.User - other.User, @@ -67,17 +61,14 @@ func (cpu Cpu) Delta(other Cpu) Cpu { } } -// LoadAverage reports standard load averages type LoadAverage struct { One, Five, Fifteen float64 } -// Uptime reports system uptime type Uptime struct { Length float64 } -// Mem contains host memory stats type Mem struct { Total uint64 Used uint64 @@ -86,14 +77,12 @@ type Mem struct { ActualUsed uint64 } -// Swap contains stats on swap space type Swap struct { Total uint64 Used uint64 Free uint64 } -// HugeTLBPages contains HugePages stats type HugeTLBPages struct { Total uint64 Free uint64 @@ -103,19 +92,16 @@ type HugeTLBPages struct { TotalAllocatedSize uint64 } -// CpuList contains a list of CPUs on the host system type CpuList struct { List []Cpu } -// FDUsage contains stats on filesystem usage type FDUsage struct { Open uint64 Unused uint64 Max uint64 } -// FileSystem contains basic information about a given mounted filesystem type FileSystem struct { DirName string DevName string @@ -125,12 +111,10 @@ type FileSystem struct { Flags uint32 } -// FileSystemList gets a list of mounted filesystems type FileSystemList struct { List []FileSystem } -// FileSystemUsage contains basic stats for the specified filesystem type FileSystemUsage struct { Total uint64 Used uint64 @@ -140,30 +124,21 @@ type FileSystemUsage struct { FreeFiles uint64 } -// ProcList contains a list of processes found on the host system type ProcList struct { List []int } -// RunState is a byte-long code used to specify the current runtime state of a process type RunState byte const ( - // RunStateSleep corresponds to a sleep state - RunStateSleep = 'S' - // RunStateRun corresponds to a running state - RunStateRun = 'R' - // 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 + RunStateSleep = 'S' + RunStateRun = 'R' + RunStateStop = 'T' + RunStateZombie = 'Z' + RunStateIdle = 'D' RunStateUnknown = '?' ) -// ProcState contains basic metadata and process ownership info for the specified process type ProcState struct { Name string Username string @@ -176,7 +151,6 @@ type ProcState struct { Processor int } -// ProcMem contains memory statistics for a specified process type ProcMem struct { Size uint64 Resident uint64 @@ -186,7 +160,6 @@ type ProcMem struct { PageFaults uint64 } -// ProcTime contains run time statistics for a specified process type ProcTime struct { StartTime uint64 User uint64 @@ -194,31 +167,26 @@ type ProcTime struct { Total uint64 } -// ProcArgs contains a list of args for a specified process type ProcArgs struct { List []string } -// ProcEnv contains a map of environment variables for specified process type ProcEnv struct { Vars map[string]string } -// ProcExe contains basic data about a specified process type ProcExe struct { Name string Cwd string Root string } -// ProcFDUsage contains data on file limits and usage type ProcFDUsage struct { Open uint64 SoftLimit uint64 HardLimit uint64 } -// Rusage contains data on resource usage for a specified process type Rusage struct { Utime time.Duration Stime time.Duration diff --git a/vendor/github.com/elastic/gosigar/sigar_windows.go b/vendor/github.com/elastic/gosigar/sigar_windows.go index d1204b80e..fc868daf3 100644 --- a/vendor/github.com/elastic/gosigar/sigar_windows.go +++ b/vendor/github.com/elastic/gosigar/sigar_windows.go @@ -8,6 +8,7 @@ import ( "path/filepath" "runtime" "strings" + "sync" "syscall" "time" @@ -23,6 +24,11 @@ var ( // 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer // OS versions it is set to 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() { @@ -57,11 +63,19 @@ func (self *Uptime) Get() error { if !version.IsWindowsVistaOrGreater() { return ErrNotImplemented{runtime.GOOS} } - uptimeMs, err := windows.GetTickCount64() - if err != nil { - return errors.Wrap(err, "failed to get boot time using GetTickCount64 api") + + bootTimeLock.Lock() + defer bootTimeLock.Unlock() + 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 } diff --git a/vendor/github.com/elastic/gosigar/sys/windows/doc.go b/vendor/github.com/elastic/gosigar/sys/windows/doc.go index 9dca12504..dda57aa83 100644 --- a/vendor/github.com/elastic/gosigar/sys/windows/doc.go +++ b/vendor/github.com/elastic/gosigar/sys/windows/doc.go @@ -1,8 +1,2 @@ // Package windows contains various Windows system call. 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 diff --git a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go index 371eb256b..0c11fda31 100644 --- a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go +++ b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go @@ -580,6 +580,11 @@ func GetTickCount64() (uptime uint64, err error) { 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 //sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx //sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW diff --git a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go index 75f19c0ea..cd5d9ca32 100644 --- a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go +++ b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go @@ -5,8 +5,6 @@ package windows import ( "syscall" "unsafe" - - "golang.org/x/sys/windows" ) var _ unsafe.Pointer @@ -37,10 +35,10 @@ func errnoErr(e syscall.Errno) error { } var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modpsapi = windows.NewLazySystemDLL("psapi.dll") - modntdll = windows.NewLazySystemDLL("ntdll.dll") - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + modpsapi = syscall.NewLazyDLL("psapi.dll") + modntdll = syscall.NewLazyDLL("ntdll.dll") + modadvapi32 = syscall.NewLazyDLL("advapi32.dll") procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") diff --git a/vendor/github.com/jackpal/go-nat-pmp/.travis.yml b/vendor/github.com/jackpal/go-nat-pmp/.travis.yml index 3f468e74b..b939153f7 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/.travis.yml +++ b/vendor/github.com/jackpal/go-nat-pmp/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - 1.13.4 + - 1.6.2 - tip allowed_failures: @@ -11,3 +11,10 @@ install: - go get -d -v ./... && go install -race -v ./... script: go test -race -v ./... + +sudo: false + +addons: + apt: + packages: + - iproute2 diff --git a/vendor/github.com/jackpal/go-nat-pmp/README.md b/vendor/github.com/jackpal/go-nat-pmp/README.md index cc45afe56..3ca687f0b 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/README.md +++ b/vendor/github.com/jackpal/go-nat-pmp/README.md @@ -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. -See https://tools.ietf.org/rfc/rfc6886.txt +See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03 [![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp) @@ -14,53 +14,27 @@ See https://tools.ietf.org/rfc/rfc6886.txt Get the package --------------- - # Get the go-nat-pmp package. go get -u github.com/jackpal/go-nat-pmp - + 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 ( - "fmt" - "github.com/jackpal/gateway" natpmp "github.com/jackpal/go-nat-pmp" ) - func main() { - gatewayIP, err := gateway.DiscoverGateway() - 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) + gatewayIP, err = gateway.DiscoverGateway() + if err != nil { + return } -Build the example - - go build - ./hello - - External IP address: [www xxx yyy zzz] + client := natpmp.NewClient(gatewayIP) + response, err := client.GetExternalAddress() + if err != nil { + return + } + print("External IP address:", response.ExternalIPAddress) Clients ------- diff --git a/vendor/github.com/jackpal/go-nat-pmp/natpmp.go b/vendor/github.com/jackpal/go-nat-pmp/natpmp.go index f296c817e..e42065306 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/natpmp.go +++ b/vendor/github.com/jackpal/go-nat-pmp/natpmp.go @@ -3,43 +3,34 @@ package natpmp import ( "fmt" "net" - "time" ) // Implement the NAT-PMP protocol, typically supported by Apple routers and open source // routers such as DD-WRT and Tomato. // -// See https://tools.ietf.org/rfc/rfc6886.txt +// See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03 // // Usage: // // client := natpmp.NewClient(gatewayIP) // response, err := client.GetExternalAddress() -// The recommended mapping lifetime for AddPortMapping. +// The recommended mapping lifetime for AddPortMapping const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600 // Interface used to make remote procedure calls. type caller interface { - call(msg []byte, timeout time.Duration) (result []byte, err error) + call(msg []byte) (result []byte, err error) } // Client is a NAT-PMP protocol client. type Client struct { - caller caller - timeout time.Duration + caller caller } // 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) { - 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} + return &Client{&network{gateway}} } // Results of the NAT-PMP GetExternalAddress operation. @@ -49,8 +40,6 @@ type GetExternalAddressResult struct { } // 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) { msg := make([]byte, 2) msg[0] = 0 // Version 0 @@ -73,8 +62,7 @@ type AddPortMappingResult struct { PortMappingLifetimeInSeconds uint32 } -// 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. +// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0 func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) { var opcode byte if protocol == "udp" { @@ -88,7 +76,6 @@ func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternal msg := make([]byte, 12) msg[0] = 0 // Version 0 msg[1] = opcode - // [2:3] is reserved. writeNetworkOrderUint16(msg[4:6], uint16(internalPort)) writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort)) writeNetworkOrderUint32(msg[8:12], uint32(lifetime)) @@ -105,7 +92,7 @@ func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternal } func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) { - result, err = n.caller.call(msg, n.timeout) + result, err = n.caller.call(msg) if err != nil { return } diff --git a/vendor/github.com/jackpal/go-nat-pmp/network.go b/vendor/github.com/jackpal/go-nat-pmp/network.go index c42b4fee9..9def1acda 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/network.go +++ b/vendor/github.com/jackpal/go-nat-pmp/network.go @@ -2,6 +2,7 @@ package natpmp import ( "fmt" + "log" "net" "time" ) @@ -15,7 +16,7 @@ type network struct { gateway net.IP } -func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err error) { +func (n *network) call(msg []byte) (result []byte, err error) { var server net.UDPAddr server.IP = n.gateway server.Port = nAT_PMP_PORT @@ -28,18 +29,12 @@ func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err er // 16 bytes is the maximum result size. result = make([]byte, 16) - var finalTimeout time.Time - if timeout != 0 { - finalTimeout = time.Now().Add(timeout) - } - needNewDeadline := true var tries uint - for tries = 0; (tries < nAT_TRIES && finalTimeout.IsZero()) || time.Now().Before(finalTimeout); { + for tries = 0; tries < nAT_TRIES; { if needNewDeadline { - nextDeadline := time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond) - err = conn.SetDeadline(minTime(nextDeadline, finalTimeout)) + err = conn.SetDeadline(time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond)) if err != nil { return } @@ -61,6 +56,7 @@ func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err er return } if !remoteAddr.IP.Equal(n.gateway) { + log.Printf("Ignoring packet because IPs differ:", remoteAddr, n.gateway) // Ignore this packet. // Continue without increasing retransmission timeout or deadline. continue @@ -74,16 +70,3 @@ func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err er err = fmt.Errorf("Timed out trying to contact gateway") 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 -} diff --git a/vendor/github.com/jackpal/go-nat-pmp/recorder.go b/vendor/github.com/jackpal/go-nat-pmp/recorder.go index 845703672..e70a3c65c 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/recorder.go +++ b/vendor/github.com/jackpal/go-nat-pmp/recorder.go @@ -1,7 +1,5 @@ package natpmp -import "time" - type callObserver interface { observeCall(msg []byte, result []byte, err error) } @@ -12,8 +10,8 @@ type recorder struct { observer callObserver } -func (n *recorder) call(msg []byte, timeout time.Duration) (result []byte, err error) { - result, err = n.child.call(msg, timeout) +func (n *recorder) call(msg []byte) (result []byte, err error) { + result, err = n.child.call(msg) n.observer.observeCall(msg, result, err) return } diff --git a/vendor/github.com/rs/cors/.travis.yml b/vendor/github.com/rs/cors/.travis.yml index 9a68b5676..17e5e50d5 100644 --- a/vendor/github.com/rs/cors/.travis.yml +++ b/vendor/github.com/rs/cors/.travis.yml @@ -1,8 +1,7 @@ language: go go: +- 1.9 - "1.10" -- "1.11" -- "1.12" - tip matrix: allow_failures: diff --git a/vendor/github.com/rs/cors/cors.go b/vendor/github.com/rs/cors/cors.go index 273093463..d301ca724 100644 --- a/vendor/github.com/rs/cors/cors.go +++ b/vendor/github.com/rs/cors/cors.go @@ -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: c := cors.New(cors.Options{ - AllowedOrigins: []string{"foo.com"}, - AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodDelete}, + AllowedOrigins: []string{"foo.com"}, + AllowedMethods: []string{"GET", "POST", "DELETE"}, AllowCredentials: true, }) @@ -69,15 +69,10 @@ type Options struct { Debug bool } -// Logger generic interface for logger -type Logger interface { - Printf(string, ...interface{}) -} - // Cors http handler type Cors struct { // Debug logger - Log Logger + Log *log.Logger // Normalized list of plain allowed origins allowedOrigins []string // List of allowed origins containing wildcards @@ -111,7 +106,7 @@ func New(options Options) *Cors { maxAge: options.MaxAge, optionPassthrough: options.OptionsPassthrough, } - if options.Debug && c.Log == nil { + if options.Debug { c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags) } @@ -166,7 +161,7 @@ func New(options Options) *Cors { // Allowed Methods if len(options.AllowedMethods) == 0 { // Default is spec's "simple" methods - c.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead} + c.allowedMethods = []string{"GET", "POST", "HEAD"} } else { c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper) } @@ -183,15 +178,8 @@ func Default() *Cors { // origins with all standard methods with any header and credentials. func AllowAll() *Cors { return New(Options{ - AllowedOrigins: []string{"*"}, - AllowedMethods: []string{ - http.MethodHead, - http.MethodGet, - http.MethodPost, - http.MethodPut, - http.MethodPatch, - http.MethodDelete, - }, + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"HEAD", "GET", "POST", "PUT", "PATCH", "DELETE"}, AllowedHeaders: []string{"*"}, AllowCredentials: false, }) @@ -316,6 +304,10 @@ func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { headers := w.Header() 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 headers.Add("Vary", "Origin") if origin == "" { @@ -350,7 +342,7 @@ func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { c.logf(" Actual response added headers: %v", headers) } -// convenience method. checks if a logger is set. +// convenience method. checks if debugging is turned on before printing func (c *Cors) logf(format string, a ...interface{}) { if c.Log != nil { c.Log.Printf(format, a...) diff --git a/vendor/github.com/rs/cors/utils.go b/vendor/github.com/rs/cors/utils.go index db83ac3ea..53ad9e9db 100644 --- a/vendor/github.com/rs/cors/utils.go +++ b/vendor/github.com/rs/cors/utils.go @@ -12,7 +12,7 @@ type wildcard struct { } func (w wildcard) match(s string) bool { - return len(s) >= len(w.prefix)+len(w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix) + return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix) } // convert converts a list of string using the passed converter function diff --git a/vendor/github.com/status-im/status-go/waku/api.go b/vendor/github.com/status-im/status-go/waku/api.go deleted file mode 100644 index 73712bf7a..000000000 --- a/vendor/github.com/status-im/status-go/waku/api.go +++ /dev/null @@ -1,600 +0,0 @@ -// 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 . -// -// 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 -} diff --git a/vendor/github.com/status-im/status-go/waku/config.go b/vendor/github.com/status-im/status-go/waku/config.go deleted file mode 100644 index 2a82a5ffd..000000000 --- a/vendor/github.com/status-im/status-go/waku/config.go +++ /dev/null @@ -1,35 +0,0 @@ -// 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 . -// -// 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, -} diff --git a/vendor/github.com/status-im/status-go/waku/doc.go b/vendor/github.com/status-im/status-go/waku/doc.go deleted file mode 100644 index 03feccbce..000000000 --- a/vendor/github.com/status-im/status-go/waku/doc.go +++ /dev/null @@ -1,217 +0,0 @@ -// 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 . -// -// 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"` - - // Topics is a list of topics. A returned message should - // belong to one of the topics from the list. - Topics [][]byte `json:"topics"` -} - -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 && len(r.Topics) == 0 { - return errors.New("invalid 'Bloom' or 'Topics', one must be non-empty") - } - - 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{}) -} diff --git a/vendor/github.com/status-im/status-go/waku/envelope.go b/vendor/github.com/status-im/status-go/waku/envelope.go deleted file mode 100644 index e4972ed16..000000000 --- a/vendor/github.com/status-im/status-go/waku/envelope.go +++ /dev/null @@ -1,272 +0,0 @@ -// 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 . -// -// 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 -} diff --git a/vendor/github.com/status-im/status-go/waku/events.go b/vendor/github.com/status-im/status-go/waku/events.go deleted file mode 100644 index 8c22e5fb9..000000000 --- a/vendor/github.com/status-im/status-go/waku/events.go +++ /dev/null @@ -1,64 +0,0 @@ -// 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 . -// -// 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{} -} diff --git a/vendor/github.com/status-im/status-go/waku/filter.go b/vendor/github.com/status-im/status-go/waku/filter.go deleted file mode 100644 index dfe3f60e5..000000000 --- a/vendor/github.com/status-im/status-go/waku/filter.go +++ /dev/null @@ -1,296 +0,0 @@ -// 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 . -// -// 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 -} diff --git a/vendor/github.com/status-im/status-go/waku/go.mod b/vendor/github.com/status-im/status-go/waku/go.mod deleted file mode 100644 index b11bde74d..000000000 --- a/vendor/github.com/status-im/status-go/waku/go.mod +++ /dev/null @@ -1,24 +0,0 @@ -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.7 - -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 -) diff --git a/vendor/github.com/status-im/status-go/waku/go.sum b/vendor/github.com/status-im/status-go/waku/go.sum deleted file mode 100644 index d8b156dc4..000000000 --- a/vendor/github.com/status-im/status-go/waku/go.sum +++ /dev/null @@ -1,309 +0,0 @@ -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/btcd v0.20.1-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/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q= -github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g= -github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= -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-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/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= diff --git a/vendor/github.com/status-im/status-go/waku/handshake.go b/vendor/github.com/status-im/status-go/waku/handshake.go deleted file mode 100644 index 99effbe37..000000000 --- a/vendor/github.com/status-im/status-go/waku/handshake.go +++ /dev/null @@ -1,125 +0,0 @@ -package waku - -import ( - "errors" - "fmt" - "io" - "math" - "reflect" - "strings" - - "github.com/ethereum/go-ethereum/rlp" -) - -// statusOptions defines additional information shared between peers -// during the handshake. -// There might be more options provided then fields in statusOptions -// and they should be ignored during deserialization to stay forward compatible. -// In the case of RLP, options should be serialized to an array of tuples -// where the first item is a field name and the second is a RLP-serialized value. -type statusOptions struct { - PoWRequirement uint64 `rlp:"key=0"` // RLP does not support float64 natively - BloomFilter []byte `rlp:"key=1"` - LightNodeEnabled bool `rlp:"key=2"` - ConfirmationsEnabled bool `rlp:"key=3"` - RateLimits RateLimits `rlp:"key=4"` - TopicInterest []TopicType `rlp:"key=5"` -} - -var idxFieldKey = make(map[int]string) -var keyFieldIdx = func() map[string]int { - result := make(map[string]int) - opts := statusOptions{} - v := reflect.ValueOf(opts) - for i := 0; i < v.NumField(); i++ { - // skip unexported fields - if !v.Field(i).CanInterface() { - continue - } - rlpTag := v.Type().Field(i).Tag.Get("rlp") - // skip fields without rlp field tag - if rlpTag == "" { - continue - } - key := strings.Split(rlpTag, "=")[1] - result[key] = i - idxFieldKey[i] = key - } - return result -}() - -func (o statusOptions) PoWRequirementF() float64 { - return math.Float64frombits(o.PoWRequirement) -} - -func (o *statusOptions) SetPoWRequirementFromF(val float64) { - o.PoWRequirement = math.Float64bits(val) -} - -func (o statusOptions) EncodeRLP(w io.Writer) error { - v := reflect.ValueOf(o) - optionsList := make([]interface{}, 0, v.NumField()) - for i := 0; i < v.NumField(); i++ { - value := v.Field(i).Interface() - key, ok := idxFieldKey[i] - if !ok { - continue - } - optionsList = append(optionsList, []interface{}{key, value}) - } - return rlp.Encode(w, optionsList) -} - -func (o *statusOptions) DecodeRLP(s *rlp.Stream) error { - _, err := s.List() - if err != nil { - return fmt.Errorf("expected an outer list: %w", err) - } - - v := reflect.ValueOf(o) - -loop: - for { - _, err := s.List() - switch err { - case nil: - // continue to decode a key - case rlp.EOL: - break loop - default: - return fmt.Errorf("expected an inner list: %w", err) - } - var key string - if err := s.Decode(&key); err != nil { - return fmt.Errorf("invalid key: %w", err) - } - // Skip processing if a key does not exist. - // It might happen when there is a new peer - // which supports a new option with - // a higher index. - idx, ok := keyFieldIdx[key] - if !ok { - // Read the rest of the list items and dump them. - _, err := s.Raw() - if err != nil { - return fmt.Errorf("failed to read the value of key %s: %w", key, err) - } - continue - } - if err := s.Decode(v.Elem().Field(idx).Addr().Interface()); err != nil { - return fmt.Errorf("failed to decode an option %s: %w", key, err) - } - if err := s.ListEnd(); err != nil { - return err - } - } - - return s.ListEnd() -} - -func (o statusOptions) Validate() error { - if len(o.TopicInterest) > 1000 { - return errors.New("topic interest is limited by 1000 items") - } - return nil -} diff --git a/vendor/github.com/status-im/status-go/waku/mailserver_response.go b/vendor/github.com/status-im/status-go/waku/mailserver_response.go deleted file mode 100644 index fb1b9ad2a..000000000 --- a/vendor/github.com/status-im/status-go/waku/mailserver_response.go +++ /dev/null @@ -1,158 +0,0 @@ -// 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 . -// -// 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:] -} diff --git a/vendor/github.com/status-im/status-go/waku/message.go b/vendor/github.com/status-im/status-go/waku/message.go deleted file mode 100644 index b35953dea..000000000 --- a/vendor/github.com/status-im/status-go/waku/message.go +++ /dev/null @@ -1,361 +0,0 @@ -// 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 . -// -// 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) -} diff --git a/vendor/github.com/status-im/status-go/waku/metrics.go b/vendor/github.com/status-im/status-go/waku/metrics.go deleted file mode 100644 index f1f08e131..000000000 --- a/vendor/github.com/status-im/status-go/waku/metrics.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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 . -// -// 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) -} diff --git a/vendor/github.com/status-im/status-go/waku/peer.go b/vendor/github.com/status-im/status-go/waku/peer.go deleted file mode 100644 index 01d8edc78..000000000 --- a/vendor/github.com/status-im/status-go/waku/peer.go +++ /dev/null @@ -1,318 +0,0 @@ -// 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 . -// -// 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() { - opts := statusOptions{ - BloomFilter: p.host.BloomFilter(), - LightNodeEnabled: isLightNode, - ConfirmationsEnabled: p.host.ConfirmationsEnabled(), - RateLimits: p.host.RateLimits(), - TopicInterest: nil, - } - opts.SetPoWRequirementFromF(p.host.MinPow()) - errc <- p2p.SendItems(p.ws, statusCode, ProtocolVersion, opts) - }() - - // 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) - } - - var ( - peerProtocolVersion uint64 - peerOptions statusOptions - ) - s := rlp.NewStream(packet.Payload, uint64(packet.Size)) - if _, err := s.List(); err != nil { - return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err) - } - // Validate protocol version. - if err := s.Decode(&peerProtocolVersion); err != nil { - return fmt.Errorf("p [%x]: failed to decode peer protocol version: %w", p.ID(), err) - } - if peerProtocolVersion != ProtocolVersion { - return fmt.Errorf("p [%x]: protocol version mismatch %d != %d", p.ID(), peerProtocolVersion, ProtocolVersion) - } - // Decode and validate other status packet options. - if err := s.Decode(&peerOptions); err != nil { - return fmt.Errorf("p [%x]: failed to decode status options: %w", p.ID(), err) - } - if err := s.ListEnd(); err != nil { - return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err) - } - if err := peerOptions.Validate(); err != nil { - return fmt.Errorf("p [%x]: sent invalid options: %w", p.ID(), err) - } - // Validate and save peer's PoW. - pow := peerOptions.PoWRequirementF() - 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 - // Validate and save peer's bloom filters. - bloom := peerOptions.BloomFilter - bloomSize := len(bloom) - if bloomSize != 0 && bloomSize != BloomFilterSize { - return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), bloomSize) - } - p.setBloomFilter(bloom) - // Validate and save other peer's options. - if peerOptions.LightNodeEnabled && isLightNode && isRestrictedLightNodeConnection { - return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID()) - } - p.confirmationsEnabled = peerOptions.ConfirmationsEnabled - p.setRateLimits(peerOptions.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 -} diff --git a/vendor/github.com/status-im/status-go/waku/rate_limiter.go b/vendor/github.com/status-im/status-go/waku/rate_limiter.go deleted file mode 100644 index 2ea260f80..000000000 --- a/vendor/github.com/status-im/status-go/waku/rate_limiter.go +++ /dev/null @@ -1,236 +0,0 @@ -// 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 . -// -// 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 -} diff --git a/vendor/github.com/status-im/status-go/waku/topic.go b/vendor/github.com/status-im/status-go/waku/topic.go deleted file mode 100644 index a9e77ff89..000000000 --- a/vendor/github.com/status-im/status-go/waku/topic.go +++ /dev/null @@ -1,56 +0,0 @@ -// 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 . -// -// 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[:]) -} diff --git a/vendor/github.com/status-im/status-go/waku/waku.go b/vendor/github.com/status-im/status-go/waku/waku.go deleted file mode 100644 index ad06fc63f..000000000 --- a/vendor/github.com/status-im/status-go/waku/waku.go +++ /dev/null @@ -1,1555 +0,0 @@ -// 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 . -// -// 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" - "crypto/ecdsa" - "crypto/sha256" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "runtime" - "sync" - "time" - - "github.com/ethereum/go-ethereum/common/hexutil" - - "go.uber.org/zap" - - mapset "github.com/deckarep/golang-set" - "golang.org/x/crypto/pbkdf2" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" -) - -// TimeSyncError error for clock skew errors. -type TimeSyncError error - -type Bridge interface { - Pipe() (<-chan *Envelope, chan<- *Envelope) -} - -type settings struct { - MaxMsgSize uint32 // Maximal message length allowed by the waku node - EnableConfirmations bool // Enable sending message confirmations - MinPow float64 // Minimal PoW required by the waku node - MinPowTolerance float64 // Minimal PoW tolerated by the waku node for a limited time - BloomFilter []byte // Bloom filter for topics of interest for this node - BloomFilterTolerance []byte // Bloom filter tolerated by the waku node for a limited time - LightClient bool // Light client mode enabled does not forward messages - RestrictLightClientsConn bool // Restrict connection between two light clients - SyncAllowance int // Maximum time in seconds allowed to process the waku-related messages -} - -// Waku represents a dark communication interface through the Ethereum -// network, using its very own P2P communication layer. -type Waku struct { - protocol p2p.Protocol // Protocol description and parameters - filters *Filters // Message filters installed with Subscribe function - - privateKeys map[string]*ecdsa.PrivateKey // Private key storage - symKeys map[string][]byte // Symmetric key storage - keyMu sync.RWMutex // Mutex associated with key stores - - envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node - expirations map[uint32]mapset.Set // Message expiration pool - poolMu sync.RWMutex // Mutex to sync the message and expiration pools - - peers map[*Peer]struct{} // Set of currently active peers - peerMu sync.RWMutex // Mutex to sync the active peer set - - msgQueue chan *Envelope // Message queue for normal waku messages - p2pMsgQueue chan interface{} // Message queue for peer-to-peer messages (not to be forwarded any further) and history delivery confirmations. - quit chan struct{} // Channel used for graceful exit - - settings settings // Holds configuration settings that can be dynamically changed - settingsMu sync.RWMutex // Mutex to sync the settings access - - mailServer MailServer - - rateLimiter *PeerRateLimiter - - envelopeFeed event.Feed - - timeSource func() time.Time // source of time for waku - - bridge Bridge - bridgeWg sync.WaitGroup - cancelBridge chan struct{} - - logger *zap.Logger -} - -// New creates a Waku client ready to communicate through the Ethereum P2P network. -func New(cfg *Config, logger *zap.Logger) *Waku { - if cfg == nil { - c := DefaultConfig - cfg = &c - } - - if logger == nil { - logger = zap.NewNop() - } - - waku := &Waku{ - privateKeys: make(map[string]*ecdsa.PrivateKey), - symKeys: make(map[string][]byte), - envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]mapset.Set), - peers: make(map[*Peer]struct{}), - msgQueue: make(chan *Envelope, messageQueueLimit), - p2pMsgQueue: make(chan interface{}, messageQueueLimit), - quit: make(chan struct{}), - timeSource: time.Now, - logger: logger, - } - - waku.settings = settings{ - MaxMsgSize: cfg.MaxMessageSize, - MinPow: cfg.MinimumAcceptedPoW, - MinPowTolerance: cfg.MinimumAcceptedPoW, - EnableConfirmations: cfg.EnableConfirmations, - LightClient: cfg.LightClient, - RestrictLightClientsConn: cfg.RestrictLightClientsConn, - SyncAllowance: DefaultSyncAllowance, - } - - if cfg.FullNode { - waku.settings.BloomFilter = MakeFullNodeBloom() - waku.settings.BloomFilterTolerance = MakeFullNodeBloom() - } - - waku.filters = NewFilters(waku) - - // p2p waku sub-protocol handler - waku.protocol = p2p.Protocol{ - Name: ProtocolName, - Version: uint(ProtocolVersion), - Length: NumberOfMessageCodes, - Run: waku.HandlePeer, - NodeInfo: func() interface{} { - return map[string]interface{}{ - "version": ProtocolVersionStr, - "maxMessageSize": waku.MaxMessageSize(), - "minimumPoW": waku.MinPow(), - } - }, - } - - return waku -} - -// Version returns the waku sub-protocol version number. -func (w *Waku) Version() uint { - return w.protocol.Version -} - -// MinPow returns the PoW value required by this node. -func (w *Waku) MinPow() float64 { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.MinPow -} - -// SetMinimumPoW sets the minimal PoW required by this node -func (w *Waku) SetMinimumPoW(val float64, tolerate bool) error { - if val < 0.0 { - return fmt.Errorf("invalid PoW: %f", val) - } - - w.settingsMu.Lock() - w.settings.MinPow = val - w.settingsMu.Unlock() - - w.notifyPeersAboutPowRequirementChange(val) - - if tolerate { - go func() { - // allow some time before all the peers have processed the notification - time.Sleep(time.Duration(w.settings.SyncAllowance) * time.Second) - w.settingsMu.Lock() - w.settings.MinPowTolerance = val - w.settingsMu.Unlock() - }() - } - - return nil -} - -// MinPowTolerance returns the value of minimum PoW which is tolerated for a limited -// time after PoW was changed. If sufficient time have elapsed or no change of PoW -// have ever occurred, the return value will be the same as return value of MinPow(). -func (w *Waku) MinPowTolerance() float64 { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.MinPowTolerance -} - -// BloomFilter returns the aggregated bloom filter for all the topics of interest. -// The nodes are required to send only messages that match the advertised bloom filter. -// If a message does not match the bloom, it will tantamount to spam, and the peer will -// be disconnected. -func (w *Waku) BloomFilter() []byte { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.BloomFilter -} - -// BloomFilterTolerance returns the bloom filter which is tolerated for a limited -// time after new bloom was advertised to the peers. If sufficient time have elapsed -// or no change of bloom filter have ever occurred, the return value will be the same -// as return value of BloomFilter(). -func (w *Waku) BloomFilterTolerance() []byte { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.BloomFilterTolerance -} - -// SetBloomFilter sets the new bloom filter -func (w *Waku) SetBloomFilter(bloom []byte) error { - if len(bloom) != BloomFilterSize { - return fmt.Errorf("invalid bloom filter size: %d", len(bloom)) - } - - b := make([]byte, BloomFilterSize) - copy(b, bloom) - - w.settingsMu.Lock() - w.settings.BloomFilter = b - w.settingsMu.Unlock() - w.notifyPeersAboutBloomFilterChange(b) - - go func() { - // allow some time before all the peers have processed the notification - time.Sleep(time.Duration(w.settings.SyncAllowance) * time.Second) - w.settingsMu.Lock() - w.settings.BloomFilterTolerance = b - w.settingsMu.Unlock() - }() - - return nil -} - -// MaxMessageSize returns the maximum accepted message size. -func (w *Waku) MaxMessageSize() uint32 { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.MaxMsgSize -} - -// SetMaxMessageSize sets the maximal message size allowed by this node -func (w *Waku) SetMaxMessageSize(size uint32) error { - if size > MaxMessageSize { - return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) - } - w.settingsMu.Lock() - w.settings.MaxMsgSize = size - w.settingsMu.Unlock() - return nil -} - -// LightClientMode indicates is this node is light client (does not forward any messages) -func (w *Waku) LightClientMode() bool { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.LightClient -} - -// SetLightClientMode makes node light client (does not forward any messages) -func (w *Waku) SetLightClientMode(v bool) { - w.settingsMu.Lock() - w.settings.LightClient = v - w.settingsMu.Unlock() -} - -// LightClientModeConnectionRestricted indicates that connection to light client in light client mode not allowed -func (w *Waku) LightClientModeConnectionRestricted() bool { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.RestrictLightClientsConn -} - -// RateLimiting returns RateLimits information. -func (w *Waku) RateLimits() RateLimits { - if w.rateLimiter == nil { - return RateLimits{} - } - return RateLimits{ - IPLimits: uint64(w.rateLimiter.limitPerSecIP), - PeerIDLimits: uint64(w.rateLimiter.limitPerSecPeerID), - } -} - -// ConfirmationsEnabled returns true if message confirmations are enabled. -func (w *Waku) ConfirmationsEnabled() bool { - w.settingsMu.RLock() - defer w.settingsMu.RUnlock() - return w.settings.EnableConfirmations -} - -// CurrentTime returns current time. -func (w *Waku) CurrentTime() time.Time { - return w.timeSource() -} - -// SetTimeSource assigns a particular source of time to a waku object. -func (w *Waku) SetTimeSource(timesource func() time.Time) { - w.timeSource = timesource -} - -// APIs returns the RPC descriptors the Waku implementation offers -func (w *Waku) APIs() []rpc.API { - return []rpc.API{ - { - Namespace: ProtocolName, - Version: ProtocolVersionStr, - Service: NewPublicWakuAPI(w), - Public: true, - }, - } -} - -// Protocols returns the waku sub-protocols ran by this particular client. -func (w *Waku) Protocols() []p2p.Protocol { - return []p2p.Protocol{w.protocol} -} - -// RegisterMailServer registers MailServer interface. -// MailServer will process all the incoming messages with p2pRequestCode. -func (w *Waku) RegisterMailServer(server MailServer) { - w.mailServer = server -} - -// SetRateLimiter registers a rate limiter. -func (w *Waku) RegisterRateLimiter(r *PeerRateLimiter) { - w.rateLimiter = r -} - -// RegisterBridge registers a new Bridge that moves envelopes -// between different subprotocols. -// It's important that a bridge is registered before the service -// is started, otherwise, it won't read and propagate envelopes. -func (w *Waku) RegisterBridge(b Bridge) { - if w.cancelBridge != nil { - close(w.cancelBridge) - } - w.bridge = b - w.cancelBridge = make(chan struct{}) - w.bridgeWg.Add(1) - go w.readBridgeLoop() -} - -func (w *Waku) readBridgeLoop() { - defer w.bridgeWg.Done() - out, _ := w.bridge.Pipe() - for { - select { - case <-w.cancelBridge: - return - case env := <-out: - _, err := w.addAndBridge(env, false, true) - if err != nil { - w.logger.Warn( - "failed to add a bridged envelope", - zap.Binary("ID", env.Hash().Bytes()), - zap.Error(err), - ) - } else { - w.logger.Debug("bridged envelope successfully", zap.Binary("ID", env.Hash().Bytes())) - w.envelopeFeed.Send(EnvelopeEvent{ - Event: EventEnvelopeReceived, - Topic: env.Topic, - Hash: env.Hash(), - }) - } - } - } -} - -// SubscribeEnvelopeEvents subscribes to envelopes feed. -// In order to prevent blocking waku producers events must be amply buffered. -func (w *Waku) SubscribeEnvelopeEvents(events chan<- EnvelopeEvent) event.Subscription { - return w.envelopeFeed.Subscribe(events) -} - -func (w *Waku) notifyPeersAboutPowRequirementChange(pow float64) { - arr := w.getPeers() - for _, p := range arr { - err := p.notifyAboutPowRequirementChange(pow) - if err != nil { - // allow one retry - err = p.notifyAboutPowRequirementChange(pow) - } - if err != nil { - w.logger.Warn("failed to notify peer about new pow requirement", zap.Binary("peer", p.ID()), zap.Error(err)) - } - } -} - -func (w *Waku) notifyPeersAboutBloomFilterChange(bloom []byte) { - arr := w.getPeers() - for _, p := range arr { - err := p.notifyAboutBloomFilterChange(bloom) - if err != nil { - // allow one retry - err = p.notifyAboutBloomFilterChange(bloom) - } - if err != nil { - w.logger.Warn("failed to notify peer about new pow requirement", zap.Binary("peer", p.ID()), zap.Error(err)) - } - } -} - -func (w *Waku) getPeers() []*Peer { - arr := make([]*Peer, len(w.peers)) - i := 0 - w.peerMu.Lock() - for p := range w.peers { - arr[i] = p - i++ - } - w.peerMu.Unlock() - return arr -} - -// getPeer retrieves peer by ID -func (w *Waku) getPeer(peerID []byte) (*Peer, error) { - w.peerMu.Lock() - defer w.peerMu.Unlock() - for p := range w.peers { - id := p.peer.ID() - if bytes.Equal(peerID, id[:]) { - return p, nil - } - } - return nil, fmt.Errorf("could not find peer with ID: %x", peerID) -} - -// AllowP2PMessagesFromPeer marks specific peer trusted, -// which will allow it to send historic (expired) messages. -func (w *Waku) AllowP2PMessagesFromPeer(peerID []byte) error { - p, err := w.getPeer(peerID) - if err != nil { - return err - } - p.trusted = true - return nil -} - -// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer, -// which is known to implement MailServer interface, and is supposed to process this -// request and respond with a number of peer-to-peer messages (possibly expired), -// which are not supposed to be forwarded any further. -// The waku protocol is agnostic of the format and contents of envelope. -func (w *Waku) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { - return w.RequestHistoricMessagesWithTimeout(peerID, envelope, 0) -} - -// RequestHistoricMessagesWithTimeout acts as RequestHistoricMessages but requires to pass a timeout. -// It sends an event EventMailServerRequestExpired after the timeout. -func (w *Waku) RequestHistoricMessagesWithTimeout(peerID []byte, envelope *Envelope, timeout time.Duration) error { - p, err := w.getPeer(peerID) - if err != nil { - return err - } - p.trusted = true - - w.envelopeFeed.Send(EnvelopeEvent{ - Peer: p.peer.ID(), - Topic: envelope.Topic, - Hash: envelope.Hash(), - Event: EventMailServerRequestSent, - }) - - err = p2p.Send(p.ws, p2pRequestCode, envelope) - if timeout != 0 { - go w.expireRequestHistoricMessages(p.peer.ID(), envelope.Hash(), timeout) - } - return err -} - -func (w *Waku) SendMessagesRequest(peerID []byte, request MessagesRequest) error { - if err := request.Validate(); err != nil { - return err - } - p, err := w.getPeer(peerID) - if err != nil { - return err - } - p.trusted = true - if err := p2p.Send(p.ws, p2pRequestCode, request); err != nil { - return err - } - w.envelopeFeed.Send(EnvelopeEvent{ - Peer: p.peer.ID(), - Hash: common.BytesToHash(request.ID), - Event: EventMailServerRequestSent, - }) - return nil -} - -func (w *Waku) expireRequestHistoricMessages(peer enode.ID, hash common.Hash, timeout time.Duration) { - timer := time.NewTimer(timeout) - defer timer.Stop() - select { - case <-w.quit: - return - case <-timer.C: - w.envelopeFeed.Send(EnvelopeEvent{ - Peer: peer, - Hash: hash, - Event: EventMailServerRequestExpired, - }) - } -} - -func (w *Waku) SendHistoricMessageResponse(peerID []byte, payload []byte) error { - size, r, err := rlp.EncodeToReader(payload) - if err != nil { - 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}) -} - -// SendP2PMessage sends a peer-to-peer message to a specific peer. -// It sends one or more envelopes in a single batch. -func (w *Waku) SendP2PMessages(peerID []byte, envelopes ...*Envelope) error { - p, err := w.getPeer(peerID) - if err != nil { - return err - } - return p2p.Send(p.ws, p2pMessageCode, envelopes) -} - -// SendP2PDirect sends a peer-to-peer message to a specific peer. -// It sends one or more envelopes in a single batch. -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) -} - -// SendRawP2PDirect sends a peer-to-peer message to a specific peer. -// It sends one or more envelopes in a single batch. -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) -} - -// NewKeyPair generates a new cryptographic identity for the client, and injects -// it into the known identities for message decryption. Returns ID of the new key pair. -func (w *Waku) NewKeyPair() (string, error) { - key, err := crypto.GenerateKey() - if err != nil || !validatePrivateKey(key) { - key, err = crypto.GenerateKey() // retry once - } - if err != nil { - return "", err - } - if !validatePrivateKey(key) { - return "", fmt.Errorf("failed to generate valid key") - } - - id, err := toDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize) - if err != nil { - return "", err - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - if w.privateKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - w.privateKeys[id] = key - return id, nil -} - -// DeleteKeyPair deletes the specified key if it exists. -func (w *Waku) DeleteKeyPair(key string) bool { - deterministicID, err := toDeterministicID(key, keyIDSize) - if err != nil { - return false - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - if w.privateKeys[deterministicID] != nil { - delete(w.privateKeys, deterministicID) - return true - } - return false -} - -// AddKeyPair imports a asymmetric private key and returns it identifier. -func (w *Waku) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { - id, err := makeDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize) - if err != nil { - return "", err - } - if w.HasKeyPair(id) { - return id, nil // no need to re-inject - } - - w.keyMu.Lock() - w.privateKeys[id] = key - w.keyMu.Unlock() - - return id, nil -} - -// SelectKeyPair adds cryptographic identity, and makes sure -// that it is the only private key known to the node. -func (w *Waku) SelectKeyPair(key *ecdsa.PrivateKey) error { - id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize) - if err != nil { - return err - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - w.privateKeys = make(map[string]*ecdsa.PrivateKey) // reset key store - w.privateKeys[id] = key - - return nil -} - -// DeleteKeyPairs removes all cryptographic identities known to the node -func (w *Waku) DeleteKeyPairs() error { - w.keyMu.Lock() - defer w.keyMu.Unlock() - - w.privateKeys = make(map[string]*ecdsa.PrivateKey) - - return nil -} - -// HasKeyPair checks if the waku node is configured with the private key -// of the specified public pair. -func (w *Waku) HasKeyPair(id string) bool { - deterministicID, err := toDeterministicID(id, keyIDSize) - if err != nil { - return false - } - - w.keyMu.RLock() - defer w.keyMu.RUnlock() - return w.privateKeys[deterministicID] != nil -} - -// GetPrivateKey retrieves the private key of the specified identity. -func (w *Waku) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { - deterministicID, err := toDeterministicID(id, keyIDSize) - if err != nil { - return nil, err - } - - w.keyMu.RLock() - defer w.keyMu.RUnlock() - key := w.privateKeys[deterministicID] - if key == nil { - return nil, fmt.Errorf("invalid id") - } - return key, nil -} - -// GenerateSymKey generates a random symmetric key and stores it under id, -// which is then returned. Will be used in the future for session key exchange. -func (w *Waku) GenerateSymKey() (string, error) { - key, err := generateSecureRandomData(aesKeyLength) - if err != nil { - return "", err - } else if !validateDataIntegrity(key, aesKeyLength) { - return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") - } - - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - if w.symKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - w.symKeys[id] = key - return id, nil -} - -// AddSymKey stores the key with a given id. -func (w *Waku) AddSymKey(id string, key []byte) (string, error) { - deterministicID, err := toDeterministicID(id, keyIDSize) - if err != nil { - return "", err - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - if w.symKeys[deterministicID] != nil { - return "", fmt.Errorf("key already exists: %v", id) - } - w.symKeys[deterministicID] = key - return deterministicID, nil -} - -// AddSymKeyDirect stores the key, and returns its id. -func (w *Waku) AddSymKeyDirect(key []byte) (string, error) { - if len(key) != aesKeyLength { - return "", fmt.Errorf("wrong key size: %d", len(key)) - } - - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - if w.symKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - w.symKeys[id] = key - return id, nil -} - -// AddSymKeyFromPassword generates the key from password, stores it, and returns its id. -func (w *Waku) AddSymKeyFromPassword(password string) (string, error) { - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - if w.HasSymKey(id) { - return "", fmt.Errorf("failed to generate unique ID") - } - - // kdf should run no less than 0.1 seconds on an average computer, - // because it's an once in a session experience - derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New) - if err != nil { - return "", err - } - - w.keyMu.Lock() - defer w.keyMu.Unlock() - - // double check is necessary, because deriveKeyMaterial() is very slow - if w.symKeys[id] != nil { - return "", fmt.Errorf("critical error: failed to generate unique ID") - } - w.symKeys[id] = derived - return id, nil -} - -// HasSymKey returns true if there is a key associated with the given id. -// Otherwise returns false. -func (w *Waku) HasSymKey(id string) bool { - w.keyMu.RLock() - defer w.keyMu.RUnlock() - return w.symKeys[id] != nil -} - -// DeleteSymKey deletes the key associated with the name string if it exists. -func (w *Waku) DeleteSymKey(id string) bool { - w.keyMu.Lock() - defer w.keyMu.Unlock() - if w.symKeys[id] != nil { - delete(w.symKeys, id) - return true - } - return false -} - -// GetSymKey returns the symmetric key associated with the given id. -func (w *Waku) GetSymKey(id string) ([]byte, error) { - w.keyMu.RLock() - defer w.keyMu.RUnlock() - if w.symKeys[id] != nil { - return w.symKeys[id], nil - } - return nil, fmt.Errorf("non-existent key ID") -} - -// Subscribe installs a new message handler used for filtering, decrypting -// and subsequent storing of incoming messages. -func (w *Waku) Subscribe(f *Filter) (string, error) { - s, err := w.filters.Install(f) - if err == nil { - w.updateBloomFilter(f) - } - return s, err -} - -// updateBloomFilter recalculates the new value of bloom filter, -// and informs the peers if necessary. -func (w *Waku) updateBloomFilter(f *Filter) { - aggregate := make([]byte, BloomFilterSize) - for _, t := range f.Topics { - top := BytesToTopic(t) - b := TopicToBloom(top) - aggregate = addBloom(aggregate, b) - } - - if !BloomFilterMatch(w.BloomFilter(), aggregate) { - // existing bloom filter must be updated - aggregate = addBloom(w.BloomFilter(), aggregate) - w.SetBloomFilter(aggregate) - } -} - -// GetFilter returns the filter by id. -func (w *Waku) GetFilter(id string) *Filter { - return w.filters.Get(id) -} - -// Unsubscribe removes an installed message handler. -func (w *Waku) Unsubscribe(id string) error { - ok := w.filters.Uninstall(id) - if !ok { - return fmt.Errorf("Unsubscribe: Invalid ID") - } - return nil -} - -// Send injects a message into the waku send queue, to be distributed in the -// network in the coming cycles. -func (w *Waku) Send(envelope *Envelope) error { - ok, err := w.add(envelope, false) - if err == nil && !ok { - return fmt.Errorf("failed to add envelope") - } - return err -} - -// Start implements node.Service, starting the background data propagation thread -// of the Waku protocol. -func (w *Waku) Start(*p2p.Server) error { - go w.update() - - numCPU := runtime.NumCPU() - for i := 0; i < numCPU; i++ { - go w.processQueue() - } - go w.processP2P() - - return nil -} - -// Stop implements node.Service, stopping the background data propagation thread -// of the Waku protocol. -func (w *Waku) Stop() error { - if w.cancelBridge != nil { - close(w.cancelBridge) - w.cancelBridge = nil - w.bridgeWg.Wait() - } - close(w.quit) - return nil -} - -// HandlePeer is called by the underlying P2P layer when the waku sub-protocol -// connection is negotiated. -func (w *Waku) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { - // Create the new peer and start tracking it - wakuPeer := newPeer(w, peer, rw, w.logger.Named("waku/peer")) - - w.peerMu.Lock() - w.peers[wakuPeer] = struct{}{} - w.peerMu.Unlock() - - defer func() { - w.peerMu.Lock() - delete(w.peers, wakuPeer) - w.peerMu.Unlock() - }() - - // Run the peer handshake and state updates - if err := wakuPeer.handshake(); err != nil { - return err - } - wakuPeer.start() - defer wakuPeer.stop() - - if w.rateLimiter != nil { - return w.rateLimiter.decorate(wakuPeer, rw, w.runMessageLoop) - } - return w.runMessageLoop(wakuPeer, rw) -} - -// sendConfirmation sends messageResponseCode and batchAcknowledgedCode messages. -func (w *Waku) sendConfirmation(rw p2p.MsgReadWriter, data []byte, envelopeErrors []EnvelopeError) (err error) { - batchHash := crypto.Keccak256Hash(data) - err = p2p.Send(rw, messageResponseCode, NewMessagesResponse(batchHash, envelopeErrors)) - err = p2p.Send(rw, batchAcknowledgedCode, batchHash) // DEPRECATED - return -} - -// runMessageLoop reads and processes inbound messages directly to merge into client-global state. -func (w *Waku) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { - logger := w.logger.Named("runMessageLoop") - peerID := p.peer.ID() - - for { - // fetch the next packet - packet, err := rw.ReadMsg() - if err != nil { - logger.Info("failed to read a message", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - - if packet.Size > w.MaxMessageSize() { - logger.Warn("oversize message received", zap.Binary("peer", peerID[:]), zap.Uint32("size", packet.Size)) - return errors.New("oversize message received") - } - - switch packet.Code { - case messagesCode: - if err := w.handleMessagesCode(p, rw, packet, logger); err != nil { - logger.Warn("failed to handle messagesCode message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case messageResponseCode: - if err := w.handleMessageResponseCode(p, packet, logger); err != nil { - logger.Warn("failed to handle messageResponseCode message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case batchAcknowledgedCode: - if err := w.handleBatchAcknowledgeCode(p, packet, logger); err != nil { - - } - case powRequirementCode: - if err := w.handlePowRequirementCode(p, packet, logger); err != nil { - logger.Warn("failed to handle powRequirementCode message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case bloomFilterExCode: - if err := w.handleBloomFilterExCode(p, packet, logger); err != nil { - logger.Warn("failed to decode bloom filter exchange message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case p2pMessageCode: - if err := w.handleP2PMessageCode(p, packet, logger); err != nil { - logger.Warn("failed to decode direct message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case p2pRequestCode: - if err := w.handleP2PRequestCode(p, packet, logger); err != nil { - logger.Warn("failed to decode p2p request message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case p2pRequestCompleteCode: - if err := w.handleP2PRequestCompleteCode(p, packet, logger); err != nil { - logger.Warn("failed to decode p2p request complete message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - default: - // New message types might be implemented in the future versions of Waku. - // For forward compatibility, just ignore. - logger.Debug("ignored packet with message code", zap.Uint64("code", packet.Code)) - } - - _ = packet.Discard() - } -} - -func (w *Waku) handleMessagesCode(p *Peer, rw p2p.MsgReadWriter, packet p2p.Msg, logger *zap.Logger) error { - peerID := p.peer.ID() - - // decode the contained envelopes - data, err := ioutil.ReadAll(packet.Payload) - if err != nil { - envelopesRejectedCounter.WithLabelValues("failed_read").Inc() - return fmt.Errorf("failed to read packet payload: %w", err) - } - - var envelopes []*Envelope - if err := rlp.DecodeBytes(data, &envelopes); err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_data").Inc() - return fmt.Errorf("invalid payload: %w", err) - } - - envelopeErrors := make([]EnvelopeError, 0) - trouble := false - for _, env := range envelopes { - cached, err := w.add(env, w.LightClientMode()) - if err != nil { - _, isTimeSyncError := err.(TimeSyncError) - if !isTimeSyncError { - trouble = true - logger.Info("invalid envelope received", zap.Binary("peer", peerID[:]), zap.Error(err)) - } - envelopeErrors = append(envelopeErrors, ErrorToEnvelopeError(env.Hash(), err)) - } else if cached { - p.mark(env) - } - - w.envelopeFeed.Send(EnvelopeEvent{ - Event: EventEnvelopeReceived, - Topic: env.Topic, - Hash: env.Hash(), - Peer: p.peer.ID(), - }) - envelopesValidatedCounter.Inc() - } - - if w.ConfirmationsEnabled() { - go w.sendConfirmation(rw, data, envelopeErrors) - } - - if trouble { - return errors.New("received invalid envelope") - } - return nil -} - -func (w *Waku) handlePowRequirementCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - s := rlp.NewStream(packet.Payload, uint64(packet.Size)) - i, err := s.Uint() - if err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_pow_req").Inc() - return fmt.Errorf("invalid powRequirementCode message: %w", err) - } - f := math.Float64frombits(i) - if math.IsInf(f, 0) || math.IsNaN(f) || f < 0.0 { - envelopesRejectedCounter.WithLabelValues("invalid_pow_req").Inc() - return errors.New("invalid value in powRequirementCode message") - } - p.powRequirement = f - return nil -} - -func (w *Waku) handleBloomFilterExCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - var bloom []byte - err := packet.Decode(&bloom) - if err == nil && len(bloom) != BloomFilterSize { - err = fmt.Errorf("wrong bloom filter size %d", len(bloom)) - } - if err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_bloom").Inc() - return errors.New("invalid bloom filter exchange message") - } - - p.setBloomFilter(bloom) - return nil -} - -func (w *Waku) handleP2PMessageCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. - // this message is not supposed to be forwarded to other peers, and - // therefore might not satisfy the PoW, expiry and other requirements. - // these messages are only accepted from the trusted peer. - if !p.trusted { - return nil - } - - var ( - envelopes []*Envelope - err error - ) - - if err = packet.Decode(&envelopes); err != nil { - return fmt.Errorf("invalid direct message payload: %w", err) - } - - for _, envelope := range envelopes { - w.postP2P(envelope) - } - return nil -} - -func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - peerID := p.peer.ID() - - // Must be processed if mail server is implemented. Otherwise ignore. - if w.mailServer == nil { - return nil - } - - // Read all data as we will try to decode it possibly twice. - data, err := ioutil.ReadAll(packet.Payload) - if err != nil { - return fmt.Errorf("invalid p2p request messages: %w", err) - } - r := bytes.NewReader(data) - packet.Payload = r - - var requestDeprecated Envelope - errDepReq := packet.Decode(&requestDeprecated) - if errDepReq == nil { - w.mailServer.DeliverMail(p.ID(), &requestDeprecated) - return nil - } else { - logger.Info("failed to decode p2p request message (deprecated)", zap.Binary("peer", peerID[:]), zap.Error(errDepReq)) - } - - // As we failed to decode the request, let's set the offset - // to the beginning and try decode it again. - if _, err := r.Seek(0, io.SeekStart); err != nil { - return fmt.Errorf("invalid p2p request message: %w", err) - } - - var request MessagesRequest - errReq := packet.Decode(&request) - if errReq == nil { - w.mailServer.Deliver(p.ID(), request) - return nil - } else { - logger.Info("failed to decode p2p request message", zap.Binary("peer", peerID[:]), zap.Error(errDepReq)) - } - - return errors.New("invalid p2p request message") -} - -func (w *Waku) handleP2PRequestCompleteCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - if !p.trusted { - return nil - } - - var payload []byte - if err := packet.Decode(&payload); err != nil { - return fmt.Errorf("invalid p2p request complete message: %w", err) - } - - event, err := CreateMailServerEvent(p.peer.ID(), payload) - if err != nil { - return fmt.Errorf("invalid p2p request complete payload: %w", err) - } - - w.postP2P(*event) - return nil -} - -func (w *Waku) handleMessageResponseCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - var resp MultiVersionResponse - if err := packet.Decode(&resp); err != nil { - envelopesRejectedCounter.WithLabelValues("failed_read").Inc() - return fmt.Errorf("invalid response message: %w", err) - } - if resp.Version != 1 { - logger.Info("received unsupported version of MultiVersionResponse for messageResponseCode packet", zap.Uint("version", resp.Version)) - return nil - } - - response, err := resp.DecodeResponse1() - if err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_data").Inc() - return fmt.Errorf("failed to decode response message: %w", err) - } - - w.envelopeFeed.Send(EnvelopeEvent{ - Batch: response.Hash, - Event: EventBatchAcknowledged, - Peer: p.peer.ID(), - Data: response.Errors, - }) - - return nil -} - -func (w *Waku) handleBatchAcknowledgeCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - var batchHash common.Hash - if err := packet.Decode(&batchHash); err != nil { - return fmt.Errorf("invalid batch ack message: %w", err) - } - w.envelopeFeed.Send(EnvelopeEvent{ - Batch: batchHash, - Event: EventBatchAcknowledged, - Peer: p.peer.ID(), - }) - return nil -} - -func (w *Waku) add(envelope *Envelope, isP2P bool) (bool, error) { - return w.addAndBridge(envelope, isP2P, false) -} - -// addAndBridge inserts a new envelope into the message pool to be distributed within the -// waku network. It also inserts the envelope into the expiration pool at the -// appropriate time-stamp. In case of error, connection should be dropped. -// param isP2P indicates whether the message is peer-to-peer (should not be forwarded). -func (w *Waku) addAndBridge(envelope *Envelope, isP2P bool, bridged bool) (bool, error) { - now := uint32(w.timeSource().Unix()) - sent := envelope.Expiry - envelope.TTL - - envelopesReceivedCounter.Inc() - if sent > now { - if sent-DefaultSyncAllowance > now { - envelopesCacheFailedCounter.WithLabelValues("in_future").Inc() - log.Warn("envelope created in the future", "hash", envelope.Hash()) - return false, TimeSyncError(errors.New("envelope from future")) - } - // recalculate PoW, adjusted for the time difference, plus one second for latency - envelope.calculatePoW(sent - now + 1) - } - - if envelope.Expiry < now { - if envelope.Expiry+DefaultSyncAllowance*2 < now { - envelopesCacheFailedCounter.WithLabelValues("very_old").Inc() - log.Warn("very old envelope", "hash", envelope.Hash()) - return false, TimeSyncError(errors.New("very old envelope")) - } - log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) - envelopesCacheFailedCounter.WithLabelValues("expired").Inc() - return false, nil // drop envelope without error - } - - if uint32(envelope.size()) > w.MaxMessageSize() { - envelopesCacheFailedCounter.WithLabelValues("oversized").Inc() - return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) - } - - if envelope.PoW() < w.MinPow() { - // maybe the value was recently changed, and the peers did not adjust yet. - // in this case the previous value is retrieved by MinPowTolerance() - // for a short period of peer synchronization. - if envelope.PoW() < w.MinPowTolerance() { - envelopesCacheFailedCounter.WithLabelValues("low_pow").Inc() - return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%v]", envelope.PoW(), envelope.Hash().Hex()) - } - } - - if !BloomFilterMatch(w.BloomFilter(), envelope.Bloom()) { - // maybe the value was recently changed, and the peers did not adjust yet. - // in this case the previous value is retrieved by BloomFilterTolerance() - // for a short period of peer synchronization. - if !BloomFilterMatch(w.BloomFilterTolerance(), envelope.Bloom()) { - envelopesCacheFailedCounter.WithLabelValues("no_bloom_match").Inc() - return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", - envelope.Hash().Hex(), w.BloomFilter(), envelope.Bloom(), envelope.Topic) - } - } - - hash := envelope.Hash() - - w.poolMu.Lock() - _, alreadyCached := w.envelopes[hash] - if !alreadyCached { - w.envelopes[hash] = envelope - if w.expirations[envelope.Expiry] == nil { - w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() - } - if !w.expirations[envelope.Expiry].Contains(hash) { - w.expirations[envelope.Expiry].Add(hash) - } - } - w.poolMu.Unlock() - - if alreadyCached { - log.Trace("w envelope already cached", "hash", envelope.Hash().Hex()) - envelopesCachedCounter.WithLabelValues("hit").Inc() - } else { - log.Trace("cached w envelope", "hash", envelope.Hash().Hex()) - envelopesCachedCounter.WithLabelValues("miss").Inc() - envelopesSizeMeter.Observe(float64(envelope.size())) - w.postEvent(envelope, isP2P) // notify the local node about the new message - if w.mailServer != nil { - w.mailServer.Archive(envelope) - w.envelopeFeed.Send(EnvelopeEvent{ - Topic: envelope.Topic, - Hash: envelope.Hash(), - Event: EventMailServerEnvelopeArchived, - }) - } - // Bridge only envelopes that are not p2p messages. - // In particular, if a node is a lightweight node, - // it should not bridge any envelopes. - if !isP2P && !bridged && w.bridge != nil { - _, in := w.bridge.Pipe() - in <- envelope - } - } - return true, nil -} - -func (w *Waku) postP2P(event interface{}) { - w.p2pMsgQueue <- event -} - -// postEvent queues the message for further processing. -func (w *Waku) postEvent(envelope *Envelope, isP2P bool) { - if isP2P { - w.postP2P(envelope) - } else { - w.msgQueue <- envelope - } -} - -// processQueue delivers the messages to the watchers during the lifetime of the waku node. -func (w *Waku) processQueue() { - for { - select { - case <-w.quit: - return - case e := <-w.msgQueue: - w.filters.NotifyWatchers(e, false) - w.envelopeFeed.Send(EnvelopeEvent{ - Topic: e.Topic, - Hash: e.Hash(), - Event: EventEnvelopeAvailable, - }) - } - } -} - -func (w *Waku) processP2P() { - for { - select { - case <-w.quit: - return - case e := <-w.p2pMsgQueue: - switch event := e.(type) { - case *Envelope: - w.filters.NotifyWatchers(event, true) - w.envelopeFeed.Send(EnvelopeEvent{ - Topic: event.Topic, - Hash: event.Hash(), - Event: EventEnvelopeAvailable, - }) - case EnvelopeEvent: - w.envelopeFeed.Send(event) - } - } - } -} - -// update loops until the lifetime of the waku node, updating its internal -// state by expiring stale messages from the pool. -func (w *Waku) update() { - // Start a ticker to check for expirations - expire := time.NewTicker(expirationCycle) - - // Repeat updates until termination is requested - for { - select { - case <-expire.C: - w.expire() - - case <-w.quit: - return - } - } -} - -// expire iterates over all the expiration timestamps, removing all stale -// messages from the pools. -func (w *Waku) expire() { - w.poolMu.Lock() - defer w.poolMu.Unlock() - - now := uint32(w.timeSource().Unix()) - for expiry, hashSet := range w.expirations { - if expiry < now { - // Dump all expired messages and remove timestamp - hashSet.Each(func(v interface{}) bool { - delete(w.envelopes, v.(common.Hash)) - envelopesCachedCounter.WithLabelValues("clear").Inc() - w.envelopeFeed.Send(EnvelopeEvent{ - Hash: v.(common.Hash), - Event: EventEnvelopeExpired, - }) - return false - }) - w.expirations[expiry].Clear() - delete(w.expirations, expiry) - } - } -} - -// Envelopes retrieves all the messages currently pooled by the node. -func (w *Waku) Envelopes() []*Envelope { - w.poolMu.RLock() - defer w.poolMu.RUnlock() - - all := make([]*Envelope, 0, len(w.envelopes)) - for _, envelope := range w.envelopes { - all = append(all, envelope) - } - return all -} - -// GetEnvelope retrieves an envelope from the message queue by its hash. -// It returns nil if the envelope can not be found. -func (w *Waku) GetEnvelope(hash common.Hash) *Envelope { - w.poolMu.RLock() - defer w.poolMu.RUnlock() - return w.envelopes[hash] -} - -// isEnvelopeCached checks if envelope with specific hash has already been received and cached. -func (w *Waku) isEnvelopeCached(hash common.Hash) bool { - w.poolMu.Lock() - defer w.poolMu.Unlock() - - _, exist := w.envelopes[hash] - return exist -} - -// ValidatePublicKey checks the format of the given public key. -func ValidatePublicKey(k *ecdsa.PublicKey) bool { - return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 -} - -// validatePrivateKey checks the format of the given private key. -func validatePrivateKey(k *ecdsa.PrivateKey) bool { - if k == nil || k.D == nil || k.D.Sign() == 0 { - return false - } - return ValidatePublicKey(&k.PublicKey) -} - -// validateDataIntegrity returns false if the data have the wrong or contains all zeros, -// which is the simplest and the most common bug. -func validateDataIntegrity(k []byte, expectedSize int) bool { - if len(k) != expectedSize { - return false - } - if expectedSize > 3 && containsOnlyZeros(k) { - return false - } - return true -} - -// containsOnlyZeros checks if the data contain only zeros. -func containsOnlyZeros(data []byte) bool { - for _, b := range data { - if b != 0 { - return false - } - } - return true -} - -// bytesToUintLittleEndian converts the slice to 64-bit unsigned integer. -func bytesToUintLittleEndian(b []byte) (res uint64) { - mul := uint64(1) - for i := 0; i < len(b); i++ { - res += uint64(b[i]) * mul - mul *= 256 - } - return res -} - -// BytesToUintBigEndian converts the slice to 64-bit unsigned integer. -func BytesToUintBigEndian(b []byte) (res uint64) { - for i := 0; i < len(b); i++ { - res *= 256 - res += uint64(b[i]) - } - return res -} - -// GenerateRandomID generates a random string, which is then returned to be used as a key id -func GenerateRandomID() (id string, err error) { - buf, err := generateSecureRandomData(keyIDSize) - if err != nil { - return "", err - } - if !validateDataIntegrity(buf, keyIDSize) { - return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") - } - id = common.Bytes2Hex(buf) - return id, err -} - -// makeDeterministicID generates a deterministic ID, based on a given input -func makeDeterministicID(input string, keyLen int) (id string, err error) { - buf := pbkdf2.Key([]byte(input), nil, 4096, keyLen, sha256.New) - if !validateDataIntegrity(buf, keyIDSize) { - return "", fmt.Errorf("error in GenerateDeterministicID: failed to generate key") - } - id = common.Bytes2Hex(buf) - return id, err -} - -// toDeterministicID reviews incoming id, and transforms it to format -// expected internally be private key store. Originally, public keys -// were used as keys, now random keys are being used. And in order to -// make it easier to consume, we now allow both random IDs and public -// keys to be passed. -func toDeterministicID(id string, expectedLen int) (string, error) { - if len(id) != (expectedLen * 2) { // we received hex key, so number of chars in id is doubled - var err error - id, err = makeDeterministicID(id, expectedLen) - if err != nil { - return "", err - } - } - - return id, nil -} - -func isFullNode(bloom []byte) bool { - if bloom == nil { - return true - } - for _, b := range bloom { - if b != 255 { - return false - } - } - return true -} - -func BloomFilterMatch(filter, sample []byte) bool { - if filter == nil { - return true - } - - for i := 0; i < BloomFilterSize; i++ { - f := filter[i] - s := sample[i] - if (f | s) != f { - return false - } - } - - return true -} - -func addBloom(a, b []byte) []byte { - c := make([]byte, BloomFilterSize) - for i := 0; i < BloomFilterSize; i++ { - c[i] = a[i] | b[i] - } - return c -} diff --git a/vendor/golang.org/x/sync/syncmap/go19.go b/vendor/golang.org/x/sync/syncmap/go19.go deleted file mode 100644 index 41a59091e..000000000 --- a/vendor/golang.org/x/sync/syncmap/go19.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 - -package syncmap - -import "sync" // home to the standard library's sync.map implementation as of Go 1.9 - -// Map is a concurrent map with amortized-constant-time loads, stores, and deletes. -// It is safe for multiple goroutines to call a Map's methods concurrently. -// -// The zero Map is valid and empty. -// -// A Map must not be copied after first use. -type Map = sync.Map diff --git a/vendor/golang.org/x/sync/syncmap/map.go b/vendor/golang.org/x/sync/syncmap/map.go index 4b638cb7a..80e15847e 100644 --- a/vendor/golang.org/x/sync/syncmap/map.go +++ b/vendor/golang.org/x/sync/syncmap/map.go @@ -1,8 +1,372 @@ -// Copyright 2019 The Go Authors. All rights reserved. +// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package syncmap provides a concurrent map implementation. -// This was the prototype for sync.Map which was added to the standard library's -// sync package in Go 1.9. https://golang.org/pkg/sync/#Map. +// It is a prototype for a proposed addition to the sync package +// in the standard library. +// (https://golang.org/issue/18177) package syncmap + +import ( + "sync" + "sync/atomic" + "unsafe" +) + +// Map is a concurrent map with amortized-constant-time loads, stores, and deletes. +// It is safe for multiple goroutines to call a Map's methods concurrently. +// +// The zero Map is valid and empty. +// +// A Map must not be copied after first use. +type Map struct { + mu sync.Mutex + + // read contains the portion of the map's contents that are safe for + // concurrent access (with or without mu held). + // + // The read field itself is always safe to load, but must only be stored with + // mu held. + // + // Entries stored in read may be updated concurrently without mu, but updating + // a previously-expunged entry requires that the entry be copied to the dirty + // map and unexpunged with mu held. + read atomic.Value // readOnly + + // dirty contains the portion of the map's contents that require mu to be + // held. To ensure that the dirty map can be promoted to the read map quickly, + // it also includes all of the non-expunged entries in the read map. + // + // Expunged entries are not stored in the dirty map. An expunged entry in the + // clean map must be unexpunged and added to the dirty map before a new value + // can be stored to it. + // + // If the dirty map is nil, the next write to the map will initialize it by + // making a shallow copy of the clean map, omitting stale entries. + dirty map[interface{}]*entry + + // misses counts the number of loads since the read map was last updated that + // needed to lock mu to determine whether the key was present. + // + // Once enough misses have occurred to cover the cost of copying the dirty + // map, the dirty map will be promoted to the read map (in the unamended + // state) and the next store to the map will make a new dirty copy. + misses int +} + +// readOnly is an immutable struct stored atomically in the Map.read field. +type readOnly struct { + m map[interface{}]*entry + amended bool // true if the dirty map contains some key not in m. +} + +// expunged is an arbitrary pointer that marks entries which have been deleted +// from the dirty map. +var expunged = unsafe.Pointer(new(interface{})) + +// An entry is a slot in the map corresponding to a particular key. +type entry struct { + // p points to the interface{} value stored for the entry. + // + // If p == nil, the entry has been deleted and m.dirty == nil. + // + // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry + // is missing from m.dirty. + // + // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty + // != nil, in m.dirty[key]. + // + // An entry can be deleted by atomic replacement with nil: when m.dirty is + // next created, it will atomically replace nil with expunged and leave + // m.dirty[key] unset. + // + // An entry's associated value can be updated by atomic replacement, provided + // p != expunged. If p == expunged, an entry's associated value can be updated + // only after first setting m.dirty[key] = e so that lookups using the dirty + // map find the entry. + p unsafe.Pointer // *interface{} +} + +func newEntry(i interface{}) *entry { + return &entry{p: unsafe.Pointer(&i)} +} + +// Load returns the value stored in the map for a key, or nil if no +// value is present. +// The ok result indicates whether value was found in the map. +func (m *Map) Load(key interface{}) (value interface{}, ok bool) { + read, _ := m.read.Load().(readOnly) + e, ok := read.m[key] + if !ok && read.amended { + m.mu.Lock() + // Avoid reporting a spurious miss if m.dirty got promoted while we were + // blocked on m.mu. (If further loads of the same key will not miss, it's + // not worth copying the dirty map for this key.) + read, _ = m.read.Load().(readOnly) + e, ok = read.m[key] + if !ok && read.amended { + e, ok = m.dirty[key] + // Regardless of whether the entry was present, record a miss: this key + // will take the slow path until the dirty map is promoted to the read + // map. + m.missLocked() + } + m.mu.Unlock() + } + if !ok { + return nil, false + } + return e.load() +} + +func (e *entry) load() (value interface{}, ok bool) { + p := atomic.LoadPointer(&e.p) + if p == nil || p == expunged { + return nil, false + } + return *(*interface{})(p), true +} + +// Store sets the value for a key. +func (m *Map) Store(key, value interface{}) { + read, _ := m.read.Load().(readOnly) + if e, ok := read.m[key]; ok && e.tryStore(&value) { + return + } + + m.mu.Lock() + read, _ = m.read.Load().(readOnly) + if e, ok := read.m[key]; ok { + if e.unexpungeLocked() { + // The entry was previously expunged, which implies that there is a + // non-nil dirty map and this entry is not in it. + m.dirty[key] = e + } + e.storeLocked(&value) + } else if e, ok := m.dirty[key]; ok { + e.storeLocked(&value) + } else { + if !read.amended { + // We're adding the first new key to the dirty map. + // Make sure it is allocated and mark the read-only map as incomplete. + m.dirtyLocked() + m.read.Store(readOnly{m: read.m, amended: true}) + } + m.dirty[key] = newEntry(value) + } + m.mu.Unlock() +} + +// tryStore stores a value if the entry has not been expunged. +// +// If the entry is expunged, tryStore returns false and leaves the entry +// unchanged. +func (e *entry) tryStore(i *interface{}) bool { + p := atomic.LoadPointer(&e.p) + if p == expunged { + return false + } + for { + if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) { + return true + } + p = atomic.LoadPointer(&e.p) + if p == expunged { + return false + } + } +} + +// unexpungeLocked ensures that the entry is not marked as expunged. +// +// If the entry was previously expunged, it must be added to the dirty map +// before m.mu is unlocked. +func (e *entry) unexpungeLocked() (wasExpunged bool) { + return atomic.CompareAndSwapPointer(&e.p, expunged, nil) +} + +// storeLocked unconditionally stores a value to the entry. +// +// The entry must be known not to be expunged. +func (e *entry) storeLocked(i *interface{}) { + atomic.StorePointer(&e.p, unsafe.Pointer(i)) +} + +// LoadOrStore returns the existing value for the key if present. +// Otherwise, it stores and returns the given value. +// The loaded result is true if the value was loaded, false if stored. +func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { + // Avoid locking if it's a clean hit. + read, _ := m.read.Load().(readOnly) + if e, ok := read.m[key]; ok { + actual, loaded, ok := e.tryLoadOrStore(value) + if ok { + return actual, loaded + } + } + + m.mu.Lock() + read, _ = m.read.Load().(readOnly) + if e, ok := read.m[key]; ok { + if e.unexpungeLocked() { + m.dirty[key] = e + } + actual, loaded, _ = e.tryLoadOrStore(value) + } else if e, ok := m.dirty[key]; ok { + actual, loaded, _ = e.tryLoadOrStore(value) + m.missLocked() + } else { + if !read.amended { + // We're adding the first new key to the dirty map. + // Make sure it is allocated and mark the read-only map as incomplete. + m.dirtyLocked() + m.read.Store(readOnly{m: read.m, amended: true}) + } + m.dirty[key] = newEntry(value) + actual, loaded = value, false + } + m.mu.Unlock() + + return actual, loaded +} + +// tryLoadOrStore atomically loads or stores a value if the entry is not +// expunged. +// +// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and +// returns with ok==false. +func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bool) { + p := atomic.LoadPointer(&e.p) + if p == expunged { + return nil, false, false + } + if p != nil { + return *(*interface{})(p), true, true + } + + // Copy the interface after the first load to make this method more amenable + // to escape analysis: if we hit the "load" path or the entry is expunged, we + // shouldn't bother heap-allocating. + ic := i + for { + if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) { + return i, false, true + } + p = atomic.LoadPointer(&e.p) + if p == expunged { + return nil, false, false + } + if p != nil { + return *(*interface{})(p), true, true + } + } +} + +// Delete deletes the value for a key. +func (m *Map) Delete(key interface{}) { + read, _ := m.read.Load().(readOnly) + e, ok := read.m[key] + if !ok && read.amended { + m.mu.Lock() + read, _ = m.read.Load().(readOnly) + e, ok = read.m[key] + if !ok && read.amended { + delete(m.dirty, key) + } + m.mu.Unlock() + } + if ok { + e.delete() + } +} + +func (e *entry) delete() (hadValue bool) { + for { + p := atomic.LoadPointer(&e.p) + if p == nil || p == expunged { + return false + } + if atomic.CompareAndSwapPointer(&e.p, p, nil) { + return true + } + } +} + +// Range calls f sequentially for each key and value present in the map. +// If f returns false, range stops the iteration. +// +// Range does not necessarily correspond to any consistent snapshot of the Map's +// contents: no key will be visited more than once, but if the value for any key +// is stored or deleted concurrently, Range may reflect any mapping for that key +// from any point during the Range call. +// +// Range may be O(N) with the number of elements in the map even if f returns +// false after a constant number of calls. +func (m *Map) Range(f func(key, value interface{}) bool) { + // We need to be able to iterate over all of the keys that were already + // present at the start of the call to Range. + // If read.amended is false, then read.m satisfies that property without + // requiring us to hold m.mu for a long time. + read, _ := m.read.Load().(readOnly) + if read.amended { + // m.dirty contains keys not in read.m. Fortunately, Range is already O(N) + // (assuming the caller does not break out early), so a call to Range + // amortizes an entire copy of the map: we can promote the dirty copy + // immediately! + m.mu.Lock() + read, _ = m.read.Load().(readOnly) + if read.amended { + read = readOnly{m: m.dirty} + m.read.Store(read) + m.dirty = nil + m.misses = 0 + } + m.mu.Unlock() + } + + for k, e := range read.m { + v, ok := e.load() + if !ok { + continue + } + if !f(k, v) { + break + } + } +} + +func (m *Map) missLocked() { + m.misses++ + if m.misses < len(m.dirty) { + return + } + m.read.Store(readOnly{m: m.dirty}) + m.dirty = nil + m.misses = 0 +} + +func (m *Map) dirtyLocked() { + if m.dirty != nil { + return + } + + read, _ := m.read.Load().(readOnly) + m.dirty = make(map[interface{}]*entry, len(read.m)) + for k, e := range read.m { + if !e.tryExpungeLocked() { + m.dirty[k] = e + } + } +} + +func (e *entry) tryExpungeLocked() (isExpunged bool) { + p := atomic.LoadPointer(&e.p) + for p == nil { + if atomic.CompareAndSwapPointer(&e.p, nil, expunged) { + return true + } + p = atomic.LoadPointer(&e.p) + } + return p == expunged +} diff --git a/vendor/golang.org/x/sync/syncmap/pre_go19.go b/vendor/golang.org/x/sync/syncmap/pre_go19.go deleted file mode 100644 index 01a7be7f9..000000000 --- a/vendor/golang.org/x/sync/syncmap/pre_go19.go +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package syncmap - -import ( - "sync" - "sync/atomic" - "unsafe" -) - -// Map is a concurrent map with amortized-constant-time loads, stores, and deletes. -// It is safe for multiple goroutines to call a Map's methods concurrently. -// -// The zero Map is valid and empty. -// -// A Map must not be copied after first use. -type Map struct { - mu sync.Mutex - - // read contains the portion of the map's contents that are safe for - // concurrent access (with or without mu held). - // - // The read field itself is always safe to load, but must only be stored with - // mu held. - // - // Entries stored in read may be updated concurrently without mu, but updating - // a previously-expunged entry requires that the entry be copied to the dirty - // map and unexpunged with mu held. - read atomic.Value // readOnly - - // dirty contains the portion of the map's contents that require mu to be - // held. To ensure that the dirty map can be promoted to the read map quickly, - // it also includes all of the non-expunged entries in the read map. - // - // Expunged entries are not stored in the dirty map. An expunged entry in the - // clean map must be unexpunged and added to the dirty map before a new value - // can be stored to it. - // - // If the dirty map is nil, the next write to the map will initialize it by - // making a shallow copy of the clean map, omitting stale entries. - dirty map[interface{}]*entry - - // misses counts the number of loads since the read map was last updated that - // needed to lock mu to determine whether the key was present. - // - // Once enough misses have occurred to cover the cost of copying the dirty - // map, the dirty map will be promoted to the read map (in the unamended - // state) and the next store to the map will make a new dirty copy. - misses int -} - -// readOnly is an immutable struct stored atomically in the Map.read field. -type readOnly struct { - m map[interface{}]*entry - amended bool // true if the dirty map contains some key not in m. -} - -// expunged is an arbitrary pointer that marks entries which have been deleted -// from the dirty map. -var expunged = unsafe.Pointer(new(interface{})) - -// An entry is a slot in the map corresponding to a particular key. -type entry struct { - // p points to the interface{} value stored for the entry. - // - // If p == nil, the entry has been deleted and m.dirty == nil. - // - // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry - // is missing from m.dirty. - // - // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty - // != nil, in m.dirty[key]. - // - // An entry can be deleted by atomic replacement with nil: when m.dirty is - // next created, it will atomically replace nil with expunged and leave - // m.dirty[key] unset. - // - // An entry's associated value can be updated by atomic replacement, provided - // p != expunged. If p == expunged, an entry's associated value can be updated - // only after first setting m.dirty[key] = e so that lookups using the dirty - // map find the entry. - p unsafe.Pointer // *interface{} -} - -func newEntry(i interface{}) *entry { - return &entry{p: unsafe.Pointer(&i)} -} - -// Load returns the value stored in the map for a key, or nil if no -// value is present. -// The ok result indicates whether value was found in the map. -func (m *Map) Load(key interface{}) (value interface{}, ok bool) { - read, _ := m.read.Load().(readOnly) - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - // Avoid reporting a spurious miss if m.dirty got promoted while we were - // blocked on m.mu. (If further loads of the same key will not miss, it's - // not worth copying the dirty map for this key.) - read, _ = m.read.Load().(readOnly) - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - // Regardless of whether the entry was present, record a miss: this key - // will take the slow path until the dirty map is promoted to the read - // map. - m.missLocked() - } - m.mu.Unlock() - } - if !ok { - return nil, false - } - return e.load() -} - -func (e *entry) load() (value interface{}, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return nil, false - } - return *(*interface{})(p), true -} - -// Store sets the value for a key. -func (m *Map) Store(key, value interface{}) { - read, _ := m.read.Load().(readOnly) - if e, ok := read.m[key]; ok && e.tryStore(&value) { - return - } - - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - // The entry was previously expunged, which implies that there is a - // non-nil dirty map and this entry is not in it. - m.dirty[key] = e - } - e.storeLocked(&value) - } else if e, ok := m.dirty[key]; ok { - e.storeLocked(&value) - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(readOnly{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - } - m.mu.Unlock() -} - -// tryStore stores a value if the entry has not been expunged. -// -// If the entry is expunged, tryStore returns false and leaves the entry -// unchanged. -func (e *entry) tryStore(i *interface{}) bool { - p := atomic.LoadPointer(&e.p) - if p == expunged { - return false - } - for { - if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) { - return true - } - p = atomic.LoadPointer(&e.p) - if p == expunged { - return false - } - } -} - -// unexpungeLocked ensures that the entry is not marked as expunged. -// -// If the entry was previously expunged, it must be added to the dirty map -// before m.mu is unlocked. -func (e *entry) unexpungeLocked() (wasExpunged bool) { - return atomic.CompareAndSwapPointer(&e.p, expunged, nil) -} - -// storeLocked unconditionally stores a value to the entry. -// -// The entry must be known not to be expunged. -func (e *entry) storeLocked(i *interface{}) { - atomic.StorePointer(&e.p, unsafe.Pointer(i)) -} - -// LoadOrStore returns the existing value for the key if present. -// Otherwise, it stores and returns the given value. -// The loaded result is true if the value was loaded, false if stored. -func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { - // Avoid locking if it's a clean hit. - read, _ := m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - actual, loaded, ok := e.tryLoadOrStore(value) - if ok { - return actual, loaded - } - } - - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - m.dirty[key] = e - } - actual, loaded, _ = e.tryLoadOrStore(value) - } else if e, ok := m.dirty[key]; ok { - actual, loaded, _ = e.tryLoadOrStore(value) - m.missLocked() - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(readOnly{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - actual, loaded = value, false - } - m.mu.Unlock() - - return actual, loaded -} - -// tryLoadOrStore atomically loads or stores a value if the entry is not -// expunged. -// -// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and -// returns with ok==false. -func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == expunged { - return nil, false, false - } - if p != nil { - return *(*interface{})(p), true, true - } - - // Copy the interface after the first load to make this method more amenable - // to escape analysis: if we hit the "load" path or the entry is expunged, we - // shouldn't bother heap-allocating. - ic := i - for { - if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) { - return i, false, true - } - p = atomic.LoadPointer(&e.p) - if p == expunged { - return nil, false, false - } - if p != nil { - return *(*interface{})(p), true, true - } - } -} - -// Delete deletes the value for a key. -func (m *Map) Delete(key interface{}) { - read, _ := m.read.Load().(readOnly) - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - e, ok = read.m[key] - if !ok && read.amended { - delete(m.dirty, key) - } - m.mu.Unlock() - } - if ok { - e.delete() - } -} - -func (e *entry) delete() (hadValue bool) { - for { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return false - } - if atomic.CompareAndSwapPointer(&e.p, p, nil) { - return true - } - } -} - -// Range calls f sequentially for each key and value present in the map. -// If f returns false, range stops the iteration. -// -// Range does not necessarily correspond to any consistent snapshot of the Map's -// contents: no key will be visited more than once, but if the value for any key -// is stored or deleted concurrently, Range may reflect any mapping for that key -// from any point during the Range call. -// -// Range may be O(N) with the number of elements in the map even if f returns -// false after a constant number of calls. -func (m *Map) Range(f func(key, value interface{}) bool) { - // We need to be able to iterate over all of the keys that were already - // present at the start of the call to Range. - // If read.amended is false, then read.m satisfies that property without - // requiring us to hold m.mu for a long time. - read, _ := m.read.Load().(readOnly) - if read.amended { - // m.dirty contains keys not in read.m. Fortunately, Range is already O(N) - // (assuming the caller does not break out early), so a call to Range - // amortizes an entire copy of the map: we can promote the dirty copy - // immediately! - m.mu.Lock() - read, _ = m.read.Load().(readOnly) - if read.amended { - read = readOnly{m: m.dirty} - m.read.Store(read) - m.dirty = nil - m.misses = 0 - } - m.mu.Unlock() - } - - for k, e := range read.m { - v, ok := e.load() - if !ok { - continue - } - if !f(k, v) { - break - } - } -} - -func (m *Map) missLocked() { - m.misses++ - if m.misses < len(m.dirty) { - return - } - m.read.Store(readOnly{m: m.dirty}) - m.dirty = nil - m.misses = 0 -} - -func (m *Map) dirtyLocked() { - if m.dirty != nil { - return - } - - read, _ := m.read.Load().(readOnly) - m.dirty = make(map[interface{}]*entry, len(read.m)) - for k, e := range read.m { - if !e.tryExpungeLocked() { - m.dirty[k] = e - } - } -} - -func (e *entry) tryExpungeLocked() (isExpunged bool) { - p := atomic.LoadPointer(&e.p) - for p == nil { - if atomic.CompareAndSwapPointer(&e.p, nil, expunged) { - return true - } - p = atomic.LoadPointer(&e.p) - } - return p == expunged -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0df9f6734..6412b187a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -3,7 +3,7 @@ github.com/BurntSushi/toml # github.com/allegro/bigcache v1.2.0 github.com/allegro/bigcache github.com/allegro/bigcache/queue -# github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 +# github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 github.com/aristanetworks/goarista/monotime # github.com/beevik/ntp v0.2.0 github.com/beevik/ntp @@ -30,7 +30,7 @@ github.com/davecgh/go-spew/spew github.com/deckarep/golang-set # github.com/edsrzf/mmap-go v1.0.0 github.com/edsrzf/mmap-go -# github.com/elastic/gosigar v0.10.5 +# github.com/elastic/gosigar v0.10.4 github.com/elastic/gosigar 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 @@ -165,7 +165,7 @@ github.com/ipfs/go-log/tracer/wire github.com/ipfs/go-log/writer # github.com/jackpal/gateway v1.0.5 github.com/jackpal/gateway -# github.com/jackpal/go-nat-pmp v1.0.2 +# github.com/jackpal/go-nat-pmp v1.0.1 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 @@ -342,7 +342,7 @@ github.com/prometheus/procfs/internal/util github.com/prometheus/tsdb/fileutil # github.com/rjeczalik/notify v0.9.2 github.com/rjeczalik/notify -# github.com/rs/cors v1.7.0 +# github.com/rs/cors v1.6.0 github.com/rs/cors # github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a github.com/russolsen/transit @@ -374,8 +374,6 @@ github.com/status-im/rendezvous/protocol github.com/status-im/rendezvous/server # github.com/status-im/status-go/extkeys v1.1.0 github.com/status-im/status-go/extkeys -# github.com/status-im/status-go/waku v1.3.0 -github.com/status-im/status-go/waku # github.com/status-im/status-go/whisper/v6 v6.2.0 github.com/status-im/status-go/whisper/v6 # github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 @@ -478,7 +476,7 @@ golang.org/x/crypto/ssh/terminal # golang.org/x/lint v0.0.0-20190930215403-16217165b5de golang.org/x/lint golang.org/x/lint/golint -# golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2 +# golang.org/x/net v0.0.0-20190620200207-3b0461eec859 golang.org/x/net/bpf golang.org/x/net/context golang.org/x/net/html @@ -488,7 +486,7 @@ golang.org/x/net/idna golang.org/x/net/internal/iana golang.org/x/net/internal/socket golang.org/x/net/ipv4 -# golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e +# golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sync/syncmap # golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 golang.org/x/sys/cpu diff --git a/waku/api.go b/waku/api.go index 73712bf7a..ea5202605 100644 --- a/waku/api.go +++ b/waku/api.go @@ -219,7 +219,7 @@ type NewMessage struct { TargetPeer string `json:"targetPeer"` } -type newMessageOverride struct { +type newMessageOverride struct { // nolint: deadcode,unused PublicKey hexutil.Bytes Payload hexutil.Bytes Padding hexutil.Bytes @@ -316,16 +316,14 @@ func (api *PublicWakuAPI) Post(ctx context.Context, req NewMessage) (hexutil.Byt // UninstallFilter is alias for Unsubscribe func (api *PublicWakuAPI) UninstallFilter(id string) { - api.w.Unsubscribe(id) + api.w.Unsubscribe(id) // nolint: errcheck } // Unsubscribe disables and removes an existing filter. func (api *PublicWakuAPI) Unsubscribe(id string) { - api.w.Unsubscribe(id) + api.w.Unsubscribe(id) // nolint: errcheck } -//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"` @@ -336,10 +334,6 @@ type Criteria struct { 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) { @@ -451,7 +445,7 @@ type Message struct { P2P bool `json:"bool,omitempty"` } -type messageOverride struct { +type messageOverride struct { // nolint: deadcode,unused Sig hexutil.Bytes Payload hexutil.Bytes Padding hexutil.Bytes diff --git a/waku/config.go b/waku/config.go index 2a82a5ffd..c77c0b02a 100644 --- a/waku/config.go +++ b/waku/config.go @@ -22,6 +22,7 @@ package waku type Config struct { MaxMessageSize uint32 `toml:",omitempty"` MinimumAcceptedPoW float64 `toml:",omitempty"` + BloomFilterMode bool `toml:",omitempty"` // when true, we only match against bloom filter 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 diff --git a/waku/doc.go b/waku/doc.go index 03feccbce..2944b097a 100644 --- a/waku/doc.go +++ b/waku/doc.go @@ -37,11 +37,9 @@ const ( // 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 + statusUpdateCode = 22 // update of settings 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) @@ -50,13 +48,14 @@ const ( 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 + 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 + MaxTopicInterest = 10000 + flagsLength = 1 EnvelopeHeaderLength = 20 diff --git a/waku/envelope_test.go b/waku/envelope_test.go index 11a9a3807..b838f0f04 100644 --- a/waku/envelope_test.go +++ b/waku/envelope_test.go @@ -55,7 +55,7 @@ func TestPoWCalculationsWith8LeadingZeros(t *testing.T) { func TestEnvelopeOpenAcceptsOnlyOneKeyTypeInFilter(t *testing.T) { symKey := make([]byte, aesKeyLength) - mrand.Read(symKey) + mrand.Read(symKey) //nolint: gosec asymKey, err := crypto.GenerateKey() if err != nil { @@ -71,7 +71,7 @@ func TestEnvelopeOpenAcceptsOnlyOneKeyTypeInFilter(t *testing.T) { Dst: nil, } - mrand.Read(params.Payload) + mrand.Read(params.Payload) // nolint: gosec msg, err := NewSentMessage(¶ms) if err != nil { diff --git a/waku/events.go b/waku/events.go index 8c22e5fb9..8dd022f1d 100644 --- a/waku/events.go +++ b/waku/events.go @@ -35,8 +35,8 @@ const ( // 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" + // EventBatchAcknowledged is sent when batch of envelopes was acknowledged by a peer. + EventBatchAcknowledged EventType = "batch.acknowledged" // EventEnvelopeAvailable fires when envelop is available for filters EventEnvelopeAvailable EventType = "envelope.available" // EventMailServerRequestSent fires when such request is sent. diff --git a/waku/filter.go b/waku/filter.go index dfe3f60e5..d90aabce4 100644 --- a/waku/filter.go +++ b/waku/filter.go @@ -57,7 +57,7 @@ func (store *MemoryMessageStore) Add(msg *ReceivedMessage) error { return nil } -// Pop returns all avaiable messages and cleans the store. +// Pop returns all available messages and cleans the store. func (store *MemoryMessageStore) Pop() ([]*ReceivedMessage, error) { store.mu.Lock() defer store.mu.Unlock() @@ -81,7 +81,6 @@ type Filter struct { id string // unique identifier Messages MessageStore - mutex sync.RWMutex } // Filters represents a collection of filters diff --git a/waku/filter_test.go b/waku/filter_test.go index 0d21473db..577defc24 100644 --- a/waku/filter_test.go +++ b/waku/filter_test.go @@ -38,11 +38,6 @@ func InitSingleTest() { mrand.Seed(seed) } -func InitDebugTest(i int64) { - seed = i - mrand.Seed(seed) -} - type FilterTestCase struct { f *Filter id string @@ -58,7 +53,7 @@ func generateFilter(t *testing.T, symmetric bool) (*Filter, error) { f.Topics = make([][]byte, topicNum) for i := 0; i < topicNum; i++ { f.Topics[i] = make([]byte, 4) - mrand.Read(f.Topics[i]) + mrand.Read(f.Topics[i]) // nolint: gosec f.Topics[i][0] = 0x01 } @@ -71,7 +66,7 @@ func generateFilter(t *testing.T, symmetric bool) (*Filter, error) { if symmetric { f.KeySym = make([]byte, aesKeyLength) - mrand.Read(f.KeySym) + mrand.Read(f.KeySym) // nolint: gosec f.SymKeyHash = crypto.Keccak256Hash(f.KeySym) } else { f.KeyAsym, err = crypto.GenerateKey() @@ -90,7 +85,7 @@ func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase { for i := 0; i < SizeTestFilters; i++ { f, _ := generateFilter(t, true) cases[i].f = f - cases[i].alive = mrand.Int()&int(1) == 0 + cases[i].alive = mrand.Int()&int(1) == 0 // nolint: gosec } return cases } @@ -311,20 +306,20 @@ func TestMatchEnvelope(t *testing.T) { if err != nil { t.Fatalf("failed to create new message with seed %d: %s.", seed, err) } - env, err := msg.Wrap(params, time.Now()) + _, err = msg.Wrap(params, time.Now()) if err != nil { t.Fatalf("failed Wrap with seed %d: %s.", seed, err) } // encrypt symmetrically - i := mrand.Int() % 4 + i := mrand.Int() % 4 // nolint: gosec fsym.Topics[i] = params.Topic[:] fasym.Topics[i] = params.Topic[:] msg, err = NewSentMessage(params) if err != nil { t.Fatalf("failed to create new message with seed %d: %s.", seed, err) } - env, err = msg.Wrap(params, time.Now()) + env, err := msg.Wrap(params, time.Now()) if err != nil { t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) } @@ -710,7 +705,10 @@ func TestWatchers(t *testing.T) { total = 0 last := NumFilters - 1 tst[last].f = clone - filters.Install(clone) + if _, err := filters.Install(clone); err != nil { + t.Fatal("failed to install filter") + } + for i = 0; i < NumFilters; i++ { tst[i].msgCnt = 0 count[i] = 0 diff --git a/waku/go.mod b/waku/go.mod deleted file mode 100644 index b11bde74d..000000000 --- a/waku/go.mod +++ /dev/null @@ -1,24 +0,0 @@ -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.7 - -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 -) diff --git a/waku/go.sum b/waku/go.sum deleted file mode 100644 index d8b156dc4..000000000 --- a/waku/go.sum +++ /dev/null @@ -1,309 +0,0 @@ -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/btcd v0.20.1-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/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q= -github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g= -github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= -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-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/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= diff --git a/waku/handshake.go b/waku/handshake.go index 99effbe37..6d8a5bfe6 100644 --- a/waku/handshake.go +++ b/waku/handshake.go @@ -11,6 +11,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) +var defaultMinPoW = math.Float64bits(0.001) + // statusOptions defines additional information shared between peers // during the handshake. // There might be more options provided then fields in statusOptions @@ -18,14 +20,43 @@ import ( // In the case of RLP, options should be serialized to an array of tuples // where the first item is a field name and the second is a RLP-serialized value. type statusOptions struct { - PoWRequirement uint64 `rlp:"key=0"` // RLP does not support float64 natively + PoWRequirement *uint64 `rlp:"key=0"` // RLP does not support float64 natively BloomFilter []byte `rlp:"key=1"` - LightNodeEnabled bool `rlp:"key=2"` - ConfirmationsEnabled bool `rlp:"key=3"` - RateLimits RateLimits `rlp:"key=4"` + LightNodeEnabled *bool `rlp:"key=2"` + ConfirmationsEnabled *bool `rlp:"key=3"` + RateLimits *RateLimits `rlp:"key=4"` TopicInterest []TopicType `rlp:"key=5"` } +// WithDefaults adds the default values for a given peer. +// This are not the host default values, but the default values that ought to +// be used when receiving from an update from a peer. +func (o statusOptions) WithDefaults() statusOptions { + if o.PoWRequirement == nil { + o.PoWRequirement = &defaultMinPoW + } + + if o.LightNodeEnabled == nil { + lightNodeEnabled := false + o.LightNodeEnabled = &lightNodeEnabled + } + + if o.ConfirmationsEnabled == nil { + confirmationsEnabled := false + o.ConfirmationsEnabled = &confirmationsEnabled + } + + if o.RateLimits == nil { + o.RateLimits = &RateLimits{} + } + + if o.BloomFilter == nil { + o.BloomFilter = MakeFullNodeBloom() + } + + return o +} + var idxFieldKey = make(map[int]string) var keyFieldIdx = func() map[string]int { result := make(map[string]int) @@ -48,24 +79,34 @@ var keyFieldIdx = func() map[string]int { return result }() -func (o statusOptions) PoWRequirementF() float64 { - return math.Float64frombits(o.PoWRequirement) +func (o statusOptions) PoWRequirementF() *float64 { + if o.PoWRequirement == nil { + return nil + } + result := math.Float64frombits(*o.PoWRequirement) + return &result } func (o *statusOptions) SetPoWRequirementFromF(val float64) { - o.PoWRequirement = math.Float64bits(val) + requirement := math.Float64bits(val) + o.PoWRequirement = &requirement } func (o statusOptions) EncodeRLP(w io.Writer) error { v := reflect.ValueOf(o) - optionsList := make([]interface{}, 0, v.NumField()) + var optionsList []interface{} for i := 0; i < v.NumField(); i++ { - value := v.Field(i).Interface() - key, ok := idxFieldKey[i] - if !ok { - continue + field := v.Field(i) + if !field.IsNil() { + value := field.Interface() + key, ok := idxFieldKey[i] + if !ok { + continue + } + if value != nil { + optionsList = append(optionsList, []interface{}{key, value}) + } } - optionsList = append(optionsList, []interface{}{key, value}) } return rlp.Encode(w, optionsList) } @@ -73,7 +114,7 @@ func (o statusOptions) EncodeRLP(w io.Writer) error { func (o *statusOptions) DecodeRLP(s *rlp.Stream) error { _, err := s.List() if err != nil { - return fmt.Errorf("expected an outer list: %w", err) + return fmt.Errorf("expected an outer list: %v", err) } v := reflect.ValueOf(o) @@ -87,11 +128,11 @@ loop: case rlp.EOL: break loop default: - return fmt.Errorf("expected an inner list: %w", err) + return fmt.Errorf("expected an inner list: %v", err) } var key string if err := s.Decode(&key); err != nil { - return fmt.Errorf("invalid key: %w", err) + return fmt.Errorf("invalid key: %v", err) } // Skip processing if a key does not exist. // It might happen when there is a new peer @@ -102,12 +143,12 @@ loop: // Read the rest of the list items and dump them. _, err := s.Raw() if err != nil { - return fmt.Errorf("failed to read the value of key %s: %w", key, err) + return fmt.Errorf("failed to read the value of key %s: %v", key, err) } continue } if err := s.Decode(v.Elem().Field(idx).Addr().Interface()); err != nil { - return fmt.Errorf("failed to decode an option %s: %w", key, err) + return fmt.Errorf("failed to decode an option %s: %v", key, err) } if err := s.ListEnd(); err != nil { return err diff --git a/waku/handshake_test.go b/waku/handshake_test.go index 002f7064c..f005b7fd8 100644 --- a/waku/handshake_test.go +++ b/waku/handshake_test.go @@ -10,12 +10,16 @@ import ( ) func TestEncodeDecodeRLP(t *testing.T) { + pow := math.Float64bits(6.02) + lightNodeEnabled := true + confirmationsEnabled := true + opts := statusOptions{ - PoWRequirement: math.Float64bits(6.02), + PoWRequirement: &pow, BloomFilter: TopicToBloom(TopicType{0xaa, 0xbb, 0xcc, 0xdd}), - LightNodeEnabled: true, - ConfirmationsEnabled: true, - RateLimits: RateLimits{ + LightNodeEnabled: &lightNodeEnabled, + ConfirmationsEnabled: &confirmationsEnabled, + RateLimits: &RateLimits{ IPLimits: 10, PeerIDLimits: 5, TopicLimits: 1, @@ -41,12 +45,14 @@ func TestBackwardCompatibility(t *testing.T) { var optsDecoded statusOptions err = rlp.DecodeBytes(data, &optsDecoded) require.NoError(t, err) - require.EqualValues(t, statusOptions{PoWRequirement: math.Float64bits(2.05)}, optsDecoded) + pow := math.Float64bits(2.05) + require.EqualValues(t, statusOptions{PoWRequirement: &pow}, optsDecoded) } func TestForwardCompatibility(t *testing.T) { + pow := math.Float64bits(2.05) alist := []interface{}{ - []interface{}{"0", math.Float64bits(2.05)}, + []interface{}{"0", pow}, []interface{}{"99", uint(10)}, // some future option } data, err := rlp.EncodeToBytes(alist) @@ -55,5 +61,5 @@ func TestForwardCompatibility(t *testing.T) { var optsDecoded statusOptions err = rlp.DecodeBytes(data, &optsDecoded) require.NoError(t, err) - require.EqualValues(t, statusOptions{PoWRequirement: math.Float64bits(2.05)}, optsDecoded) + require.EqualValues(t, statusOptions{PoWRequirement: &pow}, optsDecoded) } diff --git a/waku/message.go b/waku/message.go index b35953dea..aefa14d86 100644 --- a/waku/message.go +++ b/waku/message.go @@ -221,7 +221,7 @@ func generateSecureRandomData(length int) ([]byte, error) { } else if !validateDataIntegrity(x, length) { return nil, errors.New("crypto/rand failed to generate secure random data") } - _, err = mrand.Read(y) + _, err = mrand.Read(y) // nolint: gosec if err != nil { return nil, err } else if !validateDataIntegrity(y, length) { @@ -341,7 +341,8 @@ func (msg *ReceivedMessage) ValidateAndParse() bool { // 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 + // in case of invalid signature + defer func() { recover() }() // nolint: errcheck pub, err := crypto.SigToPub(msg.hash(), msg.Signature) if err != nil { diff --git a/waku/message_test.go b/waku/message_test.go index f7a425c77..6f9187e0b 100644 --- a/waku/message_test.go +++ b/waku/message_test.go @@ -35,7 +35,7 @@ func generateMessageParams() (*MessageParams, error) { // set all the parameters except p.Dst and p.Padding buf := make([]byte, 4) - mrand.Read(buf) + mrand.Read(buf) // nolint: gosec sz := mrand.Intn(400) var p MessageParams @@ -44,8 +44,8 @@ func generateMessageParams() (*MessageParams, error) { p.TTL = uint32(mrand.Intn(1024)) p.Payload = make([]byte, sz) p.KeySym = make([]byte, aesKeyLength) - mrand.Read(p.Payload) - mrand.Read(p.KeySym) + mrand.Read(p.Payload) // nolint: gosec + mrand.Read(p.KeySym) // nolint: gosec p.Topic = BytesToTopic(buf) var err error @@ -190,7 +190,7 @@ func TestMessageSeal(t *testing.T) { target := 32.0 params.WorkTime = 4 params.PoW = target - env.Seal(params) + env.Seal(params) // nolint: errcheck env.calculatePoW(0) pow := env.PoW() @@ -200,7 +200,7 @@ func TestMessageSeal(t *testing.T) { params.WorkTime = 1 params.PoW = 1000000000.0 - env.Seal(params) + env.Seal(params) // nolint: errcheck env.calculatePoW(0) pow = env.PoW() if pow < 2*target { @@ -353,7 +353,7 @@ func TestRlpEncode(t *testing.T) { } var decoded Envelope - rlp.DecodeBytes(raw, &decoded) + err = rlp.DecodeBytes(raw, &decoded) if err != nil { t.Fatalf("RLP decode failed: %s.", err) } @@ -374,7 +374,7 @@ func singlePaddingTest(t *testing.T, padSize int) { params.Padding = make([]byte, padSize) params.PoW = 0.0000000001 pad := make([]byte, padSize) - _, err = mrand.Read(pad) + _, err = mrand.Read(pad) // nolint: gosec if err != nil { t.Fatalf("padding is not generated (seed %d): %s", seed, err) } diff --git a/waku/peer.go b/waku/peer.go index 01d8edc78..51bd670d5 100644 --- a/waku/peer.go +++ b/waku/peer.go @@ -41,10 +41,20 @@ type Peer struct { ws p2p.MsgReadWriter logger *zap.Logger - trusted bool - powRequirement float64 - bloomMu sync.Mutex - bloomFilter []byte + trusted bool + powRequirement float64 + // bloomMu is to allow thread safe access to + // the bloom filter + bloomMu sync.Mutex + bloomFilter []byte + // topicInterestMu is to allow thread safe access to + // the map of topic interests + topicInterestMu sync.Mutex + topicInterest map[TopicType]bool + // fullNode is used to indicate that the node will be accepting any + // envelope. The opposite is an "empty node" , which is when + // a bloom filter is all 0s or topic interest is an empty map (not nil). + // In that case no envelope is accepted. fullNode bool confirmationsEnabled bool rateLimitsMu sync.Mutex @@ -93,17 +103,8 @@ func (p *Peer) stop() { func (p *Peer) handshake() error { // Send the handshake status message asynchronously errc := make(chan error, 1) - isLightNode := p.host.LightClientMode() - isRestrictedLightNodeConnection := p.host.LightClientModeConnectionRestricted() + opts := p.host.toStatusOptions() go func() { - opts := statusOptions{ - BloomFilter: p.host.BloomFilter(), - LightNodeEnabled: isLightNode, - ConfirmationsEnabled: p.host.ConfirmationsEnabled(), - RateLimits: p.host.RateLimits(), - TopicInterest: nil, - } - opts.SetPoWRequirementFromF(p.host.MinPow()) errc <- p2p.SendItems(p.ws, statusCode, ProtocolVersion, opts) }() @@ -122,51 +123,75 @@ func (p *Peer) handshake() error { ) s := rlp.NewStream(packet.Payload, uint64(packet.Size)) if _, err := s.List(); err != nil { - return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err) + return fmt.Errorf("p [%x]: failed to decode status packet: %v", p.ID(), err) } // Validate protocol version. if err := s.Decode(&peerProtocolVersion); err != nil { - return fmt.Errorf("p [%x]: failed to decode peer protocol version: %w", p.ID(), err) + return fmt.Errorf("p [%x]: failed to decode peer protocol version: %v", p.ID(), err) } if peerProtocolVersion != ProtocolVersion { return fmt.Errorf("p [%x]: protocol version mismatch %d != %d", p.ID(), peerProtocolVersion, ProtocolVersion) } // Decode and validate other status packet options. if err := s.Decode(&peerOptions); err != nil { - return fmt.Errorf("p [%x]: failed to decode status options: %w", p.ID(), err) + return fmt.Errorf("p [%x]: failed to decode status options: %v", p.ID(), err) } if err := s.ListEnd(); err != nil { - return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err) + return fmt.Errorf("p [%x]: failed to decode status packet: %v", p.ID(), err) } - if err := peerOptions.Validate(); err != nil { - return fmt.Errorf("p [%x]: sent invalid options: %w", p.ID(), err) + if err := p.setOptions(peerOptions.WithDefaults()); err != nil { + return fmt.Errorf("p [%x]: failed to set options: %v", p.ID(), err) } - // Validate and save peer's PoW. - pow := peerOptions.PoWRequirementF() - 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 - // Validate and save peer's bloom filters. - bloom := peerOptions.BloomFilter - bloomSize := len(bloom) - if bloomSize != 0 && bloomSize != BloomFilterSize { - return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), bloomSize) - } - p.setBloomFilter(bloom) - // Validate and save other peer's options. - if peerOptions.LightNodeEnabled && isLightNode && isRestrictedLightNodeConnection { - return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID()) - } - p.confirmationsEnabled = peerOptions.ConfirmationsEnabled - p.setRateLimits(peerOptions.RateLimits) - if err := <-errc; err != nil { return fmt.Errorf("p [%x] failed to send status packet: %v", p.ID(), err) } return nil } +func (p *Peer) setOptions(peerOptions statusOptions) error { + + p.logger.Debug("settings options", zap.Binary("peerID", p.ID()), zap.Any("Options", peerOptions)) + + if err := peerOptions.Validate(); err != nil { + return fmt.Errorf("p [%x]: sent invalid options: %v", p.ID(), err) + } + // Validate and save peer's PoW. + pow := peerOptions.PoWRequirementF() + if pow != nil { + 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 + } + + if peerOptions.TopicInterest != nil { + p.setTopicInterest(peerOptions.TopicInterest) + } else if peerOptions.BloomFilter != nil { + // Validate and save peer's bloom filters. + bloom := peerOptions.BloomFilter + bloomSize := len(bloom) + if bloomSize != 0 && bloomSize != BloomFilterSize { + return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), bloomSize) + } + p.setBloomFilter(bloom) + } + + if peerOptions.LightNodeEnabled != nil { + // Validate and save other peer's options. + if *peerOptions.LightNodeEnabled && p.host.LightClientMode() && p.host.LightClientModeConnectionRestricted() { + return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID()) + } + } + if peerOptions.ConfirmationsEnabled != nil { + p.confirmationsEnabled = *peerOptions.ConfirmationsEnabled + } + if peerOptions.RateLimits != nil { + p.setRateLimits(*peerOptions.RateLimits) + } + + return nil +} + // update executes periodic operations on the peer, including message transmission // and expiration. func (p *Peer) update() { @@ -224,7 +249,7 @@ 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) { + if !p.marked(envelope) && envelope.PoW() >= p.powRequirement && p.topicOrBloomMatch(envelope) { bundle = append(bundle, envelope) } } @@ -264,11 +289,15 @@ func (p *Peer) ID() []byte { func (p *Peer) notifyAboutPowRequirementChange(pow float64) error { i := math.Float64bits(pow) - return p2p.Send(p.ws, powRequirementCode, i) + return p2p.Send(p.ws, statusUpdateCode, statusOptions{PoWRequirement: &i}) } func (p *Peer) notifyAboutBloomFilterChange(bloom []byte) error { - return p2p.Send(p.ws, bloomFilterExCode, bloom) + return p2p.Send(p.ws, statusUpdateCode, statusOptions{BloomFilter: bloom}) +} + +func (p *Peer) notifyAboutTopicInterestChange(topics []TopicType) error { + return p2p.Send(p.ws, statusUpdateCode, statusOptions{TopicInterest: topics}) } func (p *Peer) bloomMatch(env *Envelope) bool { @@ -277,6 +306,33 @@ func (p *Peer) bloomMatch(env *Envelope) bool { return p.fullNode || BloomFilterMatch(p.bloomFilter, env.Bloom()) } +func (p *Peer) topicInterestMatch(env *Envelope) bool { + p.topicInterestMu.Lock() + defer p.topicInterestMu.Unlock() + + if p.topicInterest == nil { + return false + } + + return p.fullNode || p.topicInterest[env.Topic] +} + +// topicOrBloomMatch matches against topic-interest if topic interest +// is not nil. Otherwise it will match against the bloom-filter. +// If the bloom-filter is nil, or full, the node is considered a full-node +// and any envelope will be accepted. An empty topic-interest (but not nil) +// signals that we are not interested in any envelope. +func (p *Peer) topicOrBloomMatch(env *Envelope) bool { + p.topicInterestMu.Lock() + topicInterestMode := p.topicInterest != nil + p.topicInterestMu.Unlock() + + if topicInterestMode { + return p.topicInterestMatch(env) + } + return p.bloomMatch(env) +} + func (p *Peer) setBloomFilter(bloom []byte) { p.bloomMu.Lock() defer p.bloomMu.Unlock() @@ -285,6 +341,21 @@ func (p *Peer) setBloomFilter(bloom []byte) { if p.fullNode && p.bloomFilter == nil { p.bloomFilter = MakeFullNodeBloom() } + p.topicInterest = nil +} + +func (p *Peer) setTopicInterest(topicInterest []TopicType) { + p.topicInterestMu.Lock() + defer p.topicInterestMu.Unlock() + if topicInterest == nil { + p.topicInterest = nil + return + } + p.topicInterest = make(map[TopicType]bool) + for _, topic := range topicInterest { + p.topicInterest[topic] = true + } + p.bloomFilter = nil } func (p *Peer) setRateLimits(r RateLimits) { diff --git a/waku/peer_test.go b/waku/peer_test.go index 8875d0021..100694ec4 100644 --- a/waku/peer_test.go +++ b/waku/peer_test.go @@ -104,10 +104,10 @@ var debugMode = false var prevTime time.Time var cntPrev int -func TestSimulation(t *testing.T) { +func TestSimulationBloomFilter(t *testing.T) { // create a chain of waku nodes, // installs the filters with shared (predefined) parameters - initialize(t) + initializeBloomFilterMode(t) // each node sends one random (not decryptable) message for i := 0; i < NumNodes; i++ { @@ -156,7 +156,7 @@ func resetParams(t *testing.T) { func initBloom(t *testing.T) { masterBloomFilter = make([]byte, BloomFilterSize) - _, err := mrand.Read(masterBloomFilter) + _, err := mrand.Read(masterBloomFilter) // nolint: gosec if err != nil { t.Fatalf("rand failed: %s.", err) } @@ -172,7 +172,7 @@ func initBloom(t *testing.T) { } } -func initialize(t *testing.T) { +func initializeBloomFilterMode(t *testing.T) { initBloom(t) var err error @@ -181,7 +181,9 @@ func initialize(t *testing.T) { var node TestNode b := make([]byte, BloomFilterSize) copy(b, masterBloomFilter) - node.shh = New(nil, nil) + config := DefaultConfig + config.BloomFilterMode = true + node.shh = New(&config, nil) _ = node.shh.SetMinimumPoW(masterPow, false) _ = node.shh.SetBloomFilter(b) if !bytes.Equal(node.shh.BloomFilter(), masterBloomFilter) { @@ -213,7 +215,7 @@ func initialize(t *testing.T) { }, } - go startServer(t, node.server) + go startServer(t, node.server) // nolint: staticcheck nodes[i] = &node } @@ -222,9 +224,9 @@ func initialize(t *testing.T) { for i := 0; i < NumNodes; i++ { for j := 0; j < i; j++ { - peerNodeId := nodes[j].id + peerNodeID := nodes[j].id address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr) - peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, address.Port, address.Port) + peer := enode.NewV4(&peerNodeID.PublicKey, address.IP, address.Port, address.Port) nodes[i].server.AddPeer(peer) } } @@ -511,12 +513,32 @@ func waitForServersToStart(t *testing.T) { //two generic waku node handshake func TestPeerHandshakeWithTwoFullNode(t *testing.T) { w1 := Waku{} + var pow uint64 = 123 p1 := newPeer( &w1, p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), &rwStub{[]interface{}{ ProtocolVersion, - statusOptions{PoWRequirement: 123}, + statusOptions{PoWRequirement: &pow}, + }}, + nil, + ) + err := p1.handshake() + if err != nil { + t.Fatal(err) + } +} + +//two generic waku node handshake. one don't send light flag +func TestHandshakeWithOldVersionWithoutLightModeFlag(t *testing.T) { + w1 := Waku{} + var pow uint64 = 123 + p1 := newPeer( + &w1, + p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), + &rwStub{[]interface{}{ + ProtocolVersion, + statusOptions{PoWRequirement: &pow}, }}, nil, ) @@ -527,21 +549,19 @@ func TestPeerHandshakeWithTwoFullNode(t *testing.T) { } //two generic waku node handshake. one don't send light flag -func TestHandshakeWithOldVersionWithoutLightModeFlag(t *testing.T) { - w1 := Waku{} - p1 := newPeer( - &w1, - p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), - &rwStub{[]interface{}{ - ProtocolVersion, - statusOptions{PoWRequirement: 123}, - }}, - nil, - ) - err := p1.handshake() - if err != nil { - t.Fatal() +func TestTopicOrBloomMatch(t *testing.T) { + p := Peer{} + p.setTopicInterest([]TopicType{sharedTopic}) + envelope := &Envelope{Topic: sharedTopic} + if !p.topicOrBloomMatch(envelope) { + t.Fatal("envelope should match") } + + badEnvelope := &Envelope{Topic: wrongTopic} + if p.topicOrBloomMatch(badEnvelope) { + t.Fatal("envelope should not match") + } + } //two light nodes handshake. restriction disabled @@ -549,12 +569,14 @@ func TestTwoLightPeerHandshakeRestrictionOff(t *testing.T) { w1 := Waku{} w1.settings.RestrictLightClientsConn = false w1.SetLightClientMode(true) + var pow uint64 = 123 + var lightNodeEnabled = true p1 := newPeer( &w1, p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), &rwStub{[]interface{}{ ProtocolVersion, - statusOptions{PoWRequirement: 123, LightNodeEnabled: true}, + statusOptions{PoWRequirement: &pow, LightNodeEnabled: &lightNodeEnabled}, }}, nil, ) diff --git a/waku/rate_limiter.go b/waku/rate_limiter.go index 2ea260f80..867029aa8 100644 --- a/waku/rate_limiter.go +++ b/waku/rate_limiter.go @@ -143,7 +143,7 @@ func (r *PeerRateLimiter) decorate(p *Peer, rw p2p.MsgReadWriter, runLoop runLoo 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) + errC <- fmt.Errorf("exceed rate limit by IP: %v", err) return } } @@ -156,7 +156,7 @@ func (r *PeerRateLimiter) decorate(p *Peer, rw p2p.MsgReadWriter, runLoop runLoo 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) + errC <- fmt.Errorf("exceeded rate limit by peer: %v", err) return } } diff --git a/waku/rate_limiter_test.go b/waku/rate_limiter_test.go index 96c7b7599..5d60acd83 100644 --- a/waku/rate_limiter_test.go +++ b/waku/rate_limiter_test.go @@ -100,7 +100,7 @@ func TestPeerLimiterHandler(t *testing.T) { close(done) }() - for i := 0; i < count; i += 1 { + for i := 0; i < count; i++ { err := rw1.WriteMsg(p2p.Msg{Code: 101}) require.NoError(t, err) } @@ -140,7 +140,7 @@ func TestPeerLimiterHandlerWithWhitelisting(t *testing.T) { close(done) }() - for i := 0; i < count; i += 1 { + for i := 0; i < count; i++ { err := rw1.WriteMsg(p2p.Msg{Code: 101}) require.NoError(t, err) } @@ -171,5 +171,5 @@ type mockRateLimiterHandler struct { exceedIPLimit int } -func (m *mockRateLimiterHandler) ExceedPeerLimit() error { m.exceedPeerLimit += 1; return nil } -func (m *mockRateLimiterHandler) ExceedIPLimit() error { m.exceedIPLimit += 1; return nil } +func (m *mockRateLimiterHandler) ExceedPeerLimit() error { m.exceedPeerLimit++; return nil } +func (m *mockRateLimiterHandler) ExceedIPLimit() error { m.exceedIPLimit++; return nil } diff --git a/waku/waku.go b/waku/waku.go index 51d172874..fa712d46d 100644 --- a/waku/waku.go +++ b/waku/waku.go @@ -26,7 +26,6 @@ import ( "fmt" "io" "io/ioutil" - "math" "runtime" "sync" "time" @@ -56,15 +55,18 @@ type Bridge interface { } type settings struct { - MaxMsgSize uint32 // Maximal message length allowed by the waku node - EnableConfirmations bool // Enable sending message confirmations - MinPow float64 // Minimal PoW required by the waku node - MinPowTolerance float64 // Minimal PoW tolerated by the waku node for a limited time - BloomFilter []byte // Bloom filter for topics of interest for this node - BloomFilterTolerance []byte // Bloom filter tolerated by the waku node for a limited time - LightClient bool // Light client mode enabled does not forward messages - RestrictLightClientsConn bool // Restrict connection between two light clients - SyncAllowance int // Maximum time in seconds allowed to process the waku-related messages + MaxMsgSize uint32 // Maximal message length allowed by the waku node + EnableConfirmations bool // Enable sending message confirmations + MinPow float64 // Minimal PoW required by the waku node + MinPowTolerance float64 // Minimal PoW tolerated by the waku node for a limited time + BloomFilter []byte // Bloom filter for topics of interest for this node + BloomFilterTolerance []byte // Bloom filter tolerated by the waku node for a limited time + TopicInterest map[TopicType]bool // Topic interest for this node + TopicInterestTolerance map[TopicType]bool // Topic interest tolerated by the waku node for a limited time + BloomFilterMode bool // Whether we should match against bloom-filter only + LightClient bool // Light client mode enabled does not forward messages + RestrictLightClientsConn bool // Restrict connection between two light clients + SyncAllowance int // Maximum time in seconds allowed to process the waku-related messages } // Waku represents a dark communication interface through the Ethereum @@ -136,6 +138,7 @@ func New(cfg *Config, logger *zap.Logger) *Waku { MinPowTolerance: cfg.MinimumAcceptedPoW, EnableConfirmations: cfg.EnableConfirmations, LightClient: cfg.LightClient, + BloomFilterMode: cfg.BloomFilterMode, RestrictLightClientsConn: cfg.RestrictLightClientsConn, SyncAllowance: DefaultSyncAllowance, } @@ -192,10 +195,14 @@ func (w *Waku) SetMinimumPoW(val float64, tolerate bool) error { if tolerate { go func() { // allow some time before all the peers have processed the notification - time.Sleep(time.Duration(w.settings.SyncAllowance) * time.Second) - w.settingsMu.Lock() - w.settings.MinPowTolerance = val - w.settingsMu.Unlock() + select { + case <-w.quit: + return + case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second): + w.settingsMu.Lock() + w.settings.MinPowTolerance = val + w.settingsMu.Unlock() + } }() } @@ -231,6 +238,13 @@ func (w *Waku) BloomFilterTolerance() []byte { return w.settings.BloomFilterTolerance } +// BloomFilterMode returns whether the node is running in bloom filter mode +func (w *Waku) BloomFilterMode() bool { + w.settingsMu.RLock() + defer w.settingsMu.RUnlock() + return w.settings.BloomFilterMode +} + // SetBloomFilter sets the new bloom filter func (w *Waku) SetBloomFilter(bloom []byte) error { if len(bloom) != BloomFilterSize { @@ -242,15 +256,90 @@ func (w *Waku) SetBloomFilter(bloom []byte) error { w.settingsMu.Lock() w.settings.BloomFilter = b + // Setting bloom filter reset topic interest + w.settings.TopicInterest = nil w.settingsMu.Unlock() w.notifyPeersAboutBloomFilterChange(b) go func() { // allow some time before all the peers have processed the notification - time.Sleep(time.Duration(w.settings.SyncAllowance) * time.Second) - w.settingsMu.Lock() - w.settings.BloomFilterTolerance = b - w.settingsMu.Unlock() + select { + case <-w.quit: + return + case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second): + w.settingsMu.Lock() + w.settings.BloomFilterTolerance = b + w.settingsMu.Unlock() + } + + }() + + return nil +} + +// TopicInterest returns the all the topics of interest. +// The nodes are required to send only messages that match the advertised topics. +// If a message does not match the topic-interest, it will tantamount to spam, and the peer will +// be disconnected. +func (w *Waku) TopicInterest() []TopicType { + w.settingsMu.RLock() + defer w.settingsMu.RUnlock() + if w.settings.TopicInterest == nil { + return nil + } + topicInterest := make([]TopicType, len(w.settings.TopicInterest)) + + i := 0 + for topic := range w.settings.TopicInterest { + topicInterest[i] = topic + i++ + } + return topicInterest +} + +// updateTopicInterest adds a new topic interest +// and informs the peers +func (w *Waku) updateTopicInterest(f *Filter) error { + newTopicInterest := w.TopicInterest() + for _, t := range f.Topics { + top := BytesToTopic(t) + newTopicInterest = append(newTopicInterest, top) + } + + return w.SetTopicInterest(newTopicInterest) +} + +// SetTopicInterest sets the new topicInterest +func (w *Waku) SetTopicInterest(topicInterest []TopicType) error { + var topicInterestMap map[TopicType]bool + if len(topicInterest) > MaxTopicInterest { + return fmt.Errorf("invalid topic interest: %d", len(topicInterest)) + } + + if topicInterest != nil { + topicInterestMap = make(map[TopicType]bool, len(topicInterest)) + for _, topic := range topicInterest { + topicInterestMap[topic] = true + } + } + + w.settingsMu.Lock() + w.settings.TopicInterest = topicInterestMap + // Setting topic interest resets bloom filter + w.settings.BloomFilter = nil + w.settingsMu.Unlock() + w.notifyPeersAboutTopicInterestChange(topicInterest) + + go func() { + // allow some time before all the peers have processed the notification + select { + case <-w.quit: + return + case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second): + w.settingsMu.Lock() + w.settings.TopicInterestTolerance = topicInterestMap + w.settingsMu.Unlock() + } }() return nil @@ -423,7 +512,21 @@ func (w *Waku) notifyPeersAboutBloomFilterChange(bloom []byte) { err = p.notifyAboutBloomFilterChange(bloom) } if err != nil { - w.logger.Warn("failed to notify peer about new pow requirement", zap.Binary("peer", p.ID()), zap.Error(err)) + w.logger.Warn("failed to notify peer about new bloom filter change", zap.Binary("peer", p.ID()), zap.Error(err)) + } + } +} + +func (w *Waku) notifyPeersAboutTopicInterestChange(topicInterest []TopicType) { + arr := w.getPeers() + for _, p := range arr { + err := p.notifyAboutTopicInterestChange(topicInterest) + if err != nil { + // allow one retry + err = p.notifyAboutTopicInterestChange(topicInterest) + } + if err != nil { + w.logger.Warn("failed to notify peer about new topic interest", zap.Binary("peer", p.ID()), zap.Error(err)) } } } @@ -639,7 +742,7 @@ func (w *Waku) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { // SelectKeyPair adds cryptographic identity, and makes sure // that it is the only private key known to the node. func (w *Waku) SelectKeyPair(key *ecdsa.PrivateKey) error { - id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize) + id, err := makeDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize) if err != nil { return err } @@ -816,15 +919,40 @@ func (w *Waku) GetSymKey(id string) ([]byte, error) { // and subsequent storing of incoming messages. func (w *Waku) Subscribe(f *Filter) (string, error) { s, err := w.filters.Install(f) - if err == nil { - w.updateBloomFilter(f) + if err != nil { + return s, err } - return s, err + + err = w.updateSettingsForFilter(f) + if err != nil { + w.filters.Uninstall(s) + return s, err + } + return s, nil +} + +func (w *Waku) updateSettingsForFilter(f *Filter) error { + w.settingsMu.RLock() + topicInterestMode := !w.settings.BloomFilterMode + w.settingsMu.RUnlock() + + if topicInterestMode { + err := w.updateTopicInterest(f) + if err != nil { + return err + } + } else { + err := w.updateBloomFilter(f) + if err != nil { + return err + } + } + return nil } // updateBloomFilter recalculates the new value of bloom filter, // and informs the peers if necessary. -func (w *Waku) updateBloomFilter(f *Filter) { +func (w *Waku) updateBloomFilter(f *Filter) error { aggregate := make([]byte, BloomFilterSize) for _, t := range f.Topics { top := BytesToTopic(t) @@ -835,8 +963,9 @@ func (w *Waku) updateBloomFilter(f *Filter) { if !BloomFilterMatch(w.BloomFilter(), aggregate) { // existing bloom filter must be updated aggregate = addBloom(w.BloomFilter(), aggregate) - w.SetBloomFilter(aggregate) + return w.SetBloomFilter(aggregate) } + return nil } // GetFilter returns the filter by id. @@ -845,6 +974,11 @@ func (w *Waku) GetFilter(id string) *Filter { } // Unsubscribe removes an installed message handler. +// TODO: This does not seem to update the bloom filter, nor topic-interest +// Note that the filter/topic-interest needs to take into account that there +// might be filters with duplicated topics, so it's not just a matter of removing +// from the map, in the topic-interest case, while the bloom filter might need to +// be rebuilt from scratch func (w *Waku) Unsubscribe(id string) error { ok := w.filters.Uninstall(id) if !ok { @@ -922,6 +1056,9 @@ func (w *Waku) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { func (w *Waku) sendConfirmation(rw p2p.MsgReadWriter, data []byte, envelopeErrors []EnvelopeError) (err error) { batchHash := crypto.Keccak256Hash(data) err = p2p.Send(rw, messageResponseCode, NewMessagesResponse(batchHash, envelopeErrors)) + if err != nil { + return + } err = p2p.Send(rw, batchAcknowledgedCode, batchHash) // DEPRECATED return } @@ -960,20 +1097,11 @@ func (w *Waku) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { logger.Warn("failed to handle batchAcknowledgedCode message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) return err } - case powRequirementCode: - if err := w.handlePowRequirementCode(p, packet, logger); err != nil { - logger.Warn("failed to handle powRequirementCode message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) + case statusUpdateCode: + if err := w.handleStatusUpdateCode(p, packet, logger); err != nil { + logger.Warn("failed to decode status update message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) return err } - case bloomFilterExCode: - if err := w.handleBloomFilterExCode(p, packet, logger); err != nil { - logger.Warn("failed to decode bloom filter exchange message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - return err - } - case rateLimitingCode: - if err := w.handleRateLimitingCode(p, packet, logger); err != nil { - logger.Warn("failed to decode rate limits, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) - } case p2pMessageCode: if err := w.handleP2PMessageCode(p, packet, logger); err != nil { logger.Warn("failed to decode direct message, peer will be disconnected", zap.Binary("peer", peerID[:]), zap.Error(err)) @@ -1006,13 +1134,13 @@ func (w *Waku) handleMessagesCode(p *Peer, rw p2p.MsgReadWriter, packet p2p.Msg, data, err := ioutil.ReadAll(packet.Payload) if err != nil { envelopesRejectedCounter.WithLabelValues("failed_read").Inc() - return fmt.Errorf("failed to read packet payload: %w", err) + return fmt.Errorf("failed to read packet payload: %v", err) } var envelopes []*Envelope if err := rlp.DecodeBytes(data, &envelopes); err != nil { envelopesRejectedCounter.WithLabelValues("invalid_data").Inc() - return fmt.Errorf("invalid payload: %w", err) + return fmt.Errorf("invalid payload: %v", err) } envelopeErrors := make([]EnvelopeError, 0) @@ -1040,7 +1168,7 @@ func (w *Waku) handleMessagesCode(p *Peer, rw p2p.MsgReadWriter, packet p2p.Msg, } if w.ConfirmationsEnabled() { - go w.sendConfirmation(rw, data, envelopeErrors) + go w.sendConfirmation(rw, data, envelopeErrors) // nolint: errcheck } if trouble { @@ -1049,45 +1177,16 @@ func (w *Waku) handleMessagesCode(p *Peer, rw p2p.MsgReadWriter, packet p2p.Msg, return nil } -func (w *Waku) handlePowRequirementCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - s := rlp.NewStream(packet.Payload, uint64(packet.Size)) - i, err := s.Uint() +func (w *Waku) handleStatusUpdateCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { + var statusOptions statusOptions + err := packet.Decode(&statusOptions) if err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_pow_req").Inc() - return fmt.Errorf("invalid powRequirementCode message: %w", err) - } - f := math.Float64frombits(i) - if math.IsInf(f, 0) || math.IsNaN(f) || f < 0.0 { - envelopesRejectedCounter.WithLabelValues("invalid_pow_req").Inc() - return errors.New("invalid value in powRequirementCode message") - } - p.powRequirement = f - return nil -} - -func (w *Waku) handleBloomFilterExCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - var bloom []byte - err := packet.Decode(&bloom) - if err == nil && len(bloom) != BloomFilterSize { - err = fmt.Errorf("wrong bloom filter size %d", len(bloom)) - } - if err != nil { - envelopesRejectedCounter.WithLabelValues("invalid_bloom").Inc() - return errors.New("invalid bloom filter exchange message") + logger.Error("failed to decode status-options", zap.Error(err)) + envelopesRejectedCounter.WithLabelValues("invalid_settings_changed").Inc() + return err } - p.setBloomFilter(bloom) - return nil -} - -func (w *Waku) handleRateLimitingCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { - var rateLimits RateLimits - if err := packet.Decode(&rateLimits); err != nil { - logger.Warn("invalid rate limits information", zap.Binary("peerID", p.peer.ID().Bytes()), zap.Error(err)) - return errors.New("invalid rate limits exchange message") - } - p.setRateLimits(rateLimits) - return nil + return p.setOptions(statusOptions) } func (w *Waku) handleP2PMessageCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { @@ -1105,7 +1204,7 @@ func (w *Waku) handleP2PMessageCode(p *Peer, packet p2p.Msg, logger *zap.Logger) ) if err = packet.Decode(&envelopes); err != nil { - return fmt.Errorf("invalid direct message payload: %w", err) + return fmt.Errorf("invalid direct message payload: %v", err) } for _, envelope := range envelopes { @@ -1125,7 +1224,7 @@ func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger) // Read all data as we will try to decode it possibly twice. data, err := ioutil.ReadAll(packet.Payload) if err != nil { - return fmt.Errorf("invalid p2p request messages: %w", err) + return fmt.Errorf("invalid p2p request messages: %v", err) } r := bytes.NewReader(data) packet.Payload = r @@ -1135,14 +1234,13 @@ func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger) if errDepReq == nil { w.mailServer.DeliverMail(p.ID(), &requestDeprecated) return nil - } 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)) // As we failed to decode the request, let's set the offset // to the beginning and try decode it again. if _, err := r.Seek(0, io.SeekStart); err != nil { - return fmt.Errorf("invalid p2p request message: %w", err) + return fmt.Errorf("invalid p2p request message: %v", err) } var request MessagesRequest @@ -1150,9 +1248,8 @@ func (w *Waku) handleP2PRequestCode(p *Peer, packet p2p.Msg, logger *zap.Logger) if errReq == nil { w.mailServer.Deliver(p.ID(), request) return nil - } 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)) return errors.New("invalid p2p request message") } @@ -1164,12 +1261,12 @@ func (w *Waku) handleP2PRequestCompleteCode(p *Peer, packet p2p.Msg, logger *zap var payload []byte if err := packet.Decode(&payload); err != nil { - return fmt.Errorf("invalid p2p request complete message: %w", err) + return fmt.Errorf("invalid p2p request complete message: %v", err) } event, err := CreateMailServerEvent(p.peer.ID(), payload) if err != nil { - return fmt.Errorf("invalid p2p request complete payload: %w", err) + return fmt.Errorf("invalid p2p request complete payload: %v", err) } w.postP2P(*event) @@ -1180,7 +1277,7 @@ func (w *Waku) handleMessageResponseCode(p *Peer, packet p2p.Msg, logger *zap.Lo var resp MultiVersionResponse if err := packet.Decode(&resp); err != nil { envelopesRejectedCounter.WithLabelValues("failed_read").Inc() - return fmt.Errorf("invalid response message: %w", err) + return fmt.Errorf("invalid response message: %v", err) } if resp.Version != 1 { logger.Info("received unsupported version of MultiVersionResponse for messageResponseCode packet", zap.Uint("version", resp.Version)) @@ -1190,7 +1287,7 @@ func (w *Waku) handleMessageResponseCode(p *Peer, packet p2p.Msg, logger *zap.Lo response, err := resp.DecodeResponse1() if err != nil { envelopesRejectedCounter.WithLabelValues("invalid_data").Inc() - return fmt.Errorf("failed to decode response message: %w", err) + return fmt.Errorf("failed to decode response message: %v", err) } w.envelopeFeed.Send(EnvelopeEvent{ @@ -1206,7 +1303,7 @@ func (w *Waku) handleMessageResponseCode(p *Peer, packet p2p.Msg, logger *zap.Lo func (w *Waku) handleBatchAcknowledgeCode(p *Peer, packet p2p.Msg, logger *zap.Logger) error { var batchHash common.Hash if err := packet.Decode(&batchHash); err != nil { - return fmt.Errorf("invalid batch ack message: %w", err) + return fmt.Errorf("invalid batch ack message: %v", err) } w.envelopeFeed.Send(EnvelopeEvent{ Batch: batchHash, @@ -1220,6 +1317,62 @@ func (w *Waku) add(envelope *Envelope, isP2P bool) (bool, error) { return w.addAndBridge(envelope, isP2P, false) } +func (w *Waku) bloomMatch(envelope *Envelope) (bool, error) { + if !BloomFilterMatch(w.BloomFilter(), envelope.Bloom()) { + // maybe the value was recently changed, and the peers did not adjust yet. + // in this case the previous value is retrieved by BloomFilterTolerance() + // for a short period of peer synchronization. + if !BloomFilterMatch(w.BloomFilterTolerance(), envelope.Bloom()) { + envelopesCacheFailedCounter.WithLabelValues("no_bloom_match").Inc() + return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", + envelope.Hash().Hex(), w.BloomFilter(), envelope.Bloom(), envelope.Topic) + } + } + return true, nil +} + +func (w *Waku) topicInterestMatch(envelope *Envelope) (bool, error) { + w.settingsMu.RLock() + defer w.settingsMu.RUnlock() + if w.settings.TopicInterest == nil { + return false, nil + } + if !w.settings.TopicInterest[envelope.Topic] { + if !w.settings.TopicInterestTolerance[envelope.Topic] { + envelopesCacheFailedCounter.WithLabelValues("no_topic_interest_match").Inc() + return false, fmt.Errorf("envelope does not match topic interest, hash=[%v], bloom: \n%x \n%x", + envelope.Hash().Hex(), envelope.Bloom(), envelope.Topic) + + } + } + + return true, nil +} + +func (w *Waku) topicInterestOrBloomMatch(envelope *Envelope) (bool, error) { + w.settingsMu.RLock() + topicInterestMode := !w.settings.BloomFilterMode + w.settingsMu.RUnlock() + + if topicInterestMode { + match, err := w.topicInterestMatch(envelope) + if err != nil { + return false, err + } + if match { + return true, nil + } + } + return w.bloomMatch(envelope) +} + +func (w *Waku) SetBloomFilterMode(mode bool) { + w.settingsMu.Lock() + w.settings.BloomFilterMode = mode + w.settingsMu.Unlock() + // Recalculate and notify topic interest or bloom, currently not implemented +} + // addAndBridge inserts a new envelope into the message pool to be distributed within the // waku network. It also inserts the envelope into the expiration pool at the // appropriate time-stamp. In case of error, connection should be dropped. @@ -1252,7 +1405,7 @@ func (w *Waku) addAndBridge(envelope *Envelope, isP2P bool, bridged bool) (bool, if uint32(envelope.size()) > w.MaxMessageSize() { envelopesCacheFailedCounter.WithLabelValues("oversized").Inc() - return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) + return false, fmt.Errorf("huge messages are not allowed [%x][%d][%d]", envelope.Hash(), envelope.size(), w.MaxMessageSize()) } if envelope.PoW() < w.MinPow() { @@ -1265,15 +1418,13 @@ func (w *Waku) addAndBridge(envelope *Envelope, isP2P bool, bridged bool) (bool, } } - if !BloomFilterMatch(w.BloomFilter(), envelope.Bloom()) { - // maybe the value was recently changed, and the peers did not adjust yet. - // in this case the previous value is retrieved by BloomFilterTolerance() - // for a short period of peer synchronization. - if !BloomFilterMatch(w.BloomFilterTolerance(), envelope.Bloom()) { - envelopesCacheFailedCounter.WithLabelValues("no_bloom_match").Inc() - return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", - envelope.Hash().Hex(), w.BloomFilter(), envelope.Bloom(), envelope.Topic) - } + match, err := w.topicInterestOrBloomMatch(envelope) + if err != nil { + return false, err + } + + if !match { + return false, nil } hash := envelope.Hash() @@ -1414,6 +1565,31 @@ func (w *Waku) expire() { } } +func (w *Waku) toStatusOptions() statusOptions { + opts := statusOptions{} + + rateLimits := w.RateLimits() + opts.RateLimits = &rateLimits + + lightNode := w.LightClientMode() + opts.LightNodeEnabled = &lightNode + + minPoW := w.MinPow() + opts.SetPoWRequirementFromF(minPoW) + + confirmationsEnabled := w.ConfirmationsEnabled() + opts.ConfirmationsEnabled = &confirmationsEnabled + + bloomFilterMode := w.BloomFilterMode() + if bloomFilterMode { + opts.BloomFilter = w.BloomFilter() + } else { + opts.TopicInterest = w.TopicInterest() + } + + return opts +} + // Envelopes retrieves all the messages currently pooled by the node. func (w *Waku) Envelopes() []*Envelope { w.poolMu.RLock() diff --git a/waku/waku_test.go b/waku/waku_test.go index 5b75822f3..cfc66d3d3 100644 --- a/waku/waku_test.go +++ b/waku/waku_test.go @@ -30,7 +30,6 @@ import ( "go.uber.org/zap" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "golang.org/x/crypto/pbkdf2" @@ -65,7 +64,7 @@ func TestBasic(t *testing.T) { } peerID := make([]byte, 64) - mrand.Read(peerID) + mrand.Read(peerID) // nolint: gosec peer, _ := w.getPeer(peerID) if peer != nil { t.Fatal("found peer for random key.") @@ -278,10 +277,9 @@ func TestSymKeyManagement(t *testing.T) { var err error var k1, k2 []byte w := New(nil, nil) - id1 := string("arbitrary-string-1") id2 := string("arbitrary-string-2") - id1, err = w.GenerateSymKey() + id1, err := w.GenerateSymKey() if err != nil { t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err) } @@ -309,7 +307,7 @@ func TestSymKeyManagement(t *testing.T) { // add existing id, nothing should change randomKey := make([]byte, aesKeyLength) - mrand.Read(randomKey) + mrand.Read(randomKey) // nolint: gosec id1, err = w.AddSymKeyDirect(randomKey) if err != nil { t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err) @@ -428,7 +426,7 @@ func TestSymKeyManagement(t *testing.T) { } randomKey = make([]byte, aesKeyLength+1) - mrand.Read(randomKey) + mrand.Read(randomKey) // nolint: gosec _, err = w.AddSymKeyDirect(randomKey) if err == nil { t.Fatalf("added the key with wrong size, seed %d.", seed) @@ -469,10 +467,17 @@ func TestExpiry(t *testing.T) { InitSingleTest() w := New(nil, nil) - _ = w.SetMinimumPoW(0.0000001, false) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - _ = w.Start(nil) - defer w.Stop() + err := w.SetMinimumPoW(0.0000001, false) + if err != nil { + t.Fatal("failed to set min pow") + } + + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + err = w.Start(nil) + if err != nil { + t.Fatal("failed to start waku") + } + defer w.Stop() // nolint: errcheck params, err := generateMessageParams() if err != nil { @@ -533,10 +538,12 @@ func TestCustomization(t *testing.T) { InitSingleTest() w := New(nil, nil) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start(nil) - defer w.Stop() + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + defer w.SetMaxMessageSize(DefaultMaxMessageSize) // nolint: errcheck + if err := w.Start(nil); err != nil { + t.Fatal("failed to start node") + } + defer w.Stop() // nolint: errcheck const smallPoW = 0.00001 @@ -624,10 +631,104 @@ func TestSymmetricSendCycle(t *testing.T) { InitSingleTest() w := New(nil, nil) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - _ = w.Start(nil) - defer w.Stop() + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + defer w.SetMaxMessageSize(DefaultMaxMessageSize) // nolint: errcheck + err := w.Start(nil) + if err != nil { + t.Fatal("failed to start node") + } + defer w.Stop() // nolint: errcheck + + filter1, err := generateFilter(t, true) + if err != nil { + t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) + } + filter1.PoW = DefaultMinimumPoW + + // Copy the first filter since some of its fields + // are randomly generated. + filter2 := &Filter{ + KeySym: filter1.KeySym, + Topics: filter1.Topics, + PoW: filter1.PoW, + AllowP2P: filter1.AllowP2P, + Messages: NewMemoryMessageStore(), + } + + params, err := generateMessageParams() + if err != nil { + t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) + } + + filter1.Src = ¶ms.Src.PublicKey + filter2.Src = ¶ms.Src.PublicKey + + params.KeySym = filter1.KeySym + params.Topic = BytesToTopic(filter1.Topics[2]) + params.PoW = filter1.PoW + params.WorkTime = 10 + params.TTL = 50 + msg, err := NewSentMessage(params) + if err != nil { + t.Fatalf("failed to create new message with seed %d: %s.", seed, err) + } + env, err := msg.Wrap(params, time.Now()) + if err != nil { + t.Fatalf("failed Wrap with seed %d: %s.", seed, err) + } + + _, err = w.Subscribe(filter1) + if err != nil { + t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err) + } + + _, err = w.Subscribe(filter2) + if err != nil { + t.Fatalf("failed subscribe 2 with seed %d: %s.", seed, err) + } + + err = w.Send(env) + if err != nil { + t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err) + } + + // wait till received or timeout + var received bool + for j := 0; j < 200; j++ { + time.Sleep(10 * time.Millisecond) + if len(w.Envelopes()) > 0 { + received = true + break + } + } + + if !received { + t.Fatalf("did not receive the sent envelope, seed: %d.", seed) + } + + // check w.messages() + time.Sleep(5 * time.Millisecond) + mail1 := filter1.Retrieve() + mail2 := filter2.Retrieve() + if len(mail2) == 0 { + t.Fatalf("did not receive any email for filter 2") + } + if len(mail1) == 0 { + t.Fatalf("did not receive any email for filter 1") + } + +} + +func TestSymmetricSendCycleWithTopicInterest(t *testing.T) { + InitSingleTest() + + w := New(nil, nil) + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + defer w.SetMaxMessageSize(DefaultMaxMessageSize) // nolint: errcheck + if err := w.Start(nil); err != nil { + t.Fatal("could not start node") + } + defer w.Stop() // nolint: errcheck filter1, err := generateFilter(t, true) if err != nil { @@ -713,10 +814,10 @@ func TestSymmetricSendWithoutAKey(t *testing.T) { InitSingleTest() w := New(nil, nil) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start(nil) - defer w.Stop() + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + defer w.SetMaxMessageSize(DefaultMaxMessageSize) // nolint: errcheck + w.Start(nil) // nolint: errcheck + defer w.Stop() // nolint: errcheck filter, err := generateFilter(t, true) if err != nil { @@ -781,10 +882,10 @@ func TestSymmetricSendKeyMismatch(t *testing.T) { InitSingleTest() w := New(nil, nil) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start(nil) - defer w.Stop() + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + defer w.SetMaxMessageSize(DefaultMaxMessageSize) // nolint: errcheck + w.Start(nil) // nolint: errcheck + defer w.Stop() // nolint: errcheck filter, err := generateFilter(t, true) if err != nil { @@ -854,11 +955,11 @@ func TestBloom(t *testing.T) { t.Fatalf("bloom filter does not match the mask") } - _, err := mrand.Read(b) + _, err := mrand.Read(b) // nolint: gosec if err != nil { t.Fatalf("math rand error") } - _, err = mrand.Read(x) + _, err = mrand.Read(x) // nolint: gosec if err != nil { t.Fatalf("math rand error") } @@ -904,14 +1005,53 @@ func TestBloom(t *testing.T) { } } +func TestTopicInterest(t *testing.T) { + w := New(nil, nil) + topicInterest := w.TopicInterest() + if topicInterest != nil { + t.Fatalf("wrong topic on creation") + } + + filter1, err := generateFilter(t, true) + if err != nil { + t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) + } + + _, err = w.Subscribe(filter1) + if err != nil { + t.Fatalf("failed subscribe with seed %d: %s.", seed, err) + } + + topicInterest = w.TopicInterest() + if len(topicInterest) != len(filter1.Topics) { + t.Fatalf("wrong number of topics created") + } + + filter2, err := generateFilter(t, true) + if err != nil { + t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) + } + + _, err = w.Subscribe(filter2) + if err != nil { + t.Fatalf("failed subscribe with seed %d: %s.", seed, err) + } + + topicInterest = w.TopicInterest() + if len(topicInterest) != len(filter1.Topics)+len(filter2.Topics) { + t.Fatalf("wrong number of topics created") + } + +} + func TestSendP2PDirect(t *testing.T) { InitSingleTest() w := New(nil, nil) - _ = w.SetMinimumPoW(0.0000001, false) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - _ = w.Start(nil) - defer w.Stop() + _ = w.SetMinimumPoW(0.0000001, false) // nolint: errcheck + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + _ = w.Start(nil) // nolint: errcheck + defer w.Stop() // nolint: errcheck rwStub := &rwP2PMessagesStub{} peerW := newPeer(w, p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), rwStub, nil) @@ -954,10 +1094,10 @@ func TestHandleP2PMessageCode(t *testing.T) { InitSingleTest() w := New(nil, nil) - w.SetMinimumPoW(0.0000001, false) - defer w.SetMinimumPoW(DefaultMinimumPoW, false) - w.Start(nil) - defer w.Stop() + w.SetMinimumPoW(0.0000001, false) // nolint: errcheck + defer w.SetMinimumPoW(DefaultMinimumPoW, false) // nolint: errcheck + w.Start(nil) // nolint: errcheck + defer w.Stop() // nolint: errcheck envelopeEvents := make(chan EnvelopeEvent, 10) sub := w.SubscribeEnvelopeEvents(envelopeEvents) @@ -1058,11 +1198,7 @@ func testConfirmationsHandshake(t *testing.T, expectConfirmations bool) { statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - LightNodeEnabled: false, - ConfirmationsEnabled: expectConfirmations, - }, + w.toStatusOptions(), }, ), ) @@ -1100,6 +1236,9 @@ func TestConfirmationReceived(t *testing.T) { rw1.Close() } }() + pow := math.Float64bits(w.MinPow()) + confirmationsEnabled := true + lightNodeEnabled := true require.NoError( t, p2p.ExpectMsg( @@ -1107,11 +1246,7 @@ func TestConfirmationReceived(t *testing.T) { statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - }, + w.toStatusOptions(), }, ), ) @@ -1122,10 +1257,10 @@ func TestConfirmationReceived(t *testing.T) { statusCode, ProtocolVersion, statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), + PoWRequirement: &pow, BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - LightNodeEnabled: true, + ConfirmationsEnabled: &confirmationsEnabled, + LightNodeEnabled: &lightNodeEnabled, }, ), ) @@ -1163,6 +1298,10 @@ func TestMessagesResponseWithError(t *testing.T) { err := w.HandlePeer(p, rw2) errorc <- err }() + + pow := math.Float64bits(w.MinPow()) + confirmationsEnabled := true + lightNodeEnabled := true require.NoError( t, p2p.ExpectMsg( @@ -1170,11 +1309,7 @@ func TestMessagesResponseWithError(t *testing.T) { statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - }, + w.toStatusOptions(), }, ), ) @@ -1185,10 +1320,10 @@ func TestMessagesResponseWithError(t *testing.T) { statusCode, ProtocolVersion, statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), + PoWRequirement: &pow, BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - LightNodeEnabled: true, + ConfirmationsEnabled: &confirmationsEnabled, + LightNodeEnabled: &lightNodeEnabled, }, ), ) @@ -1239,16 +1374,17 @@ func testConfirmationEvents(t *testing.T, envelope Envelope, envelopeErrors []En time.AfterFunc(5*time.Second, func() { rw1.Close() }) + + pow := math.Float64bits(w.MinPow()) + confirmationsEnabled := true + lightNodeEnabled := true + require.NoError(t, p2p.ExpectMsg( rw1, statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - }, + w.toStatusOptions(), }, )) require.NoError(t, p2p.SendItems( @@ -1256,10 +1392,10 @@ func testConfirmationEvents(t *testing.T, envelope Envelope, envelopeErrors []En statusCode, ProtocolVersion, statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), + PoWRequirement: &pow, BloomFilter: w.BloomFilter(), - ConfirmationsEnabled: true, - LightNodeEnabled: true, + ConfirmationsEnabled: &confirmationsEnabled, + LightNodeEnabled: &lightNodeEnabled, }, )) require.NoError(t, w.Send(&envelope)) @@ -1336,6 +1472,10 @@ func TestEventsWithoutConfirmation(t *testing.T) { time.AfterFunc(5*time.Second, func() { rw1.Close() }) + + pow := math.Float64bits(w.MinPow()) + lightNodeEnabled := true + require.NoError( t, p2p.ExpectMsg( @@ -1343,10 +1483,7 @@ func TestEventsWithoutConfirmation(t *testing.T) { statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - BloomFilter: w.BloomFilter(), - }, + w.toStatusOptions(), }, ), ) @@ -1357,9 +1494,9 @@ func TestEventsWithoutConfirmation(t *testing.T) { statusCode, ProtocolVersion, statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), + PoWRequirement: &pow, BloomFilter: w.BloomFilter(), - LightNodeEnabled: true, + LightNodeEnabled: &lightNodeEnabled, }, ), ) @@ -1392,7 +1529,7 @@ func discardPipe() *p2p.MsgPipeRW { if err != nil { return } - msg.Discard() + msg.Discard() // nolint: errcheck } }() return rw2 @@ -1413,7 +1550,7 @@ func TestWakuTimeDesyncEnvelopeIgnored(t *testing.T) { w1, w2 := New(c, nil), New(c, nil) errc := make(chan error) go func() { - w1.HandlePeer(p2, rw2) + w1.HandlePeer(p2, rw2) // nolint: errcheck }() go func() { errc <- w2.HandlePeer(p1, rw1) @@ -1519,7 +1656,9 @@ func TestRateLimiterIntegration(t *testing.T) { go func() { err := w.HandlePeer(p, rw2) errorc <- err + }() + require.NoError( t, p2p.ExpectMsg( @@ -1527,14 +1666,7 @@ func TestRateLimiterIntegration(t *testing.T) { statusCode, []interface{}{ ProtocolVersion, - statusOptions{ - PoWRequirement: math.Float64bits(w.MinPow()), - BloomFilter: w.BloomFilter(), - RateLimits: RateLimits{ - IPLimits: 10, - PeerIDLimits: 5, - }, - }, + w.toStatusOptions(), }, ), ) @@ -1545,32 +1677,10 @@ func TestRateLimiterIntegration(t *testing.T) { } } -type stubMailServer struct{} - -func (stubMailServer) Archive(*Envelope) {} -func (stubMailServer) DeliverMail(*Peer, *Envelope) {} -func (stubMailServer) Deliver(*Peer, MessagesRequest) {} - -type mockMailServer struct { - mock.Mock -} - -func (m *mockMailServer) Archive(env *Envelope) { - m.Called(env) -} - -func (m *mockMailServer) DeliverMail(p *Peer, env *Envelope) { - m.Called(p, env) -} - -func (m *mockMailServer) Deliver(p *Peer, r MessagesRequest) { - m.Called(p, r) -} - func TestMailserverCompletionEvent(t *testing.T) { w := New(nil, nil) require.NoError(t, w.Start(nil)) - defer w.Stop() + defer w.Stop() // nolint: errcheck rw1, rw2 := p2p.MsgPipe() peer := newPeer(w, p2p.NewPeer(enode.ID{1}, "1", nil), rw1, nil) diff --git a/whisper/events.go b/whisper/events.go index 3e2c41795..18a6a6a78 100644 --- a/whisper/events.go +++ b/whisper/events.go @@ -17,8 +17,8 @@ const ( // 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" + // EventBatchAcknowledged is sent when batch of envelopes was acknowledged by a peer. + EventBatchAcknowledged EventType = "batch.acknowledged" // EventEnvelopeAvailable fires when envelop is available for filters EventEnvelopeAvailable EventType = "envelope.available" // EventMailServerRequestSent fires when such request is sent. diff --git a/whisper/filter.go b/whisper/filter.go index 9bdc7742c..21681c0d9 100644 --- a/whisper/filter.go +++ b/whisper/filter.go @@ -55,7 +55,7 @@ func (store *MemoryMessageStore) Add(msg *ReceivedMessage) error { return nil } -// Pop returns all avaiable messages and cleans the store. +// Pop returns all available messages and cleans the store. func (store *MemoryMessageStore) Pop() ([]*ReceivedMessage, error) { store.mu.Lock() defer store.mu.Unlock() diff --git a/whisper/peer_test.go b/whisper/peer_test.go index 26cda40b2..a0d06e39d 100644 --- a/whisper/peer_test.go +++ b/whisper/peer_test.go @@ -221,9 +221,9 @@ func initialize(t *testing.T) { for i := 0; i < NumNodes; i++ { for j := 0; j < i; j++ { - peerNodeId := nodes[j].id + peerNodeID := nodes[j].id address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr) - peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, address.Port, address.Port) + peer := enode.NewV4(&peerNodeID.PublicKey, address.IP, address.Port, address.Port) nodes[i].server.AddPeer(peer) } } diff --git a/whisper/rate_limiter.go b/whisper/rate_limiter.go index 02a1f302e..a591e0dbc 100644 --- a/whisper/rate_limiter.go +++ b/whisper/rate_limiter.go @@ -125,7 +125,7 @@ func (r *PeerRateLimiter) decorate(p *Peer, rw p2p.MsgReadWriter, runLoop runLoo 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) + errC <- fmt.Errorf("exceed rate limit by IP: %v", err) return } } @@ -138,7 +138,7 @@ func (r *PeerRateLimiter) decorate(p *Peer, rw p2p.MsgReadWriter, runLoop runLoo 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) + errC <- fmt.Errorf("exceeded rate limit by peer: %v", err) return } } diff --git a/whisper/rate_limiter_test.go b/whisper/rate_limiter_test.go index e6ec3f75a..fba398c03 100644 --- a/whisper/rate_limiter_test.go +++ b/whisper/rate_limiter_test.go @@ -83,7 +83,7 @@ func TestPeerLimiterHandler(t *testing.T) { close(done) }() - for i := 0; i < count; i += 1 { + for i := 0; i < count; i++ { err := rw1.WriteMsg(p2p.Msg{Code: 101}) require.NoError(t, err) } @@ -123,7 +123,7 @@ func TestPeerLimiterHandlerWithWhitelisting(t *testing.T) { close(done) }() - for i := 0; i < count; i += 1 { + for i := 0; i < count; i++ { err := rw1.WriteMsg(p2p.Msg{Code: 101}) require.NoError(t, err) } @@ -154,5 +154,5 @@ type mockRateLimiterHandler struct { exceedIPLimit int } -func (m *mockRateLimiterHandler) ExceedPeerLimit() error { m.exceedPeerLimit += 1; return nil } -func (m *mockRateLimiterHandler) ExceedIPLimit() error { m.exceedIPLimit += 1; return nil } +func (m *mockRateLimiterHandler) ExceedPeerLimit() error { m.exceedPeerLimit++; return nil } +func (m *mockRateLimiterHandler) ExceedIPLimit() error { m.exceedIPLimit++; return nil } diff --git a/whisper/whisper_test.go b/whisper/whisper_test.go index 3416c8757..fe3754f55 100644 --- a/whisper/whisper_test.go +++ b/whisper/whisper_test.go @@ -274,7 +274,6 @@ func TestWhisperSymKeyManagement(t *testing.T) { var err error var k1, k2 []byte w := New(&DefaultConfig) - id1 := string("arbitrary-string-1") id2 := string("arbitrary-string-2") id1, err = w.GenerateSymKey()