Move balances update to 10-min update thread

Add Tufte profiling
This commit is contained in:
Vitaliy Vlasov 2018-03-17 17:11:33 +02:00
parent a37be80b73
commit cf79ea7d3b
No known key found for this signature in database
GPG Key ID: A7D57C347F2B2964
4 changed files with 108 additions and 49 deletions

View File

@ -11,6 +11,7 @@
[org.clojure/clojurescript "1.9.946"] [org.clojure/clojurescript "1.9.946"]
[org.clojure/clojure "1.8.0"] [org.clojure/clojure "1.8.0"]
[selmer "1.11.1"] [selmer "1.11.1"]
[com.taoensso/tufte "1.3.0"]
[markdown-clj "1.0.1"] [markdown-clj "1.0.1"]
[ring-middleware-format "0.7.2"] [ring-middleware-format "0.7.2"]
[ring/ring-core "1.6.2"] [ring/ring-core "1.6.2"]

View File

@ -4,8 +4,10 @@
[clojure.java.io :as io] [clojure.java.io :as io]
[commiteth.config :refer [env]] [commiteth.config :refer [env]]
[clojure.string :refer [join]] [clojure.string :refer [join]]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[clojure.tools.logging :as log] [clojure.tools.logging :as log]
[clojure.string :as str] [clojure.string :as str]
[mount.core :as mount]
[pandect.core :as pandect] [pandect.core :as pandect]
[commiteth.util.util :refer [json-api-request]]) [commiteth.util.util :refer [json-api-request]])
(:import [org.web3j (:import [org.web3j
@ -26,24 +28,30 @@
(defn auto-gas-price? [] (env :auto-gas-price false)) (defn auto-gas-price? [] (env :auto-gas-price false))
(defn offline-signing? [] (env :offline-signing true)) (defn offline-signing? [] (env :offline-signing true))
(def web3j-obj (atom nil))
(def creds-obj (atom nil))
(defn wallet-file-path [] (defn wallet-file-path []
(env :eth-wallet-file)) (env :eth-wallet-file))
(defn wallet-password [] (defn wallet-password []
(env :eth-password)) (env :eth-password))
(defn create-web3j []
(or @web3j-obj
(swap! web3j-obj (constantly (Web3j/build (HttpService. (eth-rpc-url)))))))
(defn creds [] (defn creds []
(or @creds-obj
(let [password (wallet-password) (let [password (wallet-password)
file-path (wallet-file-path)] file-path (wallet-file-path)]
(if (and password file-path) (if (and password file-path)
(WalletUtils/loadCredentials (swap! creds-obj
(constantly (WalletUtils/loadCredentials
password password
file-path) file-path)))
(throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn" (throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn"
{:password password :file-path file-path}))))) {:password password :file-path file-path}))))))
(defn create-web3j []
(Web3j/build (HttpService. (eth-rpc-url))))
(defn get-signed-tx [gas-price gas-limit to data] (defn get-signed-tx [gas-price gas-limit to data]
"Create a sign a raw transaction. "Create a sign a raw transaction.
@ -192,7 +200,8 @@
(defn get-balance-eth (defn get-balance-eth
[account digits] [account digits]
(hex->eth (get-balance-hex account) digits)) (p :get-balance-eth
(hex->eth (get-balance-hex account) digits)))
(defn- format-param (defn- format-param
[param] [param]
@ -296,3 +305,15 @@
(filter true?) (filter true?)
(empty?))) (empty?)))
true)))) true))))
(mount/defstate
eth-core
:start
(do
(swap! web3j-obj (constantly nil))
(swap! creds-obj (constantly nil))
(log/info "eth/core started"))
:stop
(log/info "eth/core stopped"))

View File

@ -3,6 +3,7 @@
:refer [create-web3j creds]] :refer [create-web3j creds]]
[commiteth.config :refer [env]] [commiteth.config :refer [env]]
[clojure.tools.logging :as log] [clojure.tools.logging :as log]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[commiteth.eth.token-data :as token-data]) [commiteth.eth.token-data :as token-data])
(:import [org.web3j (:import [org.web3j
abi.datatypes.Address abi.datatypes.Address
@ -147,6 +148,7 @@
"Query (internal) ERC20 token balance from bounty contract for given "Query (internal) ERC20 token balance from bounty contract for given
token TLA." token TLA."
[bounty-addr token] [bounty-addr token]
(p :token-balance-in-bounty
(let [bounty-contract (load-bounty-contract bounty-addr) (let [bounty-contract (load-bounty-contract bounty-addr)
token-address (get-token-address token) token-address (get-token-address token)
token-addr-web3j (Address. token-address)] token-addr-web3j (Address. token-address)]
@ -154,12 +156,13 @@
(.tokenBalances token-addr-web3j) (.tokenBalances token-addr-web3j)
.get .get
.getValue .getValue
(convert-token-value token)))) (convert-token-value token)))))
(defn token-balance (defn token-balance
"Query balance of given ERC20 token TLA for given address from ERC20 "Query balance of given ERC20 token TLA for given address from ERC20
contract." contract."
[bounty-addr token] [bounty-addr token]
(p :token-balance
(let [token-address (get-token-address token)] (let [token-address (get-token-address token)]
(log/debug "token-balance" bounty-addr token token-address) (log/debug "token-balance" bounty-addr token token-address)
(try (try
@ -170,25 +173,26 @@
(convert-token-value token)) (convert-token-value token))
(catch Throwable t (catch Throwable t
(log/debug "Failed to query token balance " t) (log/debug "Failed to query token balance " t)
0)))) 0)))))
(defn token-balances (defn token-balances
"Get a given bounty contract's token balances. Assumes contract's "Get a given bounty contract's token balances. Assumes contract's
internal balances have been updated." internal balances have been updated."
[bounty-addr] [bounty-addr]
(let [bounty-contract (load-bounty-contract bounty-addr) (p :token-balances
token-addresses (-> bounty-contract (let [bounty-contract (p :load-bounty-contract (load-bounty-contract bounty-addr))
token-addresses (p :getTokenList (-> bounty-contract
(.getTokenList) (.getTokenList)
.get)] .get))]
(if token-addresses (if token-addresses
(let [addrs (map str (let [addrs (map str
(.getValue token-addresses))] (p :getValue (.getValue token-addresses)))]
(into {} (into {}
(map (fn [addr] (if-let [info (token-data/token-info-by-addr addr)] (map (fn [addr] (if-let [info (token-data/token-info-by-addr addr)]
(let [tla (first info)] (let [tla (first info)]
[tla (token-balance bounty-addr tla)]))) addrs))) [tla (token-balance bounty-addr tla)]))) addrs)))
{}))) {}))))
(defn uint256 [x] (defn uint256 [x]
(org.web3j.abi.datatypes.generated.Uint256. x)) (org.web3j.abi.datatypes.generated.Uint256. x))

View File

@ -4,6 +4,7 @@
[commiteth.eth.token-data :as token-data] [commiteth.eth.token-data :as token-data]
[commiteth.github.core :as github] [commiteth.github.core :as github]
[commiteth.db.issues :as issues] [commiteth.db.issues :as issues]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[commiteth.db.bounties :as db-bounties] [commiteth.db.bounties :as db-bounties]
[commiteth.bounties :as bounties] [commiteth.bounties :as bounties]
[commiteth.util.crypto-fiat-value :as fiat-util] [commiteth.util.crypto-fiat-value :as fiat-util]
@ -15,12 +16,34 @@
[clj-time.periodic :refer [periodic-seq]] [clj-time.periodic :refer [periodic-seq]]
[chime :refer [chime-at]])) [chime :refer [chime-at]]))
(tufte/add-basic-println-handler! {})
(tufte/add-handler! :file (fn [{stats :stats}]
(log/info "Profiling stats:" stats)))
(comment
(profile {} (update-issue-contract-address))
(profile {} (deploy-pending-contracts))
(profile {} (self-sign-bounty))
(profile {} (update-confirm-hash))
(profile {} (update-watch-hash))
(profile {} (update-payout-receipt))
(profile {} (update-contract-internal-balances))
(profile {} (update-open-issue-usd-values))
(profile {} (update-balances))
(profile {}
(doseq [i (range 5)]
(update-contract-internal-balances)
(update-open-issue-usd-values)
(update-balances)))
)
(defn update-issue-contract-address (defn update-issue-contract-address
"For each pending deployment: gets transaction receipt, updates db "For each pending deployment: gets transaction receipt, updates db
state (contract-address, comment-id) and posts github comment" state (contract-address, comment-id) and posts github comment"
[] []
(log/info "In update-issue-contract-address") (log/info "In update-issue-contract-address")
(p :update-issue-contract-address
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
transaction-hash :transaction_hash} (issues/list-pending-deployments)] transaction-hash :transaction_hash} (issues/list-pending-deployments)]
(log/info "pending deployment:" transaction-hash) (log/info "pending deployment:" transaction-hash)
@ -57,7 +80,7 @@
(log/error "Failed to find contract address in tx logs"))) (log/error "Failed to find contract address in tx logs")))
(catch Throwable ex (catch Throwable ex
(do (log/error "update-issue-contract-address exception:" ex) (do (log/error "update-issue-contract-address exception:" ex)
(clojure.stacktrace/print-stack-trace ex))))) (clojure.stacktrace/print-stack-trace ex))))))
(log/info "Exit update-issue-contract-address")) (log/info "Exit update-issue-contract-address"))
@ -84,15 +107,17 @@
(defn deploy-pending-contracts (defn deploy-pending-contracts
"Under high-concurrency circumstances or in case geth is in defunct state, a bounty contract may not deploy successfully when the bounty label is addded to an issue. This function deploys such contracts." "Under high-concurrency circumstances or in case geth is in defunct state, a bounty contract may not deploy successfully when the bounty label is addded to an issue. This function deploys such contracts."
[] []
(p :deploy-pending-contracts
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
owner-address :owner_address} (db-bounties/pending-contracts)] owner-address :owner_address} (db-bounties/pending-contracts)]
(log/debug "Trying to re-deploy failed bounty contract deployment, issue-id:" issue-id) (log/debug "Trying to re-deploy failed bounty contract deployment, issue-id:" issue-id)
(deploy-contract owner-address issue-id))) (deploy-contract owner-address issue-id))))
(defn self-sign-bounty (defn self-sign-bounty
"Walks through all issues eligible for bounty payout and signs corresponding transaction" "Walks through all issues eligible for bounty payout and signs corresponding transaction"
[] []
(log/info "In self-sign-bounty") (log/info "In self-sign-bounty")
(p :self-sign-bounty
(doseq [{contract-address :contract_address (doseq [{contract-address :contract_address
issue-id :issue_id issue-id :issue_id
payout-address :payout_address payout-address :payout_address
@ -130,7 +155,7 @@
false)))) false))))
(catch Throwable ex (catch Throwable ex
(do (log/error "self-sign-bounty exception:" ex) (do (log/error "self-sign-bounty exception:" ex)
(clojure.stacktrace/print-stack-trace ex))))) (clojure.stacktrace/print-stack-trace ex))))))
(log/info "Exit self-sign-bounty") (log/info "Exit self-sign-bounty")
) )
@ -138,6 +163,7 @@
"Gets transaction receipt for each pending payout and updates DB confirm_hash with tranaction ID of commiteth bot account's confirmation." "Gets transaction receipt for each pending payout and updates DB confirm_hash with tranaction ID of commiteth bot account's confirmation."
[] []
(log/info "In update-confirm-hash") (log/info "In update-confirm-hash")
(p :update-confirm-hash
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
execute-hash :execute_hash} (db-bounties/pending-payouts)] execute-hash :execute_hash} (db-bounties/pending-payouts)]
(log/info "pending payout:" execute-hash) (log/info "pending payout:" execute-hash)
@ -145,18 +171,19 @@
(log/info "execution receipt for issue #" issue-id ": " receipt) (log/info "execution receipt for issue #" issue-id ": " receipt)
(when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)] (when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)]
(log/info "confirm hash:" confirm-hash) (log/info "confirm hash:" confirm-hash)
(db-bounties/update-confirm-hash issue-id confirm-hash)))) (db-bounties/update-confirm-hash issue-id confirm-hash)))))
(log/info "Exit update-confirm-hash")) (log/info "Exit update-confirm-hash"))
(defn update-watch-hash (defn update-watch-hash
"Sets watch-hash to NULL for bounties where watch tx has been mined. Used to avoid unneeded watch transactions in update-bounty-token-balances" "Sets watch-hash to NULL for bounties where watch tx has been mined. Used to avoid unneeded watch transactions in update-bounty-token-balances"
[] []
(p :update-watch-hash
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
watch-hash :watch_hash} (db-bounties/pending-watch-calls)] watch-hash :watch_hash} (db-bounties/pending-watch-calls)]
(log/info "pending watch call" watch-hash) (log/info "pending watch call" watch-hash)
(when-let [receipt (eth/get-transaction-receipt watch-hash)] (when-let [receipt (eth/get-transaction-receipt watch-hash)]
(db-bounties/update-watch-hash issue-id nil)))) (db-bounties/update-watch-hash issue-id nil)))))
(defn older-than-3h? (defn older-than-3h?
@ -171,6 +198,7 @@
"Gets transaction receipt for each confirmed payout and updates payout_hash" "Gets transaction receipt for each confirmed payout and updates payout_hash"
[] []
(log/info "In update-payout-receipt") (log/info "In update-payout-receipt")
(p :update-payout-receipt
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
payout-hash :payout_hash payout-hash :payout_hash
contract-address :contract_address contract-address :contract_address
@ -213,7 +241,7 @@
(db-bounties/reset-payout-hash issue-id))) (db-bounties/reset-payout-hash issue-id)))
(catch Throwable ex (catch Throwable ex
(do (log/error "update-payout-receipt exception:" ex) (do (log/error "update-payout-receipt exception:" ex)
(clojure.stacktrace/print-stack-trace ex))))) (clojure.stacktrace/print-stack-trace ex))))))
(log/info "Exit update-payout-receipt") (log/info "Exit update-payout-receipt")
) )
@ -258,12 +286,14 @@
(defn update-contract-internal-balances (defn update-contract-internal-balances
"It is required in our current smart contract to manually update it's internal balance when some tokens have been added." "It is required in our current smart contract to manually update it's internal balance when some tokens have been added."
[] []
(log/info "In update-contract-internal-balances")
(p :update-contract-internal-balances
(doseq [{issue-id :issue_id (doseq [{issue-id :issue_id
bounty-address :contract_address bounty-address :contract_address
watch-hash :watch_hash} watch-hash :watch_hash}
(db-bounties/open-bounty-contracts)] (db-bounties/open-bounty-contracts)]
(update-bounty-token-balances issue-id bounty-address watch-hash))) (update-bounty-token-balances issue-id bounty-address watch-hash)))
(log/info "Exit update-contract-internal-balances"))
(defn get-bounty-funds (defn get-bounty-funds
"Get funds in given bounty contract. "Get funds in given bounty contract.
@ -287,13 +317,15 @@
(defn update-open-issue-usd-values (defn update-open-issue-usd-values
"Sum up current USD values of all crypto assets in a bounty and store to DB" "Sum up current USD values of all crypto assets in a bounty and store to DB"
[] []
(p :update-open-issue-usd-values
(doseq [{bounty-addr :contract_address} (doseq [{bounty-addr :contract_address}
(db-bounties/open-bounty-contracts)] (db-bounties/open-bounty-contracts)]
(update-issue-usd-value bounty-addr))) (update-issue-usd-value bounty-addr))))
(defn update-balances (defn update-balances
[] []
(log/info "In update-balances") (log/info "In update-balances")
(p :update-balances
(doseq [{contract-address :contract_address (doseq [{contract-address :contract_address
owner :owner owner :owner
repo :repo repo :repo
@ -342,7 +374,7 @@
(update-issue-usd-value contract-address)))) (update-issue-usd-value contract-address))))
(catch Throwable ex (catch Throwable ex
(do (log/error "update-balances exception:" ex) (do (log/error "update-balances exception:" ex)
(clojure.stacktrace/print-stack-trace ex))))) (clojure.stacktrace/print-stack-trace ex))))))
(log/info "Exit update-balances")) (log/info "Exit update-balances"))
@ -370,17 +402,18 @@
update-payout-receipt update-payout-receipt
update-watch-hash update-watch-hash
self-sign-bounty self-sign-bounty
update-contract-internal-balances ])
update-balances]) (log/info "run-1-min-interval-tasks done")))
(log/debug "run-1-min-interval-tasks done")))
(defn run-10-min-interval-tasks [time] (defn run-10-min-interval-tasks [time]
(do (do
(log/debug "run-1-min-interval-tasks" time) (log/info "run-10-min-interval-tasks" time)
(run-tasks (run-tasks
[update-open-issue-usd-values]) [update-contract-internal-balances
(log/debug "run-10-min-interval-tasks done"))) update-balances
update-open-issue-usd-values])
(log/info "run-10-min-interval-tasks done")))
(mount/defstate scheduler (mount/defstate scheduler