Move to protobuf for Message type (#1706)

* Use a single Message type `v1/message.go` and `message.go` are the same now, and they embed `protobuf.ChatMessage`

* Use `SendChatMessage` for sending chat messages, this is basically the old `Send` but a bit more flexible so we can send different message types (stickers,commands), and not just text.

* Remove dedup from services/shhext. Because now we process in status-protocol, dedup makes less sense, as those messages are going to be processed anyway, so removing for now, we can re-evaluate if bringing it to status-go or not.

* Change the various retrieveX method to a single one:
`RetrieveAll` will be processing those messages that it can process (Currently only `Message`), and return the rest in `RawMessages` (still transit). The format for the response is:
`Chats`: -> The chats updated by receiving the message
`Messages`: -> The messages retrieved (already matched to a chat)
`Contacts`: -> The contacts updated by the messages
`RawMessages` -> Anything else that can't be parsed, eventually as we move everything to status-protocol-go this will go away.
This commit is contained in:
Andrea Maria Piana 2019-12-05 17:25:34 +01:00 committed by GitHub
parent 429d2b4291
commit fd49b0140e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
113 changed files with 5480 additions and 3453 deletions

View file

@ -1 +1 @@
0.35.0 0.36.0

View file

@ -1,7 +1,7 @@
// Code generated by go-bindata. DO NOT EDIT. // Code generated by go-bindata. DO NOT EDIT.
// sources: // sources:
// 0001_app.down.sql (387B) // 0001_app.down.sql (387B)
// 0001_app.up.sql (2.876kB) // 0001_app.up.sql (2.951kB)
// doc.go (74B) // doc.go (74B)
package migrations package migrations
@ -86,12 +86,12 @@ func _0001_appDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "0001_app.down.sql", size: 387, mode: os.FileMode(0644), modTime: time.Unix(1567701212, 0)} info := bindataFileInfo{name: "0001_app.down.sql", size: 387, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbc, 0x9c, 0xd2, 0xe1, 0x1d, 0x8, 0x34, 0x6a, 0xc8, 0x37, 0x13, 0xb3, 0x9f, 0x26, 0x23, 0x33, 0xd4, 0x25, 0x8, 0xed, 0x53, 0xe6, 0xd, 0x46, 0xc9, 0xf4, 0x24, 0xf8, 0x1, 0x1f, 0xf5, 0xc8}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbc, 0x9c, 0xd2, 0xe1, 0x1d, 0x8, 0x34, 0x6a, 0xc8, 0x37, 0x13, 0xb3, 0x9f, 0x26, 0x23, 0x33, 0xd4, 0x25, 0x8, 0xed, 0x53, 0xe6, 0xd, 0x46, 0xc9, 0xf4, 0x24, 0xf8, 0x1, 0x1f, 0xf5, 0xc8}}
return a, nil return a, nil
} }
var __0001_appUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\x4d\x93\xaa\x38\x14\xdd\xf3\x2b\xb2\xd4\x2a\x36\xb3\x7e\x2b\xd4\x68\x53\xc3\xc0\x0c\xe2\x74\xbf\x55\x2a\x42\x44\x4a\x20\xbc\x24\xb6\xed\xbf\x9f\xca\x17\xa0\x02\xb6\xf3\x76\x24\xf7\xe6\x78\xce\xb9\x37\x37\x2e\x63\xe8\x25\x10\x24\xde\x22\x80\xc0\x5f\x83\x30\x4a\x00\xfc\xf0\xb7\xc9\x16\x70\x22\x44\x51\xe7\x1c\xcc\x1c\x71\x6d\x08\xf8\xd7\x8b\x97\x6f\x5e\x0c\xfe\x8e\xfd\xbf\xbc\xf8\x27\xf8\x13\xfe\x74\x9d\x4f\x5c\x9e\x09\x58\x04\xd1\xc2\x99\x83\x77\x3f\x79\x8b\x76\x09\x88\xa3\x77\x7f\xf5\xc3\x71\x26\xc0\x71\x9a\xd2\x73\x2d\x24\x38\xce\x32\x46\x38\x1f\xc6\xbf\xe0\xb2\x24\x02\x2c\xa2\x28\x80\x5e\xe8\x3a\xe9\x11\xf7\x56\x8a\x57\x02\x3f\x12\xd7\xe1\x82\x32\x9c\xdb\x55\x73\xde\x9f\xc8\x55\xf1\x72\x9d\x06\x8b\xa3\xd9\xaf\x71\x65\x53\x52\x5a\x52\xa6\xbe\xc7\x99\xef\x42\xff\x9f\x1d\x04\x7e\xb8\x82\x1f\xe0\x5c\x17\xbf\xce\x04\x69\x46\xc8\xb2\x8e\xc2\x9e\x16\x1d\x9b\x83\xf7\x37\x18\xc3\x76\xf9\x63\x0a\x4e\x0a\x1a\x06\x93\x91\x16\x4a\x2d\xa6\x2d\xdd\x33\x7a\xe1\x84\x49\x4b\x8b\x4c\x09\xbb\xb5\xb2\xd5\xae\x0e\x85\xbb\x20\x70\x1d\x51\x54\x84\x0b\x5c\x35\x60\xb7\xdd\xf8\x9b\x10\xae\xc0\xc2\xdf\xf8\x61\xe2\x3a\x19\x6e\x1a\xeb\x34\x58\xc1\xb5\xb7\x0b\x12\x70\xc0\x25\x27\xae\x73\x2c\xa4\xdd\x57\xbf\xce\xc8\x17\xd8\x85\x5b\x7d\xd2\x0f\x27\xac\x9c\x62\x8c\x0c\x1e\x98\x39\x66\x0b\x59\x05\x1d\x55\x9b\xa3\xab\xb7\x8e\x62\xe8\x6f\x42\xa9\x6c\xd6\x9d\x99\x83\x18\xae\x61\x0c\xc3\x25\xec\xd0\x67\x72\x3f\x92\x1a\x02\x98\x40\xb0\xf4\xb6\x4b\x6f\x05\x9d\x27\x6e\x4a\xf9\xd2\xca\xce\xb5\x9e\x99\xaf\xc9\x6c\x08\xab\x0a\xce\x0b\x5a\x4b\x40\x09\x8c\x86\x6a\xd1\xa5\xdd\x47\xfa\x62\xdb\xe3\x37\x5a\x15\xdb\x99\xde\x1e\x96\x3a\x45\x50\x30\x5c\xf3\x83\x6e\x9d\x9a\x88\x0b\x65\x27\x59\x80\xb6\xb0\xba\x25\xfa\xb5\xc0\xfc\xd8\xde\xd7\x6e\xfb\xfe\x26\x77\x91\x7d\x79\x42\x23\x87\xc4\x97\xb9\xa6\x9c\xd4\x19\x61\x03\x19\x8c\xa4\xa4\x68\x84\x49\x2b\x69\x6e\xbe\x6e\xa6\xd2\xb0\x5b\x9d\x1a\xd7\x52\xb8\xed\x91\x92\xa6\x27\xde\x4f\xd3\x29\x0f\x1e\xba\xce\x32\x0a\xb7\x49\xec\x49\x23\xcc\xd5\xb5\xb6\xa1\x86\x30\x7b\x85\xd5\xb7\x81\xb3\xf7\x7d\x26\x31\x5d\x93\xe0\x76\xbf\x35\x7f\xd6\x83\x9a\xdd\x6f\x16\xa5\x3e\x57\x7b\xc2\x1e\xd3\x7b\x57\x7f\x1c\x92\xe0\x4c\xcd\x80\x76\x00\xac\xbd\x60\x3b\x68\x86\xe2\x3a\xa8\xfe\xde\xdc\xd1\xc3\x9a\xe9\x33\x0c\x9d\xf5\xd4\x3b\x3b\x47\x91\xa0\xe8\x35\x1f\xa7\xbb\x78\xcc\x4e\x7e\xad\x53\xa0\x06\xe7\x44\xff\x19\xee\xd3\x1d\x68\x93\xbe\xd5\x83\x15\x6e\x9a\xa2\xce\xd1\x81\x32\x64\x24\xb7\x8a\x07\x9d\xb4\x6d\xd8\xd1\x79\xa5\x23\x2b\x5c\x94\x9c\xb0\x4f\x3d\x2b\x00\x00\xa0\xc8\x86\x1f\x6e\x19\x53\x53\xee\xd1\x46\x19\x1a\x37\x59\x46\x1b\xcc\xf9\x85\xb2\x16\x5a\xef\x1e\x4a\x42\xc4\xc3\x89\xd7\x66\x71\x27\x00\x31\xf2\xeb\x4c\xb8\x40\x39\x6e\xac\x98\x1c\x37\xe8\xc0\x68\x75\xf3\xa6\xc1\x0d\xbc\xe7\x27\xf3\x04\x7d\x96\x35\xf8\x0a\xcb\x80\x7a\xf3\xef\x5f\xb8\x71\x1d\xfa\xff\xc2\x08\x73\x64\xc0\x50\x91\x7d\xc9\x96\x19\x15\x68\xf2\xbe\x5d\x60\x24\x68\x53\xa4\xd6\x19\xb5\x18\xaf\xb4\x01\xe7\xb7\x05\x2b\x31\x17\x96\x45\xeb\x91\x9d\x24\x7f\xfc\xef\xc2\xa9\x1f\xb3\xe2\x18\xae\x73\x62\x59\x5a\x63\x47\x79\x96\xf4\x42\x3a\x4e\xba\xd6\x86\x98\x4e\x38\x16\xf9\xb1\x9f\x21\xa8\x8d\x3f\xd2\xfd\x2f\x00\x00\xff\xff\x86\xe7\xc8\x0b\x3c\x0b\x00\x00") var __0001_appUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\x4d\x93\xaa\x38\x14\xdd\xf3\x2b\xb2\xb4\xab\xd8\xcc\xfa\xad\x50\xa3\x4d\x0d\x03\x33\x88\xd3\xfd\x56\xa9\x34\x44\x4c\x35\x10\x5e\x12\xdb\xf6\xdf\x4f\xe5\x0b\x50\x01\xbb\xe7\xed\x48\xee\xc9\xf5\x9c\x73\x6f\x6e\x5c\xa5\x30\xc8\x20\xc8\x82\x65\x04\x41\xb8\x01\x71\x92\x01\xf8\x1a\xee\xb2\x1d\x10\x44\x4a\xda\x94\x02\x2c\x3c\x79\x69\x09\xf8\x37\x48\x57\xcf\x41\x0a\xfe\x4e\xc3\xbf\x82\xf4\x27\xf8\x13\xfe\xf4\xbd\x0f\x5c\x9d\x08\x58\x46\xc9\xd2\x7b\x02\x2f\x61\xf6\x9c\xec\x33\x90\x26\x2f\xe1\xfa\x87\xe7\xcd\x24\xc7\x79\xce\x4e\x8d\x54\xc9\x71\x51\x70\x22\xc4\x78\xfe\x33\xae\x2a\x22\xc1\x32\x49\x22\x18\xc4\xbe\x97\x1f\xf1\x60\xa5\x79\x65\xf0\x35\xf3\x3d\x21\x19\xc7\xa5\x5b\xb5\xa7\xb7\x77\x72\xd1\xbc\x7c\xaf\xc5\xf2\x68\xf7\x1b\x5c\x3b\x48\xce\x2a\xc6\xf5\xf7\x34\xf3\x7d\x1c\xfe\xb3\x87\x20\x8c\xd7\xf0\x15\x9c\x1a\xfa\xeb\x44\x90\x61\x84\x1c\xeb\x24\x1e\x68\x31\xb1\x27\xf0\xf2\x0c\x53\xd8\x2d\x7f\xcc\xa5\x53\x82\xc6\x93\xa9\x48\x97\x4a\x2f\xe6\x2d\x7d\xe3\xec\x2c\x08\x57\x96\xd2\x42\x0b\xbb\xb6\xb2\xd3\xae\x0f\xc5\xfb\x28\xf2\x3d\x49\x6b\x22\x24\xae\x5b\xb0\xdf\x6d\xc3\x6d\x0c\xd7\x60\x19\x6e\xc3\x38\xf3\xbd\x02\xb7\xad\x73\x1a\xac\xe1\x26\xd8\x47\x19\x38\xe0\x4a\x10\xdf\x3b\x52\x65\xf7\x25\x6c\x0a\xf2\x09\xf6\xf1\xce\x9c\x0c\xe3\x19\x2b\xe7\x18\x23\x9b\x0f\x2c\x3c\xbb\x85\x9c\x82\x9e\xaa\xc3\x98\xea\x6d\x92\x14\x86\xdb\x58\x29\x5b\xf4\x67\x9e\x40\x0a\x37\x30\x85\xf1\x0a\xf6\xd9\x17\x6a\x3f\x51\x1a\x22\x98\x41\xb0\x0a\x76\xab\x60\x0d\xbd\x07\x6e\x2a\xf9\xca\xca\xde\xb5\x81\x99\xdf\x93\xd9\x12\x5e\x53\x21\x28\x6b\x54\x42\x95\x18\x8d\xd5\xa2\x87\xdd\x46\x86\x62\xbb\xe3\x57\x5a\x35\xdb\x85\xd9\x1e\x97\x3a\x47\x50\x72\xdc\x88\x83\x69\x9d\x86\xc8\x33\xe3\xef\xaa\x00\x5d\x61\x4d\x4b\x0c\x6b\x81\xc5\xb1\xbb\xaf\xfd\xf6\xed\x4d\xee\x23\x6f\xd5\x3b\x9a\x38\x24\x3f\xed\x35\x15\xa4\x29\x08\x1f\x41\x70\x92\x13\xda\x4a\x0b\xab\x58\x69\xbf\xae\xa6\xd2\xb8\x5b\xbd\x1a\xdf\x51\xb8\xee\x91\x8a\xe5\xef\x62\x08\x33\x90\x3b\x0f\x7d\x6f\x95\xc4\xbb\x2c\x0d\x94\x11\xf6\xea\x3a\xdb\x50\x4b\xb8\xbb\xc2\xfa\xdb\xa6\x73\xf7\x7d\xa1\x72\xfa\x16\xe0\xf7\xbf\xf5\xf4\xa8\x07\x0d\xbb\xdf\x2c\x4a\x73\xaa\xdf\x08\xbf\x87\x0f\xae\xfe\x74\x4a\x82\x0b\x3d\x03\xba\x01\xb0\x09\xa2\xdd\xa8\x19\x9a\xeb\xa8\xfa\x5b\x73\x27\x0f\x1b\xa6\x8f\x72\x18\xd4\x43\xef\xdc\x1c\x45\x92\xa1\xef\xf9\x38\xdf\xc5\x53\x76\x8a\x4b\x93\x03\x3d\x38\x67\xfa\xcf\x72\x9f\xef\x40\x07\xfa\x52\x0f\xd6\xb8\x6d\x69\x53\xa2\x03\xe3\xc8\x4a\xee\x14\x8f\x3a\xe9\xda\xb0\xa7\xf3\x9d\x8e\xac\x31\xad\x04\xe1\x1f\x66\x56\x00\x00\x00\x2d\xc6\x1f\x6e\x15\xd3\x53\xee\xde\x46\x15\x9a\x36\x59\x45\x5b\x2c\xc4\x99\xf1\x2e\xb5\xd9\x3d\x54\x84\xc8\xbb\x13\xdf\x9b\xc5\xbd\x00\xc4\xc9\xaf\x13\x11\x12\x95\xb8\x75\x62\x4a\xdc\xa2\x03\x67\xf5\xd5\x9b\x06\xb7\xf0\x96\x9f\xc2\x49\xf6\x08\x35\xfa\x0a\xab\x80\x7e\xf3\x6f\x5f\xb8\x69\x1d\xe6\xff\xc2\x04\x73\x64\x93\x21\x5a\x7c\xaa\x96\x99\x14\x68\x71\x5f\x2e\x30\x92\xac\xa5\xb9\x73\x46\x2f\xa6\x2b\x6d\x93\x8b\xeb\x82\x55\x58\x48\xc7\xa2\xf3\xc8\x4d\x92\x3f\x0c\xa6\xa0\x22\x67\x1f\x84\x5f\xee\xfe\x6b\xd8\x51\xa3\x1b\x89\x94\x4c\x52\x2c\x49\x31\x8e\xfa\xdf\x3d\xa0\x79\x3b\x9f\x38\x6e\x4a\xe2\x04\xbb\x1a\x4d\x4a\xae\xd8\x99\xf4\xf2\x4c\xdb\x58\x8d\x06\x70\xa4\xe5\x71\x88\x90\xcc\xc5\xef\xe9\xfe\x17\x00\x00\xff\xff\xbe\x1f\x2a\xc2\x87\x0b\x00\x00")
func _0001_appUpSqlBytes() ([]byte, error) { func _0001_appUpSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -106,8 +106,8 @@ func _0001_appUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "0001_app.up.sql", size: 2876, mode: os.FileMode(0644), modTime: time.Unix(1567701215, 0)} info := bindataFileInfo{name: "0001_app.up.sql", size: 2951, mode: os.FileMode(0644), modTime: time.Unix(1575407229, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0x65, 0x8f, 0x50, 0xd3, 0x89, 0x74, 0x2e, 0x23, 0x73, 0x25, 0xbe, 0x5b, 0x53, 0x39, 0x3f, 0x4a, 0x65, 0x55, 0x39, 0x20, 0x10, 0xaa, 0xa6, 0xb9, 0xd0, 0x4c, 0xfa, 0x86, 0xaf, 0xac, 0xb0}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x2, 0xd5, 0x91, 0xff, 0x5f, 0x8f, 0xb0, 0xe8, 0x19, 0x84, 0xd1, 0xa5, 0xd5, 0xec, 0xa5, 0x4, 0x1d, 0x4c, 0x5c, 0xb5, 0xd3, 0xde, 0x36, 0xd8, 0xa6, 0x98, 0x69, 0xee, 0xfa, 0x10, 0x97}}
return a, nil return a, nil
} }
@ -126,7 +126,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1566753968, 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}} 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 return a, nil
} }

View file

@ -96,7 +96,9 @@ CREATE INDEX mailserver_request_gaps_chat_id_idx ON mailserver_request_gaps (cha
CREATE TABLE IF NOT EXISTS mailserver_topics ( CREATE TABLE IF NOT EXISTS mailserver_topics (
topic VARCHAR PRIMARY KEY, topic VARCHAR PRIMARY KEY,
chat_ids VARCHAR, chat_ids VARCHAR,
last_request INTEGER DEFAULT 1 last_request INTEGER DEFAULT 1,
discovery BOOLEAN DEFAULT FALSE,
negotiated BOOLEAN DEFAULT FALSE
) WITHOUT ROWID; ) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS mailserver_chat_request_ranges ( CREATE TABLE IF NOT EXISTS mailserver_chat_request_ranges (

11
go.mod
View file

@ -20,10 +20,12 @@ require (
github.com/beevik/ntp v0.2.0 github.com/beevik/ntp v0.2.0
github.com/elastic/gosigar v0.10.5 // indirect github.com/elastic/gosigar v0.10.5 // indirect
github.com/ethereum/go-ethereum v1.9.5 github.com/ethereum/go-ethereum v1.9.5
github.com/go-playground/locales v0.12.1 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-playground/universal-translator v0.16.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/golang-migrate/migrate/v4 v4.7.0 // indirect
github.com/golang/mock v1.3.1 github.com/golang/mock v1.3.1
github.com/leodido/go-urn v1.1.0 // indirect github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/lib/pq v1.2.0 github.com/lib/pq v1.2.0
github.com/libp2p/go-libp2p v0.4.0 // indirect github.com/libp2p/go-libp2p v0.4.0 // indirect
github.com/libp2p/go-libp2p-core v0.2.3 github.com/libp2p/go-libp2p-core v0.2.3
@ -33,7 +35,10 @@ require (
github.com/pborman/uuid v1.2.0 github.com/pborman/uuid v1.2.0
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.2.1 github.com/prometheus/client_golang v1.2.1
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 // indirect
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d // indirect
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
github.com/status-im/keycard-go v0.0.0-20191119114148-6dd40a46baa0 // indirect
github.com/status-im/migrate/v4 v4.6.2-status.2 github.com/status-im/migrate/v4 v4.6.2-status.2
github.com/status-im/rendezvous v1.3.0 github.com/status-im/rendezvous v1.3.0
github.com/status-im/status-go/eth-node v0.0.0-20191126161717-86bc127b3d0a github.com/status-im/status-go/eth-node v0.0.0-20191126161717-86bc127b3d0a

49
go.sum
View file

@ -20,6 +20,7 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -27,6 +28,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.1.0 h1:MLuIKTjdxDc+qsG2rhjsYjsHQC5LUGjIWzutg7M+W68=
github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM= github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
@ -67,6 +69,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
@ -125,9 +128,11 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 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/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa h1:o8OuEkracbk3qH6GvlI6XpEN1HTSxkzOG42xZpfDv/s=
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=
@ -136,6 +141,7 @@ github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a h1:1znxn4+q2MrEdTk1eCk6KIV3muTYVclBIB6CTVR/zBc= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a h1:1znxn4+q2MrEdTk1eCk6KIV3muTYVclBIB6CTVR/zBc=
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
@ -144,6 +150,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -152,11 +160,12 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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.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 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@ -169,6 +178,8 @@ github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k=
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
github.com/golang-migrate/migrate/v4 v4.7.0 h1:gONcHxHApDTKXDyLH/H97gEHmpu1zcnnbAaq2zgrPrs=
github.com/golang-migrate/migrate/v4 v4.7.0/go.mod h1:Qvut3N4xKWjoH3sokBccML6WyHSnggXm/DvMMnTsQIc=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -277,6 +288,8 @@ github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2vi
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A= github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ=
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@ -295,8 +308,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@ -311,14 +324,17 @@ github.com/libp2p/go-eventbus v0.1.0 h1:mlawomSAjjkk97QnYiEmHsLu7E136+2oCWSHRUvM
github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4=
github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s=
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
github.com/libp2p/go-libp2p v0.1.1 h1:52sB0TJuDk2nYMcMfHOKaPoaayDZjaYVCq6Vk1ejUTk=
github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8=
github.com/libp2p/go-libp2p v0.4.0 h1:nV2q3fdhL80OWtPyBrsoWKcw32qC4TbbR+iGjEOMRaU= github.com/libp2p/go-libp2p v0.4.0 h1:nV2q3fdhL80OWtPyBrsoWKcw32qC4TbbR+iGjEOMRaU=
github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI= github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI=
github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU=
github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78=
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk= github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk=
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
github.com/libp2p/go-libp2p-circuit v0.1.0 h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY=
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
github.com/libp2p/go-libp2p-circuit v0.1.3 h1:WsMYYaA0PwdpgJSQu12EzPYf5ypkLSTgcOsWr7DYrgI= github.com/libp2p/go-libp2p-circuit v0.1.3 h1:WsMYYaA0PwdpgJSQu12EzPYf5ypkLSTgcOsWr7DYrgI=
github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM= github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM=
@ -329,6 +345,7 @@ github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv
github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0=
github.com/libp2p/go-libp2p-core v0.2.3 h1:zXikZ5pLfebtTMeIYfcwVQ2Pae77O0FIwDquwM6AGNM= github.com/libp2p/go-libp2p-core v0.2.3 h1:zXikZ5pLfebtTMeIYfcwVQ2Pae77O0FIwDquwM6AGNM=
github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A= github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A=
github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ=
github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI=
github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs=
github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g=
@ -340,18 +357,23 @@ github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiY
github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw=
github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY=
github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU=
github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY=
github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY=
github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E=
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M= github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M=
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ=
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng= github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng=
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s=
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ= github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ=
github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc=
github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.1.0 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/HDNpeyT9U= github.com/libp2p/go-libp2p-testing v0.1.0 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/HDNpeyT9U=
github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
@ -360,6 +382,7 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07q
github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8=
github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI=
github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI=
github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs=
github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q=
github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg= github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg=
github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
@ -380,9 +403,11 @@ github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA2
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg=
github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc=
github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o=
github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc=
github.com/libp2p/go-tcp-transport v0.1.1 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw= github.com/libp2p/go-tcp-transport v0.1.1 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw=
github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4=
github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo=
github.com/libp2p/go-ws-transport v0.1.2 h1:VnxQcLfSGtqupqPpBNu8fUiCv+IN1RJ2BcVqQEM+z8E= github.com/libp2p/go-ws-transport v0.1.2 h1:VnxQcLfSGtqupqPpBNu8fUiCv+IN1RJ2BcVqQEM+z8E=
github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y=
@ -400,11 +425,12 @@ github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0X
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f h1:QTRRO+ozoYgT3CQRIzNVYJRU3DB8HRnkZv6mr4ISmMA=
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
@ -445,12 +471,15 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg
github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE= github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8=
github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
github.com/multiformats/go-multiaddr-dns v0.1.0 h1:gsPeMvo91XvcsNlQXgJgfjYjbsVV99bvveguUvDBpyQ= github.com/multiformats/go-multiaddr-dns v0.1.0 h1:gsPeMvo91XvcsNlQXgJgfjYjbsVV99bvveguUvDBpyQ=
github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY=
github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA=
github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g=
github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU=
github.com/multiformats/go-multiaddr-net v0.1.0 h1:ZepO8Ezwovd+7b5XPPDhQhayk1yt0AJpzQBpq9fejx4= github.com/multiformats/go-multiaddr-net v0.1.0 h1:ZepO8Ezwovd+7b5XPPDhQhayk1yt0AJpzQBpq9fejx4=
github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ=
@ -471,6 +500,7 @@ github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a h1:m6hB6GkmZ/suOSKZM7yx3Yt+7iZ9HNfzacCykJqgXA8=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
@ -488,6 +518,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@ -531,6 +562,7 @@ github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oA
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
@ -577,6 +609,8 @@ github.com/status-im/go-multiaddr-ethv4 v1.2.0 h1:OT84UsUzTCwguqCpJqkrCMiL4VZ1Sv
github.com/status-im/go-multiaddr-ethv4 v1.2.0/go.mod h1:2VQ3C+9zEurcceasz12gPAtmEzCeyLUGPeKLSXYQKHo= github.com/status-im/go-multiaddr-ethv4 v1.2.0/go.mod h1:2VQ3C+9zEurcceasz12gPAtmEzCeyLUGPeKLSXYQKHo=
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw= github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw=
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/status-im/keycard-go v0.0.0-20191119114148-6dd40a46baa0 h1:5UdlDkkBoPrJfh7zkfoR3X5utJhNs/MCQysK3x0ycgg=
github.com/status-im/keycard-go v0.0.0-20191119114148-6dd40a46baa0/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/status-im/markdown v0.0.0-20191113114344-af599402d015 h1:ijC73VP0hucsy/MRn4cmtoQVB1mKdLcvurMYPvmPc4Y= github.com/status-im/markdown v0.0.0-20191113114344-af599402d015 h1:ijC73VP0hucsy/MRn4cmtoQVB1mKdLcvurMYPvmPc4Y=
github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE= github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE=
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 h1:SdC+sMDl/aI7vUlwD2qj2p7KsK4T60IS9z4/rYCCbI8=
@ -798,6 +832,7 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXL
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5 h1:VWXVtmkY4YFVuF1FokZ0PUsuvtx3Di6z/m47daSP5f0=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=

View file

@ -86,7 +86,7 @@ func _1557732988_initialize_dbDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1557732988_initialize_db.down.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -106,7 +106,7 @@ func _1557732988_initialize_dbUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1557732988_initialize_db.up.sql", size: 234, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -126,7 +126,7 @@ func staticGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "static.go", size: 178, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }

View file

@ -86,7 +86,7 @@ func _0001_accountsDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "0001_accounts.down.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1573216280, 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}} 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 return a, nil
} }
@ -106,7 +106,7 @@ func _0001_accountsUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "0001_accounts.up.sql", size: 177, mode: os.FileMode(0644), modTime: time.Unix(1574408465, 0)} info := bindataFileInfo{name: "0001_accounts.up.sql", size: 177, mode: os.FileMode(0644), modTime: time.Unix(1574772479, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0x24, 0xcf, 0x7a, 0x7b, 0xb0, 0xf0, 0x95, 0x3f, 0x45, 0x63, 0x9c, 0xe1, 0xca, 0x8f, 0xe4, 0x1a, 0x83, 0x8b, 0x19, 0x1f, 0x11, 0x98, 0xc4, 0x2b, 0xa5, 0x2f, 0x79, 0x96, 0xc2, 0x8f, 0x75}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0x24, 0xcf, 0x7a, 0x7b, 0xb0, 0xf0, 0x95, 0x3f, 0x45, 0x63, 0x9c, 0xe1, 0xca, 0x8f, 0xe4, 0x1a, 0x83, 0x8b, 0x19, 0x1f, 0x11, 0x98, 0xc4, 0x2b, 0xa5, 0x2f, 0x79, 0x96, 0xc2, 0x8f, 0x75}}
return a, nil return a, nil
} }
@ -126,7 +126,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1573216280, 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}} 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 return a, nil
} }

View file

@ -4,6 +4,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/sha1" "crypto/sha1"
"encoding/hex" "encoding/hex"
"encoding/json"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
@ -43,10 +44,7 @@ type Chat struct {
// Denormalized fields // Denormalized fields
UnviewedMessagesCount uint `json:"unviewedMessagesCount"` UnviewedMessagesCount uint `json:"unviewedMessagesCount"`
LastMessageContentType string `json:"lastMessageContentType"` LastMessage []byte `json:"lastMessage"`
LastMessageContent string `json:"lastMessageContent"`
LastMessageTimestamp int64 `json:"lastMessageTimestamp"`
LastMessageClockValue int64 `json:"lastMessageClockValue"`
// Group chat fields // Group chat fields
// Members are the members who have been invited to the group chat // Members are the members who have been invited to the group chat
@ -55,6 +53,53 @@ type Chat struct {
MembershipUpdates []ChatMembershipUpdate `json:"membershipUpdates"` MembershipUpdates []ChatMembershipUpdate `json:"membershipUpdates"`
} }
func (c *Chat) MarshalJSON() ([]byte, error) {
type ChatAlias Chat
item := struct {
*ChatAlias
LastMessage json.RawMessage `json:"lastMessage"`
}{
ChatAlias: (*ChatAlias)(c),
LastMessage: c.LastMessage,
}
return json.Marshal(item)
}
func (c *Chat) UnmarshalJSON(data []byte) error {
type ChatAlias Chat
aux := struct {
*ChatAlias
LastMessage *Message `json:"lastMessage"`
}{
ChatAlias: (*ChatAlias)(c),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
c.ID = aux.ID
c.Name = aux.Name
c.Color = aux.Color
c.Active = aux.Active
c.ChatType = aux.ChatType
c.Timestamp = aux.Timestamp
c.LastClockValue = aux.LastClockValue
c.DeletedAtClockValue = aux.DeletedAtClockValue
c.UnviewedMessagesCount = aux.UnviewedMessagesCount
c.Members = aux.Members
c.MembershipUpdates = aux.MembershipUpdates
if aux.LastMessage != nil {
data, err := json.Marshal(aux.LastMessage)
if err != nil {
return err
}
c.LastMessage = data
}
return nil
}
func (c *Chat) MembersAsPublicKeys() ([]*ecdsa.PublicKey, error) { func (c *Chat) MembersAsPublicKeys() ([]*ecdsa.PublicKey, error) {
publicKeys := make([]string, len(c.Members)) publicKeys := make([]string, len(c.Members))
for idx, item := range c.Members { for idx, item := range c.Members {

View file

@ -12,9 +12,9 @@ import (
) )
const ( const (
contactBlocked = "contact/blocked" contactBlocked = ":contact/blocked"
contactAdded = "contact/added" contactAdded = ":contact/added"
contactRequestReceived = "contact/request-received" contactRequestReceived = ":contact/request-received"
) )
// ContactDeviceInfo is a struct containing information about a particular device owned by a contact // ContactDeviceInfo is a struct containing information about a particular device owned by a contact

View file

@ -100,7 +100,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}}
return a, nil return a, nil
} }
@ -120,7 +120,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}}
return a, nil return a, nil
} }
@ -140,7 +140,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}}
return a, nil return a, nil
} }
@ -160,7 +160,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}}
return a, nil return a, nil
} }
@ -180,7 +180,7 @@ func _1540715431_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}}
return a, nil return a, nil
} }
@ -200,7 +200,7 @@ func _1540715431_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}}
return a, nil return a, nil
} }
@ -220,7 +220,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}}
return a, nil return a, nil
} }
@ -240,7 +240,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}}
return a, nil return a, nil
} }
@ -260,7 +260,7 @@ func _1558084410_add_secretDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}}
return a, nil return a, nil
} }
@ -280,7 +280,7 @@ func _1558084410_add_secretUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}}
return a, nil return a, nil
} }
@ -300,7 +300,7 @@ func _1558588866_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}}
return a, nil return a, nil
} }
@ -320,7 +320,7 @@ func _1558588866_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}}
return a, nil return a, nil
} }
@ -340,7 +340,7 @@ func _1559627659_add_contact_codeDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}}
return a, nil return a, nil
} }
@ -360,7 +360,7 @@ func _1559627659_add_contact_codeUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}}
return a, nil return a, nil
} }
@ -380,7 +380,7 @@ func _1561368210_add_installation_metadataDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}}
return a, nil return a, nil
} }
@ -400,7 +400,7 @@ func _1561368210_add_installation_metadataUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}}
return a, nil return a, nil
} }
@ -420,7 +420,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}}
return a, nil return a, nil
} }

View file

@ -384,6 +384,11 @@ func (p *Protocol) GetOurInstallations(myIdentityKey *ecdsa.PublicKey) ([]*multi
return p.multidevice.GetOurInstallations(myIdentityKey) return p.multidevice.GetOurInstallations(myIdentityKey)
} }
// GetOurActiveInstallations returns all the active installations available given an identity
func (p *Protocol) GetOurActiveInstallations(myIdentityKey *ecdsa.PublicKey) ([]*multidevice.Installation, error) {
return p.multidevice.GetOurActiveInstallations(myIdentityKey)
}
// SetInstallationMetadata sets the metadata for our own installation // SetInstallationMetadata sets the metadata for our own installation
func (p *Protocol) SetInstallationMetadata(myIdentityKey *ecdsa.PublicKey, installationID string, data *multidevice.InstallationMetadata) error { func (p *Protocol) SetInstallationMetadata(myIdentityKey *ecdsa.PublicKey, installationID string, data *multidevice.InstallationMetadata) error {
return p.multidevice.SetInstallationMetadata(myIdentityKey, installationID, data) return p.multidevice.SetInstallationMetadata(myIdentityKey, installationID, data)

View file

@ -10,15 +10,15 @@ replace github.com/status-im/status-go/eth-node => ../eth-node
require ( require (
github.com/cenkalti/backoff/v3 v3.0.0 github.com/cenkalti/backoff/v3 v3.0.0
github.com/ethereum/go-ethereum v1.9.5
github.com/golang/protobuf v1.3.2 github.com/golang/protobuf v1.3.2
github.com/gomarkdown/markdown v0.0.0-20191113114344-af599402d015 github.com/gomarkdown/markdown v0.0.0-20191113114344-af599402d015
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
github.com/lucasb-eyer/go-colorful v1.0.2 github.com/lucasb-eyer/go-colorful v1.0.2
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 // indirect
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d // indirect
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
github.com/status-im/doubleratchet v3.0.0+incompatible github.com/status-im/doubleratchet v3.0.0+incompatible
github.com/status-im/migrate/v4 v4.6.2-status.2 github.com/status-im/migrate/v4 v4.6.2-status.2
@ -27,4 +27,5 @@ require (
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/vacp2p/mvds v0.0.23 github.com/vacp2p/mvds v0.0.23
go.uber.org/zap v1.13.0 go.uber.org/zap v1.13.0
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
) )

View file

@ -2,6 +2,8 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY= github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
@ -10,6 +12,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@ -18,7 +21,9 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM= github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
@ -29,12 +34,20 @@ github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0= github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 h1:fKnuvQ/O22ZpD7HaJjGQXn/GxOdDJOQFL8bpM8Xe3X8=
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 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/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/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= 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 h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
@ -53,12 +66,20 @@ github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4r
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.0 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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= 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/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/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/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= 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/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/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
@ -77,7 +98,11 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= 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/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/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= 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/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@ -87,6 +112,7 @@ github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 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/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dvyukov/go-fuzz v0.0.0-20191022152526-8cb203812681/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/dvyukov/go-fuzz v0.0.0-20191022152526-8cb203812681/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 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/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
@ -99,6 +125,7 @@ github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo= github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
@ -110,11 +137,18 @@ github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7R
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 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 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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.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 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@ -123,12 +157,16 @@ github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhD
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/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/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k=
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1/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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -138,8 +176,10 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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.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-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/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/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/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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
@ -150,9 +190,13 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 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.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/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4= github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4=
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
github.com/gyuho/goraph v0.0.0-20171001060514-a7a4454fd3eb/go.mod h1:NtSxZCD+s3sZFwbW6WceOcUD83HM9XD5OE2r4c0P8eg=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= 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 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -162,6 +206,7 @@ github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -169,31 +214,54 @@ github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOo
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= 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/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/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/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/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s=
github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= 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/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
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 v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
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/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 v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A= github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@ -202,14 +270,80 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc=
github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4=
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8=
github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI=
github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM=
github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco=
github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE=
github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I=
github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI=
github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0=
github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A=
github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI=
github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g=
github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90=
github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo=
github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE=
github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY=
github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU=
github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY=
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA=
github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8=
github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI=
github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q=
github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU=
github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI=
github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0=
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc=
github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc=
github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo=
github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y=
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI= github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@ -219,16 +353,24 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/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 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg=
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= 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/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik=
@ -240,25 +382,30 @@ github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86w
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= 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/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 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.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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/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.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY= github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -268,16 +415,27 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.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-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-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-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.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.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-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.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.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/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
@ -298,14 +456,26 @@ github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d h1:A926QrjwToaPS7gi
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d/go.mod h1:Cpq811GTlHevuU6BZxk3ObOdK8AY5gHu9QGmDak0DT4= github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d/go.mod h1:Cpq811GTlHevuU6BZxk3ObOdK8AY5gHu9QGmDak0DT4=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a h1:yVNJFSzkEG8smsvd9udiQcMJA0MIsFvlG7ba314cu+s= github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a h1:yVNJFSzkEG8smsvd9udiQcMJA0MIsFvlG7ba314cu+s=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a/go.mod h1:TPq+fcJOdGrkpZpXF4UVmFjYxH0gGqnxdgZ+OzAmvJk= github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a/go.mod h1:TPq+fcJOdGrkpZpXF4UVmFjYxH0gGqnxdgZ+OzAmvJk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= 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.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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc=
github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY= github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY=
github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU= github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
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 h1:ytuTO1yBIAuTVRtRQoc2mrdyngtP+XOQ9IHIibbz7/I=
@ -316,10 +486,13 @@ github.com/status-im/markdown v0.0.0-20191113114344-af599402d015 h1:ijC73VP0hucs
github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE= github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE=
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 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/migrate/v4 v4.6.2-status.2/go.mod h1:c/kc90n47GZu/58nnz1OMLTf7uE4Da4gZP5qmU+A/v8=
github.com/status-im/status-go v0.36.0 h1:91qDMJjHv+T3Li9FwxsWQ2JBVcYtvVDT0nGFSMnmM+8=
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM= github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs= github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s= github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
github.com/status-im/whisper v1.6.1 h1:C/T1HQHZfUI2jbccf3yIe8yfkl435I3BILIKeNASJDc=
github.com/status-im/whisper v1.6.1/go.mod h1:lygchT4p9Y1/hR451OhNNqfinvy9EYEDxtXU2T/U30Q=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
@ -338,10 +511,13 @@ github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2K
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/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= github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= 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/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU= github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU=
github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ= github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ=
github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk= github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk=
@ -350,15 +526,26 @@ github.com/wealdtech/go-multicodec v1.2.0 h1:9AHSxcSE9F9r6ZvQLAO0EXCdM08QfYohaXm
github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4= github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs= github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs=
github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4= github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8=
github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= 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/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@ -373,11 +560,20 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE= golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -395,11 +591,13 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/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-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-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-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-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-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -421,9 +619,12 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/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-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-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -436,10 +637,13 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/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-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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -455,6 +659,7 @@ google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.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-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/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/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -469,13 +674,20 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/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= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=

View file

@ -226,11 +226,10 @@ type bintree struct {
Func func() (*asset, error) Func func() (*asset, error)
Children map[string]*bintree Children map[string]*bintree
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"000001_init.down.db.sql": {_000001_initDownDbSql, map[string]*bintree{}}, "000001_init.down.db.sql": &bintree{_000001_initDownDbSql, map[string]*bintree{}},
"000001_init.up.db.sql": {_000001_initUpDbSql, map[string]*bintree{}}, "000001_init.up.db.sql": &bintree{_000001_initUpDbSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}
// RestoreAsset restores an asset under the given directory // RestoreAsset restores an asset under the given directory

View file

@ -1,72 +1,159 @@
package protocol package protocol
import ( import (
"database/sql/driver" "crypto/ecdsa"
"encoding/json"
"strings"
"unicode"
"unicode/utf8"
"github.com/pkg/errors" "github.com/gomarkdown/markdown"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/protobuf"
) )
type hexutilSQL types.HexBytes
func (h hexutilSQL) Value() (driver.Value, error) {
return []byte(h), nil
}
func (h hexutilSQL) String() string {
return types.EncodeHex(h)
}
func (h *hexutilSQL) Scan(value interface{}) error {
if value == nil {
return nil
}
if b, ok := value.([]byte); ok {
*h = hexutilSQL(b)
return nil
}
return errors.New("failed to scan hexutilSQL")
}
// QuotedMessage contains the original text of the message replied to // QuotedMessage contains the original text of the message replied to
type QuotedMessage struct { type QuotedMessage struct {
// From is a public key of the author of the message. // From is a public key of the author of the message.
From string `json:"from"` From string `json:"from"`
Content string `json:"content"` Text string `json:"text"`
} }
const (
OutgoingStatusSending = "sending"
OutgoingStatusSent = "sent"
)
// Message represents a message record in the database, // Message represents a message record in the database,
// more specifically in user_messages_legacy table. // more specifically in user_messages_legacy table.
// Encoding and decoding of byte blobs should be performed
// using hexutil package.
type Message struct { type Message struct {
protobuf.ChatMessage
// ID calculated as keccak256(compressedAuthorPubKey, data) where data is unencrypted payload. // ID calculated as keccak256(compressedAuthorPubKey, data) where data is unencrypted payload.
ID string `json:"id"` ID string `json:"id"`
// WhisperTimestamp is a timestamp of a Whisper envelope. // WhisperTimestamp is a timestamp of a Whisper envelope.
WhisperTimestamp int64 `json:"whisperTimestamp"` WhisperTimestamp uint64 `json:"whisperTimestamp"`
// From is a public key of the author of the message. // From is a public key of the author of the message.
From string `json:"from"` From string `json:"from"`
// Random 3 words name // Random 3 words name
Alias string `json:"alias"` Alias string `json:"alias"`
// Identicon of the author // Identicon of the author
Identicon string `json:"identicon"` Identicon string `json:"identicon"`
// To is a public key of the recipient unless it's a public message then it's empty. // The chat id to be stored locally
To hexutilSQL `json:"to,omitempty"` LocalChatID string `json:"localChatId"`
// BEGIN: fields from types.Message.
Content string `json:"content"`
ContentType string `json:"contentType"`
Timestamp int64 `json:"timestamp"`
ChatID string `json:"chatId"`
MessageType string `json:"messageType,omitempty"`
MessageStatus string `json:"messageStatus,omitempty"`
ClockValue int64 `json:"clockValue"`
// END
Username string `json:"username,omitempty"`
RetryCount int `json:"retryCount"` RetryCount int `json:"retryCount"`
Show bool `json:"show"` // default true
Seen bool `json:"seen"` Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"` OutgoingStatus string `json:"outgoingStatus,omitempty"`
// MessageID of the replied message
ReplyTo string `json:"replyTo"`
QuotedMessage *QuotedMessage `json:"quotedMessage"` QuotedMessage *QuotedMessage `json:"quotedMessage"`
// Computed fields
RTL bool `json:"rtl"`
ParsedText []byte `json:"parsedText"`
LineCount int `json:"lineCount"`
SigPubKey *ecdsa.PublicKey `json:"-"`
// RawPayload is the marshaled payload, used for resending the message
RawPayload []byte `json:"-"`
}
func (m *Message) MarshalJSON() ([]byte, error) {
type MessageAlias Message
item := struct {
ID string `json:"id"`
WhisperTimestamp uint64 `json:"whisperTimestamp"`
From string `json:"from"`
Alias string `json:"alias"`
Identicon string `json:"identicon"`
RetryCount int `json:"retryCount"`
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`
QuotedMessage *QuotedMessage `json:"quotedMessage"`
RTL bool `json:"rtl"`
ParsedText json.RawMessage `json:"parsedText"`
LineCount int `json:"lineCount"`
Text string `json:"text"`
ChatId string `json:"chatId"`
LocalChatID string `json:"localChatId"`
Clock uint64 `json:"clock"`
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
Sticker *protobuf.StickerMessage `json:"sticker"`
Timestamp uint64 `json:"timestamp"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
MessageType protobuf.ChatMessage_MessageType `json:"messageType"`
}{
ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp,
From: m.From,
Alias: m.Alias,
Identicon: m.Identicon,
RetryCount: m.RetryCount,
Seen: m.Seen,
OutgoingStatus: m.OutgoingStatus,
QuotedMessage: m.QuotedMessage,
RTL: m.RTL,
ParsedText: m.ParsedText,
LineCount: m.LineCount,
Text: m.Text,
ChatId: m.ChatId,
LocalChatID: m.LocalChatID,
Clock: m.Clock,
ResponseTo: m.ResponseTo,
EnsName: m.EnsName,
Timestamp: m.Timestamp,
ContentType: m.ContentType,
MessageType: m.MessageType,
Sticker: m.GetSticker(),
}
return json.Marshal(item)
}
func (m *Message) UnmarshalJSON(data []byte) error {
type Alias Message
aux := struct {
*Alias
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
ChatID string `json:"chatId"`
Sticker *protobuf.StickerMessage `json:"sticker"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
}{
Alias: (*Alias)(m),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
if aux.ContentType == protobuf.ChatMessage_STICKER {
m.Payload = &protobuf.ChatMessage_Sticker{Sticker: aux.Sticker}
}
m.ResponseTo = aux.ResponseTo
m.EnsName = aux.EnsName
m.ChatId = aux.ChatID
m.ContentType = aux.ContentType
return nil
}
// Check if the first character is Hebrew or Arabic or the RTL character
func isRTL(s string) bool {
first, _ := utf8.DecodeRuneInString(s)
return unicode.Is(unicode.Hebrew, first) ||
unicode.Is(unicode.Arabic, first) ||
// RTL character
first == '\u200f'
}
// PrepareContent return the parsed content of the message, the line-count and whether
// is a right-to-left message
func (m *Message) PrepareContent() error {
parsedText := markdown.Parse([]byte(m.Text), nil)
jsonParsedText, err := json.Marshal(parsedText)
if err != nil {
return err
}
m.ParsedText = jsonParsedText
m.LineCount = strings.Count(m.Text, "\n")
m.RTL = isRTL(m.Text)
return nil
} }

View file

@ -56,7 +56,7 @@ func (h *persistentMessageHandler) chatID(chatID string) (*Chat, error) {
return nil, err return nil, err
} }
for _, ch := range chats { for _, ch := range chats {
if chat.ID == chatID { if ch.ID == chatID {
chat = ch chat = ch
break break
} }

View file

@ -92,25 +92,6 @@ func (p *messageProcessor) Stop() {
p.datasync.Stop() // idempotent op p.datasync.Stop() // idempotent op
} }
func (p *messageProcessor) SendPrivate(
ctx context.Context,
recipient *ecdsa.PublicKey,
chatID string,
data []byte,
clock int64,
) ([]byte, *v1protocol.Message, error) {
message := v1protocol.CreatePrivateTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to encode message")
}
messageID, err := p.sendPrivate(ctx, recipient, encodedMessage)
if err != nil {
return nil, nil, err
}
return messageID, &message, nil
}
// SendPrivateRaw takes encoded data, encrypts it and sends through the wire. // SendPrivateRaw takes encoded data, encrypts it and sends through the wire.
func (p *messageProcessor) SendPrivateRaw( func (p *messageProcessor) SendPrivateRaw(
ctx context.Context, ctx context.Context,
@ -125,6 +106,34 @@ func (p *messageProcessor) SendPrivateRaw(
return p.sendPrivate(ctx, recipient, data) return p.sendPrivate(ctx, recipient, data)
} }
// SendGroupRaw takes encoded data, encrypts it and sends through the wire,
// always return the messageID
func (p *messageProcessor) SendGroupRaw(
ctx context.Context,
recipients []*ecdsa.PublicKey,
data []byte,
) ([]byte, error) {
p.logger.Debug(
"sending a private group message",
zap.String("site", "SendGroupRaw"),
)
// Calculate messageID first
wrappedMessage, err := p.wrapMessageV1(data)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap message")
}
messageID := v1protocol.MessageID(&p.identity.PublicKey, wrappedMessage)
for _, recipient := range recipients {
_, err = p.sendPrivate(ctx, recipient, data)
if err != nil {
return nil, errors.Wrap(err, "failed to send message")
}
}
return messageID, nil
}
// sendPrivate sends data to the recipient identifying with a given public key. // sendPrivate sends data to the recipient identifying with a given public key.
func (p *messageProcessor) sendPrivate( func (p *messageProcessor) sendPrivate(
ctx context.Context, ctx context.Context,
@ -133,7 +142,7 @@ func (p *messageProcessor) sendPrivate(
) ([]byte, error) { ) ([]byte, error) {
p.logger.Debug("sending private message", zap.Binary("recipient", crypto.FromECDSAPub(recipient))) p.logger.Debug("sending private message", zap.Binary("recipient", crypto.FromECDSAPub(recipient)))
wrappedMessage, err := p.tryWrapMessageV1(data) wrappedMessage, err := p.wrapMessageV1(data)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
@ -164,32 +173,6 @@ func (p *messageProcessor) sendPrivate(
return messageID, nil return messageID, nil
} }
func (p *messageProcessor) SendGroup(
ctx context.Context,
recipients []*ecdsa.PublicKey,
chatID string,
data []byte,
clock int64,
) ([][]byte, []*v1protocol.Message, error) {
p.logger.Debug("sending a group message", zap.Int("membersCount", len(recipients)))
message := v1protocol.CreatePrivateGroupTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to encode message")
}
var resultIDs [][]byte
for _, recipient := range recipients {
messageID, err := p.sendPrivate(ctx, recipient, encodedMessage)
if err != nil {
return nil, nil, err
}
resultIDs = append(resultIDs, messageID)
}
return resultIDs, nil, nil
}
func (p *messageProcessor) SendMembershipUpdate( func (p *messageProcessor) SendMembershipUpdate(
ctx context.Context, ctx context.Context,
recipients []*ecdsa.PublicKey, recipients []*ecdsa.PublicKey,
@ -219,46 +202,11 @@ func (p *messageProcessor) SendMembershipUpdate(
return resultIDs, nil return resultIDs, nil
} }
func (p *messageProcessor) SendPublic(ctx context.Context, chatID string, data []byte, clock int64) ([]byte, error) {
message := v1protocol.CreatePublicTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, errors.Wrap(err, "failed to encode message")
}
wrappedMessage, err := p.tryWrapMessageV1(encodedMessage)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap message")
}
messageSpec, err := p.protocol.BuildPublicMessage(p.identity, wrappedMessage)
if err != nil {
return nil, errors.Wrap(err, "failed to build public message")
}
newMessage, err := messageSpecToWhisper(messageSpec)
if err != nil {
return nil, err
}
hash, err := p.transport.SendPublic(ctx, newMessage, chatID)
if err != nil {
return nil, err
}
messageID := v1protocol.MessageID(&p.identity.PublicKey, wrappedMessage)
p.transport.Track([][]byte{messageID}, hash, newMessage)
return messageID, nil
}
// SendPublicRaw takes encoded data, encrypts it and sends through the wire. // SendPublicRaw takes encoded data, encrypts it and sends through the wire.
func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, data []byte) ([]byte, error) { func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, data []byte) ([]byte, error) {
var newMessage *types.NewMessage var newMessage *types.NewMessage
wrappedMessage, err := p.tryWrapMessageV1(data) wrappedMessage, err := p.wrapMessageV1(data)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
@ -282,61 +230,6 @@ func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, d
return messageID, nil return messageID, nil
} }
// Process processes received Whisper messages through all the layers
// and returns decoded user messages.
// It also handled all non-user messages like PairMessage.
func (p *messageProcessor) Process(shhMessage *types.Message) ([]*v1protocol.Message, error) {
logger := p.logger.With(zap.String("site", "Process"))
var decodedMessages []*v1protocol.Message
hlogger := logger.With(zap.Binary("hash", shhMessage.Hash))
hlogger.Debug("handling a received message")
statusMessages, err := p.handleMessages(shhMessage, true)
if err != nil {
return nil, err
}
for _, statusMessage := range statusMessages {
switch m := statusMessage.ParsedMessage.(type) {
case v1protocol.Message:
m.ID = statusMessage.ID
m.SigPubKey = statusMessage.SigPubKey()
decodedMessages = append(decodedMessages, &m)
case v1protocol.MembershipUpdateMessage:
// Handle user message that can be attached to the membership update.
userMessage := m.Message
if userMessage != nil {
userMessage.ID = statusMessage.ID
userMessage.SigPubKey = statusMessage.SigPubKey()
decodedMessages = append(decodedMessages, userMessage)
}
if err := p.processMembershipUpdate(m); err != nil {
hlogger.Error("failed to process MembershipUpdateMessage", zap.Error(err))
}
case v1protocol.PairMessage:
fromOurDevice := isPubKeyEqual(statusMessage.SigPubKey(), &p.identity.PublicKey)
if !fromOurDevice {
hlogger.Debug("received PairMessage from not our device, skipping")
break
}
if err := p.processPairMessage(m); err != nil {
hlogger.Error("failed to process PairMessage", zap.Error(err))
}
default:
hlogger.Error(
"skipped a public message of unsupported type",
zap.Any("value", statusMessage.ParsedMessage),
)
}
}
return decodedMessages, nil
}
func (p *messageProcessor) processMembershipUpdate(m v1protocol.MembershipUpdateMessage) error { func (p *messageProcessor) processMembershipUpdate(m v1protocol.MembershipUpdateMessage) error {
if err := m.Verify(); err != nil { if err := m.Verify(); err != nil {
return err return err
@ -443,24 +336,13 @@ func (p *messageProcessor) handleErrDeviceNotFound(ctx context.Context, publicKe
return nil return nil
} }
func (p *messageProcessor) encodeMessage(message v1protocol.Message) ([]byte, error) { func (p *messageProcessor) wrapMessageV1(encodedMessage []byte) ([]byte, error) {
encodedMessage, err := v1protocol.EncodeMessage(message)
if err != nil {
return nil, errors.Wrap(err, "failed to encode message")
}
return encodedMessage, nil
}
func (p *messageProcessor) tryWrapMessageV1(encodedMessage []byte) ([]byte, error) {
if p.featureFlags.sendV1Messages {
wrappedMessage, err := v1protocol.WrapMessageV1(encodedMessage, p.identity) wrappedMessage, err := v1protocol.WrapMessageV1(encodedMessage, p.identity)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
return wrappedMessage, nil return wrappedMessage, nil
} }
return encodedMessage, nil
}
func (p *messageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) error { func (p *messageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) error {
groupID := datasync.ToOneToOneGroupID(&p.identity.PublicKey, publicKey) groupID := datasync.ToOneToOneGroupID(&p.identity.PublicKey, publicKey)
@ -520,15 +402,9 @@ func (p *messageProcessor) sendMessageSpec(ctx context.Context, publicKey *ecdsa
case messageSpec.SharedSecret != nil: case messageSpec.SharedSecret != nil:
logger.Debug("sending using shared secret") logger.Debug("sending using shared secret")
hash, err = p.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret) hash, err = p.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret)
case messageSpec.PartitionedTopicMode() == encryption.PartitionTopicV1: default:
logger.Debug("sending partitioned topic") logger.Debug("sending partitioned topic")
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey) hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
case !p.featureFlags.genericDiscoveryTopicEnabled:
logger.Debug("sending partitioned topic (generic discovery topic disabled)")
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
default:
logger.Debug("sending using discovery topic")
hash, err = p.transport.SendPrivateOnDiscovery(ctx, newMessage, publicKey)
} }
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View file

@ -17,6 +17,7 @@ import (
"github.com/status-im/status-go/protocol/encryption" "github.com/status-im/status-go/protocol/encryption"
"github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/encryption/sharedsecret" "github.com/status-im/status-go/protocol/encryption/sharedsecret"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/sqlite"
transport "github.com/status-im/status-go/protocol/transport/whisper" transport "github.com/status-im/status-go/protocol/transport/whisper"
v1protocol "github.com/status-im/status-go/protocol/v1" v1protocol "github.com/status-im/status-go/protocol/v1"
@ -33,20 +34,19 @@ type MessageProcessorSuite struct {
processor *messageProcessor processor *messageProcessor
tmpDir string tmpDir string
testMessage v1protocol.Message testMessage Message
logger *zap.Logger logger *zap.Logger
} }
func (s *MessageProcessorSuite) SetupTest() { func (s *MessageProcessorSuite) SetupTest() {
s.testMessage = v1protocol.Message{ s.testMessage = Message{
ChatMessage: protobuf.ChatMessage{
Text: "abc123", Text: "abc123",
ContentT: "text/plain", ChatId: "testing-adamb",
MessageT: "public-group-user-message", ContentType: protobuf.ChatMessage_TEXT_PLAIN,
MessageType: protobuf.ChatMessage_PUBLIC_GROUP,
Clock: 154593077368201, Clock: 154593077368201,
Timestamp: 1545930773682, Timestamp: 1545930773682,
Content: v1protocol.Content{
ChatID: "testing-adamb",
Text: "abc123",
}, },
} }
@ -110,48 +110,6 @@ func (s *MessageProcessorSuite) TearDownTest() {
_ = s.logger.Sync() _ = s.logger.Sync()
} }
func (s *MessageProcessorSuite) TestHandleDecodedMessagesSingle() {
privateKey, err := crypto.GenerateKey()
s.Require().NoError(err)
encodedPayload, err := v1protocol.EncodeMessage(s.testMessage)
s.Require().NoError(err)
message := &types.Message{}
message.Sig = crypto.FromECDSAPub(&privateKey.PublicKey)
message.Payload = encodedPayload
decodedMessages, err := s.processor.handleMessages(message, true)
s.Require().NoError(err)
s.Require().Equal(1, len(decodedMessages))
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
s.Require().Equal(&privateKey.PublicKey, decodedMessages[0].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&privateKey.PublicKey, encodedPayload), decodedMessages[0].ID)
s.Require().Equal(s.testMessage, decodedMessages[0].ParsedMessage)
s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType)
}
func (s *MessageProcessorSuite) TestHandleDecodedMessagesRaw() {
privateKey, err := crypto.GenerateKey()
s.Require().NoError(err)
encodedPayload, err := v1protocol.EncodeMessage(s.testMessage)
s.Require().NoError(err)
message := &types.Message{}
message.Sig = crypto.FromECDSAPub(&privateKey.PublicKey)
message.Payload = encodedPayload
decodedMessages, err := s.processor.handleMessages(message, false)
s.Require().NoError(err)
s.Require().Equal(1, len(decodedMessages))
s.Require().Equal(message, decodedMessages[0].TransportMessage)
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
s.Require().Equal(&privateKey.PublicKey, decodedMessages[0].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&privateKey.PublicKey, encodedPayload), decodedMessages[0].ID)
s.Require().Equal(nil, decodedMessages[0].ParsedMessage)
}
func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() { func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
relayerKey, err := crypto.GenerateKey() relayerKey, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
@ -159,7 +117,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
authorKey, err := crypto.GenerateKey() authorKey, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
encodedPayload, err := v1protocol.EncodeMessage(s.testMessage) encodedPayload, err := proto.Marshal(&s.testMessage)
s.Require().NoError(err) s.Require().NoError(err)
wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey) wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey)
@ -175,8 +133,9 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
s.Require().Equal(1, len(decodedMessages)) s.Require().Equal(1, len(decodedMessages))
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey()) s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID) s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload) s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
s.Require().Equal(s.testMessage, decodedMessages[0].ParsedMessage) s.Require().True(proto.Equal(&s.testMessage.ChatMessage, &parsedMessage))
s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType) s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType)
} }
@ -187,7 +146,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
authorKey, err := crypto.GenerateKey() authorKey, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
encodedPayload, err := v1protocol.EncodeMessage(s.testMessage) encodedPayload, err := proto.Marshal(&s.testMessage)
s.Require().NoError(err) s.Require().NoError(err)
wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey) wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey)
@ -195,7 +154,6 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
dataSyncMessage := datasyncproto.Payload{ dataSyncMessage := datasyncproto.Payload{
Messages: []*datasyncproto.Message{ Messages: []*datasyncproto.Message{
{Body: encodedPayload},
{Body: wrappedPayload}, {Body: wrappedPayload},
}, },
} }
@ -209,18 +167,13 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
s.Require().NoError(err) s.Require().NoError(err)
// We send two messages, the unwrapped one will be attributed to the relayer, while the wrapped one will be attributed to the author // We send two messages, the unwrapped one will be attributed to the relayer, while the wrapped one will be attributed to the author
s.Require().Equal(2, len(decodedMessages)) s.Require().Equal(1, len(decodedMessages))
s.Require().Equal(&relayerKey.PublicKey, decodedMessages[0].SigPubKey()) s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&relayerKey.PublicKey, encodedPayload), decodedMessages[0].ID) s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload) s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
s.Require().Equal(s.testMessage, decodedMessages[0].ParsedMessage) parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
s.Require().True(proto.Equal(&s.testMessage.ChatMessage, &parsedMessage))
s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType) s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType)
s.Require().Equal(&authorKey.PublicKey, decodedMessages[1].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[1].ID)
s.Require().Equal(encodedPayload, decodedMessages[1].DecryptedPayload)
s.Require().Equal(s.testMessage, decodedMessages[1].ParsedMessage)
s.Require().Equal(v1protocol.MessageT, decodedMessages[1].MessageType)
} }
func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() { func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
@ -230,7 +183,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
authorKey, err := crypto.GenerateKey() authorKey, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
encodedPayload, err := v1protocol.EncodeMessage(s.testMessage) encodedPayload, err := proto.Marshal(&s.testMessage)
s.Require().NoError(err) s.Require().NoError(err)
wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey) wrappedPayload, err := v1protocol.WrapMessageV1(encodedPayload, authorKey)
@ -238,8 +191,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
dataSyncMessage := datasyncproto.Payload{ dataSyncMessage := datasyncproto.Payload{
Messages: []*datasyncproto.Message{ Messages: []*datasyncproto.Message{
{Body: encodedPayload}, &datasyncproto.Message{Body: wrappedPayload},
{Body: wrappedPayload},
}, },
} }
marshalledDataSyncMessage, err := proto.Marshal(&dataSyncMessage) marshalledDataSyncMessage, err := proto.Marshal(&dataSyncMessage)
@ -276,16 +228,11 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
// We send two messages, the unwrapped one will be attributed to the relayer, // We send two messages, the unwrapped one will be attributed to the relayer,
// while the wrapped one will be attributed to the author. // while the wrapped one will be attributed to the author.
s.Require().Equal(2, len(decodedMessages)) s.Require().Equal(1, len(decodedMessages))
s.Require().Equal(&relayerKey.PublicKey, decodedMessages[0].SigPubKey()) s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&relayerKey.PublicKey, encodedPayload), decodedMessages[0].ID) s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload) s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
s.Require().Equal(s.testMessage, decodedMessages[0].ParsedMessage) parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
s.Require().True(proto.Equal(&s.testMessage.ChatMessage, &parsedMessage))
s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType) s.Require().Equal(v1protocol.MessageT, decodedMessages[0].MessageType)
s.Require().Equal(&authorKey.PublicKey, decodedMessages[1].SigPubKey())
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[1].ID)
s.Require().Equal(encodedPayload, decodedMessages[1].DecryptedPayload)
s.Require().Equal(s.testMessage, decodedMessages[1].ParsedMessage)
s.Require().Equal(v1protocol.MessageT, decodedMessages[1].MessageType)
} }

View file

@ -4,12 +4,15 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"database/sql" "database/sql"
"strings" "encoding/hex"
"encoding/json"
"strconv"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/golang/protobuf/proto"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
enstypes "github.com/status-im/status-go/eth-node/types/ens" enstypes "github.com/status-im/status-go/eth-node/types/ens"
@ -18,11 +21,14 @@ import (
"github.com/status-im/status-go/protocol/encryption/sharedsecret" "github.com/status-im/status-go/protocol/encryption/sharedsecret"
"github.com/status-im/status-go/protocol/identity/alias" "github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/identity/identicon" "github.com/status-im/status-go/protocol/identity/identicon"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/sqlite"
transport "github.com/status-im/status-go/protocol/transport/whisper" transport "github.com/status-im/status-go/protocol/transport/whisper"
v1protocol "github.com/status-im/status-go/protocol/v1" v1protocol "github.com/status-im/status-go/protocol/v1"
) )
const PubKeyStringLength = 132
var ( var (
ErrChatIDEmpty = errors.New("chat ID is empty") ErrChatIDEmpty = errors.New("chat ID is empty")
ErrNotImplemented = errors.New("not implemented") ErrNotImplemented = errors.New("not implemented")
@ -46,20 +52,29 @@ type Messenger struct {
processor *messageProcessor processor *messageProcessor
logger *zap.Logger logger *zap.Logger
ownMessages []*v1protocol.Message
featureFlags featureFlags featureFlags featureFlags
messagesPersistenceEnabled bool messagesPersistenceEnabled bool
shutdownTasks []func() error shutdownTasks []func() error
} }
type featureFlags struct { type RawResponse struct {
genericDiscoveryTopicEnabled bool Filter *transport.Filter `json:"filter"`
// sendV1Messages indicates whether we should send Messages []*v1protocol.StatusMessage `json:"messages"`
// messages compatible only with V1 and later. }
// V1 messages adds additional wrapping
// which contains a signature and payload.
sendV1Messages bool
type MessengerResponse struct {
Chats []*Chat `json:"chats,omitEmpty"`
Messages []*Message `json:"messages,omitEmpty"`
Contacts []*Contact `json:"contacts,omitEmpty"`
// Raw unprocessed messages
RawMessages []*RawResponse `json:"rawMessages,omitEmpty"`
}
func (m *MessengerResponse) IsEmpty() bool {
return len(m.Chats) == 0 && len(m.Messages) == 0 && len(m.Contacts) == 0 && len(m.RawMessages) == 0
}
type featureFlags struct {
// datasync indicates whether direct messages should be sent exclusively // datasync indicates whether direct messages should be sent exclusively
// using datasync, breaking change for non-v1 clients. Public messages // using datasync, breaking change for non-v1 clients. Public messages
// are not impacted // are not impacted
@ -117,13 +132,6 @@ func WithCustomLogger(logger *zap.Logger) Option {
} }
} }
func WithGenericDiscoveryTopicSupport() Option {
return func(c *config) error {
c.featureFlags.genericDiscoveryTopicEnabled = true
return nil
}
}
func WithMessagesPersistenceEnabled() Option { func WithMessagesPersistenceEnabled() Option {
return func(c *config) error { return func(c *config) error {
c.messagesPersistenceEnabled = true c.messagesPersistenceEnabled = true
@ -145,13 +153,6 @@ func WithDatabase(db *sql.DB) Option {
} }
} }
func WithSendV1Messages() Option {
return func(c *config) error {
c.featureFlags.sendV1Messages = true
return nil
}
}
func WithDatasync() func(c *config) error { func WithDatasync() func(c *config) error {
return func(c *config) error { return func(c *config) error {
c.featureFlags.datasync = true c.featureFlags.datasync = true
@ -267,7 +268,6 @@ func NewMessenger(
nil, nil,
c.envelopesMonitorConfig, c.envelopesMonitorConfig,
logger, logger,
transport.SetGenericDiscoveryTopicSupport(c.featureFlags.genericDiscoveryTopicEnabled),
) )
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to create a WhisperServiceTransport") return nil, errors.Wrap(err, "failed to create a WhisperServiceTransport")
@ -624,47 +624,58 @@ func (m *Messenger) Contacts() ([]*Contact, error) {
return m.persistence.Contacts() return m.persistence.Contacts()
} }
func (m *Messenger) Send(ctx context.Context, chatID string, data []byte) ([][]byte, error) { func timestampInMs() uint64 {
logger := m.logger.With(zap.String("site", "Send"), zap.String("chatID", chatID)) return uint64(time.Now().UnixNano() / int64(time.Millisecond))
}
// A valid added chat is required. // ReSendChatMessage pulls a message from the database and sends it again
chat, err := m.chatByID(chatID) func (m *Messenger) ReSendChatMessage(ctx context.Context, messageID string) (*MessengerResponse, error) {
logger := m.logger.With(zap.String("site", "ReSendChatMessage"))
var response MessengerResponse
message, err := m.persistence.MessageByID(messageID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if message == nil {
return nil, errors.New("message not found")
}
if message.RawPayload == nil {
return nil, errors.New("message payload not found, can't resend message")
}
clock, err := m.persistence.LastMessageClock(chat.ID) chat, err := m.chatByID(message.LocalChatID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
logger.Debug("last message clock received", zap.Int64("clock", clock))
switch chat.ChatType { switch chat.ChatType {
case ChatTypeOneToOne: case ChatTypeOneToOne:
logger.Debug("sending private message", zap.Binary("publicKey", crypto.FromECDSAPub(chat.PublicKey))) publicKey := crypto.FromECDSAPub(chat.PublicKey)
id, message, err := m.processor.SendPrivate(ctx, chat.PublicKey, chat.ID, data, clock) logger.Debug("re-sending private message", zap.Binary("publicKey", publicKey))
id, err := m.processor.SendPrivateRaw(ctx, chat.PublicKey, message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := m.cacheOwnMessage(chatID, id, message); err != nil { message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, message.RawPayload)
if err != nil {
return nil, err return nil, err
} }
return [][]byte{id}, nil
case ChatTypePublic: case ChatTypePublic:
logger.Debug("sending public message", zap.String("chatName", chat.Name)) logger.Debug("re-sending public message", zap.String("chatName", chat.Name))
id, err := m.processor.SendPublic(ctx, chat.ID, data, clock) id, err := m.processor.SendPublicRaw(ctx, chat.ID, message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return [][]byte{id}, nil message.ID = "0x" + hex.EncodeToString(id)
case ChatTypePrivateGroupChat: case ChatTypePrivateGroupChat:
logger.Debug("sending group message", zap.String("chatName", chat.Name)) logger.Debug("re-sending group message", zap.String("chatName", chat.Name))
recipients, err := chat.MembersAsPublicKeys() recipients, err := chat.MembersAsPublicKeys()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Filter me out of recipients.
n := 0 n := 0
for _, item := range recipients { for _, item := range recipients {
if !isPubKeyEqual(item, &m.identity.PublicKey) { if !isPubKeyEqual(item, &m.identity.PublicKey) {
@ -672,40 +683,186 @@ func (m *Messenger) Send(ctx context.Context, chatID string, data []byte) ([][]b
n++ n++
} }
} }
ids, messages, err := m.processor.SendGroup(ctx, recipients[:n], chat.ID, data, clock) id, err := m.processor.SendGroupRaw(ctx, recipients[:n], message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for idx, message := range messages {
if err := m.cacheOwnMessage(chatID, ids[idx], message); err != nil { message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, message.RawPayload)
if err != nil {
return nil, err return nil, err
} }
}
return ids, nil
default: default:
return nil, errors.New("chat is neither public nor private") return nil, errors.New("chat type not supported")
}
} }
func (m *Messenger) cacheOwnMessage(chatID string, id []byte, message *v1protocol.Message) error { response.Messages = []*Message{message}
// Save our message because it won't be received from the transport layer. response.Chats = []*Chat{chat}
message.ID = id // a Message need ID to be properly stored in the db return &response, nil
message.SigPubKey = &m.identity.PublicKey }
message.ChatID = chatID
if m.messagesPersistenceEnabled { // sendToPairedDevices will check if we have any paired devices and send to them if necessary
_, err := m.persistence.SaveMessages([]*v1protocol.Message{message}) func (m *Messenger) sendToPairedDevices(ctx context.Context, payload []byte) error {
activeInstallations, err := m.encryptor.GetOurActiveInstallations(&m.identity.PublicKey)
if err != nil {
return err
}
// We send a message to any paired device
if len(activeInstallations) > 1 {
_, err := m.processor.SendPrivateRaw(ctx, &m.identity.PublicKey, payload)
if err != nil { if err != nil {
return err return err
} }
} }
// Cache it to be returned in Retrieve().
m.ownMessages = append(m.ownMessages, message)
return nil return nil
} }
// SendChatMessage takes a minimal message and sends it based on the corresponding chat
func (m *Messenger) SendChatMessage(ctx context.Context, message *Message) (*MessengerResponse, error) {
logger := m.logger.With(zap.String("site", "Send"), zap.String("chatID", message.ChatId))
var response MessengerResponse
// A valid added chat is required.
chat, err := m.chatByID(message.ChatId)
if err != nil {
return nil, err
}
clock := chat.LastClockValue
timestamp := timestampInMs()
if clock == 0 || clock < timestamp {
clock = timestamp
} else {
clock = clock + 1
}
message.LocalChatID = chat.ID
message.Clock = clock
message.Timestamp = timestamp
message.From = "0x" + hex.EncodeToString(crypto.FromECDSAPub(&m.identity.PublicKey))
message.SigPubKey = &m.identity.PublicKey
message.WhisperTimestamp = timestamp
message.Seen = true
message.OutgoingStatus = OutgoingStatusSending
identicon, err := identicon.GenerateBase64(message.From)
if err != nil {
return nil, err
}
message.Identicon = identicon
alias, err := alias.GenerateFromPublicKeyString(message.From)
if err != nil {
return nil, err
}
message.Alias = alias
switch chat.ChatType {
case ChatTypeOneToOne:
publicKey := crypto.FromECDSAPub(chat.PublicKey)
logger.Debug("sending private message", zap.Binary("publicKey", publicKey))
message.MessageType = protobuf.ChatMessage_ONE_TO_ONE
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
id, err := m.processor.SendPrivateRaw(ctx, chat.PublicKey, encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, encodedMessage)
if err != nil {
return nil, err
}
case ChatTypePublic:
logger.Debug("sending public message", zap.String("chatName", chat.Name))
message.MessageType = protobuf.ChatMessage_PUBLIC_GROUP
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
id, err := m.processor.SendPublicRaw(ctx, chat.ID, encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
case ChatTypePrivateGroupChat:
logger.Debug("sending public message", zap.String("chatName", chat.Name))
message.MessageType = protobuf.ChatMessage_PRIVATE_GROUP
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
logger.Debug("sending group message", zap.String("chatName", chat.Name))
recipients, err := chat.MembersAsPublicKeys()
if err != nil {
return nil, err
}
n := 0
for _, item := range recipients {
if !isPubKeyEqual(item, &m.identity.PublicKey) {
recipients[n] = item
n++
}
}
id, err := m.processor.SendGroupRaw(ctx, recipients[:n], encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, encodedMessage)
if err != nil {
return nil, err
}
default:
return nil, errors.New("chat type not supported")
}
err = message.PrepareContent()
if err != nil {
return nil, err
}
jsonMessage, err := json.Marshal(message)
if err != nil {
return nil, err
}
chat.LastClockValue = clock
chat.LastMessage = jsonMessage
chat.Timestamp = int64(timestamp)
if err := m.SaveChat(*chat); err != nil {
return nil, err
}
err = m.persistence.SaveMessagesLegacy([]*Message{message})
if err != nil {
return nil, err
}
response.Chats = []*Chat{chat}
response.Messages = []*Message{message}
return &response, nil
}
// SendRaw takes encoded data, encrypts it and sends through the wire. // SendRaw takes encoded data, encrypts it and sends through the wire.
// DEPRECATED // DEPRECATED
func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte, error) { func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte, error) {
@ -717,94 +874,48 @@ func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte
return nil, errors.New("chat is neither public nor private") return nil, errors.New("chat is neither public nor private")
} }
type RetrieveConfig struct { // RetrieveAll retrieves messages from all filters, processes them and returns a
From time.Time // MessengerResponse to the client
To time.Time func (m *Messenger) RetrieveAll() (*MessengerResponse, error) {
latest bool
last24Hours bool
}
var (
RetrieveLatest = RetrieveConfig{latest: true}
RetrieveLastDay = RetrieveConfig{latest: true, last24Hours: true}
)
// RetrieveAll retrieves all previously fetched messages
func (m *Messenger) RetrieveAll(ctx context.Context, c RetrieveConfig) ([]*v1protocol.Message, error) {
result, err := m.retrieveLatest(ctx)
if err != nil {
return nil, err
}
postProcess := newPostProcessor(m, postProcessorConfig{
MatchChat: true,
Persist: true,
})
result, err = postProcess.Run(result)
if err != nil {
return nil, errors.Wrap(err, "failed to post process messages")
}
retrievedMessages, err := m.retrieveSaved(ctx, c)
if err != nil {
return nil, errors.Wrap(err, "failed to get saved messages")
}
result = append(result, retrievedMessages...)
// Include own messages.
result = append(result, m.ownMessages...)
m.ownMessages = nil
return result, nil
}
func (m *Messenger) retrieveLatest(ctx context.Context) ([]*v1protocol.Message, error) {
latest, err := m.transport.RetrieveAllMessages()
if err != nil {
return nil, errors.Wrap(err, "failed to retrieve messages")
}
logger := m.logger.With(zap.String("site", "retrieveLatest"))
logger.Debug("retrieved messages", zap.Int("count", len(latest)))
var result []*v1protocol.Message
for _, transpMessage := range latest {
protoMessages, err := m.processor.Process(transpMessage.Message)
if err != nil {
return nil, err
}
result = append(result, protoMessages...)
}
return result, nil
}
func (m *Messenger) retrieveSaved(ctx context.Context, c RetrieveConfig) (messages []*v1protocol.Message, err error) {
if !m.messagesPersistenceEnabled {
return nil, nil
}
if !c.latest {
return m.persistence.Messages(c.From, c.To)
}
if c.last24Hours {
to := time.Now()
from := to.Add(-time.Hour * 24)
return m.persistence.Messages(from, to)
}
return nil, nil
}
// DEPRECATED
func (m *Messenger) RetrieveRawAll() (map[transport.Filter][]*v1protocol.StatusMessage, error) {
chatWithMessages, err := m.transport.RetrieveRawAll() chatWithMessages, err := m.transport.RetrieveRawAll()
if err != nil { if err != nil {
return nil, err return nil, err
} }
logger := m.logger.With(zap.String("site", "RetrieveRawAll")) return m.handleRetrievedMessages(chatWithMessages)
result := make(map[transport.Filter][]*v1protocol.StatusMessage) }
func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filter][]*types.Message) (*MessengerResponse, error) {
response := &MessengerResponse{
Chats: []*Chat{},
Messages: []*Message{},
}
allChats, err := m.persistence.Chats()
if err != nil {
return nil, err
}
postProcessor := newPostProcessor(m, postProcessorConfig{MatchChat: true})
logger := m.logger.With(zap.String("site", "RetrieveAll"))
rawMessages := make(map[transport.Filter][]*v1protocol.StatusMessage)
// We should query this instead
contacts, err := m.Contacts()
if err != nil {
return nil, err
}
blockedContacts := make(map[string]bool)
for _, c := range contacts {
if c.IsBlocked() {
blockedContacts[c.ID] = true
}
}
allContactsMap := make(map[string]*Contact)
allChatsMap := make(map[string]*Chat)
existingMessagesMap := make(map[string]bool)
for chat, messages := range chatWithMessages { for chat, messages := range chatWithMessages {
for _, shhMessage := range messages { for _, shhMessage := range messages {
@ -816,48 +927,130 @@ func (m *Messenger) RetrieveRawAll() (map[transport.Filter][]*v1protocol.StatusM
} }
for _, msg := range statusMessages { for _, msg := range statusMessages {
// Check for messages from blocked users
senderID := "0x" + hex.EncodeToString(crypto.FromECDSAPub(msg.SigPubKey()))
if blockedContacts[senderID] {
continue
}
// Don't process duplicates
messageID := "0x" + hex.EncodeToString(msg.ID)
if _, ok := existingMessagesMap[messageID]; ok {
continue
}
existingMessagesMap[messageID] = true
// Check against the database, this is probably a bit slow for
// each message, but for now might do, we'll make it faster later
existingMessage, err := m.persistence.MessageByID(messageID)
if err != nil && err != errRecordNotFound {
return nil, err
}
if existingMessage != nil {
continue
}
publicKey := msg.SigPubKey()
if publicKey == nil {
return nil, errors.New("public key can't be nil")
}
var contact *Contact
if c, ok := allContactsMap[senderID]; ok {
contact = c
} else {
c, err := buildContact(publicKey)
if err != nil {
logger.Info("failed to build contact", zap.Error(err))
continue
}
contact = c
allContactsMap[senderID] = c
response.Contacts = append(response.Contacts, c)
}
if msg.ParsedMessage != nil { if msg.ParsedMessage != nil {
if textMessage, ok := msg.ParsedMessage.(v1protocol.Message); ok { if textMessage, ok := msg.ParsedMessage.(protobuf.ChatMessage); ok {
textMessage.Content = v1protocol.PrepareContent(textMessage.Content) receivedMessage := &Message{
msg.ParsedMessage = textMessage ID: messageID,
ChatMessage: textMessage,
From: contact.ID,
Alias: contact.Alias,
SigPubKey: publicKey,
Identicon: contact.Identicon,
WhisperTimestamp: uint64(msg.TransportMessage.Timestamp) * 1000,
} }
receivedMessage.PrepareContent()
chat, err := postProcessor.matchMessage(receivedMessage, allChats)
if err != nil {
logger.Warn("failed to match message", zap.String("receivedChatID", receivedMessage.ChatId), zap.Error(err))
continue
}
// If deleted-at is greater, ignore message
if chat.DeletedAtClockValue >= receivedMessage.Clock {
continue
}
// Set the LocalChatID for the message
receivedMessage.LocalChatID = chat.ID
if c, ok := allChatsMap[chat.ID]; ok {
chat = c
}
// Increase unviewed count
if !isPubKeyEqual(receivedMessage.SigPubKey, &m.identity.PublicKey) {
chat.UnviewedMessagesCount++
} else {
// Our own message, mark as sent
receivedMessage.OutgoingStatus = OutgoingStatusSent
}
// Update chat timestamp
chat.Timestamp = int64(timestampInMs())
// Update last clock value
if chat.LastClockValue <= receivedMessage.Clock {
chat.LastClockValue = receivedMessage.Clock
encodedLastMessage, err := json.Marshal(receivedMessage)
if err != nil {
return nil, err
}
chat.LastMessage = encodedLastMessage
}
// Set chat active
chat.Active = true
// Set in the map
allChatsMap[chat.ID] = chat
// Add to response
response.Messages = append(response.Messages, receivedMessage)
}
} else {
// RawMessage, not processed here, pass straight to the client
rawMessages[chat] = append(rawMessages[chat], msg)
} }
} }
result[chat] = append(result[chat], statusMessages...)
} }
} }
err = m.updateContactsFromMessages(result) err = m.persistence.SetContactsGeneratedData(response.Contacts, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return result, nil for _, c := range allChatsMap {
response.Chats = append(response.Chats, c)
} }
func (m *Messenger) updateContactsFromMessages(messages map[transport.Filter][]*v1protocol.StatusMessage) error { m.persistence.SaveChats(response.Chats)
allContactsMap := make(map[string]bool) m.SaveMessages(response.Messages)
var allContacts []Contact
for _, chatMessages := range messages {
for _, message := range chatMessages {
publicKey := message.SigPubKey()
address := strings.ToLower(crypto.PubkeyToAddress(*publicKey).Hex())
if _, ok := allContactsMap[address]; ok { for filter, messages := range rawMessages {
continue response.RawMessages = append(response.RawMessages, &RawResponse{Filter: &filter, Messages: messages})
} }
contact, err := buildContact(publicKey) return response, nil
if err != nil {
continue
}
allContactsMap[address] = true
allContacts = append(allContacts, *contact)
}
}
return m.persistence.SetContactsGeneratedData(allContacts, nil)
} }
func (m *Messenger) RequestHistoricMessages( func (m *Messenger) RequestHistoricMessages(
@ -909,6 +1102,47 @@ func (m *Messenger) SaveMessages(messages []*Message) error {
return m.persistence.SaveMessagesLegacy(messages) return m.persistence.SaveMessagesLegacy(messages)
} }
// AddSystemMessages format an array of system-messages and saves them to the database
// It's needed until group chats are fully in status-go.
func (m *Messenger) AddSystemMessages(messages []*Message) ([]*Message, error) {
timestamp := timestampInMs()
for _, message := range messages {
message.LocalChatID = message.ChatId
message.Timestamp = timestamp
message.WhisperTimestamp = timestamp
message.Seen = true
identicon, err := identicon.GenerateBase64(message.From)
if err != nil {
return nil, err
}
message.Identicon = identicon
alias, err := alias.GenerateFromPublicKeyString(message.From)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(crypto.Keccak256([]byte(message.Text+message.From+strconv.FormatUint(message.Clock, 10))))
message.Alias = alias
message.ContentType = protobuf.ChatMessage_STATUS
message.MessageType = protobuf.ChatMessage_SYSTEM_MESSAGE_PRIVATE_GROUP
err = message.PrepareContent()
if err != nil {
return nil, err
}
}
err := m.SaveMessages(messages)
if err != nil {
return nil, err
}
return messages, nil
}
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
func (m *Messenger) DeleteMessage(id string) error { func (m *Messenger) DeleteMessage(id string) error {
return m.persistence.DeleteMessage(id) return m.persistence.DeleteMessage(id)
@ -920,8 +1154,8 @@ func (m *Messenger) DeleteMessagesByChatID(id string) error {
} }
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
func (m *Messenger) MarkMessagesSeen(ids ...string) error { func (m *Messenger) MarkMessagesSeen(chatID string, ids []string) error {
return m.persistence.MarkMessagesSeen(ids...) return m.persistence.MarkMessagesSeen(chatID, ids)
} }
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
@ -955,100 +1189,68 @@ func newPostProcessor(m *Messenger, config postProcessorConfig) *postProcessor {
} }
} }
func (p *postProcessor) Run(messages []*v1protocol.Message) ([]*v1protocol.Message, error) { func (p *postProcessor) matchMessages(messages []*Message) ([]*Message, error) {
var err error
p.logger.Debug("running post processor", zap.Int("messages", len(messages)))
var fns []func([]*v1protocol.Message) ([]*v1protocol.Message, error)
// Order is important. Persisting messages should be always at the end.
if p.config.MatchChat {
fns = append(fns, p.matchMessages)
}
if p.config.Parse {
fns = append(fns, p.parseMessages)
}
if p.config.Persist {
fns = append(fns, p.saveMessages)
}
for _, fn := range fns {
messages, err = fn(messages)
if err != nil {
return nil, err
}
}
return messages, nil
}
func (p *postProcessor) saveMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
_, err := p.persistence.SaveMessages(messages)
if err != nil {
return nil, err
}
return messages, nil
}
func (p *postProcessor) parseMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
for _, m := range messages {
m.Content = v1protocol.PrepareContent(m.Content)
}
return messages, nil
}
func (p *postProcessor) matchMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
chats, err := p.persistence.Chats() chats, err := p.persistence.Chats()
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := make([]*v1protocol.Message, 0, len(messages)) result := make([]*Message, 0, len(messages))
for _, message := range messages { for _, message := range messages {
chat, err := p.matchMessage(message, chats) chat, err := p.matchMessage(message, chats)
if err != nil { if err != nil {
p.logger.Error("failed to match a chat to a message", zap.Error(err)) p.logger.Error("failed to match a chat to a message", zap.Error(err))
continue continue
} }
message.ChatID = chat.ID message.LocalChatID = chat.ID
result = append(result, message) result = append(result, message)
} }
return result, nil return result, nil
} }
func (p *postProcessor) matchMessage(message *v1protocol.Message, chats []*Chat) (*Chat, error) { func (p *postProcessor) matchMessage(message *Message, chats []*Chat) (*Chat, error) {
if message.SigPubKey == nil { if message.SigPubKey == nil {
p.logger.Error("public key can't be empty") p.logger.Error("public key can't be empty")
return nil, errors.New("received a message with empty public key") return nil, errors.New("received a message with empty public key")
} }
switch { switch {
case message.MessageT == v1protocol.MessageTypePublicGroup: case message.MessageType == protobuf.ChatMessage_PUBLIC_GROUP:
// For public messages, all outgoing and incoming messages have the same chatID // For public messages, all outgoing and incoming messages have the same chatID
// equal to a public chat name. // equal to a public chat name.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
return nil, errors.New("received a public message from non-existing chat") return nil, errors.New("received a public message from non-existing chat")
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivate && isPubKeyEqual(message.SigPubKey, p.myPublicKey): case message.MessageType == protobuf.ChatMessage_ONE_TO_ONE && isPubKeyEqual(message.SigPubKey, p.myPublicKey):
// It's a private message coming from us so we rely on Message.Content.ChatID. // It's a private message coming from us so we rely on Message.ChatId
// If chat does not exist, it should be created to support multidevice synchronization. // If chat does not exist, it should be created to support multidevice synchronization.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
// TODO: this should be a three-word name used in the mobile client if len(chatID) != PubKeyStringLength {
newChat := CreateOneToOneChat(chatID[:8], message.SigPubKey) return nil, errors.New("invalid pubkey length")
}
bytePubKey, err := hex.DecodeString(chatID[2:])
if err != nil {
return nil, errors.Wrap(err, "failed to decode hex chatID")
}
pubKey, err := crypto.UnmarshalPubkey(bytePubKey)
if err != nil {
return nil, errors.Wrap(err, "failed to decode pubkey")
}
newChat := CreateOneToOneChat(chatID[:8], pubKey)
if err := p.persistence.SaveChat(newChat); err != nil { if err := p.persistence.SaveChat(newChat); err != nil {
return nil, errors.Wrap(err, "failed to save newly created chat") return nil, errors.Wrap(err, "failed to save newly created chat")
} }
chat = &newChat chat = &newChat
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivate: case message.MessageType == protobuf.ChatMessage_ONE_TO_ONE:
// It's an incoming private message. ChatID is calculated from the signature. // It's an incoming private message. ChatID is calculated from the signature.
// If a chat does not exist, a new one is created and saved. // If a chat does not exist, a new one is created and saved.
chatID := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey)) chatID := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
@ -1062,21 +1264,34 @@ func (p *postProcessor) matchMessage(message *v1protocol.Message, chats []*Chat)
chat = &newChat chat = &newChat
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivateGroup: case message.MessageType == protobuf.ChatMessage_PRIVATE_GROUP:
// In the case of a group message, ChatID is the same for all messages belonging to a group. // In the case of a group message, ChatID is the same for all messages belonging to a group.
// It needs to be verified if the signature public key belongs to the chat. // It needs to be verified if the signature public key belongs to the chat.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
return nil, errors.New("received group chat message for non-existing chat") return nil, errors.New("received group chat message for non-existing chat")
} }
sigPubKeyHex := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey)) theirKeyHex := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
myKeyHex := types.EncodeHex(crypto.FromECDSAPub(p.myPublicKey))
var theyJoined bool
var iJoined bool
for _, member := range chat.Members { for _, member := range chat.Members {
if member.ID == sigPubKeyHex { if member.ID == theirKeyHex && member.Joined {
theyJoined = true
}
}
for _, member := range chat.Members {
if member.ID == myKeyHex && member.Joined {
iJoined = true
}
}
if theyJoined && iJoined {
return chat, nil return chat, nil
} }
}
return nil, errors.New("did not find a matching group chat") return nil, errors.New("did not find a matching group chat")
default: default:
return nil, errors.New("can not match a chat because there is no valid case") return nil, errors.New("can not match a chat because there is no valid case")
@ -1098,7 +1313,7 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
} }
// Update contacts // Update contacts
var contacts []Contact var contacts []*Contact
for _, details := range ensResponse { for _, details := range ensResponse {
if details.Error == nil { if details.Error == nil {
contact, err := buildContact(details.PublicKey) contact, err := buildContact(details.PublicKey)
@ -1109,7 +1324,7 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
contact.ENSVerifiedAt = details.VerifiedAt contact.ENSVerifiedAt = details.VerifiedAt
contact.Name = details.Name contact.Name = details.Name
contacts = append(contacts, *contact) contacts = append(contacts, contact)
} else { } else {
m.logger.Warn("Failed to resolve ens name", m.logger.Warn("Failed to resolve ens name",
zap.String("name", details.Name), zap.String("name", details.Name),
@ -1133,8 +1348,3 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
func GenerateAlias(id string) (string, error) { func GenerateAlias(id string) (string, error) {
return alias.GenerateFromPublicKeyString(id) return alias.GenerateFromPublicKeyString(id)
} }
// PrepareContent parses the content of a message and returns the parsed version
func (m *Messenger) PrepareContent(content v1protocol.Content) v1protocol.Content {
return v1protocol.PrepareContent(content)
}

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,15 @@
// Code generated by go-bindata. DO NOT EDIT. // Code generated by go-bindata. DO NOT EDIT.
// sources: // sources:
// 000001_init.down.db.sql (82B) // 000001_init.down.db.sql (82B)
// 000001_init.up.db.sql (840B) // 000001_init.up.db.sql (832B)
// 000002_add_chats.down.db.sql (74B) // 000002_add_chats.down.db.sql (74B)
// 000002_add_chats.up.db.sql (599B) // 000002_add_chats.up.db.sql (495B)
// 000003_add_contacts.down.db.sql (21B) // 000003_add_contacts.down.db.sql (21B)
// 000003_add_contacts.up.db.sql (381B) // 000003_add_contacts.up.db.sql (381B)
// 000004_user_messages_compatibility.down.sql (33B) // 000004_user_messages_compatibility.down.sql (33B)
// 000004_user_messages_compatibility.up.sql (928B) // 000004_user_messages_compatibility.up.sql (980B)
// 1567112142_user_messages.down.sql (26B) // 1567112142_user_messages.down.sql (26B)
// 1567112142_user_messages.up.sql (551B) // 1567112142_user_messages.up.sql (543B)
// doc.go (377B) // doc.go (377B)
package migrations package migrations
@ -94,12 +94,12 @@ func _000001_initDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000001_init.down.db.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "000001_init.down.db.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe8, 0x5f, 0xe0, 0x6, 0xfc, 0xed, 0xb7, 0xff, 0xb5, 0xf3, 0x33, 0x45, 0x1, 0x5b, 0x84, 0x80, 0x74, 0x60, 0x81, 0xa6, 0x8b, 0xb4, 0xd4, 0xad, 0x10, 0xa8, 0xb3, 0x61, 0x6f, 0xc5, 0x2f, 0xaa}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe8, 0x5f, 0xe0, 0x6, 0xfc, 0xed, 0xb7, 0xff, 0xb5, 0xf3, 0x33, 0x45, 0x1, 0x5b, 0x84, 0x80, 0x74, 0x60, 0x81, 0xa6, 0x8b, 0xb4, 0xd4, 0xad, 0x10, 0xa8, 0xb3, 0x61, 0x6f, 0xc5, 0x2f, 0xaa}}
return a, nil return a, nil
} }
var __000001_initUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x52\xb1\x6e\xc2\x30\x14\xdc\xf3\x15\x6f\x24\x12\x43\xf7\x4e\x0e\xbc\x80\xd5\xd4\x6e\x1d\xa7\xc0\x14\x19\xe2\x82\x0b\x09\x11\x36\x52\xf9\xfb\xaa\x49\x8c\x02\x45\x15\xac\xef\xce\xe7\xbb\x7b\x6f\x24\x90\x48\x04\x49\xa2\x04\x81\xc6\xc0\xb8\x04\x9c\xd3\x54\xa6\x70\xb4\xfa\x90\x97\xda\x5a\xb5\xd6\x16\x06\x01\x00\x80\x29\x20\x4a\x78\x04\x19\xa3\xef\x19\x36\x6c\x96\x25\xc9\xb0\x01\x57\x1b\xe5\x72\x53\xc0\x07\x11\xa3\x29\x11\xd7\xe8\xbe\x72\xba\x72\xb9\x3b\xd5\xda\x53\x5a\xa4\xfb\xe3\x06\xe2\xf4\xb7\x03\x89\x73\xd9\x49\xec\xf6\xab\x2d\x44\x74\x42\x59\x37\x71\xa6\xd4\xd6\xa9\xb2\xbe\x98\xfa\xaf\xbc\xa1\x9e\x82\x37\x71\x29\x5c\x1f\x97\x3b\xb3\xca\xb7\xfa\xd4\xc4\x6b\x87\x9f\x3b\xb5\xb6\x40\x99\x3c\x07\x81\x31\xc6\x24\x4b\x24\x3c\x05\xe1\x73\x10\x74\xdd\x51\x36\xc6\xb9\x0f\x6f\x81\xb3\xcb\xe6\x06\x1d\xd2\x7b\x71\xab\xed\x52\x97\x4b\x7d\xb0\x1b\x53\xe7\xc7\xba\x50\xae\x5f\xb9\x2f\xf4\x4d\xd0\x57\x22\x16\xf0\x82\x8b\xab\x72\x0b\xe5\x54\xbb\x99\x47\x56\x12\x73\x81\x74\xc2\x1a\xbd\xb3\x4d\x10\x18\xa3\x40\x36\xc2\xb4\x79\x6e\x07\xa6\x08\x83\x10\x66\x54\x4e\x79\x26\x41\xf0\x19\x1d\xff\x9f\xa5\x91\xea\x02\x75\x29\xae\x1a\x7e\xc8\xa6\x2a\x4a\x53\x41\xc4\x79\x82\x84\xfd\x5d\x46\x4c\x92\x14\x5b\xe6\xd7\xde\x54\xba\xb8\x8b\x7a\x7f\xf6\x96\xdf\x5e\xbc\x67\x0e\x7b\x81\xc2\xdf\x63\xf8\x09\x00\x00\xff\xff\x66\xab\x2d\x2f\x48\x03\x00\x00") var __000001_initUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\xcd\x6e\xea\x30\x10\x85\xf7\x79\x8a\x59\x12\x89\xc5\xdd\xdf\x95\x03\x13\xb0\x9a\xda\xad\xe3\x14\x58\x45\x26\x71\xc1\x85\x84\x08\x1b\xa9\xbc\x7d\x45\x7e\x68\x48\xab\x0a\x96\x9e\x39\x3e\x9e\xef\x8c\x27\x02\x89\x44\x90\x24\x88\x10\x68\x08\x8c\x4b\xc0\x25\x8d\x65\x0c\x27\xab\x8f\x69\xa1\xad\x55\x1b\x6d\x61\xe4\x01\x00\x98\x1c\x82\x88\x07\x90\x30\xfa\x9a\x60\xad\x66\x49\x14\x8d\xeb\x66\xb6\x55\x2e\x35\x39\xbc\x11\x31\x99\x13\x31\xec\x1e\x4a\xa7\x4b\x97\xba\x73\xa5\x81\x32\xd9\x54\x5b\xff\x41\xd5\xe9\x4f\x07\x12\x97\xed\x31\xdb\x1f\xb2\x1d\x04\x74\xf6\x2d\x30\x85\xb6\x4e\x15\xd5\x4d\xb5\x7b\xa2\x1b\xa4\xe7\xd0\x3d\x7e\x6b\x5c\x9d\xd6\x7b\x93\xa5\x3b\x7d\xae\xb1\x9a\xe2\xfb\x5e\x6d\xec\x65\x96\x2b\x00\x4c\x31\x24\x49\x24\xe1\x9f\xe7\xff\xf7\xbc\x36\x33\xca\xa6\xb8\xec\xa0\x2d\x70\x76\x9b\xd8\xa8\xed\xf4\x6e\xfc\x96\x72\xa1\x8b\xb5\x3e\xda\xad\xa9\xd2\x53\x95\x2b\xd7\x8f\xba\x0b\xf2\x45\xd0\x67\x22\x56\xf0\x84\xab\x41\xa8\xb9\x72\xaa\xd9\xc8\x23\xab\x08\xb9\x40\x3a\x63\xb5\xdf\x75\x4c\x10\x18\xa2\x40\x36\xc1\xb8\xbe\x6e\x47\x26\xf7\x3d\x1f\x16\x54\xce\x79\x22\x41\xf0\x05\x9d\xfe\xcd\x52\x5b\xb5\x40\x2d\xc5\x20\xe1\x87\xc6\x54\x79\x61\x4a\x08\x38\x8f\x90\xb0\x9f\xcb\x08\x49\x14\x63\xa3\xfc\x38\x98\x52\xe7\x77\x49\xef\x67\x6f\xf4\xcd\x4f\xef\x94\xe3\x1e\x90\x7f\xf9\x0c\x5f\x01\x00\x00\xff\xff\x22\x17\x48\xa6\x40\x03\x00\x00")
func _000001_initUpDbSqlBytes() ([]byte, error) { func _000001_initUpDbSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -114,8 +114,8 @@ func _000001_initUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000001_init.up.db.sql", size: 840, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "000001_init.up.db.sql", size: 832, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe7, 0x27, 0x96, 0x3b, 0x72, 0x81, 0x7d, 0xba, 0xa4, 0xfb, 0xf7, 0x4, 0xd, 0x6f, 0xc8, 0x30, 0xfe, 0x47, 0xe0, 0x9, 0xf, 0x43, 0x13, 0x6, 0x55, 0xfc, 0xee, 0x15, 0x69, 0x99, 0x53, 0x3f}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1c, 0xa4, 0xac, 0x0, 0xd3, 0x19, 0x53, 0x35, 0x91, 0x1c, 0x94, 0xea, 0xde, 0xa7, 0x75, 0xb6, 0x73, 0x1d, 0x42, 0x14, 0xca, 0x84, 0x5b, 0xdb, 0x10, 0x94, 0x28, 0xc0, 0x33, 0x95, 0x7f, 0xf}}
return a, nil return a, nil
} }
@ -134,12 +134,12 @@ func _000002_add_chatsDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000002_add_chats.down.db.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1565597460, 0)} info := bindataFileInfo{name: "000002_add_chats.down.db.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0xa7, 0xf0, 0x94, 0x7a, 0x9, 0xdc, 0x6c, 0x7b, 0xdc, 0x12, 0x30, 0x55, 0x31, 0x17, 0xf2, 0xcc, 0x6e, 0xfd, 0xbb, 0x70, 0xb9, 0xd8, 0x9f, 0x81, 0x83, 0xdc, 0x1d, 0x1c, 0x3a, 0x8d, 0xce}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0xa7, 0xf0, 0x94, 0x7a, 0x9, 0xdc, 0x6c, 0x7b, 0xdc, 0x12, 0x30, 0x55, 0x31, 0x17, 0xf2, 0xcc, 0x6e, 0xfd, 0xbb, 0x70, 0xb9, 0xd8, 0x9f, 0x81, 0x83, 0xdc, 0x1d, 0x1c, 0x3a, 0x8d, 0xce}}
return a, nil return a, nil
} }
var __000002_add_chatsUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x92\x4f\x4b\x03\x31\x10\xc5\xef\xf3\x29\x06\x3c\x54\x21\x07\x3d\x88\x42\x4f\xd9\x6d\x8a\x8b\x71\x53\xd2\x54\xec\x29\xa4\xd9\xc1\x2e\xdd\x7f\x74\xb3\x95\x7e\x7b\x69\x5d\x6a\xff\x58\xf0\x98\xbc\xf7\x7b\x93\x17\x26\xd6\x82\x1b\x81\x86\x47\x52\x60\x32\xc6\x54\x19\x14\x1f\xc9\xd4\x4c\xd1\x2f\x5d\x68\xf1\x16\xf2\x0c\xdf\xb9\x8e\x5f\xb8\xc6\x89\x4e\xde\xb8\x9e\xe3\xab\x98\xa3\x4a\x31\x56\xe9\x58\x26\xb1\x41\x2d\x26\x92\xc7\x82\x41\xe5\x4a\x3a\xb8\x77\x59\xe9\x4c\x4a\x06\xbe\x2e\xea\xf5\xc5\x3d\x8e\xc4\x98\xcf\xa4\xc1\xc1\x8d\x7b\x78\x7e\xca\x1e\x07\x0c\xc2\xb6\x21\x4c\x52\x73\x04\x3b\x1f\xf2\x0d\x61\xa4\x94\x14\x3c\xbd\xa4\x8d\x9e\x09\x06\x21\x2f\xa9\x0d\xae\x6c\xce\xe8\x8c\x0a\x0a\x94\x59\x17\xac\x2f\x6a\xbf\xb2\x1b\x57\x74\xa7\x23\x0e\x49\xf7\x0c\x9a\x6e\x51\xe4\xde\xae\x68\x8b\x91\x54\x11\x83\xae\xda\xe4\xf4\x45\x99\x2d\xa9\x6d\xdd\x27\x59\x5f\x77\x55\xb8\xca\x17\xae\xfd\xdf\xa0\xbd\xf1\x37\xb3\x0a\x54\x05\xbb\x6f\xdf\x7f\xd3\xdf\x96\x2b\xea\x49\xfb\x73\xf2\xf4\x35\x0c\x4a\x2a\x17\xb4\x6e\xfb\x82\xfd\x69\x99\x37\xb6\x6b\x32\x17\xe8\x47\x80\xbb\x21\x00\x8c\xb4\x9a\xf4\xcb\x71\xe9\x1b\x1e\xcb\xbb\x6d\xb1\xbd\x67\x08\xdf\x01\x00\x00\xff\xff\x44\xe3\x59\x6f\x57\x02\x00\x00") var __000002_add_chatsUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x91\xc1\x6a\x32\x31\x14\x85\xf7\xf7\x29\x2e\xfc\x0b\xff\xc2\x2c\xda\x45\x69\xc1\x55\x66\x8c\x74\x68\x3a\x91\x18\x4b\x5d\x85\x98\xb9\xd4\xc1\xc4\x19\x4c\xc6\xe2\xdb\x17\xdb\x41\xb4\x52\xe8\x32\xb9\xdf\x77\xce\xe2\x14\x8a\x33\xcd\x51\xb3\x5c\x70\x2c\xa7\x58\x49\x8d\xfc\xad\x9c\xeb\x39\xba\xb5\x4d\x11\xff\x43\x53\xe3\x2b\x53\xc5\x13\x53\x38\x53\xe5\x0b\x53\x4b\x7c\xe6\x4b\x94\x15\x16\xb2\x9a\x8a\xb2\xd0\xa8\xf8\x4c\xb0\x82\x67\xb0\xb5\x81\x4e\xf4\x31\xab\x5a\x08\x91\x81\x6b\x7d\xbb\xbb\xfa\xc7\x09\x9f\xb2\x85\xd0\x38\xfa\x67\xef\x1e\x1f\xea\xfb\x51\x06\xe9\xd0\x11\x96\x95\x3e\x93\xad\x4b\xcd\x9e\x30\x97\x52\x70\x56\x5d\xdb\x5a\x2d\x78\x06\xa9\x09\x14\x93\x0d\xdd\x0f\xbb\x26\x4f\x89\x6a\x63\x93\x71\xbe\x75\x1b\xb3\xb7\xbe\xbf\xac\x38\x25\xdd\x66\xd0\xf5\x2b\xdf\x38\xb3\xa1\x03\xe6\x42\xe6\x19\xf4\xdb\x7d\x43\x1f\x54\x9b\x40\x31\xda\x77\x32\xae\xed\xb7\xe9\x57\xdf\xdb\xf8\xb7\xa2\x2f\x70\xc8\x1c\xaa\x02\x85\x15\xed\xe2\xe5\x6b\xdd\x74\xa6\xef\x6a\x9b\xe8\xfb\x00\x37\x63\x00\x98\x28\x39\x1b\x46\xbb\xe6\xc6\xe7\xe7\xe3\x8a\x66\x60\xc6\xf0\x19\x00\x00\xff\xff\x99\xae\x9f\xf2\xef\x01\x00\x00")
func _000002_add_chatsUpDbSqlBytes() ([]byte, error) { func _000002_add_chatsUpDbSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -154,8 +154,8 @@ func _000002_add_chatsUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000002_add_chats.up.db.sql", size: 599, mode: os.FileMode(0644), modTime: time.Unix(1572543168, 0)} info := bindataFileInfo{name: "000002_add_chats.up.db.sql", size: 495, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdb, 0xf, 0xef, 0x31, 0x64, 0x3, 0xf0, 0x58, 0x1e, 0xed, 0x1e, 0x7e, 0xce, 0x4, 0x20, 0x51, 0x79, 0xf9, 0xca, 0xc3, 0xb9, 0xc9, 0x60, 0x25, 0x2f, 0x6b, 0x99, 0xb1, 0x92, 0x6d, 0x56, 0x31}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6e, 0xca, 0x2b, 0xf7, 0xca, 0x21, 0xda, 0x17, 0x1f, 0x97, 0xa8, 0x12, 0xb5, 0x6c, 0xad, 0x92, 0xe7, 0x2, 0xaf, 0x1, 0xcb, 0x5e, 0xe9, 0x71, 0xc4, 0x81, 0xa7, 0x3, 0x93, 0x5b, 0x73, 0x73}}
return a, nil return a, nil
} }
@ -174,7 +174,7 @@ func _000003_add_contactsDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000003_add_contacts.down.db.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1565597570, 0)} info := bindataFileInfo{name: "000003_add_contacts.down.db.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0x7e, 0xb, 0xec, 0x72, 0xcd, 0x21, 0x3e, 0xa2, 0x38, 0xe0, 0x95, 0x7e, 0xce, 0x4a, 0x17, 0xc8, 0xd0, 0x1c, 0xfa, 0xa3, 0x23, 0x5, 0xab, 0x89, 0xf9, 0xfc, 0x63, 0x7, 0x28, 0xe9, 0x93}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0x7e, 0xb, 0xec, 0x72, 0xcd, 0x21, 0x3e, 0xa2, 0x38, 0xe0, 0x95, 0x7e, 0xce, 0x4a, 0x17, 0xc8, 0xd0, 0x1c, 0xfa, 0xa3, 0x23, 0x5, 0xab, 0x89, 0xf9, 0xfc, 0x63, 0x7, 0x28, 0xe9, 0x93}}
return a, nil return a, nil
} }
@ -194,7 +194,7 @@ func _000003_add_contactsUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000003_add_contacts.up.db.sql", size: 381, mode: os.FileMode(0644), modTime: time.Unix(1572543168, 0)} info := bindataFileInfo{name: "000003_add_contacts.up.db.sql", size: 381, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x45, 0xfe, 0x1e, 0xf2, 0x75, 0x33, 0x37, 0x8e, 0x7f, 0x93, 0x6f, 0x16, 0xbb, 0xf8, 0xa4, 0x70, 0x6b, 0xe0, 0xc1, 0x4f, 0x99, 0x8d, 0xc8, 0x2d, 0x40, 0xf1, 0xed, 0x65, 0x90, 0xc3, 0xad, 0xc7}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x45, 0xfe, 0x1e, 0xf2, 0x75, 0x33, 0x37, 0x8e, 0x7f, 0x93, 0x6f, 0x16, 0xbb, 0xf8, 0xa4, 0x70, 0x6b, 0xe0, 0xc1, 0x4f, 0x99, 0x8d, 0xc8, 0x2d, 0x40, 0xf1, 0xed, 0x65, 0x90, 0xc3, 0xad, 0xc7}}
return a, nil return a, nil
} }
@ -214,12 +214,12 @@ func _000004_user_messages_compatibilityDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000004_user_messages_compatibility.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1565631683, 0)} info := bindataFileInfo{name: "000004_user_messages_compatibility.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0xaf, 0x48, 0x80, 0x3d, 0x54, 0x5e, 0x53, 0xee, 0x98, 0x26, 0xbb, 0x99, 0x6a, 0xd8, 0x37, 0x94, 0xf2, 0xf, 0x82, 0xfa, 0xb7, 0x6a, 0x68, 0xcd, 0x8b, 0xe2, 0xc4, 0x6, 0x25, 0xdc, 0x6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0xaf, 0x48, 0x80, 0x3d, 0x54, 0x5e, 0x53, 0xee, 0x98, 0x26, 0xbb, 0x99, 0x6a, 0xd8, 0x37, 0x94, 0xf2, 0xf, 0x82, 0xfa, 0xb7, 0x6a, 0x68, 0xcd, 0x8b, 0xe2, 0xc4, 0x6, 0x25, 0xdc, 0x6}}
return a, nil return a, nil
} }
var __000004_user_messages_compatibilityUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x92\xcf\x6e\xe2\x3c\x14\xc5\xf7\x3c\xc5\xd9\x01\x12\xf9\xd4\x45\xd5\x4d\x57\x81\x9a\x6f\xa2\xc9\x24\x55\x30\x23\xba\xb2\x4c\xb8\x43\xac\x49\x6c\x64\xdf\x0c\x13\xa9\x0f\x3f\xa2\x84\xaa\x61\xe8\x6a\xb2\xc8\xc2\xbf\x73\xec\x73\xff\x44\x11\x12\x1e\x07\x98\xe6\xe0\x3c\x6b\xcb\xe0\x4a\x9f\x7e\x26\x80\xf5\xb6\x26\x54\x3a\xc0\xbb\xa3\xd9\x41\x07\x1c\x09\x9e\xea\x0e\xce\xc2\xf0\x28\x8a\x70\xac\xc8\x9e\xcc\x35\x35\x64\xd9\xd8\x3d\x8c\xfd\x61\xac\x61\x8a\x42\xe9\x5d\x5d\xff\x37\x5a\x14\x22\x96\x02\x32\x9e\xa7\x02\xc9\x12\x59\x2e\x21\x36\xc9\x4a\xae\xd0\x06\xf2\xaa\xa1\x10\xf4\x9e\x82\xaa\x69\xaf\xcb\x0e\x93\x11\x00\x98\x1d\xbe\xc7\xc5\xe2\x4b\x5c\xe0\xb9\x48\xbe\xc5\xc5\x0b\xbe\x8a\x17\xe4\x19\x16\x79\xb6\x4c\x93\x85\x44\x21\x9e\xd3\x78\x21\x66\x6f\xfa\x63\x65\xc2\x81\xbc\x62\xd3\x50\x60\xdd\x1c\x90\x64\x52\xfc\x2f\x8a\xb7\xf7\xb2\x75\x9a\x9e\x75\xc1\xb5\xbe\x24\x48\xb1\x91\x57\x64\x47\x81\x8d\xd5\x6c\x9c\xc5\x3c\xcd\xe7\xe7\xd3\xd2\x59\x26\xcb\xef\x61\x86\x9e\x9e\x2a\xee\x0e\xf4\x89\xe4\x54\xa3\xd5\xcd\x3b\x3e\x9f\x0e\x62\x5e\x5f\x5a\x69\x56\x1f\xea\x1f\x52\x4f\xec\x3b\x55\xba\xd6\xf2\xc0\x8b\x27\xb1\x8c\xd7\xa9\xc4\xdd\x45\x77\xa8\x3b\xc5\x6e\xf8\x6e\xdf\xec\x41\xe0\x21\x09\xac\xb9\x0d\x43\x56\xd6\xae\xfc\xa9\x7e\xe9\xba\xa5\x1b\x79\x43\xe5\x8e\x98\xe7\x79\x2a\xe2\xec\xef\x38\xb2\x58\xf7\x23\x0a\x44\xf6\x73\xdd\x32\x4e\x57\xbd\xd0\xb5\xbc\x77\xc6\xee\xaf\xb2\x8c\xa6\x8f\xa3\xcb\x36\x25\xd9\x93\xd8\xc0\xec\x7e\xab\x7e\xa0\x79\x76\x73\x9b\x26\x67\x3c\x7d\xbc\x61\x24\xed\xcb\x4a\x6d\x3b\x75\x69\x78\x9e\xe1\xf6\x25\xe7\xf8\xed\x36\xb0\x9f\x8c\xef\xfe\xf1\x1b\xe3\xf5\xf5\x63\x47\x67\x88\x1e\xee\x67\x78\xb8\x9f\x9e\x80\xd9\xcd\x2e\x0b\x70\xaa\xf7\x4f\x00\x00\x00\xff\xff\xe0\x0c\x93\xa2\xa0\x03\x00\x00") var __000004_user_messages_compatibilityUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x52\xc1\x6e\xda\x40\x10\xbd\xf3\x15\x73\x0b\x48\xb8\xca\x21\xca\x25\x27\x43\x96\xd6\xaa\x6b\x47\xc6\xa9\xc8\x69\xb5\xd8\x53\xbc\x62\xbd\x6b\xed\x8c\x4b\x2c\xe5\xe3\x2b\x03\x26\x40\x51\x2f\xf5\xc1\x87\x79\x33\x6f\xde\xdb\x79\x41\x00\x11\xdf\x11\xe8\xba\x71\x9e\x95\x65\xe0\x4a\xf5\x3f\x4d\xc0\x6a\x6d\x10\x2a\x45\xe0\xdd\x4e\x97\xa0\x08\x76\x08\x1e\x4d\x07\xce\x82\xe6\x51\x10\xc0\xae\x42\xdb\x0f\x1b\xac\xd1\xb2\xb6\x1b\xd0\xf6\x97\xb6\x9a\x31\xa0\xc2\x3b\x63\xbe\x8c\xe6\x99\x08\x73\x01\x79\x38\x8b\x05\x44\x0b\x48\xd2\x1c\xc4\x2a\x5a\xe6\x4b\x68\x09\xbd\xac\x91\x48\x6d\x90\xa4\xc1\x8d\x2a\x3a\x18\x8f\x00\x00\x74\x09\x3f\xc3\x6c\xfe\x2d\xcc\xe0\x25\x8b\x7e\x84\xd9\x1b\x7c\x17\x6f\x90\x26\x30\x4f\x93\x45\x1c\xcd\x73\xc8\xc4\x4b\x1c\xce\xc5\x74\xdf\xbf\xab\x34\x35\xe8\x25\xeb\x1a\x89\x55\xdd\x40\x94\xe4\xe2\xab\xc8\xf6\xfb\x92\xd7\x38\x3e\xf4\x91\x6b\x7d\x81\x90\x8b\x55\x7e\x85\x94\x48\xac\xad\x62\xed\x2c\xcc\xe2\x74\x76\xa8\x32\xbe\xf3\x49\xc9\xe5\x40\xe1\x2c\xa3\x65\xc9\x5d\x83\xfd\xb6\x2b\xb8\x37\x67\x55\x8d\xc3\xf4\x91\xef\x5c\xdf\x35\x61\xa5\x58\x9e\x19\xbf\x44\x8d\x2b\x94\x91\xff\xee\xf1\xc8\xbe\x93\x85\x6b\x2d\x5f\xf0\xc3\xb3\x58\x84\xaf\x71\x0e\xf7\x43\x1f\x35\xce\x12\x4a\x76\x97\xf2\x8e\xc7\x38\x79\x3a\x0a\x33\xae\xd8\xca\xdf\xca\xb4\xb7\x8c\x12\xa2\x85\x59\x9a\xc6\x22\x4c\xfe\xde\xb8\x08\xe3\xe5\xf1\x46\xae\xe5\x8d\xd3\x76\x23\x89\x15\xb7\x74\xb9\xb9\x51\x9e\xb0\x94\xfb\xf7\xfe\x7c\x7e\xaf\x76\xb2\x51\x9d\x71\xaa\x3c\xab\x12\xeb\x62\x8b\x5e\x36\xaa\xd8\x7e\xaa\x1c\xaa\x95\xa2\x6a\xe0\x1e\x4d\x9e\x46\x43\x02\xa3\xe4\x59\xac\x40\x97\xef\xf2\x18\x82\x34\xb9\x99\xc0\xf1\x01\x9e\x3c\xdd\x18\x44\xe5\x8b\x4a\xae\xbb\xd3\x1d\xd2\x04\x6e\x93\x1c\x24\xb5\x6b\x62\x3f\xbe\xbb\xff\xcf\xef\x0e\x3e\x3e\xce\xaf\x30\x85\xe0\xf1\x61\x0a\x8f\x0f\x93\x1e\xd0\xe5\x74\xc8\x4e\xef\xf7\x4f\x00\x00\x00\xff\xff\x91\x46\x82\xd5\xd4\x03\x00\x00")
func _000004_user_messages_compatibilityUpSqlBytes() ([]byte, error) { func _000004_user_messages_compatibilityUpSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -234,8 +234,8 @@ func _000004_user_messages_compatibilityUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000004_user_messages_compatibility.up.sql", size: 928, mode: os.FileMode(0644), modTime: time.Unix(1569474812, 0)} info := bindataFileInfo{name: "000004_user_messages_compatibility.up.sql", size: 980, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x60, 0x6c, 0x7f, 0xfb, 0xb3, 0x30, 0xd8, 0xbf, 0x6, 0x4a, 0x4a, 0xec, 0x9e, 0xd7, 0xa, 0x5e, 0x8, 0xbb, 0xf8, 0x11, 0x97, 0x80, 0xd3, 0xfa, 0x2c, 0x1e, 0x82, 0xb2, 0xe2, 0xe7, 0x6e, 0xa}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x7a, 0xba, 0xae, 0x6d, 0xef, 0x69, 0x12, 0x6b, 0x48, 0xe3, 0xa7, 0xad, 0x21, 0x4a, 0xcf, 0x4f, 0xbc, 0x14, 0xc1, 0x19, 0x69, 0x1c, 0xc, 0xa2, 0x3d, 0xbc, 0x12, 0x32, 0x71, 0x76, 0x15}}
return a, nil return a, nil
} }
@ -254,12 +254,12 @@ func _1567112142_user_messagesDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1567112142_user_messages.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1568961800, 0)} info := bindataFileInfo{name: "1567112142_user_messages.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x79, 0x8e, 0xbe, 0x63, 0x64, 0x52, 0xa3, 0x13, 0x83, 0xc7, 0x47, 0xff, 0x56, 0xa9, 0xc, 0x72, 0xb4, 0x97, 0x6, 0xc7, 0xa5, 0x68, 0xb6, 0x55, 0x6a, 0xd5, 0xb0, 0x12, 0xfb, 0x4c, 0xa5, 0x27}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x79, 0x8e, 0xbe, 0x63, 0x64, 0x52, 0xa3, 0x13, 0x83, 0xc7, 0x47, 0xff, 0x56, 0xa9, 0xc, 0x72, 0xb4, 0x97, 0x6, 0xc7, 0xa5, 0x68, 0xb6, 0x55, 0x6a, 0xd5, 0xb0, 0x12, 0xfb, 0x4c, 0xa5, 0x27}}
return a, nil return a, nil
} }
var __1567112142_user_messagesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x90\x51\x6f\x9b\x30\x14\x85\xdf\xf9\x15\xe7\xad\xad\xb4\x54\x7b\xef\x13\x01\x67\x43\x42\x64\x23\xce\xd6\xb7\xc8\xd8\xb7\xc5\x8a\xb1\x11\xbe\x2c\xe5\xdf\x4f\xa1\xb0\x2d\x53\x5f\xcf\x77\xfd\xdd\x73\xbd\xd9\x20\x1f\x42\x0f\xe5\x27\xf4\x03\xfd\xb2\x61\x8c\x6e\x82\x1e\x48\x31\x19\x8c\x91\x86\x53\x47\x31\xaa\x57\x8a\x60\xd5\x38\x7a\x4c\x36\x1b\xfc\x24\x98\xe0\xef\x18\x9e\xc8\x80\x03\x22\xab\x09\x8d\xd2\xe7\x8b\x1a\x0c\x74\xe8\x7a\xc5\xb6\x71\x84\x8b\xe5\x16\x96\xaf\x8f\x1a\xd2\x6a\x8c\x04\xcb\x77\x11\x3e\xf0\xd5\x6e\xae\x9b\x2f\x2d\x0d\x04\x7a\xd3\xd4\x33\x5e\xc2\x00\x6e\x09\x3a\xf8\x18\x1c\x41\x3b\x4b\x9e\x1f\x93\xbc\xde\x7f\x83\x4c\xb7\xa5\xb8\x6d\xf5\x94\x24\x59\x2d\x52\x29\x16\x58\xec\x50\xed\x25\xc4\x73\x71\x90\x87\xff\x0e\xb8\x4f\x00\xc0\x1a\x6c\xcb\xfd\x16\xc7\xaa\xf8\x7e\x14\xf3\x74\x75\x2c\xcb\x4f\x33\xd4\xad\xe2\x93\x35\xf8\x91\xd6\xd9\xd7\xb4\xfe\x43\x51\x8b\x9d\xa8\x45\x95\x89\xc3\x3c\x13\xef\xad\x79\xc0\xbe\x42\x2e\x4a\x21\x05\xb2\xf4\x90\xa5\xb9\x58\x24\xc1\x33\x79\x3e\xf1\xd4\xd3\x6a\x7a\x27\x4b\x95\x0f\x08\xd3\x1b\x43\x8a\x67\xb9\x28\x5c\xd0\x67\x6c\x8b\x2f\x45\xb5\x24\x6c\x3b\x8a\xac\xba\xfe\x26\x5d\x57\xad\xbd\xff\x31\xac\x25\x6e\xc5\xfd\xd8\x38\xab\x4f\x67\x9a\xe6\x5f\x78\x0f\x5f\x9c\x7a\x8d\x28\x2a\xf9\xf7\xde\x5c\xec\xd2\x63\x29\xf1\x39\x79\x78\x4a\x7e\x07\x00\x00\xff\xff\x07\x0e\xee\x5c\x27\x02\x00\x00") var __1567112142_user_messagesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x4f\x4d\x73\x9b\x30\x14\xbc\xf3\x2b\xf6\x96\x64\xa6\xce\xf4\x9e\x13\x06\xb9\x65\x86\xc1\x2d\x96\xdb\xdc\x3c\x42\x7a\x09\x1a\x0b\x89\x41\x8f\x3a\xfc\xfb\x0e\x04\x37\x75\x8e\x6f\x77\xdf\x7e\x6c\x36\xc8\x87\xd0\x43\xf9\x09\xfd\x40\x7f\x6c\x18\xa3\x9b\xa0\x07\x52\x4c\x06\x63\xa4\xe1\xd4\x51\x8c\xea\x95\x22\x58\x35\x8e\x1e\x93\xcd\x06\xbf\x09\x26\xf8\x3b\x86\x27\x32\xe0\x80\xc8\x6a\x42\xa3\xf4\xf9\xa2\x06\x03\x1d\xba\x5e\xb1\x6d\x1c\xe1\x62\xb9\x85\xe5\xf9\xa9\x21\xad\xc6\x48\xb0\x7c\x17\xe1\x03\xcf\xee\x66\x4e\xbe\xb4\x34\x10\xe8\x4d\x53\xcf\x78\x09\x03\xb8\x25\xe8\xe0\x63\x70\x04\xed\x2c\x79\x7e\x4c\xf2\x7a\xff\x03\x32\xdd\x96\xe2\xb6\xd5\x53\x92\x64\xb5\x48\xa5\x58\xc9\x62\x87\x6a\x2f\x21\x9e\x8b\x83\x3c\x7c\x1a\x70\x9f\x00\x80\x35\xd8\x96\xfb\x2d\x8e\x55\xf1\xf3\x28\x16\x75\x75\x2c\xcb\x2f\x0b\xa9\x5b\xc5\x27\x6b\xf0\x2b\xad\xb3\xef\x69\xfd\x8f\x45\x2d\x76\xa2\x16\x55\x26\x0e\x8b\x26\xde\x5b\xf3\x80\x7d\x85\x5c\x94\x42\x0a\x64\xe9\x21\x4b\x73\xb1\x9a\x04\xcf\xe4\xf9\xc4\x53\x4f\x28\x2a\xf9\x8e\xae\x35\x3e\xa1\x4c\x6f\x0c\x29\x9e\xd7\x53\xbb\xa0\xcf\xd8\x16\xdf\x3e\x04\xb6\xa3\xc8\xaa\xeb\x6f\xd0\x6b\xc4\xb5\xef\x7f\x0e\xd7\xf0\x5b\xe3\x7e\x6c\x9c\xd5\xa7\x33\x4d\xcb\xfa\x77\xf0\xc5\xa9\xd7\x38\x77\xf9\xd8\x99\x8b\x5d\x7a\x2c\x25\xbe\x26\x0f\x4f\xc9\xdf\x00\x00\x00\xff\xff\x6e\x1c\xcd\x6f\x1f\x02\x00\x00")
func _1567112142_user_messagesUpSqlBytes() ([]byte, error) { func _1567112142_user_messagesUpSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -274,8 +274,8 @@ func _1567112142_user_messagesUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1567112142_user_messages.up.sql", size: 551, mode: os.FileMode(0644), modTime: time.Unix(1568961800, 0)} info := bindataFileInfo{name: "1567112142_user_messages.up.sql", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7a, 0x11, 0x2, 0x79, 0x3b, 0xc5, 0x37, 0xe7, 0x3f, 0xa9, 0x35, 0x99, 0xa5, 0x3f, 0x32, 0xa3, 0xbe, 0xf7, 0x53, 0xf3, 0xea, 0x72, 0xbd, 0xb, 0xfc, 0xa7, 0xdc, 0x97, 0x1c, 0x6, 0x71, 0x16}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xff, 0xc0, 0x47, 0x32, 0xa9, 0xa4, 0x6, 0x63, 0x6b, 0xe7, 0x79, 0x2b, 0x80, 0x52, 0x2b, 0x6f, 0xf9, 0x9d, 0x9a, 0xc2, 0xa9, 0x7a, 0xf7, 0x4d, 0x14, 0x12, 0x21, 0x10, 0xc4, 0x30, 0x42, 0xaa}}
return a, nil return a, nil
} }
@ -294,7 +294,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}}
return a, nil return a, nil
} }
@ -454,17 +454,17 @@ type bintree struct {
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"000001_init.down.db.sql": {_000001_initDownDbSql, map[string]*bintree{}}, "000001_init.down.db.sql": &bintree{_000001_initDownDbSql, map[string]*bintree{}},
"000001_init.up.db.sql": {_000001_initUpDbSql, map[string]*bintree{}}, "000001_init.up.db.sql": &bintree{_000001_initUpDbSql, map[string]*bintree{}},
"000002_add_chats.down.db.sql": {_000002_add_chatsDownDbSql, map[string]*bintree{}}, "000002_add_chats.down.db.sql": &bintree{_000002_add_chatsDownDbSql, map[string]*bintree{}},
"000002_add_chats.up.db.sql": {_000002_add_chatsUpDbSql, map[string]*bintree{}}, "000002_add_chats.up.db.sql": &bintree{_000002_add_chatsUpDbSql, map[string]*bintree{}},
"000003_add_contacts.down.db.sql": {_000003_add_contactsDownDbSql, map[string]*bintree{}}, "000003_add_contacts.down.db.sql": &bintree{_000003_add_contactsDownDbSql, map[string]*bintree{}},
"000003_add_contacts.up.db.sql": {_000003_add_contactsUpDbSql, map[string]*bintree{}}, "000003_add_contacts.up.db.sql": &bintree{_000003_add_contactsUpDbSql, map[string]*bintree{}},
"000004_user_messages_compatibility.down.sql": {_000004_user_messages_compatibilityDownSql, map[string]*bintree{}}, "000004_user_messages_compatibility.down.sql": &bintree{_000004_user_messages_compatibilityDownSql, map[string]*bintree{}},
"000004_user_messages_compatibility.up.sql": {_000004_user_messages_compatibilityUpSql, map[string]*bintree{}}, "000004_user_messages_compatibility.up.sql": &bintree{_000004_user_messages_compatibilityUpSql, map[string]*bintree{}},
"1567112142_user_messages.down.sql": {_1567112142_user_messagesDownSql, map[string]*bintree{}}, "1567112142_user_messages.down.sql": &bintree{_1567112142_user_messagesDownSql, map[string]*bintree{}},
"1567112142_user_messages.up.sql": {_1567112142_user_messagesUpSql, map[string]*bintree{}}, "1567112142_user_messages.up.sql": &bintree{_1567112142_user_messagesUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}
// RestoreAsset restores an asset under the given directory. // RestoreAsset restores an asset under the given directory.

View file

@ -1,8 +1,8 @@
CREATE TABLE IF NOT EXISTS user_messages ( CREATE TABLE IF NOT EXISTS user_messages (
id BLOB UNIQUE NOT NULL, id BLOB UNIQUE NOT NULL,
chat_id VARCHAR NOT NULL, chat_id VARCHAR NOT NULL,
content_type VARCHAR, content_type INT,
message_type VARCHAR, message_type INT,
text TEXT, text TEXT,
clock BIGINT, clock BIGINT,
timestamp BIGINT, timestamp BIGINT,

View file

@ -9,10 +9,7 @@ deleted_at_clock_value INT NOT NULL DEFAULT 0,
public_key BLOB, public_key BLOB,
unviewed_message_count INT NOT NULL DEFAULT 0, unviewed_message_count INT NOT NULL DEFAULT 0,
last_clock_value INT NOT NULL DEFAULT 0, last_clock_value INT NOT NULL DEFAULT 0,
last_message_content_type VARCHAR, last_message BLOB,
last_message_content VARCHAR,
last_message_timestamp INT,
last_message_clock_value INT,
members BLOB, members BLOB,
membership_updates BLOB membership_updates BLOB
); );

View file

@ -5,19 +5,22 @@ CREATE TABLE IF NOT EXISTS user_messages_legacy (
whisper_timestamp INTEGER NOT NULL, whisper_timestamp INTEGER NOT NULL,
source TEXT NOT NULL, source TEXT NOT NULL,
destination BLOB, destination BLOB,
content VARCHAR NOT NULL, text VARCHAR NOT NULL,
content_type VARCHAR NOT NULL, content_type INT NOT NULL,
username VARCHAR, username VARCHAR,
timestamp INT NOT NULL, timestamp INT NOT NULL,
chat_id VARCHAR NOT NULL, chat_id VARCHAR NOT NULL,
local_chat_id VARCHAR NOT NULL,
retry_count INT NOT NULL DEFAULT 0, retry_count INT NOT NULL DEFAULT 0,
reply_to VARCHAR, response_to VARCHAR,
message_type VARCHAR, message_type INT,
message_status VARCHAR,
clock_value INT NOT NULL, clock_value INT NOT NULL,
show BOOLEAN NOT NULL DEFAULT TRUE,
seen BOOLEAN NOT NULL DEFAULT FALSE, seen BOOLEAN NOT NULL DEFAULT FALSE,
outgoing_status VARCHAR outgoing_status VARCHAR,
parsed_text BLOB,
raw_payload BLOB,
sticker_pack INT,
sticker_hash VARCHAR
); );
CREATE INDEX idx_source ON user_messages_legacy(source); CREATE INDEX idx_source ON user_messages_legacy(source);

View file

@ -6,8 +6,8 @@ DROP TABLE user_messages;
CREATE TABLE IF NOT EXISTS user_messages ( CREATE TABLE IF NOT EXISTS user_messages (
id BLOB UNIQUE NOT NULL, id BLOB UNIQUE NOT NULL,
chat_id VARCHAR NOT NULL REFERENCES chats(id) ON DELETE CASCADE, chat_id VARCHAR NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
content_type VARCHAR, content_type INT,
message_type VARCHAR, message_type INT,
text TEXT, text TEXT,
clock BIGINT, clock BIGINT,
timestamp BIGINT, timestamp BIGINT,

View file

@ -6,12 +6,9 @@ import (
"database/sql" "database/sql"
"encoding/gob" "encoding/gob"
"encoding/hex" "encoding/hex"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
v1protocol "github.com/status-im/status-go/protocol/v1"
) )
var ( var (
@ -24,21 +21,46 @@ type sqlitePersistence struct {
db *sql.DB db *sql.DB
} }
func (db sqlitePersistence) LastMessageClock(chatID string) (int64, error) {
if chatID == "" {
return 0, errors.New("chat ID is empty")
}
var last sql.NullInt64
err := db.db.QueryRow("SELECT max(clock) FROM user_messages WHERE chat_id = ?", chatID).Scan(&last)
if err != nil {
return 0, err
}
return last.Int64, nil
}
func (db sqlitePersistence) SaveChat(chat Chat) error { func (db sqlitePersistence) SaveChat(chat Chat) error {
return db.saveChat(nil, chat)
}
func (db sqlitePersistence) SaveChats(chats []*Chat) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
for _, chat := range chats {
err := db.saveChat(tx, *chat)
if err != nil {
return err
}
}
return nil
}
func (db sqlitePersistence) saveChat(tx *sql.Tx, chat Chat) error {
var err error var err error
if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
}
pkey := []byte{} pkey := []byte{}
// For one to one chatID is an encoded public key // For one to one chatID is an encoded public key
@ -72,8 +94,8 @@ func (db sqlitePersistence) SaveChat(chat Chat) error {
} }
// Insert record // Insert record
stmt, err := db.db.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, public_key, unviewed_message_count, last_clock_value, last_message_content_type, last_message_content, last_message_timestamp, last_message_clock_value, members, membership_updates) stmt, err := tx.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, public_key, unviewed_message_count, last_clock_value, last_message, members, membership_updates)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
if err != nil { if err != nil {
return err return err
} }
@ -90,10 +112,7 @@ func (db sqlitePersistence) SaveChat(chat Chat) error {
pkey, pkey,
chat.UnviewedMessagesCount, chat.UnviewedMessagesCount,
chat.LastClockValue, chat.LastClockValue,
chat.LastMessageContentType, chat.LastMessage,
chat.LastMessageContent,
chat.LastMessageTimestamp,
chat.LastMessageClockValue,
encodedMembers.Bytes(), encodedMembers.Bytes(),
encodedMembershipUpdates.Bytes(), encodedMembershipUpdates.Bytes(),
) )
@ -141,10 +160,7 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
public_key, public_key,
unviewed_message_count, unviewed_message_count,
last_clock_value, last_clock_value,
last_message_content_type, last_message,
last_message_content,
last_message_timestamp,
last_message_clock_value,
members, members,
membership_updates membership_updates
FROM chats FROM chats
@ -157,11 +173,6 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
for rows.Next() { for rows.Next() {
var ( var (
lastMessageContentType sql.NullString
lastMessageContent sql.NullString
lastMessageTimestamp sql.NullInt64
lastMessageClockValue sql.NullInt64
chat Chat chat Chat
encodedMembers []byte encodedMembers []byte
encodedMembershipUpdates []byte encodedMembershipUpdates []byte
@ -178,20 +189,13 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
&pkey, &pkey,
&chat.UnviewedMessagesCount, &chat.UnviewedMessagesCount,
&chat.LastClockValue, &chat.LastClockValue,
&lastMessageContentType, &chat.LastMessage,
&lastMessageContent,
&lastMessageTimestamp,
&lastMessageClockValue,
&encodedMembers, &encodedMembers,
&encodedMembershipUpdates, &encodedMembershipUpdates,
) )
if err != nil { if err != nil {
return return
} }
chat.LastMessageContent = lastMessageContent.String
chat.LastMessageContentType = lastMessageContentType.String
chat.LastMessageTimestamp = lastMessageTimestamp.Int64
chat.LastMessageClockValue = lastMessageClockValue.Int64
// Restore members // Restore members
membersDecoder := gob.NewDecoder(bytes.NewBuffer(encodedMembers)) membersDecoder := gob.NewDecoder(bytes.NewBuffer(encodedMembers))
@ -289,7 +293,7 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
return response, nil return response, nil
} }
func (db sqlitePersistence) SetContactsENSData(contacts []Contact) error { func (db sqlitePersistence) SetContactsENSData(contacts []*Contact) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
return err return err
@ -323,7 +327,7 @@ func (db sqlitePersistence) SetContactsENSData(contacts []Contact) error {
// SetContactsGeneratedData sets a contact generated data if not existing already // SetContactsGeneratedData sets a contact generated data if not existing already
// in the database // in the database
func (db sqlitePersistence) SetContactsGeneratedData(contacts []Contact, tx *sql.Tx) (err error) { func (db sqlitePersistence) SetContactsGeneratedData(contacts []*Contact, tx *sql.Tx) (err error) {
if tx == nil { if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
@ -435,109 +439,3 @@ func (db sqlitePersistence) SaveContact(contact Contact, tx *sql.Tx) (err error)
) )
return return
} }
// Messages returns messages for a given contact, in a given period. Ordered by a timestamp.
func (db sqlitePersistence) Messages(from, to time.Time) (result []*v1protocol.Message, err error) {
rows, err := db.db.Query(`
SELECT
id,
chat_id,
content_type,
message_type,
text,
clock,
timestamp,
content_chat_id,
content_text,
public_key,
flags
FROM user_messages
WHERE timestamp >= ? AND timestamp <= ?
ORDER BY timestamp`,
v1protocol.TimestampInMsFromTime(from),
v1protocol.TimestampInMsFromTime(to),
)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
msg := v1protocol.Message{
Content: v1protocol.Content{},
}
var pkey []byte
err = rows.Scan(
&msg.ID, &msg.ChatID, &msg.ContentT, &msg.MessageT, &msg.Text, &msg.Clock,
&msg.Timestamp, &msg.Content.ChatID, &msg.Content.Text, &pkey, &msg.Flags,
)
if err != nil {
return
}
if len(pkey) != 0 {
msg.SigPubKey, err = crypto.UnmarshalPubkey(pkey)
if err != nil {
return
}
}
result = append(result, &msg)
}
return
}
func (db sqlitePersistence) SaveMessages(messages []*v1protocol.Message) (last int64, err error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
stmt, err := tx.Prepare(`
INSERT OR IGNORE INTO user_messages(
id,
chat_id,
content_type,
message_type,
text,
clock,
timestamp,
content_chat_id,
content_text,
public_key,
flags
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`)
if err != nil {
return
}
var rst sql.Result
for _, msg := range messages {
var pkey []byte
if msg.SigPubKey != nil {
pkey = crypto.FromECDSAPub(msg.SigPubKey)
}
rst, err = stmt.Exec(
msg.ID, msg.ChatID, msg.ContentT, msg.MessageT, msg.Text, msg.Clock, msg.Timestamp,
msg.Content.ChatID, msg.Content.Text, pkey, msg.Flags,
)
if err != nil {
return
}
last, err = rst.LastInsertId()
if err != nil {
return
}
}
return
}

View file

@ -3,7 +3,9 @@ package protocol
import ( import (
"context" "context"
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"github.com/status-im/status-go/protocol/protobuf"
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -17,42 +19,46 @@ func (db sqlitePersistence) tableUserMessagesLegacyAllFields() string {
return `id, return `id,
whisper_timestamp, whisper_timestamp,
source, source,
destination, text,
content,
content_type, content_type,
username, username,
timestamp, timestamp,
chat_id, chat_id,
local_chat_id,
retry_count, retry_count,
message_type, message_type,
message_status,
clock_value, clock_value,
show,
seen, seen,
outgoing_status, outgoing_status,
reply_to` parsed_text,
raw_payload,
sticker_pack,
sticker_hash,
response_to`
} }
func (db sqlitePersistence) tableUserMessagesLegacyAllFieldsJoin() string { func (db sqlitePersistence) tableUserMessagesLegacyAllFieldsJoin() string {
return `m1.id, return `m1.id,
m1.whisper_timestamp, m1.whisper_timestamp,
m1.source, m1.source,
m1.destination, m1.text,
m1.content,
m1.content_type, m1.content_type,
m1.username, m1.username,
m1.timestamp, m1.timestamp,
m1.chat_id, m1.chat_id,
m1.local_chat_id,
m1.retry_count, m1.retry_count,
m1.message_type, m1.message_type,
m1.message_status,
m1.clock_value, m1.clock_value,
m1.show,
m1.seen, m1.seen,
m1.outgoing_status, m1.outgoing_status,
m1.reply_to, m1.parsed_text,
m1.raw_payload,
m1.sticker_pack,
m1.sticker_hash,
m1.response_to,
m2.source, m2.source,
m2.content, m2.text,
c.alias, c.alias,
c.identicon` c.identicon`
} }
@ -66,30 +72,35 @@ type scanner interface {
} }
func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, message *Message, others ...interface{}) error { func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, message *Message, others ...interface{}) error {
var quotedContent sql.NullString var quotedText sql.NullString
var quotedFrom sql.NullString var quotedFrom sql.NullString
var alias sql.NullString var alias sql.NullString
var identicon sql.NullString var identicon sql.NullString
sticker := &protobuf.StickerMessage{}
args := []interface{}{ args := []interface{}{
&message.ID, &message.ID,
&message.WhisperTimestamp, &message.WhisperTimestamp,
&message.From, // source in table &message.From, // source in table
&message.To, // destination in table &message.Text,
&message.Content,
&message.ContentType, &message.ContentType,
&message.Alias, &message.Alias,
&message.Timestamp, &message.Timestamp,
&message.ChatID, &message.ChatId,
&message.LocalChatID,
&message.RetryCount, &message.RetryCount,
&message.MessageType, &message.MessageType,
&message.MessageStatus, &message.Clock,
&message.ClockValue,
&message.Show,
&message.Seen, &message.Seen,
&message.OutgoingStatus, &message.OutgoingStatus,
&message.ReplyTo, &message.ParsedText,
&message.RawPayload,
&sticker.Pack,
&sticker.Hash,
&message.ResponseTo,
&quotedFrom, &quotedFrom,
&quotedContent, &quotedText,
&alias, &alias,
&identicon, &identicon,
} }
@ -98,45 +109,70 @@ func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, me
return err return err
} }
if quotedContent.Valid { if quotedText.Valid {
message.QuotedMessage = &QuotedMessage{ message.QuotedMessage = &QuotedMessage{
From: quotedFrom.String, From: quotedFrom.String,
Content: quotedContent.String, Text: quotedText.String,
} }
} }
message.Alias = alias.String message.Alias = alias.String
message.Identicon = identicon.String message.Identicon = identicon.String
if message.ContentType == protobuf.ChatMessage_STICKER {
message.Payload = &protobuf.ChatMessage_Sticker{Sticker: sticker}
}
return nil return nil
} }
func (db sqlitePersistence) tableUserMessagesLegacyAllValues(message *Message) []interface{} { func (db sqlitePersistence) tableUserMessagesLegacyAllValues(message *Message) ([]interface{}, error) {
sticker := message.GetSticker()
if sticker == nil {
sticker = &protobuf.StickerMessage{}
}
return []interface{}{ return []interface{}{
message.ID, message.ID,
message.WhisperTimestamp, message.WhisperTimestamp,
message.From, // source in table message.From, // source in table
message.To, // destination in table message.Text,
message.Content,
message.ContentType, message.ContentType,
message.Alias, message.Alias,
message.Timestamp, message.Timestamp,
message.ChatID, message.ChatId,
message.LocalChatID,
message.RetryCount, message.RetryCount,
message.MessageType, message.MessageType,
message.MessageStatus, message.Clock,
message.ClockValue,
message.Show,
message.Seen, message.Seen,
message.OutgoingStatus, message.OutgoingStatus,
message.ReplyTo, message.ParsedText,
} message.RawPayload,
sticker.Pack,
sticker.Hash,
message.ResponseTo,
}, nil
}
func (db sqlitePersistence) messageByID(tx *sql.Tx, id string) (*Message, error) {
var err error
if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return nil, err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
} }
func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
var message Message var message Message
allFields := db.tableUserMessagesLegacyAllFieldsJoin() allFields := db.tableUserMessagesLegacyAllFieldsJoin()
row := db.db.QueryRow( row := tx.QueryRow(
fmt.Sprintf(` fmt.Sprintf(`
SELECT SELECT
%s %s
@ -145,7 +181,7 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
LEFT JOIN LEFT JOIN
user_messages_legacy m2 user_messages_legacy m2
ON ON
m1.reply_to = m2.id m1.response_to = m2.id
LEFT JOIN LEFT JOIN
contacts c contacts c
@ -156,7 +192,7 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
`, allFields), `, allFields),
id, id,
) )
err := db.tableUserMessagesLegacyScanAllFields(row, &message) err = db.tableUserMessagesLegacyScanAllFields(row, &message)
switch err { switch err {
case sql.ErrNoRows: case sql.ErrNoRows:
return nil, errRecordNotFound return nil, errRecordNotFound
@ -167,6 +203,10 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
} }
} }
func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
return db.messageByID(nil, id)
}
func (db sqlitePersistence) MessagesExist(ids []string) (map[string]bool, error) { func (db sqlitePersistence) MessagesExist(ids []string) (map[string]bool, error) {
result := make(map[string]bool) result := make(map[string]bool)
if len(ids) == 0 { if len(ids) == 0 {
@ -224,7 +264,7 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
LEFT JOIN LEFT JOIN
user_messages_legacy m2 user_messages_legacy m2
ON ON
m1.reply_to = m2.id m1.response_to = m2.id
LEFT JOIN LEFT JOIN
contacts c contacts c
@ -232,7 +272,7 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
m1.source = c.id m1.source = c.id
WHERE WHERE
m1.chat_id = ? %s m1.local_chat_id = ? %s
ORDER BY cursor DESC ORDER BY cursor DESC
LIMIT ? LIMIT ?
`, allFields, cursorWhere), `, allFields, cursorWhere),
@ -290,7 +330,13 @@ func (db sqlitePersistence) SaveMessagesLegacy(messages []*Message) (err error)
} }
for _, msg := range messages { for _, msg := range messages {
_, err = stmt.Exec(db.tableUserMessagesLegacyAllValues(msg)...) var allValues []interface{}
allValues, err = db.tableUserMessagesLegacyAllValues(msg)
if err != nil {
return
}
_, err = stmt.Exec(allValues...)
if err != nil { if err != nil {
return return
} }
@ -304,24 +350,49 @@ func (db sqlitePersistence) DeleteMessage(id string) error {
} }
func (db sqlitePersistence) DeleteMessagesByChatID(id string) error { func (db sqlitePersistence) DeleteMessagesByChatID(id string) error {
_, err := db.db.Exec(`DELETE FROM user_messages_legacy WHERE chat_id = ?`, id) _, err := db.db.Exec(`DELETE FROM user_messages_legacy WHERE local_chat_id = ?`, id)
return err return err
} }
func (db sqlitePersistence) MarkMessagesSeen(ids ...string) error { func (db sqlitePersistence) MarkMessagesSeen(chatID string, ids []string) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
idsArgs := make([]interface{}, 0, len(ids)) idsArgs := make([]interface{}, 0, len(ids))
for _, id := range ids { for _, id := range ids {
idsArgs = append(idsArgs, id) idsArgs = append(idsArgs, id)
} }
inVector := strings.Repeat("?, ", len(ids)-1) + "?" inVector := strings.Repeat("?, ", len(ids)-1) + "?"
_, err := db.db.Exec( _, err = tx.Exec(
fmt.Sprintf(` fmt.Sprintf(`
UPDATE user_messages_legacy UPDATE user_messages_legacy
SET seen = 1 SET seen = 1
WHERE id IN (%s) WHERE id IN (%s)
`, inVector), `, inVector),
idsArgs...) idsArgs...)
if err != nil {
return err
}
// Update denormalized count
_, err = tx.Exec(
`UPDATE chats
SET unviewed_message_count =
(SELECT COUNT(1)
FROM user_messages_legacy
WHERE local_chat_id = ? AND seen = 0)
WHERE id = ?`, chatID, chatID)
return err return err
} }
@ -335,10 +406,11 @@ func (db sqlitePersistence) UpdateMessageOutgoingStatus(id string, newOutgoingSt
} }
// BlockContact updates a contact, deletes all the messages and 1-to-1 chat, updates the unread messages count and returns a map with the new count // BlockContact updates a contact, deletes all the messages and 1-to-1 chat, updates the unread messages count and returns a map with the new count
func (db sqlitePersistence) BlockContact(contact Contact) (chats []*Chat, err error) { func (db sqlitePersistence) BlockContact(contact Contact) ([]*Chat, error) {
var chats []*Chat
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
return return nil, err
} }
defer func() { defer func() {
if err == nil { if err == nil {
@ -357,36 +429,69 @@ func (db sqlitePersistence) BlockContact(contact Contact) (chats []*Chat, err er
contact.ID, contact.ID,
) )
if err != nil { if err != nil {
return return nil, err
} }
// Update contact // Update contact
err = db.SaveContact(contact, tx) err = db.SaveContact(contact, tx)
if err != nil { if err != nil {
return return nil, err
} }
// Delete one-to-one chat // Delete one-to-one chat
_, err = tx.Exec("DELETE FROM chats WHERE id = ?", contact.ID) _, err = tx.Exec("DELETE FROM chats WHERE id = ?", contact.ID)
if err != nil { if err != nil {
return return nil, err
} }
// Recalculate denormalized fields // Recalculate denormalized fields
_, err = tx.Exec(` _, err = tx.Exec(`
UPDATE chats UPDATE chats
SET SET
unviewed_message_count = (SELECT COUNT(1) FROM user_messages_legacy WHERE seen = 0 AND chat_id = chats.id), unviewed_message_count = (SELECT COUNT(1) FROM user_messages_legacy WHERE seen = 0 AND local_chat_id = chats.id)`)
last_message_content = (SELECT content from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_timestamp = (SELECT timestamp from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_clock_value = (SELECT clock_value from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_content_type = (SELECT content_type from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1)
`)
if err != nil { if err != nil {
return return nil, err
} }
// return the updated chats // return the updated chats
chats, err = db.chats(tx) chats, err = db.chats(tx)
return if err != nil {
return nil, err
}
for _, c := range chats {
var lastMessageID string
row := tx.QueryRow(`SELECT id FROM user_messages_legacy WHERE local_chat_id = ? ORDER BY clock_value DESC LIMIT 1`, c.ID)
switch err := row.Scan(&lastMessageID); err {
case nil:
message, err := db.messageByID(tx, lastMessageID)
if err != nil {
return nil, err
}
if message != nil {
encodedMessage, err := json.Marshal(message)
if err != nil {
return nil, err
}
_, err = tx.Exec(`UPDATE chats SET last_message = ? WHERE id = ?`, encodedMessage, c.ID)
if err != nil {
return nil, err
}
c.LastMessage = encodedMessage
}
case sql.ErrNoRows:
// Reset LastMessage
_, err = tx.Exec(`UPDATE chats SET last_message = NULL WHERE id = ?`, c.ID)
if err != nil {
return nil, err
}
c.LastMessage = nil
default:
return nil, err
}
}
return chats, err
} }

View file

@ -9,6 +9,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/sqlite"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -85,18 +86,23 @@ func TestMessageByChatID(t *testing.T) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
messages = append(messages, &Message{ messages = append(messages, &Message{
ID: strconv.Itoa(i), ID: strconv.Itoa(i),
ChatID: chatID, LocalChatID: chatID,
ChatMessage: protobuf.ChatMessage{
Clock: uint64(i),
},
From: "me", From: "me",
ClockValue: int64(i),
}) })
// Add some other chats. // Add some other chats.
if count%5 == 0 { if count%5 == 0 {
messages = append(messages, &Message{ messages = append(messages, &Message{
ID: strconv.Itoa(count + i), ID: strconv.Itoa(count + i),
ChatID: "other-chat", LocalChatID: "other-chat",
ChatMessage: protobuf.ChatMessage{
Clock: uint64(i),
},
From: "me", From: "me",
ClockValue: int64(i),
}) })
} }
} }
@ -107,9 +113,12 @@ func TestMessageByChatID(t *testing.T) {
for i := 0; i < pageSize+1; i++ { for i := 0; i < pageSize+1; i++ {
messages = append(messages, &Message{ messages = append(messages, &Message{
ID: strconv.Itoa(count*2 + i), ID: strconv.Itoa(count*2 + i),
ChatID: chatID, LocalChatID: chatID,
ChatMessage: protobuf.ChatMessage{
Clock: uint64(i),
},
From: "me", From: "me",
ClockValue: int64(i), // use very old clock values
}) })
} }
@ -143,7 +152,7 @@ func TestMessageByChatID(t *testing.T) {
t, t,
// Verify descending order. // Verify descending order.
sort.SliceIsSorted(result, func(i, j int) bool { sort.SliceIsSorted(result, func(i, j int) bool {
return result[i].ClockValue > result[j].ClockValue return result[i].Clock > result[j].Clock
}), }),
) )
} }
@ -155,27 +164,34 @@ func TestMessageReplies(t *testing.T) {
chatID := "super-chat" chatID := "super-chat"
message1 := &Message{ message1 := &Message{
ID: "id-1", ID: "id-1",
ChatID: chatID, LocalChatID: chatID,
Content: "content-1", ChatMessage: protobuf.ChatMessage{
Text: "content-1",
Clock: uint64(1),
},
From: "1", From: "1",
ClockValue: int64(1),
} }
message2 := &Message{ message2 := &Message{
ID: "id-2", ID: "id-2",
ChatID: chatID, LocalChatID: chatID,
Content: "content-2", ChatMessage: protobuf.ChatMessage{
Text: "content-2",
Clock: uint64(2),
ResponseTo: "id-1",
},
From: "2", From: "2",
ClockValue: int64(2),
ReplyTo: "id-1",
} }
message3 := &Message{ message3 := &Message{
ID: "id-3", ID: "id-3",
ChatID: chatID, LocalChatID: chatID,
Content: "content-3", ChatMessage: protobuf.ChatMessage{
Text: "content-3",
Clock: uint64(3),
ResponseTo: "non-existing",
},
From: "3", From: "3",
ClockValue: int64(3),
ReplyTo: "non-existing",
} }
messages := []*Message{message1, message2, message3} messages := []*Message{message1, message2, message3}
@ -186,22 +202,22 @@ func TestMessageReplies(t *testing.T) {
retrievedMessages, _, err := p.MessageByChatID(chatID, "", 10) retrievedMessages, _, err := p.MessageByChatID(chatID, "", 10)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "non-existing", retrievedMessages[0].ReplyTo) require.Equal(t, "non-existing", retrievedMessages[0].ResponseTo)
require.Nil(t, retrievedMessages[0].QuotedMessage) require.Nil(t, retrievedMessages[0].QuotedMessage)
require.Equal(t, "id-1", retrievedMessages[1].ReplyTo) require.Equal(t, "id-1", retrievedMessages[1].ResponseTo)
require.Equal(t, &QuotedMessage{From: "1", Content: "content-1"}, retrievedMessages[1].QuotedMessage) require.Equal(t, &QuotedMessage{From: "1", Text: "content-1"}, retrievedMessages[1].QuotedMessage)
require.Equal(t, "", retrievedMessages[2].ReplyTo) require.Equal(t, "", retrievedMessages[2].ResponseTo)
require.Nil(t, retrievedMessages[2].QuotedMessage) require.Nil(t, retrievedMessages[2].QuotedMessage)
} }
func TestMessageByChatIDWithTheSameClockValues(t *testing.T) { func TestMessageByChatIDWithTheSameClocks(t *testing.T) {
db, err := openTestDB() db, err := openTestDB()
require.NoError(t, err) require.NoError(t, err)
p := sqlitePersistence{db: db} p := sqlitePersistence{db: db}
chatID := "super-chat" chatID := "super-chat"
clockValues := []int64{10, 10, 9, 9, 9, 11, 12, 11, 100000, 6, 4, 5, 5, 5, 5} clockValues := []uint64{10, 10, 9, 9, 9, 11, 12, 11, 100000, 6, 4, 5, 5, 5, 5}
count := len(clockValues) count := len(clockValues)
pageSize := 2 pageSize := 2
@ -210,9 +226,11 @@ func TestMessageByChatIDWithTheSameClockValues(t *testing.T) {
for i, clock := range clockValues { for i, clock := range clockValues {
messages = append(messages, &Message{ messages = append(messages, &Message{
ID: strconv.Itoa(i), ID: strconv.Itoa(i),
ChatID: chatID, LocalChatID: chatID,
ChatMessage: protobuf.ChatMessage{
Clock: clock,
},
From: "me", From: "me",
ClockValue: clock,
}) })
} }
@ -242,16 +260,16 @@ func TestMessageByChatIDWithTheSameClockValues(t *testing.T) {
require.Empty(t, cursor) // for loop should exit because of cursor being empty require.Empty(t, cursor) // for loop should exit because of cursor being empty
require.Len(t, result, count) require.Len(t, result, count)
// Verify the order. // Verify the order.
expectedClockValues := make([]int64, len(clockValues)) expectedClocks := make([]uint64, len(clockValues))
copy(expectedClockValues, clockValues) copy(expectedClocks, clockValues)
sort.Slice(expectedClockValues, func(i, j int) bool { sort.Slice(expectedClocks, func(i, j int) bool {
return expectedClockValues[i] > expectedClockValues[j] return expectedClocks[i] > expectedClocks[j]
}) })
resultClockValues := make([]int64, 0, len(clockValues)) resultClocks := make([]uint64, 0, len(clockValues))
for _, m := range result { for _, m := range result {
resultClockValues = append(resultClockValues, m.ClockValue) resultClocks = append(resultClocks, m.Clock)
} }
require.EqualValues(t, expectedClockValues, resultClockValues) require.EqualValues(t, expectedClocks, resultClocks)
} }
func TestDeleteMessageByID(t *testing.T) { func TestDeleteMessageByID(t *testing.T) {
@ -299,6 +317,7 @@ func TestDeleteMessagesByChatID(t *testing.T) {
} }
func TestMarkMessageSeen(t *testing.T) { func TestMarkMessageSeen(t *testing.T) {
chatID := "test-chat"
db, err := openTestDB() db, err := openTestDB()
require.NoError(t, err) require.NoError(t, err)
p := sqlitePersistence{db: db} p := sqlitePersistence{db: db}
@ -311,7 +330,7 @@ func TestMarkMessageSeen(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.False(t, m.Seen) require.False(t, m.Seen)
err = p.MarkMessagesSeen(m.ID) err = p.MarkMessagesSeen(chatID, []string{m.ID})
require.NoError(t, err) require.NoError(t, err)
m, err = p.MessageByID(id) m, err = p.MessageByID(id)
@ -348,12 +367,12 @@ func TestSetContactGeneratedData(t *testing.T) {
LastUpdated: 20, LastUpdated: 20,
SystemTags: []string{"1", "2"}, SystemTags: []string{"1", "2"},
DeviceInfo: []ContactDeviceInfo{ DeviceInfo: []ContactDeviceInfo{
{ ContactDeviceInfo{
InstallationID: "1", InstallationID: "1",
Timestamp: 2, Timestamp: 2,
FCMToken: "token", FCMToken: "token",
}, },
{ ContactDeviceInfo{
InstallationID: "2", InstallationID: "2",
Timestamp: 3, Timestamp: 3,
FCMToken: "token-2", FCMToken: "token-2",
@ -377,7 +396,7 @@ func TestSetContactGeneratedData(t *testing.T) {
err = p.SaveContact(existingContact, nil) err = p.SaveContact(existingContact, nil)
require.NoError(t, err) require.NoError(t, err)
err = p.SetContactsGeneratedData([]Contact{existingContactUpdate, nonExistingContactUpdate}, nil) err = p.SetContactsGeneratedData([]*Contact{&existingContactUpdate, &nonExistingContactUpdate}, nil)
require.NoError(t, err) require.NoError(t, err)
allContacts, err := p.Contacts() allContacts, err := p.Contacts()
@ -401,9 +420,10 @@ func openTestDB() (*sql.DB, error) {
} }
func insertMinimalMessage(p sqlitePersistence, id string) error { func insertMinimalMessage(p sqlitePersistence, id string) error {
return p.SaveMessagesLegacy([]*Message{{ return p.SaveMessagesLegacy([]*Message{&Message{
ID: id, ID: id,
ChatID: "chat-id", LocalChatID: "chat-id",
ChatMessage: protobuf.ChatMessage{Text: "some-text"},
From: "me", From: "me",
}}) }})
} }

View file

@ -0,0 +1,421 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: message.proto
package protobuf
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type ChatMessage_MessageType int32
const (
ChatMessage_ONE_TO_ONE ChatMessage_MessageType = 0
ChatMessage_PUBLIC_GROUP ChatMessage_MessageType = 1
ChatMessage_PRIVATE_GROUP ChatMessage_MessageType = 2
// Only local
ChatMessage_SYSTEM_MESSAGE_PRIVATE_GROUP ChatMessage_MessageType = 3
)
var ChatMessage_MessageType_name = map[int32]string{
0: "ONE_TO_ONE",
1: "PUBLIC_GROUP",
2: "PRIVATE_GROUP",
3: "SYSTEM_MESSAGE_PRIVATE_GROUP",
}
var ChatMessage_MessageType_value = map[string]int32{
"ONE_TO_ONE": 0,
"PUBLIC_GROUP": 1,
"PRIVATE_GROUP": 2,
"SYSTEM_MESSAGE_PRIVATE_GROUP": 3,
}
func (x ChatMessage_MessageType) String() string {
return proto.EnumName(ChatMessage_MessageType_name, int32(x))
}
func (ChatMessage_MessageType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1, 0}
}
type ChatMessage_ContentType int32
const (
ChatMessage_TEXT_PLAIN ChatMessage_ContentType = 0
ChatMessage_STICKER ChatMessage_ContentType = 1
ChatMessage_STATUS ChatMessage_ContentType = 2
ChatMessage_EMOJI ChatMessage_ContentType = 3
ChatMessage_COMMAND ChatMessage_ContentType = 4
ChatMessage_COMMAND_REQUEST ChatMessage_ContentType = 5
)
var ChatMessage_ContentType_name = map[int32]string{
0: "TEXT_PLAIN",
1: "STICKER",
2: "STATUS",
3: "EMOJI",
4: "COMMAND",
5: "COMMAND_REQUEST",
}
var ChatMessage_ContentType_value = map[string]int32{
"TEXT_PLAIN": 0,
"STICKER": 1,
"STATUS": 2,
"EMOJI": 3,
"COMMAND": 4,
"COMMAND_REQUEST": 5,
}
func (x ChatMessage_ContentType) String() string {
return proto.EnumName(ChatMessage_ContentType_name, int32(x))
}
func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1, 1}
}
type ApplicationMetadataMessage_MessageType int32
const (
ApplicationMetadataMessage_TEXT_MESSAGE ApplicationMetadataMessage_MessageType = 0
ApplicationMetadataMessage_CONTACT_REQUEST ApplicationMetadataMessage_MessageType = 1
ApplicationMetadataMessage_MEMBERSHIP_UPDATE ApplicationMetadataMessage_MessageType = 2
ApplicationMetadataMessage_PAIR_INSTALLATION ApplicationMetadataMessage_MessageType = 3
ApplicationMetadataMessage_SYNC_INSTALLATION ApplicationMetadataMessage_MessageType = 4
)
var ApplicationMetadataMessage_MessageType_name = map[int32]string{
0: "TEXT_MESSAGE",
1: "CONTACT_REQUEST",
2: "MEMBERSHIP_UPDATE",
3: "PAIR_INSTALLATION",
4: "SYNC_INSTALLATION",
}
var ApplicationMetadataMessage_MessageType_value = map[string]int32{
"TEXT_MESSAGE": 0,
"CONTACT_REQUEST": 1,
"MEMBERSHIP_UPDATE": 2,
"PAIR_INSTALLATION": 3,
"SYNC_INSTALLATION": 4,
}
func (x ApplicationMetadataMessage_MessageType) String() string {
return proto.EnumName(ApplicationMetadataMessage_MessageType_name, int32(x))
}
func (ApplicationMetadataMessage_MessageType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{2, 0}
}
type StickerMessage struct {
Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Pack int32 `protobuf:"varint,2,opt,name=pack,proto3" json:"pack,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StickerMessage) Reset() { *m = StickerMessage{} }
func (m *StickerMessage) String() string { return proto.CompactTextString(m) }
func (*StickerMessage) ProtoMessage() {}
func (*StickerMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{0}
}
func (m *StickerMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StickerMessage.Unmarshal(m, b)
}
func (m *StickerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StickerMessage.Marshal(b, m, deterministic)
}
func (m *StickerMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_StickerMessage.Merge(m, src)
}
func (m *StickerMessage) XXX_Size() int {
return xxx_messageInfo_StickerMessage.Size(m)
}
func (m *StickerMessage) XXX_DiscardUnknown() {
xxx_messageInfo_StickerMessage.DiscardUnknown(m)
}
var xxx_messageInfo_StickerMessage proto.InternalMessageInfo
func (m *StickerMessage) GetHash() string {
if m != nil {
return m.Hash
}
return ""
}
func (m *StickerMessage) GetPack() int32 {
if m != nil {
return m.Pack
}
return 0
}
type ChatMessage struct {
// Lamport timestamp of the chat message
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
// Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
// so that we don't rely on it
Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// Text of the message
Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"`
// Id of the message that we are replying to
ResponseTo string `protobuf:"bytes,4,opt,name=response_to,json=responseTo,proto3" json:"response_to,omitempty"`
// Ens name of the sender
EnsName string `protobuf:"bytes,5,opt,name=ens_name,json=ensName,proto3" json:"ens_name,omitempty"`
// Chat id, this field is symmetric for public-chats and private group chats,
// but asymmetric in case of one-to-ones, as the sender will use the chat-id
// of the received, while the receiver will use the chat-id of the sender.
// Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
ChatId string `protobuf:"bytes,6,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
// The type of message (public/one-to-one/private-group-chat)
MessageType ChatMessage_MessageType `protobuf:"varint,7,opt,name=message_type,json=messageType,proto3,enum=protobuf.ChatMessage_MessageType" json:"message_type,omitempty"`
// The type of the content of the message
ContentType ChatMessage_ContentType `protobuf:"varint,8,opt,name=content_type,json=contentType,proto3,enum=protobuf.ChatMessage_ContentType" json:"content_type,omitempty"`
// Types that are valid to be assigned to Payload:
// *ChatMessage_Sticker
Payload isChatMessage_Payload `protobuf_oneof:"payload"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ChatMessage) Reset() { *m = ChatMessage{} }
func (m *ChatMessage) String() string { return proto.CompactTextString(m) }
func (*ChatMessage) ProtoMessage() {}
func (*ChatMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1}
}
func (m *ChatMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChatMessage.Unmarshal(m, b)
}
func (m *ChatMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ChatMessage.Marshal(b, m, deterministic)
}
func (m *ChatMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_ChatMessage.Merge(m, src)
}
func (m *ChatMessage) XXX_Size() int {
return xxx_messageInfo_ChatMessage.Size(m)
}
func (m *ChatMessage) XXX_DiscardUnknown() {
xxx_messageInfo_ChatMessage.DiscardUnknown(m)
}
var xxx_messageInfo_ChatMessage proto.InternalMessageInfo
func (m *ChatMessage) GetClock() uint64 {
if m != nil {
return m.Clock
}
return 0
}
func (m *ChatMessage) GetTimestamp() uint64 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *ChatMessage) GetText() string {
if m != nil {
return m.Text
}
return ""
}
func (m *ChatMessage) GetResponseTo() string {
if m != nil {
return m.ResponseTo
}
return ""
}
func (m *ChatMessage) GetEnsName() string {
if m != nil {
return m.EnsName
}
return ""
}
func (m *ChatMessage) GetChatId() string {
if m != nil {
return m.ChatId
}
return ""
}
func (m *ChatMessage) GetMessageType() ChatMessage_MessageType {
if m != nil {
return m.MessageType
}
return ChatMessage_ONE_TO_ONE
}
func (m *ChatMessage) GetContentType() ChatMessage_ContentType {
if m != nil {
return m.ContentType
}
return ChatMessage_TEXT_PLAIN
}
type isChatMessage_Payload interface {
isChatMessage_Payload()
}
type ChatMessage_Sticker struct {
Sticker *StickerMessage `protobuf:"bytes,9,opt,name=sticker,proto3,oneof"`
}
func (*ChatMessage_Sticker) isChatMessage_Payload() {}
func (m *ChatMessage) GetPayload() isChatMessage_Payload {
if m != nil {
return m.Payload
}
return nil
}
func (m *ChatMessage) GetSticker() *StickerMessage {
if x, ok := m.GetPayload().(*ChatMessage_Sticker); ok {
return x.Sticker
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ChatMessage) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*ChatMessage_Sticker)(nil),
}
}
type ApplicationMetadataMessage struct {
// Signature of the payload field
Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
// This is the encoded protobuf of the application level message, i.e ChatMessage
Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
// The type of protobuf message sent
MessageType ApplicationMetadataMessage_MessageType `protobuf:"varint,3,opt,name=message_type,json=messageType,proto3,enum=protobuf.ApplicationMetadataMessage_MessageType" json:"message_type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ApplicationMetadataMessage) Reset() { *m = ApplicationMetadataMessage{} }
func (m *ApplicationMetadataMessage) String() string { return proto.CompactTextString(m) }
func (*ApplicationMetadataMessage) ProtoMessage() {}
func (*ApplicationMetadataMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{2}
}
func (m *ApplicationMetadataMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ApplicationMetadataMessage.Unmarshal(m, b)
}
func (m *ApplicationMetadataMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ApplicationMetadataMessage.Marshal(b, m, deterministic)
}
func (m *ApplicationMetadataMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_ApplicationMetadataMessage.Merge(m, src)
}
func (m *ApplicationMetadataMessage) XXX_Size() int {
return xxx_messageInfo_ApplicationMetadataMessage.Size(m)
}
func (m *ApplicationMetadataMessage) XXX_DiscardUnknown() {
xxx_messageInfo_ApplicationMetadataMessage.DiscardUnknown(m)
}
var xxx_messageInfo_ApplicationMetadataMessage proto.InternalMessageInfo
func (m *ApplicationMetadataMessage) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *ApplicationMetadataMessage) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func (m *ApplicationMetadataMessage) GetMessageType() ApplicationMetadataMessage_MessageType {
if m != nil {
return m.MessageType
}
return ApplicationMetadataMessage_TEXT_MESSAGE
}
func init() {
proto.RegisterEnum("protobuf.ChatMessage_MessageType", ChatMessage_MessageType_name, ChatMessage_MessageType_value)
proto.RegisterEnum("protobuf.ChatMessage_ContentType", ChatMessage_ContentType_name, ChatMessage_ContentType_value)
proto.RegisterEnum("protobuf.ApplicationMetadataMessage_MessageType", ApplicationMetadataMessage_MessageType_name, ApplicationMetadataMessage_MessageType_value)
proto.RegisterType((*StickerMessage)(nil), "protobuf.StickerMessage")
proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage")
proto.RegisterType((*ApplicationMetadataMessage)(nil), "protobuf.ApplicationMetadataMessage")
}
func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) }
var fileDescriptor_33c57e4bae7b9afd = []byte{
// 563 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x5f, 0x6f, 0xda, 0x3e,
0x14, 0x25, 0x10, 0xa0, 0xdc, 0xd0, 0xfe, 0x5c, 0xff, 0x36, 0x2d, 0x9b, 0x2a, 0x8d, 0xf1, 0xc4,
0x13, 0x9a, 0xba, 0x3d, 0xec, 0x35, 0x4d, 0xad, 0x36, 0x1b, 0xf9, 0x33, 0xdb, 0x4c, 0xeb, 0x93,
0xe5, 0x06, 0xaf, 0xa0, 0x96, 0x24, 0x22, 0xae, 0x34, 0xbe, 0xcf, 0x3e, 0xc9, 0x3e, 0xd9, 0x14,
0x07, 0x0a, 0x4c, 0xea, 0x9e, 0xec, 0x73, 0x7c, 0x7d, 0xee, 0xbd, 0xe7, 0x5e, 0x38, 0x5e, 0xaa,
0xb2, 0x94, 0x77, 0x6a, 0x5c, 0xac, 0x72, 0x9d, 0xe3, 0x23, 0x73, 0xdc, 0x3e, 0xfe, 0x18, 0x7e,
0x82, 0x13, 0xa6, 0x17, 0xe9, 0xbd, 0x5a, 0x85, 0x75, 0x04, 0xc6, 0x60, 0xcf, 0x65, 0x39, 0x77,
0xad, 0x81, 0x35, 0xea, 0x51, 0x73, 0xaf, 0xb8, 0x42, 0xa6, 0xf7, 0x6e, 0x73, 0x60, 0x8d, 0xda,
0xd4, 0xdc, 0x87, 0xbf, 0x6d, 0x70, 0xfc, 0xb9, 0xd4, 0xdb, 0x7f, 0x2f, 0xa0, 0x9d, 0x3e, 0xe4,
0xe9, 0xbd, 0xf9, 0x68, 0xd3, 0x1a, 0xe0, 0x33, 0xe8, 0xe9, 0xc5, 0x52, 0x95, 0x5a, 0x2e, 0x0b,
0xf3, 0xdd, 0xa6, 0x3b, 0xa2, 0xd2, 0xd5, 0xea, 0xa7, 0x76, 0x5b, 0x75, 0xae, 0xea, 0x8e, 0xdf,
0x82, 0xb3, 0x52, 0x65, 0x91, 0x67, 0xa5, 0x12, 0x3a, 0x77, 0x6d, 0xf3, 0x04, 0x5b, 0x8a, 0xe7,
0xf8, 0x35, 0x1c, 0xa9, 0xac, 0x14, 0x99, 0x5c, 0x2a, 0xb7, 0x6d, 0x5e, 0xbb, 0x2a, 0x2b, 0x23,
0xb9, 0x54, 0xf8, 0x15, 0x74, 0xd3, 0xb9, 0xd4, 0x62, 0x31, 0x73, 0x3b, 0xe6, 0xa5, 0x53, 0xc1,
0x60, 0x86, 0x2f, 0xa1, 0xbf, 0x71, 0x40, 0xe8, 0x75, 0xa1, 0xdc, 0xee, 0xc0, 0x1a, 0x9d, 0x9c,
0xbf, 0x1b, 0x6f, 0x7d, 0x18, 0xef, 0x75, 0x32, 0xde, 0x9c, 0x7c, 0x5d, 0x28, 0xea, 0x2c, 0x77,
0xa0, 0x52, 0x49, 0xf3, 0x4c, 0xab, 0x4c, 0xd7, 0x2a, 0x47, 0xff, 0x52, 0xf1, 0xeb, 0xc8, 0x5a,
0x25, 0xdd, 0x01, 0xfc, 0x11, 0xba, 0x65, 0x6d, 0xb9, 0xdb, 0x1b, 0x58, 0x23, 0xe7, 0xdc, 0xdd,
0x09, 0x1c, 0xce, 0xe2, 0xba, 0x41, 0xb7, 0xa1, 0xc3, 0x19, 0x38, 0x7b, 0x75, 0xe1, 0x13, 0x80,
0x38, 0x22, 0x82, 0xc7, 0x22, 0x8e, 0x08, 0x6a, 0x60, 0x04, 0xfd, 0x64, 0x7a, 0x31, 0x09, 0x7c,
0x71, 0x45, 0xe3, 0x69, 0x82, 0x2c, 0x7c, 0x0a, 0xc7, 0x09, 0x0d, 0xbe, 0x79, 0x9c, 0x6c, 0xa8,
0x26, 0x1e, 0xc0, 0x19, 0xbb, 0x61, 0x9c, 0x84, 0x22, 0x24, 0x8c, 0x79, 0x57, 0x44, 0x1c, 0x46,
0xb4, 0x86, 0x29, 0x38, 0x7b, 0x75, 0x57, 0x59, 0x38, 0xf9, 0xce, 0x45, 0x32, 0xf1, 0x82, 0x08,
0x35, 0xb0, 0x03, 0x5d, 0xc6, 0x03, 0xff, 0x0b, 0xa1, 0xc8, 0xc2, 0x00, 0x1d, 0xc6, 0x3d, 0x3e,
0x65, 0xa8, 0x89, 0x7b, 0xd0, 0x26, 0x61, 0xfc, 0x39, 0x40, 0xad, 0x2a, 0xc6, 0x8f, 0xc3, 0xd0,
0x8b, 0x2e, 0x91, 0x8d, 0xff, 0x87, 0xff, 0x36, 0x40, 0x50, 0xf2, 0x75, 0x4a, 0x18, 0x47, 0xed,
0x8b, 0x1e, 0x74, 0x0b, 0xb9, 0x7e, 0xc8, 0xe5, 0x6c, 0xf8, 0xab, 0x09, 0x6f, 0xbc, 0xa2, 0x78,
0x58, 0xa4, 0x52, 0x2f, 0xf2, 0x2c, 0x54, 0x5a, 0xce, 0xa4, 0x96, 0xdb, 0x9d, 0x3a, 0x83, 0x5e,
0xb9, 0xb8, 0xcb, 0xa4, 0x7e, 0x5c, 0x29, 0xb3, 0x57, 0x7d, 0xba, 0x23, 0xb0, 0xfb, 0xa4, 0x63,
0x36, 0xab, 0x4f, 0xb7, 0x10, 0xb3, 0xbf, 0xc6, 0xdd, 0x32, 0x83, 0x7a, 0xbf, 0xf3, 0xf9, 0xf9,
0x9c, 0xcf, 0x4e, 0x7f, 0xb8, 0x3e, 0x9c, 0x00, 0x82, 0xbe, 0xf1, 0x66, 0x63, 0x25, 0x6a, 0xd4,
0xcd, 0x46, 0xdc, 0xf3, 0xf9, 0x53, 0xb3, 0x16, 0x7e, 0x09, 0xa7, 0x21, 0x09, 0x2f, 0x08, 0x65,
0xd7, 0x41, 0x22, 0xa6, 0xc9, 0xa5, 0xc7, 0x09, 0x6a, 0x56, 0x74, 0xe2, 0x05, 0x54, 0x04, 0x11,
0xe3, 0xde, 0x64, 0xe2, 0xf1, 0x20, 0x8e, 0x50, 0xab, 0xa2, 0xd9, 0x4d, 0xe4, 0x1f, 0xd2, 0xf6,
0x6d, 0xc7, 0x14, 0xfe, 0xe1, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xa4, 0x11, 0xfe, 0xc7,
0x03, 0x00, 0x00,
}

View file

@ -0,0 +1,70 @@
syntax = "proto3";
package protobuf;
message StickerMessage {
string hash = 1;
int32 pack = 2;
}
message ChatMessage {
// Lamport timestamp of the chat message
uint64 clock = 1;
// Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
// so that we don't rely on it
uint64 timestamp = 2;
// Text of the message
string text = 3;
// Id of the message that we are replying to
string response_to = 4;
// Ens name of the sender
string ens_name = 5;
// Chat id, this field is symmetric for public-chats and private group chats,
// but asymmetric in case of one-to-ones, as the sender will use the chat-id
// of the received, while the receiver will use the chat-id of the sender.
// Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
string chat_id = 6;
// The type of message (public/one-to-one/private-group-chat)
MessageType message_type = 7;
// The type of the content of the message
ContentType content_type = 8;
oneof payload {
StickerMessage sticker = 9;
}
enum MessageType {
ONE_TO_ONE = 0;
PUBLIC_GROUP = 1;
PRIVATE_GROUP = 2;
// Only local
SYSTEM_MESSAGE_PRIVATE_GROUP = 3;
}
enum ContentType {
TEXT_PLAIN = 0;
STICKER = 1;
STATUS = 2;
EMOJI = 3;
COMMAND = 4;
COMMAND_REQUEST = 5;
}
}
message ApplicationMetadataMessage {
// Signature of the payload field
bytes signature = 1;
// This is the encoded protobuf of the application level message, i.e ChatMessage
bytes payload = 2;
// The type of protobuf message sent
MessageType message_type = 3;
enum MessageType {
TEXT_MESSAGE = 0;
CONTACT_REQUEST = 1;
MEMBERSHIP_UPDATE = 2;
PAIR_INSTALLATION = 3;
SYNC_INSTALLATION = 4;
}
}

View file

@ -1,11 +1,11 @@
package applicationmetadata package protobuf
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
) )
func (m *Message) RecoverKey() (*ecdsa.PublicKey, error) { func (m *ApplicationMetadataMessage) RecoverKey() (*ecdsa.PublicKey, error) {
if m.Signature == nil { if m.Signature == nil {
return nil, nil return nil, nil
} }

View file

@ -1,4 +1,4 @@
package applicationmetadata package protobuf
import ( import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
@ -6,8 +6,8 @@ import (
//go:generate protoc --go_out=. ./message.proto //go:generate protoc --go_out=. ./message.proto
func Unmarshal(payload []byte) (*Message, error) { func Unmarshal(payload []byte) (*ApplicationMetadataMessage, error) {
var message Message var message ApplicationMetadataMessage
err := proto.Unmarshal(payload, &message) err := proto.Unmarshal(payload, &message)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -96,14 +96,11 @@ func newFiltersManager(db *sql.DB, w types.Whisper, privateKey *ecdsa.PrivateKey
func (s *filtersManager) Init( func (s *filtersManager) Init(
chatIDs []string, chatIDs []string,
publicKeys []*ecdsa.PublicKey, publicKeys []*ecdsa.PublicKey,
genericDiscoveryTopicEnabled bool,
) ([]*Filter, error) { ) ([]*Filter, error) {
logger := s.logger.With(zap.String("site", "Init")) logger := s.logger.With(zap.String("site", "Init"))
logger.Info("initializing") logger.Info("initializing")
s.genericDiscoveryTopicEnabled = genericDiscoveryTopicEnabled
// Load our contact code. // Load our contact code.
_, err := s.LoadContactCode(&s.privateKey.PublicKey) _, err := s.LoadContactCode(&s.privateKey.PublicKey)
if err != nil { if err != nil {
@ -148,7 +145,7 @@ func (s *filtersManager) Init(
} }
// DEPRECATED // DEPRECATED
func (s *filtersManager) InitWithFilters(filters []*Filter, genericDiscoveryTopicEnabled bool) ([]*Filter, error) { func (s *filtersManager) InitWithFilters(filters []*Filter) ([]*Filter, error) {
var ( var (
chatIDs []string chatIDs []string
publicKeys []*ecdsa.PublicKey publicKeys []*ecdsa.PublicKey
@ -166,7 +163,7 @@ func (s *filtersManager) InitWithFilters(filters []*Filter, genericDiscoveryTopi
} }
} }
return s.Init(chatIDs, publicKeys, genericDiscoveryTopicEnabled) return s.Init(chatIDs, publicKeys)
} }
func (s *filtersManager) Reset() error { func (s *filtersManager) Reset() error {
@ -315,8 +312,8 @@ func (s *filtersManager) LoadNegotiated(secret types.NegotiatedSecret) (*Filter,
return chat, nil return chat, nil
} }
// LoadDiscovery adds 1-2 discovery filters: one for generic discovery topic (if enabled) // LoadDiscovery adds 1 discovery filter
// and one for the personal discovery topic. // for the personal discovery topic.
func (s *filtersManager) LoadDiscovery() ([]*Filter, error) { func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -328,12 +325,6 @@ func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
expectedTopicCount := 1 expectedTopicCount := 1
if s.genericDiscoveryTopicEnabled {
expectedTopicCount = 2
if chat, ok := s.filters[discoveryTopic]; ok {
result = append(result, chat)
}
}
if chat, ok := s.filters[personalDiscoveryTopic]; ok { if chat, ok := s.filters[personalDiscoveryTopic]; ok {
result = append(result, chat) result = append(result, chat)
} }
@ -365,29 +356,6 @@ func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
s.filters[personalDiscoveryChat.ChatID] = personalDiscoveryChat s.filters[personalDiscoveryChat.ChatID] = personalDiscoveryChat
if s.genericDiscoveryTopicEnabled {
// Load generic discovery topic.
discoveryChat := &Filter{
ChatID: discoveryTopic,
Identity: identityStr,
Discovery: true,
Listen: true,
OneToOne: true,
}
discoveryResponse, err = s.addAsymmetric(discoveryChat.ChatID, true)
if err != nil {
return nil, err
}
discoveryChat.Topic = discoveryResponse.Topic
discoveryChat.FilterID = discoveryResponse.FilterID
s.filters[discoveryChat.ChatID] = discoveryChat
return []*Filter{discoveryChat, personalDiscoveryChat}, nil
}
return []*Filter{personalDiscoveryChat}, nil return []*Filter{personalDiscoveryChat}, nil
} }

View file

@ -85,21 +85,8 @@ func (s *FiltersManagerSuite) TearDownTest() {
_ = s.logger.Sync() _ = s.logger.Sync()
} }
func (s *FiltersManagerSuite) TestDiscoveryAndPartitionedTopic() {
_, err := s.chats.Init(nil, nil, true)
s.Require().NoError(err)
s.Require().Equal(4, len(s.chats.filters), "It creates four filters")
discoveryFilter := s.chats.filters[discoveryTopic]
s.Require().NotNil(discoveryFilter, "It adds the discovery filter")
s.Require().True(discoveryFilter.Listen)
s.assertRequiredFilters()
}
func (s *FiltersManagerSuite) TestPartitionedTopicWithDiscoveryDisabled() { func (s *FiltersManagerSuite) TestPartitionedTopicWithDiscoveryDisabled() {
_, err := s.chats.Init(nil, nil, false) _, err := s.chats.Init(nil, nil)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(3, len(s.chats.filters), "It creates three filters") s.Require().Equal(3, len(s.chats.filters), "It creates three filters")

View file

@ -86,7 +86,7 @@ func _1561059285_add_whisper_keysDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x31, 0x3f, 0xce, 0xfa, 0x44, 0x36, 0x1b, 0xb0, 0xec, 0x5d, 0xb, 0x90, 0xb, 0x21, 0x4f, 0xd5, 0xe5, 0x50, 0xed, 0xc7, 0x43, 0xdf, 0x83, 0xb4, 0x3a, 0xc1, 0x55, 0x2e, 0x53, 0x7c, 0x67}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x31, 0x3f, 0xce, 0xfa, 0x44, 0x36, 0x1b, 0xb0, 0xec, 0x5d, 0xb, 0x90, 0xb, 0x21, 0x4f, 0xd5, 0xe5, 0x50, 0xed, 0xc7, 0x43, 0xdf, 0x83, 0xb4, 0x3a, 0xc1, 0x55, 0x2e, 0x53, 0x7c, 0x67}}
return a, nil return a, nil
} }
@ -106,7 +106,7 @@ func _1561059285_add_whisper_keysUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x25, 0x41, 0xc, 0x92, 0xdd, 0x9e, 0xff, 0x5d, 0xd0, 0x93, 0xe4, 0x24, 0x50, 0x29, 0xcf, 0xc6, 0xf7, 0x49, 0x3c, 0x73, 0xd9, 0x8c, 0xfa, 0xf2, 0xcf, 0xf6, 0x6f, 0xbc, 0x31, 0xe6, 0xf7, 0xe2}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x25, 0x41, 0xc, 0x92, 0xdd, 0x9e, 0xff, 0x5d, 0xd0, 0x93, 0xe4, 0x24, 0x50, 0x29, 0xcf, 0xc6, 0xf7, 0x49, 0x3c, 0x73, 0xd9, 0x8c, 0xfa, 0xf2, 0xcf, 0xf6, 0x6f, 0xbc, 0x31, 0xe6, 0xf7, 0xe2}}
return a, nil return a, nil
} }
@ -126,7 +126,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}}
return a, nil return a, nil
} }
@ -270,9 +270,9 @@ type bintree struct {
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"1561059285_add_whisper_keys.down.sql": {_1561059285_add_whisper_keysDownSql, map[string]*bintree{}}, "1561059285_add_whisper_keys.down.sql": &bintree{_1561059285_add_whisper_keysDownSql, map[string]*bintree{}},
"1561059285_add_whisper_keys.up.sql": {_1561059285_add_whisper_keysUpSql, map[string]*bintree{}}, "1561059285_add_whisper_keys.up.sql": &bintree{_1561059285_add_whisper_keysUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}
// RestoreAsset restores an asset under the given directory. // RestoreAsset restores an asset under the given directory.

View file

@ -58,13 +58,6 @@ func (m *whisperServiceKeysManager) RawSymKey(id string) ([]byte, error) {
type Option func(*WhisperServiceTransport) error type Option func(*WhisperServiceTransport) error
func SetGenericDiscoveryTopicSupport(val bool) Option {
return func(t *WhisperServiceTransport) error {
t.genericDiscoveryTopicEnabled = val
return nil
}
}
// WhisperServiceTransport is a transport based on Whisper service. // WhisperServiceTransport is a transport based on Whisper service.
type WhisperServiceTransport struct { type WhisperServiceTransport struct {
shh types.Whisper shh types.Whisper
@ -75,8 +68,6 @@ type WhisperServiceTransport struct {
mailservers []string mailservers []string
envelopesMonitor *EnvelopesMonitor envelopesMonitor *EnvelopesMonitor
genericDiscoveryTopicEnabled bool
} }
// NewWhisperServiceTransport returns a new WhisperServiceTransport. // NewWhisperServiceTransport returns a new WhisperServiceTransport.
@ -131,7 +122,7 @@ func NewWhisperServiceTransport(
} }
func (a *WhisperServiceTransport) InitFilters(chatIDs []string, publicKeys []*ecdsa.PublicKey) ([]*Filter, error) { func (a *WhisperServiceTransport) InitFilters(chatIDs []string, publicKeys []*ecdsa.PublicKey) ([]*Filter, error) {
return a.filters.Init(chatIDs, publicKeys, a.genericDiscoveryTopicEnabled) return a.filters.Init(chatIDs, publicKeys)
} }
func (a *WhisperServiceTransport) Filters() []*Filter { func (a *WhisperServiceTransport) Filters() []*Filter {
@ -140,7 +131,7 @@ func (a *WhisperServiceTransport) Filters() []*Filter {
// DEPRECATED // DEPRECATED
func (a *WhisperServiceTransport) LoadFilters(filters []*Filter) ([]*Filter, error) { func (a *WhisperServiceTransport) LoadFilters(filters []*Filter) ([]*Filter, error) {
return a.filters.InitWithFilters(filters, a.genericDiscoveryTopicEnabled) return a.filters.InitWithFilters(filters)
} }
// DEPRECATED // DEPRECATED
@ -247,7 +238,7 @@ func (a *WhisperServiceTransport) RetrievePublicMessages(chatID string) ([]*type
func (a *WhisperServiceTransport) RetrievePrivateMessages(publicKey *ecdsa.PublicKey) ([]*types.Message, error) { func (a *WhisperServiceTransport) RetrievePrivateMessages(publicKey *ecdsa.PublicKey) ([]*types.Message, error) {
chats := a.filters.FiltersByPublicKey(publicKey) chats := a.filters.FiltersByPublicKey(publicKey)
discoveryChats, err := a.filters.Init(nil, nil, true) discoveryChats, err := a.filters.Init(nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -5,7 +5,7 @@ import "time"
const clockBumpInMs = int64(time.Minute / time.Millisecond) const clockBumpInMs = int64(time.Minute / time.Millisecond)
// CalcMessageClock calculates a new clock value for Message. // CalcMessageClock calculates a new clock value for Message.
// It is used to properly sort messages and accomodate the fact // It is used to properly sort messages and accommodate the fact
// that time might be different on each device. // that time might be different on each device.
func CalcMessageClock(lastObservedValue int64, timeInMs TimestampInMs) int64 { func CalcMessageClock(lastObservedValue int64, timeInMs TimestampInMs) int64 {
clock := lastObservedValue clock := lastObservedValue

View file

@ -1,38 +0,0 @@
package protocol
import (
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/ast"
"strings"
"unicode"
"unicode/utf8"
)
// Content contains the chat ID and the actual text of a message.
type Content struct {
ChatID string `json:"chat_id"`
Text string `json:"text"`
ResponseTo string `json:"response-to"`
Name string `json:"name"` // the ENS name of the sender
ParsedText ast.Node `json:"parsedText"`
LineCount int `json:"lineCount"`
RTL bool `json:"rtl"`
}
// Check if the first character is Hebrew or Arabic or the RTL character
func isRTL(s string) bool {
first, _ := utf8.DecodeRuneInString(s)
return unicode.Is(unicode.Hebrew, first) ||
unicode.Is(unicode.Arabic, first) ||
// RTL character
first == '\u200f'
}
// PrepareContent return the parsed content of the message, the line-count and whether
// is a right-to-left message
func PrepareContent(content Content) Content {
content.ParsedText = markdown.Parse([]byte(content.Text), nil)
content.LineCount = strings.Count(content.Text, "\n")
content.RTL = isRTL(content.Text)
return content
}

View file

@ -14,7 +14,6 @@ import (
// More about Transit: https://github.com/cognitect/transit-format // More about Transit: https://github.com/cognitect/transit-format
func NewMessageDecoder(r io.Reader) *transit.Decoder { func NewMessageDecoder(r io.Reader) *transit.Decoder {
decoder := transit.NewDecoder(r) decoder := transit.NewDecoder(r)
decoder.AddHandler(messageTag, statusMessageHandler)
decoder.AddHandler(pairMessageTag, pairMessageHandler) decoder.AddHandler(pairMessageTag, pairMessageHandler)
decoder.AddHandler(membershipUpdateTag, membershipUpdateMessageHandler) decoder.AddHandler(membershipUpdateTag, membershipUpdateMessageHandler)
return decoder return decoder
@ -26,76 +25,6 @@ const (
membershipUpdateTag = "g5" membershipUpdateTag = "g5"
) )
func statusMessageHandler(d transit.Decoder, value interface{}) (interface{}, error) {
taggedValue, ok := value.(transit.TaggedValue)
if !ok {
return nil, errors.New("not a tagged value")
}
values, ok := taggedValue.Value.([]interface{})
if !ok {
return nil, errors.New("tagged value does not contain values")
}
sm := Message{}
for idx, v := range values {
var ok bool
switch idx {
case 0:
sm.Text, ok = v.(string)
case 1:
sm.ContentT, ok = v.(string)
case 2:
var messageT transit.Keyword
messageT, ok = v.(transit.Keyword)
if ok {
sm.MessageT = string(messageT)
}
case 3:
sm.Clock, ok = v.(int64)
case 4:
var timestamp int64
timestamp, ok = v.(int64)
if ok {
sm.Timestamp = TimestampInMs(timestamp)
}
case 5:
var content map[interface{}]interface{}
content, ok = v.(map[interface{}]interface{})
if !ok {
break
}
for key, contentVal := range content {
var keyKeyword transit.Keyword
keyKeyword, ok = key.(transit.Keyword)
if !ok {
break
}
switch keyKeyword {
case transit.Keyword("text"):
sm.Content.Text, ok = contentVal.(string)
case transit.Keyword("response-to"):
sm.Content.ResponseTo, ok = contentVal.(string)
case transit.Keyword("name"):
sm.Content.Name, ok = contentVal.(string)
case transit.Keyword("chat-id"):
sm.Content.ChatID, ok = contentVal.(string)
}
}
default:
// skip any other values
ok = true
}
if !ok {
return nil, fmt.Errorf("invalid value for index: %d", idx)
}
}
return sm, nil
}
func pairMessageHandler(d transit.Decoder, value interface{}) (interface{}, error) { func pairMessageHandler(d transit.Decoder, value interface{}) (interface{}, error) {
taggedValue, ok := value.(transit.TaggedValue) taggedValue, ok := value.(transit.TaggedValue)
if !ok { if !ok {
@ -196,21 +125,6 @@ func membershipUpdateMessageHandler(d transit.Decoder, value interface{}) (inter
m.Updates = append(m.Updates, update) m.Updates = append(m.Updates, update)
} }
case 2:
if v == nil {
continue
}
messageI, err := statusMessageHandler(d, v)
if err != nil {
return nil, fmt.Errorf("failed to handle message in membership update: %v", err)
}
var message Message
message, ok = messageI.(Message)
if ok {
m.Message = &message
}
default: default:
// skip any other values // skip any other values
ok = true ok = true

View file

@ -10,7 +10,6 @@ import (
) )
var ( var (
messageType = reflect.TypeOf(Message{})
pairMessageType = reflect.TypeOf(PairMessage{}) pairMessageType = reflect.TypeOf(PairMessage{})
membershipUpdateType = reflect.TypeOf(MembershipUpdateMessage{}) membershipUpdateType = reflect.TypeOf(MembershipUpdateMessage{})
@ -22,7 +21,6 @@ var (
// More about Transit: https://github.com/cognitect/transit-format // More about Transit: https://github.com/cognitect/transit-format
func NewMessageEncoder(w io.Writer) *transit.Encoder { func NewMessageEncoder(w io.Writer) *transit.Encoder {
encoder := transit.NewEncoder(w, false) encoder := transit.NewEncoder(w, false)
encoder.AddHandler(messageType, defaultMessageValueEncoder)
encoder.AddHandler(pairMessageType, defaultMessageValueEncoder) encoder.AddHandler(pairMessageType, defaultMessageValueEncoder)
encoder.AddHandler(membershipUpdateType, defaultMessageValueEncoder) encoder.AddHandler(membershipUpdateType, defaultMessageValueEncoder)
return encoder return encoder
@ -36,9 +34,6 @@ func (messageValueEncoder) IsStringable(reflect.Value) bool {
func (messageValueEncoder) Encode(e transit.Encoder, value reflect.Value, asString bool) error { func (messageValueEncoder) Encode(e transit.Encoder, value reflect.Value, asString bool) error {
switch message := value.Interface().(type) { switch message := value.Interface().(type) {
case Message:
taggedValue := encodeMessageToTaggedValue(message)
return e.EncodeInterface(taggedValue, false)
case PairMessage: case PairMessage:
taggedValue := transit.TaggedValue{ taggedValue := transit.TaggedValue{
Tag: pairMessageTag, Tag: pairMessageTag,
@ -86,9 +81,6 @@ func (messageValueEncoder) Encode(e transit.Encoder, value reflect.Value, asStri
message.ChatID, message.ChatID,
updatesList, updatesList,
} }
if message.Message != nil {
value = append(value, encodeMessageToTaggedValue(*message.Message))
}
taggedValue := transit.TaggedValue{ taggedValue := transit.TaggedValue{
Tag: membershipUpdateTag, Tag: membershipUpdateTag,
Value: value, Value: value,
@ -98,20 +90,3 @@ func (messageValueEncoder) Encode(e transit.Encoder, value reflect.Value, asStri
return errors.New("unknown message type to encode") return errors.New("unknown message type to encode")
} }
func encodeMessageToTaggedValue(m Message) transit.TaggedValue {
return transit.TaggedValue{
Tag: messageTag,
Value: []interface{}{
m.Text,
m.ContentT,
transit.Keyword(m.MessageT),
m.Clock,
m.Timestamp,
map[interface{}]interface{}{
transit.Keyword("chat-id"): m.Content.ChatID,
transit.Keyword("text"): m.Content.Text,
},
},
}
}

View file

@ -33,7 +33,6 @@ const (
type MembershipUpdateMessage struct { type MembershipUpdateMessage struct {
ChatID string `json:"chatId"` // UUID concatenated with hex-encoded public key of the creator for the chat ChatID string `json:"chatId"` // UUID concatenated with hex-encoded public key of the creator for the chat
Updates []MembershipUpdate `json:"updates"` Updates []MembershipUpdate `json:"updates"`
Message *Message `json:"message"` // optional message
} }
// Verify makes sure that the received update message has a valid signature. // Verify makes sure that the received update message has a valid signature.

View file

@ -33,26 +33,9 @@ var (
}, },
}, },
}, },
Message: nil,
} }
) )
func TestDecodeMembershipUpdateMessage(t *testing.T) {
val, err := decodeTransitMessage(testMembershipUpdateMessageBytes)
require.NoError(t, err)
require.EqualValues(t, testMembershipUpdateMessageStruct, val)
}
func TestEncodeMembershipUpdateMessage(t *testing.T) {
data, err := EncodeMembershipUpdateMessage(testMembershipUpdateMessageStruct)
require.NoError(t, err)
// Decode it back to a struct and compare. Comparing bytes is not an option because,
// for example, map encoding is non-deterministic.
val, err := decodeTransitMessage(data)
require.NoError(t, err)
require.EqualValues(t, testMembershipUpdateMessageStruct, val)
}
func TestTupleMembershipUpdateEvent(t *testing.T) { func TestTupleMembershipUpdateEvent(t *testing.T) {
event1 := testMembershipUpdateMessageStruct.Updates[0].Events[0] event1 := testMembershipUpdateMessageStruct.Updates[0].Events[0]
result1 := tupleMembershipUpdateEvent(event1) result1 := tupleMembershipUpdateEvent(event1)

View file

@ -1,29 +1,14 @@
package protocol package protocol
import ( import (
"bytes"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/hex"
"encoding/json"
"strings"
"time" "time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
) "github.com/status-im/status-go/protocol/protobuf"
const (
// ContentTypeTextPlain means that the message contains plain text.
ContentTypeTextPlain = "text/plain"
)
// Message types.
const (
MessageTypePublicGroup = "public-group-user-message"
MessageTypePrivate = "user-message"
MessageTypePrivateGroup = "group-user-message"
) )
var ( var (
@ -60,95 +45,11 @@ const (
MessageRead Flags = 1 << iota MessageRead Flags = 1 << iota
) )
// Message is a chat message sent by an user.
type Message struct {
Text string `json:"text"` // TODO: why is this duplicated?
ContentT string `json:"content_type"`
MessageT string `json:"message_type"`
Clock int64 `json:"clock"` // lamport timestamp; see CalcMessageClock for more details
Timestamp TimestampInMs `json:"timestamp"`
Content Content `json:"content"`
Flags Flags `json:"-"`
ID []byte `json:"-"`
SigPubKey *ecdsa.PublicKey `json:"-"`
ChatID string `json:"-"` // reference to Chat.ID; not connected to Content.ChatID which is set by sender
}
func (m *Message) MarshalJSON() ([]byte, error) {
type MessageAlias Message
item := struct {
*MessageAlias
ID string `json:"id"`
}{
MessageAlias: (*MessageAlias)(m),
ID: "0x" + hex.EncodeToString(m.ID),
}
return json.Marshal(item)
}
// createTextMessage creates a Message.
func createTextMessage(data []byte, lastClock int64, chatID, messageType string) Message {
text := strings.TrimSpace(string(data))
ts := TimestampInMsFromTime(time.Now())
clock := CalcMessageClock(lastClock, ts)
return Message{
Text: text,
ContentT: ContentTypeTextPlain,
MessageT: messageType,
Clock: clock,
Timestamp: ts,
Content: Content{ChatID: chatID, Text: text},
}
}
// CreatePublicTextMessage creates a public text Message.
func CreatePublicTextMessage(data []byte, lastClock int64, chatID string) Message {
m := createTextMessage(data, lastClock, chatID, MessageTypePublicGroup)
return m
}
// CreatePrivateTextMessage creates a one-to-one message.
func CreatePrivateTextMessage(data []byte, lastClock int64, chatID string) Message {
return createTextMessage(data, lastClock, chatID, MessageTypePrivate)
}
// CreatePrivateGroupTextMessage creates a group message.
func CreatePrivateGroupTextMessage(data []byte, lastClock int64, chatID string) Message {
return createTextMessage(data, lastClock, chatID, MessageTypePrivateGroup)
}
func decodeTransitMessage(originalPayload []byte) (interface{}, error) {
payload := make([]byte, len(originalPayload))
copy(payload, originalPayload)
// This modifies the payload
buf := bytes.NewBuffer(payload)
decoder := NewMessageDecoder(buf)
value, err := decoder.Decode()
if err != nil {
return nil, err
}
return value, nil
}
// EncodeMessage encodes a Message using Transit serialization.
func EncodeMessage(value Message) ([]byte, error) {
var buf bytes.Buffer
encoder := NewMessageEncoder(&buf)
if err := encoder.Encode(value); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// MessageID calculates the messageID from author's compressed public key // MessageID calculates the messageID from author's compressed public key
// and not encrypted but encoded payload. // and not encrypted but encoded payload.
func MessageID(author *ecdsa.PublicKey, data []byte) types.HexBytes { func MessageID(author *ecdsa.PublicKey, data []byte) types.HexBytes {
keyBytes := crypto.FromECDSAPub(author) keyBytes := crypto.FromECDSAPub(author)
return crypto.Keccak256(append(keyBytes, data...)) return types.HexBytes(crypto.Keccak256(append(keyBytes, data...)))
} }
// WrapMessageV1 wraps a payload into a protobuf message and signs it if an identity is provided // WrapMessageV1 wraps a payload into a protobuf message and signs it if an identity is provided
@ -162,7 +63,7 @@ func WrapMessageV1(payload []byte, identity *ecdsa.PrivateKey) ([]byte, error) {
} }
} }
message := &StatusProtocolMessage{ message := &protobuf.ApplicationMetadataMessage{
Signature: signature, Signature: signature,
Payload: payload, Payload: payload,
} }

View file

@ -1,85 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: message.proto
package protocol
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type StatusProtocolMessage struct {
Signature []byte `protobuf:"bytes,4001,opt,name=signature,proto3" json:"signature,omitempty"`
Payload []byte `protobuf:"bytes,4002,opt,name=payload,proto3" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StatusProtocolMessage) Reset() { *m = StatusProtocolMessage{} }
func (m *StatusProtocolMessage) String() string { return proto.CompactTextString(m) }
func (*StatusProtocolMessage) ProtoMessage() {}
func (*StatusProtocolMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{0}
}
func (m *StatusProtocolMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StatusProtocolMessage.Unmarshal(m, b)
}
func (m *StatusProtocolMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StatusProtocolMessage.Marshal(b, m, deterministic)
}
func (m *StatusProtocolMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_StatusProtocolMessage.Merge(m, src)
}
func (m *StatusProtocolMessage) XXX_Size() int {
return xxx_messageInfo_StatusProtocolMessage.Size(m)
}
func (m *StatusProtocolMessage) XXX_DiscardUnknown() {
xxx_messageInfo_StatusProtocolMessage.DiscardUnknown(m)
}
var xxx_messageInfo_StatusProtocolMessage proto.InternalMessageInfo
func (m *StatusProtocolMessage) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *StatusProtocolMessage) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func init() {
proto.RegisterType((*StatusProtocolMessage)(nil), "protocol.StatusProtocolMessage")
}
func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) }
var fileDescriptor_33c57e4bae7b9afd = []byte{
// 109 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x4d, 0x2d, 0x2e,
0x4e, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x2e, 0x2e, 0x49, 0x2c, 0x29,
0x2d, 0x06, 0x73, 0x94, 0x02, 0xb9, 0x44, 0x83, 0xc1, 0xdc, 0x00, 0x10, 0x37, 0x39, 0x3f, 0xc7,
0x17, 0xa2, 0x56, 0x48, 0x96, 0x8b, 0xb3, 0x38, 0x33, 0x3d, 0x2f, 0xb1, 0xa4, 0xb4, 0x28, 0x55,
0x62, 0xa1, 0xbc, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x42, 0x44, 0x48, 0x92, 0x8b, 0xbd, 0x20, 0xb1,
0x32, 0x27, 0x3f, 0x31, 0x45, 0x62, 0x11, 0x44, 0x12, 0xc6, 0x4f, 0x62, 0x03, 0x9b, 0x6c, 0x0c,
0x08, 0x00, 0x00, 0xff, 0xff, 0x92, 0x1a, 0x92, 0xf0, 0x77, 0x00, 0x00, 0x00,
}

View file

@ -9,50 +9,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var (
testMessageBytes = []byte(`["~#c4",["abc123","text/plain","~:public-group-user-message",154593077368201,1545930773682,["^ ","~:chat-id","testing-adamb","~:name", "test-name","~:response-to", "id","~:text","abc123"]]]`)
testMessageStruct = Message{
Text: "abc123",
ContentT: "text/plain",
MessageT: "public-group-user-message",
Clock: 154593077368201,
Timestamp: 1545930773682,
Content: Content{
ChatID: "testing-adamb",
Text: "abc123",
ResponseTo: "id",
Name: "test-name",
},
}
)
func TestDecodeTransitMessage(t *testing.T) {
val, err := decodeTransitMessage(testMessageBytes)
require.NoError(t, err)
require.EqualValues(t, testMessageStruct, val)
}
func BenchmarkDecodeTransitMessage(b *testing.B) {
_, err := decodeTransitMessage(testMessageBytes)
if err != nil {
b.Fatalf("failed to decode message: %v", err)
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, _ = decodeTransitMessage(testMessageBytes)
}
data, err := EncodeMessage(testMessageStruct)
require.NoError(b, err)
// Decode it back to a struct because, for example, map encoding is non-deterministic
// and it is not possible to compare bytes.
val, err := decodeTransitMessage(data)
require.NoError(b, err)
require.EqualValues(b, testMessageStruct, val)
}
func TestMessageID(t *testing.T) { func TestMessageID(t *testing.T) {
key, err := crypto.GenerateKey() key, err := crypto.GenerateKey()
require.NoError(t, err) require.NoError(t, err)

View file

@ -1,33 +0,0 @@
package protocol
import (
"testing"
"github.com/stretchr/testify/require"
)
var (
testPairMessageBytes = []byte(`["~#p2",["installation-id","desktop","name","token"]]`)
testPairMessageStruct = PairMessage{
Name: "name",
DeviceType: "desktop",
FCMToken: "token",
InstallationID: "installation-id",
}
)
func TestDecodePairMessage(t *testing.T) {
val, err := decodeTransitMessage(testPairMessageBytes)
require.NoError(t, err)
require.EqualValues(t, testPairMessageStruct, val)
}
func TestEncodePairMessage(t *testing.T) {
data, err := EncodePairMessage(testPairMessageStruct)
require.NoError(t, err)
// Decode it back to a struct because, for example, map encoding is non-deterministic
// and it is not possible to compare bytes.
val, err := decodeTransitMessage(data)
require.NoError(t, err)
require.EqualValues(t, testPairMessageStruct, val)
}

View file

@ -2,6 +2,7 @@ package protocol
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json"
"log" "log"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
@ -9,9 +10,9 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/applicationmetadata"
"github.com/status-im/status-go/protocol/datasync" "github.com/status-im/status-go/protocol/datasync"
"github.com/status-im/status-go/protocol/encryption" "github.com/status-im/status-go/protocol/encryption"
"github.com/status-im/status-go/protocol/protobuf"
) )
type StatusMessageT int type StatusMessageT int
@ -25,26 +26,43 @@ const (
// StatusMessage is any Status Protocol message. // StatusMessage is any Status Protocol message.
type StatusMessage struct { type StatusMessage struct {
// TransportMessage is the parsed message received from the transport layer, i.e the input // TransportMessage is the parsed message received from the transport layer, i.e the input
TransportMessage *types.Message TransportMessage *types.Message `json:"transportMessage"`
// MessageType is the type of application message contained // MessageType is the type of application message contained
MessageType StatusMessageT MessageType StatusMessageT `json:"-"`
// ParsedMessage is the parsed message by the application layer, i.e the output // ParsedMessage is the parsed message by the application layer, i.e the output
ParsedMessage interface{} ParsedMessage interface{} `json:"-"`
// TransportPayload is the payload as received from the transport layer // TransportPayload is the payload as received from the transport layer
TransportPayload []byte TransportPayload []byte `json:"-"`
// DecryptedPayload is the payload after having been processed by the encryption layer // DecryptedPayload is the payload after having been processed by the encryption layer
DecryptedPayload []byte DecryptedPayload []byte `json:"decryptedPayload"`
// ID is the canonical ID of the message // ID is the canonical ID of the message
ID types.HexBytes ID types.HexBytes `json:"id"`
// Hash is the transport layer hash // Hash is the transport layer hash
Hash []byte Hash []byte `json:"-"`
// TransportLayerSigPubKey contains the public key provided by the transport layer // TransportLayerSigPubKey contains the public key provided by the transport layer
TransportLayerSigPubKey *ecdsa.PublicKey TransportLayerSigPubKey *ecdsa.PublicKey `json:"-"`
// ApplicationMetadataLayerPubKey contains the public key provided by the application metadata layer // ApplicationMetadataLayerPubKey contains the public key provided by the application metadata layer
ApplicationMetadataLayerSigPubKey *ecdsa.PublicKey ApplicationMetadataLayerSigPubKey *ecdsa.PublicKey `json:"-"`
}
// Temporary JSON marshaling for those messages that are not yet processed
// by the go code
func (m *StatusMessage) MarshalJSON() ([]byte, error) {
item := struct {
ID types.HexBytes `json:"id"`
Payload string `json:"payload"`
From types.HexBytes `json:"from"`
Timestamp uint32 `json:"timestamp"`
}{
ID: m.ID,
Payload: string(m.DecryptedPayload),
Timestamp: m.TransportMessage.Timestamp,
From: m.TransportMessage.Sig,
}
return json.Marshal(item)
} }
// SigPubKey returns the most important signature, from the application layer to transport // SigPubKey returns the most important signature, from the application layer to transport
@ -126,12 +144,9 @@ func (m *StatusMessage) HandleDatasync(datasync *datasync.DataSync) ([]*StatusMe
} }
func (m *StatusMessage) HandleApplicationMetadata() error { func (m *StatusMessage) HandleApplicationMetadata() error {
message, err := applicationmetadata.Unmarshal(m.DecryptedPayload) message, err := protobuf.Unmarshal(m.DecryptedPayload)
// Not an applicationmetadata message, calculate ID using the previous
// signature
if err != nil { if err != nil {
m.ID = MessageID(m.SigPubKey(), m.DecryptedPayload) return err
return nil
} }
recoveredKey, err := message.RecoverKey() recoveredKey, err := message.RecoverKey()
@ -147,26 +162,18 @@ func (m *StatusMessage) HandleApplicationMetadata() error {
} }
func (m *StatusMessage) HandleApplication() error { func (m *StatusMessage) HandleApplication() error {
value, err := decodeTransitMessage(m.DecryptedPayload) // Try protobuf first
if err != nil { var message protobuf.ChatMessage
log.Printf("[message::DecodeMessage] could not decode message: %#x, err: %v", m.Hash, err.Error())
return err
}
m.ParsedMessage = value
switch m.ParsedMessage.(type) {
case Message:
m.MessageType = MessageT
case MembershipUpdateMessage:
m.MessageType = MembershipUpdateMessageT
case PairMessage:
m.MessageType = PairMessageT
// By default we null the parsed message field, as
// otherwise is populated with the raw transit and we are
// unable to marshal in case it contains maps
// as they have type map[interface{}]interface{}
default:
m.ParsedMessage = nil
err := proto.Unmarshal(m.DecryptedPayload, &message)
if err != nil {
m.ParsedMessage = nil
log.Printf("[message::DecodeMessage] could not decode protobuf message: %#x, err: %v", m.Hash, err.Error())
} else {
m.MessageType = MessageT
m.ParsedMessage = message
return nil
} }
return nil return nil
} }

View file

@ -34,6 +34,8 @@ type MailserverRequestGap struct {
type MailserverTopic struct { type MailserverTopic struct {
Topic string `json:"topic"` Topic string `json:"topic"`
Discovery bool `json:"discovery?"`
Negotiated bool `json:"negotiated?"`
ChatIDs []string `json:"chat-ids"` ChatIDs []string `json:"chat-ids"`
LastRequest int `json:"last-request"` // default is 1 LastRequest int `json:"last-request"` // default is 1
} }
@ -212,11 +214,15 @@ func (d *Database) AddTopic(topic MailserverTopic) error {
_, err := d.db.Exec(`INSERT OR REPLACE INTO mailserver_topics( _, err := d.db.Exec(`INSERT OR REPLACE INTO mailserver_topics(
topic, topic,
chat_ids, chat_ids,
last_request last_request,
) VALUES (?, ?, ?)`, discovery,
negotiated
) VALUES (?, ?, ?,?,?)`,
topic.Topic, topic.Topic,
chatIDs, chatIDs,
topic.LastRequest, topic.LastRequest,
topic.Discovery,
topic.Negotiated,
) )
return err return err
} }
@ -224,7 +230,7 @@ func (d *Database) AddTopic(topic MailserverTopic) error {
func (d *Database) Topics() ([]MailserverTopic, error) { func (d *Database) Topics() ([]MailserverTopic, error) {
var result []MailserverTopic var result []MailserverTopic
rows, err := d.db.Query(`SELECT topic, chat_ids, last_request FROM mailserver_topics`) rows, err := d.db.Query(`SELECT topic, chat_ids, last_request,discovery,negotiated FROM mailserver_topics`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -238,6 +244,8 @@ func (d *Database) Topics() ([]MailserverTopic, error) {
&t.Topic, &t.Topic,
&chatIDs, &chatIDs,
&t.LastRequest, &t.LastRequest,
&t.Discovery,
&t.Negotiated,
); err != nil { ); err != nil {
return nil, err return nil, err
} }

View file

@ -27,7 +27,6 @@ import (
"github.com/status-im/status-go/protocol" "github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/encryption/multidevice"
statustransp "github.com/status-im/status-go/protocol/transport/whisper" statustransp "github.com/status-im/status-go/protocol/transport/whisper"
statusprotomessage "github.com/status-im/status-go/protocol/v1"
) )
const ( const (
@ -444,10 +443,6 @@ func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg SendPublicMessa
return api.service.messenger.SendRaw(ctx, chat, msg.Payload) return api.service.messenger.SendRaw(ctx, chat, msg.Payload)
} }
func (api *PublicAPI) PrepareContent(ctx context.Context, content statusprotomessage.Content) statusprotomessage.Content {
return api.service.messenger.PrepareContent(content)
}
// SendDirectMessage sends a 1:1 chat message to the underlying transport // SendDirectMessage sends a 1:1 chat message to the underlying transport
// Message's payload is a transit encoded message. // Message's payload is a transit encoded message.
// It's important to call PublicAPI.afterSend() so that the client receives a signal // It's important to call PublicAPI.afterSend() so that the client receives a signal
@ -648,8 +643,8 @@ func (api *PublicAPI) ChatMessages(chatID, cursor string, limit int) (*Applicati
}, nil }, nil
} }
func (api *PublicAPI) SaveMessages(messages []*protocol.Message) error { func (api *PublicAPI) AddSystemMessages(messages []*protocol.Message) ([]*protocol.Message, error) {
return api.service.messenger.SaveMessages(messages) return api.service.messenger.AddSystemMessages(messages)
} }
func (api *PublicAPI) DeleteMessage(id string) error { func (api *PublicAPI) DeleteMessage(id string) error {
@ -660,14 +655,22 @@ func (api *PublicAPI) DeleteMessagesByChatID(id string) error {
return api.service.messenger.DeleteMessagesByChatID(id) return api.service.messenger.DeleteMessagesByChatID(id)
} }
func (api *PublicAPI) MarkMessagesSeen(ids []string) error { func (api *PublicAPI) MarkMessagesSeen(chatID string, ids []string) error {
return api.service.messenger.MarkMessagesSeen(ids...) return api.service.messenger.MarkMessagesSeen(chatID, ids)
} }
func (api *PublicAPI) UpdateMessageOutgoingStatus(id, newOutgoingStatus string) error { func (api *PublicAPI) UpdateMessageOutgoingStatus(id, newOutgoingStatus string) error {
return api.service.messenger.UpdateMessageOutgoingStatus(id, newOutgoingStatus) return api.service.messenger.UpdateMessageOutgoingStatus(id, newOutgoingStatus)
} }
func (api *PublicAPI) SendChatMessage(ctx context.Context, message *protocol.Message) (*protocol.MessengerResponse, error) {
return api.service.messenger.SendChatMessage(ctx, message)
}
func (api *PublicAPI) ReSendChatMessage(ctx context.Context, messageID string) (*protocol.MessengerResponse, error) {
return api.service.messenger.ReSendChatMessage(ctx, messageID)
}
// ----- // -----
// HELPER // HELPER
// ----- // -----

View file

@ -4,7 +4,6 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"database/sql" "database/sql"
"encoding/hex"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -12,7 +11,6 @@ import (
"github.com/status-im/status-go/logutils" "github.com/status-im/status-go/logutils"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
@ -163,87 +161,14 @@ func (s *Service) retrieveMessagesLoop(tick time.Duration, cancel <-chan struct{
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
chatWithMessages, err := s.messenger.RetrieveRawAll() response, err := s.messenger.RetrieveAll()
if err != nil { if err != nil {
log.Error("failed to retrieve raw messages", "err", err) log.Error("failed to retrieve raw messages", "err", err)
continue continue
} }
var messageIDs []string if !response.IsEmpty() {
PublisherSignalHandler{}.NewMessages(response)
for _, messages := range chatWithMessages {
for _, message := range messages {
messageIDs = append(messageIDs, message.ID.String())
} }
}
existingMessages, err := s.messenger.MessagesExist(messageIDs)
if err != nil {
log.Error("failed to check existing messages", "err", err)
continue
}
var signalMessages []*signal.Messages
for chat, messages := range chatWithMessages {
var dedupMessages []*dedup.DeduplicateMessage
// Filter out already saved messages
for _, message := range messages {
if !existingMessages[message.ID.String()] {
id := fmt.Sprintf("0x%s", hex.EncodeToString(crypto.FromECDSAPub(message.SigPubKey())))
identicon, err := protocol.Identicon(id)
if err != nil {
log.Error("failed to generate identicon", "err", err)
continue
}
alias, err := protocol.GenerateAlias(id)
if err != nil {
log.Error("failed to generate identicon", "err", err)
continue
}
dedupMessage := &dedup.DeduplicateMessage{
Metadata: dedup.Metadata{
Author: dedup.Author{
PublicKey: crypto.FromECDSAPub(message.SigPubKey()),
Alias: alias,
Identicon: identicon,
},
MessageID: message.ID,
EncryptionID: message.Hash,
},
Message: message.TransportMessage,
}
dedupMessage.Message.Payload = message.DecryptedPayload
dedupMessage.Payload = string(message.DecryptedPayload)
dedupMessage.ParsedMessage = message.ParsedMessage
dedupMessage.MessageType = message.MessageType
dedupMessages = append(dedupMessages, dedupMessage)
}
}
dedupMessages = s.deduplicator.Deduplicate(dedupMessages)
if len(dedupMessages) != 0 {
signalMessage := &signal.Messages{
Chat: chat,
Error: nil, // TODO: what is it needed for?
Messages: dedupMessages,
}
signalMessages = append(signalMessages, signalMessage)
}
}
log.Debug("retrieve messages loop", "messages", len(signalMessages))
if len(signalMessages) == 0 {
continue
}
PublisherSignalHandler{}.NewMessages(signalMessages)
case <-cancel: case <-cancel:
return return
} }
@ -425,16 +350,9 @@ func buildMessengerOptions(config params.ShhextConfig, db *sql.DB, envelopesMoni
protocol.WithOnNegotiatedFilters(onNegotiatedFilters), protocol.WithOnNegotiatedFilters(onNegotiatedFilters),
} }
if !config.DisableGenericDiscoveryTopic {
options = append(options, protocol.WithGenericDiscoveryTopicSupport())
}
if config.DataSyncEnabled { if config.DataSyncEnabled {
options = append(options, protocol.WithDatasync()) options = append(options, protocol.WithDatasync())
} }
if config.SendV1Messages {
options = append(options, protocol.WithSendV1Messages())
}
return options return options
} }

View file

@ -2,6 +2,7 @@ package shhext
import ( import (
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/signal" "github.com/status-im/status-go/signal"
) )
@ -43,6 +44,6 @@ func (h PublisherSignalHandler) WhisperFilterAdded(filters []*signal.Filter) {
signal.SendWhisperFilterAdded(filters) signal.SendWhisperFilterAdded(filters)
} }
func (h PublisherSignalHandler) NewMessages(messages []*signal.Messages) { func (h PublisherSignalHandler) NewMessages(response *protocol.MessengerResponse) {
signal.SendNewMessages(messages) signal.SendNewMessages(response)
} }

View file

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
statusproto "github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/services/shhext/dedup" "github.com/status-im/status-go/services/shhext/dedup"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
@ -88,11 +89,6 @@ type WhisperFilterAddedSignal struct {
Filters []*Filter `json:"filters"` Filters []*Filter `json:"filters"`
} }
// NewMessagesSignal notifies clients of new messages
type NewMessagesSignal struct {
Messages []*Messages `json:"messages"`
}
// SendEnvelopeSent triggered when envelope delivered at least to 1 peer. // SendEnvelopeSent triggered when envelope delivered at least to 1 peer.
func SendEnvelopeSent(identifiers [][]byte) { func SendEnvelopeSent(identifiers [][]byte) {
var hexIdentifiers []hexutil.Bytes var hexIdentifiers []hexutil.Bytes
@ -172,6 +168,6 @@ func SendWhisperFilterAdded(filters []*Filter) {
send(EventWhisperFilterAdded, WhisperFilterAddedSignal{Filters: filters}) send(EventWhisperFilterAdded, WhisperFilterAddedSignal{Filters: filters})
} }
func SendNewMessages(messages []*Messages) { func SendNewMessages(response *statusproto.MessengerResponse) {
send(EventNewMessages, NewMessagesSignal{Messages: messages}) send(EventNewMessages, response)
} }

View file

@ -97,7 +97,7 @@ func ConfigReadmeMd() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/README.md", size: 3330, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 0)} info := bindataFileInfo{name: "../config/README.md", size: 3330, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x65, 0xb9, 0xf5, 0x6, 0xbe, 0x7d, 0x85, 0x3b, 0x8, 0xbc, 0x5c, 0x71, 0x85, 0x19, 0xd1, 0xde, 0x38, 0xb5, 0xe9, 0x90, 0x5c, 0x45, 0xb2, 0xa5, 0x8a, 0x91, 0xee, 0xeb, 0x1e, 0xb4, 0xa9, 0x8f}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x65, 0xb9, 0xf5, 0x6, 0xbe, 0x7d, 0x85, 0x3b, 0x8, 0xbc, 0x5c, 0x71, 0x85, 0x19, 0xd1, 0xde, 0x38, 0xb5, 0xe9, 0x90, 0x5c, 0x45, 0xb2, 0xa5, 0x8a, 0x91, 0xee, 0xeb, 0x1e, 0xb4, 0xa9, 0x8f}}
return a, nil return a, nil
} }
@ -117,7 +117,7 @@ func ConfigCliFleetEthBetaJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/cli/fleet-eth.beta.json", size: 3261, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 0)} info := bindataFileInfo{name: "../config/cli/fleet-eth.beta.json", size: 3261, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2b, 0xae, 0x42, 0x4b, 0xa4, 0xd9, 0x2, 0x69, 0x99, 0x29, 0x7e, 0x1, 0x4e, 0xd9, 0x58, 0x84, 0x28, 0x3a, 0x81, 0xc4, 0xde, 0x1d, 0xea, 0x51, 0xc8, 0x21, 0xff, 0x7b, 0xff, 0x23, 0x1c, 0x16}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2b, 0xae, 0x42, 0x4b, 0xa4, 0xd9, 0x2, 0x69, 0x99, 0x29, 0x7e, 0x1, 0x4e, 0xd9, 0x58, 0x84, 0x28, 0x3a, 0x81, 0xc4, 0xde, 0x1d, 0xea, 0x51, 0xc8, 0x21, 0xff, 0x7b, 0xff, 0x23, 0x1c, 0x16}}
return a, nil return a, nil
} }
@ -137,7 +137,7 @@ func ConfigCliFleetEthStagingJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 1862, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 0)} info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 1862, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0x85, 0xa1, 0x10, 0x16, 0x87, 0x10, 0x1c, 0xc3, 0xf4, 0xc7, 0xc, 0x2e, 0x51, 0xb7, 0x3, 0x61, 0x16, 0x99, 0x84, 0x3d, 0x5d, 0x82, 0x62, 0xfb, 0xf4, 0x5e, 0x19, 0xda, 0xb9, 0xaa, 0xc4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0x85, 0xa1, 0x10, 0x16, 0x87, 0x10, 0x1c, 0xc3, 0xf4, 0xc7, 0xc, 0x2e, 0x51, 0xb7, 0x3, 0x61, 0x16, 0x99, 0x84, 0x3d, 0x5d, 0x82, 0x62, 0xfb, 0xf4, 0x5e, 0x19, 0xda, 0xb9, 0xaa, 0xc4}}
return a, nil return a, nil
} }
@ -157,7 +157,7 @@ func ConfigCliFleetEthTestJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 1543, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 0)} info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 1543, mode: os.FileMode(0644), modTime: time.Unix(1573806410, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x68, 0xef, 0x71, 0xa1, 0x38, 0x37, 0xf0, 0x0, 0xbb, 0x95, 0x26, 0x2a, 0x2a, 0x65, 0x98, 0xfe, 0xe5, 0x3f, 0xbf, 0xb, 0x68, 0xa6, 0xb5, 0xa4, 0x10, 0xc1, 0x4b, 0x67, 0xb4, 0x4e, 0x32, 0xc0}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x68, 0xef, 0x71, 0xa1, 0x38, 0x37, 0xf0, 0x0, 0xbb, 0x95, 0x26, 0x2a, 0x2a, 0x65, 0x98, 0xfe, 0xe5, 0x3f, 0xbf, 0xb, 0x68, 0xa6, 0xb5, 0xa4, 0x10, 0xc1, 0x4b, 0x67, 0xb4, 0x4e, 0x32, 0xc0}}
return a, nil return a, nil
} }
@ -177,7 +177,7 @@ func ConfigCliLesEnabledJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/cli/les-enabled.json", size: 58, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -197,7 +197,7 @@ func ConfigCliMailserverEnabledJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/cli/mailserver-enabled.json", size: 176, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -217,7 +217,7 @@ func ConfigStatusChainGenesisJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "../config/status-chain-genesis.json", size: 612, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -237,7 +237,7 @@ func keysBootnodeKey() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/bootnode.key", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -277,7 +277,7 @@ func keysTestAccount1StatusChainPk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -297,7 +297,7 @@ func keysTestAccount1Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -317,7 +317,7 @@ func keysTestAccount2StatusChainPk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -337,7 +337,7 @@ func keysTestAccount2Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -357,7 +357,7 @@ func keysTestAccount3BeforeEip55Pk() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }

View file

@ -86,7 +86,7 @@ func configPublicChainAccountsJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 307, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -106,7 +106,7 @@ func configStatusChainAccountsJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }
@ -126,7 +126,7 @@ func configTestDataJson() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1564144050, 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}} 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 return a, nil
} }

View file

@ -36,66 +36,66 @@ type ErrorCode uint32
const ( const (
SCardSuccess ErrorCode = 0x00000000 /* No error was encountered. */ SCardSuccess ErrorCode = 0x00000000 /* No error was encountered. */
ErrSCardInternal = 0x80100001 /* An internal consistency check failed. */ ErrSCardInternal ErrorCode = 0x80100001 /* An internal consistency check failed. */
ErrSCardCancelled = 0x80100002 /* The action was cancelled by an SCardCancel request. */ ErrSCardCancelled ErrorCode = 0x80100002 /* The action was cancelled by an SCardCancel request. */
ErrSCardInvalidHandle = 0x80100003 /* The supplied handle was invalid. */ ErrSCardInvalidHandle ErrorCode = 0x80100003 /* The supplied handle was invalid. */
ErrSCardInvalidParameter = 0x80100004 /* One or more of the supplied parameters could not be properly interpreted. */ ErrSCardInvalidParameter ErrorCode = 0x80100004 /* One or more of the supplied parameters could not be properly interpreted. */
ErrSCardInvalidTarget = 0x80100005 /* Registry startup information is missing or invalid. */ ErrSCardInvalidTarget ErrorCode = 0x80100005 /* Registry startup information is missing or invalid. */
ErrSCardNoMemory = 0x80100006 /* Not enough memory available to complete this command. */ ErrSCardNoMemory ErrorCode = 0x80100006 /* Not enough memory available to complete this command. */
ErrSCardWaitedTooLong = 0x80100007 /* An internal consistency timer has expired. */ ErrSCardWaitedTooLong ErrorCode = 0x80100007 /* An internal consistency timer has expired. */
ErrSCardInsufficientBuffer = 0x80100008 /* The data buffer to receive returned data is too small for the returned data. */ ErrSCardInsufficientBuffer ErrorCode = 0x80100008 /* The data buffer to receive returned data is too small for the returned data. */
ErrScardUnknownReader = 0x80100009 /* The specified reader name is not recognized. */ ErrScardUnknownReader ErrorCode = 0x80100009 /* The specified reader name is not recognized. */
ErrSCardTimeout = 0x8010000A /* The user-specified timeout value has expired. */ ErrSCardTimeout ErrorCode = 0x8010000A /* The user-specified timeout value has expired. */
ErrSCardSharingViolation = 0x8010000B /* The smart card cannot be accessed because of other connections outstanding. */ ErrSCardSharingViolation ErrorCode = 0x8010000B /* The smart card cannot be accessed because of other connections outstanding. */
ErrSCardNoSmartCard = 0x8010000C /* The operation requires a Smart Card, but no Smart Card is currently in the device. */ ErrSCardNoSmartCard ErrorCode = 0x8010000C /* The operation requires a Smart Card, but no Smart Card is currently in the device. */
ErrSCardUnknownCard = 0x8010000D /* The specified smart card name is not recognized. */ ErrSCardUnknownCard ErrorCode = 0x8010000D /* The specified smart card name is not recognized. */
ErrSCardCannotDispose = 0x8010000E /* The system could not dispose of the media in the requested manner. */ ErrSCardCannotDispose ErrorCode = 0x8010000E /* The system could not dispose of the media in the requested manner. */
ErrSCardProtoMismatch = 0x8010000F /* The requested protocols are incompatible with the protocol currently in use with the smart card. */ ErrSCardProtoMismatch ErrorCode = 0x8010000F /* The requested protocols are incompatible with the protocol currently in use with the smart card. */
ErrSCardNotReady = 0x80100010 /* The reader or smart card is not ready to accept commands. */ ErrSCardNotReady ErrorCode = 0x80100010 /* The reader or smart card is not ready to accept commands. */
ErrSCardInvalidValue = 0x80100011 /* One or more of the supplied parameters values could not be properly interpreted. */ ErrSCardInvalidValue ErrorCode = 0x80100011 /* One or more of the supplied parameters values could not be properly interpreted. */
ErrSCardSystemCancelled = 0x80100012 /* The action was cancelled by the system, presumably to log off or shut down. */ ErrSCardSystemCancelled ErrorCode = 0x80100012 /* The action was cancelled by the system, presumably to log off or shut down. */
ErrSCardCommError = 0x80100013 /* An internal communications error has been detected. */ ErrSCardCommError ErrorCode = 0x80100013 /* An internal communications error has been detected. */
ErrScardUnknownError = 0x80100014 /* An internal error has been detected, but the source is unknown. */ ErrScardUnknownError ErrorCode = 0x80100014 /* An internal error has been detected, but the source is unknown. */
ErrSCardInvalidATR = 0x80100015 /* An ATR obtained from the registry is not a valid ATR string. */ ErrSCardInvalidATR ErrorCode = 0x80100015 /* An ATR obtained from the registry is not a valid ATR string. */
ErrSCardNotTransacted = 0x80100016 /* An attempt was made to end a non-existent transaction. */ ErrSCardNotTransacted ErrorCode = 0x80100016 /* An attempt was made to end a non-existent transaction. */
ErrSCardReaderUnavailable = 0x80100017 /* The specified reader is not currently available for use. */ ErrSCardReaderUnavailable ErrorCode = 0x80100017 /* The specified reader is not currently available for use. */
ErrSCardShutdown = 0x80100018 /* The operation has been aborted to allow the server application to exit. */ ErrSCardShutdown ErrorCode = 0x80100018 /* The operation has been aborted to allow the server application to exit. */
ErrSCardPCITooSmall = 0x80100019 /* The PCI Receive buffer was too small. */ ErrSCardPCITooSmall ErrorCode = 0x80100019 /* The PCI Receive buffer was too small. */
ErrSCardReaderUnsupported = 0x8010001A /* The reader driver does not meet minimal requirements for support. */ ErrSCardReaderUnsupported ErrorCode = 0x8010001A /* The reader driver does not meet minimal requirements for support. */
ErrSCardDuplicateReader = 0x8010001B /* The reader driver did not produce a unique reader name. */ ErrSCardDuplicateReader ErrorCode = 0x8010001B /* The reader driver did not produce a unique reader name. */
ErrSCardCardUnsupported = 0x8010001C /* The smart card does not meet minimal requirements for support. */ ErrSCardCardUnsupported ErrorCode = 0x8010001C /* The smart card does not meet minimal requirements for support. */
ErrScardNoService = 0x8010001D /* The Smart card resource manager is not running. */ ErrScardNoService ErrorCode = 0x8010001D /* The Smart card resource manager is not running. */
ErrSCardServiceStopped = 0x8010001E /* The Smart card resource manager has shut down. */ ErrSCardServiceStopped ErrorCode = 0x8010001E /* The Smart card resource manager has shut down. */
ErrSCardUnexpected = 0x8010001F /* An unexpected card error has occurred. */ ErrSCardUnexpected ErrorCode = 0x8010001F /* An unexpected card error has occurred. */
ErrSCardUnsupportedFeature = 0x8010001F /* This smart card does not support the requested feature. */ ErrSCardUnsupportedFeature ErrorCode = 0x8010001F /* This smart card does not support the requested feature. */
ErrSCardICCInstallation = 0x80100020 /* No primary provider can be found for the smart card. */ ErrSCardICCInstallation ErrorCode = 0x80100020 /* No primary provider can be found for the smart card. */
ErrSCardICCCreateOrder = 0x80100021 /* The requested order of object creation is not supported. */ ErrSCardICCCreateOrder ErrorCode = 0x80100021 /* The requested order of object creation is not supported. */
ErrSCardDirNotFound = 0x80100023 /* The identified directory does not exist in the smart card. */ ErrSCardDirNotFound ErrorCode = 0x80100023 /* The identified directory does not exist in the smart card. */
ErrSCardFileNotFound = 0x80100024 /* The identified file does not exist in the smart card. */ ErrSCardFileNotFound ErrorCode = 0x80100024 /* The identified file does not exist in the smart card. */
ErrSCardNoDir = 0x80100025 /* The supplied path does not represent a smart card directory. */ ErrSCardNoDir ErrorCode = 0x80100025 /* The supplied path does not represent a smart card directory. */
ErrSCardNoFile = 0x80100026 /* The supplied path does not represent a smart card file. */ ErrSCardNoFile ErrorCode = 0x80100026 /* The supplied path does not represent a smart card file. */
ErrScardNoAccess = 0x80100027 /* Access is denied to this file. */ ErrScardNoAccess ErrorCode = 0x80100027 /* Access is denied to this file. */
ErrSCardWriteTooMany = 0x80100028 /* The smart card does not have enough memory to store the information. */ ErrSCardWriteTooMany ErrorCode = 0x80100028 /* The smart card does not have enough memory to store the information. */
ErrSCardBadSeek = 0x80100029 /* There was an error trying to set the smart card file object pointer. */ ErrSCardBadSeek ErrorCode = 0x80100029 /* There was an error trying to set the smart card file object pointer. */
ErrSCardInvalidCHV = 0x8010002A /* The supplied PIN is incorrect. */ ErrSCardInvalidCHV ErrorCode = 0x8010002A /* The supplied PIN is incorrect. */
ErrSCardUnknownResMNG = 0x8010002B /* An unrecognized error code was returned from a layered component. */ ErrSCardUnknownResMNG ErrorCode = 0x8010002B /* An unrecognized error code was returned from a layered component. */
ErrSCardNoSuchCertificate = 0x8010002C /* The requested certificate does not exist. */ ErrSCardNoSuchCertificate ErrorCode = 0x8010002C /* The requested certificate does not exist. */
ErrSCardCertificateUnavailable = 0x8010002D /* The requested certificate could not be obtained. */ ErrSCardCertificateUnavailable ErrorCode = 0x8010002D /* The requested certificate could not be obtained. */
ErrSCardNoReadersAvailable = 0x8010002E /* Cannot find a smart card reader. */ ErrSCardNoReadersAvailable ErrorCode = 0x8010002E /* Cannot find a smart card reader. */
ErrSCardCommDataLost = 0x8010002F /* A communications error with the smart card has been detected. Retry the operation. */ ErrSCardCommDataLost ErrorCode = 0x8010002F /* A communications error with the smart card has been detected. Retry the operation. */
ErrScardNoKeyContainer = 0x80100030 /* The requested key container does not exist on the smart card. */ ErrScardNoKeyContainer ErrorCode = 0x80100030 /* The requested key container does not exist on the smart card. */
ErrSCardServerTooBusy = 0x80100031 /* The Smart Card Resource Manager is too busy to complete this operation. */ ErrSCardServerTooBusy ErrorCode = 0x80100031 /* The Smart Card Resource Manager is too busy to complete this operation. */
ErrSCardUnsupportedCard = 0x80100065 /* The reader cannot communicate with the card, due to ATR string configuration conflicts. */ ErrSCardUnsupportedCard ErrorCode = 0x80100065 /* The reader cannot communicate with the card, due to ATR string configuration conflicts. */
ErrSCardUnresponsiveCard = 0x80100066 /* The smart card is not responding to a reset. */ ErrSCardUnresponsiveCard ErrorCode = 0x80100066 /* The smart card is not responding to a reset. */
ErrSCardUnpoweredCard = 0x80100067 /* Power has been removed from the smart card, so that further communication is not possible. */ ErrSCardUnpoweredCard ErrorCode = 0x80100067 /* Power has been removed from the smart card, so that further communication is not possible. */
ErrSCardResetCard = 0x80100068 /* The smart card has been reset, so any shared state information is invalid. */ ErrSCardResetCard ErrorCode = 0x80100068 /* The smart card has been reset, so any shared state information is invalid. */
ErrSCardRemovedCard = 0x80100069 /* The smart card has been removed, so further communication is not possible. */ ErrSCardRemovedCard ErrorCode = 0x80100069 /* The smart card has been removed, so further communication is not possible. */
ErrSCardSecurityViolation = 0x8010006A /* Access was denied because of a security violation. */ ErrSCardSecurityViolation ErrorCode = 0x8010006A /* Access was denied because of a security violation. */
ErrSCardWrongCHV = 0x8010006B /* The card cannot be accessed because the wrong PIN was presented. */ ErrSCardWrongCHV ErrorCode = 0x8010006B /* The card cannot be accessed because the wrong PIN was presented. */
ErrSCardCHVBlocked = 0x8010006C /* The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */ ErrSCardCHVBlocked ErrorCode = 0x8010006C /* The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */
ErrSCardEOF = 0x8010006D /* The end of the smart card file has been reached. */ ErrSCardEOF ErrorCode = 0x8010006D /* The end of the smart card file has been reached. */
ErrSCardCancelledByUser = 0x8010006E /* The user pressed "Cancel" on a Smart Card Selection Dialog. */ ErrSCardCancelledByUser ErrorCode = 0x8010006E /* The user pressed "Cancel" on a Smart Card Selection Dialog. */
ErrSCardCardNotAuthenticated = 0x8010006F /* No PIN was presented to the smart card. */ ErrSCardCardNotAuthenticated ErrorCode = 0x8010006F /* No PIN was presented to the smart card. */
) )
// Code returns the error code, with an uint32 type to be used in PutUInt32 // Code returns the error code, with an uint32 type to be used in PutUInt32
@ -106,95 +106,95 @@ func (code ErrorCode) Code() uint32 {
func (code ErrorCode) Error() error { func (code ErrorCode) Error() error {
switch code { switch code {
case SCardSuccess: case SCardSuccess:
return fmt.Errorf("Command successful") return fmt.Errorf("command successful")
case ErrSCardInternal: case ErrSCardInternal:
return fmt.Errorf("Internal error") return fmt.Errorf("internal error")
case ErrSCardCancelled: case ErrSCardCancelled:
return fmt.Errorf("Command cancelled") return fmt.Errorf("command cancelled")
case ErrSCardInvalidHandle: case ErrSCardInvalidHandle:
return fmt.Errorf("Invalid handle") return fmt.Errorf("invalid handle")
case ErrSCardInvalidParameter: case ErrSCardInvalidParameter:
return fmt.Errorf("Invalid parameter given") return fmt.Errorf("invalid parameter given")
case ErrSCardInvalidTarget: case ErrSCardInvalidTarget:
return fmt.Errorf("Invalid target given") return fmt.Errorf("invalid target given")
case ErrSCardNoMemory: case ErrSCardNoMemory:
return fmt.Errorf("Not enough memory") return fmt.Errorf("not enough memory")
case ErrSCardWaitedTooLong: case ErrSCardWaitedTooLong:
return fmt.Errorf("Waited too long") return fmt.Errorf("waited too long")
case ErrSCardInsufficientBuffer: case ErrSCardInsufficientBuffer:
return fmt.Errorf("Insufficient buffer") return fmt.Errorf("insufficient buffer")
case ErrScardUnknownReader: case ErrScardUnknownReader:
return fmt.Errorf("Unknown reader specified") return fmt.Errorf("unknown reader specified")
case ErrSCardTimeout: case ErrSCardTimeout:
return fmt.Errorf("Command timeout") return fmt.Errorf("command timeout")
case ErrSCardSharingViolation: case ErrSCardSharingViolation:
return fmt.Errorf("Sharing violation") return fmt.Errorf("sharing violation")
case ErrSCardNoSmartCard: case ErrSCardNoSmartCard:
return fmt.Errorf("No smart card inserted") return fmt.Errorf("no smart card inserted")
case ErrSCardUnknownCard: case ErrSCardUnknownCard:
return fmt.Errorf("Unknown card") return fmt.Errorf("unknown card")
case ErrSCardCannotDispose: case ErrSCardCannotDispose:
return fmt.Errorf("Cannot dispose handle") return fmt.Errorf("cannot dispose handle")
case ErrSCardProtoMismatch: case ErrSCardProtoMismatch:
return fmt.Errorf("Card protocol mismatch") return fmt.Errorf("card protocol mismatch")
case ErrSCardNotReady: case ErrSCardNotReady:
return fmt.Errorf("Subsystem not ready") return fmt.Errorf("subsystem not ready")
case ErrSCardInvalidValue: case ErrSCardInvalidValue:
return fmt.Errorf("Invalid value given") return fmt.Errorf("invalid value given")
case ErrSCardSystemCancelled: case ErrSCardSystemCancelled:
return fmt.Errorf("System cancelled") return fmt.Errorf("system cancelled")
case ErrSCardCommError: case ErrSCardCommError:
return fmt.Errorf("RPC transport error") return fmt.Errorf("rpc transport error")
case ErrScardUnknownError: case ErrScardUnknownError:
return fmt.Errorf("Unknown error") return fmt.Errorf("unknown error")
case ErrSCardInvalidATR: case ErrSCardInvalidATR:
return fmt.Errorf("Invalid ATR") return fmt.Errorf("invalid ATR")
case ErrSCardNotTransacted: case ErrSCardNotTransacted:
return fmt.Errorf("Transaction failed") return fmt.Errorf("transaction failed")
case ErrSCardReaderUnavailable: case ErrSCardReaderUnavailable:
return fmt.Errorf("Reader is unavailable") return fmt.Errorf("reader is unavailable")
/* case SCARD_P_SHUTDOWN: */ /* case SCARD_P_SHUTDOWN: */
case ErrSCardPCITooSmall: case ErrSCardPCITooSmall:
return fmt.Errorf("PCI struct too small") return fmt.Errorf("PCI struct too small")
case ErrSCardReaderUnsupported: case ErrSCardReaderUnsupported:
return fmt.Errorf("Reader is unsupported") return fmt.Errorf("reader is unsupported")
case ErrSCardDuplicateReader: case ErrSCardDuplicateReader:
return fmt.Errorf("Reader already exists") return fmt.Errorf("reader already exists")
case ErrSCardCardUnsupported: case ErrSCardCardUnsupported:
return fmt.Errorf("Card is unsupported") return fmt.Errorf("card is unsupported")
case ErrScardNoService: case ErrScardNoService:
return fmt.Errorf("Service not available") return fmt.Errorf("service not available")
case ErrSCardServiceStopped: case ErrSCardServiceStopped:
return fmt.Errorf("Service was stopped") return fmt.Errorf("service was stopped")
/* case SCARD_E_UNEXPECTED: */ /* case SCARD_E_UNEXPECTED: */
/* case SCARD_E_ICC_CREATEORDER: */ /* case SCARD_E_ICC_CREATEORDER: */
@ -210,7 +210,7 @@ func (code ErrorCode) Error() error {
/* case SCARD_E_NO_SUCH_CERTIFICATE: */ /* case SCARD_E_NO_SUCH_CERTIFICATE: */
/* case SCARD_E_CERTIFICATE_UNAVAILABLE: */ /* case SCARD_E_CERTIFICATE_UNAVAILABLE: */
case ErrSCardNoReadersAvailable: case ErrSCardNoReadersAvailable:
return fmt.Errorf("Cannot find a smart card reader") return fmt.Errorf("cannot find a smart card reader")
/* case SCARD_E_COMM_DATA_LOST: */ /* case SCARD_E_COMM_DATA_LOST: */
/* case SCARD_E_NO_KEY_CONTAINER: */ /* case SCARD_E_NO_KEY_CONTAINER: */
@ -238,7 +238,7 @@ func (code ErrorCode) Error() error {
/* case SCARD_W_CARD_NOT_AUTHENTICATED: */ /* case SCARD_W_CARD_NOT_AUTHENTICATED: */
case ErrSCardUnsupportedFeature: case ErrSCardUnsupportedFeature:
return fmt.Errorf("Feature not supported") return fmt.Errorf("feature not supported")
default: default:
return fmt.Errorf("unknown error: %08x", code) return fmt.Errorf("unknown error: %08x", code)

View file

@ -291,16 +291,16 @@ func (client *Client) Connect(name string, shareMode uint32, preferredProtocol u
* *
* These data are passed throw the field \c sharedSegmentMsg.data. * These data are passed throw the field \c sharedSegmentMsg.data.
*/ */
type transmit struct { //type transmit struct {
hCard uint32 //hCard uint32
ioSendPciProtocol uint32 //ioSendPciProtocol uint32
ioSendPciLength uint32 //ioSendPciLength uint32
cbSendLength uint32 //cbSendLength uint32
ioRecvPciProtocol uint32 //ioRecvPciProtocol uint32
ioRecvPciLength uint32 //ioRecvPciLength uint32
pcbRecvLength uint32 //pcbRecvLength uint32
rv uint32 //rv uint32
} //}
// SCardIoRequest contains the info needed for performing an IO request // SCardIoRequest contains the info needed for performing an IO request
type SCardIoRequest struct { type SCardIoRequest struct {
@ -336,7 +336,7 @@ func (card *Card) Transmit(adpu []byte) ([]byte, *SCardIoRequest, error) {
return nil, nil, err return nil, nil, err
} }
if n != len(adpu) { if n != len(adpu) {
return nil, nil, fmt.Errorf("Invalid number of bytes written: expected %d, got %d", len(adpu), n) return nil, nil, fmt.Errorf("invalid number of bytes written: expected %d, got %d", len(adpu), n)
} }
response := [TransmitRequestLength]byte{} response := [TransmitRequestLength]byte{}
total := 0 total := 0

26
vendor/github.com/go-playground/locales/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,26 @@
language: go
go:
- 1.13.1
- tip
matrix:
allow_failures:
- go: tip
notifications:
email:
recipients: dean.karn@gmail.com
on_success: change
on_failure: always
before_install:
- go install github.com/mattn/goveralls
# Only clone the most recent commit.
git:
depth: 1
script:
- go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
after_success: |
goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN

View file

@ -1,6 +1,6 @@
## locales ## locales
<img align="right" src="https://raw.githubusercontent.com/go-playground/locales/master/logo.png">![Project status](https://img.shields.io/badge/version-0.12.1-green.svg) <img align="right" src="https://raw.githubusercontent.com/go-playground/locales/master/logo.png">![Project status](https://img.shields.io/badge/version-0.13.0-green.svg)
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/locales/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/locales) [![Build Status](https://travis-ci.org/go-playground/locales.svg?branch=master)](https://travis-ci.org/go-playground/locales)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales)
[![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales) [![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales)
![License](https://img.shields.io/dub/l/vibe-d.svg) ![License](https://img.shields.io/dub/l/vibe-d.svg)

5
vendor/github.com/go-playground/locales/go.mod generated vendored Normal file
View file

@ -0,0 +1,5 @@
module github.com/go-playground/locales
go 1.13
require golang.org/x/text v0.3.2

3
vendor/github.com/go-playground/locales/go.sum generated vendored Normal file
View file

@ -0,0 +1,3 @@
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -22,3 +22,4 @@ _testmain.go
*.exe *.exe
*.test *.test
*.prof *.prof
*.coverprofile

View file

@ -0,0 +1,27 @@
language: go
go:
- 1.13.4
- tip
matrix:
allow_failures:
- go: tip
notifications:
email:
recipients: dean.karn@gmail.com
on_success: change
on_failure: always
before_install:
- go install github.com/mattn/goveralls
# Only clone the most recent commit.
git:
depth: 1
script:
- go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
after_success: |
[ $TRAVIS_GO_VERSION = 1.13.4 ] &&
goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN

View file

@ -1,7 +1,6 @@
## universal-translator ## universal-translator
<img align="right" src="https://raw.githubusercontent.com/go-playground/universal-translator/master/logo.png"> <img align="right" src="https://raw.githubusercontent.com/go-playground/universal-translator/master/logo.png">![Project status](https://img.shields.io/badge/version-0.17.0-green.svg)
![Project status](https://img.shields.io/badge/version-0.16.0-green.svg) [![Build Status](https://travis-ci.org/go-playground/universal-translator.svg?branch=master)](https://travis-ci.org/go-playground/universal-translator)
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/universal-translator/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/universal-translator)
[![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator) [![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator)
[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator) [![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator)
@ -46,9 +45,9 @@ Please see https://godoc.org/github.com/go-playground/universal-translator for u
##### Examples: ##### Examples:
- [Basic](https://github.com/go-playground/universal-translator/tree/master/examples/basic) - [Basic](https://github.com/go-playground/universal-translator/tree/master/_examples/basic)
- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/examples/full-no-files) - [Full - no files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-no-files)
- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/examples/full-with-files) - [Full - with files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-with-files)
File formatting File formatting
-------------- --------------
@ -57,10 +56,10 @@ they are only separated for easy viewing.
##### Examples: ##### Examples:
- [Formats](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats) - [Formats](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
##### Basic Makeup ##### Basic Makeup
NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats) NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
```json ```json
{ {
"locale": "en", "locale": "en",

View file

@ -0,0 +1,5 @@
module github.com/go-playground/universal-translator
go 1.13
require github.com/go-playground/locales v0.13.0

View file

@ -0,0 +1,4 @@
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -1,6 +1,6 @@
run: run:
# timeout for analysis, e.g. 30s, 5m, default is 1m # timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 2m timeout: 2m
linters: linters:
enable: enable:
#- golint #- golint

View file

@ -6,8 +6,8 @@ matrix:
- go: master - go: master
include: include:
# Supported versions of Go: https://golang.org/dl/ # Supported versions of Go: https://golang.org/dl/
- go: "1.11.x"
- go: "1.12.x" - go: "1.12.x"
- go: "1.13.x"
- go: master - go: master
go_import_path: github.com/golang-migrate/migrate go_import_path: github.com/golang-migrate/migrate
@ -34,7 +34,7 @@ before_install:
- sudo apt-get update - sudo apt-get update
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
# Install golangci-lint # Install golangci-lint
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.17.1 - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.20.0
- echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}" - echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}"
install: install:
@ -57,7 +57,7 @@ deploy:
secure: hWH1HLPpzpfA8pXQ93T1qKQVFSpQp0as/JLQ7D91jHuJ8p+RxVeqblDrR6HQY/95R/nyiE9GJmvUolSuw5h449LSrGxPtVWhdh6EnkxlQHlen5XeMhVjRjFV0sE9qGe8v7uAkiTfRO61ktTWHrEAvw5qpyqnNISodmZS78XIasPODQbNlzwINhWhDTHIjXGb4FpizYaL3OGCanrxfR9fQyCaqKGGBjRq3Mfq8U6Yd4mApmsE+uJxgaZV8K5zBqpkSzQRWhcVGNL5DuLsU3gfSJOo7kZeA2G71SHffH577dBoqtCZ4VFv169CoUZehLWCb+7XKJZmHXVujCURATSySLGUOPc6EoLFAn3YtsCA04mS4bZVo5FZPWVwfhjmkhtDR4f6wscKp7r1HsFHSOgm59QfETQdrn4MnZ44H2Jd39axqndn5DvK9EcZVjPHynOPnueXP2u6mTuUgh2VyyWBCDO3CNo0fGlo7VJI69IkIWNSD87K9cHZWYMClyKZkUzS+PmRAhHRYbVd+9ZjKOmnU36kUHNDG/ft1D4ogsY+rhVtXB4lgWDM5adri+EIScYdYnB1/pQexLBigcJY9uE7nQTR0U6QgVNYvun7uRNs40E0c4voSfmPdFO0FlOD2y1oQhnaXfWLbu9nMcTcs4RFGrcC7NzkUN4/WjG8s285V6w= secure: hWH1HLPpzpfA8pXQ93T1qKQVFSpQp0as/JLQ7D91jHuJ8p+RxVeqblDrR6HQY/95R/nyiE9GJmvUolSuw5h449LSrGxPtVWhdh6EnkxlQHlen5XeMhVjRjFV0sE9qGe8v7uAkiTfRO61ktTWHrEAvw5qpyqnNISodmZS78XIasPODQbNlzwINhWhDTHIjXGb4FpizYaL3OGCanrxfR9fQyCaqKGGBjRq3Mfq8U6Yd4mApmsE+uJxgaZV8K5zBqpkSzQRWhcVGNL5DuLsU3gfSJOo7kZeA2G71SHffH577dBoqtCZ4VFv169CoUZehLWCb+7XKJZmHXVujCURATSySLGUOPc6EoLFAn3YtsCA04mS4bZVo5FZPWVwfhjmkhtDR4f6wscKp7r1HsFHSOgm59QfETQdrn4MnZ44H2Jd39axqndn5DvK9EcZVjPHynOPnueXP2u6mTuUgh2VyyWBCDO3CNo0fGlo7VJI69IkIWNSD87K9cHZWYMClyKZkUzS+PmRAhHRYbVd+9ZjKOmnU36kUHNDG/ft1D4ogsY+rhVtXB4lgWDM5adri+EIScYdYnB1/pQexLBigcJY9uE7nQTR0U6QgVNYvun7uRNs40E0c4voSfmPdFO0FlOD2y1oQhnaXfWLbu9nMcTcs4RFGrcC7NzkUN4/WjG8s285V6w=
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
file: file:
@ -75,7 +75,7 @@ deploy:
package_glob: '*.deb' package_glob: '*.deb'
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
- provider: packagecloud - provider: packagecloud
@ -87,7 +87,7 @@ deploy:
package_glob: '*.deb' package_glob: '*.deb'
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
- provider: packagecloud - provider: packagecloud
@ -99,7 +99,7 @@ deploy:
package_glob: '*.deb' package_glob: '*.deb'
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
- provider: packagecloud - provider: packagecloud
@ -111,7 +111,7 @@ deploy:
package_glob: '*.deb' package_glob: '*.deb'
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
- provider: packagecloud - provider: packagecloud
@ -123,13 +123,13 @@ deploy:
package_glob: '*.deb' package_glob: '*.deb'
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true
- provider: script - provider: script
script: ./docker-deploy.sh script: ./docker-deploy.sh
skip_cleanup: true skip_cleanup: true
on: on:
go: "1.12.x" go: "1.13.x"
repo: golang-migrate/migrate repo: golang-migrate/migrate
tags: true tags: true

View file

@ -8,7 +8,7 @@ WORKDIR /go/src/github.com/golang-migrate/migrate
COPY . ./ COPY . ./
ENV GO111MODULE=on ENV GO111MODULE=on
ENV DATABASES="postgres mysql redshift cassandra spanner cockroachdb clickhouse mongodb sqlserver" ENV DATABASES="postgres mysql redshift cassandra spanner cockroachdb clickhouse mongodb sqlserver firebird"
ENV SOURCES="file go_bindata github github_ee aws_s3 google_cloud_storage godoc_vfs gitlab" ENV SOURCES="file go_bindata github github_ee aws_s3 google_cloud_storage godoc_vfs gitlab"
RUN go build -a -o build/migrate.linux-386 -ldflags="-s -w -X main.Version=${VERSION}" -tags "$DATABASES $SOURCES" ./cmd/migrate RUN go build -a -o build/migrate.linux-386 -ldflags="-s -w -X main.Version=${VERSION}" -tags "$DATABASES $SOURCES" ./cmd/migrate

View file

@ -1,5 +1,5 @@
SOURCE ?= file go_bindata github github_ee aws_s3 google_cloud_storage godoc_vfs gitlab SOURCE ?= file go_bindata github github_ee aws_s3 google_cloud_storage godoc_vfs gitlab
DATABASE ?= postgres mysql redshift cassandra spanner cockroachdb clickhouse mongodb sqlserver DATABASE ?= postgres mysql redshift cassandra spanner cockroachdb clickhouse mongodb sqlserver firebird
VERSION ?= $(shell git describe --tags 2>/dev/null | cut -c 2-) VERSION ?= $(shell git describe --tags 2>/dev/null | cut -c 2-)
TEST_FLAGS ?= TEST_FLAGS ?=
REPO_OWNER ?= $(shell cd .. && basename "$$(pwd)") REPO_OWNER ?= $(shell cd .. && basename "$$(pwd)")

View file

@ -3,7 +3,7 @@
[![Coverage Status](https://img.shields.io/coveralls/github/golang-migrate/migrate/master.svg)](https://coveralls.io/github/golang-migrate/migrate?branch=master) [![Coverage Status](https://img.shields.io/coveralls/github/golang-migrate/migrate/master.svg)](https://coveralls.io/github/golang-migrate/migrate?branch=master)
[![packagecloud.io](https://img.shields.io/badge/deb-packagecloud.io-844fec.svg)](https://packagecloud.io/golang-migrate/migrate?filter=debs) [![packagecloud.io](https://img.shields.io/badge/deb-packagecloud.io-844fec.svg)](https://packagecloud.io/golang-migrate/migrate?filter=debs)
[![Docker Pulls](https://img.shields.io/docker/pulls/migrate/migrate.svg)](https://hub.docker.com/r/migrate/migrate/) [![Docker Pulls](https://img.shields.io/docker/pulls/migrate/migrate.svg)](https://hub.docker.com/r/migrate/migrate/)
![Supported Go Versions](https://img.shields.io/badge/Go-1.11%2C%201.12-lightgrey.svg) ![Supported Go Versions](https://img.shields.io/badge/Go-1.12%2C%201.13-lightgrey.svg)
[![GitHub Release](https://img.shields.io/github/release/golang-migrate/migrate.svg)](https://github.com/golang-migrate/migrate/releases) [![GitHub Release](https://img.shields.io/github/release/golang-migrate/migrate.svg)](https://github.com/golang-migrate/migrate/releases)
[![Go Report Card](https://goreportcard.com/badge/github.com/golang-migrate/migrate)](https://goreportcard.com/report/github.com/golang-migrate/migrate) [![Go Report Card](https://goreportcard.com/badge/github.com/golang-migrate/migrate)](https://goreportcard.com/report/github.com/golang-migrate/migrate)
@ -36,7 +36,7 @@ Database drivers run migrations. [Add a new database?](database/driver.go)
* [Google Cloud Spanner](database/spanner) * [Google Cloud Spanner](database/spanner)
* [CockroachDB](database/cockroachdb) * [CockroachDB](database/cockroachdb)
* [ClickHouse](database/clickhouse) * [ClickHouse](database/clickhouse)
* [Firebird](database/firebird) ([todo #49](https://github.com/golang-migrate/migrate/issues/49)) * [Firebird](database/firebird)
* [MS SQL Server](database/sqlserver) * [MS SQL Server](database/sqlserver)
### Database URLs ### Database URLs

View file

@ -54,3 +54,5 @@ require (
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb
google.golang.org/grpc v1.20.1 // indirect google.golang.org/grpc v1.20.1 // indirect
) )
go 1.12

View file

@ -74,6 +74,8 @@ extern "C" {
#pragma warning(disable:4996) #pragma warning(disable:4996)
#endif #endif
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -428,7 +430,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
if (str) { if (str) {
len = strlen(str); len = strlen(str);
cur_dev->path = (char*) calloc(len+1, sizeof(char)); cur_dev->path = (char*) calloc(len+1, sizeof(char));
strncpy(cur_dev->path, str, sizeof(cur_dev->path)); strncpy(cur_dev->path, str, len+1);
cur_dev->path[len] = '\0'; cur_dev->path[len] = '\0';
} }
else else

View file

@ -7,3 +7,5 @@
*.out *.out
*.txt *.txt
vendor/

View file

@ -3,6 +3,9 @@ language: go
go: go:
- 1.9.x - 1.9.x
- 1.10.x - 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- tip - tip
before_install: before_install:

21
vendor/github.com/leodido/go-urn/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Leonardo Di Donato
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
vendor/github.com/leodido/go-urn/go.mod generated vendored Normal file
View file

@ -0,0 +1,5 @@
module github.com/leodido/go-urn
go 1.13
require github.com/stretchr/testify v1.4.0

11
vendor/github.com/leodido/go-urn/go.sum generated vendored Normal file
View file

@ -0,0 +1,11 @@
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,21 @@
SHELL := /bin/bash SHELL := /bin/bash
build: machine.go
images: docs/urn.png
machine.go: machine.go.rl machine.go: machine.go.rl
ragel -Z -G2 -e -o $@ $< ragel -Z -G2 -e -o $@ $<
@gofmt -w -s $@
@sed -i '/^\/\/line/d' $@ @sed -i '/^\/\/line/d' $@
@$(MAKE) -s file=$@ snake2camel
@gofmt -w -s $@
.PHONY: build docs/urn.dot: machine.go.rl
build: machine.go @mkdir -p docs
ragel -Z -e -Vp $< -o $@
docs/urn.png: docs/urn.dot
dot $< -Tpng -o $@
.PHONY: bench .PHONY: bench
bench: *_test.go machine.go bench: *_test.go machine.go
@ -15,3 +24,16 @@ bench: *_test.go machine.go
.PHONY: tests .PHONY: tests
tests: *_test.go machine.go tests: *_test.go machine.go
go test -race -timeout 10s -coverprofile=coverage.out -covermode=atomic -v ./... go test -race -timeout 10s -coverprofile=coverage.out -covermode=atomic -v ./...
.PHONY: clean
clean:
@rm -rf docs
@rm -f machine.go
.PHONY: snake2camel
snake2camel:
@awk -i inplace '{ \
while ( match($$0, /(.*)([a-z]+[0-9]*)_([a-zA-Z0-9])(.*)/, cap) ) \
$$0 = cap[1] cap[2] toupper(cap[3]) cap[4]; \
print \
}' $(file)

View file

@ -1,85 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: message.proto
package applicationmetadata
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Message struct {
Signature []byte `protobuf:"bytes,4001,opt,name=signature,proto3" json:"signature,omitempty"`
Payload []byte `protobuf:"bytes,4002,opt,name=payload,proto3" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Message) Reset() { *m = Message{} }
func (m *Message) String() string { return proto.CompactTextString(m) }
func (*Message) ProtoMessage() {}
func (*Message) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{0}
}
func (m *Message) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Message.Unmarshal(m, b)
}
func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Message.Marshal(b, m, deterministic)
}
func (m *Message) XXX_Merge(src proto.Message) {
xxx_messageInfo_Message.Merge(m, src)
}
func (m *Message) XXX_Size() int {
return xxx_messageInfo_Message.Size(m)
}
func (m *Message) XXX_DiscardUnknown() {
xxx_messageInfo_Message.DiscardUnknown(m)
}
var xxx_messageInfo_Message proto.InternalMessageInfo
func (m *Message) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *Message) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func init() {
proto.RegisterType((*Message)(nil), "applicationmetadata.Message")
}
func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) }
var fileDescriptor_33c57e4bae7b9afd = []byte{
// 112 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x4d, 0x2d, 0x2e,
0x4e, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4e, 0x2c, 0x28, 0xc8, 0xc9,
0x4c, 0x4e, 0x2c, 0xc9, 0xcc, 0xcf, 0xcb, 0x4d, 0x2d, 0x49, 0x4c, 0x49, 0x2c, 0x49, 0x54, 0x72,
0xe6, 0x62, 0xf7, 0x85, 0xa8, 0x12, 0x92, 0xe5, 0xe2, 0x2c, 0xce, 0x4c, 0xcf, 0x4b, 0x2c, 0x29,
0x2d, 0x4a, 0x95, 0x58, 0x28, 0xaf, 0xc0, 0xa8, 0xc1, 0x13, 0x84, 0x10, 0x11, 0x92, 0xe4, 0x62,
0x2f, 0x48, 0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x91, 0x58, 0x04, 0x91, 0x84, 0xf1, 0x93, 0xd8, 0xc0,
0x16, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x7f, 0x4a, 0x96, 0x71, 0x00, 0x00, 0x00,
}

View file

@ -1,8 +0,0 @@
syntax = "proto3";
package applicationmetadata;
message Message {
bytes signature = 4001;
bytes payload = 4002;
}

View file

@ -4,6 +4,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/sha1" "crypto/sha1"
"encoding/hex" "encoding/hex"
"encoding/json"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
@ -43,10 +44,7 @@ type Chat struct {
// Denormalized fields // Denormalized fields
UnviewedMessagesCount uint `json:"unviewedMessagesCount"` UnviewedMessagesCount uint `json:"unviewedMessagesCount"`
LastMessageContentType string `json:"lastMessageContentType"` LastMessage []byte `json:"lastMessage"`
LastMessageContent string `json:"lastMessageContent"`
LastMessageTimestamp int64 `json:"lastMessageTimestamp"`
LastMessageClockValue int64 `json:"lastMessageClockValue"`
// Group chat fields // Group chat fields
// Members are the members who have been invited to the group chat // Members are the members who have been invited to the group chat
@ -55,6 +53,53 @@ type Chat struct {
MembershipUpdates []ChatMembershipUpdate `json:"membershipUpdates"` MembershipUpdates []ChatMembershipUpdate `json:"membershipUpdates"`
} }
func (c *Chat) MarshalJSON() ([]byte, error) {
type ChatAlias Chat
item := struct {
*ChatAlias
LastMessage json.RawMessage `json:"lastMessage"`
}{
ChatAlias: (*ChatAlias)(c),
LastMessage: c.LastMessage,
}
return json.Marshal(item)
}
func (c *Chat) UnmarshalJSON(data []byte) error {
type ChatAlias Chat
aux := struct {
*ChatAlias
LastMessage *Message `json:"lastMessage"`
}{
ChatAlias: (*ChatAlias)(c),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
c.ID = aux.ID
c.Name = aux.Name
c.Color = aux.Color
c.Active = aux.Active
c.ChatType = aux.ChatType
c.Timestamp = aux.Timestamp
c.LastClockValue = aux.LastClockValue
c.DeletedAtClockValue = aux.DeletedAtClockValue
c.UnviewedMessagesCount = aux.UnviewedMessagesCount
c.Members = aux.Members
c.MembershipUpdates = aux.MembershipUpdates
if aux.LastMessage != nil {
data, err := json.Marshal(aux.LastMessage)
if err != nil {
return err
}
c.LastMessage = data
}
return nil
}
func (c *Chat) MembersAsPublicKeys() ([]*ecdsa.PublicKey, error) { func (c *Chat) MembersAsPublicKeys() ([]*ecdsa.PublicKey, error) {
publicKeys := make([]string, len(c.Members)) publicKeys := make([]string, len(c.Members))
for idx, item := range c.Members { for idx, item := range c.Members {

View file

@ -12,9 +12,9 @@ import (
) )
const ( const (
contactBlocked = "contact/blocked" contactBlocked = ":contact/blocked"
contactAdded = "contact/added" contactAdded = ":contact/added"
contactRequestReceived = "contact/request-received" contactRequestReceived = ":contact/request-received"
) )
// ContactDeviceInfo is a struct containing information about a particular device owned by a contact // ContactDeviceInfo is a struct containing information about a particular device owned by a contact

View file

@ -100,7 +100,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}}
return a, nil return a, nil
} }
@ -120,7 +120,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}}
return a, nil return a, nil
} }
@ -140,7 +140,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}}
return a, nil return a, nil
} }
@ -160,7 +160,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}}
return a, nil return a, nil
} }
@ -180,7 +180,7 @@ func _1540715431_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}}
return a, nil return a, nil
} }
@ -200,7 +200,7 @@ func _1540715431_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}}
return a, nil return a, nil
} }
@ -220,7 +220,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}}
return a, nil return a, nil
} }
@ -240,7 +240,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}}
return a, nil return a, nil
} }
@ -260,7 +260,7 @@ func _1558084410_add_secretDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}}
return a, nil return a, nil
} }
@ -280,7 +280,7 @@ func _1558084410_add_secretUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}}
return a, nil return a, nil
} }
@ -300,7 +300,7 @@ func _1558588866_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}}
return a, nil return a, nil
} }
@ -320,7 +320,7 @@ func _1558588866_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}}
return a, nil return a, nil
} }
@ -340,7 +340,7 @@ func _1559627659_add_contact_codeDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}}
return a, nil return a, nil
} }
@ -360,7 +360,7 @@ func _1559627659_add_contact_codeUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}}
return a, nil return a, nil
} }
@ -380,7 +380,7 @@ func _1561368210_add_installation_metadataDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}}
return a, nil return a, nil
} }
@ -400,7 +400,7 @@ func _1561368210_add_installation_metadataUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}}
return a, nil return a, nil
} }
@ -420,7 +420,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}}
return a, nil return a, nil
} }

View file

@ -384,6 +384,11 @@ func (p *Protocol) GetOurInstallations(myIdentityKey *ecdsa.PublicKey) ([]*multi
return p.multidevice.GetOurInstallations(myIdentityKey) return p.multidevice.GetOurInstallations(myIdentityKey)
} }
// GetOurActiveInstallations returns all the active installations available given an identity
func (p *Protocol) GetOurActiveInstallations(myIdentityKey *ecdsa.PublicKey) ([]*multidevice.Installation, error) {
return p.multidevice.GetOurActiveInstallations(myIdentityKey)
}
// SetInstallationMetadata sets the metadata for our own installation // SetInstallationMetadata sets the metadata for our own installation
func (p *Protocol) SetInstallationMetadata(myIdentityKey *ecdsa.PublicKey, installationID string, data *multidevice.InstallationMetadata) error { func (p *Protocol) SetInstallationMetadata(myIdentityKey *ecdsa.PublicKey, installationID string, data *multidevice.InstallationMetadata) error {
return p.multidevice.SetInstallationMetadata(myIdentityKey, installationID, data) return p.multidevice.SetInstallationMetadata(myIdentityKey, installationID, data)

View file

@ -10,15 +10,15 @@ replace github.com/status-im/status-go/eth-node => ../eth-node
require ( require (
github.com/cenkalti/backoff/v3 v3.0.0 github.com/cenkalti/backoff/v3 v3.0.0
github.com/ethereum/go-ethereum v1.9.5
github.com/golang/protobuf v1.3.2 github.com/golang/protobuf v1.3.2
github.com/gomarkdown/markdown v0.0.0-20191113114344-af599402d015 github.com/gomarkdown/markdown v0.0.0-20191113114344-af599402d015
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
github.com/lucasb-eyer/go-colorful v1.0.2 github.com/lucasb-eyer/go-colorful v1.0.2
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 // indirect
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d // indirect
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
github.com/status-im/doubleratchet v3.0.0+incompatible github.com/status-im/doubleratchet v3.0.0+incompatible
github.com/status-im/migrate/v4 v4.6.2-status.2 github.com/status-im/migrate/v4 v4.6.2-status.2
@ -27,4 +27,5 @@ require (
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/vacp2p/mvds v0.0.23 github.com/vacp2p/mvds v0.0.23
go.uber.org/zap v1.13.0 go.uber.org/zap v1.13.0
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
) )

View file

@ -2,6 +2,8 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY= github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
@ -10,6 +12,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@ -18,7 +21,9 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM= github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
@ -29,12 +34,20 @@ github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0= github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5 h1:L0TwgZQo7Mga9im6FvKEZGIvyLE/VG/HI5loz5LpvC0=
github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20190219163901-728bce664cf5/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 h1:fKnuvQ/O22ZpD7HaJjGQXn/GxOdDJOQFL8bpM8Xe3X8=
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 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/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/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= 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 h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
@ -53,12 +66,20 @@ github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4r
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.0 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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= 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/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/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/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= 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/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/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
@ -77,7 +98,11 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= 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/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/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= 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/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@ -87,6 +112,7 @@ github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 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/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dvyukov/go-fuzz v0.0.0-20191022152526-8cb203812681/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/dvyukov/go-fuzz v0.0.0-20191022152526-8cb203812681/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 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/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
@ -99,6 +125,7 @@ github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo= github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
@ -110,11 +137,18 @@ github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7R
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 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 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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.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 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@ -123,12 +157,16 @@ github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhD
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/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/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k=
github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1/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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -138,8 +176,10 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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.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-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/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/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/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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
@ -150,9 +190,13 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 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.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/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4= github.com/graph-gophers/graphql-go v0.0.0-20190724201507-010347b5f9e6/go.mod h1:Au3iQ8DvDis8hZ4q2OzRcaKYlAsPt+fYvib5q4nIqu4=
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
github.com/gyuho/goraph v0.0.0-20171001060514-a7a4454fd3eb/go.mod h1:NtSxZCD+s3sZFwbW6WceOcUD83HM9XD5OE2r4c0P8eg=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= 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 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -162,6 +206,7 @@ github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -169,31 +214,54 @@ github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOo
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= 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/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/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/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/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s=
github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= 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/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
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 v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
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/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 v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A= github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8 h1:VhnqxaTIudc9IWKx8uXRLnpdSb9noCEj+vHacjmhp68=
github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190819132248-550797b1cad8/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@ -202,14 +270,80 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc=
github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4=
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8=
github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI=
github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM=
github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco=
github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE=
github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I=
github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI=
github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0=
github.com/libp2p/go-libp2p-core v0.2.3/go.mod h1:GqhyQqyIAPsxFYXHMjfXgMv03lxsvM0mFzuYA9Ib42A=
github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI=
github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g=
github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90=
github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo=
github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE=
github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY=
github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU=
github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY=
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA=
github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8=
github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI=
github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q=
github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU=
github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI=
github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0=
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc=
github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc=
github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo=
github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y=
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI= github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@ -219,16 +353,24 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/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 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg=
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= 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/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik=
@ -240,25 +382,30 @@ github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86w
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= 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/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 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.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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/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.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY= github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -268,16 +415,27 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.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-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-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-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.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.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-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.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.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/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
@ -298,14 +456,26 @@ github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d h1:A926QrjwToaPS7gi
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d/go.mod h1:Cpq811GTlHevuU6BZxk3ObOdK8AY5gHu9QGmDak0DT4= github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d/go.mod h1:Cpq811GTlHevuU6BZxk3ObOdK8AY5gHu9QGmDak0DT4=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a h1:yVNJFSzkEG8smsvd9udiQcMJA0MIsFvlG7ba314cu+s= github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a h1:yVNJFSzkEG8smsvd9udiQcMJA0MIsFvlG7ba314cu+s=
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a/go.mod h1:TPq+fcJOdGrkpZpXF4UVmFjYxH0gGqnxdgZ+OzAmvJk= github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a/go.mod h1:TPq+fcJOdGrkpZpXF4UVmFjYxH0gGqnxdgZ+OzAmvJk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= 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.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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc=
github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY= github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY=
github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU= github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
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 h1:ytuTO1yBIAuTVRtRQoc2mrdyngtP+XOQ9IHIibbz7/I=
@ -316,10 +486,13 @@ github.com/status-im/markdown v0.0.0-20191113114344-af599402d015 h1:ijC73VP0hucs
github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE= github.com/status-im/markdown v0.0.0-20191113114344-af599402d015/go.mod h1:tmG2bxyvZ2EItDO5JewbdFvV45j13IYQgvnMJ3+qAaE=
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 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/migrate/v4 v4.6.2-status.2/go.mod h1:c/kc90n47GZu/58nnz1OMLTf7uE4Da4gZP5qmU+A/v8=
github.com/status-im/status-go v0.36.0 h1:91qDMJjHv+T3Li9FwxsWQ2JBVcYtvVDT0nGFSMnmM+8=
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM= github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU= github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs= github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s= github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
github.com/status-im/whisper v1.6.1 h1:C/T1HQHZfUI2jbccf3yIe8yfkl435I3BILIKeNASJDc=
github.com/status-im/whisper v1.6.1/go.mod h1:lygchT4p9Y1/hR451OhNNqfinvy9EYEDxtXU2T/U30Q=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
@ -338,10 +511,13 @@ github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2K
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/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= github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= 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/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU= github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU=
github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ= github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ=
github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk= github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk=
@ -350,15 +526,26 @@ github.com/wealdtech/go-multicodec v1.2.0 h1:9AHSxcSE9F9r6ZvQLAO0EXCdM08QfYohaXm
github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4= github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs= github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs=
github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4= github.com/wealdtech/go-string2eth v1.0.0/go.mod h1:UZA/snEybGcD6n+Pl+yoDjmexlEJ6dtoS9myfM83Ol4=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8=
github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= 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/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@ -373,11 +560,20 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE= golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -395,11 +591,13 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/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-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-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-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-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-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -421,9 +619,12 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/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-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-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -436,10 +637,13 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/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-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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -455,6 +659,7 @@ google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.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-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/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/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -469,13 +674,20 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/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= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=

View file

@ -1,72 +1,159 @@
package protocol package protocol
import ( import (
"database/sql/driver" "crypto/ecdsa"
"encoding/json"
"strings"
"unicode"
"unicode/utf8"
"github.com/pkg/errors" "github.com/gomarkdown/markdown"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/protobuf"
) )
type hexutilSQL types.HexBytes
func (h hexutilSQL) Value() (driver.Value, error) {
return []byte(h), nil
}
func (h hexutilSQL) String() string {
return types.EncodeHex(h)
}
func (h *hexutilSQL) Scan(value interface{}) error {
if value == nil {
return nil
}
if b, ok := value.([]byte); ok {
*h = hexutilSQL(b)
return nil
}
return errors.New("failed to scan hexutilSQL")
}
// QuotedMessage contains the original text of the message replied to // QuotedMessage contains the original text of the message replied to
type QuotedMessage struct { type QuotedMessage struct {
// From is a public key of the author of the message. // From is a public key of the author of the message.
From string `json:"from"` From string `json:"from"`
Content string `json:"content"` Text string `json:"text"`
} }
const (
OutgoingStatusSending = "sending"
OutgoingStatusSent = "sent"
)
// Message represents a message record in the database, // Message represents a message record in the database,
// more specifically in user_messages_legacy table. // more specifically in user_messages_legacy table.
// Encoding and decoding of byte blobs should be performed
// using hexutil package.
type Message struct { type Message struct {
protobuf.ChatMessage
// ID calculated as keccak256(compressedAuthorPubKey, data) where data is unencrypted payload. // ID calculated as keccak256(compressedAuthorPubKey, data) where data is unencrypted payload.
ID string `json:"id"` ID string `json:"id"`
// WhisperTimestamp is a timestamp of a Whisper envelope. // WhisperTimestamp is a timestamp of a Whisper envelope.
WhisperTimestamp int64 `json:"whisperTimestamp"` WhisperTimestamp uint64 `json:"whisperTimestamp"`
// From is a public key of the author of the message. // From is a public key of the author of the message.
From string `json:"from"` From string `json:"from"`
// Random 3 words name // Random 3 words name
Alias string `json:"alias"` Alias string `json:"alias"`
// Identicon of the author // Identicon of the author
Identicon string `json:"identicon"` Identicon string `json:"identicon"`
// To is a public key of the recipient unless it's a public message then it's empty. // The chat id to be stored locally
To hexutilSQL `json:"to,omitempty"` LocalChatID string `json:"localChatId"`
// BEGIN: fields from types.Message.
Content string `json:"content"`
ContentType string `json:"contentType"`
Timestamp int64 `json:"timestamp"`
ChatID string `json:"chatId"`
MessageType string `json:"messageType,omitempty"`
MessageStatus string `json:"messageStatus,omitempty"`
ClockValue int64 `json:"clockValue"`
// END
Username string `json:"username,omitempty"`
RetryCount int `json:"retryCount"` RetryCount int `json:"retryCount"`
Show bool `json:"show"` // default true
Seen bool `json:"seen"` Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"` OutgoingStatus string `json:"outgoingStatus,omitempty"`
// MessageID of the replied message
ReplyTo string `json:"replyTo"`
QuotedMessage *QuotedMessage `json:"quotedMessage"` QuotedMessage *QuotedMessage `json:"quotedMessage"`
// Computed fields
RTL bool `json:"rtl"`
ParsedText []byte `json:"parsedText"`
LineCount int `json:"lineCount"`
SigPubKey *ecdsa.PublicKey `json:"-"`
// RawPayload is the marshaled payload, used for resending the message
RawPayload []byte `json:"-"`
}
func (m *Message) MarshalJSON() ([]byte, error) {
type MessageAlias Message
item := struct {
ID string `json:"id"`
WhisperTimestamp uint64 `json:"whisperTimestamp"`
From string `json:"from"`
Alias string `json:"alias"`
Identicon string `json:"identicon"`
RetryCount int `json:"retryCount"`
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`
QuotedMessage *QuotedMessage `json:"quotedMessage"`
RTL bool `json:"rtl"`
ParsedText json.RawMessage `json:"parsedText"`
LineCount int `json:"lineCount"`
Text string `json:"text"`
ChatId string `json:"chatId"`
LocalChatID string `json:"localChatId"`
Clock uint64 `json:"clock"`
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
Sticker *protobuf.StickerMessage `json:"sticker"`
Timestamp uint64 `json:"timestamp"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
MessageType protobuf.ChatMessage_MessageType `json:"messageType"`
}{
ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp,
From: m.From,
Alias: m.Alias,
Identicon: m.Identicon,
RetryCount: m.RetryCount,
Seen: m.Seen,
OutgoingStatus: m.OutgoingStatus,
QuotedMessage: m.QuotedMessage,
RTL: m.RTL,
ParsedText: m.ParsedText,
LineCount: m.LineCount,
Text: m.Text,
ChatId: m.ChatId,
LocalChatID: m.LocalChatID,
Clock: m.Clock,
ResponseTo: m.ResponseTo,
EnsName: m.EnsName,
Timestamp: m.Timestamp,
ContentType: m.ContentType,
MessageType: m.MessageType,
Sticker: m.GetSticker(),
}
return json.Marshal(item)
}
func (m *Message) UnmarshalJSON(data []byte) error {
type Alias Message
aux := struct {
*Alias
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
ChatID string `json:"chatId"`
Sticker *protobuf.StickerMessage `json:"sticker"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
}{
Alias: (*Alias)(m),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
if aux.ContentType == protobuf.ChatMessage_STICKER {
m.Payload = &protobuf.ChatMessage_Sticker{Sticker: aux.Sticker}
}
m.ResponseTo = aux.ResponseTo
m.EnsName = aux.EnsName
m.ChatId = aux.ChatID
m.ContentType = aux.ContentType
return nil
}
// Check if the first character is Hebrew or Arabic or the RTL character
func isRTL(s string) bool {
first, _ := utf8.DecodeRuneInString(s)
return unicode.Is(unicode.Hebrew, first) ||
unicode.Is(unicode.Arabic, first) ||
// RTL character
first == '\u200f'
}
// PrepareContent return the parsed content of the message, the line-count and whether
// is a right-to-left message
func (m *Message) PrepareContent() error {
parsedText := markdown.Parse([]byte(m.Text), nil)
jsonParsedText, err := json.Marshal(parsedText)
if err != nil {
return err
}
m.ParsedText = jsonParsedText
m.LineCount = strings.Count(m.Text, "\n")
m.RTL = isRTL(m.Text)
return nil
} }

View file

@ -56,7 +56,7 @@ func (h *persistentMessageHandler) chatID(chatID string) (*Chat, error) {
return nil, err return nil, err
} }
for _, ch := range chats { for _, ch := range chats {
if chat.ID == chatID { if ch.ID == chatID {
chat = ch chat = ch
break break
} }

View file

@ -92,25 +92,6 @@ func (p *messageProcessor) Stop() {
p.datasync.Stop() // idempotent op p.datasync.Stop() // idempotent op
} }
func (p *messageProcessor) SendPrivate(
ctx context.Context,
recipient *ecdsa.PublicKey,
chatID string,
data []byte,
clock int64,
) ([]byte, *v1protocol.Message, error) {
message := v1protocol.CreatePrivateTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to encode message")
}
messageID, err := p.sendPrivate(ctx, recipient, encodedMessage)
if err != nil {
return nil, nil, err
}
return messageID, &message, nil
}
// SendPrivateRaw takes encoded data, encrypts it and sends through the wire. // SendPrivateRaw takes encoded data, encrypts it and sends through the wire.
func (p *messageProcessor) SendPrivateRaw( func (p *messageProcessor) SendPrivateRaw(
ctx context.Context, ctx context.Context,
@ -125,6 +106,34 @@ func (p *messageProcessor) SendPrivateRaw(
return p.sendPrivate(ctx, recipient, data) return p.sendPrivate(ctx, recipient, data)
} }
// SendGroupRaw takes encoded data, encrypts it and sends through the wire,
// always return the messageID
func (p *messageProcessor) SendGroupRaw(
ctx context.Context,
recipients []*ecdsa.PublicKey,
data []byte,
) ([]byte, error) {
p.logger.Debug(
"sending a private group message",
zap.String("site", "SendGroupRaw"),
)
// Calculate messageID first
wrappedMessage, err := p.wrapMessageV1(data)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap message")
}
messageID := v1protocol.MessageID(&p.identity.PublicKey, wrappedMessage)
for _, recipient := range recipients {
_, err = p.sendPrivate(ctx, recipient, data)
if err != nil {
return nil, errors.Wrap(err, "failed to send message")
}
}
return messageID, nil
}
// sendPrivate sends data to the recipient identifying with a given public key. // sendPrivate sends data to the recipient identifying with a given public key.
func (p *messageProcessor) sendPrivate( func (p *messageProcessor) sendPrivate(
ctx context.Context, ctx context.Context,
@ -133,7 +142,7 @@ func (p *messageProcessor) sendPrivate(
) ([]byte, error) { ) ([]byte, error) {
p.logger.Debug("sending private message", zap.Binary("recipient", crypto.FromECDSAPub(recipient))) p.logger.Debug("sending private message", zap.Binary("recipient", crypto.FromECDSAPub(recipient)))
wrappedMessage, err := p.tryWrapMessageV1(data) wrappedMessage, err := p.wrapMessageV1(data)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
@ -164,32 +173,6 @@ func (p *messageProcessor) sendPrivate(
return messageID, nil return messageID, nil
} }
func (p *messageProcessor) SendGroup(
ctx context.Context,
recipients []*ecdsa.PublicKey,
chatID string,
data []byte,
clock int64,
) ([][]byte, []*v1protocol.Message, error) {
p.logger.Debug("sending a group message", zap.Int("membersCount", len(recipients)))
message := v1protocol.CreatePrivateGroupTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to encode message")
}
var resultIDs [][]byte
for _, recipient := range recipients {
messageID, err := p.sendPrivate(ctx, recipient, encodedMessage)
if err != nil {
return nil, nil, err
}
resultIDs = append(resultIDs, messageID)
}
return resultIDs, nil, nil
}
func (p *messageProcessor) SendMembershipUpdate( func (p *messageProcessor) SendMembershipUpdate(
ctx context.Context, ctx context.Context,
recipients []*ecdsa.PublicKey, recipients []*ecdsa.PublicKey,
@ -219,46 +202,11 @@ func (p *messageProcessor) SendMembershipUpdate(
return resultIDs, nil return resultIDs, nil
} }
func (p *messageProcessor) SendPublic(ctx context.Context, chatID string, data []byte, clock int64) ([]byte, error) {
message := v1protocol.CreatePublicTextMessage(data, clock, chatID)
encodedMessage, err := p.encodeMessage(message)
if err != nil {
return nil, errors.Wrap(err, "failed to encode message")
}
wrappedMessage, err := p.tryWrapMessageV1(encodedMessage)
if err != nil {
return nil, errors.Wrap(err, "failed to wrap message")
}
messageSpec, err := p.protocol.BuildPublicMessage(p.identity, wrappedMessage)
if err != nil {
return nil, errors.Wrap(err, "failed to build public message")
}
newMessage, err := messageSpecToWhisper(messageSpec)
if err != nil {
return nil, err
}
hash, err := p.transport.SendPublic(ctx, newMessage, chatID)
if err != nil {
return nil, err
}
messageID := v1protocol.MessageID(&p.identity.PublicKey, wrappedMessage)
p.transport.Track([][]byte{messageID}, hash, newMessage)
return messageID, nil
}
// SendPublicRaw takes encoded data, encrypts it and sends through the wire. // SendPublicRaw takes encoded data, encrypts it and sends through the wire.
func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, data []byte) ([]byte, error) { func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, data []byte) ([]byte, error) {
var newMessage *types.NewMessage var newMessage *types.NewMessage
wrappedMessage, err := p.tryWrapMessageV1(data) wrappedMessage, err := p.wrapMessageV1(data)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
@ -282,61 +230,6 @@ func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, d
return messageID, nil return messageID, nil
} }
// Process processes received Whisper messages through all the layers
// and returns decoded user messages.
// It also handled all non-user messages like PairMessage.
func (p *messageProcessor) Process(shhMessage *types.Message) ([]*v1protocol.Message, error) {
logger := p.logger.With(zap.String("site", "Process"))
var decodedMessages []*v1protocol.Message
hlogger := logger.With(zap.Binary("hash", shhMessage.Hash))
hlogger.Debug("handling a received message")
statusMessages, err := p.handleMessages(shhMessage, true)
if err != nil {
return nil, err
}
for _, statusMessage := range statusMessages {
switch m := statusMessage.ParsedMessage.(type) {
case v1protocol.Message:
m.ID = statusMessage.ID
m.SigPubKey = statusMessage.SigPubKey()
decodedMessages = append(decodedMessages, &m)
case v1protocol.MembershipUpdateMessage:
// Handle user message that can be attached to the membership update.
userMessage := m.Message
if userMessage != nil {
userMessage.ID = statusMessage.ID
userMessage.SigPubKey = statusMessage.SigPubKey()
decodedMessages = append(decodedMessages, userMessage)
}
if err := p.processMembershipUpdate(m); err != nil {
hlogger.Error("failed to process MembershipUpdateMessage", zap.Error(err))
}
case v1protocol.PairMessage:
fromOurDevice := isPubKeyEqual(statusMessage.SigPubKey(), &p.identity.PublicKey)
if !fromOurDevice {
hlogger.Debug("received PairMessage from not our device, skipping")
break
}
if err := p.processPairMessage(m); err != nil {
hlogger.Error("failed to process PairMessage", zap.Error(err))
}
default:
hlogger.Error(
"skipped a public message of unsupported type",
zap.Any("value", statusMessage.ParsedMessage),
)
}
}
return decodedMessages, nil
}
func (p *messageProcessor) processMembershipUpdate(m v1protocol.MembershipUpdateMessage) error { func (p *messageProcessor) processMembershipUpdate(m v1protocol.MembershipUpdateMessage) error {
if err := m.Verify(); err != nil { if err := m.Verify(); err != nil {
return err return err
@ -443,24 +336,13 @@ func (p *messageProcessor) handleErrDeviceNotFound(ctx context.Context, publicKe
return nil return nil
} }
func (p *messageProcessor) encodeMessage(message v1protocol.Message) ([]byte, error) { func (p *messageProcessor) wrapMessageV1(encodedMessage []byte) ([]byte, error) {
encodedMessage, err := v1protocol.EncodeMessage(message)
if err != nil {
return nil, errors.Wrap(err, "failed to encode message")
}
return encodedMessage, nil
}
func (p *messageProcessor) tryWrapMessageV1(encodedMessage []byte) ([]byte, error) {
if p.featureFlags.sendV1Messages {
wrappedMessage, err := v1protocol.WrapMessageV1(encodedMessage, p.identity) wrappedMessage, err := v1protocol.WrapMessageV1(encodedMessage, p.identity)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to wrap message") return nil, errors.Wrap(err, "failed to wrap message")
} }
return wrappedMessage, nil return wrappedMessage, nil
} }
return encodedMessage, nil
}
func (p *messageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) error { func (p *messageProcessor) addToDataSync(publicKey *ecdsa.PublicKey, message []byte) error {
groupID := datasync.ToOneToOneGroupID(&p.identity.PublicKey, publicKey) groupID := datasync.ToOneToOneGroupID(&p.identity.PublicKey, publicKey)
@ -520,15 +402,9 @@ func (p *messageProcessor) sendMessageSpec(ctx context.Context, publicKey *ecdsa
case messageSpec.SharedSecret != nil: case messageSpec.SharedSecret != nil:
logger.Debug("sending using shared secret") logger.Debug("sending using shared secret")
hash, err = p.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret) hash, err = p.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret)
case messageSpec.PartitionedTopicMode() == encryption.PartitionTopicV1: default:
logger.Debug("sending partitioned topic") logger.Debug("sending partitioned topic")
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey) hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
case !p.featureFlags.genericDiscoveryTopicEnabled:
logger.Debug("sending partitioned topic (generic discovery topic disabled)")
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
default:
logger.Debug("sending using discovery topic")
hash, err = p.transport.SendPrivateOnDiscovery(ctx, newMessage, publicKey)
} }
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View file

@ -4,12 +4,15 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"database/sql" "database/sql"
"strings" "encoding/hex"
"encoding/json"
"strconv"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/golang/protobuf/proto"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
enstypes "github.com/status-im/status-go/eth-node/types/ens" enstypes "github.com/status-im/status-go/eth-node/types/ens"
@ -18,11 +21,14 @@ import (
"github.com/status-im/status-go/protocol/encryption/sharedsecret" "github.com/status-im/status-go/protocol/encryption/sharedsecret"
"github.com/status-im/status-go/protocol/identity/alias" "github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/identity/identicon" "github.com/status-im/status-go/protocol/identity/identicon"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/sqlite"
transport "github.com/status-im/status-go/protocol/transport/whisper" transport "github.com/status-im/status-go/protocol/transport/whisper"
v1protocol "github.com/status-im/status-go/protocol/v1" v1protocol "github.com/status-im/status-go/protocol/v1"
) )
const PubKeyStringLength = 132
var ( var (
ErrChatIDEmpty = errors.New("chat ID is empty") ErrChatIDEmpty = errors.New("chat ID is empty")
ErrNotImplemented = errors.New("not implemented") ErrNotImplemented = errors.New("not implemented")
@ -46,20 +52,29 @@ type Messenger struct {
processor *messageProcessor processor *messageProcessor
logger *zap.Logger logger *zap.Logger
ownMessages []*v1protocol.Message
featureFlags featureFlags featureFlags featureFlags
messagesPersistenceEnabled bool messagesPersistenceEnabled bool
shutdownTasks []func() error shutdownTasks []func() error
} }
type featureFlags struct { type RawResponse struct {
genericDiscoveryTopicEnabled bool Filter *transport.Filter `json:"filter"`
// sendV1Messages indicates whether we should send Messages []*v1protocol.StatusMessage `json:"messages"`
// messages compatible only with V1 and later. }
// V1 messages adds additional wrapping
// which contains a signature and payload.
sendV1Messages bool
type MessengerResponse struct {
Chats []*Chat `json:"chats,omitEmpty"`
Messages []*Message `json:"messages,omitEmpty"`
Contacts []*Contact `json:"contacts,omitEmpty"`
// Raw unprocessed messages
RawMessages []*RawResponse `json:"rawMessages,omitEmpty"`
}
func (m *MessengerResponse) IsEmpty() bool {
return len(m.Chats) == 0 && len(m.Messages) == 0 && len(m.Contacts) == 0 && len(m.RawMessages) == 0
}
type featureFlags struct {
// datasync indicates whether direct messages should be sent exclusively // datasync indicates whether direct messages should be sent exclusively
// using datasync, breaking change for non-v1 clients. Public messages // using datasync, breaking change for non-v1 clients. Public messages
// are not impacted // are not impacted
@ -117,13 +132,6 @@ func WithCustomLogger(logger *zap.Logger) Option {
} }
} }
func WithGenericDiscoveryTopicSupport() Option {
return func(c *config) error {
c.featureFlags.genericDiscoveryTopicEnabled = true
return nil
}
}
func WithMessagesPersistenceEnabled() Option { func WithMessagesPersistenceEnabled() Option {
return func(c *config) error { return func(c *config) error {
c.messagesPersistenceEnabled = true c.messagesPersistenceEnabled = true
@ -145,13 +153,6 @@ func WithDatabase(db *sql.DB) Option {
} }
} }
func WithSendV1Messages() Option {
return func(c *config) error {
c.featureFlags.sendV1Messages = true
return nil
}
}
func WithDatasync() func(c *config) error { func WithDatasync() func(c *config) error {
return func(c *config) error { return func(c *config) error {
c.featureFlags.datasync = true c.featureFlags.datasync = true
@ -267,7 +268,6 @@ func NewMessenger(
nil, nil,
c.envelopesMonitorConfig, c.envelopesMonitorConfig,
logger, logger,
transport.SetGenericDiscoveryTopicSupport(c.featureFlags.genericDiscoveryTopicEnabled),
) )
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to create a WhisperServiceTransport") return nil, errors.Wrap(err, "failed to create a WhisperServiceTransport")
@ -624,47 +624,58 @@ func (m *Messenger) Contacts() ([]*Contact, error) {
return m.persistence.Contacts() return m.persistence.Contacts()
} }
func (m *Messenger) Send(ctx context.Context, chatID string, data []byte) ([][]byte, error) { func timestampInMs() uint64 {
logger := m.logger.With(zap.String("site", "Send"), zap.String("chatID", chatID)) return uint64(time.Now().UnixNano() / int64(time.Millisecond))
}
// A valid added chat is required. // ReSendChatMessage pulls a message from the database and sends it again
chat, err := m.chatByID(chatID) func (m *Messenger) ReSendChatMessage(ctx context.Context, messageID string) (*MessengerResponse, error) {
logger := m.logger.With(zap.String("site", "ReSendChatMessage"))
var response MessengerResponse
message, err := m.persistence.MessageByID(messageID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if message == nil {
return nil, errors.New("message not found")
}
if message.RawPayload == nil {
return nil, errors.New("message payload not found, can't resend message")
}
clock, err := m.persistence.LastMessageClock(chat.ID) chat, err := m.chatByID(message.LocalChatID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
logger.Debug("last message clock received", zap.Int64("clock", clock))
switch chat.ChatType { switch chat.ChatType {
case ChatTypeOneToOne: case ChatTypeOneToOne:
logger.Debug("sending private message", zap.Binary("publicKey", crypto.FromECDSAPub(chat.PublicKey))) publicKey := crypto.FromECDSAPub(chat.PublicKey)
id, message, err := m.processor.SendPrivate(ctx, chat.PublicKey, chat.ID, data, clock) logger.Debug("re-sending private message", zap.Binary("publicKey", publicKey))
id, err := m.processor.SendPrivateRaw(ctx, chat.PublicKey, message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := m.cacheOwnMessage(chatID, id, message); err != nil { message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, message.RawPayload)
if err != nil {
return nil, err return nil, err
} }
return [][]byte{id}, nil
case ChatTypePublic: case ChatTypePublic:
logger.Debug("sending public message", zap.String("chatName", chat.Name)) logger.Debug("re-sending public message", zap.String("chatName", chat.Name))
id, err := m.processor.SendPublic(ctx, chat.ID, data, clock) id, err := m.processor.SendPublicRaw(ctx, chat.ID, message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return [][]byte{id}, nil message.ID = "0x" + hex.EncodeToString(id)
case ChatTypePrivateGroupChat: case ChatTypePrivateGroupChat:
logger.Debug("sending group message", zap.String("chatName", chat.Name)) logger.Debug("re-sending group message", zap.String("chatName", chat.Name))
recipients, err := chat.MembersAsPublicKeys() recipients, err := chat.MembersAsPublicKeys()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Filter me out of recipients.
n := 0 n := 0
for _, item := range recipients { for _, item := range recipients {
if !isPubKeyEqual(item, &m.identity.PublicKey) { if !isPubKeyEqual(item, &m.identity.PublicKey) {
@ -672,40 +683,186 @@ func (m *Messenger) Send(ctx context.Context, chatID string, data []byte) ([][]b
n++ n++
} }
} }
ids, messages, err := m.processor.SendGroup(ctx, recipients[:n], chat.ID, data, clock) id, err := m.processor.SendGroupRaw(ctx, recipients[:n], message.RawPayload)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for idx, message := range messages {
if err := m.cacheOwnMessage(chatID, ids[idx], message); err != nil { message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, message.RawPayload)
if err != nil {
return nil, err return nil, err
} }
}
return ids, nil
default: default:
return nil, errors.New("chat is neither public nor private") return nil, errors.New("chat type not supported")
}
} }
func (m *Messenger) cacheOwnMessage(chatID string, id []byte, message *v1protocol.Message) error { response.Messages = []*Message{message}
// Save our message because it won't be received from the transport layer. response.Chats = []*Chat{chat}
message.ID = id // a Message need ID to be properly stored in the db return &response, nil
message.SigPubKey = &m.identity.PublicKey }
message.ChatID = chatID
if m.messagesPersistenceEnabled { // sendToPairedDevices will check if we have any paired devices and send to them if necessary
_, err := m.persistence.SaveMessages([]*v1protocol.Message{message}) func (m *Messenger) sendToPairedDevices(ctx context.Context, payload []byte) error {
activeInstallations, err := m.encryptor.GetOurActiveInstallations(&m.identity.PublicKey)
if err != nil {
return err
}
// We send a message to any paired device
if len(activeInstallations) > 1 {
_, err := m.processor.SendPrivateRaw(ctx, &m.identity.PublicKey, payload)
if err != nil { if err != nil {
return err return err
} }
} }
// Cache it to be returned in Retrieve().
m.ownMessages = append(m.ownMessages, message)
return nil return nil
} }
// SendChatMessage takes a minimal message and sends it based on the corresponding chat
func (m *Messenger) SendChatMessage(ctx context.Context, message *Message) (*MessengerResponse, error) {
logger := m.logger.With(zap.String("site", "Send"), zap.String("chatID", message.ChatId))
var response MessengerResponse
// A valid added chat is required.
chat, err := m.chatByID(message.ChatId)
if err != nil {
return nil, err
}
clock := chat.LastClockValue
timestamp := timestampInMs()
if clock == 0 || clock < timestamp {
clock = timestamp
} else {
clock = clock + 1
}
message.LocalChatID = chat.ID
message.Clock = clock
message.Timestamp = timestamp
message.From = "0x" + hex.EncodeToString(crypto.FromECDSAPub(&m.identity.PublicKey))
message.SigPubKey = &m.identity.PublicKey
message.WhisperTimestamp = timestamp
message.Seen = true
message.OutgoingStatus = OutgoingStatusSending
identicon, err := identicon.GenerateBase64(message.From)
if err != nil {
return nil, err
}
message.Identicon = identicon
alias, err := alias.GenerateFromPublicKeyString(message.From)
if err != nil {
return nil, err
}
message.Alias = alias
switch chat.ChatType {
case ChatTypeOneToOne:
publicKey := crypto.FromECDSAPub(chat.PublicKey)
logger.Debug("sending private message", zap.Binary("publicKey", publicKey))
message.MessageType = protobuf.ChatMessage_ONE_TO_ONE
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
id, err := m.processor.SendPrivateRaw(ctx, chat.PublicKey, encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, encodedMessage)
if err != nil {
return nil, err
}
case ChatTypePublic:
logger.Debug("sending public message", zap.String("chatName", chat.Name))
message.MessageType = protobuf.ChatMessage_PUBLIC_GROUP
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
id, err := m.processor.SendPublicRaw(ctx, chat.ID, encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
case ChatTypePrivateGroupChat:
logger.Debug("sending public message", zap.String("chatName", chat.Name))
message.MessageType = protobuf.ChatMessage_PRIVATE_GROUP
encodedMessage, err := proto.Marshal(message)
if err != nil {
return nil, err
}
message.RawPayload = encodedMessage
logger.Debug("sending group message", zap.String("chatName", chat.Name))
recipients, err := chat.MembersAsPublicKeys()
if err != nil {
return nil, err
}
n := 0
for _, item := range recipients {
if !isPubKeyEqual(item, &m.identity.PublicKey) {
recipients[n] = item
n++
}
}
id, err := m.processor.SendGroupRaw(ctx, recipients[:n], encodedMessage)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(id)
err = m.sendToPairedDevices(ctx, encodedMessage)
if err != nil {
return nil, err
}
default:
return nil, errors.New("chat type not supported")
}
err = message.PrepareContent()
if err != nil {
return nil, err
}
jsonMessage, err := json.Marshal(message)
if err != nil {
return nil, err
}
chat.LastClockValue = clock
chat.LastMessage = jsonMessage
chat.Timestamp = int64(timestamp)
if err := m.SaveChat(*chat); err != nil {
return nil, err
}
err = m.persistence.SaveMessagesLegacy([]*Message{message})
if err != nil {
return nil, err
}
response.Chats = []*Chat{chat}
response.Messages = []*Message{message}
return &response, nil
}
// SendRaw takes encoded data, encrypts it and sends through the wire. // SendRaw takes encoded data, encrypts it and sends through the wire.
// DEPRECATED // DEPRECATED
func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte, error) { func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte, error) {
@ -717,94 +874,48 @@ func (m *Messenger) SendRaw(ctx context.Context, chat Chat, data []byte) ([]byte
return nil, errors.New("chat is neither public nor private") return nil, errors.New("chat is neither public nor private")
} }
type RetrieveConfig struct { // RetrieveAll retrieves messages from all filters, processes them and returns a
From time.Time // MessengerResponse to the client
To time.Time func (m *Messenger) RetrieveAll() (*MessengerResponse, error) {
latest bool
last24Hours bool
}
var (
RetrieveLatest = RetrieveConfig{latest: true}
RetrieveLastDay = RetrieveConfig{latest: true, last24Hours: true}
)
// RetrieveAll retrieves all previously fetched messages
func (m *Messenger) RetrieveAll(ctx context.Context, c RetrieveConfig) ([]*v1protocol.Message, error) {
result, err := m.retrieveLatest(ctx)
if err != nil {
return nil, err
}
postProcess := newPostProcessor(m, postProcessorConfig{
MatchChat: true,
Persist: true,
})
result, err = postProcess.Run(result)
if err != nil {
return nil, errors.Wrap(err, "failed to post process messages")
}
retrievedMessages, err := m.retrieveSaved(ctx, c)
if err != nil {
return nil, errors.Wrap(err, "failed to get saved messages")
}
result = append(result, retrievedMessages...)
// Include own messages.
result = append(result, m.ownMessages...)
m.ownMessages = nil
return result, nil
}
func (m *Messenger) retrieveLatest(ctx context.Context) ([]*v1protocol.Message, error) {
latest, err := m.transport.RetrieveAllMessages()
if err != nil {
return nil, errors.Wrap(err, "failed to retrieve messages")
}
logger := m.logger.With(zap.String("site", "retrieveLatest"))
logger.Debug("retrieved messages", zap.Int("count", len(latest)))
var result []*v1protocol.Message
for _, transpMessage := range latest {
protoMessages, err := m.processor.Process(transpMessage.Message)
if err != nil {
return nil, err
}
result = append(result, protoMessages...)
}
return result, nil
}
func (m *Messenger) retrieveSaved(ctx context.Context, c RetrieveConfig) (messages []*v1protocol.Message, err error) {
if !m.messagesPersistenceEnabled {
return nil, nil
}
if !c.latest {
return m.persistence.Messages(c.From, c.To)
}
if c.last24Hours {
to := time.Now()
from := to.Add(-time.Hour * 24)
return m.persistence.Messages(from, to)
}
return nil, nil
}
// DEPRECATED
func (m *Messenger) RetrieveRawAll() (map[transport.Filter][]*v1protocol.StatusMessage, error) {
chatWithMessages, err := m.transport.RetrieveRawAll() chatWithMessages, err := m.transport.RetrieveRawAll()
if err != nil { if err != nil {
return nil, err return nil, err
} }
logger := m.logger.With(zap.String("site", "RetrieveRawAll")) return m.handleRetrievedMessages(chatWithMessages)
result := make(map[transport.Filter][]*v1protocol.StatusMessage) }
func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filter][]*types.Message) (*MessengerResponse, error) {
response := &MessengerResponse{
Chats: []*Chat{},
Messages: []*Message{},
}
allChats, err := m.persistence.Chats()
if err != nil {
return nil, err
}
postProcessor := newPostProcessor(m, postProcessorConfig{MatchChat: true})
logger := m.logger.With(zap.String("site", "RetrieveAll"))
rawMessages := make(map[transport.Filter][]*v1protocol.StatusMessage)
// We should query this instead
contacts, err := m.Contacts()
if err != nil {
return nil, err
}
blockedContacts := make(map[string]bool)
for _, c := range contacts {
if c.IsBlocked() {
blockedContacts[c.ID] = true
}
}
allContactsMap := make(map[string]*Contact)
allChatsMap := make(map[string]*Chat)
existingMessagesMap := make(map[string]bool)
for chat, messages := range chatWithMessages { for chat, messages := range chatWithMessages {
for _, shhMessage := range messages { for _, shhMessage := range messages {
@ -816,48 +927,130 @@ func (m *Messenger) RetrieveRawAll() (map[transport.Filter][]*v1protocol.StatusM
} }
for _, msg := range statusMessages { for _, msg := range statusMessages {
// Check for messages from blocked users
senderID := "0x" + hex.EncodeToString(crypto.FromECDSAPub(msg.SigPubKey()))
if blockedContacts[senderID] {
continue
}
// Don't process duplicates
messageID := "0x" + hex.EncodeToString(msg.ID)
if _, ok := existingMessagesMap[messageID]; ok {
continue
}
existingMessagesMap[messageID] = true
// Check against the database, this is probably a bit slow for
// each message, but for now might do, we'll make it faster later
existingMessage, err := m.persistence.MessageByID(messageID)
if err != nil && err != errRecordNotFound {
return nil, err
}
if existingMessage != nil {
continue
}
publicKey := msg.SigPubKey()
if publicKey == nil {
return nil, errors.New("public key can't be nil")
}
var contact *Contact
if c, ok := allContactsMap[senderID]; ok {
contact = c
} else {
c, err := buildContact(publicKey)
if err != nil {
logger.Info("failed to build contact", zap.Error(err))
continue
}
contact = c
allContactsMap[senderID] = c
response.Contacts = append(response.Contacts, c)
}
if msg.ParsedMessage != nil { if msg.ParsedMessage != nil {
if textMessage, ok := msg.ParsedMessage.(v1protocol.Message); ok { if textMessage, ok := msg.ParsedMessage.(protobuf.ChatMessage); ok {
textMessage.Content = v1protocol.PrepareContent(textMessage.Content) receivedMessage := &Message{
msg.ParsedMessage = textMessage ID: messageID,
ChatMessage: textMessage,
From: contact.ID,
Alias: contact.Alias,
SigPubKey: publicKey,
Identicon: contact.Identicon,
WhisperTimestamp: uint64(msg.TransportMessage.Timestamp) * 1000,
} }
receivedMessage.PrepareContent()
chat, err := postProcessor.matchMessage(receivedMessage, allChats)
if err != nil {
logger.Warn("failed to match message", zap.String("receivedChatID", receivedMessage.ChatId), zap.Error(err))
continue
}
// If deleted-at is greater, ignore message
if chat.DeletedAtClockValue >= receivedMessage.Clock {
continue
}
// Set the LocalChatID for the message
receivedMessage.LocalChatID = chat.ID
if c, ok := allChatsMap[chat.ID]; ok {
chat = c
}
// Increase unviewed count
if !isPubKeyEqual(receivedMessage.SigPubKey, &m.identity.PublicKey) {
chat.UnviewedMessagesCount++
} else {
// Our own message, mark as sent
receivedMessage.OutgoingStatus = OutgoingStatusSent
}
// Update chat timestamp
chat.Timestamp = int64(timestampInMs())
// Update last clock value
if chat.LastClockValue <= receivedMessage.Clock {
chat.LastClockValue = receivedMessage.Clock
encodedLastMessage, err := json.Marshal(receivedMessage)
if err != nil {
return nil, err
}
chat.LastMessage = encodedLastMessage
}
// Set chat active
chat.Active = true
// Set in the map
allChatsMap[chat.ID] = chat
// Add to response
response.Messages = append(response.Messages, receivedMessage)
}
} else {
// RawMessage, not processed here, pass straight to the client
rawMessages[chat] = append(rawMessages[chat], msg)
} }
} }
result[chat] = append(result[chat], statusMessages...)
} }
} }
err = m.updateContactsFromMessages(result) err = m.persistence.SetContactsGeneratedData(response.Contacts, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return result, nil for _, c := range allChatsMap {
response.Chats = append(response.Chats, c)
} }
func (m *Messenger) updateContactsFromMessages(messages map[transport.Filter][]*v1protocol.StatusMessage) error { m.persistence.SaveChats(response.Chats)
allContactsMap := make(map[string]bool) m.SaveMessages(response.Messages)
var allContacts []Contact
for _, chatMessages := range messages {
for _, message := range chatMessages {
publicKey := message.SigPubKey()
address := strings.ToLower(crypto.PubkeyToAddress(*publicKey).Hex())
if _, ok := allContactsMap[address]; ok { for filter, messages := range rawMessages {
continue response.RawMessages = append(response.RawMessages, &RawResponse{Filter: &filter, Messages: messages})
} }
contact, err := buildContact(publicKey) return response, nil
if err != nil {
continue
}
allContactsMap[address] = true
allContacts = append(allContacts, *contact)
}
}
return m.persistence.SetContactsGeneratedData(allContacts, nil)
} }
func (m *Messenger) RequestHistoricMessages( func (m *Messenger) RequestHistoricMessages(
@ -909,6 +1102,47 @@ func (m *Messenger) SaveMessages(messages []*Message) error {
return m.persistence.SaveMessagesLegacy(messages) return m.persistence.SaveMessagesLegacy(messages)
} }
// AddSystemMessages format an array of system-messages and saves them to the database
// It's needed until group chats are fully in status-go.
func (m *Messenger) AddSystemMessages(messages []*Message) ([]*Message, error) {
timestamp := timestampInMs()
for _, message := range messages {
message.LocalChatID = message.ChatId
message.Timestamp = timestamp
message.WhisperTimestamp = timestamp
message.Seen = true
identicon, err := identicon.GenerateBase64(message.From)
if err != nil {
return nil, err
}
message.Identicon = identicon
alias, err := alias.GenerateFromPublicKeyString(message.From)
if err != nil {
return nil, err
}
message.ID = "0x" + hex.EncodeToString(crypto.Keccak256([]byte(message.Text+message.From+strconv.FormatUint(message.Clock, 10))))
message.Alias = alias
message.ContentType = protobuf.ChatMessage_STATUS
message.MessageType = protobuf.ChatMessage_SYSTEM_MESSAGE_PRIVATE_GROUP
err = message.PrepareContent()
if err != nil {
return nil, err
}
}
err := m.SaveMessages(messages)
if err != nil {
return nil, err
}
return messages, nil
}
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
func (m *Messenger) DeleteMessage(id string) error { func (m *Messenger) DeleteMessage(id string) error {
return m.persistence.DeleteMessage(id) return m.persistence.DeleteMessage(id)
@ -920,8 +1154,8 @@ func (m *Messenger) DeleteMessagesByChatID(id string) error {
} }
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
func (m *Messenger) MarkMessagesSeen(ids ...string) error { func (m *Messenger) MarkMessagesSeen(chatID string, ids []string) error {
return m.persistence.MarkMessagesSeen(ids...) return m.persistence.MarkMessagesSeen(chatID, ids)
} }
// DEPRECATED: required by status-react. // DEPRECATED: required by status-react.
@ -955,100 +1189,68 @@ func newPostProcessor(m *Messenger, config postProcessorConfig) *postProcessor {
} }
} }
func (p *postProcessor) Run(messages []*v1protocol.Message) ([]*v1protocol.Message, error) { func (p *postProcessor) matchMessages(messages []*Message) ([]*Message, error) {
var err error
p.logger.Debug("running post processor", zap.Int("messages", len(messages)))
var fns []func([]*v1protocol.Message) ([]*v1protocol.Message, error)
// Order is important. Persisting messages should be always at the end.
if p.config.MatchChat {
fns = append(fns, p.matchMessages)
}
if p.config.Parse {
fns = append(fns, p.parseMessages)
}
if p.config.Persist {
fns = append(fns, p.saveMessages)
}
for _, fn := range fns {
messages, err = fn(messages)
if err != nil {
return nil, err
}
}
return messages, nil
}
func (p *postProcessor) saveMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
_, err := p.persistence.SaveMessages(messages)
if err != nil {
return nil, err
}
return messages, nil
}
func (p *postProcessor) parseMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
for _, m := range messages {
m.Content = v1protocol.PrepareContent(m.Content)
}
return messages, nil
}
func (p *postProcessor) matchMessages(messages []*v1protocol.Message) ([]*v1protocol.Message, error) {
chats, err := p.persistence.Chats() chats, err := p.persistence.Chats()
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := make([]*v1protocol.Message, 0, len(messages)) result := make([]*Message, 0, len(messages))
for _, message := range messages { for _, message := range messages {
chat, err := p.matchMessage(message, chats) chat, err := p.matchMessage(message, chats)
if err != nil { if err != nil {
p.logger.Error("failed to match a chat to a message", zap.Error(err)) p.logger.Error("failed to match a chat to a message", zap.Error(err))
continue continue
} }
message.ChatID = chat.ID message.LocalChatID = chat.ID
result = append(result, message) result = append(result, message)
} }
return result, nil return result, nil
} }
func (p *postProcessor) matchMessage(message *v1protocol.Message, chats []*Chat) (*Chat, error) { func (p *postProcessor) matchMessage(message *Message, chats []*Chat) (*Chat, error) {
if message.SigPubKey == nil { if message.SigPubKey == nil {
p.logger.Error("public key can't be empty") p.logger.Error("public key can't be empty")
return nil, errors.New("received a message with empty public key") return nil, errors.New("received a message with empty public key")
} }
switch { switch {
case message.MessageT == v1protocol.MessageTypePublicGroup: case message.MessageType == protobuf.ChatMessage_PUBLIC_GROUP:
// For public messages, all outgoing and incoming messages have the same chatID // For public messages, all outgoing and incoming messages have the same chatID
// equal to a public chat name. // equal to a public chat name.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
return nil, errors.New("received a public message from non-existing chat") return nil, errors.New("received a public message from non-existing chat")
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivate && isPubKeyEqual(message.SigPubKey, p.myPublicKey): case message.MessageType == protobuf.ChatMessage_ONE_TO_ONE && isPubKeyEqual(message.SigPubKey, p.myPublicKey):
// It's a private message coming from us so we rely on Message.Content.ChatID. // It's a private message coming from us so we rely on Message.ChatId
// If chat does not exist, it should be created to support multidevice synchronization. // If chat does not exist, it should be created to support multidevice synchronization.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
// TODO: this should be a three-word name used in the mobile client if len(chatID) != PubKeyStringLength {
newChat := CreateOneToOneChat(chatID[:8], message.SigPubKey) return nil, errors.New("invalid pubkey length")
}
bytePubKey, err := hex.DecodeString(chatID[2:])
if err != nil {
return nil, errors.Wrap(err, "failed to decode hex chatID")
}
pubKey, err := crypto.UnmarshalPubkey(bytePubKey)
if err != nil {
return nil, errors.Wrap(err, "failed to decode pubkey")
}
newChat := CreateOneToOneChat(chatID[:8], pubKey)
if err := p.persistence.SaveChat(newChat); err != nil { if err := p.persistence.SaveChat(newChat); err != nil {
return nil, errors.Wrap(err, "failed to save newly created chat") return nil, errors.Wrap(err, "failed to save newly created chat")
} }
chat = &newChat chat = &newChat
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivate: case message.MessageType == protobuf.ChatMessage_ONE_TO_ONE:
// It's an incoming private message. ChatID is calculated from the signature. // It's an incoming private message. ChatID is calculated from the signature.
// If a chat does not exist, a new one is created and saved. // If a chat does not exist, a new one is created and saved.
chatID := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey)) chatID := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
@ -1062,21 +1264,34 @@ func (p *postProcessor) matchMessage(message *v1protocol.Message, chats []*Chat)
chat = &newChat chat = &newChat
} }
return chat, nil return chat, nil
case message.MessageT == v1protocol.MessageTypePrivateGroup: case message.MessageType == protobuf.ChatMessage_PRIVATE_GROUP:
// In the case of a group message, ChatID is the same for all messages belonging to a group. // In the case of a group message, ChatID is the same for all messages belonging to a group.
// It needs to be verified if the signature public key belongs to the chat. // It needs to be verified if the signature public key belongs to the chat.
chatID := message.Content.ChatID chatID := message.ChatId
chat := findChatByID(chatID, chats) chat := findChatByID(chatID, chats)
if chat == nil { if chat == nil {
return nil, errors.New("received group chat message for non-existing chat") return nil, errors.New("received group chat message for non-existing chat")
} }
sigPubKeyHex := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey)) theirKeyHex := types.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
myKeyHex := types.EncodeHex(crypto.FromECDSAPub(p.myPublicKey))
var theyJoined bool
var iJoined bool
for _, member := range chat.Members { for _, member := range chat.Members {
if member.ID == sigPubKeyHex { if member.ID == theirKeyHex && member.Joined {
theyJoined = true
}
}
for _, member := range chat.Members {
if member.ID == myKeyHex && member.Joined {
iJoined = true
}
}
if theyJoined && iJoined {
return chat, nil return chat, nil
} }
}
return nil, errors.New("did not find a matching group chat") return nil, errors.New("did not find a matching group chat")
default: default:
return nil, errors.New("can not match a chat because there is no valid case") return nil, errors.New("can not match a chat because there is no valid case")
@ -1098,7 +1313,7 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
} }
// Update contacts // Update contacts
var contacts []Contact var contacts []*Contact
for _, details := range ensResponse { for _, details := range ensResponse {
if details.Error == nil { if details.Error == nil {
contact, err := buildContact(details.PublicKey) contact, err := buildContact(details.PublicKey)
@ -1109,7 +1324,7 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
contact.ENSVerifiedAt = details.VerifiedAt contact.ENSVerifiedAt = details.VerifiedAt
contact.Name = details.Name contact.Name = details.Name
contacts = append(contacts, *contact) contacts = append(contacts, contact)
} else { } else {
m.logger.Warn("Failed to resolve ens name", m.logger.Warn("Failed to resolve ens name",
zap.String("name", details.Name), zap.String("name", details.Name),
@ -1133,8 +1348,3 @@ func (m *Messenger) VerifyENSNames(rpcEndpoint, contractAddress string, ensDetai
func GenerateAlias(id string) (string, error) { func GenerateAlias(id string) (string, error) {
return alias.GenerateFromPublicKeyString(id) return alias.GenerateFromPublicKeyString(id)
} }
// PrepareContent parses the content of a message and returns the parsed version
func (m *Messenger) PrepareContent(content v1protocol.Content) v1protocol.Content {
return v1protocol.PrepareContent(content)
}

View file

@ -1,15 +1,15 @@
// Code generated by go-bindata. DO NOT EDIT. // Code generated by go-bindata. DO NOT EDIT.
// sources: // sources:
// 000001_init.down.db.sql (82B) // 000001_init.down.db.sql (82B)
// 000001_init.up.db.sql (840B) // 000001_init.up.db.sql (832B)
// 000002_add_chats.down.db.sql (74B) // 000002_add_chats.down.db.sql (74B)
// 000002_add_chats.up.db.sql (599B) // 000002_add_chats.up.db.sql (495B)
// 000003_add_contacts.down.db.sql (21B) // 000003_add_contacts.down.db.sql (21B)
// 000003_add_contacts.up.db.sql (381B) // 000003_add_contacts.up.db.sql (381B)
// 000004_user_messages_compatibility.down.sql (33B) // 000004_user_messages_compatibility.down.sql (33B)
// 000004_user_messages_compatibility.up.sql (928B) // 000004_user_messages_compatibility.up.sql (980B)
// 1567112142_user_messages.down.sql (26B) // 1567112142_user_messages.down.sql (26B)
// 1567112142_user_messages.up.sql (551B) // 1567112142_user_messages.up.sql (543B)
// doc.go (377B) // doc.go (377B)
package migrations package migrations
@ -94,12 +94,12 @@ func _000001_initDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000001_init.down.db.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "000001_init.down.db.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe8, 0x5f, 0xe0, 0x6, 0xfc, 0xed, 0xb7, 0xff, 0xb5, 0xf3, 0x33, 0x45, 0x1, 0x5b, 0x84, 0x80, 0x74, 0x60, 0x81, 0xa6, 0x8b, 0xb4, 0xd4, 0xad, 0x10, 0xa8, 0xb3, 0x61, 0x6f, 0xc5, 0x2f, 0xaa}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe8, 0x5f, 0xe0, 0x6, 0xfc, 0xed, 0xb7, 0xff, 0xb5, 0xf3, 0x33, 0x45, 0x1, 0x5b, 0x84, 0x80, 0x74, 0x60, 0x81, 0xa6, 0x8b, 0xb4, 0xd4, 0xad, 0x10, 0xa8, 0xb3, 0x61, 0x6f, 0xc5, 0x2f, 0xaa}}
return a, nil return a, nil
} }
var __000001_initUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x52\xb1\x6e\xc2\x30\x14\xdc\xf3\x15\x6f\x24\x12\x43\xf7\x4e\x0e\xbc\x80\xd5\xd4\x6e\x1d\xa7\xc0\x14\x19\xe2\x82\x0b\x09\x11\x36\x52\xf9\xfb\xaa\x49\x8c\x02\x45\x15\xac\xef\xce\xe7\xbb\x7b\x6f\x24\x90\x48\x04\x49\xa2\x04\x81\xc6\xc0\xb8\x04\x9c\xd3\x54\xa6\x70\xb4\xfa\x90\x97\xda\x5a\xb5\xd6\x16\x06\x01\x00\x80\x29\x20\x4a\x78\x04\x19\xa3\xef\x19\x36\x6c\x96\x25\xc9\xb0\x01\x57\x1b\xe5\x72\x53\xc0\x07\x11\xa3\x29\x11\xd7\xe8\xbe\x72\xba\x72\xb9\x3b\xd5\xda\x53\x5a\xa4\xfb\xe3\x06\xe2\xf4\xb7\x03\x89\x73\xd9\x49\xec\xf6\xab\x2d\x44\x74\x42\x59\x37\x71\xa6\xd4\xd6\xa9\xb2\xbe\x98\xfa\xaf\xbc\xa1\x9e\x82\x37\x71\x29\x5c\x1f\x97\x3b\xb3\xca\xb7\xfa\xd4\xc4\x6b\x87\x9f\x3b\xb5\xb6\x40\x99\x3c\x07\x81\x31\xc6\x24\x4b\x24\x3c\x05\xe1\x73\x10\x74\xdd\x51\x36\xc6\xb9\x0f\x6f\x81\xb3\xcb\xe6\x06\x1d\xd2\x7b\x71\xab\xed\x52\x97\x4b\x7d\xb0\x1b\x53\xe7\xc7\xba\x50\xae\x5f\xb9\x2f\xf4\x4d\xd0\x57\x22\x16\xf0\x82\x8b\xab\x72\x0b\xe5\x54\xbb\x99\x47\x56\x12\x73\x81\x74\xc2\x1a\xbd\xb3\x4d\x10\x18\xa3\x40\x36\xc2\xb4\x79\x6e\x07\xa6\x08\x83\x10\x66\x54\x4e\x79\x26\x41\xf0\x19\x1d\xff\x9f\xa5\x91\xea\x02\x75\x29\xae\x1a\x7e\xc8\xa6\x2a\x4a\x53\x41\xc4\x79\x82\x84\xfd\x5d\x46\x4c\x92\x14\x5b\xe6\xd7\xde\x54\xba\xb8\x8b\x7a\x7f\xf6\x96\xdf\x5e\xbc\x67\x0e\x7b\x81\xc2\xdf\x63\xf8\x09\x00\x00\xff\xff\x66\xab\x2d\x2f\x48\x03\x00\x00") var __000001_initUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\xcd\x6e\xea\x30\x10\x85\xf7\x79\x8a\x59\x12\x89\xc5\xdd\xdf\x95\x03\x13\xb0\x9a\xda\xad\xe3\x14\x58\x45\x26\x71\xc1\x85\x84\x08\x1b\xa9\xbc\x7d\x45\x7e\x68\x48\xab\x0a\x96\x9e\x39\x3e\x9e\xef\x8c\x27\x02\x89\x44\x90\x24\x88\x10\x68\x08\x8c\x4b\xc0\x25\x8d\x65\x0c\x27\xab\x8f\x69\xa1\xad\x55\x1b\x6d\x61\xe4\x01\x00\x98\x1c\x82\x88\x07\x90\x30\xfa\x9a\x60\xad\x66\x49\x14\x8d\xeb\x66\xb6\x55\x2e\x35\x39\xbc\x11\x31\x99\x13\x31\xec\x1e\x4a\xa7\x4b\x97\xba\x73\xa5\x81\x32\xd9\x54\x5b\xff\x41\xd5\xe9\x4f\x07\x12\x97\xed\x31\xdb\x1f\xb2\x1d\x04\x74\xf6\x2d\x30\x85\xb6\x4e\x15\xd5\x4d\xb5\x7b\xa2\x1b\xa4\xe7\xd0\x3d\x7e\x6b\x5c\x9d\xd6\x7b\x93\xa5\x3b\x7d\xae\xb1\x9a\xe2\xfb\x5e\x6d\xec\x65\x96\x2b\x00\x4c\x31\x24\x49\x24\xe1\x9f\xe7\xff\xf7\xbc\x36\x33\xca\xa6\xb8\xec\xa0\x2d\x70\x76\x9b\xd8\xa8\xed\xf4\x6e\xfc\x96\x72\xa1\x8b\xb5\x3e\xda\xad\xa9\xd2\x53\x95\x2b\xd7\x8f\xba\x0b\xf2\x45\xd0\x67\x22\x56\xf0\x84\xab\x41\xa8\xb9\x72\xaa\xd9\xc8\x23\xab\x08\xb9\x40\x3a\x63\xb5\xdf\x75\x4c\x10\x18\xa2\x40\x36\xc1\xb8\xbe\x6e\x47\x26\xf7\x3d\x1f\x16\x54\xce\x79\x22\x41\xf0\x05\x9d\xfe\xcd\x52\x5b\xb5\x40\x2d\xc5\x20\xe1\x87\xc6\x54\x79\x61\x4a\x08\x38\x8f\x90\xb0\x9f\xcb\x08\x49\x14\x63\xa3\xfc\x38\x98\x52\xe7\x77\x49\xef\x67\x6f\xf4\xcd\x4f\xef\x94\xe3\x1e\x90\x7f\xf9\x0c\x5f\x01\x00\x00\xff\xff\x22\x17\x48\xa6\x40\x03\x00\x00")
func _000001_initUpDbSqlBytes() ([]byte, error) { func _000001_initUpDbSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -114,8 +114,8 @@ func _000001_initUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000001_init.up.db.sql", size: 840, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "000001_init.up.db.sql", size: 832, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe7, 0x27, 0x96, 0x3b, 0x72, 0x81, 0x7d, 0xba, 0xa4, 0xfb, 0xf7, 0x4, 0xd, 0x6f, 0xc8, 0x30, 0xfe, 0x47, 0xe0, 0x9, 0xf, 0x43, 0x13, 0x6, 0x55, 0xfc, 0xee, 0x15, 0x69, 0x99, 0x53, 0x3f}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1c, 0xa4, 0xac, 0x0, 0xd3, 0x19, 0x53, 0x35, 0x91, 0x1c, 0x94, 0xea, 0xde, 0xa7, 0x75, 0xb6, 0x73, 0x1d, 0x42, 0x14, 0xca, 0x84, 0x5b, 0xdb, 0x10, 0x94, 0x28, 0xc0, 0x33, 0x95, 0x7f, 0xf}}
return a, nil return a, nil
} }
@ -134,12 +134,12 @@ func _000002_add_chatsDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000002_add_chats.down.db.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1565597460, 0)} info := bindataFileInfo{name: "000002_add_chats.down.db.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0xa7, 0xf0, 0x94, 0x7a, 0x9, 0xdc, 0x6c, 0x7b, 0xdc, 0x12, 0x30, 0x55, 0x31, 0x17, 0xf2, 0xcc, 0x6e, 0xfd, 0xbb, 0x70, 0xb9, 0xd8, 0x9f, 0x81, 0x83, 0xdc, 0x1d, 0x1c, 0x3a, 0x8d, 0xce}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0xa7, 0xf0, 0x94, 0x7a, 0x9, 0xdc, 0x6c, 0x7b, 0xdc, 0x12, 0x30, 0x55, 0x31, 0x17, 0xf2, 0xcc, 0x6e, 0xfd, 0xbb, 0x70, 0xb9, 0xd8, 0x9f, 0x81, 0x83, 0xdc, 0x1d, 0x1c, 0x3a, 0x8d, 0xce}}
return a, nil return a, nil
} }
var __000002_add_chatsUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x92\x4f\x4b\x03\x31\x10\xc5\xef\xf3\x29\x06\x3c\x54\x21\x07\x3d\x88\x42\x4f\xd9\x6d\x8a\x8b\x71\x53\xd2\x54\xec\x29\xa4\xd9\xc1\x2e\xdd\x7f\x74\xb3\x95\x7e\x7b\x69\x5d\x6a\xff\x58\xf0\x98\xbc\xf7\x7b\x93\x17\x26\xd6\x82\x1b\x81\x86\x47\x52\x60\x32\xc6\x54\x19\x14\x1f\xc9\xd4\x4c\xd1\x2f\x5d\x68\xf1\x16\xf2\x0c\xdf\xb9\x8e\x5f\xb8\xc6\x89\x4e\xde\xb8\x9e\xe3\xab\x98\xa3\x4a\x31\x56\xe9\x58\x26\xb1\x41\x2d\x26\x92\xc7\x82\x41\xe5\x4a\x3a\xb8\x77\x59\xe9\x4c\x4a\x06\xbe\x2e\xea\xf5\xc5\x3d\x8e\xc4\x98\xcf\xa4\xc1\xc1\x8d\x7b\x78\x7e\xca\x1e\x07\x0c\xc2\xb6\x21\x4c\x52\x73\x04\x3b\x1f\xf2\x0d\x61\xa4\x94\x14\x3c\xbd\xa4\x8d\x9e\x09\x06\x21\x2f\xa9\x0d\xae\x6c\xce\xe8\x8c\x0a\x0a\x94\x59\x17\xac\x2f\x6a\xbf\xb2\x1b\x57\x74\xa7\x23\x0e\x49\xf7\x0c\x9a\x6e\x51\xe4\xde\xae\x68\x8b\x91\x54\x11\x83\xae\xda\xe4\xf4\x45\x99\x2d\xa9\x6d\xdd\x27\x59\x5f\x77\x55\xb8\xca\x17\xae\xfd\xdf\xa0\xbd\xf1\x37\xb3\x0a\x54\x05\xbb\x6f\xdf\x7f\xd3\xdf\x96\x2b\xea\x49\xfb\x73\xf2\xf4\x35\x0c\x4a\x2a\x17\xb4\x6e\xfb\x82\xfd\x69\x99\x37\xb6\x6b\x32\x17\xe8\x47\x80\xbb\x21\x00\x8c\xb4\x9a\xf4\xcb\x71\xe9\x1b\x1e\xcb\xbb\x6d\xb1\xbd\x67\x08\xdf\x01\x00\x00\xff\xff\x44\xe3\x59\x6f\x57\x02\x00\x00") var __000002_add_chatsUpDbSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x91\xc1\x6a\x32\x31\x14\x85\xf7\xf7\x29\x2e\xfc\x0b\xff\xc2\x2c\xda\x45\x69\xc1\x55\x66\x8c\x74\x68\x3a\x91\x18\x4b\x5d\x85\x98\xb9\xd4\xc1\xc4\x19\x4c\xc6\xe2\xdb\x17\xdb\x41\xb4\x52\xe8\x32\xb9\xdf\x77\xce\xe2\x14\x8a\x33\xcd\x51\xb3\x5c\x70\x2c\xa7\x58\x49\x8d\xfc\xad\x9c\xeb\x39\xba\xb5\x4d\x11\xff\x43\x53\xe3\x2b\x53\xc5\x13\x53\x38\x53\xe5\x0b\x53\x4b\x7c\xe6\x4b\x94\x15\x16\xb2\x9a\x8a\xb2\xd0\xa8\xf8\x4c\xb0\x82\x67\xb0\xb5\x81\x4e\xf4\x31\xab\x5a\x08\x91\x81\x6b\x7d\xbb\xbb\xfa\xc7\x09\x9f\xb2\x85\xd0\x38\xfa\x67\xef\x1e\x1f\xea\xfb\x51\x06\xe9\xd0\x11\x96\x95\x3e\x93\xad\x4b\xcd\x9e\x30\x97\x52\x70\x56\x5d\xdb\x5a\x2d\x78\x06\xa9\x09\x14\x93\x0d\xdd\x0f\xbb\x26\x4f\x89\x6a\x63\x93\x71\xbe\x75\x1b\xb3\xb7\xbe\xbf\xac\x38\x25\xdd\x66\xd0\xf5\x2b\xdf\x38\xb3\xa1\x03\xe6\x42\xe6\x19\xf4\xdb\x7d\x43\x1f\x54\x9b\x40\x31\xda\x77\x32\xae\xed\xb7\xe9\x57\xdf\xdb\xf8\xb7\xa2\x2f\x70\xc8\x1c\xaa\x02\x85\x15\xed\xe2\xe5\x6b\xdd\x74\xa6\xef\x6a\x9b\xe8\xfb\x00\x37\x63\x00\x98\x28\x39\x1b\x46\xbb\xe6\xc6\xe7\xe7\xe3\x8a\x66\x60\xc6\xf0\x19\x00\x00\xff\xff\x99\xae\x9f\xf2\xef\x01\x00\x00")
func _000002_add_chatsUpDbSqlBytes() ([]byte, error) { func _000002_add_chatsUpDbSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -154,8 +154,8 @@ func _000002_add_chatsUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000002_add_chats.up.db.sql", size: 599, mode: os.FileMode(0644), modTime: time.Unix(1572543168, 0)} info := bindataFileInfo{name: "000002_add_chats.up.db.sql", size: 495, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdb, 0xf, 0xef, 0x31, 0x64, 0x3, 0xf0, 0x58, 0x1e, 0xed, 0x1e, 0x7e, 0xce, 0x4, 0x20, 0x51, 0x79, 0xf9, 0xca, 0xc3, 0xb9, 0xc9, 0x60, 0x25, 0x2f, 0x6b, 0x99, 0xb1, 0x92, 0x6d, 0x56, 0x31}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6e, 0xca, 0x2b, 0xf7, 0xca, 0x21, 0xda, 0x17, 0x1f, 0x97, 0xa8, 0x12, 0xb5, 0x6c, 0xad, 0x92, 0xe7, 0x2, 0xaf, 0x1, 0xcb, 0x5e, 0xe9, 0x71, 0xc4, 0x81, 0xa7, 0x3, 0x93, 0x5b, 0x73, 0x73}}
return a, nil return a, nil
} }
@ -174,7 +174,7 @@ func _000003_add_contactsDownDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000003_add_contacts.down.db.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1565597570, 0)} info := bindataFileInfo{name: "000003_add_contacts.down.db.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0x7e, 0xb, 0xec, 0x72, 0xcd, 0x21, 0x3e, 0xa2, 0x38, 0xe0, 0x95, 0x7e, 0xce, 0x4a, 0x17, 0xc8, 0xd0, 0x1c, 0xfa, 0xa3, 0x23, 0x5, 0xab, 0x89, 0xf9, 0xfc, 0x63, 0x7, 0x28, 0xe9, 0x93}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0x7e, 0xb, 0xec, 0x72, 0xcd, 0x21, 0x3e, 0xa2, 0x38, 0xe0, 0x95, 0x7e, 0xce, 0x4a, 0x17, 0xc8, 0xd0, 0x1c, 0xfa, 0xa3, 0x23, 0x5, 0xab, 0x89, 0xf9, 0xfc, 0x63, 0x7, 0x28, 0xe9, 0x93}}
return a, nil return a, nil
} }
@ -194,7 +194,7 @@ func _000003_add_contactsUpDbSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000003_add_contacts.up.db.sql", size: 381, mode: os.FileMode(0644), modTime: time.Unix(1572543168, 0)} info := bindataFileInfo{name: "000003_add_contacts.up.db.sql", size: 381, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x45, 0xfe, 0x1e, 0xf2, 0x75, 0x33, 0x37, 0x8e, 0x7f, 0x93, 0x6f, 0x16, 0xbb, 0xf8, 0xa4, 0x70, 0x6b, 0xe0, 0xc1, 0x4f, 0x99, 0x8d, 0xc8, 0x2d, 0x40, 0xf1, 0xed, 0x65, 0x90, 0xc3, 0xad, 0xc7}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x45, 0xfe, 0x1e, 0xf2, 0x75, 0x33, 0x37, 0x8e, 0x7f, 0x93, 0x6f, 0x16, 0xbb, 0xf8, 0xa4, 0x70, 0x6b, 0xe0, 0xc1, 0x4f, 0x99, 0x8d, 0xc8, 0x2d, 0x40, 0xf1, 0xed, 0x65, 0x90, 0xc3, 0xad, 0xc7}}
return a, nil return a, nil
} }
@ -214,12 +214,12 @@ func _000004_user_messages_compatibilityDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000004_user_messages_compatibility.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1565631683, 0)} info := bindataFileInfo{name: "000004_user_messages_compatibility.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0xaf, 0x48, 0x80, 0x3d, 0x54, 0x5e, 0x53, 0xee, 0x98, 0x26, 0xbb, 0x99, 0x6a, 0xd8, 0x37, 0x94, 0xf2, 0xf, 0x82, 0xfa, 0xb7, 0x6a, 0x68, 0xcd, 0x8b, 0xe2, 0xc4, 0x6, 0x25, 0xdc, 0x6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0xaf, 0x48, 0x80, 0x3d, 0x54, 0x5e, 0x53, 0xee, 0x98, 0x26, 0xbb, 0x99, 0x6a, 0xd8, 0x37, 0x94, 0xf2, 0xf, 0x82, 0xfa, 0xb7, 0x6a, 0x68, 0xcd, 0x8b, 0xe2, 0xc4, 0x6, 0x25, 0xdc, 0x6}}
return a, nil return a, nil
} }
var __000004_user_messages_compatibilityUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x92\xcf\x6e\xe2\x3c\x14\xc5\xf7\x3c\xc5\xd9\x01\x12\xf9\xd4\x45\xd5\x4d\x57\x81\x9a\x6f\xa2\xc9\x24\x55\x30\x23\xba\xb2\x4c\xb8\x43\xac\x49\x6c\x64\xdf\x0c\x13\xa9\x0f\x3f\xa2\x84\xaa\x61\xe8\x6a\xb2\xc8\xc2\xbf\x73\xec\x73\xff\x44\x11\x12\x1e\x07\x98\xe6\xe0\x3c\x6b\xcb\xe0\x4a\x9f\x7e\x26\x80\xf5\xb6\x26\x54\x3a\xc0\xbb\xa3\xd9\x41\x07\x1c\x09\x9e\xea\x0e\xce\xc2\xf0\x28\x8a\x70\xac\xc8\x9e\xcc\x35\x35\x64\xd9\xd8\x3d\x8c\xfd\x61\xac\x61\x8a\x42\xe9\x5d\x5d\xff\x37\x5a\x14\x22\x96\x02\x32\x9e\xa7\x02\xc9\x12\x59\x2e\x21\x36\xc9\x4a\xae\xd0\x06\xf2\xaa\xa1\x10\xf4\x9e\x82\xaa\x69\xaf\xcb\x0e\x93\x11\x00\x98\x1d\xbe\xc7\xc5\xe2\x4b\x5c\xe0\xb9\x48\xbe\xc5\xc5\x0b\xbe\x8a\x17\xe4\x19\x16\x79\xb6\x4c\x93\x85\x44\x21\x9e\xd3\x78\x21\x66\x6f\xfa\x63\x65\xc2\x81\xbc\x62\xd3\x50\x60\xdd\x1c\x90\x64\x52\xfc\x2f\x8a\xb7\xf7\xb2\x75\x9a\x9e\x75\xc1\xb5\xbe\x24\x48\xb1\x91\x57\x64\x47\x81\x8d\xd5\x6c\x9c\xc5\x3c\xcd\xe7\xe7\xd3\xd2\x59\x26\xcb\xef\x61\x86\x9e\x9e\x2a\xee\x0e\xf4\x89\xe4\x54\xa3\xd5\xcd\x3b\x3e\x9f\x0e\x62\x5e\x5f\x5a\x69\x56\x1f\xea\x1f\x52\x4f\xec\x3b\x55\xba\xd6\xf2\xc0\x8b\x27\xb1\x8c\xd7\xa9\xc4\xdd\x45\x77\xa8\x3b\xc5\x6e\xf8\x6e\xdf\xec\x41\xe0\x21\x09\xac\xb9\x0d\x43\x56\xd6\xae\xfc\xa9\x7e\xe9\xba\xa5\x1b\x79\x43\xe5\x8e\x98\xe7\x79\x2a\xe2\xec\xef\x38\xb2\x58\xf7\x23\x0a\x44\xf6\x73\xdd\x32\x4e\x57\xbd\xd0\xb5\xbc\x77\xc6\xee\xaf\xb2\x8c\xa6\x8f\xa3\xcb\x36\x25\xd9\x93\xd8\xc0\xec\x7e\xab\x7e\xa0\x79\x76\x73\x9b\x26\x67\x3c\x7d\xbc\x61\x24\xed\xcb\x4a\x6d\x3b\x75\x69\x78\x9e\xe1\xf6\x25\xe7\xf8\xed\x36\xb0\x9f\x8c\xef\xfe\xf1\x1b\xe3\xf5\xf5\x63\x47\x67\x88\x1e\xee\x67\x78\xb8\x9f\x9e\x80\xd9\xcd\x2e\x0b\x70\xaa\xf7\x4f\x00\x00\x00\xff\xff\xe0\x0c\x93\xa2\xa0\x03\x00\x00") var __000004_user_messages_compatibilityUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x52\xc1\x6e\xda\x40\x10\xbd\xf3\x15\x73\x0b\x48\xb8\xca\x21\xca\x25\x27\x43\x96\xd6\xaa\x6b\x47\xc6\xa9\xc8\x69\xb5\xd8\x53\xbc\x62\xbd\x6b\xed\x8c\x4b\x2c\xe5\xe3\x2b\x03\x26\x40\x51\x2f\xf5\xc1\x87\x79\x33\x6f\xde\xdb\x79\x41\x00\x11\xdf\x11\xe8\xba\x71\x9e\x95\x65\xe0\x4a\xf5\x3f\x4d\xc0\x6a\x6d\x10\x2a\x45\xe0\xdd\x4e\x97\xa0\x08\x76\x08\x1e\x4d\x07\xce\x82\xe6\x51\x10\xc0\xae\x42\xdb\x0f\x1b\xac\xd1\xb2\xb6\x1b\xd0\xf6\x97\xb6\x9a\x31\xa0\xc2\x3b\x63\xbe\x8c\xe6\x99\x08\x73\x01\x79\x38\x8b\x05\x44\x0b\x48\xd2\x1c\xc4\x2a\x5a\xe6\x4b\x68\x09\xbd\xac\x91\x48\x6d\x90\xa4\xc1\x8d\x2a\x3a\x18\x8f\x00\x00\x74\x09\x3f\xc3\x6c\xfe\x2d\xcc\xe0\x25\x8b\x7e\x84\xd9\x1b\x7c\x17\x6f\x90\x26\x30\x4f\x93\x45\x1c\xcd\x73\xc8\xc4\x4b\x1c\xce\xc5\x74\xdf\xbf\xab\x34\x35\xe8\x25\xeb\x1a\x89\x55\xdd\x40\x94\xe4\xe2\xab\xc8\xf6\xfb\x92\xd7\x38\x3e\xf4\x91\x6b\x7d\x81\x90\x8b\x55\x7e\x85\x94\x48\xac\xad\x62\xed\x2c\xcc\xe2\x74\x76\xa8\x32\xbe\xf3\x49\xc9\xe5\x40\xe1\x2c\xa3\x65\xc9\x5d\x83\xfd\xb6\x2b\xb8\x37\x67\x55\x8d\xc3\xf4\x91\xef\x5c\xdf\x35\x61\xa5\x58\x9e\x19\xbf\x44\x8d\x2b\x94\x91\xff\xee\xf1\xc8\xbe\x93\x85\x6b\x2d\x5f\xf0\xc3\xb3\x58\x84\xaf\x71\x0e\xf7\x43\x1f\x35\xce\x12\x4a\x76\x97\xf2\x8e\xc7\x38\x79\x3a\x0a\x33\xae\xd8\xca\xdf\xca\xb4\xb7\x8c\x12\xa2\x85\x59\x9a\xc6\x22\x4c\xfe\xde\xb8\x08\xe3\xe5\xf1\x46\xae\xe5\x8d\xd3\x76\x23\x89\x15\xb7\x74\xb9\xb9\x51\x9e\xb0\x94\xfb\xf7\xfe\x7c\x7e\xaf\x76\xb2\x51\x9d\x71\xaa\x3c\xab\x12\xeb\x62\x8b\x5e\x36\xaa\xd8\x7e\xaa\x1c\xaa\x95\xa2\x6a\xe0\x1e\x4d\x9e\x46\x43\x02\xa3\xe4\x59\xac\x40\x97\xef\xf2\x18\x82\x34\xb9\x99\xc0\xf1\x01\x9e\x3c\xdd\x18\x44\xe5\x8b\x4a\xae\xbb\xd3\x1d\xd2\x04\x6e\x93\x1c\x24\xb5\x6b\x62\x3f\xbe\xbb\xff\xcf\xef\x0e\x3e\x3e\xce\xaf\x30\x85\xe0\xf1\x61\x0a\x8f\x0f\x93\x1e\xd0\xe5\x74\xc8\x4e\xef\xf7\x4f\x00\x00\x00\xff\xff\x91\x46\x82\xd5\xd4\x03\x00\x00")
func _000004_user_messages_compatibilityUpSqlBytes() ([]byte, error) { func _000004_user_messages_compatibilityUpSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -234,8 +234,8 @@ func _000004_user_messages_compatibilityUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "000004_user_messages_compatibility.up.sql", size: 928, mode: os.FileMode(0644), modTime: time.Unix(1569474812, 0)} info := bindataFileInfo{name: "000004_user_messages_compatibility.up.sql", size: 980, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x60, 0x6c, 0x7f, 0xfb, 0xb3, 0x30, 0xd8, 0xbf, 0x6, 0x4a, 0x4a, 0xec, 0x9e, 0xd7, 0xa, 0x5e, 0x8, 0xbb, 0xf8, 0x11, 0x97, 0x80, 0xd3, 0xfa, 0x2c, 0x1e, 0x82, 0xb2, 0xe2, 0xe7, 0x6e, 0xa}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x7a, 0xba, 0xae, 0x6d, 0xef, 0x69, 0x12, 0x6b, 0x48, 0xe3, 0xa7, 0xad, 0x21, 0x4a, 0xcf, 0x4f, 0xbc, 0x14, 0xc1, 0x19, 0x69, 0x1c, 0xc, 0xa2, 0x3d, 0xbc, 0x12, 0x32, 0x71, 0x76, 0x15}}
return a, nil return a, nil
} }
@ -254,12 +254,12 @@ func _1567112142_user_messagesDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1567112142_user_messages.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1568961800, 0)} info := bindataFileInfo{name: "1567112142_user_messages.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x79, 0x8e, 0xbe, 0x63, 0x64, 0x52, 0xa3, 0x13, 0x83, 0xc7, 0x47, 0xff, 0x56, 0xa9, 0xc, 0x72, 0xb4, 0x97, 0x6, 0xc7, 0xa5, 0x68, 0xb6, 0x55, 0x6a, 0xd5, 0xb0, 0x12, 0xfb, 0x4c, 0xa5, 0x27}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x79, 0x8e, 0xbe, 0x63, 0x64, 0x52, 0xa3, 0x13, 0x83, 0xc7, 0x47, 0xff, 0x56, 0xa9, 0xc, 0x72, 0xb4, 0x97, 0x6, 0xc7, 0xa5, 0x68, 0xb6, 0x55, 0x6a, 0xd5, 0xb0, 0x12, 0xfb, 0x4c, 0xa5, 0x27}}
return a, nil return a, nil
} }
var __1567112142_user_messagesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x90\x51\x6f\x9b\x30\x14\x85\xdf\xf9\x15\xe7\xad\xad\xb4\x54\x7b\xef\x13\x01\x67\x43\x42\x64\x23\xce\xd6\xb7\xc8\xd8\xb7\xc5\x8a\xb1\x11\xbe\x2c\xe5\xdf\x4f\xa1\xb0\x2d\x53\x5f\xcf\x77\xfd\xdd\x73\xbd\xd9\x20\x1f\x42\x0f\xe5\x27\xf4\x03\xfd\xb2\x61\x8c\x6e\x82\x1e\x48\x31\x19\x8c\x91\x86\x53\x47\x31\xaa\x57\x8a\x60\xd5\x38\x7a\x4c\x36\x1b\xfc\x24\x98\xe0\xef\x18\x9e\xc8\x80\x03\x22\xab\x09\x8d\xd2\xe7\x8b\x1a\x0c\x74\xe8\x7a\xc5\xb6\x71\x84\x8b\xe5\x16\x96\xaf\x8f\x1a\xd2\x6a\x8c\x04\xcb\x77\x11\x3e\xf0\xd5\x6e\xae\x9b\x2f\x2d\x0d\x04\x7a\xd3\xd4\x33\x5e\xc2\x00\x6e\x09\x3a\xf8\x18\x1c\x41\x3b\x4b\x9e\x1f\x93\xbc\xde\x7f\x83\x4c\xb7\xa5\xb8\x6d\xf5\x94\x24\x59\x2d\x52\x29\x16\x58\xec\x50\xed\x25\xc4\x73\x71\x90\x87\xff\x0e\xb8\x4f\x00\xc0\x1a\x6c\xcb\xfd\x16\xc7\xaa\xf8\x7e\x14\xf3\x74\x75\x2c\xcb\x4f\x33\xd4\xad\xe2\x93\x35\xf8\x91\xd6\xd9\xd7\xb4\xfe\x43\x51\x8b\x9d\xa8\x45\x95\x89\xc3\x3c\x13\xef\xad\x79\xc0\xbe\x42\x2e\x4a\x21\x05\xb2\xf4\x90\xa5\xb9\x58\x24\xc1\x33\x79\x3e\xf1\xd4\xd3\x6a\x7a\x27\x4b\x95\x0f\x08\xd3\x1b\x43\x8a\x67\xb9\x28\x5c\xd0\x67\x6c\x8b\x2f\x45\xb5\x24\x6c\x3b\x8a\xac\xba\xfe\x26\x5d\x57\xad\xbd\xff\x31\xac\x25\x6e\xc5\xfd\xd8\x38\xab\x4f\x67\x9a\xe6\x5f\x78\x0f\x5f\x9c\x7a\x8d\x28\x2a\xf9\xf7\xde\x5c\xec\xd2\x63\x29\xf1\x39\x79\x78\x4a\x7e\x07\x00\x00\xff\xff\x07\x0e\xee\x5c\x27\x02\x00\x00") var __1567112142_user_messagesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x4f\x4d\x73\x9b\x30\x14\xbc\xf3\x2b\xf6\x96\x64\xa6\xce\xf4\x9e\x13\x06\xb9\x65\x86\xc1\x2d\x96\xdb\xdc\x3c\x42\x7a\x09\x1a\x0b\x89\x41\x8f\x3a\xfc\xfb\x0e\x04\x37\x75\x8e\x6f\x77\xdf\x7e\x6c\x36\xc8\x87\xd0\x43\xf9\x09\xfd\x40\x7f\x6c\x18\xa3\x9b\xa0\x07\x52\x4c\x06\x63\xa4\xe1\xd4\x51\x8c\xea\x95\x22\x58\x35\x8e\x1e\x93\xcd\x06\xbf\x09\x26\xf8\x3b\x86\x27\x32\xe0\x80\xc8\x6a\x42\xa3\xf4\xf9\xa2\x06\x03\x1d\xba\x5e\xb1\x6d\x1c\xe1\x62\xb9\x85\xe5\xf9\xa9\x21\xad\xc6\x48\xb0\x7c\x17\xe1\x03\xcf\xee\x66\x4e\xbe\xb4\x34\x10\xe8\x4d\x53\xcf\x78\x09\x03\xb8\x25\xe8\xe0\x63\x70\x04\xed\x2c\x79\x7e\x4c\xf2\x7a\xff\x03\x32\xdd\x96\xe2\xb6\xd5\x53\x92\x64\xb5\x48\xa5\x58\xc9\x62\x87\x6a\x2f\x21\x9e\x8b\x83\x3c\x7c\x1a\x70\x9f\x00\x80\x35\xd8\x96\xfb\x2d\x8e\x55\xf1\xf3\x28\x16\x75\x75\x2c\xcb\x2f\x0b\xa9\x5b\xc5\x27\x6b\xf0\x2b\xad\xb3\xef\x69\xfd\x8f\x45\x2d\x76\xa2\x16\x55\x26\x0e\x8b\x26\xde\x5b\xf3\x80\x7d\x85\x5c\x94\x42\x0a\x64\xe9\x21\x4b\x73\xb1\x9a\x04\xcf\xe4\xf9\xc4\x53\x4f\x28\x2a\xf9\x8e\xae\x35\x3e\xa1\x4c\x6f\x0c\x29\x9e\xd7\x53\xbb\xa0\xcf\xd8\x16\xdf\x3e\x04\xb6\xa3\xc8\xaa\xeb\x6f\xd0\x6b\xc4\xb5\xef\x7f\x0e\xd7\xf0\x5b\xe3\x7e\x6c\x9c\xd5\xa7\x33\x4d\xcb\xfa\x77\xf0\xc5\xa9\xd7\x38\x77\xf9\xd8\x99\x8b\x5d\x7a\x2c\x25\xbe\x26\x0f\x4f\xc9\xdf\x00\x00\x00\xff\xff\x6e\x1c\xcd\x6f\x1f\x02\x00\x00")
func _1567112142_user_messagesUpSqlBytes() ([]byte, error) { func _1567112142_user_messagesUpSqlBytes() ([]byte, error) {
return bindataRead( return bindataRead(
@ -274,8 +274,8 @@ func _1567112142_user_messagesUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1567112142_user_messages.up.sql", size: 551, mode: os.FileMode(0644), modTime: time.Unix(1568961800, 0)} info := bindataFileInfo{name: "1567112142_user_messages.up.sql", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1575009877, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7a, 0x11, 0x2, 0x79, 0x3b, 0xc5, 0x37, 0xe7, 0x3f, 0xa9, 0x35, 0x99, 0xa5, 0x3f, 0x32, 0xa3, 0xbe, 0xf7, 0x53, 0xf3, 0xea, 0x72, 0xbd, 0xb, 0xfc, 0xa7, 0xdc, 0x97, 0x1c, 0x6, 0x71, 0x16}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xff, 0xc0, 0x47, 0x32, 0xa9, 0xa4, 0x6, 0x63, 0x6b, 0xe7, 0x79, 0x2b, 0x80, 0x52, 0x2b, 0x6f, 0xf9, 0x9d, 0x9a, 0xc2, 0xa9, 0x7a, 0xf7, 0x4d, 0x14, 0x12, 0x21, 0x10, 0xc4, 0x30, 0x42, 0xaa}}
return a, nil return a, nil
} }
@ -294,7 +294,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}}
return a, nil return a, nil
} }
@ -454,17 +454,17 @@ type bintree struct {
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"000001_init.down.db.sql": {_000001_initDownDbSql, map[string]*bintree{}}, "000001_init.down.db.sql": &bintree{_000001_initDownDbSql, map[string]*bintree{}},
"000001_init.up.db.sql": {_000001_initUpDbSql, map[string]*bintree{}}, "000001_init.up.db.sql": &bintree{_000001_initUpDbSql, map[string]*bintree{}},
"000002_add_chats.down.db.sql": {_000002_add_chatsDownDbSql, map[string]*bintree{}}, "000002_add_chats.down.db.sql": &bintree{_000002_add_chatsDownDbSql, map[string]*bintree{}},
"000002_add_chats.up.db.sql": {_000002_add_chatsUpDbSql, map[string]*bintree{}}, "000002_add_chats.up.db.sql": &bintree{_000002_add_chatsUpDbSql, map[string]*bintree{}},
"000003_add_contacts.down.db.sql": {_000003_add_contactsDownDbSql, map[string]*bintree{}}, "000003_add_contacts.down.db.sql": &bintree{_000003_add_contactsDownDbSql, map[string]*bintree{}},
"000003_add_contacts.up.db.sql": {_000003_add_contactsUpDbSql, map[string]*bintree{}}, "000003_add_contacts.up.db.sql": &bintree{_000003_add_contactsUpDbSql, map[string]*bintree{}},
"000004_user_messages_compatibility.down.sql": {_000004_user_messages_compatibilityDownSql, map[string]*bintree{}}, "000004_user_messages_compatibility.down.sql": &bintree{_000004_user_messages_compatibilityDownSql, map[string]*bintree{}},
"000004_user_messages_compatibility.up.sql": {_000004_user_messages_compatibilityUpSql, map[string]*bintree{}}, "000004_user_messages_compatibility.up.sql": &bintree{_000004_user_messages_compatibilityUpSql, map[string]*bintree{}},
"1567112142_user_messages.down.sql": {_1567112142_user_messagesDownSql, map[string]*bintree{}}, "1567112142_user_messages.down.sql": &bintree{_1567112142_user_messagesDownSql, map[string]*bintree{}},
"1567112142_user_messages.up.sql": {_1567112142_user_messagesUpSql, map[string]*bintree{}}, "1567112142_user_messages.up.sql": &bintree{_1567112142_user_messagesUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}
// RestoreAsset restores an asset under the given directory. // RestoreAsset restores an asset under the given directory.

View file

@ -6,12 +6,9 @@ import (
"database/sql" "database/sql"
"encoding/gob" "encoding/gob"
"encoding/hex" "encoding/hex"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
v1protocol "github.com/status-im/status-go/protocol/v1"
) )
var ( var (
@ -24,21 +21,46 @@ type sqlitePersistence struct {
db *sql.DB db *sql.DB
} }
func (db sqlitePersistence) LastMessageClock(chatID string) (int64, error) {
if chatID == "" {
return 0, errors.New("chat ID is empty")
}
var last sql.NullInt64
err := db.db.QueryRow("SELECT max(clock) FROM user_messages WHERE chat_id = ?", chatID).Scan(&last)
if err != nil {
return 0, err
}
return last.Int64, nil
}
func (db sqlitePersistence) SaveChat(chat Chat) error { func (db sqlitePersistence) SaveChat(chat Chat) error {
return db.saveChat(nil, chat)
}
func (db sqlitePersistence) SaveChats(chats []*Chat) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
for _, chat := range chats {
err := db.saveChat(tx, *chat)
if err != nil {
return err
}
}
return nil
}
func (db sqlitePersistence) saveChat(tx *sql.Tx, chat Chat) error {
var err error var err error
if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
}
pkey := []byte{} pkey := []byte{}
// For one to one chatID is an encoded public key // For one to one chatID is an encoded public key
@ -72,8 +94,8 @@ func (db sqlitePersistence) SaveChat(chat Chat) error {
} }
// Insert record // Insert record
stmt, err := db.db.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, public_key, unviewed_message_count, last_clock_value, last_message_content_type, last_message_content, last_message_timestamp, last_message_clock_value, members, membership_updates) stmt, err := tx.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, public_key, unviewed_message_count, last_clock_value, last_message, members, membership_updates)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
if err != nil { if err != nil {
return err return err
} }
@ -90,10 +112,7 @@ func (db sqlitePersistence) SaveChat(chat Chat) error {
pkey, pkey,
chat.UnviewedMessagesCount, chat.UnviewedMessagesCount,
chat.LastClockValue, chat.LastClockValue,
chat.LastMessageContentType, chat.LastMessage,
chat.LastMessageContent,
chat.LastMessageTimestamp,
chat.LastMessageClockValue,
encodedMembers.Bytes(), encodedMembers.Bytes(),
encodedMembershipUpdates.Bytes(), encodedMembershipUpdates.Bytes(),
) )
@ -141,10 +160,7 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
public_key, public_key,
unviewed_message_count, unviewed_message_count,
last_clock_value, last_clock_value,
last_message_content_type, last_message,
last_message_content,
last_message_timestamp,
last_message_clock_value,
members, members,
membership_updates membership_updates
FROM chats FROM chats
@ -157,11 +173,6 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
for rows.Next() { for rows.Next() {
var ( var (
lastMessageContentType sql.NullString
lastMessageContent sql.NullString
lastMessageTimestamp sql.NullInt64
lastMessageClockValue sql.NullInt64
chat Chat chat Chat
encodedMembers []byte encodedMembers []byte
encodedMembershipUpdates []byte encodedMembershipUpdates []byte
@ -178,20 +189,13 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
&pkey, &pkey,
&chat.UnviewedMessagesCount, &chat.UnviewedMessagesCount,
&chat.LastClockValue, &chat.LastClockValue,
&lastMessageContentType, &chat.LastMessage,
&lastMessageContent,
&lastMessageTimestamp,
&lastMessageClockValue,
&encodedMembers, &encodedMembers,
&encodedMembershipUpdates, &encodedMembershipUpdates,
) )
if err != nil { if err != nil {
return return
} }
chat.LastMessageContent = lastMessageContent.String
chat.LastMessageContentType = lastMessageContentType.String
chat.LastMessageTimestamp = lastMessageTimestamp.Int64
chat.LastMessageClockValue = lastMessageClockValue.Int64
// Restore members // Restore members
membersDecoder := gob.NewDecoder(bytes.NewBuffer(encodedMembers)) membersDecoder := gob.NewDecoder(bytes.NewBuffer(encodedMembers))
@ -289,7 +293,7 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
return response, nil return response, nil
} }
func (db sqlitePersistence) SetContactsENSData(contacts []Contact) error { func (db sqlitePersistence) SetContactsENSData(contacts []*Contact) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
return err return err
@ -323,7 +327,7 @@ func (db sqlitePersistence) SetContactsENSData(contacts []Contact) error {
// SetContactsGeneratedData sets a contact generated data if not existing already // SetContactsGeneratedData sets a contact generated data if not existing already
// in the database // in the database
func (db sqlitePersistence) SetContactsGeneratedData(contacts []Contact, tx *sql.Tx) (err error) { func (db sqlitePersistence) SetContactsGeneratedData(contacts []*Contact, tx *sql.Tx) (err error) {
if tx == nil { if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
@ -435,109 +439,3 @@ func (db sqlitePersistence) SaveContact(contact Contact, tx *sql.Tx) (err error)
) )
return return
} }
// Messages returns messages for a given contact, in a given period. Ordered by a timestamp.
func (db sqlitePersistence) Messages(from, to time.Time) (result []*v1protocol.Message, err error) {
rows, err := db.db.Query(`
SELECT
id,
chat_id,
content_type,
message_type,
text,
clock,
timestamp,
content_chat_id,
content_text,
public_key,
flags
FROM user_messages
WHERE timestamp >= ? AND timestamp <= ?
ORDER BY timestamp`,
v1protocol.TimestampInMsFromTime(from),
v1protocol.TimestampInMsFromTime(to),
)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
msg := v1protocol.Message{
Content: v1protocol.Content{},
}
var pkey []byte
err = rows.Scan(
&msg.ID, &msg.ChatID, &msg.ContentT, &msg.MessageT, &msg.Text, &msg.Clock,
&msg.Timestamp, &msg.Content.ChatID, &msg.Content.Text, &pkey, &msg.Flags,
)
if err != nil {
return
}
if len(pkey) != 0 {
msg.SigPubKey, err = crypto.UnmarshalPubkey(pkey)
if err != nil {
return
}
}
result = append(result, &msg)
}
return
}
func (db sqlitePersistence) SaveMessages(messages []*v1protocol.Message) (last int64, err error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
stmt, err := tx.Prepare(`
INSERT OR IGNORE INTO user_messages(
id,
chat_id,
content_type,
message_type,
text,
clock,
timestamp,
content_chat_id,
content_text,
public_key,
flags
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`)
if err != nil {
return
}
var rst sql.Result
for _, msg := range messages {
var pkey []byte
if msg.SigPubKey != nil {
pkey = crypto.FromECDSAPub(msg.SigPubKey)
}
rst, err = stmt.Exec(
msg.ID, msg.ChatID, msg.ContentT, msg.MessageT, msg.Text, msg.Clock, msg.Timestamp,
msg.Content.ChatID, msg.Content.Text, pkey, msg.Flags,
)
if err != nil {
return
}
last, err = rst.LastInsertId()
if err != nil {
return
}
}
return
}

View file

@ -3,7 +3,9 @@ package protocol
import ( import (
"context" "context"
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"github.com/status-im/status-go/protocol/protobuf"
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -17,42 +19,46 @@ func (db sqlitePersistence) tableUserMessagesLegacyAllFields() string {
return `id, return `id,
whisper_timestamp, whisper_timestamp,
source, source,
destination, text,
content,
content_type, content_type,
username, username,
timestamp, timestamp,
chat_id, chat_id,
local_chat_id,
retry_count, retry_count,
message_type, message_type,
message_status,
clock_value, clock_value,
show,
seen, seen,
outgoing_status, outgoing_status,
reply_to` parsed_text,
raw_payload,
sticker_pack,
sticker_hash,
response_to`
} }
func (db sqlitePersistence) tableUserMessagesLegacyAllFieldsJoin() string { func (db sqlitePersistence) tableUserMessagesLegacyAllFieldsJoin() string {
return `m1.id, return `m1.id,
m1.whisper_timestamp, m1.whisper_timestamp,
m1.source, m1.source,
m1.destination, m1.text,
m1.content,
m1.content_type, m1.content_type,
m1.username, m1.username,
m1.timestamp, m1.timestamp,
m1.chat_id, m1.chat_id,
m1.local_chat_id,
m1.retry_count, m1.retry_count,
m1.message_type, m1.message_type,
m1.message_status,
m1.clock_value, m1.clock_value,
m1.show,
m1.seen, m1.seen,
m1.outgoing_status, m1.outgoing_status,
m1.reply_to, m1.parsed_text,
m1.raw_payload,
m1.sticker_pack,
m1.sticker_hash,
m1.response_to,
m2.source, m2.source,
m2.content, m2.text,
c.alias, c.alias,
c.identicon` c.identicon`
} }
@ -66,30 +72,35 @@ type scanner interface {
} }
func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, message *Message, others ...interface{}) error { func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, message *Message, others ...interface{}) error {
var quotedContent sql.NullString var quotedText sql.NullString
var quotedFrom sql.NullString var quotedFrom sql.NullString
var alias sql.NullString var alias sql.NullString
var identicon sql.NullString var identicon sql.NullString
sticker := &protobuf.StickerMessage{}
args := []interface{}{ args := []interface{}{
&message.ID, &message.ID,
&message.WhisperTimestamp, &message.WhisperTimestamp,
&message.From, // source in table &message.From, // source in table
&message.To, // destination in table &message.Text,
&message.Content,
&message.ContentType, &message.ContentType,
&message.Alias, &message.Alias,
&message.Timestamp, &message.Timestamp,
&message.ChatID, &message.ChatId,
&message.LocalChatID,
&message.RetryCount, &message.RetryCount,
&message.MessageType, &message.MessageType,
&message.MessageStatus, &message.Clock,
&message.ClockValue,
&message.Show,
&message.Seen, &message.Seen,
&message.OutgoingStatus, &message.OutgoingStatus,
&message.ReplyTo, &message.ParsedText,
&message.RawPayload,
&sticker.Pack,
&sticker.Hash,
&message.ResponseTo,
&quotedFrom, &quotedFrom,
&quotedContent, &quotedText,
&alias, &alias,
&identicon, &identicon,
} }
@ -98,45 +109,70 @@ func (db sqlitePersistence) tableUserMessagesLegacyScanAllFields(row scanner, me
return err return err
} }
if quotedContent.Valid { if quotedText.Valid {
message.QuotedMessage = &QuotedMessage{ message.QuotedMessage = &QuotedMessage{
From: quotedFrom.String, From: quotedFrom.String,
Content: quotedContent.String, Text: quotedText.String,
} }
} }
message.Alias = alias.String message.Alias = alias.String
message.Identicon = identicon.String message.Identicon = identicon.String
if message.ContentType == protobuf.ChatMessage_STICKER {
message.Payload = &protobuf.ChatMessage_Sticker{Sticker: sticker}
}
return nil return nil
} }
func (db sqlitePersistence) tableUserMessagesLegacyAllValues(message *Message) []interface{} { func (db sqlitePersistence) tableUserMessagesLegacyAllValues(message *Message) ([]interface{}, error) {
sticker := message.GetSticker()
if sticker == nil {
sticker = &protobuf.StickerMessage{}
}
return []interface{}{ return []interface{}{
message.ID, message.ID,
message.WhisperTimestamp, message.WhisperTimestamp,
message.From, // source in table message.From, // source in table
message.To, // destination in table message.Text,
message.Content,
message.ContentType, message.ContentType,
message.Alias, message.Alias,
message.Timestamp, message.Timestamp,
message.ChatID, message.ChatId,
message.LocalChatID,
message.RetryCount, message.RetryCount,
message.MessageType, message.MessageType,
message.MessageStatus, message.Clock,
message.ClockValue,
message.Show,
message.Seen, message.Seen,
message.OutgoingStatus, message.OutgoingStatus,
message.ReplyTo, message.ParsedText,
} message.RawPayload,
sticker.Pack,
sticker.Hash,
message.ResponseTo,
}, nil
}
func (db sqlitePersistence) messageByID(tx *sql.Tx, id string) (*Message, error) {
var err error
if tx == nil {
tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return nil, err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
} }
func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
var message Message var message Message
allFields := db.tableUserMessagesLegacyAllFieldsJoin() allFields := db.tableUserMessagesLegacyAllFieldsJoin()
row := db.db.QueryRow( row := tx.QueryRow(
fmt.Sprintf(` fmt.Sprintf(`
SELECT SELECT
%s %s
@ -145,7 +181,7 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
LEFT JOIN LEFT JOIN
user_messages_legacy m2 user_messages_legacy m2
ON ON
m1.reply_to = m2.id m1.response_to = m2.id
LEFT JOIN LEFT JOIN
contacts c contacts c
@ -156,7 +192,7 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
`, allFields), `, allFields),
id, id,
) )
err := db.tableUserMessagesLegacyScanAllFields(row, &message) err = db.tableUserMessagesLegacyScanAllFields(row, &message)
switch err { switch err {
case sql.ErrNoRows: case sql.ErrNoRows:
return nil, errRecordNotFound return nil, errRecordNotFound
@ -167,6 +203,10 @@ func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
} }
} }
func (db sqlitePersistence) MessageByID(id string) (*Message, error) {
return db.messageByID(nil, id)
}
func (db sqlitePersistence) MessagesExist(ids []string) (map[string]bool, error) { func (db sqlitePersistence) MessagesExist(ids []string) (map[string]bool, error) {
result := make(map[string]bool) result := make(map[string]bool)
if len(ids) == 0 { if len(ids) == 0 {
@ -224,7 +264,7 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
LEFT JOIN LEFT JOIN
user_messages_legacy m2 user_messages_legacy m2
ON ON
m1.reply_to = m2.id m1.response_to = m2.id
LEFT JOIN LEFT JOIN
contacts c contacts c
@ -232,7 +272,7 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
m1.source = c.id m1.source = c.id
WHERE WHERE
m1.chat_id = ? %s m1.local_chat_id = ? %s
ORDER BY cursor DESC ORDER BY cursor DESC
LIMIT ? LIMIT ?
`, allFields, cursorWhere), `, allFields, cursorWhere),
@ -290,7 +330,13 @@ func (db sqlitePersistence) SaveMessagesLegacy(messages []*Message) (err error)
} }
for _, msg := range messages { for _, msg := range messages {
_, err = stmt.Exec(db.tableUserMessagesLegacyAllValues(msg)...) var allValues []interface{}
allValues, err = db.tableUserMessagesLegacyAllValues(msg)
if err != nil {
return
}
_, err = stmt.Exec(allValues...)
if err != nil { if err != nil {
return return
} }
@ -304,24 +350,49 @@ func (db sqlitePersistence) DeleteMessage(id string) error {
} }
func (db sqlitePersistence) DeleteMessagesByChatID(id string) error { func (db sqlitePersistence) DeleteMessagesByChatID(id string) error {
_, err := db.db.Exec(`DELETE FROM user_messages_legacy WHERE chat_id = ?`, id) _, err := db.db.Exec(`DELETE FROM user_messages_legacy WHERE local_chat_id = ?`, id)
return err return err
} }
func (db sqlitePersistence) MarkMessagesSeen(ids ...string) error { func (db sqlitePersistence) MarkMessagesSeen(chatID string, ids []string) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()
idsArgs := make([]interface{}, 0, len(ids)) idsArgs := make([]interface{}, 0, len(ids))
for _, id := range ids { for _, id := range ids {
idsArgs = append(idsArgs, id) idsArgs = append(idsArgs, id)
} }
inVector := strings.Repeat("?, ", len(ids)-1) + "?" inVector := strings.Repeat("?, ", len(ids)-1) + "?"
_, err := db.db.Exec( _, err = tx.Exec(
fmt.Sprintf(` fmt.Sprintf(`
UPDATE user_messages_legacy UPDATE user_messages_legacy
SET seen = 1 SET seen = 1
WHERE id IN (%s) WHERE id IN (%s)
`, inVector), `, inVector),
idsArgs...) idsArgs...)
if err != nil {
return err
}
// Update denormalized count
_, err = tx.Exec(
`UPDATE chats
SET unviewed_message_count =
(SELECT COUNT(1)
FROM user_messages_legacy
WHERE local_chat_id = ? AND seen = 0)
WHERE id = ?`, chatID, chatID)
return err return err
} }
@ -335,10 +406,11 @@ func (db sqlitePersistence) UpdateMessageOutgoingStatus(id string, newOutgoingSt
} }
// BlockContact updates a contact, deletes all the messages and 1-to-1 chat, updates the unread messages count and returns a map with the new count // BlockContact updates a contact, deletes all the messages and 1-to-1 chat, updates the unread messages count and returns a map with the new count
func (db sqlitePersistence) BlockContact(contact Contact) (chats []*Chat, err error) { func (db sqlitePersistence) BlockContact(contact Contact) ([]*Chat, error) {
var chats []*Chat
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil { if err != nil {
return return nil, err
} }
defer func() { defer func() {
if err == nil { if err == nil {
@ -357,36 +429,69 @@ func (db sqlitePersistence) BlockContact(contact Contact) (chats []*Chat, err er
contact.ID, contact.ID,
) )
if err != nil { if err != nil {
return return nil, err
} }
// Update contact // Update contact
err = db.SaveContact(contact, tx) err = db.SaveContact(contact, tx)
if err != nil { if err != nil {
return return nil, err
} }
// Delete one-to-one chat // Delete one-to-one chat
_, err = tx.Exec("DELETE FROM chats WHERE id = ?", contact.ID) _, err = tx.Exec("DELETE FROM chats WHERE id = ?", contact.ID)
if err != nil { if err != nil {
return return nil, err
} }
// Recalculate denormalized fields // Recalculate denormalized fields
_, err = tx.Exec(` _, err = tx.Exec(`
UPDATE chats UPDATE chats
SET SET
unviewed_message_count = (SELECT COUNT(1) FROM user_messages_legacy WHERE seen = 0 AND chat_id = chats.id), unviewed_message_count = (SELECT COUNT(1) FROM user_messages_legacy WHERE seen = 0 AND local_chat_id = chats.id)`)
last_message_content = (SELECT content from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_timestamp = (SELECT timestamp from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_clock_value = (SELECT clock_value from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1),
last_message_content_type = (SELECT content_type from user_messages_legacy WHERE chat_id = chats.id ORDER BY clock_value DESC LIMIT 1)
`)
if err != nil { if err != nil {
return return nil, err
} }
// return the updated chats // return the updated chats
chats, err = db.chats(tx) chats, err = db.chats(tx)
return if err != nil {
return nil, err
}
for _, c := range chats {
var lastMessageID string
row := tx.QueryRow(`SELECT id FROM user_messages_legacy WHERE local_chat_id = ? ORDER BY clock_value DESC LIMIT 1`, c.ID)
switch err := row.Scan(&lastMessageID); err {
case nil:
message, err := db.messageByID(tx, lastMessageID)
if err != nil {
return nil, err
}
if message != nil {
encodedMessage, err := json.Marshal(message)
if err != nil {
return nil, err
}
_, err = tx.Exec(`UPDATE chats SET last_message = ? WHERE id = ?`, encodedMessage, c.ID)
if err != nil {
return nil, err
}
c.LastMessage = encodedMessage
}
case sql.ErrNoRows:
// Reset LastMessage
_, err = tx.Exec(`UPDATE chats SET last_message = NULL WHERE id = ?`, c.ID)
if err != nil {
return nil, err
}
c.LastMessage = nil
default:
return nil, err
}
}
return chats, err
} }

View file

@ -0,0 +1,421 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: message.proto
package protobuf
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type ChatMessage_MessageType int32
const (
ChatMessage_ONE_TO_ONE ChatMessage_MessageType = 0
ChatMessage_PUBLIC_GROUP ChatMessage_MessageType = 1
ChatMessage_PRIVATE_GROUP ChatMessage_MessageType = 2
// Only local
ChatMessage_SYSTEM_MESSAGE_PRIVATE_GROUP ChatMessage_MessageType = 3
)
var ChatMessage_MessageType_name = map[int32]string{
0: "ONE_TO_ONE",
1: "PUBLIC_GROUP",
2: "PRIVATE_GROUP",
3: "SYSTEM_MESSAGE_PRIVATE_GROUP",
}
var ChatMessage_MessageType_value = map[string]int32{
"ONE_TO_ONE": 0,
"PUBLIC_GROUP": 1,
"PRIVATE_GROUP": 2,
"SYSTEM_MESSAGE_PRIVATE_GROUP": 3,
}
func (x ChatMessage_MessageType) String() string {
return proto.EnumName(ChatMessage_MessageType_name, int32(x))
}
func (ChatMessage_MessageType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1, 0}
}
type ChatMessage_ContentType int32
const (
ChatMessage_TEXT_PLAIN ChatMessage_ContentType = 0
ChatMessage_STICKER ChatMessage_ContentType = 1
ChatMessage_STATUS ChatMessage_ContentType = 2
ChatMessage_EMOJI ChatMessage_ContentType = 3
ChatMessage_COMMAND ChatMessage_ContentType = 4
ChatMessage_COMMAND_REQUEST ChatMessage_ContentType = 5
)
var ChatMessage_ContentType_name = map[int32]string{
0: "TEXT_PLAIN",
1: "STICKER",
2: "STATUS",
3: "EMOJI",
4: "COMMAND",
5: "COMMAND_REQUEST",
}
var ChatMessage_ContentType_value = map[string]int32{
"TEXT_PLAIN": 0,
"STICKER": 1,
"STATUS": 2,
"EMOJI": 3,
"COMMAND": 4,
"COMMAND_REQUEST": 5,
}
func (x ChatMessage_ContentType) String() string {
return proto.EnumName(ChatMessage_ContentType_name, int32(x))
}
func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1, 1}
}
type ApplicationMetadataMessage_MessageType int32
const (
ApplicationMetadataMessage_TEXT_MESSAGE ApplicationMetadataMessage_MessageType = 0
ApplicationMetadataMessage_CONTACT_REQUEST ApplicationMetadataMessage_MessageType = 1
ApplicationMetadataMessage_MEMBERSHIP_UPDATE ApplicationMetadataMessage_MessageType = 2
ApplicationMetadataMessage_PAIR_INSTALLATION ApplicationMetadataMessage_MessageType = 3
ApplicationMetadataMessage_SYNC_INSTALLATION ApplicationMetadataMessage_MessageType = 4
)
var ApplicationMetadataMessage_MessageType_name = map[int32]string{
0: "TEXT_MESSAGE",
1: "CONTACT_REQUEST",
2: "MEMBERSHIP_UPDATE",
3: "PAIR_INSTALLATION",
4: "SYNC_INSTALLATION",
}
var ApplicationMetadataMessage_MessageType_value = map[string]int32{
"TEXT_MESSAGE": 0,
"CONTACT_REQUEST": 1,
"MEMBERSHIP_UPDATE": 2,
"PAIR_INSTALLATION": 3,
"SYNC_INSTALLATION": 4,
}
func (x ApplicationMetadataMessage_MessageType) String() string {
return proto.EnumName(ApplicationMetadataMessage_MessageType_name, int32(x))
}
func (ApplicationMetadataMessage_MessageType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{2, 0}
}
type StickerMessage struct {
Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Pack int32 `protobuf:"varint,2,opt,name=pack,proto3" json:"pack,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StickerMessage) Reset() { *m = StickerMessage{} }
func (m *StickerMessage) String() string { return proto.CompactTextString(m) }
func (*StickerMessage) ProtoMessage() {}
func (*StickerMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{0}
}
func (m *StickerMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StickerMessage.Unmarshal(m, b)
}
func (m *StickerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StickerMessage.Marshal(b, m, deterministic)
}
func (m *StickerMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_StickerMessage.Merge(m, src)
}
func (m *StickerMessage) XXX_Size() int {
return xxx_messageInfo_StickerMessage.Size(m)
}
func (m *StickerMessage) XXX_DiscardUnknown() {
xxx_messageInfo_StickerMessage.DiscardUnknown(m)
}
var xxx_messageInfo_StickerMessage proto.InternalMessageInfo
func (m *StickerMessage) GetHash() string {
if m != nil {
return m.Hash
}
return ""
}
func (m *StickerMessage) GetPack() int32 {
if m != nil {
return m.Pack
}
return 0
}
type ChatMessage struct {
// Lamport timestamp of the chat message
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
// Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
// so that we don't rely on it
Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// Text of the message
Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"`
// Id of the message that we are replying to
ResponseTo string `protobuf:"bytes,4,opt,name=response_to,json=responseTo,proto3" json:"response_to,omitempty"`
// Ens name of the sender
EnsName string `protobuf:"bytes,5,opt,name=ens_name,json=ensName,proto3" json:"ens_name,omitempty"`
// Chat id, this field is symmetric for public-chats and private group chats,
// but asymmetric in case of one-to-ones, as the sender will use the chat-id
// of the received, while the receiver will use the chat-id of the sender.
// Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
ChatId string `protobuf:"bytes,6,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"`
// The type of message (public/one-to-one/private-group-chat)
MessageType ChatMessage_MessageType `protobuf:"varint,7,opt,name=message_type,json=messageType,proto3,enum=protobuf.ChatMessage_MessageType" json:"message_type,omitempty"`
// The type of the content of the message
ContentType ChatMessage_ContentType `protobuf:"varint,8,opt,name=content_type,json=contentType,proto3,enum=protobuf.ChatMessage_ContentType" json:"content_type,omitempty"`
// Types that are valid to be assigned to Payload:
// *ChatMessage_Sticker
Payload isChatMessage_Payload `protobuf_oneof:"payload"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ChatMessage) Reset() { *m = ChatMessage{} }
func (m *ChatMessage) String() string { return proto.CompactTextString(m) }
func (*ChatMessage) ProtoMessage() {}
func (*ChatMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{1}
}
func (m *ChatMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChatMessage.Unmarshal(m, b)
}
func (m *ChatMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ChatMessage.Marshal(b, m, deterministic)
}
func (m *ChatMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_ChatMessage.Merge(m, src)
}
func (m *ChatMessage) XXX_Size() int {
return xxx_messageInfo_ChatMessage.Size(m)
}
func (m *ChatMessage) XXX_DiscardUnknown() {
xxx_messageInfo_ChatMessage.DiscardUnknown(m)
}
var xxx_messageInfo_ChatMessage proto.InternalMessageInfo
func (m *ChatMessage) GetClock() uint64 {
if m != nil {
return m.Clock
}
return 0
}
func (m *ChatMessage) GetTimestamp() uint64 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *ChatMessage) GetText() string {
if m != nil {
return m.Text
}
return ""
}
func (m *ChatMessage) GetResponseTo() string {
if m != nil {
return m.ResponseTo
}
return ""
}
func (m *ChatMessage) GetEnsName() string {
if m != nil {
return m.EnsName
}
return ""
}
func (m *ChatMessage) GetChatId() string {
if m != nil {
return m.ChatId
}
return ""
}
func (m *ChatMessage) GetMessageType() ChatMessage_MessageType {
if m != nil {
return m.MessageType
}
return ChatMessage_ONE_TO_ONE
}
func (m *ChatMessage) GetContentType() ChatMessage_ContentType {
if m != nil {
return m.ContentType
}
return ChatMessage_TEXT_PLAIN
}
type isChatMessage_Payload interface {
isChatMessage_Payload()
}
type ChatMessage_Sticker struct {
Sticker *StickerMessage `protobuf:"bytes,9,opt,name=sticker,proto3,oneof"`
}
func (*ChatMessage_Sticker) isChatMessage_Payload() {}
func (m *ChatMessage) GetPayload() isChatMessage_Payload {
if m != nil {
return m.Payload
}
return nil
}
func (m *ChatMessage) GetSticker() *StickerMessage {
if x, ok := m.GetPayload().(*ChatMessage_Sticker); ok {
return x.Sticker
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ChatMessage) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*ChatMessage_Sticker)(nil),
}
}
type ApplicationMetadataMessage struct {
// Signature of the payload field
Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
// This is the encoded protobuf of the application level message, i.e ChatMessage
Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
// The type of protobuf message sent
MessageType ApplicationMetadataMessage_MessageType `protobuf:"varint,3,opt,name=message_type,json=messageType,proto3,enum=protobuf.ApplicationMetadataMessage_MessageType" json:"message_type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ApplicationMetadataMessage) Reset() { *m = ApplicationMetadataMessage{} }
func (m *ApplicationMetadataMessage) String() string { return proto.CompactTextString(m) }
func (*ApplicationMetadataMessage) ProtoMessage() {}
func (*ApplicationMetadataMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_33c57e4bae7b9afd, []int{2}
}
func (m *ApplicationMetadataMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ApplicationMetadataMessage.Unmarshal(m, b)
}
func (m *ApplicationMetadataMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ApplicationMetadataMessage.Marshal(b, m, deterministic)
}
func (m *ApplicationMetadataMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_ApplicationMetadataMessage.Merge(m, src)
}
func (m *ApplicationMetadataMessage) XXX_Size() int {
return xxx_messageInfo_ApplicationMetadataMessage.Size(m)
}
func (m *ApplicationMetadataMessage) XXX_DiscardUnknown() {
xxx_messageInfo_ApplicationMetadataMessage.DiscardUnknown(m)
}
var xxx_messageInfo_ApplicationMetadataMessage proto.InternalMessageInfo
func (m *ApplicationMetadataMessage) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *ApplicationMetadataMessage) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func (m *ApplicationMetadataMessage) GetMessageType() ApplicationMetadataMessage_MessageType {
if m != nil {
return m.MessageType
}
return ApplicationMetadataMessage_TEXT_MESSAGE
}
func init() {
proto.RegisterEnum("protobuf.ChatMessage_MessageType", ChatMessage_MessageType_name, ChatMessage_MessageType_value)
proto.RegisterEnum("protobuf.ChatMessage_ContentType", ChatMessage_ContentType_name, ChatMessage_ContentType_value)
proto.RegisterEnum("protobuf.ApplicationMetadataMessage_MessageType", ApplicationMetadataMessage_MessageType_name, ApplicationMetadataMessage_MessageType_value)
proto.RegisterType((*StickerMessage)(nil), "protobuf.StickerMessage")
proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage")
proto.RegisterType((*ApplicationMetadataMessage)(nil), "protobuf.ApplicationMetadataMessage")
}
func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) }
var fileDescriptor_33c57e4bae7b9afd = []byte{
// 563 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x5f, 0x6f, 0xda, 0x3e,
0x14, 0x25, 0x10, 0xa0, 0xdc, 0xd0, 0xfe, 0x5c, 0xff, 0x36, 0x2d, 0x9b, 0x2a, 0x8d, 0xf1, 0xc4,
0x13, 0x9a, 0xba, 0x3d, 0xec, 0x35, 0x4d, 0xad, 0x36, 0x1b, 0xf9, 0x33, 0xdb, 0x4c, 0xeb, 0x93,
0xe5, 0x06, 0xaf, 0xa0, 0x96, 0x24, 0x22, 0xae, 0x34, 0xbe, 0xcf, 0x3e, 0xc9, 0x3e, 0xd9, 0x14,
0x07, 0x0a, 0x4c, 0xea, 0x9e, 0xec, 0x73, 0x7c, 0x7d, 0xee, 0xbd, 0xe7, 0x5e, 0x38, 0x5e, 0xaa,
0xb2, 0x94, 0x77, 0x6a, 0x5c, 0xac, 0x72, 0x9d, 0xe3, 0x23, 0x73, 0xdc, 0x3e, 0xfe, 0x18, 0x7e,
0x82, 0x13, 0xa6, 0x17, 0xe9, 0xbd, 0x5a, 0x85, 0x75, 0x04, 0xc6, 0x60, 0xcf, 0x65, 0x39, 0x77,
0xad, 0x81, 0x35, 0xea, 0x51, 0x73, 0xaf, 0xb8, 0x42, 0xa6, 0xf7, 0x6e, 0x73, 0x60, 0x8d, 0xda,
0xd4, 0xdc, 0x87, 0xbf, 0x6d, 0x70, 0xfc, 0xb9, 0xd4, 0xdb, 0x7f, 0x2f, 0xa0, 0x9d, 0x3e, 0xe4,
0xe9, 0xbd, 0xf9, 0x68, 0xd3, 0x1a, 0xe0, 0x33, 0xe8, 0xe9, 0xc5, 0x52, 0x95, 0x5a, 0x2e, 0x0b,
0xf3, 0xdd, 0xa6, 0x3b, 0xa2, 0xd2, 0xd5, 0xea, 0xa7, 0x76, 0x5b, 0x75, 0xae, 0xea, 0x8e, 0xdf,
0x82, 0xb3, 0x52, 0x65, 0x91, 0x67, 0xa5, 0x12, 0x3a, 0x77, 0x6d, 0xf3, 0x04, 0x5b, 0x8a, 0xe7,
0xf8, 0x35, 0x1c, 0xa9, 0xac, 0x14, 0x99, 0x5c, 0x2a, 0xb7, 0x6d, 0x5e, 0xbb, 0x2a, 0x2b, 0x23,
0xb9, 0x54, 0xf8, 0x15, 0x74, 0xd3, 0xb9, 0xd4, 0x62, 0x31, 0x73, 0x3b, 0xe6, 0xa5, 0x53, 0xc1,
0x60, 0x86, 0x2f, 0xa1, 0xbf, 0x71, 0x40, 0xe8, 0x75, 0xa1, 0xdc, 0xee, 0xc0, 0x1a, 0x9d, 0x9c,
0xbf, 0x1b, 0x6f, 0x7d, 0x18, 0xef, 0x75, 0x32, 0xde, 0x9c, 0x7c, 0x5d, 0x28, 0xea, 0x2c, 0x77,
0xa0, 0x52, 0x49, 0xf3, 0x4c, 0xab, 0x4c, 0xd7, 0x2a, 0x47, 0xff, 0x52, 0xf1, 0xeb, 0xc8, 0x5a,
0x25, 0xdd, 0x01, 0xfc, 0x11, 0xba, 0x65, 0x6d, 0xb9, 0xdb, 0x1b, 0x58, 0x23, 0xe7, 0xdc, 0xdd,
0x09, 0x1c, 0xce, 0xe2, 0xba, 0x41, 0xb7, 0xa1, 0xc3, 0x19, 0x38, 0x7b, 0x75, 0xe1, 0x13, 0x80,
0x38, 0x22, 0x82, 0xc7, 0x22, 0x8e, 0x08, 0x6a, 0x60, 0x04, 0xfd, 0x64, 0x7a, 0x31, 0x09, 0x7c,
0x71, 0x45, 0xe3, 0x69, 0x82, 0x2c, 0x7c, 0x0a, 0xc7, 0x09, 0x0d, 0xbe, 0x79, 0x9c, 0x6c, 0xa8,
0x26, 0x1e, 0xc0, 0x19, 0xbb, 0x61, 0x9c, 0x84, 0x22, 0x24, 0x8c, 0x79, 0x57, 0x44, 0x1c, 0x46,
0xb4, 0x86, 0x29, 0x38, 0x7b, 0x75, 0x57, 0x59, 0x38, 0xf9, 0xce, 0x45, 0x32, 0xf1, 0x82, 0x08,
0x35, 0xb0, 0x03, 0x5d, 0xc6, 0x03, 0xff, 0x0b, 0xa1, 0xc8, 0xc2, 0x00, 0x1d, 0xc6, 0x3d, 0x3e,
0x65, 0xa8, 0x89, 0x7b, 0xd0, 0x26, 0x61, 0xfc, 0x39, 0x40, 0xad, 0x2a, 0xc6, 0x8f, 0xc3, 0xd0,
0x8b, 0x2e, 0x91, 0x8d, 0xff, 0x87, 0xff, 0x36, 0x40, 0x50, 0xf2, 0x75, 0x4a, 0x18, 0x47, 0xed,
0x8b, 0x1e, 0x74, 0x0b, 0xb9, 0x7e, 0xc8, 0xe5, 0x6c, 0xf8, 0xab, 0x09, 0x6f, 0xbc, 0xa2, 0x78,
0x58, 0xa4, 0x52, 0x2f, 0xf2, 0x2c, 0x54, 0x5a, 0xce, 0xa4, 0x96, 0xdb, 0x9d, 0x3a, 0x83, 0x5e,
0xb9, 0xb8, 0xcb, 0xa4, 0x7e, 0x5c, 0x29, 0xb3, 0x57, 0x7d, 0xba, 0x23, 0xb0, 0xfb, 0xa4, 0x63,
0x36, 0xab, 0x4f, 0xb7, 0x10, 0xb3, 0xbf, 0xc6, 0xdd, 0x32, 0x83, 0x7a, 0xbf, 0xf3, 0xf9, 0xf9,
0x9c, 0xcf, 0x4e, 0x7f, 0xb8, 0x3e, 0x9c, 0x00, 0x82, 0xbe, 0xf1, 0x66, 0x63, 0x25, 0x6a, 0xd4,
0xcd, 0x46, 0xdc, 0xf3, 0xf9, 0x53, 0xb3, 0x16, 0x7e, 0x09, 0xa7, 0x21, 0x09, 0x2f, 0x08, 0x65,
0xd7, 0x41, 0x22, 0xa6, 0xc9, 0xa5, 0xc7, 0x09, 0x6a, 0x56, 0x74, 0xe2, 0x05, 0x54, 0x04, 0x11,
0xe3, 0xde, 0x64, 0xe2, 0xf1, 0x20, 0x8e, 0x50, 0xab, 0xa2, 0xd9, 0x4d, 0xe4, 0x1f, 0xd2, 0xf6,
0x6d, 0xc7, 0x14, 0xfe, 0xe1, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xa4, 0x11, 0xfe, 0xc7,
0x03, 0x00, 0x00,
}

View file

@ -0,0 +1,70 @@
syntax = "proto3";
package protobuf;
message StickerMessage {
string hash = 1;
int32 pack = 2;
}
message ChatMessage {
// Lamport timestamp of the chat message
uint64 clock = 1;
// Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
// so that we don't rely on it
uint64 timestamp = 2;
// Text of the message
string text = 3;
// Id of the message that we are replying to
string response_to = 4;
// Ens name of the sender
string ens_name = 5;
// Chat id, this field is symmetric for public-chats and private group chats,
// but asymmetric in case of one-to-ones, as the sender will use the chat-id
// of the received, while the receiver will use the chat-id of the sender.
// Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
string chat_id = 6;
// The type of message (public/one-to-one/private-group-chat)
MessageType message_type = 7;
// The type of the content of the message
ContentType content_type = 8;
oneof payload {
StickerMessage sticker = 9;
}
enum MessageType {
ONE_TO_ONE = 0;
PUBLIC_GROUP = 1;
PRIVATE_GROUP = 2;
// Only local
SYSTEM_MESSAGE_PRIVATE_GROUP = 3;
}
enum ContentType {
TEXT_PLAIN = 0;
STICKER = 1;
STATUS = 2;
EMOJI = 3;
COMMAND = 4;
COMMAND_REQUEST = 5;
}
}
message ApplicationMetadataMessage {
// Signature of the payload field
bytes signature = 1;
// This is the encoded protobuf of the application level message, i.e ChatMessage
bytes payload = 2;
// The type of protobuf message sent
MessageType message_type = 3;
enum MessageType {
TEXT_MESSAGE = 0;
CONTACT_REQUEST = 1;
MEMBERSHIP_UPDATE = 2;
PAIR_INSTALLATION = 3;
SYNC_INSTALLATION = 4;
}
}

View file

@ -0,0 +1,22 @@
package protobuf
import (
"crypto/ecdsa"
"github.com/status-im/status-go/eth-node/crypto"
)
func (m *ApplicationMetadataMessage) RecoverKey() (*ecdsa.PublicKey, error) {
if m.Signature == nil {
return nil, nil
}
recoveredKey, err := crypto.SigToPub(
crypto.Keccak256(m.Payload),
m.Signature,
)
if err != nil {
return nil, err
}
return recoveredKey, nil
}

View file

@ -0,0 +1,17 @@
package protobuf
import (
"github.com/golang/protobuf/proto"
)
//go:generate protoc --go_out=. ./message.proto
func Unmarshal(payload []byte) (*ApplicationMetadataMessage, error) {
var message ApplicationMetadataMessage
err := proto.Unmarshal(payload, &message)
if err != nil {
return nil, err
}
return &message, nil
}

View file

@ -96,14 +96,11 @@ func newFiltersManager(db *sql.DB, w types.Whisper, privateKey *ecdsa.PrivateKey
func (s *filtersManager) Init( func (s *filtersManager) Init(
chatIDs []string, chatIDs []string,
publicKeys []*ecdsa.PublicKey, publicKeys []*ecdsa.PublicKey,
genericDiscoveryTopicEnabled bool,
) ([]*Filter, error) { ) ([]*Filter, error) {
logger := s.logger.With(zap.String("site", "Init")) logger := s.logger.With(zap.String("site", "Init"))
logger.Info("initializing") logger.Info("initializing")
s.genericDiscoveryTopicEnabled = genericDiscoveryTopicEnabled
// Load our contact code. // Load our contact code.
_, err := s.LoadContactCode(&s.privateKey.PublicKey) _, err := s.LoadContactCode(&s.privateKey.PublicKey)
if err != nil { if err != nil {
@ -148,7 +145,7 @@ func (s *filtersManager) Init(
} }
// DEPRECATED // DEPRECATED
func (s *filtersManager) InitWithFilters(filters []*Filter, genericDiscoveryTopicEnabled bool) ([]*Filter, error) { func (s *filtersManager) InitWithFilters(filters []*Filter) ([]*Filter, error) {
var ( var (
chatIDs []string chatIDs []string
publicKeys []*ecdsa.PublicKey publicKeys []*ecdsa.PublicKey
@ -166,7 +163,7 @@ func (s *filtersManager) InitWithFilters(filters []*Filter, genericDiscoveryTopi
} }
} }
return s.Init(chatIDs, publicKeys, genericDiscoveryTopicEnabled) return s.Init(chatIDs, publicKeys)
} }
func (s *filtersManager) Reset() error { func (s *filtersManager) Reset() error {
@ -315,8 +312,8 @@ func (s *filtersManager) LoadNegotiated(secret types.NegotiatedSecret) (*Filter,
return chat, nil return chat, nil
} }
// LoadDiscovery adds 1-2 discovery filters: one for generic discovery topic (if enabled) // LoadDiscovery adds 1 discovery filter
// and one for the personal discovery topic. // for the personal discovery topic.
func (s *filtersManager) LoadDiscovery() ([]*Filter, error) { func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -328,12 +325,6 @@ func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
expectedTopicCount := 1 expectedTopicCount := 1
if s.genericDiscoveryTopicEnabled {
expectedTopicCount = 2
if chat, ok := s.filters[discoveryTopic]; ok {
result = append(result, chat)
}
}
if chat, ok := s.filters[personalDiscoveryTopic]; ok { if chat, ok := s.filters[personalDiscoveryTopic]; ok {
result = append(result, chat) result = append(result, chat)
} }
@ -365,29 +356,6 @@ func (s *filtersManager) LoadDiscovery() ([]*Filter, error) {
s.filters[personalDiscoveryChat.ChatID] = personalDiscoveryChat s.filters[personalDiscoveryChat.ChatID] = personalDiscoveryChat
if s.genericDiscoveryTopicEnabled {
// Load generic discovery topic.
discoveryChat := &Filter{
ChatID: discoveryTopic,
Identity: identityStr,
Discovery: true,
Listen: true,
OneToOne: true,
}
discoveryResponse, err = s.addAsymmetric(discoveryChat.ChatID, true)
if err != nil {
return nil, err
}
discoveryChat.Topic = discoveryResponse.Topic
discoveryChat.FilterID = discoveryResponse.FilterID
s.filters[discoveryChat.ChatID] = discoveryChat
return []*Filter{discoveryChat, personalDiscoveryChat}, nil
}
return []*Filter{personalDiscoveryChat}, nil return []*Filter{personalDiscoveryChat}, nil
} }

View file

@ -86,7 +86,7 @@ func _1561059285_add_whisper_keysDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x31, 0x3f, 0xce, 0xfa, 0x44, 0x36, 0x1b, 0xb0, 0xec, 0x5d, 0xb, 0x90, 0xb, 0x21, 0x4f, 0xd5, 0xe5, 0x50, 0xed, 0xc7, 0x43, 0xdf, 0x83, 0xb4, 0x3a, 0xc1, 0x55, 0x2e, 0x53, 0x7c, 0x67}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x31, 0x3f, 0xce, 0xfa, 0x44, 0x36, 0x1b, 0xb0, 0xec, 0x5d, 0xb, 0x90, 0xb, 0x21, 0x4f, 0xd5, 0xe5, 0x50, 0xed, 0xc7, 0x43, 0xdf, 0x83, 0xb4, 0x3a, 0xc1, 0x55, 0x2e, 0x53, 0x7c, 0x67}}
return a, nil return a, nil
} }
@ -106,7 +106,7 @@ func _1561059285_add_whisper_keysUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x25, 0x41, 0xc, 0x92, 0xdd, 0x9e, 0xff, 0x5d, 0xd0, 0x93, 0xe4, 0x24, 0x50, 0x29, 0xcf, 0xc6, 0xf7, 0x49, 0x3c, 0x73, 0xd9, 0x8c, 0xfa, 0xf2, 0xcf, 0xf6, 0x6f, 0xbc, 0x31, 0xe6, 0xf7, 0xe2}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x25, 0x41, 0xc, 0x92, 0xdd, 0x9e, 0xff, 0x5d, 0xd0, 0x93, 0xe4, 0x24, 0x50, 0x29, 0xcf, 0xc6, 0xf7, 0x49, 0x3c, 0x73, 0xd9, 0x8c, 0xfa, 0xf2, 0xcf, 0xf6, 0x6f, 0xbc, 0x31, 0xe6, 0xf7, 0xe2}}
return a, nil return a, nil
} }
@ -126,7 +126,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1564484687, 0)} info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1574354941, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}}
return a, nil return a, nil
} }
@ -270,9 +270,9 @@ type bintree struct {
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"1561059285_add_whisper_keys.down.sql": {_1561059285_add_whisper_keysDownSql, map[string]*bintree{}}, "1561059285_add_whisper_keys.down.sql": &bintree{_1561059285_add_whisper_keysDownSql, map[string]*bintree{}},
"1561059285_add_whisper_keys.up.sql": {_1561059285_add_whisper_keysUpSql, map[string]*bintree{}}, "1561059285_add_whisper_keys.up.sql": &bintree{_1561059285_add_whisper_keysUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}
// RestoreAsset restores an asset under the given directory. // RestoreAsset restores an asset under the given directory.

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