[Fix #2751] Allow switching between wnodes for offline messaging

Signed-off-by: Eric Dvorsak <eric@dvorsak.fr>
This commit is contained in:
Foo Pang 2018-01-16 11:36:48 +08:00 committed by Eric Dvorsak
parent 3b6b987db4
commit 8582be2e69
No known key found for this signature in database
GPG Key ID: 932AC1CE5F05DE0C
15 changed files with 148 additions and 47 deletions

View File

@ -13,7 +13,7 @@
(def text-content-type "text/plain")
(def content-type-log-message "log-message")
(def content-type-command "command")
(def content-type-command-request "command-request")
(def content-type-command-request "command-request")
(def content-type-status "status")
(def min-password-length 6)
@ -82,10 +82,15 @@
(when config/mainnet-networks-enabled? mainnet-networks))))
;; adamb's status-cluster enode
(def default-wnode {:name "Status mailserver"
:address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"})
(def default-wnode "main")
(def default-wnodes [default-wnode])
(def default-wnodes
{"main" {:id "main"
:name "Status mailserver"
:address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"}
"test" {:id "test"
:name "Status mailserver (test)"
:address "enode://e2fdcf8a55d9d1ab75b492c3b9a99c206cf5ceede3db716033d0605205218c9d9a406d04b3460f4e8a64f16907ab78ba88e0e46324568bf58b3329e2c5483faa@163.172.177.138:30353"}})
;; TODO(oskarth): Determine if this is the correct topic or not
(def inbox-topic "0xaabb11ee")

View File

@ -3,7 +3,8 @@
[status-im.data-store.realm.schemas.base.v2.core :as v2]
[status-im.data-store.realm.schemas.base.v3.core :as v3]
[status-im.data-store.realm.schemas.base.v4.core :as v4]
[status-im.data-store.realm.schemas.base.v5.core :as v5]))
[status-im.data-store.realm.schemas.base.v5.core :as v5]
[status-im.data-store.realm.schemas.base.v6.core :as v6]))
; put schemas ordered by version
(def schemas [{:schema v1/schema
@ -20,4 +21,7 @@
:migration v4/migration}
{:schema v5/schema
:schemaVersion 5
:migration v5/migration}])
:migration v5/migration}
{:schema v6/schema
:schemaVersion 6
:migration v6/migration}])

View File

@ -0,0 +1,34 @@
(ns status-im.data-store.realm.schemas.base.v6.account
(:require [taoensso.timbre :as log]
[status-im.constants :as constants]))
(def schema {:name :account
:primaryKey :address
:properties {:address :string
:public-key :string
:updates-public-key {:type :string
:optional true}
:updates-private-key {:type :string
:optional true}
:name {:type :string :optional true}
:phone {:type :string :optional true}
:email {:type :string :optional true}
:status {:type :string :optional true}
:debug? {:type :bool :default false}
:photo-path :string
:signing-phrase {:type :string}
:last-updated {:type :int :default 0}
:signed-up? {:type :bool
:default false}
:network :string
:networks {:type :list
:objectType :network}
:wnode :string
:settings {:type :string}}})
(defn migration [_old-realm new-realm]
(log/debug "migrating account schema v6")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)]
(aset account "wnode" constants/default-wnode)))))

View File

@ -0,0 +1,11 @@
(ns status-im.data-store.realm.schemas.base.v6.core
(:require [status-im.data-store.realm.schemas.base.v4.network :as network]
[status-im.data-store.realm.schemas.base.v6.account :as account]
[taoensso.timbre :as log]))
(def schema [network/schema
account/schema])
(defn migration [old-realm new-realm]
(log/debug "migrating v6 base database: " old-realm new-realm)
(account/migration old-realm new-realm))

View File

@ -17,7 +17,7 @@
[status-im.chat.models.message :as models.message]
[status-im.protocol.web3.inbox :as inbox]
[status-im.protocol.web3.keys :as web3.keys]
[status-im.utils.datetime :as datetime]
[status-im.utils.datetime :as datetime]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]
[clojure.string :as string]
@ -274,14 +274,16 @@
:initialize-offline-inbox
(fn [{:keys [db]} [_ web3]]
(log/info "offline inbox: initialize")
(let [wnode (get-in db [:inbox/wnode :address])]
(let [wnode-id (get db :inbox/wnode)
wnode (get-in db [:inbox/wnodes wnode-id :address])]
{::add-peer {:wnode wnode
:web3 web3}})))
(handlers/register-handler-fx
::add-peer-success
(fn [{:keys [db]} [_ web3 response]]
(let [wnode (get-in db [:inbox/wnode :address])]
(let [wnode-id (get db :inbox/wnode)
wnode (get-in db [:inbox/wnodes wnode-id :address])]
(log/info "offline inbox: add-peer response" wnode response)
{::fetch-peers {:wnode wnode
:web3 web3
@ -290,7 +292,8 @@
(handlers/register-handler-fx
::fetch-peers-success
(fn [{:keys [db]} [_ web3 peers retries]]
(let [wnode (get-in db [:inbox/wnode :address])]
(let [wnode-id (get db :inbox/wnode)
wnode (get-in db [:inbox/wnodes wnode-id :address])]
(log/info "offline inbox: fetch-peers response" peers)
(if (inbox/registered-peer? peers wnode)
{::mark-trusted-peer {:wnode wnode
@ -298,14 +301,15 @@
:peers peers}}
(do
(log/info "Peer" wnode "is not registered. Retrying fetch peers.")
{::fetch-peers {:wnode wnode
:web3 web3
{::fetch-peers {:wnode wnode
:web3 web3
:retries (inc retries)}})))))
(handlers/register-handler-fx
::mark-trusted-peer-success
(fn [{:keys [db]} [_ web3 response]]
(let [wnode (get-in db [:inbox/wnode :address])
(let [wnode-id (get db :inbox/wnode)
wnode (get-in db [:inbox/wnodes wnode-id :address])
password (:inbox/password db)]
(log/info "offline inbox: mark-trusted-peer response" wnode response)
{::get-sym-key {:password password
@ -317,8 +321,9 @@
::get-sym-key-success
(fn [{:keys [db]} [_ web3 sym-key-id]]
(log/info "offline inbox: get-sym-key response" sym-key-id)
(let [wnode (get-in db [:inbox/wnode :address])
topic (:inbox/topic db)]
(let [wnode-id (get db :inbox/wnode)
wnode (get-in db [:inbox/wnodes wnode-id :address])
topic (:inbox/topic db)]
{::request-messages {:wnode wnode
:topic topic
:sym-key-id sym-key-id
@ -424,7 +429,7 @@
;;; MESSAGES
(defn- transform-protocol-message [{:keys [from to payload]}]
(defn- transform-protocol-message [{:keys [from to payload]}]
(merge payload {:from from
:to to
:chat-id (or (:group-id payload) from)}))
@ -439,7 +444,7 @@
(or ack-of-message message-id))
(handlers/register-handler-fx
:incoming-message
:incoming-message
(fn [{:keys [db]} [_ type {:keys [payload ttl id] :as message}]]
(let [message-id (or id (:message-id payload))]
(when-not (cache/exists? message-id type)
@ -473,7 +478,7 @@
:discoveries-response {:dispatch [:discoveries-response-received message]}
:profile {:dispatch [:contact-update-received message]}
:update-keys {:dispatch [:update-keys-received message]}
:online {:dispatch [:contact-online-received message]}
:online {:dispatch [:contact-online-received message]}
nil)]
(when (nil? route-fx) (log/debug "Unknown message type" type))
(cache/add! processed-message)
@ -487,19 +492,19 @@
(fn [{:keys [db get-stored-message]} [{:keys [from sent-from payload]} status]]
(let [message-identifier (get-message-id payload)
chat-identifier (or (:group-id payload) from)
message-db-path [:chats chat-identifier :messages message-identifier]
from-id (or sent-from from)
message-db-path [:chats chat-identifier :messages message-identifier]
from-id (or sent-from from)
message (or (get-in db message-db-path)
(and (get (:not-loaded-message-ids db) message-identifier)
(get-stored-message message-identifier)))]
;; proceed with updating status if chat is in db, status is not the same and message was not already seen
;; proceed with updating status if chat is in db, status is not the same and message was not already seen
(when (and message
(get-in db [:chats chat-identifier])
(not= status (get-in message [:user-statuses from-id]))
(not (models.message/message-seen-by? message from-id)))
(let [statuses (assoc (:user-statuses message) from-id status)]
(cond-> {:update-message {:message-id message-identifier
:user-statuses statuses}}
:user-statuses statuses}}
(get-in db message-db-path)
(assoc :db (assoc-in db (conj message-db-path :user-statuses) statuses))))))))
@ -527,7 +532,7 @@
;; Get timestamp from message root level.
;; Root level "timestamp" is a unix ts in seconds.
timestamp' (or (:payload timestamp)
(* 1000 timestamp))]
(* 1000 timestamp))]
(if-not existing-contact
(let [contact (assoc contact :pending? true)]
{:dispatch-n [[:add-contacts [contact]]

View File

@ -399,6 +399,7 @@
:close-app-title "Warning!"
:close-app-content "The app will stop and close. When you reopen it, the selected network will be used"
:close-app-button "Confirm"
:connect-wnode-content "Connect to {{name}}?"
;; browser
:browser "Browser"

View File

@ -18,6 +18,7 @@
(spec/def :account/status (spec/nilable string?))
(spec/def :account/network (spec/nilable string?))
(spec/def :account/networks (spec/nilable :networks/networks))
(spec/def :account/wnode (spec/nilable string?))
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
(spec/def :account/phone (spec/nilable string?))
(spec/def :account/signing-phrase :global/not-empty-string)
@ -28,7 +29,8 @@
:opt-un [:account/debug? :account/status :account/last-updated
:account/updates-private-key :account/updates-public-key
:account/email :account/signed-up? :account/network
:account/phone :account/networks :account/settings]))
:account/phone :account/networks :account/settings
:account/wnode]))
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))

View File

@ -92,11 +92,12 @@
(defn add-account
"Takes db and new account, creates map of effects describing adding account to database and realm"
[{:keys [network] :networks/keys [networks] :as db} {:keys [address] :as account}]
[{:keys [network inbox/wnode] :networks/keys [networks] :as db} {:keys [address] :as account}]
(let [enriched-account (assoc account
:network network
:network network
:networks networks
:address address)]
:wnode wnode
:address address)]
{:db (assoc-in db [:accounts/accounts address] enriched-account)
::save-account enriched-account}))

View File

@ -9,7 +9,8 @@
[status-im.native-module.core :as status]
[status-im.constants :refer [console-chat-id]]
[status-im.utils.config :as config]
[status-im.utils.utils :as utils]))
[status-im.utils.utils :as utils]
[status-im.constants :as constants]))
;;;; FX
@ -70,6 +71,9 @@
{:network network
:config config}))
(defn get-wnode-by-address [db address]
(get-in db [:accounts/accounts address :wnode] constants/default-wnode))
(defn wrap-with-initialize-geth-fx [db address password]
(let [{:keys [network config]} (get-network-by-address db address)]
{:initialize-geth-fx config
@ -92,8 +96,10 @@
(fn [{{:keys [network status-node-started?] :as db} :db}
[_ address password account-creation?]]
(let [{account-network :network} (get-network-by-address db address)
wnode (get-wnode-by-address db address)
db' (-> db
(assoc :accounts/account-creation? account-creation?)
(assoc :inbox/wnode wnode)
(assoc-in [:accounts/login :processing] true))
wrap-fn (cond (not status-node-started?)
wrap-with-initialize-geth-fx

View File

@ -49,6 +49,7 @@
:network constants/default-network
:networks/networks constants/default-networks
:inbox/wnode constants/default-wnode
:inbox/wnodes constants/default-wnodes
:inbox/topic constants/inbox-topic
:inbox/password constants/inbox-password
:my-profile/editing? false})
@ -132,6 +133,7 @@
:node/after-start
:node/after-stop
:inbox/wnode
:inbox/wnodes
:inbox/topic
:inbox/password
:browser/browsers
@ -176,7 +178,7 @@
:chat/message-data
:chat/message-status
:chat/selected-participants
:chat/chat-loaded-callbacks
:chat/chat-loaded-callbacks
:chat/public-group-topic
:chat/confirmation-code-sms-listener
:chat/messages

View File

@ -24,6 +24,7 @@
status-im.ui.screens.wallet.choose-recipient.events
status-im.ui.screens.browser.events
status-im.ui.screens.add-new.open-dapp.events
status-im.ui.screens.offline-messaging-settings.events
[re-frame.core :as re-frame]
[status-im.native-module.core :as status]
[status-im.ui.components.react :as react]
@ -250,8 +251,10 @@
(fn [{:keys [accounts/accounts contacts/contacts networks/networks
network network-status view-id navigation-stack chats
access-scope->commands-responses layout-height
status-module-initialized? status-node-started?]
:or [network (get app-db :network)]
status-module-initialized? status-node-started?
inbox/wnode]
:or [network (get app-db :network)
wnode (get app-db :inbox/wnode)]
:as db} [_ address]]
(let [console-contact (get contacts console-chat-id)]
(cond-> (assoc app-db
@ -270,7 +273,8 @@
:accounts/creating-account? false
:networks/networks networks
:network-status network-status
:network network)
:network network
:inbox/wnode wnode)
console-contact
(assoc :contacts/contacts {console-chat-id console-contact})))))

View File

@ -5,8 +5,13 @@
(def enode-address-regex #"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
(spec/def ::not-blank-string (spec/and string? seq))
(spec/def :wnode/address (spec/and string? #(re-matches enode-address-regex %)))
(spec/def :wnode/name ::not-blank-string)
(spec/def :wnode/id ::not-blank-string)
(spec/def :wnode/wnode (allowed-keys :req-un [:wnode/address :wnode/name :wnode/id]))
(spec/def :inbox/topic ::not-blank-string)
(spec/def :inbox/password ::not-blank-string)
(spec/def :inbox/wnode (allowed-keys :req-un [:wnode/address :wnode/name]))
(spec/def :inbox/wnode ::not-blank-string)
(spec/def :inbox/wnodes (spec/nilable (spec/map-of :wnode/id :wnode/wnode)))

View File

@ -0,0 +1,23 @@
(ns status-im.ui.screens.offline-messaging-settings.events
(:require [re-frame.core :refer [dispatch]]
[status-im.utils.handlers :as handlers]
[status-im.ui.screens.accounts.events :as accounts-events]
[status-im.i18n :as i18n]))
(handlers/register-handler-fx
::save-wnode
(fn [{:keys [db now]} [_ wnode]]
(-> (accounts-events/account-update {:db db}
{:wnode wnode :last-updated now})
(merge {:dispatch [:navigate-to-clean :accounts]
:stop-whisper nil}))))
(handlers/register-handler-fx
:connect-wnode
(fn [{:keys [db now]} [_ wnode]]
{:show-confirmation {:title (i18n/label :t/close-app-title)
:content (i18n/label :t/connect-wnode-content
{:name (get-in db [:inbox/wnodes wnode :name])})
:confirm-button-text (i18n/label :t/close-app-button)
:on-accept #(dispatch [::save-wnode wnode])
:on-cancel nil}}))

View File

@ -1,5 +1,6 @@
(ns status-im.ui.screens.offline-messaging-settings.views
(:require [status-im.constants :as constants]
(:require [re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.i18n :as i18n]
[status-im.ui.components.common.common :as common]
[status-im.ui.components.icons.vector-icons :as vector-icons]
@ -11,23 +12,19 @@
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]
[reagent.core :as reagent])
(:require-macros [status-im.utils.views :as views]))
(defn- add-wnode []
;; TODO:(dmitryn) to be added in #2751
(log/info "add wnode not implemented"))
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn- wnode-icon [connected?]
[react/view (styles/wnode-icon connected?)
[vector-icons/icon :icons/wnode {:color (if connected? :white :gray)}]])
(defn- render-row [current-wnode]
(fn [{:keys [address name] :as row} _ _]
(let [connected? (= address (:address current-wnode))]
(fn [{:keys [address name id] :as row} _ _]
(let [connected? (= id current-wnode)]
[react/list-item
^{:key row}
[react/touchable-highlight
{:on-press add-wnode}
{:on-press #(re-frame/dispatch [:connect-wnode id])}
[react/view styles/wnode-item
[wnode-icon connected?]
[react/view styles/wnode-item-inner
@ -53,10 +50,9 @@
[common/list-footer]
[common/bottom-shadow]]])
(views/defview offline-messaging-settings []
;; TODO:(dmitryn) store wnodes in user account, but now use defaults for MVP
(let [current-wnode constants/default-wnode
wnodes constants/default-wnodes]
(defview offline-messaging-settings []
(letsubs [current-wnode [:get :inbox/wnode]
wnodes [:get :inbox/wnodes]]
[react/view {:flex 1}
[status-bar/status-bar]
[toolbar/simple-toolbar (i18n/label :t/offline-messaging-settings)]
@ -66,7 +62,7 @@
;; TODO(dmitryn) migrate to :header/:footer properties of flat-list
;; after merge of https://github.com/status-im/status-react/pull/2297/
[render-header wnodes]
[list/flat-list {:data wnodes
[list/flat-list {:data (vals wnodes)
:separator? false
:render-fn (render-row current-wnode)
:ListFooterComponent (reagent/as-element (render-footer))

View File

@ -26,6 +26,7 @@
:status "be the hero of your own journey"
:network constants/default-network
:networks constants/default-networks
:wnode constants/default-wnode
:public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"})
(def new-account
@ -38,6 +39,7 @@
:status "the future starts today, not tomorrow"
:network constants/default-network
:networks constants/default-networks
:wnode constants/default-wnode
:signing-phrase "long loan limo"
:public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"})