diff --git a/VERSION b/VERSION index d4ca2c6b1..4f7eae858 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.0-beta.0 +0.27.0-beta.1 diff --git a/node/status_node_test.go b/node/status_node_test.go index 394f646f9..283399bf5 100644 --- a/node/status_node_test.go +++ b/node/status_node_test.go @@ -373,7 +373,7 @@ func TestChaosModeCheckRPCClientsUpstreamURL(t *testing.T) { // assert err = client.Call(nil, "net_version") - require.EqualError(t, err, `500 Internal Server Error "500 Internal Server Error"`) + require.EqualError(t, err, `500 Internal Server Error {"code": 500, "description": "Internal Server Error"}`) // act err = n.ChaosModeCheckRPCClientsUpstreamURL(false) diff --git a/services/shhext/chat/db/migrations/bindata.go b/services/shhext/chat/db/migrations/bindata.go index 86ceda0bc..afb375175 100644 --- a/services/shhext/chat/db/migrations/bindata.go +++ b/services/shhext/chat/db/migrations/bindata.go @@ -13,6 +13,8 @@ // 1558588866_add_version.up.sql // 1559627659_add_contact_code.down.sql // 1559627659_add_contact_code.up.sql +// 1561059285_add_whisper_keys.down.sql +// 1561059285_add_whisper_keys.up.sql // static.go // DO NOT EDIT! @@ -96,7 +98,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -116,7 +118,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -136,7 +138,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,7 +158,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -176,7 +178,7 @@ func _1540715431_add_versionDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -196,7 +198,7 @@ func _1540715431_add_versionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -216,7 +218,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -236,7 +238,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -256,7 +258,7 @@ func _1558084410_add_secretDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(420), modTime: time.Unix(1560418252, 0)} + info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -276,7 +278,7 @@ func _1558084410_add_secretUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(420), modTime: time.Unix(1560418252, 0)} + info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -296,7 +298,7 @@ func _1558588866_add_versionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(420), modTime: time.Unix(1560418251, 0)} + info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -316,7 +318,7 @@ func _1559627659_add_contact_codeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(420), modTime: time.Unix(1560418335, 0)} + info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -336,7 +338,47 @@ func _1559627659_add_contact_codeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(420), modTime: time.Unix(1560418335, 0)} + info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var __1561059285_add_whisper_keysDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x28\xcf\xc8\x2c\x2e\x48\x2d\x8a\xcf\x4e\xad\x2c\xb6\xe6\x02\x04\x00\x00\xff\xff\x42\x93\x8e\x79\x19\x00\x00\x00") + +func _1561059285_add_whisper_keysDownSqlBytes() ([]byte, error) { + return bindataRead( + __1561059285_add_whisper_keysDownSql, + "1561059285_add_whisper_keys.down.sql", + ) +} + +func _1561059285_add_whisper_keysDownSql() (*asset, error) { + bytes, err := _1561059285_add_whisper_keysDownSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(420), modTime: time.Unix(1561059394, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var __1561059285_add_whisper_keysUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x04\xc0\xb1\x0a\xc2\x40\x0c\x06\xe0\xfd\x9e\xe2\x1f\x15\x7c\x03\xa7\xde\x19\x35\x18\x13\x09\x29\xb5\x53\x11\x3d\x68\xe9\x22\x56\x90\xbe\xbd\x5f\x71\x6a\x82\x10\x4d\x16\xc2\x6f\x9c\x96\x77\xfd\x0c\x73\x5d\x17\x6c\x12\xf0\x1c\x1f\xdf\x61\x7a\x21\xe8\x1e\xb8\x39\x5f\x1b\xef\x71\xa1\x1e\xa6\x28\xa6\x47\xe1\x12\xe0\x93\x9a\xd3\x2e\x01\x73\x5d\x91\xc5\x32\xd4\x02\xda\x8a\xa4\x2d\x3a\x8e\xb3\xb5\x01\xb7\x8e\x0f\xfb\xf4\x0f\x00\x00\xff\xff\x6e\x23\x28\x7d\x70\x00\x00\x00") + +func _1561059285_add_whisper_keysUpSqlBytes() ([]byte, error) { + return bindataRead( + __1561059285_add_whisper_keysUpSql, + "1561059285_add_whisper_keys.up.sql", + ) +} + +func _1561059285_add_whisper_keysUpSql() (*asset, error) { + bytes, err := _1561059285_add_whisper_keysUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(420), modTime: time.Unix(1561097945, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -356,7 +398,7 @@ func staticGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static.go", size: 191, mode: os.FileMode(420), modTime: time.Unix(1560418030, 0)} + info := bindataFileInfo{name: "static.go", size: 191, mode: os.FileMode(420), modTime: time.Unix(1561038914, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -426,6 +468,8 @@ var _bindata = map[string]func() (*asset, error){ "1558588866_add_version.up.sql": _1558588866_add_versionUpSql, "1559627659_add_contact_code.down.sql": _1559627659_add_contact_codeDownSql, "1559627659_add_contact_code.up.sql": _1559627659_add_contact_codeUpSql, + "1561059285_add_whisper_keys.down.sql": _1561059285_add_whisper_keysDownSql, + "1561059285_add_whisper_keys.up.sql": _1561059285_add_whisper_keysUpSql, "static.go": staticGo, } @@ -482,6 +526,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "1558588866_add_version.up.sql": &bintree{_1558588866_add_versionUpSql, map[string]*bintree{}}, "1559627659_add_contact_code.down.sql": &bintree{_1559627659_add_contact_codeDownSql, map[string]*bintree{}}, "1559627659_add_contact_code.up.sql": &bintree{_1559627659_add_contact_codeUpSql, map[string]*bintree{}}, + "1561059285_add_whisper_keys.down.sql": &bintree{_1561059285_add_whisper_keysDownSql, map[string]*bintree{}}, + "1561059285_add_whisper_keys.up.sql": &bintree{_1561059285_add_whisper_keysUpSql, map[string]*bintree{}}, "static.go": &bintree{staticGo, map[string]*bintree{}}, }} diff --git a/services/shhext/filter/persistence.go b/services/shhext/filter/persistence.go new file mode 100644 index 000000000..4ce7e3243 --- /dev/null +++ b/services/shhext/filter/persistence.go @@ -0,0 +1,59 @@ +package filter + +import ( + "database/sql" +) + +type Persistence interface { + Add(chatID string, key []byte) error + All() (map[string][]byte, error) +} + +type SQLLitePersistence struct { + db *sql.DB +} + +func NewSQLLitePersistence(db *sql.DB) *SQLLitePersistence { + return &SQLLitePersistence{db: db} +} + +func (s *SQLLitePersistence) All() (map[string][]byte, error) { + keys := make(map[string][]byte) + + statement := "SELECT chat_id, key FROM whisper_keys" + + stmt, err := s.db.Prepare(statement) + if err != nil { + return nil, err + } + defer stmt.Close() + + rows, err := stmt.Query() + if err != nil && err != sql.ErrNoRows { + return nil, err + } + + for rows.Next() { + var chatID string + var key []byte + err := rows.Scan(&chatID, &key) + if err != nil { + return nil, err + } + keys[chatID] = key + } + + return keys, nil +} + +func (s *SQLLitePersistence) Add(chatID string, key []byte) error { + statement := "INSERT INTO whisper_keys(chat_id, key) VALUES(?, ?)" + stmt, err := s.db.Prepare(statement) + if err != nil { + return err + } + defer stmt.Close() + + _, err = stmt.Exec(chatID, key) + return err +} diff --git a/services/shhext/filter/service.go b/services/shhext/filter/service.go index 7f215484d..8c5fa8c4a 100644 --- a/services/shhext/filter/service.go +++ b/services/shhext/filter/service.go @@ -49,25 +49,35 @@ type Chat struct { } type Service struct { - whisper *whisper.Whisper - secret *sharedsecret.Service - chats map[string]*Chat - mutex sync.Mutex + whisper *whisper.Whisper + secret *sharedsecret.Service + chats map[string]*Chat + persistence Persistence + mutex sync.Mutex + keys map[string][]byte } // New returns a new filter service -func New(w *whisper.Whisper, s *sharedsecret.Service) *Service { +func New(w *whisper.Whisper, p Persistence, s *sharedsecret.Service) *Service { return &Service{ - whisper: w, - secret: s, - mutex: sync.Mutex{}, - chats: make(map[string]*Chat), + whisper: w, + secret: s, + mutex: sync.Mutex{}, + persistence: p, + chats: make(map[string]*Chat), } } // LoadChat should return a list of newly chats loaded func (s *Service) Init(chats []*Chat) ([]*Chat, error) { log.Debug("Initializing filter service", "chats", chats) + + keys, err := s.persistence.All() + if err != nil { + return nil, err + } + s.keys = keys + keyID := s.whisper.SelectedKeyPairID() if keyID == "" { return nil, errors.New("no key selected") @@ -123,6 +133,7 @@ func (s *Service) Init(chats []*Chat) ([]*Chat, error) { for _, chat := range s.chats { allChats = append(allChats, chat) } + log.Debug("Loaded chats") return allChats, nil } @@ -390,19 +401,36 @@ func (s *Service) loadContactCode(identity string) (*Chat, error) { // addSymmetric adds a symmetric key filter func (s *Service) addSymmetric(chatID string) (*Filter, error) { - var symKey []byte + var symKeyID string + var err error topic := ToTopic(chatID) topics := [][]byte{topic} - symKeyID, err := s.whisper.AddSymKeyFromPassword(chatID) - if err != nil { - log.Error("SYM KEYN FAILED", "err", err) - return nil, err - } + symKey, ok := s.keys[chatID] + if ok { + log.Debug("Loading from cache", "chat-id", chatID) + symKeyID, err = s.whisper.AddSymKeyDirect(symKey) + if err != nil { + log.Error("Adding symkey failed", "err", err) + return nil, err + } + } else { + log.Debug("Generating symkey", "chat-id", chatID) + symKeyID, err = s.whisper.AddSymKeyFromPassword(chatID) + if err != nil { + log.Error("Adding symkey from password failed", "err", err) + return nil, err + } + if symKey, err = s.whisper.GetSymKey(symKeyID); err != nil { + return nil, err + } + s.keys[chatID] = symKey - if symKey, err = s.whisper.GetSymKey(symKeyID); err != nil { - return nil, err + err = s.persistence.Add(chatID, symKey) + if err != nil { + return nil, err + } } f := &whisper.Filter{ diff --git a/services/shhext/filter/service_test.go b/services/shhext/filter/service_test.go index 4a8ba27aa..97639908c 100644 --- a/services/shhext/filter/service_test.go +++ b/services/shhext/filter/service_test.go @@ -72,7 +72,9 @@ func (s *ServiceTestSuite) SetupTest() { _, err = whisper.AddKeyPair(s.keys[0].privateKey) s.Require().NoError(err) - s.service = New(whisper, sharedSecretService) + persistence := NewSQLLitePersistence(db) + + s.service = New(whisper, persistence, sharedSecretService) } func (s *ServiceTestSuite) TearDownTest() { @@ -136,6 +138,24 @@ func (s *ServiceTestSuite) TestPublicAndOneToOneChats() { s.Require().True(contactCodeFilter.Listen) } +func (s *ServiceTestSuite) TestLoadFromCache() { + chats := []*Chat{ + { + ChatID: "status", + }, + { + ChatID: "status-1", + }, + } + _, err := s.service.Init(chats) + s.Require().NoError(err) + + // We create another service using the same persistence + service2 := New(s.service.whisper, s.service.persistence, s.service.secret) + _, err = service2.Init(chats) + s.Require().NoError(err) +} + func (s *ServiceTestSuite) TestNegotiatedTopic() { chats := []*Chat{} diff --git a/services/shhext/publisher/service.go b/services/shhext/publisher/service.go index 44aad9697..0a104e4f3 100644 --- a/services/shhext/publisher/service.go +++ b/services/shhext/publisher/service.go @@ -148,7 +148,7 @@ func (s *Service) initProtocol(address, encKey, password string) error { // Initialize sharedsecret sharedSecretService := sharedsecret.NewService(persistence.GetSharedSecretStorage()) // Initialize filter - filterService := filter.New(s.whisper, sharedSecretService) + filterService := filter.New(s.whisper, filter.NewSQLLitePersistence(persistence.DB), sharedSecretService) s.filter = filterService // Initialize multidevice diff --git a/static/chat_db_migrations/1561059285_add_whisper_keys.down.sql b/static/chat_db_migrations/1561059285_add_whisper_keys.down.sql new file mode 100644 index 000000000..f0761da00 --- /dev/null +++ b/static/chat_db_migrations/1561059285_add_whisper_keys.down.sql @@ -0,0 +1 @@ +DROP TABLE whisper_keys; diff --git a/static/chat_db_migrations/1561059285_add_whisper_keys.up.sql b/static/chat_db_migrations/1561059285_add_whisper_keys.up.sql new file mode 100644 index 000000000..844e77282 --- /dev/null +++ b/static/chat_db_migrations/1561059285_add_whisper_keys.up.sql @@ -0,0 +1,4 @@ +CREATE TABLE whisper_keys ( + chat_id TEXT PRIMARY KEY ON CONFLICT IGNORE, + key BLOB NOT NULL +) WITHOUT ROWID;