diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index f7a3317136..09f1c5ef4e 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -76,6 +76,7 @@ "settings_saveNodeConfig" {} "accounts_getAccounts" {} "accounts_saveAccounts" {} + "mailservers_ping" {} "mailservers_addMailserver" {} "mailservers_getMailservers" {} "mailservers_deleteMailserver" {} diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index dd789f90fc..bdebd22c51 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -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 _] diff --git a/src/status_im/mailserver/core.cljs b/src/status_im/mailserver/core.cljs index 2a5e379774..f31a5c7319 100644 --- a/src/status_im/mailserver/core.cljs +++ b/src/status_im/mailserver/core.cljs @@ -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 diff --git a/src/status_im/transport/core.cljs b/src/status_im/transport/core.cljs index afb1117189..d622659928 100644 --- a/src/status_im/transport/core.cljs +++ b/src/status_im/transport/core.cljs @@ -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" diff --git a/status-go-version.json b/status-go-version.json index db33c45030..788afee7ae 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' 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" } diff --git a/test/cljs/status_im/test/mailserver/core.cljs b/test/cljs/status_im/test/mailserver/core.cljs index 842d046a78..fc166f6c21 100644 --- a/test/cljs/status_im/test/mailserver/core.cljs +++ b/test/cljs/status_im/test/mailserver/core.cljs @@ -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")