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" {}
"accounts_getAccounts" {}
"accounts_saveAccounts" {}
"mailservers_ping" {}
"mailservers_addMailserver" {}
"mailservers_getMailservers" {}
"mailservers_deleteMailserver" {}

View File

@ -245,11 +245,6 @@
(fn [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
:mailserver.ui/unpin-pressed
(fn [cofx _]

View File

@ -40,57 +40,42 @@
(def limit (atom constants/default-limit))
(def success-counter (atom 0))
(defn connected? [{:keys [db]} id]
(defn connected? [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]))
(defn fetch-current [{:keys [db] :as cofx}]
(fetch cofx (:mailserver/current-id db)))
(defn fetch-current [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)]))
(defn- round-robin
"Find the choice and pick the next one, default to first if not found"
[choices current-id]
(let [next-index (reduce
(fn [index choice]
(if (= current-id choice)
(reduced (inc index))
(inc index)))
0
choices)]
(nth choices
(mod
next-index
(count choices)))))
(defn mailserver-address->id [db address]
(let [current-fleet (node/current-fleet-key db)]
(:id (some #(when (= address (:address %))
%)
(-> db
:mailserver/mailservers
current-fleet
vals)))))
(defn selected-or-random-id
"Use the preferred mailserver if set & exists, otherwise picks one randomly
if current-id is not set, else round-robin"
[{:keys [db] :as cofx}]
(defn get-selected-mailserver
"Use the preferred mailserver if set & exists"
[db]
(let [current-fleet (node/current-fleet-key db)
current-id (:mailserver/current-id db)
preference (preferred-mailserver-id cofx)
choices (-> db :mailserver/mailservers current-fleet keys)]
(if (and preference
(fetch cofx 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))})
preference (preferred-mailserver-id db)]
(when (and preference
(fetch db preference))
preference)))
(defn add-peer! [enode]
(status/add-peer enode
(handlers/response-handler #(log/debug "mailserver: add-peer success" %)
#(log/error "mailserver: add-peer error" %))))
(handlers/response-handler
#(log/debug "mailserver: add-peer success" %)
#(log/error "mailserver: add-peer error" %))))
;; We now wait for a confirmation from the mailserver before marking the message
;; as sent.
@ -98,8 +83,9 @@
(defn update-mailservers! [enodes]
(status/update-mailservers
(.stringify js/JSON (clj->js enodes))
(handlers/response-handler #(log/debug "mailserver: update-mailservers success" %)
#(log/error "mailserver: update-mailservers error" %))))
(handlers/response-handler
#(log/debug "mailserver: update-mailservers success" %)
#(log/error "mailserver: update-mailservers error" %))))
(defn remove-peer! [enode]
(let [args {:jsonrpc "2.0"
@ -108,8 +94,9 @@
:params [enode]}
payload (.stringify js/JSON (clj->js args))]
(status/call-private-rpc payload
(handlers/response-handler #(log/debug "mailserver: remove-peer success" %)
#(log/error "mailserver: remove-peer error" %)))))
(handlers/response-handler
#(log/debug "mailserver: remove-peer success" %)
#(log/error "mailserver: remove-peer error" %)))))
(re-frame/reg-fx
:mailserver/add-peer
@ -151,10 +138,13 @@
(reset! success-counter 0)))
(defn mark-trusted-peer! [enode]
(json-rpc/call {:method "shh_markTrustedPeer"
:params [enode]
:on-success #(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-success %])
:on-error #(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-error %])}))
(json-rpc/call
{:method "shh_markTrustedPeer"
:params [enode]
:on-success
#(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-success %])
:on-error
#(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-error %])}))
(re-frame/reg-fx
:mailserver/mark-trusted-peer
@ -163,11 +153,16 @@
(fx/defn generate-mailserver-symkey
[{:keys [db] :as cofx} {:keys [password id] :as mailserver}]
(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
[{:password password
:on-success (fn [_ sym-key-id]
(re-frame/dispatch [:mailserver.callback/generate-mailserver-symkey-success mailserver sym-key-id]))
:on-success
(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" %)}]}))
(defn registered-peer?
@ -181,7 +176,8 @@
(fx/defn mark-trusted-peer
[{: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
{:db (update-mailserver-state db :added)
:mailserver/mark-trusted-peer address}
@ -190,19 +186,22 @@
(fx/defn add-peer
[{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver} (fetch-current cofx)]
(fx/merge cofx
{:db (-> db
(update-mailserver-state :connecting)
(update :mailserver/connection-checks inc))
:mailserver/add-peer address
;; 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
:mailserver/update-mailservers [address]
:utils/dispatch-later [{:ms constants/connection-timeout
:dispatch [:mailserver/check-connection-timeout]}]}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey mailserver)))))
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver}
(fetch-current db)]
(fx/merge
cofx
{:db (-> db
(update-mailserver-state :connecting)
(update :mailserver/connection-checks inc))
:mailserver/add-peer address
;; 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
:mailserver/update-mailservers [address]
:utils/dispatch-later [{:ms constants/connection-timeout
:dispatch [:mailserver/check-connection-timeout]}]}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey mailserver)))))
(defn executing-gap-request?
[{:mailserver/keys [current-request fetching-gaps-in-progress]}]
@ -218,8 +217,9 @@
this is successful
A connection-check is made after `connection timeout` is reached and
mailserver-state is changed to error if it is not connected by then"
{:events [:mailserver.ui/reconnect-mailserver-pressed]}
[{:keys [db] :as cofx}]
(let [{:keys [address]} (fetch-current cofx)
(let [{:keys [address]} (fetch-current db)
{:keys [peers-summary]} db
added? (registered-peer? peers-summary address)
gap-request? (executing-gap-request? db)]
@ -232,6 +232,47 @@
(mark-trusted-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
"There is only 2 summary changes that require mailserver action:
- mailserver disconnected: we try to reconnect
@ -239,7 +280,7 @@
[{:keys [db] :as cofx} previous-summary]
(when (:multiaccount 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
address)
mailserver-is-registered? (registered-peer? peers-summary
@ -260,7 +301,8 @@
whisper-tolerance (:whisper-drift-tolerance protocol/whisper-opts)
adjustment (+ whisper-tolerance ttl)
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))
(defn chats->never-synced-public-chats [chats]
@ -269,25 +311,33 @@
(fx/defn handle-request-success [{{:keys [chats] :as db} :db}
{:keys [request-id topics]}]
(when (:mailserver/current-request db)
(let [by-topic-never-synced-chats (reduce-kv
#(assoc %1 (transport.utils/get-topic %2) %3)
{}
(chats->never-synced-public-chats chats))
never-synced-chats-in-this-request (select-keys by-topic-never-synced-chats (vec topics))]
(let [by-topic-never-synced-chats
(reduce-kv
#(assoc %1 (transport.utils/get-topic %2) %3)
{}
(chats->never-synced-public-chats chats))
never-synced-chats-in-this-request
(select-keys by-topic-never-synced-chats (vec topics))]
(if (seq never-synced-chats-in-this-request)
{:db (-> db
((fn [db] (reduce
(fn [db chat]
(assoc-in db [:chats (:chat-id chat) :join-time-mail-request-id] request-id))
db
(vals never-synced-chats-in-this-request))))
(assoc-in [:mailserver/current-request :request-id] request-id))}
{:db (assoc-in db [:mailserver/current-request :request-id] request-id)}))))
{:db
(-> db
((fn [db]
(reduce
(fn [db chat]
(assoc-in db [:chats (:chat-id chat)
:join-time-mail-request-id] request-id))
db
(vals never-synced-chats-in-this-request))))
(assoc-in [:mailserver/current-request :request-id]
request-id))}
{:db (assoc-in db [:mailserver/current-request :request-id]
request-id)}))))
(defn request-messages!
[{:keys [sym-key-id address]} {:keys [topics cursor to from force-to?] :as request}]
;; Add some room to from, unless we break day boundaries so that messages that have
;; been received after the last request are also fetched
[{:keys [sym-key-id address]}
{:keys [topics cursor to from force-to?] :as request}]
;; 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)
actual-limit (or (:limit request)
@limit)]
@ -299,23 +349,30 @@
" range " (- to from)
" cursor " cursor
" limit " actual-limit)
(json-rpc/call {:method "shhext_requestMessages"
:params [(cond-> {:topics topics
:mailServerPeer address
:symKeyID sym-key-id
:timeout constants/request-timeout
:limit actual-limit
:cursor cursor
:from actual-from}
force-to?
(assoc :to to))]
:on-success (fn [request-id]
(log/info "mailserver: messages request success for topic " topics "from" from "to" to)
(re-frame/dispatch [:mailserver.callback/request-success {:request-id request-id :topics topics}]))
:on-error (fn [error]
(log/error "mailserver: messages request error for topic " topics ": " error)
(utils/set-timeout #(re-frame/dispatch [:mailserver.callback/resend-request {:request-id nil}])
constants/backoff-interval-ms))})))
(json-rpc/call
{:method "shhext_requestMessages"
:params [(cond-> {:topics topics
:mailServerPeer address
:symKeyID sym-key-id
:timeout constants/request-timeout
:limit actual-limit
:cursor cursor
:from actual-from}
force-to?
(assoc :to to))]
:on-success (fn [request-id]
(log/info "mailserver: messages request success for topic "
topics "from" from "to" to)
(re-frame/dispatch
[:mailserver.callback/request-success
{:request-id request-id :topics topics}]))
:on-error (fn [error]
(log/error "mailserver: messages request error for topic "
topics ": " error)
(utils/set-timeout
#(re-frame/dispatch
[:mailserver.callback/resend-request {:request-id nil}])
constants/backoff-interval-ms))})))
(re-frame/reg-fx
:mailserver/request-messages
@ -325,7 +382,7 @@
(defn get-mailserver-when-ready
"return the mailserver if the mailserver is ready"
[{: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)]
(when (and (= :connected mailserver-state)
sym-key-id)
@ -388,10 +445,10 @@
requests (prepare-messages-requests cofx request-to)]
(log/debug "Mailserver: planned requests " requests)
(if-let [request (first requests)]
{:db (assoc db
:mailserver/pending-requests (count requests)
:mailserver/current-request request
:mailserver/request-to request-to)
{:db (assoc db
:mailserver/pending-requests (count requests)
:mailserver/current-request request
:mailserver/request-to request-to)
:mailserver/request-messages {:mailserver mailserver
:request request}}
{:db (dissoc db
@ -415,18 +472,21 @@
mailserver is ready"
[{:keys [db] :as cofx} {:keys [id]} sym-key-id]
(let [current-fleet (node/current-fleet-key db)]
(fx/merge cofx
{:db (-> db
(assoc-in [:mailserver/mailservers current-fleet id :sym-key-id] sym-key-id)
(update-in [:mailserver/mailservers current-fleet id] dissoc :generating-sym-key?))}
(process-next-messages-request))))
(fx/merge
cofx
{:db (-> db
(assoc-in [:mailserver/mailservers current-fleet id :sym-key-id]
sym-key-id)
(update-in [:mailserver/mailservers current-fleet id]
dissoc :generating-sym-key?))}
(process-next-messages-request))))
(fx/defn change-mailserver
"mark mailserver status as `:error` if custom mailserver is used
otherwise try to reconnect to another mailserver"
[{:keys [db] :as cofx}]
(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)]
{:db
(update-mailserver-state db :error)
@ -444,11 +504,10 @@
current-fleet
preferred-mailserver])
:style "default"}]}})
(let [{:keys [address]} (fetch-current cofx)]
(let [{:keys [address]} (fetch-current db)]
(fx/merge cofx
{:mailserver/remove-peer address}
(set-current-mailserver)
(connect-to-mailserver))))))
(set-current-mailserver))))))
(fx/defn check-connection
"connection-checks counter is used to prevent changing
@ -659,22 +718,23 @@
ranges (:mailserver/ranges db)
prepared-new-gaps (prepare-new-gaps new-gaps ranges request chat-ids)]
(fx/merge cofx
{:db
(reduce (fn [db chat-id]
(let [chats-deleted-gaps (get deleted-gaps chat-id)
chats-updated-gaps (merge (get updated-gaps chat-id)
(get prepared-new-gaps chat-id))]
(update-in db [:mailserver/gaps chat-id]
(fn [chat-gaps]
(-> (apply dissoc chat-gaps chats-deleted-gaps)
(merge chats-updated-gaps))))))
db
chat-ids)}
(data-store.mailservers/delete-gaps (mapcat val deleted-gaps))
(data-store.mailservers/save-gaps
(concat (mapcat vals (vals updated-gaps))
(mapcat vals (vals prepared-new-gaps)))))))
(fx/merge
cofx
{:db
(reduce (fn [db chat-id]
(let [chats-deleted-gaps (get deleted-gaps chat-id)
chats-updated-gaps (merge (get updated-gaps chat-id)
(get prepared-new-gaps chat-id))]
(update-in db [:mailserver/gaps chat-id]
(fn [chat-gaps]
(-> (apply dissoc chat-gaps chats-deleted-gaps)
(merge chats-updated-gaps))))))
db
chat-ids)}
(data-store.mailservers/delete-gaps (mapcat val deleted-gaps))
(data-store.mailservers/save-gaps
(concat (mapcat vals (vals updated-gaps))
(mapcat vals (vals prepared-new-gaps)))))))
(fx/defn update-chats-and-gaps
[cofx cursor]
@ -714,33 +774,36 @@
(if (seq cursor)
(when-let [mailserver (get-mailserver-when-ready cofx)]
(let [request-with-cursor (assoc request :cursor cursor)]
{:db (assoc db :mailserver/current-request request-with-cursor)
{:db (assoc db :mailserver/current-request request-with-cursor)
:mailserver/request-messages {:mailserver mailserver
:request request-with-cursor}}))
(let [{:keys [gap chat-id]} request]
(fx/merge cofx
{:db (-> db
(dissoc :mailserver/current-request)
(update :mailserver/requests-from
#(apply dissoc % topics))
(update :mailserver/requests-to
#(apply dissoc % topics))
(update :mailserver/topics merge mailserver-topics)
(update :mailserver/fetching-gaps-in-progress
(fn [gaps]
(if gap
(update gaps chat-id dissoc gap)
gaps)))
(update :mailserver/planned-gap-requests
dissoc gap))
::json-rpc/call
(mapv (fn [[topic mailserver-topic]]
{:method "mailservers_addMailserverTopic"
:params [(assoc mailserver-topic :topic topic)]
:on-success #(log/debug "added mailserver-topic successfully")
:on-failure #(log/error "failed to delete mailserver topic" %)})
mailserver-topics)}
(process-next-messages-request))))))))
(fx/merge
cofx
{:db (-> db
(dissoc :mailserver/current-request)
(update :mailserver/requests-from
#(apply dissoc % topics))
(update :mailserver/requests-to
#(apply dissoc % topics))
(update :mailserver/topics merge mailserver-topics)
(update :mailserver/fetching-gaps-in-progress
(fn [gaps]
(if gap
(update gaps chat-id dissoc gap)
gaps)))
(update :mailserver/planned-gap-requests
dissoc gap))
::json-rpc/call
(mapv (fn [[topic mailserver-topic]]
{:method "mailservers_addMailserverTopic"
:params [(assoc mailserver-topic :topic topic)]
:on-success
#(log/debug "added mailserver-topic successfully")
:on-failure
#(log/error "failed to delete mailserver topic" %)})
mailserver-topics)}
(process-next-messages-request))))))))
(fx/defn retry-next-messages-request
[{:keys [db] :as cofx}]
@ -772,21 +835,23 @@
(fx/merge
cofx
{:mailserver/increase-limit []
:dispatch-n (map
#(identity [:chat.ui/join-time-messages-checked %])
never-synced-chats-in-request)}
:dispatch-n
(map
#(identity [:chat.ui/join-time-messages-checked %])
never-synced-chats-in-request)}
(update-chats-and-gaps cursor)
(update-mailserver-topics {:request-id requestID
:cursor cursor}))
(fx/merge
cofx
{:mailserver/increase-limit []
:dispatch-later (vec
(map
#(identity
{:ms 1000
:dispatch [:chat.ui/join-time-messages-checked %]})
never-synced-chats-in-request))}
:dispatch-later
(vec
(map
#(identity
{:ms 1000
:dispatch [:chat.ui/join-time-messages-checked %]})
never-synced-chats-in-request))}
(update-chats-and-gaps cursor)
(update-mailserver-topics {:request-id requestID
:cursor cursor})))
@ -803,18 +868,20 @@
(let [mailserver-error (:mailserver/request-error db)]
{:utils/show-confirmation
{: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])
:confirm-button-text (i18n/label :t/mailserver-request-retry)}}))
(fx/defn fetch-history
"Retrive a list of topics given a chat id, set them to the specified time interval
and start a mailserver request"
"Retrive a list of topics given a chat id, set them to the specified
time interval and start a mailserver request"
[{:keys [db] :as cofx} chat-id {:keys [from to]}]
(let [topics (mailserver.topics/topics-for-chat
db
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
{:db (reduce
(fn [db topic]
@ -833,8 +900,8 @@
(map
(fn [{:keys [from to id]}]
[id
{:from (max from
(- to constants/max-request-range))
{:from (max from
(- to constants/max-request-range))
:to to
:force-to? true
:topics topics
@ -885,12 +952,16 @@
(dissoc :mailserver/planned-gap-requests))}
mailserver
(let [{:keys [topics from to cursor limit] :as request} 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)
(let [{:keys [topics from to cursor limit] :as request}
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)
:mailserver/decrease-limit []
:mailserver/request-messages {:mailserver mailserver
:request (assoc request :limit (decrease-limit))}})
:mailserver/request-messages
{:mailserver mailserver
:request (assoc request :limit (decrease-limit))}})
:else
{:mailserver/decrease-limit []}))))))
@ -901,8 +972,10 @@
{:mailserver/set-limit constants/default-limit}
(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-url-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
#"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]
(rest (re-matches #"enode://(.*)@(.*)" address)))
@ -948,7 +1021,7 @@
(def default? (comp not :user-defined fetch))
(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))]
(fx/merge cofx
(set-input :id id)
@ -966,16 +1039,17 @@
[{{:mailserver.edit/keys [mailserver] :keys [multiaccount] :as db} :db
random-id-generator :random-id-generator :as cofx}]
(let [{:keys [name url id]} mailserver
current-fleet (node/current-fleet-key db)
mailserver (build
(or (:value id)
(keyword (string/replace (random-id-generator) "-" "")))
(:value name)
(:value url))
current (connected? cofx (:id mailserver))]
current-fleet (node/current-fleet-key db)
mailserver (build
(or (:value id)
(keyword (string/replace (random-id-generator) "-" "")))
(:value name)
(:value url))
current (connected? db (:id mailserver))]
{:db (-> db
(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
[{:method "mailservers_addMailserver"
:params [(mailserver->rpc mailserver current-fleet)]
@ -990,13 +1064,13 @@
:dispatch [:navigate-back]}))
(defn can-delete?
[cofx id]
(not (or (default? cofx id)
(connected? cofx id))))
[db id]
(not (or (default? db id)
(connected? db id))))
(fx/defn delete
[{:keys [db] :as cofx} id]
(if (can-delete? cofx id)
(if (can-delete? db id)
{:db (update-in db
[:mailserver/mailservers (node/current-fleet-key db)]
dissoc id)
@ -1012,12 +1086,16 @@
[{:keys [db]} mailserver-id]
(let [current-fleet (node/current-fleet-key db)]
{:ui/show-confirmation
{:title (i18n/label :t/close-app-title)
:content (i18n/label :t/connect-mailserver-content
{:name (get-in db [:mailserver/mailservers current-fleet mailserver-id :name])})
{:title (i18n/label :t/close-app-title)
:content
(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)
:on-accept #(re-frame/dispatch [:mailserver.ui/connect-confirmed current-fleet mailserver-id])
:on-cancel nil}}))
:on-accept
#(re-frame/dispatch
[:mailserver.ui/connect-confirmed current-fleet mailserver-id])
:on-cancel nil}}))
(fx/defn show-delete-confirmation
[{:keys [db]} mailserver-id]
@ -1025,7 +1103,8 @@
{:title (i18n/label :t/delete-mailserver-title)
:content (i18n/label :t/delete-mailserver-are-you-sure)
: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
[cofx url]
@ -1034,7 +1113,7 @@
(fx/defn save-settings
[{: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])
;; Check if previous mailserver was pinned
pinned? (get-in settings [:mailserver current-fleet])]
@ -1043,16 +1122,18 @@
:mailserver/remove-peer address}
(connect-to-mailserver)
(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
[{:keys [db] :as cofx}]
(let [current-fleet (node/current-fleet-key db)
settings (get-in db [:multiaccount :settings])]
(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))))
(fx/defn pin
@ -1061,8 +1142,9 @@
mailserver-id (:mailserver/current-id db)
settings (get-in db [:multiaccount :settings])]
(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]
(when-not (get-in db [:chats chat-id :gaps-loaded?])
@ -1073,10 +1155,12 @@
{:events [::gaps-loaded]}
[{:keys [db now] :as cofx} chat-id gaps]
(let [now-s (quot now 1000)
outdated-gaps (into [] (comp (filter #(< (:to %)
(- now-s constants/max-gaps-range)))
(map :id))
(vals gaps))
outdated-gaps
(into []
(comp (filter #(< (:to %)
(- now-s constants/max-gaps-range)))
(map :id))
(vals gaps))
gaps (apply dissoc gaps outdated-gaps)]
(fx/merge
cofx

View File

@ -42,8 +42,7 @@
(fetch-node-info-fx)
(pairing/init)
(publisher/start-fx)
(mailserver/initialize-mailserver)
(mailserver/connect-to-mailserver)))
(mailserver/initialize-mailserver)))
(fx/defn stop-whisper
"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",
"owner": "status-im",
"repo": "status-go",
"version": "develop",
"commit-sha1": "5f6c7008e19227392589a917def8db3780fcc5db",
"src-sha256": "0akpf4k7i5rpna0vb2m6lsy7lgsgv19g5lszxhysiacpf37q0hxv"
"version": "v0.35.1",
"commit-sha1": "4769fb91c3247c72c21013bf36194843d8d72d18",
"src-sha256": "1b6050kvnvf69gqw5llb7gb5v25pq6vbhkf9nznk9ra2spasqqzy"
}

View File

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