fix 9394 select mailserver based on ping

- if not mailserver was actively selected by user,
use rpc call to get latency for known mailservers
and use the best one
- this happens when `set-current-mailserver` is called which happens
in `change-mailserver` when user unpins his preferred mailserver and when
there's been too many failed attemps to fetch messages or to connect to
then current mailserverm as well as when user logs in.

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2019-11-18 16:46:08 +01:00
parent 67e6ab6055
commit 572e028f32
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
6 changed files with 370 additions and 280 deletions

View File

@ -76,6 +76,7 @@
"settings_saveNodeConfig" {} "settings_saveNodeConfig" {}
"accounts_getAccounts" {} "accounts_getAccounts" {}
"accounts_saveAccounts" {} "accounts_saveAccounts" {}
"mailservers_ping" {}
"mailservers_addMailserver" {} "mailservers_addMailserver" {}
"mailservers_getMailservers" {} "mailservers_getMailservers" {}
"mailservers_deleteMailserver" {} "mailservers_deleteMailserver" {}

View File

@ -245,11 +245,6 @@
(fn [cofx [_ current-fleet mailserver-id]] (fn [cofx [_ current-fleet mailserver-id]]
(mailserver/save-settings cofx current-fleet mailserver-id))) (mailserver/save-settings cofx current-fleet mailserver-id)))
(handlers/register-handler-fx
:mailserver.ui/reconnect-mailserver-pressed
(fn [cofx _]
(mailserver/connect-to-mailserver cofx)))
(handlers/register-handler-fx (handlers/register-handler-fx
:mailserver.ui/unpin-pressed :mailserver.ui/unpin-pressed
(fn [cofx _] (fn [cofx _]

View File

@ -40,56 +40,41 @@
(def limit (atom constants/default-limit)) (def limit (atom constants/default-limit))
(def success-counter (atom 0)) (def success-counter (atom 0))
(defn connected? [{:keys [db]} id] (defn connected? [db id]
(= (:mailserver/current-id db) id)) (= (:mailserver/current-id db) id))
(defn fetch [{:keys [db] :as cofx} id] (defn fetch [db id]
(get-in db [:mailserver/mailservers (node/current-fleet-key db) id])) (get-in db [:mailserver/mailservers (node/current-fleet-key db) id]))
(defn fetch-current [{:keys [db] :as cofx}] (defn fetch-current [db]
(fetch cofx (:mailserver/current-id db))) (fetch db (:mailserver/current-id db)))
(defn preferred-mailserver-id [{:keys [db] :as cofx}] (defn preferred-mailserver-id [db]
(get-in db [:multiaccount :settings :mailserver (node/current-fleet-key db)])) (get-in db [:multiaccount :settings :mailserver (node/current-fleet-key db)]))
(defn- round-robin (defn mailserver-address->id [db address]
"Find the choice and pick the next one, default to first if not found" (let [current-fleet (node/current-fleet-key db)]
[choices current-id] (:id (some #(when (= address (:address %))
(let [next-index (reduce %)
(fn [index choice] (-> db
(if (= current-id choice) :mailserver/mailservers
(reduced (inc index)) current-fleet
(inc index))) vals)))))
0
choices)]
(nth choices
(mod
next-index
(count choices)))))
(defn selected-or-random-id (defn get-selected-mailserver
"Use the preferred mailserver if set & exists, otherwise picks one randomly "Use the preferred mailserver if set & exists"
if current-id is not set, else round-robin" [db]
[{:keys [db] :as cofx}]
(let [current-fleet (node/current-fleet-key db) (let [current-fleet (node/current-fleet-key db)
current-id (:mailserver/current-id db) current-id (:mailserver/current-id db)
preference (preferred-mailserver-id cofx) preference (preferred-mailserver-id db)]
choices (-> db :mailserver/mailservers current-fleet keys)] (when (and preference
(if (and preference (fetch db preference))
(fetch cofx preference)) preference)))
preference
(if current-id
(round-robin choices current-id)
(rand-nth choices)))))
(fx/defn set-current-mailserver
[{:keys [db] :as cofx}]
{:db (assoc db :mailserver/current-id
(selected-or-random-id cofx))})
(defn add-peer! [enode] (defn add-peer! [enode]
(status/add-peer enode (status/add-peer enode
(handlers/response-handler #(log/debug "mailserver: add-peer success" %) (handlers/response-handler
#(log/debug "mailserver: add-peer success" %)
#(log/error "mailserver: add-peer error" %)))) #(log/error "mailserver: add-peer error" %))))
;; We now wait for a confirmation from the mailserver before marking the message ;; We now wait for a confirmation from the mailserver before marking the message
@ -98,7 +83,8 @@
(defn update-mailservers! [enodes] (defn update-mailservers! [enodes]
(status/update-mailservers (status/update-mailservers
(.stringify js/JSON (clj->js enodes)) (.stringify js/JSON (clj->js enodes))
(handlers/response-handler #(log/debug "mailserver: update-mailservers success" %) (handlers/response-handler
#(log/debug "mailserver: update-mailservers success" %)
#(log/error "mailserver: update-mailservers error" %)))) #(log/error "mailserver: update-mailservers error" %))))
(defn remove-peer! [enode] (defn remove-peer! [enode]
@ -108,7 +94,8 @@
:params [enode]} :params [enode]}
payload (.stringify js/JSON (clj->js args))] payload (.stringify js/JSON (clj->js args))]
(status/call-private-rpc payload (status/call-private-rpc payload
(handlers/response-handler #(log/debug "mailserver: remove-peer success" %) (handlers/response-handler
#(log/debug "mailserver: remove-peer success" %)
#(log/error "mailserver: remove-peer error" %))))) #(log/error "mailserver: remove-peer error" %)))))
(re-frame/reg-fx (re-frame/reg-fx
@ -151,10 +138,13 @@
(reset! success-counter 0))) (reset! success-counter 0)))
(defn mark-trusted-peer! [enode] (defn mark-trusted-peer! [enode]
(json-rpc/call {:method "shh_markTrustedPeer" (json-rpc/call
{:method "shh_markTrustedPeer"
:params [enode] :params [enode]
:on-success #(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-success %]) :on-success
:on-error #(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-error %])})) #(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-success %])
:on-error
#(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-error %])}))
(re-frame/reg-fx (re-frame/reg-fx
:mailserver/mark-trusted-peer :mailserver/mark-trusted-peer
@ -163,11 +153,16 @@
(fx/defn generate-mailserver-symkey (fx/defn generate-mailserver-symkey
[{:keys [db] :as cofx} {:keys [password id] :as mailserver}] [{:keys [db] :as cofx} {:keys [password id] :as mailserver}]
(let [current-fleet (node/current-fleet-key db)] (let [current-fleet (node/current-fleet-key db)]
{:db (assoc-in db [:mailserver/mailservers current-fleet id :generating-sym-key?] true) {:db (assoc-in db [:mailserver/mailservers current-fleet id
:generating-sym-key?]
true)
:shh/generate-sym-key-from-password :shh/generate-sym-key-from-password
[{:password password [{:password password
:on-success (fn [_ sym-key-id] :on-success
(re-frame/dispatch [:mailserver.callback/generate-mailserver-symkey-success mailserver sym-key-id])) (fn [_ sym-key-id]
(re-frame/dispatch
[:mailserver.callback/generate-mailserver-symkey-success
mailserver sym-key-id]))
:on-error #(log/error "mailserver: get-sym-key error" %)}]})) :on-error #(log/error "mailserver: get-sym-key error" %)}]}))
(defn registered-peer? (defn registered-peer?
@ -181,7 +176,8 @@
(fx/defn mark-trusted-peer (fx/defn mark-trusted-peer
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver} (fetch-current cofx)] (let [{:keys [address sym-key-id generating-sym-key?] :as mailserver}
(fetch-current db)]
(fx/merge cofx (fx/merge cofx
{:db (update-mailserver-state db :added) {:db (update-mailserver-state db :added)
:mailserver/mark-trusted-peer address} :mailserver/mark-trusted-peer address}
@ -190,14 +186,17 @@
(fx/defn add-peer (fx/defn add-peer
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver} (fetch-current cofx)] (let [{:keys [address sym-key-id generating-sym-key?] :as mailserver}
(fx/merge cofx (fetch-current db)]
(fx/merge
cofx
{:db (-> db {:db (-> db
(update-mailserver-state :connecting) (update-mailserver-state :connecting)
(update :mailserver/connection-checks inc)) (update :mailserver/connection-checks inc))
:mailserver/add-peer address :mailserver/add-peer address
;; Any message sent before this takes effect will not be marked as sent ;; Any message sent before this takes effect will not be marked as sent
;; probably we should improve the UX so that is more transparent to the user ;; probably we should improve the UX so that is more transparent to the
;; user
:mailserver/update-mailservers [address] :mailserver/update-mailservers [address]
:utils/dispatch-later [{:ms constants/connection-timeout :utils/dispatch-later [{:ms constants/connection-timeout
:dispatch [:mailserver/check-connection-timeout]}]} :dispatch [:mailserver/check-connection-timeout]}]}
@ -218,8 +217,9 @@
this is successful this is successful
A connection-check is made after `connection timeout` is reached and A connection-check is made after `connection timeout` is reached and
mailserver-state is changed to error if it is not connected by then" mailserver-state is changed to error if it is not connected by then"
{:events [:mailserver.ui/reconnect-mailserver-pressed]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [address]} (fetch-current cofx) (let [{:keys [address]} (fetch-current db)
{:keys [peers-summary]} db {:keys [peers-summary]} db
added? (registered-peer? peers-summary address) added? (registered-peer? peers-summary address)
gap-request? (executing-gap-request? db)] gap-request? (executing-gap-request? db)]
@ -232,6 +232,47 @@
(mark-trusted-peer) (mark-trusted-peer)
(add-peer))))) (add-peer)))))
(defn pool-size [fleet-size]
(.ceil js/Math (/ fleet-size 4)))
(fx/defn get-mailservers-latency
[{:keys [db] :as cofx}]
(let [current-fleet (node/current-fleet-key db)
addresses (mapv :address (-> db
:mailserver/mailservers
current-fleet
vals))]
{::json-rpc/call [{:method "mailservers_ping"
:params [{:addresses addresses
:timeoutMs 500}]
:on-success
#(re-frame/dispatch [::get-latency-callback %])}]}))
(fx/defn set-current-mailserver-with-lowest-latency
"Picks a random mailserver amongs the ones with the lowest latency
The results with error are ignored
The pool size is 1/4 of the mailservers were pinged successfully"
{:events [::get-latency-callback]}
[{:keys [db] :as cofx} latency-results]
(let [successful-pings (remove :error latency-results)]
(when (seq successful-pings)
(let [address (-> (take (pool-size (count successful-pings))
(sort-by :rttMs successful-pings))
rand-nth
:address)
mailserver-id (mailserver-address->id db address)]
(fx/merge cofx
{:db (assoc db :mailserver/current-id mailserver-id)}
(connect-to-mailserver))))))
(fx/defn set-current-mailserver
[{:keys [db] :as cofx}]
(if-let [mailserver-id (get-selected-mailserver db)]
(fx/merge cofx
{:db (assoc db :mailserver/current-id mailserver-id)}
(connect-to-mailserver))
(get-mailservers-latency cofx)))
(fx/defn peers-summary-change (fx/defn peers-summary-change
"There is only 2 summary changes that require mailserver action: "There is only 2 summary changes that require mailserver action:
- mailserver disconnected: we try to reconnect - mailserver disconnected: we try to reconnect
@ -239,7 +280,7 @@
[{:keys [db] :as cofx} previous-summary] [{:keys [db] :as cofx} previous-summary]
(when (:multiaccount db) (when (:multiaccount db)
(let [{:keys [peers-summary peers-count]} db (let [{:keys [peers-summary peers-count]} db
{:keys [address sym-key-id] :as mailserver} (fetch-current cofx) {:keys [address sym-key-id] :as mailserver} (fetch-current db)
mailserver-was-registered? (registered-peer? previous-summary mailserver-was-registered? (registered-peer? previous-summary
address) address)
mailserver-is-registered? (registered-peer? peers-summary mailserver-is-registered? (registered-peer? peers-summary
@ -260,7 +301,8 @@
whisper-tolerance (:whisper-drift-tolerance protocol/whisper-opts) whisper-tolerance (:whisper-drift-tolerance protocol/whisper-opts)
adjustment (+ whisper-tolerance ttl) adjustment (+ whisper-tolerance ttl)
adjusted-from (- (max from adjustment) adjustment)] adjusted-from (- (max from adjustment) adjustment)]
(log/debug "Adjusting mailserver request" "from:" from "adjusted-from:" adjusted-from) (log/debug "Adjusting mailserver request" "from:" from
"adjusted-from:" adjusted-from)
adjusted-from)) adjusted-from))
(defn chats->never-synced-public-chats [chats] (defn chats->never-synced-public-chats [chats]
@ -269,25 +311,33 @@
(fx/defn handle-request-success [{{:keys [chats] :as db} :db} (fx/defn handle-request-success [{{:keys [chats] :as db} :db}
{:keys [request-id topics]}] {:keys [request-id topics]}]
(when (:mailserver/current-request db) (when (:mailserver/current-request db)
(let [by-topic-never-synced-chats (reduce-kv (let [by-topic-never-synced-chats
(reduce-kv
#(assoc %1 (transport.utils/get-topic %2) %3) #(assoc %1 (transport.utils/get-topic %2) %3)
{} {}
(chats->never-synced-public-chats chats)) (chats->never-synced-public-chats chats))
never-synced-chats-in-this-request (select-keys by-topic-never-synced-chats (vec topics))] never-synced-chats-in-this-request
(select-keys by-topic-never-synced-chats (vec topics))]
(if (seq never-synced-chats-in-this-request) (if (seq never-synced-chats-in-this-request)
{:db (-> db {:db
((fn [db] (reduce (-> db
((fn [db]
(reduce
(fn [db chat] (fn [db chat]
(assoc-in db [:chats (:chat-id chat) :join-time-mail-request-id] request-id)) (assoc-in db [:chats (:chat-id chat)
:join-time-mail-request-id] request-id))
db db
(vals never-synced-chats-in-this-request)))) (vals never-synced-chats-in-this-request))))
(assoc-in [:mailserver/current-request :request-id] request-id))} (assoc-in [:mailserver/current-request :request-id]
{:db (assoc-in db [:mailserver/current-request :request-id] request-id)})))) request-id))}
{:db (assoc-in db [:mailserver/current-request :request-id]
request-id)}))))
(defn request-messages! (defn request-messages!
[{:keys [sym-key-id address]} {:keys [topics cursor to from force-to?] :as request}] [{:keys [sym-key-id address]}
;; Add some room to from, unless we break day boundaries so that messages that have {:keys [topics cursor to from force-to?] :as request}]
;; been received after the last request are also fetched ;; Add some room to from, unless we break day boundaries so that
;; messages that have been received after the last request are also fetched
(let [actual-from (adjust-request-for-transit-time from) (let [actual-from (adjust-request-for-transit-time from)
actual-limit (or (:limit request) actual-limit (or (:limit request)
@limit)] @limit)]
@ -299,7 +349,8 @@
" range " (- to from) " range " (- to from)
" cursor " cursor " cursor " cursor
" limit " actual-limit) " limit " actual-limit)
(json-rpc/call {:method "shhext_requestMessages" (json-rpc/call
{:method "shhext_requestMessages"
:params [(cond-> {:topics topics :params [(cond-> {:topics topics
:mailServerPeer address :mailServerPeer address
:symKeyID sym-key-id :symKeyID sym-key-id
@ -310,11 +361,17 @@
force-to? force-to?
(assoc :to to))] (assoc :to to))]
:on-success (fn [request-id] :on-success (fn [request-id]
(log/info "mailserver: messages request success for topic " topics "from" from "to" to) (log/info "mailserver: messages request success for topic "
(re-frame/dispatch [:mailserver.callback/request-success {:request-id request-id :topics topics}])) topics "from" from "to" to)
(re-frame/dispatch
[:mailserver.callback/request-success
{:request-id request-id :topics topics}]))
:on-error (fn [error] :on-error (fn [error]
(log/error "mailserver: messages request error for topic " topics ": " error) (log/error "mailserver: messages request error for topic "
(utils/set-timeout #(re-frame/dispatch [:mailserver.callback/resend-request {:request-id nil}]) topics ": " error)
(utils/set-timeout
#(re-frame/dispatch
[:mailserver.callback/resend-request {:request-id nil}])
constants/backoff-interval-ms))}))) constants/backoff-interval-ms))})))
(re-frame/reg-fx (re-frame/reg-fx
@ -325,7 +382,7 @@
(defn get-mailserver-when-ready (defn get-mailserver-when-ready
"return the mailserver if the mailserver is ready" "return the mailserver if the mailserver is ready"
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [sym-key-id] :as mailserver} (fetch-current cofx) (let [{:keys [sym-key-id] :as mailserver} (fetch-current db)
mailserver-state (:mailserver/state db)] mailserver-state (:mailserver/state db)]
(when (and (= :connected mailserver-state) (when (and (= :connected mailserver-state)
sym-key-id) sym-key-id)
@ -415,10 +472,13 @@
mailserver is ready" mailserver is ready"
[{:keys [db] :as cofx} {:keys [id]} sym-key-id] [{:keys [db] :as cofx} {:keys [id]} sym-key-id]
(let [current-fleet (node/current-fleet-key db)] (let [current-fleet (node/current-fleet-key db)]
(fx/merge cofx (fx/merge
cofx
{:db (-> db {:db (-> db
(assoc-in [:mailserver/mailservers current-fleet id :sym-key-id] sym-key-id) (assoc-in [:mailserver/mailservers current-fleet id :sym-key-id]
(update-in [:mailserver/mailservers current-fleet id] dissoc :generating-sym-key?))} sym-key-id)
(update-in [:mailserver/mailservers current-fleet id]
dissoc :generating-sym-key?))}
(process-next-messages-request)))) (process-next-messages-request))))
(fx/defn change-mailserver (fx/defn change-mailserver
@ -426,7 +486,7 @@
otherwise try to reconnect to another mailserver" otherwise try to reconnect to another mailserver"
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(when-not (zero? (:peers-count db)) (when-not (zero? (:peers-count db))
(if-let [preferred-mailserver (preferred-mailserver-id cofx)] (if-let [preferred-mailserver (preferred-mailserver-id db)]
(let [current-fleet (node/current-fleet-key db)] (let [current-fleet (node/current-fleet-key db)]
{:db {:db
(update-mailserver-state db :error) (update-mailserver-state db :error)
@ -444,11 +504,10 @@
current-fleet current-fleet
preferred-mailserver]) preferred-mailserver])
:style "default"}]}}) :style "default"}]}})
(let [{:keys [address]} (fetch-current cofx)] (let [{:keys [address]} (fetch-current db)]
(fx/merge cofx (fx/merge cofx
{:mailserver/remove-peer address} {:mailserver/remove-peer address}
(set-current-mailserver) (set-current-mailserver))))))
(connect-to-mailserver))))))
(fx/defn check-connection (fx/defn check-connection
"connection-checks counter is used to prevent changing "connection-checks counter is used to prevent changing
@ -659,7 +718,8 @@
ranges (:mailserver/ranges db) ranges (:mailserver/ranges db)
prepared-new-gaps (prepare-new-gaps new-gaps ranges request chat-ids)] prepared-new-gaps (prepare-new-gaps new-gaps ranges request chat-ids)]
(fx/merge cofx (fx/merge
cofx
{:db {:db
(reduce (fn [db chat-id] (reduce (fn [db chat-id]
(let [chats-deleted-gaps (get deleted-gaps chat-id) (let [chats-deleted-gaps (get deleted-gaps chat-id)
@ -718,7 +778,8 @@
:mailserver/request-messages {:mailserver mailserver :mailserver/request-messages {:mailserver mailserver
:request request-with-cursor}})) :request request-with-cursor}}))
(let [{:keys [gap chat-id]} request] (let [{:keys [gap chat-id]} request]
(fx/merge cofx (fx/merge
cofx
{:db (-> db {:db (-> db
(dissoc :mailserver/current-request) (dissoc :mailserver/current-request)
(update :mailserver/requests-from (update :mailserver/requests-from
@ -737,8 +798,10 @@
(mapv (fn [[topic mailserver-topic]] (mapv (fn [[topic mailserver-topic]]
{:method "mailservers_addMailserverTopic" {:method "mailservers_addMailserverTopic"
:params [(assoc mailserver-topic :topic topic)] :params [(assoc mailserver-topic :topic topic)]
:on-success #(log/debug "added mailserver-topic successfully") :on-success
:on-failure #(log/error "failed to delete mailserver topic" %)}) #(log/debug "added mailserver-topic successfully")
:on-failure
#(log/error "failed to delete mailserver topic" %)})
mailserver-topics)} mailserver-topics)}
(process-next-messages-request)))))))) (process-next-messages-request))))))))
@ -772,7 +835,8 @@
(fx/merge (fx/merge
cofx cofx
{:mailserver/increase-limit [] {:mailserver/increase-limit []
:dispatch-n (map :dispatch-n
(map
#(identity [:chat.ui/join-time-messages-checked %]) #(identity [:chat.ui/join-time-messages-checked %])
never-synced-chats-in-request)} never-synced-chats-in-request)}
(update-chats-and-gaps cursor) (update-chats-and-gaps cursor)
@ -781,7 +845,8 @@
(fx/merge (fx/merge
cofx cofx
{:mailserver/increase-limit [] {:mailserver/increase-limit []
:dispatch-later (vec :dispatch-later
(vec
(map (map
#(identity #(identity
{:ms 1000 {:ms 1000
@ -803,18 +868,20 @@
(let [mailserver-error (:mailserver/request-error db)] (let [mailserver-error (:mailserver/request-error db)]
{:utils/show-confirmation {:utils/show-confirmation
{:title (i18n/label :t/mailserver-request-error-title) {:title (i18n/label :t/mailserver-request-error-title)
:content (i18n/label :t/mailserver-request-error-content {:error mailserver-error}) :content (i18n/label :t/mailserver-request-error-content
{:error mailserver-error})
:on-accept #(re-frame/dispatch [:mailserver.ui/retry-request-pressed]) :on-accept #(re-frame/dispatch [:mailserver.ui/retry-request-pressed])
:confirm-button-text (i18n/label :t/mailserver-request-retry)}})) :confirm-button-text (i18n/label :t/mailserver-request-retry)}}))
(fx/defn fetch-history (fx/defn fetch-history
"Retrive a list of topics given a chat id, set them to the specified time interval "Retrive a list of topics given a chat id, set them to the specified
and start a mailserver request" time interval and start a mailserver request"
[{:keys [db] :as cofx} chat-id {:keys [from to]}] [{:keys [db] :as cofx} chat-id {:keys [from to]}]
(let [topics (mailserver.topics/topics-for-chat (let [topics (mailserver.topics/topics-for-chat
db db
chat-id)] chat-id)]
(log/debug "fetch-history" "chat-id:" chat-id "from-timestamp:" from "topics:" topics) (log/debug "fetch-history" "chat-id:" chat-id "from-timestamp:"
from "topics:" topics)
(fx/merge cofx (fx/merge cofx
{:db (reduce {:db (reduce
(fn [db topic] (fn [db topic]
@ -885,11 +952,15 @@
(dissoc :mailserver/planned-gap-requests))} (dissoc :mailserver/planned-gap-requests))}
mailserver mailserver
(let [{:keys [topics from to cursor limit] :as request} current-request] (let [{:keys [topics from to cursor limit] :as request}
(log/info "mailserver: message request " request-id "expired for mailserver topic" topics "from" from "to" to "cursor" cursor "limit" (decrease-limit)) current-request]
(log/info "mailserver: message request " request-id
"expired for mailserver topic" topics "from" from
"to" to "cursor" cursor "limit" (decrease-limit))
{:db (update-in db [:mailserver/current-request :attempts] inc) {:db (update-in db [:mailserver/current-request :attempts] inc)
:mailserver/decrease-limit [] :mailserver/decrease-limit []
:mailserver/request-messages {:mailserver mailserver :mailserver/request-messages
{:mailserver mailserver
:request (assoc request :limit (decrease-limit))}}) :request (assoc request :limit (decrease-limit))}})
:else :else
@ -901,8 +972,10 @@
{:mailserver/set-limit constants/default-limit} {:mailserver/set-limit constants/default-limit}
(set-current-mailserver))) (set-current-mailserver)))
(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})") (def enode-address-regex
(def enode-url-regex #"enode://[a-zA-Z0-9]+:(.+)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})") #"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
(def enode-url-regex
#"enode://[a-zA-Z0-9]+:(.+)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
(defn- extract-address-components [address] (defn- extract-address-components [address]
(rest (re-matches #"enode://(.*)@(.*)" address))) (rest (re-matches #"enode://(.*)@(.*)" address)))
@ -948,7 +1021,7 @@
(def default? (comp not :user-defined fetch)) (def default? (comp not :user-defined fetch))
(fx/defn edit [{:keys [db] :as cofx} id] (fx/defn edit [{:keys [db] :as cofx} id]
(let [{:keys [id address password name]} (fetch cofx id) (let [{:keys [id address password name]} (fetch db id)
url (when address (build-url address password))] url (when address (build-url address password))]
(fx/merge cofx (fx/merge cofx
(set-input :id id) (set-input :id id)
@ -972,10 +1045,11 @@
(keyword (string/replace (random-id-generator) "-" ""))) (keyword (string/replace (random-id-generator) "-" "")))
(:value name) (:value name)
(:value url)) (:value url))
current (connected? cofx (:id mailserver))] current (connected? db (:id mailserver))]
{:db (-> db {:db (-> db
(dissoc :mailserver.edit/mailserver) (dissoc :mailserver.edit/mailserver)
(assoc-in [:mailserver/mailservers current-fleet (:id mailserver)] mailserver)) (assoc-in [:mailserver/mailservers current-fleet (:id mailserver)]
mailserver))
::json-rpc/call ::json-rpc/call
[{:method "mailservers_addMailserver" [{:method "mailservers_addMailserver"
:params [(mailserver->rpc mailserver current-fleet)] :params [(mailserver->rpc mailserver current-fleet)]
@ -990,13 +1064,13 @@
:dispatch [:navigate-back]})) :dispatch [:navigate-back]}))
(defn can-delete? (defn can-delete?
[cofx id] [db id]
(not (or (default? cofx id) (not (or (default? db id)
(connected? cofx id)))) (connected? db id))))
(fx/defn delete (fx/defn delete
[{:keys [db] :as cofx} id] [{:keys [db] :as cofx} id]
(if (can-delete? cofx id) (if (can-delete? db id)
{:db (update-in db {:db (update-in db
[:mailserver/mailservers (node/current-fleet-key db)] [:mailserver/mailservers (node/current-fleet-key db)]
dissoc id) dissoc id)
@ -1013,10 +1087,14 @@
(let [current-fleet (node/current-fleet-key db)] (let [current-fleet (node/current-fleet-key db)]
{:ui/show-confirmation {:ui/show-confirmation
{:title (i18n/label :t/close-app-title) {:title (i18n/label :t/close-app-title)
:content (i18n/label :t/connect-mailserver-content :content
{:name (get-in db [:mailserver/mailservers current-fleet mailserver-id :name])}) (i18n/label :t/connect-mailserver-content
{:name (get-in db [:mailserver/mailservers
current-fleet mailserver-id :name])})
:confirm-button-text (i18n/label :t/close-app-button) :confirm-button-text (i18n/label :t/close-app-button)
:on-accept #(re-frame/dispatch [:mailserver.ui/connect-confirmed current-fleet mailserver-id]) :on-accept
#(re-frame/dispatch
[:mailserver.ui/connect-confirmed current-fleet mailserver-id])
:on-cancel nil}})) :on-cancel nil}}))
(fx/defn show-delete-confirmation (fx/defn show-delete-confirmation
@ -1025,7 +1103,8 @@
{:title (i18n/label :t/delete-mailserver-title) {:title (i18n/label :t/delete-mailserver-title)
:content (i18n/label :t/delete-mailserver-are-you-sure) :content (i18n/label :t/delete-mailserver-are-you-sure)
:confirm-button-text (i18n/label :t/delete-mailserver) :confirm-button-text (i18n/label :t/delete-mailserver)
:on-accept #(re-frame/dispatch [:mailserver.ui/delete-confirmed mailserver-id])}}) :on-accept #(re-frame/dispatch
[:mailserver.ui/delete-confirmed mailserver-id])}})
(fx/defn set-url-from-qr (fx/defn set-url-from-qr
[cofx url] [cofx url]
@ -1034,7 +1113,7 @@
(fx/defn save-settings (fx/defn save-settings
[{:keys [db] :as cofx} current-fleet mailserver-id] [{:keys [db] :as cofx} current-fleet mailserver-id]
(let [{:keys [address]} (fetch-current cofx) (let [{:keys [address]} (fetch-current db)
settings (get-in db [:multiaccount :settings]) settings (get-in db [:multiaccount :settings])
;; Check if previous mailserver was pinned ;; Check if previous mailserver was pinned
pinned? (get-in settings [:mailserver current-fleet])] pinned? (get-in settings [:mailserver current-fleet])]
@ -1043,7 +1122,8 @@
:mailserver/remove-peer address} :mailserver/remove-peer address}
(connect-to-mailserver) (connect-to-mailserver)
(when pinned? (when pinned?
(multiaccounts.update/update-settings (assoc-in settings [:mailserver current-fleet] mailserver-id) (multiaccounts.update/update-settings
(assoc-in settings [:mailserver current-fleet] mailserver-id)
{}))))) {})))))
(fx/defn unpin (fx/defn unpin
@ -1051,7 +1131,8 @@
(let [current-fleet (node/current-fleet-key db) (let [current-fleet (node/current-fleet-key db)
settings (get-in db [:multiaccount :settings])] settings (get-in db [:multiaccount :settings])]
(fx/merge cofx (fx/merge cofx
(multiaccounts.update/update-settings (update settings :mailserver dissoc current-fleet) (multiaccounts.update/update-settings
(update settings :mailserver dissoc current-fleet)
{}) {})
(change-mailserver)))) (change-mailserver))))
@ -1061,7 +1142,8 @@
mailserver-id (:mailserver/current-id db) mailserver-id (:mailserver/current-id db)
settings (get-in db [:multiaccount :settings])] settings (get-in db [:multiaccount :settings])]
(fx/merge cofx (fx/merge cofx
(multiaccounts.update/update-settings (assoc-in settings [:mailserver current-fleet] mailserver-id) (multiaccounts.update/update-settings
(assoc-in settings [:mailserver current-fleet] mailserver-id)
{})))) {}))))
(fx/defn load-gaps-fx [{:keys [db] :as cofx} chat-id] (fx/defn load-gaps-fx [{:keys [db] :as cofx} chat-id]
@ -1073,7 +1155,9 @@
{:events [::gaps-loaded]} {:events [::gaps-loaded]}
[{:keys [db now] :as cofx} chat-id gaps] [{:keys [db now] :as cofx} chat-id gaps]
(let [now-s (quot now 1000) (let [now-s (quot now 1000)
outdated-gaps (into [] (comp (filter #(< (:to %) outdated-gaps
(into []
(comp (filter #(< (:to %)
(- now-s constants/max-gaps-range))) (- now-s constants/max-gaps-range)))
(map :id)) (map :id))
(vals gaps)) (vals gaps))

View File

@ -42,8 +42,7 @@
(fetch-node-info-fx) (fetch-node-info-fx)
(pairing/init) (pairing/init)
(publisher/start-fx) (publisher/start-fx)
(mailserver/initialize-mailserver) (mailserver/initialize-mailserver)))
(mailserver/connect-to-mailserver)))
(fx/defn stop-whisper (fx/defn stop-whisper
"Stops whisper protocol" "Stops whisper protocol"

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead", "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im", "owner": "status-im",
"repo": "status-go", "repo": "status-go",
"version": "develop", "version": "v0.35.1",
"commit-sha1": "5f6c7008e19227392589a917def8db3780fcc5db", "commit-sha1": "4769fb91c3247c72c21013bf36194843d8d72d18",
"src-sha256": "0akpf4k7i5rpna0vb2m6lsy7lgsgv19g5lszxhysiacpf37q0hxv" "src-sha256": "1b6050kvnvf69gqw5llb7gb5v25pq6vbhkf9nznk9ra2spasqqzy"
} }

View File

@ -45,14 +45,14 @@
:peers-count 1}}))))) :peers-count 1}})))))
(testing "there's not a preferred mailserver" (testing "there's not a preferred mailserver"
(testing "it changes the mailserver" (testing "it changes the mailserver"
(is (= :a (is (= "mailservers_ping"
(get-in (get-in
(mailserver/change-mailserver (mailserver/change-mailserver
{:db {:mailserver/mailservers {:staging {:a "b"}} {:db {:mailserver/mailservers {:staging {:a "b"}}
:multiaccount {:settings :multiaccount {:settings
{:fleet :staging}} {:fleet :staging}}
:peers-count 1}}) :peers-count 1}})
[:db :mailserver/current-id])))) [::json-rpc/call 0 :method]))))
(testing "it does not show the popup" (testing "it does not show the popup"
(is (not (:ui/show-confirmation (mailserver/change-mailserver (is (not (:ui/show-confirmation (mailserver/change-mailserver
{:db {:peers-count 1}})))))))) {:db {:peers-count 1}}))))))))
@ -179,28 +179,27 @@
(deftest connected-mailserver (deftest connected-mailserver
(testing "it returns true when set in mailserver/current-id" (testing "it returns true when set in mailserver/current-id"
(let [cofx {:db {:mailserver/current-id "a"}}] (let [db {:mailserver/current-id "a"}]
(is (mailserver/connected? cofx "a")))) (is (mailserver/connected? db "a"))))
(testing "it returns false otherwise" (testing "it returns false otherwise"
(is (not (mailserver/connected? {:db {}} "a"))))) (is (not (mailserver/connected? {} "a")))))
(deftest fetch-mailserver (deftest fetch-mailserver
(testing "it fetches the mailserver from the db" (testing "it fetches the mailserver from the db"
(let [cofx {:db {:mailserver/mailservers {:eth.staging {"a" {:id "a" (let [db {:mailserver/mailservers {:eth.staging {"a" {:id "a"
:name "old-name" :name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}] :address "enode://old-id:old-password@url:port"}}}}]
(is (mailserver/fetch cofx "a"))))) (is (mailserver/fetch db "a")))))
(deftest fetch-current-mailserver (deftest fetch-current-mailserver
(testing "it fetches the mailserver from the db with corresponding id" (testing "it fetches the mailserver from the db with corresponding id"
(let [cofx {:db {:mailserver/current-id "a" (let [db {:mailserver/current-id "a"
:mailserver/mailservers {:eth.staging {"a" {:id "a" :mailserver/mailservers {:eth.staging {"a" {:id "a"
:name "old-name" :name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}] :address "enode://old-id:old-password@url:port"}}}}]
(is (mailserver/fetch-current cofx))))) (is (mailserver/fetch-current db)))))
(deftest set-current-mailserver (deftest set-current-mailserver
(with-redefs [rand-nth (comp last sort)]
(let [cofx {:db {:mailserver/mailservers {:eth.staging {"a" {} (let [cofx {:db {:mailserver/mailservers {:eth.staging {"a" {}
"b" {} "b" {}
"c" {} "c" {}
@ -216,36 +215,46 @@
:mailserver/current-id))))) :mailserver/current-id)))))
(testing "the mailserver does not exists" (testing "the mailserver does not exists"
(let [cofx (update-in cofx [:db :mailserver/mailservers :eth.staging] dissoc "a")] (let [cofx (update-in cofx [:db :mailserver/mailservers :eth.staging] dissoc "a")]
(testing "sets a random mailserver" (testing "look for fastest mailserver"
(is (= "d" (-> (mailserver/set-current-mailserver cofx) (is (= "mailservers_ping"
:db (-> (mailserver/set-current-mailserver cofx)
:mailserver/current-id)))))))) ::json-rpc/call
first
:method))))))))
(testing "the user has not set an explicit preference" (testing "the user has not set an explicit preference"
(testing "current-id is not set" (testing "current-id is not set"
(testing "it sets a random mailserver" (testing "it looks for fastest mailserver"
(is (= "d" (-> (mailserver/set-current-mailserver cofx) (is (= "mailservers_ping"
:db (-> (mailserver/set-current-mailserver cofx)
:mailserver/current-id))))) ::json-rpc/call
first
:method)))))
(testing "current-id is set" (testing "current-id is set"
(testing "it sets the next mailserver" (testing "it looks for fastest mailserver"
(is (= "c" (-> (mailserver/set-current-mailserver (assoc-in (is (= "mailservers_ping"
(-> (mailserver/set-current-mailserver (assoc-in
cofx cofx
[:db :mailserver/current-id] [:db :mailserver/current-id]
"b")) "b"))
:db ::json-rpc/call
:mailserver/current-id))) first
(is (= "a" (-> (mailserver/set-current-mailserver (assoc-in :method)))
(is (= "mailservers_ping"
(-> (mailserver/set-current-mailserver (assoc-in
cofx cofx
[:db :mailserver/current-id] [:db :mailserver/current-id]
"d")) "d"))
:db ::json-rpc/call
:mailserver/current-id))) first
(is (= "a" (-> (mailserver/set-current-mailserver (assoc-in :method)))
(is (= "mailservers_ping"
(-> (mailserver/set-current-mailserver (assoc-in
cofx cofx
[:db :mailserver/current-id] [:db :mailserver/current-id]
"non-existing")) "non-existing"))
:db ::json-rpc/call
:mailserver/current-id))))))))) first
:method))))))))
(deftest delete-mailserver (deftest delete-mailserver
(testing "the user is not connected to the mailserver" (testing "the user is not connected to the mailserver"
@ -256,7 +265,7 @@
:address "enode://old-id:old-password@url:port"}}}}} :address "enode://old-id:old-password@url:port"}}}}}
actual (mailserver/delete cofx "a")] actual (mailserver/delete cofx "a")]
(testing "it removes the mailserver from the list" (testing "it removes the mailserver from the list"
(is (not (mailserver/fetch actual "a")))) (is (not (mailserver/fetch (:db actual) "a"))))
(testing "it stores it in the db" (testing "it stores it in the db"
(is (= 1 (count (::json-rpc/call actual))))))) (is (= 1 (count (::json-rpc/call actual)))))))
(testing "the mailserver is not user-defined" (testing "the mailserver is not user-defined"
@ -343,12 +352,14 @@
(testing "there's a current request" (testing "there's a current request"
(testing "it reached the maximum number of attempts" (testing "it reached the maximum number of attempts"
(testing "it changes mailserver" (testing "it changes mailserver"
(is (= :connecting (is (= "mailservers_ping"
(get-in (mailserver/resend-request (-> (mailserver/resend-request
{:db {:mailserver/current-request {:db {:mailserver/current-request
{:attempts constants/maximum-number-of-attempts}}} {:attempts constants/maximum-number-of-attempts}}}
{}) {})
[:db :mailserver/state]))))) ::json-rpc/call
first
:method)))))
(testing "it did not reach the maximum number of attempts" (testing "it did not reach the maximum number of attempts"
(testing "it reached the maximum number of attempts" (testing "it reached the maximum number of attempts"
(testing "it decrease the limit") (testing "it decrease the limit")