Andrey Shovkoplyas 6d337bc69a
multiaccounts
2019-07-30 20:35:58 +02:00

236 lines
8.4 KiB
Clojure

(ns status-im.node.core
(:require [re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.fleet.core :as fleet]
[status-im.native-module.core :as status]
[status-im.utils.config :as config]
[status-im.utils.types :as types]
[status-im.utils.platform :as utils.platform]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.utils.fx :as fx]))
(defn- add-custom-bootnodes [config network all-bootnodes]
(let [bootnodes (as-> all-bootnodes $
(get $ network)
(vals $)
(map :address $))]
(if (seq bootnodes)
(assoc-in config [:ClusterConfig :BootNodes] bootnodes)
config)))
(defn- add-log-level [config log-level]
(if (empty? log-level)
(assoc config
:LogEnabled false)
(assoc config
:LogLevel log-level
:LogEnabled true)))
(defn get-network-genesis-hash-prefix
"returns the hex representation of the first 8 bytes of a network's genesis hash"
[network]
(case network
1 "d4e56740f876aef8"
3 "41941023680923e0"
4 "6341fd3daf94b748"
nil))
(defn get-les-topic
"returns discovery v5 topic derived from genesis of the provided network"
[network]
(let [les-discovery-identifier "LES2@"
hash-prefix (get-network-genesis-hash-prefix network)]
(when hash-prefix
(str les-discovery-identifier hash-prefix))))
(defn get-topics
[network]
(let [les-topic (get-les-topic network)]
(cond-> {"whisper" {:Min 2, :Max 2}}
les-topic (assoc les-topic {:Min 2, :Max 2}))))
(defn get-multiaccount-network [db address]
(get-in db [:multiaccount address :network]))
(defn- get-base-node-config [config]
(let [initial-props @(re-frame/subscribe [:initial-props])
status-node-port (get initial-props :STATUS_NODE_PORT)]
(cond-> (assoc config
:Name "StatusIM")
config/dev-build?
(assoc :ListenAddr ":30304"
:DataDir (str (:DataDir config) "_dev"))
status-node-port
(assoc :ListenAddr (str ":" status-node-port)))))
(defn- pick-nodes
"Picks `limit` different nodes randomly from the list of nodes
if there is more than `limit` nodes in the list, otherwise return the list
of nodes"
[limit nodes]
(take limit (shuffle nodes)))
(defn get-log-level
[multiaccount-settings]
(or (:log-level multiaccount-settings)
(if utils.platform/desktop? ""
config/log-level-status-go)))
(defn- ulc-network? [config]
(get-in config [:LightEthConfig :ULC] false))
(defn- add-ulc-trusted-nodes [config trusted-nodes]
(if (ulc-network? config)
(-> config
(assoc-in [:LightEthConfig :TrustedNodes] trusted-nodes)
(assoc-in [:LightEthConfig :MinTrustedFraction] 50))
config))
(defn- get-multiaccount-node-config [db address]
(let [multiaccounts (get db :multiaccounts/multiaccounts)
current-fleet-key (fleet/current-fleet db address)
current-fleet (get (fleet/fleets db) current-fleet-key)
rendezvous-nodes (pick-nodes 3 (vals (:rendezvous current-fleet)))
{:keys [network installation-id settings bootnodes networks]}
(merge
{:network config/default-network
:networks (:networks/networks db)
:settings (constants/default-multiaccount-settings)
:installation-id (get db :multiaccounts/new-installation-id)}
(get multiaccounts address))
use-custom-bootnodes (get-in settings [:bootnodes network])
log-level (get-log-level settings)
datasync? (:datasync? settings)
disable-discovery-topic? (:disable-discovery-topic? settings)
v1-messages? (:v1-messages? settings)]
(cond-> (get-in networks [network :config])
:always
(get-base-node-config)
current-fleet
(assoc :NoDiscovery false
:Rendezvous (not (empty? rendezvous-nodes))
:ClusterConfig {:Enabled true
:Fleet (name current-fleet-key)
:BootNodes (pick-nodes 4 (vals (:boot current-fleet)))
:TrustedMailServers (pick-nodes 6 (vals (:mail current-fleet)))
:StaticNodes (into (pick-nodes 2 (vals (:whisper current-fleet))) (vals (:static current-fleet)))
:RendezvousNodes rendezvous-nodes})
:always
(assoc :WalletConfig {:Enabled true}
:BrowsersConfig {:Enabled true}
:PermissionsConfig {:Enabled true}
:WhisperConfig {:Enabled true
:LightClient true
:MinimumPoW 0.001
:EnableNTPSync true}
:ShhextConfig {:BackupDisabledDataDir (utils.platform/no-backup-directory)
:InstallationID installation-id
:MaxMessageDeliveryAttempts config/max-message-delivery-attempts
:MailServerConfirmations config/mailserver-confirmations-enabled?
:DataSyncEnabled (boolean datasync?)
:DisableGenericDiscoveryTopic (boolean disable-discovery-topic?)
:SendV1Messages (boolean v1-messages?)
:PFSEnabled true}
:RequireTopics (get-topics network)
:StatusAccountsConfig {:Enabled true})
(and
config/bootnodes-settings-enabled?
use-custom-bootnodes)
(add-custom-bootnodes network bootnodes)
:always
(add-ulc-trusted-nodes (vals (:static current-fleet)))
:always
(add-log-level log-level))))
(defn get-verify-multiaccount-config
"Is used when the node has to be started before
`VerifyAccountPassword` call."
[db network]
(-> (get-in (:networks/networks db) [network :config])
(get-base-node-config)
(assoc :ShhextConfig {:BackupDisabledDataDir (utils.platform/no-backup-directory)})
(assoc :PFSEnabled false
:NoDiscovery true)
(add-log-level config/log-level-status-go)))
(fx/defn update-sync-state
[{:keys [db]} error sync-state]
{:db (assoc db :node/chain-sync-state
(if error
{:error error}
(when sync-state (js->clj sync-state :keywordize-keys true))))})
(fx/defn start
[{:keys [db]} address]
(let [network (if address
(get-multiaccount-network db address)
(:network db))
node-config (if (= (:node/on-ready db) :verify-multiaccount)
(get-verify-multiaccount-config db network)
(get-multiaccount-node-config db address))
node-config-json (types/clj->json node-config)]
(log/info "Node config: " node-config-json)
{:db (assoc db
:network network
:node/status :starting)
:node/start node-config-json}))
(fx/defn stop
[{:keys [db]}]
{:db (assoc db :node/status :stopping)
:node/stop nil})
(fx/defn initialize
[{{:node/keys [status] :as db} :db :as cofx} address]
(let [restart {:db (assoc db :node/restart? true :node/address address)}]
(case status
:started nil
:starting restart
:stopping restart
(start cofx address))))
(re-frame/reg-fx
:node/start
(fn [config]
(status/start-node config)))
(re-frame/reg-fx
:node/ready
(fn [config]
(status/node-ready)))
(re-frame/reg-fx
:node/stop
(fn []
(status/stop-node)))
(re-frame/reg-fx
:node/les-show-debug-info
(fn [[web3 multiaccount chain-sync-state]]
(.getBalance
(.-eth web3)
(:address multiaccount)
(fn [error-balance balance]
(.getBlockNumber
(.-eth web3)
(fn
[error-block block]
(utils/show-popup
"LES sync status"
(str
"* multiaccount=" (:address multiaccount) "\n"
"* latest block=" (or error-block block) "\n"
"* balance=" (or error-balance balance) "\n"
"* eth_getSyncing=" (or chain-sync-state "false")))))))))
(defn display-les-debug-info
[{{:keys [web3 multiaccount] :node/keys [chain-sync-state]} :db}]
{:node/les-show-debug-info [web3 multiaccount]})