Merge branch 'develop' into fix/remove-dep-on-older-web3j-and-solc

This commit is contained in:
Vitaliy Vlasov 2018-03-22 15:49:15 +02:00 committed by GitHub
commit 64cb84f0e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 194 additions and 204 deletions

View File

@ -5,12 +5,13 @@
:exclusions [joda-time]] :exclusions [joda-time]]
[re-frame "0.10.2"] [re-frame "0.10.2"]
[cljs-ajax "0.7.2"] [cljs-ajax "0.7.2"]
[secretary "1.2.3"] [funcool/bide "1.6.0"]
[reagent-utils "0.2.1"] [reagent-utils "0.2.1"]
[reagent "0.7.0"] [reagent "0.7.0"]
[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

@ -102,19 +102,16 @@ WHERE i.repo_id = :repo_id
AND i.confirm_hash is null AND i.confirm_hash is null
AND i.is_open = true; AND i.is_open = true;
-- :name update-repo-generic :! :n -- :name update-repo-name :! :n
/* :require [clojure.string :as string]
[hugsql.parameters :refer [identifier-param-quote]] */
UPDATE repositories UPDATE repositories
SET SET repo = :repo_name
/*~ WHERE repo_id = :repo_id
(string/join "," AND repo != :repo_name
(for [[field _] (:updates params)]
(str (identifier-param-quote (name field) options)
" = :v:updates." (name field))))
~*/
where repo_id = :repo_id;
-- :name update-repo-state :! :n
UPDATE repositories
SET state = :repo_state
WHERE repo_id = :repo_id
-- Issues -------------------------------------------------------------------------- -- Issues --------------------------------------------------------------------------

View File

@ -25,13 +25,17 @@
(jdbc/with-db-connection [con-db *db*] (jdbc/with-db-connection [con-db *db*]
(db/get-enabled-repositories con-db {:user_id user-id})))) (db/get-enabled-repositories con-db {:user_id user-id}))))
(defn update-repo (defn update-repo-name
[repo-id updates] [repo-id repo-name]
(jdbc/with-db-connection [con-db *db*] (jdbc/with-db-connection [con-db *db*]
(db/update-repo-generic con-db {:repo_id repo-id (db/update-repo-name con-db {:repo_id repo-id
:updates updates}))) :repo_name repo-name})))
(defn update-repo-state
[repo-id repo-state]
(jdbc/with-db-connection [con-db *db*]
(db/update-repo-name con-db {:repo_id repo-id
:repo_state repo-state})))
(defn get-repo (defn get-repo
"Get a repo from DB given it's full name (owner/repo-name)" "Get a repo from DB given it's full name (owner/repo-name)"
[full-name] [full-name]

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 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 [] (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] (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,20 +148,22 @@
"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]
(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-address (get-token-address token)
token-addr-web3j (Address. token-address)] token-addr-web3j (Address. token-address)]
(-> bounty-contract (-> bounty-contract
(.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]
(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) (log/debug "token-balance" bounty-addr token token-address)
(try (try
(-> (eth/call token-address (-> (eth/call token-address
@ -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

@ -46,67 +46,6 @@
(log/debug "token" token "member?" member?) (log/debug "token" token "member?" member?)
member?)) member?))
(defn enable-repo [repo-id repo full-repo token]
(log/debug "enable-repo" repo-id repo)
(when (github/webhook-exists? full-repo token)
(github/remove-our-webhooks full-repo token))
(let [hook-secret (random/base64 32)]
(repositories/update-repo repo-id {:state 1
:hook_secret hook-secret})
(let [created-hook (github/add-webhook full-repo token hook-secret)]
(log/debug "Created webhook:" created-hook)
(repositories/update-repo repo-id {:hook_id (:id created-hook)})))
(github/create-label full-repo token)
(repositories/update-repo repo-id {:state 2})
(when (add-bounties-for-existing-issues?)
(bounties/add-bounties-for-existing-issues full-repo)))
(defn disable-repo [repo-id full-repo hook-id token]
(log/debug "disable-repo" repo-id full-repo)
(github/remove-webhook full-repo hook-id token)
(repositories/update-repo repo-id {:hook_secret ""
:state 0
:hook_id nil}))
;; NOTE(oskarth): This and above two functions about to be deprecated with Github App
(defn handle-toggle-repo [user params can-create?]
(log/info "XXX handle-toggle-repo" (pr-str user) (pr-str params))
(let [{user-id :id} user
{repo-id :id
full-repo :full_name
owner-avatar-url :owner-avatar-url
token :token
repo :name} params
[owner _] (str/split full-repo #"/")
db-user (users/get-user (:id user))]
(cond (not can-create?)
{:status 400
:body "Please join our Riot - chat.status.im/#/register and request
access in our #openbounty room to have your account whitelisted"}
(empty? (:address db-user))
{:status 400
:body "Please add your ethereum address to your profile first"}
:else
(try
(let [_ (println "CREATING")
db-item (repositories/create (merge params {:user_id user-id
:owner owner}))
is-enabled (= 2 (:state db-item))]
(if is-enabled
(disable-repo repo-id full-repo (:hook_id db-item) token)
(enable-repo repo-id repo full-repo token))
(ok (merge
{:enabled (not is-enabled)}
(select-keys params [:id :full_name]))))
(catch Exception e
(log/error "exception when enabling repo" e)
(repositories/update-repo repo-id {:state -1})
(internal-server-error))))))
(defn in? [coll elem] (defn in? [coll elem]
(some #(= elem %) coll)) (some #(= elem %) coll))
@ -286,9 +225,4 @@
:auth-rules authenticated? :auth-rules authenticated?
:current-user user :current-user user
(log/debug "/user/bounties") (log/debug "/user/bounties")
(ok (user-bounties user))) (ok (user-bounties user))))))
(POST "/repository/toggle" {:keys [params]}
;; NOTE: Don't allow anyone to create repos; manual add
:auth-rules authenticated?
:current-user user
(handle-toggle-repo user params (user-whitelisted? (:login user)))))))

View File

@ -199,9 +199,15 @@
new-title (:title gh-issue)] new-title (:title gh-issue)]
(issues/update-issue-title issue-id new-title))) (issues/update-issue-title issue-id new-title)))
(defn update-repo-name [webhook-payload]
"Update repo name in DB if changed"
(let [{repo-id :id
repo-name :name} (:repository webhook-payload)]
(repositories/update-repo-name repo-id repo-name)))
(defn handle-issue (defn handle-issue
[webhook-payload] [webhook-payload]
(update-repo-name webhook-payload)
(when-let [action (:action webhook-payload)] (when-let [action (:action webhook-payload)]
(log/debug "handle-issue" action) (log/debug "handle-issue" action)
(when (labeled-as-bounty? action webhook-payload) (when (labeled-as-bounty? action webhook-payload)
@ -216,17 +222,17 @@
(handle-issue-reopened webhook-payload))) (handle-issue-reopened webhook-payload)))
(ok)) (ok))
(defn enable-repo-2 [repo-id full-repo] (defn enable-repo [repo-id full-repo]
(log/debug "enable-repo-2" repo-id full-repo) (log/debug "enable-repo" repo-id full-repo)
;; TODO(oskarth): Add granular permissions to enable creation of label ;; TODO(oskarth): Add granular permissions to enable creation of label
#_(github/create-label full-repo) #_(github/create-label full-repo)
(repositories/update-repo repo-id {:state 2}) (repositories/update-repo-state repo-id 2)
(when (add-bounties-for-existing-issues?) (when (add-bounties-for-existing-issues?)
(bounties/add-bounties-for-existing-issues full-repo))) (bounties/add-bounties-for-existing-issues full-repo)))
(defn disable-repo-2 [repo-id full-repo] (defn disable-repo [repo-id full-repo]
(log/debug "disable-repo-2" repo-id full-repo) (log/debug "disable-repo" repo-id full-repo)
(repositories/update-repo repo-id {:state 0})) (repositories/update-repo-state repo-id 0))
(defn full-repo->owner [full-repo] (defn full-repo->owner [full-repo]
(try (try
@ -236,8 +242,6 @@
(log/error "exception when parsing repo" e) (log/error "exception when parsing repo" e)
nil))) nil)))
;; NOTE(oskarth): Together with {enable,disable}-repo-2 above, this replaces
;; handle-toggle-repo for Github App.
(defn handle-add-repo [user-id username owner-avatar-url repo can-create?] (defn handle-add-repo [user-id username owner-avatar-url repo can-create?]
(let [repo-id (:id repo) (let [repo-id (:id repo)
repo-name (:name repo) repo-name (:name repo)
@ -277,14 +281,14 @@
_ (log/info "handle-add-repo db-item" db-item) _ (log/info "handle-add-repo db-item" db-item)
is-enabled (= 2 (:state db-item))] is-enabled (= 2 (:state db-item))]
(if is-enabled (if is-enabled
(disable-repo-2 repo-id full-repo) (disable-repo repo-id full-repo)
(enable-repo-2 repo-id full-repo)) (enable-repo repo-id full-repo))
(ok {:enabled (not is-enabled) (ok {:enabled (not is-enabled)
:id repo-id :id repo-id
:full_name full-repo})) :full_name full-repo}))
(catch Exception e (catch Exception e
(log/error "exception when enabling repo" e) (log/error "exception when enabling repo" e)
(repositories/update-repo repo-id {:state -1}) (repositories/update-repo-state repo-id -1)
(internal-server-error)))))) (internal-server-error))))))
(defn handle-installation [{:keys [action installation repositories sender]}] (defn handle-installation [{:keys [action installation repositories sender]}]
@ -327,12 +331,13 @@
(ok)) (ok))
(defn handle-pull-request (defn handle-pull-request
[pull-request] [webhook-payload]
(let [action (keyword (:action pull-request))] (update-repo-name webhook-payload)
(let [action (keyword (:action webhook-payload))]
(when (contains? #{:opened (when (contains? #{:opened
:edited :edited
:closed} action) :closed} action)
(handle-pull-request-event action pull-request)) (handle-pull-request-event action webhook-payload))
(ok))) (ok)))
@ -385,14 +390,5 @@
"pull_request" (handle-pull-request payload) "pull_request" (handle-pull-request payload)
"installation" (handle-installation payload) "installation" (handle-installation payload)
"installation_repositories" (handle-installation-repositories payload) "installation_repositories" (handle-installation-repositories payload)
;; NOTE(oskarth): These two webhooks are / will be deprecated on
;; November 22, 2017 but they keep being called. According to
;; documentation they should contain same format.
;; https://developer.github.com/webhooks/
"integration_installation" (handle-installation payload)
"integration_installation_repositories" (handle-installation-repositories payload)
(ok))) (ok)))
(forbidden))))) (forbidden)))))

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,13 +16,35 @@
[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")
(doseq [{issue-id :issue_id (p :update-issue-contract-address
(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)
(try (try
@ -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,16 +107,18 @@
(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."
[] []
(doseq [{issue-id :issue_id (p :deploy-pending-contracts
(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")
(doseq [{contract-address :contract_address (p :self-sign-bounty
(doseq [{contract-address :contract_address
issue-id :issue_id issue-id :issue_id
payout-address :payout_address payout-address :payout_address
repo :repo repo :repo
@ -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,25 +163,27 @@
"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")
(doseq [{issue-id :issue_id (p :update-confirm-hash
(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)
(when-let [receipt (eth/get-transaction-receipt execute-hash)] (when-let [receipt (eth/get-transaction-receipt execute-hash)]
(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"
[] []
(doseq [{issue-id :issue_id (p :update-watch-hash
(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,7 +198,8 @@
"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")
(doseq [{issue-id :issue_id (p :update-payout-receipt
(doseq [{issue-id :issue_id
payout-hash :payout_hash payout-hash :payout_hash
contract-address :contract_address contract-address :contract_address
repo :repo repo :repo
@ -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")
) )
@ -252,12 +280,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."
[] []
(doseq [{issue-id :issue_id (log/info "In update-contract-internal-balances")
bounty-address :contract_address (p :update-contract-internal-balances
watch-hash :watch_hash} (doseq [{issue-id :issue_id
(db-bounties/open-bounty-contracts)] bounty-address :contract_address
(update-bounty-token-balances issue-id bounty-address watch-hash))) 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 (defn get-bounty-funds
"Get funds in given bounty contract. "Get funds in given bounty contract.
@ -281,9 +311,10 @@
(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"
[] []
(doseq [{bounty-addr :contract_address} (p :update-open-issue-usd-values
(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 float= (defn float=
([x y] (float= x y 0.0000001)) ([x y] (float= x y 0.0000001))
@ -299,7 +330,8 @@
(defn update-balances (defn update-balances
[] []
(log/info "In update-balances") (log/info "In update-balances")
(doseq [{contract-address :contract_address (p :update-balances
(doseq [{contract-address :contract_address
owner :owner owner :owner
repo :repo repo :repo
comment-id :comment_id comment-id :comment_id
@ -347,7 +379,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"))
@ -375,17 +407,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

View File

@ -1,10 +1,10 @@
(ns commiteth.core (ns commiteth.core
(:require [reagent.core :as r] (:require [reagent.core :as r]
[re-frame.core :as rf] [re-frame.core :as rf]
[secretary.core :as secretary]
[goog.events :as events] [goog.events :as events]
[goog.history.EventType :as HistoryEventType] [goog.history.EventType :as HistoryEventType]
[commiteth.ajax :refer [load-interceptors!]] [commiteth.ajax :refer [load-interceptors!]]
[commiteth.routes]
[commiteth.handlers] [commiteth.handlers]
[commiteth.subscriptions] [commiteth.subscriptions]
[commiteth.activity :refer [activity-page]] [commiteth.activity :refer [activity-page]]
@ -53,7 +53,7 @@
[:a [:a
(merge props (merge props
(if (keyword? target) (if (keyword? target)
{:on-click #(rf/dispatch [target])} {:on-click #(commiteth.routes/nav! target)}
{:href target})) {:href target}))
caption]]))]])) caption]]))]]))
@ -66,7 +66,7 @@
[:div.ui.container.user-component [:div.ui.container.user-component
[user-dropdown [user-dropdown
@user @user
[[:update-address "My Payment Details" {}] [[:settings "My Payment Details" {}]
["/logout" "Sign Out" {:class "logout-link"}]] ["/logout" "Sign Out" {:class "logout-link"}]]
mobile?]] mobile?]]
[:a.ui.button.small.login-button {:href js/authorizeUrl} (str "LOG IN" [:a.ui.button.small.login-button {:href js/authorizeUrl} (str "LOG IN"
@ -89,7 +89,7 @@
(for [[page caption] tabs] (for [[page caption] tabs]
(let [props {:class (str "ui item" (let [props {:class (str "ui item"
(when (= @current-page page) " active")) (when (= @current-page page) " active"))
:on-click #(rf/dispatch [:set-active-page page])}] :on-click #(commiteth.routes/nav! page)}]
^{:key page} [:div props caption]))))))) ^{:key page} [:div props caption])))))))
@ -124,15 +124,6 @@
[flash-message-pane])]))) [flash-message-pane])])))
(def pages
{:activity #'activity-page
:bounties #'bounties-page
:repos #'repos-page
:manage-payouts #'manage-payouts-page
:update-address #'update-address-page
:usage-metrics #'usage-metrics-page})
(defn top-hunters [] (defn top-hunters []
(let [top-hunters (rf/subscribe [:top-hunters])] (let [top-hunters (rf/subscribe [:top-hunters])]
(fn [] (fn []
@ -211,7 +202,13 @@
[:div {:class (str (if (show-top-hunters?) "eleven" "sixteen") [:div {:class (str (if (show-top-hunters?) "eleven" "sixteen")
" wide computer sixteen wide tablet column")} " wide computer sixteen wide tablet column")}
[:div.ui.container [:div.ui.container
[(pages @current-page)]]] (case @current-page
:activity [activity-page]
:bounties [bounties-page]
:repos [repos-page]
:manage-payouts [manage-payouts-page]
:settings [update-address-page]
:usage-metrics [usage-metrics-page])]]
(when (show-top-hunters?) (when (show-top-hunters?)
[:div.five.wide.column.computer.only [:div.five.wide.column.computer.only
[:div.ui.container.top-hunters [:div.ui.container.top-hunters
@ -220,28 +217,6 @@
[top-hunters]]])]]] [top-hunters]]])]]]
[footer]]))) [footer]])))
(secretary/set-config! :prefix "#")
(secretary/defroute "/" []
(rf/dispatch [:set-active-page :bounties]))
(secretary/defroute "/activity" []
(rf/dispatch [:set-active-page :activity]))
(secretary/defroute "/repos" []
(if js/user
(rf/dispatch [:set-active-page :repos])
(secretary/dispatch! "/")))
(defn hook-browser-navigation! []
(doto (History.)
(events/listen
HistoryEventType/NAVIGATE
(fn [event]
(secretary/dispatch! (.-token event))))
(.setEnabled true)))
(defn mount-components [] (defn mount-components []
(r/render [#'page] (.getElementById js/document "app"))) (r/render [#'page] (.getElementById js/document "app")))
@ -286,7 +261,7 @@
(when config/debug? (when config/debug?
(enable-re-frisk!)) (enable-re-frisk!))
(load-interceptors!) (load-interceptors!)
(hook-browser-navigation!) (commiteth.routes/setup-nav!)
(load-data true) (load-data true)
(.addEventListener js/window "click" #(rf/dispatch [:clear-flash-message])) (.addEventListener js/window "click" #(rf/dispatch [:clear-flash-message]))
(on-js-load)) (on-js-load))

View File

@ -312,12 +312,6 @@
(:status-text response)))]})) (:status-text response)))]}))
(reg-event-fx
:update-address
(fn [{:keys [db]} [_]]
{:db db
:dispatch [:set-active-page :update-address]}))
(reg-event-db (reg-event-db
:update-user :update-user
(fn [db [_ fields]] (fn [db [_ fields]]

View File

@ -0,0 +1,25 @@
(ns commiteth.routes
(:require [bide.core :as bide]
[re-frame.core :as rf]))
(defonce router
(bide/router [["/" :bounties]
["/activity" :activity]
["/repos" :repos]
["/manage-payouts" :manage-payouts]
["/settings" :settings]
["/usage-metrics" :usage-metrics]]))
(defn on-navigate
"A function which will be called on each route change."
[name params query]
(println "Route change to: " name params query)
(rf/dispatch [:set-active-page name]))
(defn setup-nav! []
(bide/start! router {:default :bounties
:on-navigate on-navigate}))
(defn nav! [route-id]
(bide/navigate! router route-id {}))

3
test/Jenkinsfile vendored
View File

@ -1,7 +1,8 @@
node ('linux1') {sauce('1be1b688-e0e7-4314-92a0-db11f52d3c00') { node ('linux1') {sauce('1be1b688-e0e7-4314-92a0-db11f52d3c00') {
checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanBeforeCheckout']], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/status-im/open-bounty.git']]]) checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanBeforeCheckout']], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/status-im/open-bounty.git']]])
configFileProvider([configFile(fileId: 'sob_automation_test_config', targetLocation: 'test/end-to-end/tests')]) { configFileProvider([configFile(fileId: 'sob_automation_test_config', targetLocation: 'test/end-to-end/tests')]) {
try {sh 'cd test/end-to-end/tests && python3 -m pytest -m sanity --build=$BUILD_NAME -v -n 1' try {withCredentials([string(credentialsId: 'SOB_SAUCE_ACCESS_KEY', variable: 'SAUCE_ACCESS_KEY'), string(credentialsId: 'SOB_SAUCE_USERNAME', variable: 'SAUCE_USERNAME')])
{sh 'cd test && docker build -t end2end . && docker run --rm -e "SAUCE_USERNAME="${SAUCE_USERNAME} -e "SAUCE_ACCESS_KEY="${SAUCE_ACCESS_KEY} --name end2end-container end2end -m pytest -m sanity --build=$BUILD_NAME -v -n 1'}
} }
finally { finally {
saucePublisher() saucePublisher()

View File

@ -1,4 +1,5 @@
import configparser import configparser
import os
class TestData(object): class TestData(object):
@ -9,7 +10,7 @@ class TestData(object):
# define here path to your config.ini file # define here path to your config.ini file
# example - config_example.ini # example - config_example.ini
self.config.read("tests/config.ini") self.config.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'config.ini'))
# self.issue['title'] is set in GithubPage::create_new_bounty # self.issue['title'] is set in GithubPage::create_new_bounty
# self.issue['id'] is set in GithubPage::create_new_bounty # self.issue['id'] is set in GithubPage::create_new_bounty

View File

@ -18,6 +18,8 @@ class BaseTestCase:
sauce_lab_cap = dict() sauce_lab_cap = dict()
sauce_lab_cap['name'] = test_data.test_name sauce_lab_cap['name'] = test_data.test_name
sauce_lab_cap['build'] = pytest.config.getoption('build') sauce_lab_cap['build'] = pytest.config.getoption('build')
sauce_lab_cap['idleTimeout'] = 900
sauce_lab_cap['commandTimeout'] = 500
sauce_lab_cap['platform'] = "MAC" sauce_lab_cap['platform'] = "MAC"
sauce_lab_cap['browserName'] = 'Chrome' sauce_lab_cap['browserName'] = 'Chrome'
sauce_lab_cap['screenResolution'] = '2048x1536' sauce_lab_cap['screenResolution'] = '2048x1536'
@ -67,8 +69,9 @@ class BaseTestCase:
if cls.environment == 'sauce': if cls.environment == 'sauce':
for caps in cls.capabilities_dev, cls.capabilities_org: for caps in cls.capabilities_dev, cls.capabilities_org:
cls.get_remote_caps(cls) remote = cls.get_remote_caps(cls)
new_caps = caps.to_capabilities() new_caps = caps.to_capabilities()
new_caps.update(remote)
driver = webdriver.Remote(cls.executor_sauce_lab, driver = webdriver.Remote(cls.executor_sauce_lab,
desired_capabilities=new_caps) desired_capabilities=new_caps)
drivers.append(driver) drivers.append(driver)
@ -79,6 +82,7 @@ class BaseTestCase:
cls.driver_dev = drivers[0] cls.driver_dev = drivers[0]
cls.driver_org = drivers[1] cls.driver_org = drivers[1]
for driver in drivers: for driver in drivers:
driver.implicitly_wait(10) driver.implicitly_wait(10)
@ -132,9 +136,9 @@ class BaseTestCase:
remove_installation(cls.driver_org) remove_installation(cls.driver_org)
######DEV ######DEV
cls.github_dev.delete_fork()
cls.github_dev.clean_repo_local_folder() cls.github_dev.clean_repo_local_folder()
cls.github_dev.delete_fork()
try: try:
cls.driver_dev.quit() cls.driver_dev.quit()
cls.driver_org.quit() cls.driver_org.quit()