[fix 3843] query mailserver when going back online

Signed-off-by: Eric Dvorsak <eric@dvorsak.fr>
This commit is contained in:
Eric Dvorsak 2018-04-13 19:14:26 +02:00
parent de03fc2d6a
commit f8e535f9bc
No known key found for this signature in database
GPG Key ID: 932AC1CE5F05DE0C
8 changed files with 118 additions and 65 deletions

View File

@ -8,7 +8,8 @@
com.andrewmcveigh/cljs-time {:mvn/version "0.5.2"}
com.taoensso/timbre {:mvn/version "4.10.0"}
hickory {:mvn/version "0.7.1"}
com.cognitect/transit-cljs {:mvn/version "0.8.248"}}
com.cognitect/transit-cljs {:mvn/version "0.8.248"}
day8.re-frame/async-flow-fx {:mvn/version "0.0.10"}}
:aliases
{:repl {:extra-deps

View File

@ -10,7 +10,8 @@
[com.andrewmcveigh/cljs-time "0.5.2"]
[com.taoensso/timbre "4.10.0"]
[hickory "0.7.1"]
[com.cognitect/transit-cljs "0.8.248"]]
[com.cognitect/transit-cljs "0.8.248"]
[day8.re-frame/async-flow-fx "0.0.10"]]
:plugins [[lein-cljsbuild "1.1.7"]
[lein-re-frisk "0.5.8"]]
:clean-targets ["target/" "index.ios.js" "index.android.js"]

View File

@ -1,8 +1,10 @@
(ns status-im.network.events
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.network.net-info :as net-info]
[status-im.native-module.core :as status]))
[status-im.native-module.core :as status]
[status-im.transport.inbox :as inbox]))
(re-frame/reg-fx
::listen-to-network-status
@ -26,12 +28,15 @@
(handlers/register-handler-fx
::update-connection-status
[re-frame/trim-v]
(fn [{:keys [db]} [is-connected?]]
(cond->
(fn [{:keys [db] :as cofx} [is-connected?]]
(let [previous-status (:network-status db)
back-online? (and (= previous-status :offline)
is-connected?)]
(cond-> (handlers-macro/merge-fx cofx
{:db (assoc db :network-status (if is-connected? :online :offline))}
(inbox/recover-offline-inbox back-online?))
is-connected?
(assoc :drain-mixpanel-events nil))))
(assoc :drain-mixpanel-events nil)))))
(handlers/register-handler-fx
::update-network-status

View File

@ -27,6 +27,7 @@
:no "No"
:on "On"
:off "Off"
:mailserver-connection-error "Could not connect to mailserver"
:camera-access-error "To grant the required camera permission, please go to your system settings and make sure that Status > Camera is selected."
:photos-access-error "To grant the required photos permission, please go to your system settings and make sure that Status > Photos is selected."

View File

@ -6,7 +6,10 @@
[status-im.transport.utils :as web3.utils]
[status-im.utils.config :as config]
[taoensso.timbre :as log]
[status-im.utils.ethereum.core :as ethereum]))
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.utils :as utils]
[status-im.i18n :as i18n]
[day8.re-frame.async-flow-fx]))
(defn- parse-json
;; NOTE(dmitryn) Expects JSON response like:
@ -41,15 +44,38 @@
wnode-id (get-in db [:account/account :settings :wnode network])]
(get-in db [:inbox/wnodes network wnode-id :address])))
(defn initialize-offline-inbox-flow []
{:first-dispatch [:inbox/get-sym-key]
:rules [{:when :seen-both?
:events [:inbox/get-sym-key-success :inbox/connection-success]
:dispatch [:inbox/request-messages]}]})
(defn recover-offline-inbox-flow []
{:first-dispatch [:inbox/fetch-peers]
:rules [{:when :seen?
:events :inbox/connection-success
:dispatch [:inbox/request-messages]}]})
(defn initialize-offline-inbox
"Initialises offline inbox by producing `::add-peer` effect if inboxing enabled in config,
then the event chan is:
add-peer -> fetch-peers -> check-peer-added -> mark-trusted-peer -> get-sym-key -> request-messages"
"Initialises offline inbox if inboxing enabled in config"
[{:keys [db]}]
(when config/offline-inbox-enabled?
(let [wnode (get-current-wnode-address db)]
(log/info "offline inbox: initialize")
{::add-peer {:wnode wnode}})))
(log/info "offline inbox: initialize " wnode)
(when wnode
{:async-flow (initialize-offline-inbox-flow)
::add-peer {:wnode wnode}}))))
(defn recover-offline-inbox
"Recover offline inbox connection after being offline because of connectivity loss"
[back-online? {:keys [db]}]
(when config/offline-inbox-enabled?
(let [wnode (get-current-wnode-address db)]
(when (and back-online?
wnode
(:account/account db))
(log/info "offline inbox: recover" wnode)
{:async-flow (recover-offline-inbox-flow)}))))
(defn add-peer [enode success-fn error-fn]
(status/add-peer enode (response-handler error-fn success-fn)))
@ -71,7 +97,7 @@
enode-id (web3.utils/extract-enode-id enode)]
(contains? peer-ids enode-id)))
(defn mark-trusted-peer [web3 enode peers success-fn error-fn]
(defn mark-trusted-peer [web3 enode success-fn error-fn]
(.markTrustedPeer (web3.utils/shh web3)
enode
(fn [err resp]
@ -80,7 +106,6 @@
(error-fn err)))))
(defn request-messages [web3 wnode topics to from sym-key-id success-fn error-fn]
(log/info "offline inbox: sym-key-id" sym-key-id)
(let [opts (merge {:mailServerPeer wnode
:symKeyID sym-key-id}
(when from {:from from})
@ -100,22 +125,21 @@
::add-peer
(fn [{:keys [wnode]}]
(add-peer wnode
#(re-frame/dispatch [::fetch-peers %])
#(re-frame/dispatch [:inbox/fetch-peers])
#(log/error "offline inbox: add-peer error" %))))
(re-frame/reg-fx
::fetch-peers
(fn [retries]
(fetch-peers #(re-frame/dispatch [::check-peer-added % retries])
(fetch-peers #(re-frame/dispatch [:inbox/check-peer-added % retries])
#(log/error "offline inbox: fetch-peers error" %))))
(re-frame/reg-fx
::mark-trusted-peer
(fn [{:keys [wnode web3 peers]}]
(fn [{:keys [wnode web3]}]
(mark-trusted-peer web3
wnode
peers
#(re-frame/dispatch [::get-sym-key %])
#(re-frame/dispatch [:inbox/connection-success %])
#(log/error "offline inbox: mark-trusted-peer error" % wnode))))
(re-frame/reg-fx
@ -133,14 +157,20 @@
;;;; Handlers
(handlers/register-handler-fx
::fetch-peers
:inbox/add-peer
;; This event adds a wnode to the list of peers
(fn [_ [_ wnode]]
{::add-peer {:wnode wnode}}))
(handlers/register-handler-fx
:inbox/fetch-peers
;; This event fetches the list of peers
;; We want it to check if the node has been added
(fn [_ [_ retries]]
{::fetch-peers (or retries 0)}))
(handlers/register-handler-fx
::check-peer-added
:inbox/check-peer-added
;; We check if the wnode is part of the peers list
;; if not we dispatch a new fetch-peer event for later
(fn [{:keys [db]} [_ peers retries]]
@ -149,44 +179,54 @@
(log/info "offline inbox: fetch-peers response" peers)
(if (registered-peer? peers wnode)
{::mark-trusted-peer {:web3 web3
:wnode wnode
:peers peers}}
:wnode wnode}}
(do
(log/info "Peer" wnode "is not registered. Retrying fetch peers.")
(let [delay (if (< retries 3) 300 5000)]
(if (> retries 10)
(log/error "Could not connect to mailserver")
{:dispatch-later [{:ms delay :dispatch [::fetch-peers (inc retries)]}]})))))))
(do (log/error :mailserver-connection-error)
(utils/show-popup (i18n/label :t/error)
(i18n/label :t/mailserver-connection-error)))
{:dispatch-later [{:ms delay :dispatch [:inbox/fetch-peers (inc retries)]}]})))))))
(handlers/register-handler-fx
::get-sym-key
;; TODO(yenda): using core async flow this event can be done in parallel
;; with add-peer
(fn [{:keys [db]} [_ response]]
:inbox/get-sym-key
(fn [{:keys [db]} _]
(let [web3 (:web3 db)
wnode (get-current-wnode-address db)
password (:inbox/password db)]
(log/info "offline inbox: mark-trusted-peer response" wnode response)
{:shh/generate-sym-key-from-password {:password password
:web3 web3
:on-success (fn [_ sym-key-id]
(re-frame/dispatch [::request-messages sym-key-id]))
(re-frame/dispatch [:inbox/get-sym-key-success sym-key-id]))
:on-error #(log/error "offline inbox: get-sym-key error" %)}})))
(handlers/register-handler-fx
::request-messages
;; TODO(yenda): we want to request-message once per topic and for specific timespan so
;; we want a plural version of this function that does the right thing
:inbox/get-sym-key-success
(fn [{:keys [db]} [_ sym-key-id]]
(log/info "offline inbox: get-sym-key response") sym-key-id
{:db (assoc db :inbox/sym-key-id sym-key-id)}))
(handlers/register-handler-fx
:inbox/connection-success
(fn [{:keys [db]} _]
{:db (assoc db :mailserver-status :connected)}))
(handlers/register-handler-fx
:inbox/request-messages
(fn [{:keys [db now]} [_ {:keys [from topics]}]]
(let [web3 (:web3 db)
wnode (get-current-wnode-address db)
topics (map #(:topic %) (vals (:transport/chats db)))
to nil
from nil]
topics (or topics
(map #(:topic %) (vals (:transport/chats db))))
from (or from (:inbox/last-request db) nil)
sym-key-id (:inbox/sym-key-id db)]
{::request-messages {:wnode wnode
:topics topics
:to to
:from from
;;TODO (yenda) fix from, right now mailserver is dropping us
;;when we send a requestMessage with a from field
;;:from from
:sym-key-id sym-key-id
:web3 web3}})))
:web3 web3}
:db (assoc db :inbox/last-request (quot now 1000))})))

View File

@ -27,16 +27,17 @@
(handlers/register-handler-fx
::add-new-sym-key
(fn [{:keys [db] :as cofx} [_ {:keys [sym-key-id sym-key chat-id]}]]
(let [{:keys [web3]} db]
(handlers-macro/merge-fx
cofx
(let [{:keys [web3]} db
topic (transport.utils/get-topic chat-id)]
{:db (assoc-in db [:transport/chats chat-id :sym-key-id] sym-key-id)
:shh/add-filter {:web3 web3
:sym-key-id sym-key-id
:topic (transport.utils/get-topic chat-id)
:topic topic
:chat-id chat-id}
:data-store.transport/save {:chat-id chat-id
:chat (-> (get-in db [:transport/chats chat-id])
(assoc :sym-key-id sym-key-id)
;;TODO (yenda) remove once go implements persistence
(assoc :sym-key sym-key))}}))))
(assoc :sym-key sym-key))}
:dispatch [:inbox/request-messages {:topics [topic]
:from 0}]})))

View File

@ -166,6 +166,8 @@
:node/after-stop
:inbox/wnodes
:inbox/password
:inbox/sym-key-id
:inbox/last-request
:browser/browsers
:browser/options
:new/open-dapp

View File

@ -13,3 +13,5 @@
(spec/def :inbox/password ::not-blank-string)
(spec/def :inbox/wnodes (spec/nilable (spec/map-of keyword? (spec/map-of :wnode/id :wnode/wnode))))
(spec/def :inbox/sym-key-id string?)
(spec/def :inbox/last-request integer?)