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/clojure "1.8.0"]
[selmer "1.11.1"]
[com.taoensso/tufte "1.3.0"]
[markdown-clj "1.0.1"]
[ring-middleware-format "0.7.2"]
[ring/ring-core "1.6.2"]

View File

@ -4,8 +4,10 @@
[clojure.java.io :as io]
[commiteth.config :refer [env]]
[clojure.string :refer [join]]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[clojure.tools.logging :as log]
[clojure.string :as str]
[mount.core :as mount]
[pandect.core :as pandect]
[commiteth.util.util :refer [json-api-request]])
(:import [org.web3j
@ -26,24 +28,30 @@
(defn auto-gas-price? [] (env :auto-gas-price false))
(defn offline-signing? [] (env :offline-signing true))
(def web3j-obj (atom nil))
(def creds-obj (atom nil))
(defn wallet-file-path []
(env :eth-wallet-file))
(defn wallet-password []
(env :eth-password))
(defn creds []
(let [password (wallet-password)
file-path (wallet-file-path)]
(if (and password file-path)
(WalletUtils/loadCredentials
password
file-path)
(throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn"
{:password password :file-path file-path})))))
(defn create-web3j []
(Web3j/build (HttpService. (eth-rpc-url))))
(or @web3j-obj
(swap! web3j-obj (constantly (Web3j/build (HttpService. (eth-rpc-url)))))))
(defn creds []
(or @creds-obj
(let [password (wallet-password)
file-path (wallet-file-path)]
(if (and password file-path)
(swap! creds-obj
(constantly (WalletUtils/loadCredentials
password
file-path)))
(throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn"
{:password password :file-path file-path}))))))
(defn get-signed-tx [gas-price gas-limit to data]
"Create a sign a raw transaction.
@ -192,7 +200,8 @@
(defn get-balance-eth
[account digits]
(hex->eth (get-balance-hex account) digits))
(p :get-balance-eth
(hex->eth (get-balance-hex account) digits)))
(defn- format-param
[param]
@ -296,3 +305,15 @@
(filter true?)
(empty?)))
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]]
[commiteth.config :refer [env]]
[clojure.tools.logging :as log]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[commiteth.eth.token-data :as token-data])
(:import [org.web3j
abi.datatypes.Address
@ -147,20 +148,22 @@
"Query (internal) ERC20 token balance from bounty contract for given
token TLA."
[bounty-addr token]
(let [bounty-contract (load-bounty-contract bounty-addr)
(p :token-balance-in-bounty
(let [bounty-contract (load-bounty-contract bounty-addr)
token-address (get-token-address token)
token-addr-web3j (Address. token-address)]
(-> bounty-contract
(.tokenBalances token-addr-web3j)
.get
.getValue
(convert-token-value token))))
(convert-token-value token)))))
(defn token-balance
"Query balance of given ERC20 token TLA for given address from ERC20
contract."
[bounty-addr token]
(let [token-address (get-token-address token)]
(p :token-balance
(let [token-address (get-token-address token)]
(log/debug "token-balance" bounty-addr token token-address)
(try
(-> (eth/call token-address
@ -170,25 +173,26 @@
(convert-token-value token))
(catch Throwable t
(log/debug "Failed to query token balance " t)
0))))
0)))))
(defn token-balances
"Get a given bounty contract's token balances. Assumes contract's
internal balances have been updated."
[bounty-addr]
(let [bounty-contract (load-bounty-contract bounty-addr)
token-addresses (-> bounty-contract
(p :token-balances
(let [bounty-contract (p :load-bounty-contract (load-bounty-contract bounty-addr))
token-addresses (p :getTokenList (-> bounty-contract
(.getTokenList)
.get)]
.get))]
(if token-addresses
(let [addrs (map str
(.getValue token-addresses))]
(p :getValue (.getValue token-addresses)))]
(into {}
(map (fn [addr] (if-let [info (token-data/token-info-by-addr addr)]
(let [tla (first info)]
[tla (token-balance bounty-addr tla)]))) addrs)))
{})))
{}))))
(defn uint256 [x]
(org.web3j.abi.datatypes.generated.Uint256. x))

View File

@ -4,6 +4,7 @@
[commiteth.eth.token-data :as token-data]
[commiteth.github.core :as github]
[commiteth.db.issues :as issues]
[taoensso.tufte :as tufte :refer (defnp p profiled profile)]
[commiteth.db.bounties :as db-bounties]
[commiteth.bounties :as bounties]
[commiteth.util.crypto-fiat-value :as fiat-util]
@ -15,13 +16,35 @@
[clj-time.periodic :refer [periodic-seq]]
[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
"For each pending deployment: gets transaction receipt, updates db
state (contract-address, comment-id) and posts github comment"
[]
(log/info "In update-issue-contract-address")
(doseq [{issue-id :issue_id
(p :update-issue-contract-address
(doseq [{issue-id :issue_id
transaction-hash :transaction_hash} (issues/list-pending-deployments)]
(log/info "pending deployment:" transaction-hash)
(try
@ -57,7 +80,7 @@
(log/error "Failed to find contract address in tx logs")))
(catch Throwable 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"))
@ -84,16 +107,18 @@
(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."
[]
(doseq [{issue-id :issue_id
(p :deploy-pending-contracts
(doseq [{issue-id :issue_id
owner-address :owner_address} (db-bounties/pending-contracts)]
(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
"Walks through all issues eligible for bounty payout and signs corresponding transaction"
[]
(log/info "In self-sign-bounty")
(doseq [{contract-address :contract_address
(p :self-sign-bounty
(doseq [{contract-address :contract_address
issue-id :issue_id
payout-address :payout_address
repo :repo
@ -130,7 +155,7 @@
false))))
(catch Throwable 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")
)
@ -138,25 +163,27 @@
"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")
(doseq [{issue-id :issue_id
(p :update-confirm-hash
(doseq [{issue-id :issue_id
execute-hash :execute_hash} (db-bounties/pending-payouts)]
(log/info "pending payout:" execute-hash)
(when-let [receipt (eth/get-transaction-receipt execute-hash)]
(log/info "execution receipt for issue #" issue-id ": " receipt)
(when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)]
(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"))
(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"
[]
(doseq [{issue-id :issue_id
(p :update-watch-hash
(doseq [{issue-id :issue_id
watch-hash :watch_hash} (db-bounties/pending-watch-calls)]
(log/info "pending watch call" 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?
@ -171,7 +198,8 @@
"Gets transaction receipt for each confirmed payout and updates payout_hash"
[]
(log/info "In update-payout-receipt")
(doseq [{issue-id :issue_id
(p :update-payout-receipt
(doseq [{issue-id :issue_id
payout-hash :payout_hash
contract-address :contract_address
repo :repo
@ -213,7 +241,7 @@
(db-bounties/reset-payout-hash issue-id)))
(catch Throwable 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")
)
@ -258,12 +286,14 @@
(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."
[]
(doseq [{issue-id :issue_id
bounty-address :contract_address
watch-hash :watch_hash}
(db-bounties/open-bounty-contracts)]
(update-bounty-token-balances issue-id bounty-address watch-hash)))
(log/info "In update-contract-internal-balances")
(p :update-contract-internal-balances
(doseq [{issue-id :issue_id
bounty-address :contract_address
watch-hash :watch_hash}
(db-bounties/open-bounty-contracts)]
(update-bounty-token-balances issue-id bounty-address watch-hash)))
(log/info "Exit update-contract-internal-balances"))
(defn get-bounty-funds
"Get funds in given bounty contract.
@ -287,14 +317,16 @@
(defn update-open-issue-usd-values
"Sum up current USD values of all crypto assets in a bounty and store to DB"
[]
(doseq [{bounty-addr :contract_address}
(p :update-open-issue-usd-values
(doseq [{bounty-addr :contract_address}
(db-bounties/open-bounty-contracts)]
(update-issue-usd-value bounty-addr)))
(update-issue-usd-value bounty-addr))))
(defn update-balances
[]
(log/info "In update-balances")
(doseq [{contract-address :contract_address
(p :update-balances
(doseq [{contract-address :contract_address
owner :owner
repo :repo
comment-id :comment_id
@ -342,7 +374,7 @@
(update-issue-usd-value contract-address))))
(catch Throwable 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"))
@ -370,17 +402,18 @@
update-payout-receipt
update-watch-hash
self-sign-bounty
update-contract-internal-balances
update-balances])
(log/debug "run-1-min-interval-tasks done")))
])
(log/info "run-1-min-interval-tasks done")))
(defn run-10-min-interval-tasks [time]
(do
(log/debug "run-1-min-interval-tasks" time)
(log/info "run-10-min-interval-tasks" time)
(run-tasks
[update-open-issue-usd-values])
(log/debug "run-10-min-interval-tasks done")))
[update-contract-internal-balances
update-balances
update-open-issue-usd-values])
(log/info "run-10-min-interval-tasks done")))
(mount/defstate scheduler