From eb7b5e1010e62de4c4e88e2e5b785e54be5ffa54 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Wed, 4 Apr 2018 15:12:12 +0300 Subject: [PATCH 01/35] Process multiple claims in one PR --- ...80403131200-multiple-claims-in-pr.down.sql | 7 ++++ ...0180403131200-multiple-claims-in-pr.up.sql | 7 ++++ src/clj/commiteth/routes/webhooks.clj | 33 ++++++++++--------- 3 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 resources/migrations/20180403131200-multiple-claims-in-pr.down.sql create mode 100644 resources/migrations/20180403131200-multiple-claims-in-pr.up.sql diff --git a/resources/migrations/20180403131200-multiple-claims-in-pr.down.sql b/resources/migrations/20180403131200-multiple-claims-in-pr.down.sql new file mode 100644 index 0000000..096ced8 --- /dev/null +++ b/resources/migrations/20180403131200-multiple-claims-in-pr.down.sql @@ -0,0 +1,7 @@ +ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pkey; +ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pr_id_key; +ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_fkey; + + +ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pkey PRIMARY KEY (pr_id); +ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pr_id_key UNIQUE (pr_id); diff --git a/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql new file mode 100644 index 0000000..c74f51d --- /dev/null +++ b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql @@ -0,0 +1,7 @@ +ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pkey; +ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pr_id_key; + + +ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pkey PRIMARY KEY (pr_id, issue_id); +ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pr_id_key UNIQUE (pr_id, issue_id); +ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_fkey FOREIGN KEY (issue_id) REFERENCES issues(issue_id); diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index a3728a7..6c2f1e7 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -174,22 +174,23 @@ pr-body :body pr-title :title} :pull_request}] (log/info "handle-pull-request-event" event-type owner repo repo-id login pr-body pr-title) - (if-let [issue (some #(issues/get-issue repo-id %1) (extract-issue-number owner repo pr-body pr-title))] - (if-not (:commit_sha issue) ; no PR has been merged yet referencing this issue - (do - (log/info "Referenced bounty issue found" owner repo (:issue_number issue)) - (handle-claim issue - user-id - login name - avatar_url - owner repo - repo-id - pr-id - pr-number - head-sha - merged? - event-type)) - (log/info "PR for issue already merged")) + (if-let [issues (remove nil? (map #(issues/get-issue repo-id %1) (extract-issue-number owner repo pr-body pr-title)))] + (doseq [issue issues] + (if-not (:commit_sha issue) ; no PR has been merged yet referencing this issue + (do + (log/info "Referenced bounty issue found" owner repo (:issue_number issue)) + (handle-claim issue + user-id + login name + avatar_url + owner repo + repo-id + pr-id + pr-number + head-sha + merged? + event-type)) + (log/info "PR for issue already merged"))) (when (= :edited event-type) ; Remove PR if it does not reference any issue (pull-requests/remove pr-id)))) From aaee8a072a9c43c7e001af8188088b2ec80931d8 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Tue, 10 Apr 2018 13:59:12 +0300 Subject: [PATCH 02/35] Delete rows from pull_requests which map to non-existing issues --- .../migrations/20180403131200-multiple-claims-in-pr.up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql index c74f51d..1f05d4f 100644 --- a/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql +++ b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql @@ -1,7 +1,7 @@ ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pkey; ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pr_id_key; - +DELETE FROM pull_requests p WHERE NOT EXISTS (SELECT issue_id FROM issues i where p.issue_id=i.issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pkey PRIMARY KEY (pr_id, issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pr_id_key UNIQUE (pr_id, issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_fkey FOREIGN KEY (issue_id) REFERENCES issues(issue_id); From ae6a08cd0c3e7952577950f272417eb51552d24e Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Tue, 10 Apr 2018 14:41:25 +0300 Subject: [PATCH 03/35] Undo DELETE statement in migration script --- resources/migrations/20180403131200-multiple-claims-in-pr.up.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql index 1f05d4f..c7b29fb 100644 --- a/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql +++ b/resources/migrations/20180403131200-multiple-claims-in-pr.up.sql @@ -1,7 +1,6 @@ ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pkey; ALTER TABLE pull_requests DROP CONSTRAINT pull_requests_pr_id_key; -DELETE FROM pull_requests p WHERE NOT EXISTS (SELECT issue_id FROM issues i where p.issue_id=i.issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pkey PRIMARY KEY (pr_id, issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_pr_id_key UNIQUE (pr_id, issue_id); ALTER TABLE pull_requests ADD CONSTRAINT pull_requests_fkey FOREIGN KEY (issue_id) REFERENCES issues(issue_id); From 97d5c64548cbc3076f42e0800f254e82efa3407c Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Tue, 10 Apr 2018 18:17:31 +0300 Subject: [PATCH 04/35] Fix column spec in ON CONFLICT clause --- resources/sql/queries.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 81316d8..4c061f8 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -220,7 +220,7 @@ VALUES(:pr_id, :commit_sha, :user_id, :state) -ON CONFLICT (pr_id) DO UPDATE +ON CONFLICT (pr_id,issue_id) DO UPDATE SET state = :state, issue_number = :issue_number, From ffce0828c07924a04ce068d7f69c15c9547d63c5 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Fri, 6 Apr 2018 18:37:12 +0300 Subject: [PATCH 05/35] Add less to Dockerfile --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 83164d0..b920d3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,7 @@ WORKDIR /root/ RUN apt-get update RUN apt-get -y install xvfb RUN apt-get -y install wkhtmltopdf +RUN apt-get -y install less COPY --from=builder /usr/src/app/target/uberjar/commiteth.jar . COPY html2png.sh . From a4463b9810c33d3c8d3e7e12e2f47a9c78e5c292 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 12 Apr 2018 10:58:42 +0200 Subject: [PATCH 06/35] always log issue id when deploying contracts --- src/clj/commiteth/bounties.clj | 27 ++++++++++++--------------- src/clj/commiteth/db/issues.clj | 4 +++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index 13661ae..2be8511 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -22,24 +22,22 @@ (defn deploy-contract [owner owner-address repo issue-id issue-number] (if (empty? owner-address) - (log/error "Unable to deploy bounty contract because" - "repo owner has no Ethereum addres") + (log/errorf "issue %s: Unable to deploy bounty contract because repo owner has no Ethereum addres" issue-id) (do - (log/info "deploying contract to " owner-address) + (log/infof "issue %s: Deploying contract to %s" issue-id owner-address) (if-let [transaction-hash (multisig/deploy-multisig owner-address)] (do - (log/info "Contract deployed, transaction-hash:" - transaction-hash) + (log/infof "issue %s: Contract deployed, transaction-hash: %s" issue-id transaction-hash) (let [resp (github/post-deploying-comment owner repo issue-number transaction-hash) - _ (log/info "post-deploying-comment response:" resp) comment-id (:id resp)] + (log/infof "issue %s: post-deploying-comment response: %s" issue-id resp) (issues/update-comment-id issue-id comment-id)) (issues/update-transaction-hash issue-id transaction-hash)) - (log/error "Failed to deploy contract to" owner-address))))) - + (log/errorf "issue %s Failed to deploy contract to %s" issue-id owner-address))))) + (defn add-bounty-for-issue [repo repo-id issue] (let [{issue-id :id issue-number :number @@ -47,16 +45,17 @@ created-issue (issues/create repo-id issue-id issue-number issue-title) {owner-address :address owner :owner} (users/get-repo-owner repo-id)] - (log/debug "Adding bounty for issue " repo issue-number "owner address: " owner-address) + (log/debug "issue %s: Adding bounty for issue %s/%s - owner address: %s" + issue-id repo issue-number owner-address) (if (= 1 created-issue) (deploy-contract owner owner-address repo issue-id issue-number) - (log/debug "Issue already exists in DB, ignoring")))) + (log/debug "issue %s: Issue already exists in DB, ignoring")))) (defn maybe-add-bounty-for-issue [repo repo-id issue] (let [res (issues/get-issues-count repo-id) {count :count} res - limit-reached? (> count max-issues-limit) - _ (log/debug "*** get-issues-count" repo-id " " res " " count " " limit-reached?)] + limit-reached? (> count max-issues-limit)] + (log/debug "*** get-issues-count" repo-id " " res " " count " " limit-reached?) (if limit-reached? (log/debug "Total issues for repo limit reached " repo " " count) (add-bounty-for-issue repo repo-id issue)))) @@ -102,9 +101,7 @@ (issues/get-issue-titles)] (let [gh-issue (github/get-issue owner repo issue_number)] (if-not (= title (:title gh-issue)) - (do - (log/info "Updating changed title for issue" (:id gh-issue)) - (issues/update-issue-title (:id gh-issue) (:title gh-issue))))))) + (issues/update-issue-title (:id gh-issue) (:title gh-issue)))))) (defn assert-keys [m ks] (doseq [k ks] diff --git a/src/clj/commiteth/db/issues.clj b/src/clj/commiteth/db/issues.clj index fe4b6ce..d910aae 100644 --- a/src/clj/commiteth/db/issues.clj +++ b/src/clj/commiteth/db/issues.clj @@ -1,7 +1,8 @@ (ns commiteth.db.issues (:require [commiteth.db.core :refer [*db*] :as db] [clojure.java.jdbc :as jdbc] - [clojure.set :refer [rename-keys]])) + [clojure.set :refer [rename-keys]] + [clojure.tools.logging :as log])) (defn create "Creates issue" @@ -31,6 +32,7 @@ (defn update-issue-title [issue-id title] + (log/info "issue %s: Updating changed title \"%s\"" issue-id title) (jdbc/with-db-connection [con-db *db*] (db/update-issue-title con-db {:issue_id issue-id :title title}))) From 52edd4e20706f56ff01a30e0c9f1ed41758d4600 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 12 Apr 2018 12:08:12 +0200 Subject: [PATCH 07/35] improved logging in commiteth.scheduler --- src/clj/commiteth/scheduler.clj | 215 ++++++++++++++++---------------- 1 file changed, 105 insertions(+), 110 deletions(-) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 8400033..ab9be50 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -38,6 +38,7 @@ (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" @@ -45,56 +46,54 @@ (log/info "In update-issue-contract-address") (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 - (when-let [receipt (eth/get-transaction-receipt transaction-hash)] - (log/info "update-issue-contract-address: transaction receipt for issue #" - issue-id ": " receipt) - (if-let [contract-address (multisig/find-created-multisig-address receipt)] - (let [issue (issues/update-contract-address issue-id contract-address) - {owner :owner - repo :repo - comment-id :comment_id - issue-number :issue_number} issue - balance-eth-str (eth/get-balance-eth contract-address 6) - balance-eth (read-string balance-eth-str)] - (log/info "Updating comment image") - (bounties/update-bounty-comment-image issue-id - owner - repo - issue-number - contract-address - balance-eth - balance-eth-str - {}) - (log/info "Updating comment") - (github/update-comment owner - repo - comment-id - issue-number - contract-address - balance-eth - balance-eth-str - {})) - (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)))))) + transaction-hash :transaction_hash} (issues/list-pending-deployments)] + (log/infof "issue %s: pending deployment: %s" issue-id transaction-hash) + (try + (when-let [receipt (eth/get-transaction-receipt transaction-hash)] + (log/infof "issue %s: update-issue-contract-address: tx receipt: %s" issue-id receipt) + (if-let [contract-address (multisig/find-created-multisig-address receipt)] + (let [issue (issues/update-contract-address issue-id contract-address) + {owner :owner + repo :repo + comment-id :comment_id + issue-number :issue_number} issue + balance-eth-str (eth/get-balance-eth contract-address 6) + balance-eth (read-string balance-eth-str)] + (log/infof "issue %s: Updating comment image" issue-id) + (bounties/update-bounty-comment-image issue-id + owner + repo + issue-number + contract-address + balance-eth + balance-eth-str + {}) + (log/infof "issue %s: Updating comment" issue-id) + (github/update-comment owner + repo + comment-id + issue-number + contract-address + balance-eth + balance-eth-str + {})) + (log/errorf "issue %s: Failed to find contract address in tx logs" issue-id))) + (catch Throwable ex + (log/errorf ex "issue %s: update-issue-contract-address exception:" issue-id))))) (log/info "Exit update-issue-contract-address")) (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." [] - (p :deploy-pending-contracts - (doseq [{issue-id :issue_id - issue-number :issue_number - owner :owner - owner-address :owner_address - repo :repo} (db-bounties/pending-contracts)] - (log/debug "Trying to re-deploy failed bounty contract deployment, issue-id:" issue-id) - (bounties/deploy-contract owner owner-address repo issue-id issue-number)))) + (p :deploy-pending-contracts + (doseq [{issue-id :issue_id + issue-number :issue_number + owner :owner + owner-address :owner_address + repo :repo} (db-bounties/pending-contracts)] + (log/infof "issue %s: Trying to re-deploy failed bounty contract deployment" issue-id) + (bounties/deploy-contract owner owner-address repo issue-id issue-number)))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" @@ -110,37 +109,35 @@ issue-number :issue_number balance-eth :balance_eth tokens :tokens - winner-login :winner_login} (db-bounties/pending-bounties)] - (try - (let [value (eth/get-balance-hex contract-address)] - (if (empty? payout-address) - (do - (log/error "Cannot sign pending bounty - winner has no payout address") - (github/update-merged-issue-comment owner - repo - comment-id - contract-address - (eth-decimal->str balance-eth) - tokens - winner-login - true)) - (let [execute-hash (multisig/send-all contract-address payout-address)] - (log/info "Payout self-signed, called sign-all(" contract-address payout-address ") tx:" execute-hash) - (db-bounties/update-execute-hash issue-id execute-hash) - (db-bounties/update-winner-login issue-id winner-login) - (github/update-merged-issue-comment owner - repo - comment-id - contract-address - (eth-decimal->str balance-eth) - tokens - winner-login - false)))) - (catch Throwable ex - (do (log/error "self-sign-bounty exception:" ex) - (clojure.stacktrace/print-stack-trace ex)))))) - (log/info "Exit self-sign-bounty") - ) + winner-login :winner_login} (db-bounties/pending-bounties)] + (try + (let [value (eth/get-balance-hex contract-address)] + (if (empty? payout-address) + (do + (log/warn "issue %s: Cannot sign pending bounty - winner has no payout address" issue-id) + (github/update-merged-issue-comment owner + repo + comment-id + contract-address + (eth-decimal->str balance-eth) + tokens + winner-login + true)) + (let [execute-hash (multisig/send-all contract-address payout-address)] + (log/infof "issue %s: Payout self-signed, called sign-all(%s) tx: %s" issue-id contract-address payout-address execute-hash) + (db-bounties/update-execute-hash issue-id execute-hash) + (db-bounties/update-winner-login issue-id winner-login) + (github/update-merged-issue-comment owner + repo + comment-id + contract-address + (eth-decimal->str balance-eth) + tokens + winner-login + false)))) + (catch Throwable ex + (log/error ex "issue %s: self-sign-bounty exception" issue-id))))) + (log/info "Exit self-sign-bounty")) (defn update-confirm-hash "Gets transaction receipt for each pending payout and updates DB confirm_hash with tranaction ID of commiteth bot account's confirmation." @@ -148,13 +145,13 @@ (log/info "In update-confirm-hash") (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))))) + execute-hash :execute_hash} (db-bounties/pending-payouts)] + (log/infof "issue %s: pending payout: %s" issue-id execute-hash) + (when-let [receipt (eth/get-transaction-receipt execute-hash)] + (log/infof "issue %s: execution receipt for issue " issue-id receipt) + (when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)] + (log/infof "issue %s: confirm hash:" issue-id confirm-hash) + (db-bounties/update-confirm-hash issue-id confirm-hash))))) (log/info "Exit update-confirm-hash")) @@ -163,10 +160,10 @@ [] (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))))) + watch-hash :watch_hash} (db-bounties/pending-watch-calls)] + (log/infof "issue %s: pending watch call %s" issue-id watch-hash) + (when-let [receipt (eth/get-transaction-receipt watch-hash)] + (db-bounties/update-watch-hash issue-id nil))))) (defn older-than-3h? @@ -194,7 +191,7 @@ confirm-id :confirm_hash payee-login :payee_login updated :updated} (db-bounties/confirmed-payouts)] - (log/debug "confirmed payout:" payout-hash) + (log/infof "issue %s: confirmed payout: %s" issue-id payout-hash) (try (if-let [receipt (eth/get-transaction-receipt payout-hash)] (let [contract-tokens (multisig/token-balances contract-address) @@ -203,14 +200,14 @@ (some #(> (second %) 0.0) contract-tokens) (> contract-eth-balance 0)) (do - (log/info "Contract still has funds") + (log/infof "issue %s: Contract (%s) still has funds" issue-id contract-address) (when (multisig/is-confirmed? contract-address confirm-id) - (log/info "Detected bounty with funds and confirmed payout, calling executeTransaction") + (log/infof "issue %s: Detected bounty with funds and confirmed payout, calling executeTransaction" issue-id) (let [execute-tx-hash (multisig/execute-tx contract-address confirm-id)] - (log/info "execute tx:" execute-tx-hash)))) + (log/infof "issue %s: execute tx: %s" issue-id execute-tx-hash)))) (do - (log/info "Payout has succeeded, saving payout receipt for issue #" issue-id ": " receipt) + (log/infof "issue %s: Payout has succeeded, payout receipt %s" issue-id receipt) (db-bounties/update-payout-receipt issue-id receipt) (github/update-paid-issue-comment owner repo @@ -220,13 +217,11 @@ tokens payee-login)))) (when (older-than-3h? updated) - (log/info "Resetting payout hash for issue" issue-id "as it has not been mined in 3h") + (log/warn "issue %s: Resetting payout hash for issue as it has not been mined in 3h" issue-id) (db-bounties/reset-payout-hash issue-id))) - (catch Throwable ex - (do (log/error "update-payout-receipt exception:" ex) - (clojure.stacktrace/print-stack-trace ex)))))) - (log/info "Exit update-payout-receipt") - ) + (catch Throwable ex + (log/error ex "issue %s: update-payout-receipt exception" issue-id))))) + (log/info "Exit update-payout-receipt")) (defn abs "(abs n) is the absolute value of n" @@ -239,7 +234,9 @@ (defn update-bounty-token-balances - "Helper function for updating internal ERC20 token balances to token multisig contract. Will be called periodically for all open bounty contracts." + "Helper function for updating internal ERC20 token balances to token + multisig contract. Will be called periodically for all open bounty + contracts." [issue-id bounty-addr watch-hash] #_(log/info "In update-bounty-token-balances for issue" issue-id) (doseq [[tla token-data] (token-data/as-map)] @@ -247,18 +244,17 @@ (let [balance (multisig/token-balance bounty-addr tla)] (when (> balance 0) (do - (log/info "bounty at" bounty-addr "has" balance "of token" tla) + (log/infof "bounty %s: has %s of token %s" bounty-addr balance tla) (let [internal-balance (multisig/token-balance-in-bounty bounty-addr tla)] (when (and (nil? watch-hash) (not= balance internal-balance)) - (log/info "balances not in sync, calling watch") + (log/infof "bounty %s: balances not in sync, calling watch" bounty-addr) (let [hash (multisig/watch-token bounty-addr tla)] (db-bounties/update-watch-hash issue-id hash))))))) - (catch Throwable ex - (do (log/error "update-bounty-token-balances exception:" ex) - (clojure.stacktrace/print-stack-trace ex))))) + (catch Throwable ex + (log/error ex "bounty %s: update-bounty-token-balances exception" bounty-addr)))) #_(log/info "Exit update-bounty-token-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." @@ -296,8 +292,8 @@ [] (p :update-open-issue-usd-values (doseq [{bounty-addr :contract_address} - (db-bounties/open-bounty-contracts)] - (update-issue-usd-value bounty-addr)))) + (db-bounties/open-bounty-contracts)] + (update-issue-usd-value bounty-addr)))) (defn float= ([x y] (float= x y 0.0000001)) @@ -327,7 +323,7 @@ (let [balance-eth-str (eth/get-balance-eth contract-address 6) balance-eth (read-string balance-eth-str) token-balances (multisig/token-balances contract-address)] - (log/debug "update-balances" balance-eth + (log/debug "issue" issue-id ": update-balances" balance-eth balance-eth-str token-balances owner repo issue-number) (when (or @@ -361,8 +357,7 @@ token-balances) (update-issue-usd-value contract-address)))) (catch Throwable ex - (do (log/error "update-balances exception:" ex) - (clojure.stacktrace/print-stack-trace ex)))))) + (log/error ex "issue %s: update-balances exception" issue-id))))) (log/info "Exit update-balances")) @@ -370,7 +365,7 @@ (try (func) (catch Throwable t - (log/error t)))) + (log/error t (.getMessage t) (ex-data t))))) (defn run-tasks [tasks] (doall From 893a0bdffb6efaa1aef7a20a752410659a26961d Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Thu, 12 Apr 2018 13:56:20 +0300 Subject: [PATCH 08/35] Add try-catch to update-confirm-hash, update-watch-hash, deploy-pending-contracts --- src/clj/commiteth/scheduler.clj | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index ab9be50..907b143 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -93,7 +93,10 @@ owner-address :owner_address repo :repo} (db-bounties/pending-contracts)] (log/infof "issue %s: Trying to re-deploy failed bounty contract deployment" issue-id) - (bounties/deploy-contract owner owner-address repo issue-id issue-number)))) + (try + (bounties/deploy-contract owner owner-address repo issue-id issue-number) + (catch Throwable ex + (log/errorf ex "issue %s: deploy-pending-contracts exception:" issue-id)))))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" @@ -147,11 +150,14 @@ (doseq [{issue-id :issue_id execute-hash :execute_hash} (db-bounties/pending-payouts)] (log/infof "issue %s: pending payout: %s" issue-id execute-hash) - (when-let [receipt (eth/get-transaction-receipt execute-hash)] - (log/infof "issue %s: execution receipt for issue " issue-id receipt) - (when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)] - (log/infof "issue %s: confirm hash:" issue-id confirm-hash) - (db-bounties/update-confirm-hash issue-id confirm-hash))))) + (try + (when-let [receipt (eth/get-transaction-receipt execute-hash)] + (log/infof "issue %s: execution receipt for issue " issue-id receipt) + (when-let [confirm-hash (multisig/find-confirmation-tx-id receipt)] + (log/infof "issue %s: confirm hash:" issue-id confirm-hash) + (db-bounties/update-confirm-hash issue-id confirm-hash))) + (catch Throwable ex + (log/errorf ex "issue %s: update-confirm-hash exception:" issue-id))))) (log/info "Exit update-confirm-hash")) @@ -162,8 +168,11 @@ (doseq [{issue-id :issue_id watch-hash :watch_hash} (db-bounties/pending-watch-calls)] (log/infof "issue %s: pending watch call %s" issue-id watch-hash) - (when-let [receipt (eth/get-transaction-receipt watch-hash)] - (db-bounties/update-watch-hash issue-id nil))))) + (try + (when-let [receipt (eth/get-transaction-receipt watch-hash)] + (db-bounties/update-watch-hash issue-id nil)) + (catch Throwable ex + (log/errorf ex "issue %s: update-watch-hash exception:" issue-id)))))) (defn older-than-3h? @@ -238,7 +247,7 @@ multisig contract. Will be called periodically for all open bounty contracts." [issue-id bounty-addr watch-hash] - #_(log/info "In update-bounty-token-balances for issue" issue-id) + (log/info "In update-bounty-token-balances for issue" issue-id) (doseq [[tla token-data] (token-data/as-map)] (try (let [balance (multisig/token-balance bounty-addr tla)] @@ -253,7 +262,7 @@ (db-bounties/update-watch-hash issue-id hash))))))) (catch Throwable ex (log/error ex "bounty %s: update-bounty-token-balances exception" bounty-addr)))) - #_(log/info "Exit update-bounty-token-balances")) + (log/info "Exit update-bounty-token-balances")) (defn update-contract-internal-balances From 2df66222fc95b880b939b59954ec8412dab16b6d Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 12 Apr 2018 16:00:52 +0200 Subject: [PATCH 09/35] log ex-data for deploy-pending-contracts exception --- src/clj/commiteth/scheduler.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 907b143..1be116c 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -95,8 +95,8 @@ (log/infof "issue %s: Trying to re-deploy failed bounty contract deployment" issue-id) (try (bounties/deploy-contract owner owner-address repo issue-id issue-number) - (catch Throwable ex - (log/errorf ex "issue %s: deploy-pending-contracts exception:" issue-id)))))) + (catch Throwable t + (log/errorf t "issue %s: deploy-pending-contracts exception: %s" issue-id (ex-data t))))))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" From 5c9245810b237e43f765cc30973ba128b2dc56f4 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Thu, 12 Apr 2018 16:00:52 +0200 Subject: [PATCH 10/35] log ex-data for deploy-pending-contracts exception --- src/clj/commiteth/scheduler.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 907b143..1be116c 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -95,8 +95,8 @@ (log/infof "issue %s: Trying to re-deploy failed bounty contract deployment" issue-id) (try (bounties/deploy-contract owner owner-address repo issue-id issue-number) - (catch Throwable ex - (log/errorf ex "issue %s: deploy-pending-contracts exception:" issue-id)))))) + (catch Throwable t + (log/errorf t "issue %s: deploy-pending-contracts exception: %s" issue-id (ex-data t))))))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" From 4705b6619aa1e35f1ca1cb810844b05f675bac76 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 13:24:03 +0200 Subject: [PATCH 11/35] log eth-rpc results + different req-id approach --- src/clj/commiteth/eth/core.clj | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 4db60c1..b172592 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -122,18 +122,24 @@ nil))))) +(def req-id-tracker + ;; HACK to ensure previous random-number approach doesn't lead to + ;; unintended collisions + (atom 0)) + (defn eth-rpc [method params] - (let [request-id (rand-int 4096) - body (json/write-str {:jsonrpc "2.0" - :method method - :params params - :id request-id}) + (let [request-id (swap! req-id-tracker inc) + body {:jsonrpc "2.0" + :method method + :params params + :id request-id} options {:headers {"content-type" "application/json"} - :body body} + :body (json/write-str body)} response @(post (eth-rpc-url) options) result (safe-read-str (:body response))] - (log/debug body "\n" result) + (log/infof "eth-rpc req(%s) body: %s\neth-rpc req(%s) result: %s" + request-id body request-id result) (cond ;; Ignore any responses that have mismatching request ID From 98522ea16fdb4545460d37a4ddf6b66362854895 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 14:11:17 +0200 Subject: [PATCH 12/35] disable verbose webhook logging for now --- src/clj/commiteth/routes/webhooks.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index 6c2f1e7..b7fc05d 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -384,7 +384,7 @@ (log/debug "webhook-app POST, headers" headers) (let [raw-payload (slurp body) payload (json/parse-string raw-payload true)] - (log/info "webhook-app POST, payload:" (pr-str payload)) + (log/debug "webhook-app POST, payload:" (pr-str payload)) (if (validate-secret-one-hook payload raw-payload (get headers "x-hub-signature")) (do (log/debug "Github secret validation OK app") From 248da65d3200860e9b68b41c2cdd8c6eac450a67 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 13:24:03 +0200 Subject: [PATCH 13/35] log eth-rpc results + different req-id approach --- src/clj/commiteth/eth/core.clj | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 4db60c1..b172592 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -122,18 +122,24 @@ nil))))) +(def req-id-tracker + ;; HACK to ensure previous random-number approach doesn't lead to + ;; unintended collisions + (atom 0)) + (defn eth-rpc [method params] - (let [request-id (rand-int 4096) - body (json/write-str {:jsonrpc "2.0" - :method method - :params params - :id request-id}) + (let [request-id (swap! req-id-tracker inc) + body {:jsonrpc "2.0" + :method method + :params params + :id request-id} options {:headers {"content-type" "application/json"} - :body body} + :body (json/write-str body)} response @(post (eth-rpc-url) options) result (safe-read-str (:body response))] - (log/debug body "\n" result) + (log/infof "eth-rpc req(%s) body: %s\neth-rpc req(%s) result: %s" + request-id body request-id result) (cond ;; Ignore any responses that have mismatching request ID From 5d8f23201695a021306d0cd70edefccdbac8d0c0 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 14:11:17 +0200 Subject: [PATCH 14/35] disable verbose webhook logging for now --- src/clj/commiteth/routes/webhooks.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index 6c2f1e7..b7fc05d 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -384,7 +384,7 @@ (log/debug "webhook-app POST, headers" headers) (let [raw-payload (slurp body) payload (json/parse-string raw-payload true)] - (log/info "webhook-app POST, payload:" (pr-str payload)) + (log/debug "webhook-app POST, payload:" (pr-str payload)) (if (validate-secret-one-hook payload raw-payload (get headers "x-hub-signature")) (do (log/debug "Github secret validation OK app") From ca439aa1ec8792bb91bc21744115917a02b54dce Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 14:51:41 +0200 Subject: [PATCH 15/35] log various tx params --- src/clj/commiteth/eth/core.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index b172592..31ec238 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -73,6 +73,7 @@ data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] + (log/info "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" nonce gas-price gas-limit data) hex-string)) (defn eth-gasstation-gas-price From cdf889caaa4bad6b300993a409fb4334b684ef87 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 14:51:41 +0200 Subject: [PATCH 16/35] log various tx params --- src/clj/commiteth/eth/core.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index b172592..31ec238 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -73,6 +73,7 @@ data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] + (log/info "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" nonce gas-price gas-limit data) hex-string)) (defn eth-gasstation-gas-price From 7ab281ff137e961acbb0a036aa1774100529124a Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 15:09:03 +0200 Subject: [PATCH 17/35] log/infof typo --- src/clj/commiteth/eth/core.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 31ec238..f70374d 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -73,7 +73,8 @@ data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] - (log/info "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" nonce gas-price gas-limit data) + (log/infof "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" + nonce gas-price gas-limit data) hex-string)) (defn eth-gasstation-gas-price From dbb672318bb424ce561e12ef8b3eacbf92ba55f6 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Fri, 13 Apr 2018 15:09:03 +0200 Subject: [PATCH 18/35] log/infof typo --- src/clj/commiteth/eth/core.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 31ec238..f70374d 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -73,7 +73,8 @@ data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] - (log/info "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" nonce gas-price gas-limit data) + (log/infof "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" + nonce gas-price gas-limit data) hex-string)) (defn eth-gasstation-gas-price From 6724e2612adafde84c3bcce1ad1caaa8960d5c9b Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Wed, 14 Mar 2018 12:49:00 -0400 Subject: [PATCH 19/35] display other helpful fields if pr title is missing --- .../20180314124717-store-pr-title.down.sql | 1 + .../20180314124717-store-pr-title.up.sql | 1 + ...80330143004-pr-data-activity-feed.down.sql | 78 ++++++++++++ ...0180330143004-pr-data-activity-feed.up.sql | 91 ++++++++++++++ resources/public/blue-arrow-down.png | Bin 0 -> 266 bytes resources/public/blue-arrow-up.png | Bin 0 -> 620 bytes resources/sql/queries.sql | 6 + src/clj/commiteth/routes/services.clj | 4 + src/clj/commiteth/routes/webhooks.clj | 5 +- src/cljs/commiteth/bounties.cljs | 118 ++++++++++++------ src/cljs/commiteth/common.cljs | 3 + src/cljs/commiteth/db.cljs | 3 +- src/cljs/commiteth/handlers.cljs | 10 ++ src/cljs/commiteth/subscriptions.cljs | 28 +++-- src/less/style.less | 36 +++++- 15 files changed, 333 insertions(+), 51 deletions(-) create mode 100644 resources/migrations/20180314124717-store-pr-title.down.sql create mode 100644 resources/migrations/20180314124717-store-pr-title.up.sql create mode 100644 resources/migrations/20180330143004-pr-data-activity-feed.down.sql create mode 100644 resources/migrations/20180330143004-pr-data-activity-feed.up.sql create mode 100644 resources/public/blue-arrow-down.png create mode 100644 resources/public/blue-arrow-up.png diff --git a/resources/migrations/20180314124717-store-pr-title.down.sql b/resources/migrations/20180314124717-store-pr-title.down.sql new file mode 100644 index 0000000..d8d5a59 --- /dev/null +++ b/resources/migrations/20180314124717-store-pr-title.down.sql @@ -0,0 +1 @@ +ALTER TABLE "public"."pull_requests" DROP COLUMN "title"; diff --git a/resources/migrations/20180314124717-store-pr-title.up.sql b/resources/migrations/20180314124717-store-pr-title.up.sql new file mode 100644 index 0000000..1a3e001 --- /dev/null +++ b/resources/migrations/20180314124717-store-pr-title.up.sql @@ -0,0 +1 @@ +ALTER TABLE "public"."pull_requests" ADD COLUMN "title" character varying(256); diff --git a/resources/migrations/20180330143004-pr-data-activity-feed.down.sql b/resources/migrations/20180330143004-pr-data-activity-feed.down.sql new file mode 100644 index 0000000..2fb71ed --- /dev/null +++ b/resources/migrations/20180330143004-pr-data-activity-feed.down.sql @@ -0,0 +1,78 @@ +-- restore the previous version of the view +CREATE VIEW "public"."claims_view" AS SELECT i.title AS issue_title, + i.issue_number, + r.repo AS repo_name, + r.owner AS repo_owner, + COALESCE(u.name, u.login) AS user_name, + u.avatar_url AS user_avatar_url, + i.payout_receipt, + p.updated, + i.updated AS issue_updated, + i.balance_eth, + i.tokens, + i.value_usd, + p.state AS pr_state, + i.is_open AS issue_open, + (case when u.address IS NULL THEN false ELSE true END) AS user_has_address + FROM issues i, + users u, + repositories r, + pull_requests p + WHERE r.repo_id = i.repo_id + AND p.issue_id = i.issue_id + AND p.user_id = u.id + AND i.contract_address IS NOT NULL + AND i.comment_id IS NOT NULL + ORDER BY p.updated; + + +CREATE OR REPLACE VIEW "public"."activity_feed_view" AS + SELECT 'open-claim'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.updated + FROM claims_view + WHERE claims_view.pr_state = 0 + AND claims_view.payout_receipt IS NULL + AND claims_view.issue_open IS TRUE +UNION + SELECT 'claim-pending'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.issue_updated AS updated + FROM claims_view + WHERE claims_view.pr_state = 1 + AND claims_view.payout_receipt IS NULL +UNION + SELECT 'claim-payout'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.issue_updated AS updated + FROM claims_view + WHERE claims_view.pr_state = 1 + AND claims_view.payout_receipt IS NOT NULL + ORDER BY 12 DESC; diff --git a/resources/migrations/20180330143004-pr-data-activity-feed.up.sql b/resources/migrations/20180330143004-pr-data-activity-feed.up.sql new file mode 100644 index 0000000..38a0cf8 --- /dev/null +++ b/resources/migrations/20180330143004-pr-data-activity-feed.up.sql @@ -0,0 +1,91 @@ +DROP VIEW "public"."claims_view" CASCADE; + +CREATE VIEW "public"."claims_view" AS SELECT i.title AS issue_title, + i.issue_number, + r.repo AS repo_name, + r.owner AS repo_owner, + p.title AS pr_title, -- added + p.pr_number AS pr_number, -- added + p.pr_id AS pr_id, -- added + COALESCE(u.name, u.login) AS user_name, + u.avatar_url AS user_avatar_url, + i.payout_receipt, + p.updated, + i.updated AS issue_updated, + i.balance_eth, + i.tokens, + i.value_usd, + p.state AS pr_state, + i.is_open AS issue_open, + (case when u.address IS NULL THEN false ELSE true END) AS user_has_address + FROM issues i, + users u, + repositories r, + pull_requests p + WHERE r.repo_id = i.repo_id + AND p.issue_id = i.issue_id + AND p.user_id = u.id + AND i.contract_address IS NOT NULL + AND i.comment_id IS NOT NULL + ORDER BY p.updated; + + +CREATE VIEW "public"."activity_feed_view" AS -- altered + SELECT 'open-claim'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.pr_title, -- added + claims_view.pr_number, -- added + claims_view.pr_id, -- added + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.updated + FROM claims_view + WHERE claims_view.pr_state = 0 + AND claims_view.payout_receipt IS NULL + AND claims_view.issue_open IS TRUE +UNION + SELECT 'claim-pending'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.pr_title, -- added + claims_view.pr_number, -- added + claims_view.pr_id, -- added + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.issue_updated AS updated + FROM claims_view + WHERE claims_view.pr_state = 1 + AND claims_view.payout_receipt IS NULL +UNION + SELECT 'claim-payout'::text AS type, + claims_view.issue_title, + claims_view.repo_name, + claims_view.repo_owner, + claims_view.pr_title, -- added + claims_view.pr_number, -- added + claims_view.pr_id, -- added + claims_view.issue_number, + claims_view.user_name, + claims_view.user_avatar_url, + claims_view.balance_eth, + claims_view.tokens, + claims_view.value_usd, + claims_view.user_has_address, + claims_view.issue_updated AS updated + FROM claims_view + WHERE claims_view.pr_state = 1 + AND claims_view.payout_receipt IS NOT NULL + ORDER BY 12 DESC; diff --git a/resources/public/blue-arrow-down.png b/resources/public/blue-arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..962ed795cf170221aef01ac7b04b14eab2d36581 GIT binary patch literal 266 zcmV+l0rmcgP)5QNO$x#=5QXRE0&TaR%G^O){6j$~xDj0lf+&iDvT-TQ+Z-$NJyu6Q!Ci3a@D= Q4FCWD07*qoM6N<$f}XHx&j0`b literal 0 HcmV?d00001 diff --git a/resources/public/blue-arrow-up.png b/resources/public/blue-arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..16774b73c1bbf32e56892a9d366694949fa04ddd GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&H!3HG1G_PL;q*&4&eH|GXHuiJ>Nn~YUV2sQR zi71Ki^|4CM&(%vz$xlkvtH>8?tx|+mh4pF`@Az>wVM>EaloA=*13kn4~EPut|U18>v5 zu_&!@4G>{*{NTvyDB^liG3@pQ|N*_9c_aH z^$kWRKe`%tNs8>ab~YjI*z~R{HA~@x2kcXBwxt@^KPz%{aaoZhUHI1e#Co0E8*^Tr zzcfcURVaBq%aXc-G5wDUruTN*|L(FAIy&t;ucLK6T}@z$vT literal 0 HcmV?d00001 diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 4c061f8..ef40b5f 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -207,6 +207,7 @@ AND i.transaction_hash IS NOT NULL; INSERT INTO pull_requests (pr_id, repo_id, pr_number, + title, issue_number, issue_id, commit_sha, @@ -215,6 +216,7 @@ INSERT INTO pull_requests (pr_id, VALUES(:pr_id, :repo_id, :pr_number, + :title, :issue_number, :issue_id, :commit_sha, @@ -225,6 +227,7 @@ SET state = :state, issue_number = :issue_number, issue_id = :issue_id, + title = :title, updated = timezone('utc'::text, now()), commit_sha = :commit_sha; @@ -592,6 +595,9 @@ SELECT issue_title, repo_name, repo_owner, + pr_number, + pr_title, + pr_id, issue_number, user_name, user_avatar_url, diff --git a/src/clj/commiteth/routes/services.clj b/src/clj/commiteth/routes/services.clj index ce5d426..656c804 100644 --- a/src/clj/commiteth/routes/services.clj +++ b/src/clj/commiteth/routes/services.clj @@ -109,10 +109,14 @@ renames {:user_name :display-name :user_avatar_url :avatar-url :issue_title :issue-title + :pr_title :pr-title + :pr_number :pr-number + :pr_id :pr-id :type :item-type :repo_name :repo-name :repo_owner :repo-owner :issue_number :issue-number + :issue_id :issue-id :value_usd :value-usd :claim_count :claim-count :balance_eth :balance-eth diff --git a/src/clj/commiteth/routes/webhooks.clj b/src/clj/commiteth/routes/webhooks.clj index b7fc05d..88b374d 100644 --- a/src/clj/commiteth/routes/webhooks.clj +++ b/src/clj/commiteth/routes/webhooks.clj @@ -115,18 +115,18 @@ (defn handle-claim - [issue user-id login name avatar_url owner repo repo-id pr-id pr-number head-sha merged? event-type] + [issue user-id login name avatar_url owner repo repo-id pr-id pr-number pr-title head-sha merged? event-type] (users/create-user user-id login name nil avatar_url) (let [open-or-edit? (contains? #{:opened :edited} event-type) close? (= :closed event-type) pr-data {:repo_id repo-id :pr_id pr-id :pr_number pr-number + :title pr-title :user_id user-id :issue_number (:issue_number issue) :issue_id (:issue_id issue) :state event-type}] - ;; TODO: in the opened case if the submitting user has no ;; Ethereum address stored, we could post a comment to the ;; Github PR explaining that payout is not possible if the PR is @@ -187,6 +187,7 @@ repo-id pr-id pr-number + pr-title head-sha merged? event-type)) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index f1fa460..0e30bd8 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -4,51 +4,95 @@ [commiteth.common :refer [human-time display-data-page items-per-page - issue-url]] + issue-url + pull-request-url]] [commiteth.handlers :as handlers] [commiteth.db :as db] [commiteth.ui-model :as ui-model] [commiteth.subscriptions :as subs] [commiteth.util :as util])) +(defn display-bounty-claims [claims] + [:div.bounty-claims-container.pv3 + (for [claim claims] + (let [{:keys [avatar-url + pr-title + pr-id + updated + repo-owner + repo-name + pr-number]} claim] + ^{:key pr-id} + [:div.bounty-claims-row.open-bounty-item-content.flex + [:div.bounty-claims-icon.pl2 + [:div.ui.tiny.circular.image + [:img {:src avatar-url}]]] + [:span.bounty-claims-text.pt2.pl2 + [:a.fw5 + {:href (pull-request-url repo-owner repo-name pr-number)} + (if pr-title + pr-title + (str "#" pr-number " by " repo-owner " in " repo-name))] + [:span.time.pl2 (human-time updated)]]]))]) + +(defn blue-arrow-box [image-src] + "generates the appropriate container for a blue arrow" + [:span.blue-arrow-box.pa1 + [:img.blue-arrow-image.v-mid {:src image-src}]]) (defn bounty-item [bounty] - (let [{avatar-url :repo_owner_avatar_url - owner :repo-owner - repo-name :repo-name - issue-title :issue-title - issue-number :issue-number - updated :updated - tokens :tokens - balance-eth :balance-eth - value-usd :value-usd - claim-count :claim-count} bounty - full-repo (str owner "/" repo-name) - repo-url (str "https://github.com/" full-repo) - repo-link [:a {:href repo-url} full-repo] - issue-link [:a - {:href (issue-url owner repo-name issue-number)} - issue-title]] - [:div.open-bounty-item - [:div.open-bounty-item-content - [:div.header issue-link] - [:div.bounty-item-row - [:div.time (human-time updated)] - [:span.bounty-repo-label repo-link]] - - [:div.footer-row - [:div.balance-badge "ETH " balance-eth] - (for [[tla balance] tokens] - ^{:key (random-uuid)} - [:div.balance-badge.token - (str (subs (str tla) 1) " " balance)]) - [:span.usd-value-label "Value "] [:span.usd-balance-label (str "$" value-usd)] - (when (> claim-count 0) - [:span.open-claims-label (str claim-count " open claim" - (when (> claim-count 1) "s"))])]] - [:div.open-bounty-item-icon - [:div.ui.tiny.circular.image - [:img {:src avatar-url}]]]])) + (let [open-bounty-claims (rf/subscribe [::subs/open-bounty-claims])] + (fn [bounty] + (let [{avatar-url :repo_owner_avatar_url + owner :repo-owner + repo-name :repo-name + issue-title :issue-title + issue-number :issue-number + issue-id :issue-id + updated :updated + tokens :tokens + balance-eth :balance-eth + value-usd :value-usd + claim-count :claim-count + claims :claims} bounty + full-repo (str owner "/" repo-name) + repo-url (str "https://github.com/" full-repo) + repo-link [:a {:href repo-url} full-repo] + issue-link [:a + {:href (issue-url owner repo-name issue-number)} + issue-title] + open-claims-click #(rf/dispatch [::handlers/open-bounty-claim issue-id]) + close-claims-click #(rf/dispatch [::handlers/close-bounty-claim issue-id]) + matches-current-issue? (some #{issue-id} @open-bounty-claims)] + [:div + [:div.open-bounty-item + [:div.open-bounty-item-content + [:div.header issue-link] + [:div.bounty-item-row + [:div.time (human-time updated)] + [:span.bounty-repo-label repo-link]] + [:div.footer-row + [:div.balance-badge "ETH " balance-eth] + (for [[tla balance] tokens] + ^{:key (random-uuid)} + [:div.balance-badge.token + (str (subs (str tla) 1) " " balance)]) + [:span.usd-value-label "Value "] [:span.usd-balance-label (str "$" value-usd)] + (when (> claim-count 0) + [:span.open-claims-label + {:on-click (if matches-current-issue? + #(close-claims-click) + #(open-claims-click))} + (str claim-count " open claim" + (when (> claim-count 1) "s")) + (if matches-current-issue? + [blue-arrow-box "blue-arrow-up.png"] + [blue-arrow-box "blue-arrow-down.png"])])]] + [:div.open-bounty-item-icon + [:div.ui.tiny.circular.image + [:img {:src avatar-url}]]]] + (when matches-current-issue? + [display-bounty-claims claims])])))) (defn bounties-filter-tooltip-value-input-view [label tooltip-open? opts] [:div.open-bounties-filter-element-tooltip-value-input-container diff --git a/src/cljs/commiteth/common.cljs b/src/cljs/commiteth/common.cljs index 7b87894..4eec7c9 100644 --- a/src/cljs/commiteth/common.cljs +++ b/src/cljs/commiteth/common.cljs @@ -48,6 +48,9 @@ (defn issue-url [owner repo number] (str "https://github.com/" owner "/" repo "/issues/" number)) +(defn pull-request-url [owner repo number] + (str "https://github.com/" owner "/" repo "/pull/" number)) + (def items-per-page 15) (defn draw-page-numbers [page-number page-count container-element] diff --git a/src/cljs/commiteth/db.cljs b/src/cljs/commiteth/db.cljs index c92b2a1..295969f 100644 --- a/src/cljs/commiteth/db.cljs +++ b/src/cljs/commiteth/db.cljs @@ -4,7 +4,7 @@ (def default-db {:page :bounties :user nil - :user-profile-loaded? false + :user-profile-loaded? false :repos-loading? false :repos {} :activity-feed-loading? false @@ -18,6 +18,7 @@ ::ui-model/bounty-filter-type|currency nil ::ui-model/bounty-filter-type|date nil ::ui-model/bounty-filter-type|owner nil} + ::open-bounty-claims #{} :owner-bounties {} :top-hunters [] :activity-feed []}) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index 61447c1..e5579fa 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -484,6 +484,16 @@ (.removeEventListener js/window "click" close-dropdown) (assoc db :user-dropdown-open? false))) +(reg-event-db + ::open-bounty-claim + (fn [db [_ opening-issue-id]] + (update db ::db/open-bounty-claims #(conj % opening-issue-id)))) + +(reg-event-db + ::close-bounty-claim + (fn [db [_ closing-issue-id]] + (update db ::db/open-bounty-claims #(disj % closing-issue-id)))) + (reg-event-db ::set-open-bounties-sorting-type (fn [db [_ sorting-type]] diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 3ecd6e2..24ffbb7 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -53,17 +53,24 @@ :open-bounties-page :<- [::filtered-and-sorted-open-bounties] :<- [:page-number] - (fn [[open-bounties page-number] _] + :<- [:activity-feed] + (fn [[open-bounties page-number activity-feed] _] (let [total-count (count open-bounties) - start (* (dec page-number) items-per-page) - end (min total-count (+ items-per-page start)) - items (subvec open-bounties start end)] - {:items items - :item-count (count items) + start (* (dec page-number) items-per-page) + end (min total-count (+ items-per-page start)) + items (->> (subvec open-bounties start end) + (map (fn [bounty] + (let [matching-claims (filter + (fn [claim] + (= (:issue-number claim) + (:issue-number bounty))) + activity-feed)] + (assoc bounty :claims matching-claims)))))] + {:items items + :item-count (count items) :total-count total-count :page-number page-number - :page-count (Math/ceil (/ total-count items-per-page))}))) - + :page-count (Math/ceil (/ total-count items-per-page))}))) (reg-sub :owner-bounties @@ -146,6 +153,11 @@ (fn [db _] (:user-dropdown-open? db))) +(reg-sub + ::open-bounty-claims + (fn [db _] + (::db/open-bounty-claims db))) + (reg-sub ::open-bounties-sorting-type (fn [db _] diff --git a/src/less/style.less b/src/less/style.less index 0c3d7c7..714fb7a 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -714,6 +714,17 @@ label[for="input-hidden"] { padding: 4px; text-align: center; } + + .blue-arrow-box { + width: 24px; + height: 24px; + } + + .blue-arrow-image { + width: 13.5px; + height: 6px; + } + } .open-bounty-item:first-child { @@ -748,8 +759,6 @@ label[for="input-hidden"] { font-size: 15px; } - border-bottom: #eaecee 1px solid !important; - .open-bounty-item-content { width: 80%; padding: .7em 0 1em; @@ -780,8 +789,28 @@ label[for="input-hidden"] { flex-direction: row !important; justify-content: space-between; width: 80%; - } + +.bounty-claims-row { + padding-top: 6px; + padding-bottom: 6px; +} + +.bounty-claims-container { + background-color: #FBFBFB; +} + +.bounty-claims-icon { + width: 40px; + } + +.bounty-claims-text { + a { + text-decoration: none; + color: #42505c; + } +} + .bounty-repo-label a { margin: auto; font-family: "PostGrotesk-Book"; @@ -804,6 +833,7 @@ label[for="input-hidden"] { padding-left: 15px; font-size: 15px; color: #57a7ed; + cursor: pointer; } .activity-item-container { From 61e8d2188fbb8debcc55336e4df41180c120acf5 Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Thu, 12 Apr 2018 15:07:51 -0400 Subject: [PATCH 20/35] use issue-id instead of issue-number throughout PR, not just for app-db --- ... 20180412143511-update-activity-feed-with-claims.down.sql} | 0 ...=> 20180412143511-update-activity-feed-with-claims.up.sql} | 4 ++++ resources/sql/queries.sql | 1 + src/cljs/commiteth/subscriptions.cljs | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) rename resources/migrations/{20180330143004-pr-data-activity-feed.down.sql => 20180412143511-update-activity-feed-with-claims.down.sql} (100%) rename resources/migrations/{20180330143004-pr-data-activity-feed.up.sql => 20180412143511-update-activity-feed-with-claims.up.sql} (94%) diff --git a/resources/migrations/20180330143004-pr-data-activity-feed.down.sql b/resources/migrations/20180412143511-update-activity-feed-with-claims.down.sql similarity index 100% rename from resources/migrations/20180330143004-pr-data-activity-feed.down.sql rename to resources/migrations/20180412143511-update-activity-feed-with-claims.down.sql diff --git a/resources/migrations/20180330143004-pr-data-activity-feed.up.sql b/resources/migrations/20180412143511-update-activity-feed-with-claims.up.sql similarity index 94% rename from resources/migrations/20180330143004-pr-data-activity-feed.up.sql rename to resources/migrations/20180412143511-update-activity-feed-with-claims.up.sql index 38a0cf8..34cdf7c 100644 --- a/resources/migrations/20180330143004-pr-data-activity-feed.up.sql +++ b/resources/migrations/20180412143511-update-activity-feed-with-claims.up.sql @@ -7,6 +7,7 @@ CREATE VIEW "public"."claims_view" AS SELECT i.title AS issue_title, p.title AS pr_title, -- added p.pr_number AS pr_number, -- added p.pr_id AS pr_id, -- added + i.issue_id AS issue_id, -- added COALESCE(u.name, u.login) AS user_name, u.avatar_url AS user_avatar_url, i.payout_receipt, @@ -39,6 +40,7 @@ CREATE VIEW "public"."activity_feed_view" AS -- altered claims_view.pr_number, -- added claims_view.pr_id, -- added claims_view.issue_number, + claims_view.issue_id, -- added claims_view.user_name, claims_view.user_avatar_url, claims_view.balance_eth, @@ -59,6 +61,7 @@ UNION claims_view.pr_number, -- added claims_view.pr_id, -- added claims_view.issue_number, + claims_view.issue_id, -- added claims_view.user_name, claims_view.user_avatar_url, claims_view.balance_eth, @@ -78,6 +81,7 @@ UNION claims_view.pr_number, -- added claims_view.pr_id, -- added claims_view.issue_number, + claims_view.issue_id, -- added claims_view.user_name, claims_view.user_avatar_url, claims_view.balance_eth, diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index ef40b5f..75d73e4 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -599,6 +599,7 @@ SELECT pr_title, pr_id, issue_number, + issue_id, user_name, user_avatar_url, balance_eth, diff --git a/src/cljs/commiteth/subscriptions.cljs b/src/cljs/commiteth/subscriptions.cljs index 24ffbb7..c6aaf57 100644 --- a/src/cljs/commiteth/subscriptions.cljs +++ b/src/cljs/commiteth/subscriptions.cljs @@ -62,8 +62,8 @@ (map (fn [bounty] (let [matching-claims (filter (fn [claim] - (= (:issue-number claim) - (:issue-number bounty))) + (= (:issue-id claim) + (:issue-id bounty))) activity-feed)] (assoc bounty :claims matching-claims)))))] {:items items From 24e39ad8679eb4472a5b796b6eeb266b02f47cec Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Fri, 13 Apr 2018 16:47:24 +0300 Subject: [PATCH 21/35] Throw exception if attempting to create tx with the same nonce --- src/clj/commiteth/bounties.clj | 5 +++-- src/clj/commiteth/eth/core.clj | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index 2be8511..d1ee19d 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -23,7 +23,7 @@ (defn deploy-contract [owner owner-address repo issue-id issue-number] (if (empty? owner-address) (log/errorf "issue %s: Unable to deploy bounty contract because repo owner has no Ethereum addres" issue-id) - (do + (try (log/infof "issue %s: Deploying contract to %s" issue-id owner-address) (if-let [transaction-hash (multisig/deploy-multisig owner-address)] (do @@ -36,7 +36,8 @@ (log/infof "issue %s: post-deploying-comment response: %s" issue-id resp) (issues/update-comment-id issue-id comment-id)) (issues/update-transaction-hash issue-id transaction-hash)) - (log/errorf "issue %s Failed to deploy contract to %s" issue-id owner-address))))) + (log/errorf "issue %s Failed to deploy contract to %s" issue-id owner-address)) + (catch Exception ex (log/errorf ex "issue %s: deploy-contract exception" issue-id))))) (defn add-bounty-for-issue [repo repo-id issue] (let [{issue-id :id diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index f70374d..4250153 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -53,18 +53,27 @@ (throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn" {:password password :file-path file-path})))))) +(defn get-nonce [] + (let [current-nonce (atom nil)] + (fn [] + (let [nonce (.. (.ethGetTransactionCount (create-web3j) + (env :eth-account) + DefaultBlockParameterName/LATEST) + sendAsync + get + getTransactionCount)] + (if (= nonce @current-nonce) + (throw (Exception. (str "Attempting to create transaction with the same nonce: " nonce))) + (swap! current-nonce (constantly nonce))) + (log/info "Current nonce:" nonce) + nonce)))) + (defn get-signed-tx [gas-price gas-limit to data] "Create a sign a raw transaction. 'From' argument is not needed as it's already encoded in credentials. See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" - (let [web3j (create-web3j) - nonce (.. (.ethGetTransactionCount web3j - (env :eth-account) - DefaultBlockParameterName/LATEST) - sendAsync - get - getTransactionCount) + (let [nonce ((get-nonce)) tx (RawTransaction/createTransaction nonce gas-price From 05d93a18938f5fa50b57390e375fd3a92409c744 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Fri, 13 Apr 2018 17:03:22 +0300 Subject: [PATCH 22/35] Remove superfluous logging statement --- src/clj/commiteth/eth/core.clj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 4250153..2f6bfe5 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -65,7 +65,6 @@ (if (= nonce @current-nonce) (throw (Exception. (str "Attempting to create transaction with the same nonce: " nonce))) (swap! current-nonce (constantly nonce))) - (log/info "Current nonce:" nonce) nonce)))) (defn get-signed-tx [gas-price gas-limit to data] From 1a50f9f607bf3a3c2f289105a2b8d18d1188d59e Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Mon, 16 Apr 2018 11:58:18 +0300 Subject: [PATCH 23/35] Fix lame mistake with get-nonce closure invocation --- src/clj/commiteth/eth/core.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 2f6bfe5..c85df48 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -66,13 +66,14 @@ (throw (Exception. (str "Attempting to create transaction with the same nonce: " nonce))) (swap! current-nonce (constantly nonce))) nonce)))) +(def get-nonce-fn (get-nonce)) (defn get-signed-tx [gas-price gas-limit to data] "Create a sign a raw transaction. 'From' argument is not needed as it's already encoded in credentials. See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" - (let [nonce ((get-nonce)) + (let [nonce (get-nonce-fn) tx (RawTransaction/createTransaction nonce gas-price From 614fdf9d0324884bb6440fda0784c73856151960 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 16 Apr 2018 11:48:16 +0200 Subject: [PATCH 24/35] fix #399: track each internal transaction and associated nonce --- src/clj/commiteth/bounties.clj | 3 +- src/clj/commiteth/eth/core.clj | 88 +++++++++++++---------- src/clj/commiteth/eth/multisig_wallet.clj | 67 ++++++++--------- src/clj/commiteth/eth/token_registry.clj | 18 +++-- src/clj/commiteth/scheduler.clj | 4 +- 5 files changed, 91 insertions(+), 89 deletions(-) diff --git a/src/clj/commiteth/bounties.clj b/src/clj/commiteth/bounties.clj index d1ee19d..a2c93c6 100644 --- a/src/clj/commiteth/bounties.clj +++ b/src/clj/commiteth/bounties.clj @@ -25,7 +25,8 @@ (log/errorf "issue %s: Unable to deploy bounty contract because repo owner has no Ethereum addres" issue-id) (try (log/infof "issue %s: Deploying contract to %s" issue-id owner-address) - (if-let [transaction-hash (multisig/deploy-multisig owner-address)] + (if-let [transaction-hash (multisig/deploy-multisig {:owner owner-address + :internal-tx-id (str "contract-github-issue-" issue-id)})] (do (log/infof "issue %s: Contract deployed, transaction-hash: %s" issue-id transaction-hash) (let [resp (github/post-deploying-comment owner diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index c85df48..ae9a585 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -28,7 +28,9 @@ (defn auto-gas-price? [] (env :auto-gas-price false)) (defn offline-signing? [] (env :offline-signing true)) -(def web3j-obj (atom nil)) +(def web3j-obj + (delay (Web3j/build (HttpService. (eth-rpc-url))))) + (def creds-obj (atom nil)) (defn wallet-file-path [] @@ -37,10 +39,6 @@ (defn wallet-password [] (env :eth-password)) -(defn create-web3j [] - (or @web3j-obj - (swap! web3j-obj (constantly (Web3j/build (HttpService. (eth-rpc-url))))))) - (defn creds [] (or @creds-obj (let [password (wallet-password) @@ -53,37 +51,48 @@ (throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn" {:password password :file-path file-path})))))) -(defn get-nonce [] - (let [current-nonce (atom nil)] - (fn [] - (let [nonce (.. (.ethGetTransactionCount (create-web3j) - (env :eth-account) - DefaultBlockParameterName/LATEST) - sendAsync - get - getTransactionCount)] - (if (= nonce @current-nonce) - (throw (Exception. (str "Attempting to create transaction with the same nonce: " nonce))) - (swap! current-nonce (constantly nonce))) - nonce)))) -(def get-nonce-fn (get-nonce)) +(defprotocol INonceTracker + "The reason we need this is that we might send mutliple identical + transactions (e.g. bounty contract deploy with same owner) shortly + after another. In this case web3j's TX counting only increases once + a transaction has been confirmed and so we send multiple identical + transactions with the same nonce." + (get-nonce [this internal-tx-id] + "Return the to be used nonce for an OpenBounty Ethereum + transaction identified by `internal-tx-id`. As these IDs are stable + we can use them to use consistent nonces for the same transaction.")) -(defn get-signed-tx [gas-price gas-limit to data] - "Create a sign a raw transaction. - 'From' argument is not needed as it's already - encoded in credentials. +(defrecord NonceTracker [state] + INonceTracker + (get-nonce [this internal-tx-id] + (or (get @state internal-tx-id) + (let [nonces (set (vals @state)) + web3j-tx-count (.. (.ethGetTransactionCount + @web3j-obj + (env :eth-account) + DefaultBlockParameterName/LATEST) + sendAsync + get + getTransactionCount)] + ;; TODO this is a memory leak since tracking state is never pruned + ;; Since we're not doing 1000s of transactions every day yet we can + ;; probably defer worrying about this until a bit later + (if (contains? nonces web3j-tx-count) + (swap! state assoc internal-tx-id (inc (max nonces))) + (swap! state assoc internal-tx-id web3j-tx-count)))))) + +(def nonce-tracker + (->NonceTracker (atom {}))) + +(defn get-signed-tx [{:keys [gas-price gas-limit to data internal-tx-id]}] + "Create a sign a raw transaction. 'From' argument is not needed as it's already encoded in credentials. See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" - (let [nonce (get-nonce-fn) - tx (RawTransaction/createTransaction - nonce - gas-price - gas-limit - to - data) + (let [nonce (get-nonce nonce-tracker internal-tx-id) + tx (RawTransaction/createTransaction nonce gas-price gas-limit to data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] - (log/infof "Signing TX: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" - nonce gas-price gas-limit data) + (log/infof "Signing TX %s: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" + internal-tx-id nonce gas-price gas-limit data) hex-string)) (defn eth-gasstation-gas-price @@ -253,7 +262,8 @@ (eth-rpc "eth_call" [{:to contract :data data} "latest"]))) (defn execute - [from contract method-id gas-limit & params] + [{:keys [from contract method-id gas-limit params internal-tx-id]}] + {:pre [(string? method-id)]} (let [data (apply format-call-params method-id params) gas-price (gas-price) value (format "0x%x" 0) @@ -264,13 +274,13 @@ (merge {:gasPrice (integer->hex gas-price)}) contract (merge {:to contract})) - gas (if gas-limit gas-limit - (estimate-gas from contract value params)) + gas (or gas-limit (estimate-gas from contract value params)) params (if (offline-signing?) - (get-signed-tx (biginteger gas-price) - (hex->big-integer gas) - contract - data) + (get-signed-tx {:internal-tx-id internal-tx-id + :gas-price (biginteger gas-price) + :gas-limit (hex->big-integer gas) + :to contract + :data data}) (assoc params :gas gas))] (if (offline-signing?) (eth-rpc diff --git a/src/clj/commiteth/eth/multisig_wallet.clj b/src/clj/commiteth/eth/multisig_wallet.clj index 941b0ca..a7cc7df 100644 --- a/src/clj/commiteth/eth/multisig_wallet.clj +++ b/src/clj/commiteth/eth/multisig_wallet.clj @@ -1,6 +1,5 @@ (ns commiteth.eth.multisig-wallet - (:require [commiteth.eth.core :as eth - :refer [create-web3j creds]] + (:require [commiteth.eth.core :as eth] [commiteth.config :refer [env]] [clojure.tools.logging :as log] [taoensso.tufte :as tufte :refer (defnp p profiled profile)] @@ -36,24 +35,19 @@ [] (env :tokenreg-base-format :status)) -(defn create-new - [owner1 owner2 required] - (eth/execute (eth/eth-account) - (factory-contract-addr) - (:create method-ids) - (eth/integer->hex 865000) ;; gas-limit - 0x40 - 0x2 - required - owner1 - owner2)) - - (defn deploy-multisig "Deploy a new multisig contract to the blockchain with commiteth bot - and given owner as owners." - [owner] - (create-new (eth/eth-account) owner 2)) + and given owner as owners. + `internal-tx-id` is used to identify what issue this multisig is deployed + for and manage nonces at a later point in time." + [{:keys [owner internal-tx-id]}] + {:pre [(string? owner) (string? internal-tx-id)]} + (eth/execute {:internal-tx-id internal-tx-id + :from (eth/eth-account) + :contract (factory-contract-addr) + :method-id (:create method-ids) + :gas-limit (eth/integer->hex 865000) + :params [0x40 0x2 2 (eth/eth-account) owner]})) (defn find-event-in-tx-receipt [tx-receipt topic-id] (let [logs (:logs tx-receipt) @@ -92,20 +86,18 @@ (defn send-all - [contract to] - (log/debug "multisig/send-all " contract to) + [{:keys [contract payout-address internal-tx-id]}] + {:pre [(string? contract) (string? payout-address) (string? internal-tx-id)]} + (log/debug "multisig/send-all " contract payout-address internal-tx-id) (let [params (eth/format-call-params (:withdraw-everything method-ids) - to)] - (eth/execute (eth/eth-account) - contract - (:submit-transaction method-ids) - nil - contract - 0 - "0x60" ;; TODO: document these - "0x24" ;; or refactor out - params))) + payout-address)] + (eth/execute {:internal-tx-id internal-tx-id + :from (eth/eth-account) + :contract contract + :method-id (:submit-transaction method-ids) + :gas-limit nil + :params [contract 0 "0x60" "0x24" params]}))) (defn get-token-address [token] @@ -118,17 +110,16 @@ (log/debug "multisig/watch-token" bounty-addr token) (let [token-address (get-token-address token)] (assert token-address) - (eth/execute (eth/eth-account) - bounty-addr - (:watch method-ids) - nil - token-address))) - + (eth/execute {:from (eth/eth-account) + :contract bounty-addr + :method-id (:watch method-ids) + :gas-limit nil + :params [token-address]}))) (defn load-bounty-contract [addr] (MultiSigTokenWallet/load addr - (create-web3j) - (creds) + @eth/web3j-obj + (eth/creds) (eth/gas-price) (BigInteger/valueOf 500000))) diff --git a/src/clj/commiteth/eth/token_registry.clj b/src/clj/commiteth/eth/token_registry.clj index 4d1ddea..c7aeec7 100644 --- a/src/clj/commiteth/eth/token_registry.clj +++ b/src/clj/commiteth/eth/token_registry.clj @@ -1,6 +1,5 @@ (ns commiteth.eth.token-registry - (:require [commiteth.eth.core :as eth - :refer [create-web3j creds]] + (:require [commiteth.eth.core :as eth] [commiteth.config :refer [env]] [clojure.tools.logging :as log]) (:import [org.web3j @@ -23,8 +22,8 @@ (defn- load-tokenreg-contract [addr] (TokenReg/load addr - (create-web3j) - (creds) + @eth/web3j-obj + (eth/creds) (eth/gas-price) (BigInteger/valueOf 21000))) @@ -59,9 +58,8 @@ (defn deploy-parity-tokenreg "Deploy an instance of parity token-registry to current network" [] - (let [web3j (create-web3j)] - (TokenReg/deploy web3j - (creds) - (eth/gas-price) - (BigInteger/valueOf 4000000) ;; gas limit - BigInteger/ZERO))) + (TokenReg/deploy @eth/web3j-obj + (eth/creds) + (eth/gas-price) + (BigInteger/valueOf 4000000) ;; gas limit + BigInteger/ZERO)) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 1be116c..4299c49 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -126,7 +126,9 @@ tokens winner-login true)) - (let [execute-hash (multisig/send-all contract-address payout-address)] + (let [execute-hash (multisig/send-all {:contract contract-address + :payout-address payout-address + :internal-tx-id (str "payout-github-issue-" issue-id)})] (log/infof "issue %s: Payout self-signed, called sign-all(%s) tx: %s" issue-id contract-address payout-address execute-hash) (db-bounties/update-execute-hash issue-id execute-hash) (db-bounties/update-winner-login issue-id winner-login) From a78c1cff66ec3a5ccb26fe1b374890f9ad107695 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 16 Apr 2018 13:17:41 +0200 Subject: [PATCH 25/35] set internal-tx-id for watch-token call --- src/clj/commiteth/eth/multisig_wallet.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clj/commiteth/eth/multisig_wallet.clj b/src/clj/commiteth/eth/multisig_wallet.clj index a7cc7df..874c113 100644 --- a/src/clj/commiteth/eth/multisig_wallet.clj +++ b/src/clj/commiteth/eth/multisig_wallet.clj @@ -110,7 +110,8 @@ (log/debug "multisig/watch-token" bounty-addr token) (let [token-address (get-token-address token)] (assert token-address) - (eth/execute {:from (eth/eth-account) + (eth/execute {:internal-tx-id (str "watch-token-" (System/currentTimeMillis) "-" bounty-addr) + :from (eth/eth-account) :contract bounty-addr :method-id (:watch method-ids) :gas-limit nil From 70e91932e99296def5a8e47811297639ea595c30 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 16 Apr 2018 13:58:24 +0200 Subject: [PATCH 26/35] remove stale swap! call --- src/clj/commiteth/eth/core.clj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index ae9a585..92e66df 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -349,7 +349,6 @@ eth-core :start (do - (swap! web3j-obj (constantly nil)) (swap! creds-obj (constantly nil)) (log/info "eth/core started")) :stop From 09cd9ec49ac408049f32cb4fb20d40ee89d21f08 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 16 Apr 2018 14:58:18 +0200 Subject: [PATCH 27/35] fix bug --- src/clj/commiteth/eth/core.clj | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 92e66df..3156543 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -73,13 +73,15 @@ DefaultBlockParameterName/LATEST) sendAsync get - getTransactionCount)] + getTransactionCount) + nonce (if (contains? nonces web3j-tx-count) + (inc (max nonces)) + web3j-tx-count)] ;; TODO this is a memory leak since tracking state is never pruned ;; Since we're not doing 1000s of transactions every day yet we can ;; probably defer worrying about this until a bit later - (if (contains? nonces web3j-tx-count) - (swap! state assoc internal-tx-id (inc (max nonces))) - (swap! state assoc internal-tx-id web3j-tx-count)))))) + (swap! state assoc internal-tx-id nonce) + nonce)))) (def nonce-tracker (->NonceTracker (atom {}))) From 82c2b6be476d4c1536fabf7576ed2731d9a72d89 Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Wed, 11 Apr 2018 14:02:13 -0400 Subject: [PATCH 28/35] update-repo-state should call db/update-repo-state --- src/clj/commiteth/db/repositories.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/commiteth/db/repositories.clj b/src/clj/commiteth/db/repositories.clj index eb06b38..9e82b7b 100644 --- a/src/clj/commiteth/db/repositories.clj +++ b/src/clj/commiteth/db/repositories.clj @@ -34,7 +34,7 @@ (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 + (db/update-repo-state con-db {:repo_id repo-id :repo_state repo-state}))) (defn get-repo "Get a repo from DB given it's full name (owner/repo-name)" From c7b2f12c4fd01f236ab64e0066b35220497fc762 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 17 Apr 2018 17:58:04 +0200 Subject: [PATCH 29/35] fix outstanding issues with NonceTracker --- src/clj/commiteth/eth/core.clj | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 3156543..a5a8f48 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -56,7 +56,13 @@ transactions (e.g. bounty contract deploy with same owner) shortly after another. In this case web3j's TX counting only increases once a transaction has been confirmed and so we send multiple identical - transactions with the same nonce." + transactions with the same nonce. + + Web3j also provides a TransactionManager that increases nonces but it + does not track nonces related to transactions and so as far as I understand + it might cause transactions to be executed twice if they are retried. + + https://github.com/web3j/web3j/blob/d19855475aa6620a7e93523bd9ede26ca50ed042/core/src/main/java/org/web3j/tx/RawTransactionManager.java" (get-nonce [this internal-tx-id] "Return the to be used nonce for an OpenBounty Ethereum transaction identified by `internal-tx-id`. As these IDs are stable @@ -75,7 +81,7 @@ get getTransactionCount) nonce (if (contains? nonces web3j-tx-count) - (inc (max nonces)) + (inc (apply max nonces)) web3j-tx-count)] ;; TODO this is a memory leak since tracking state is never pruned ;; Since we're not doing 1000s of transactions every day yet we can @@ -90,7 +96,7 @@ "Create a sign a raw transaction. 'From' argument is not needed as it's already encoded in credentials. See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" (let [nonce (get-nonce nonce-tracker internal-tx-id) - tx (RawTransaction/createTransaction nonce gas-price gas-limit to data) + tx (RawTransaction/createTransaction (biginteger nonce) gas-price gas-limit to data) signed (TransactionEncoder/signMessage tx (creds)) hex-string (Numeric/toHexString signed)] (log/infof "Signing TX %s: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" From 0d7ac5637d9588cda6ebedde08fa7a384272ea22 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 17 Apr 2018 21:59:16 +0200 Subject: [PATCH 30/35] always increase nonce, but log for diagnostics --- src/clj/commiteth/eth/core.clj | 83 +++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index a5a8f48..fc634bf 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -51,6 +51,12 @@ (throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn" {:password password :file-path file-path})))))) +(defn get-web3j-nonce [web3j-instance] + (.. (.ethGetTransactionCount web3j-instance (env :eth-account) DefaultBlockParameterName/LATEST) + sendAsync + get + getTransactionCount)) + (defprotocol INonceTracker "The reason we need this is that we might send mutliple identical transactions (e.g. bounty contract deploy with same owner) shortly @@ -71,23 +77,20 @@ (defrecord NonceTracker [state] INonceTracker (get-nonce [this internal-tx-id] - (or (get @state internal-tx-id) - (let [nonces (set (vals @state)) - web3j-tx-count (.. (.ethGetTransactionCount - @web3j-obj - (env :eth-account) - DefaultBlockParameterName/LATEST) - sendAsync - get - getTransactionCount) - nonce (if (contains? nonces web3j-tx-count) - (inc (apply max nonces)) - web3j-tx-count)] - ;; TODO this is a memory leak since tracking state is never pruned - ;; Since we're not doing 1000s of transactions every day yet we can - ;; probably defer worrying about this until a bit later - (swap! state assoc internal-tx-id nonce) - nonce)))) + (let [prev-nonce (get @state internal-tx-id) + web3j-nonce (get-web3j-nonce @web3j-obj) + nonces (set (vals @state)) + nonce (if (seq nonces) + (inc (apply max nonces)) + web3j-nonce)] + (when prev-nonce + (log/warnf "%s: tx will be retried (prev-nonce: %s, new-nonce: %s, web3j-nonce: %s)" + internal-tx-id prev-nonce nonce web3j-nonce)) + ;; TODO this is a memory leak since tracking state is never pruned + ;; Since we're not doing 1000s of transactions every day yet we can + ;; probably defer worrying about this until a bit later + (swap! state assoc internal-tx-id nonce) + nonce))) (def nonce-tracker (->NonceTracker (atom {}))) @@ -95,13 +98,12 @@ (defn get-signed-tx [{:keys [gas-price gas-limit to data internal-tx-id]}] "Create a sign a raw transaction. 'From' argument is not needed as it's already encoded in credentials. See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" - (let [nonce (get-nonce nonce-tracker internal-tx-id) - tx (RawTransaction/createTransaction (biginteger nonce) gas-price gas-limit to data) - signed (TransactionEncoder/signMessage tx (creds)) - hex-string (Numeric/toHexString signed)] - (log/infof "Signing TX %s: nonce: %s, gas-price: %s, gas-limit: %s, data: %s" - internal-tx-id nonce gas-price gas-limit data) - hex-string)) + (let [nonce (get-nonce nonce-tracker internal-tx-id)] + (log/infof "%s: Signing nonce: %s, gas-price: %s, gas-limit: %s" + internal-tx-id nonce gas-price gas-limit) + (-> (RawTransaction/createTransaction (biginteger nonce) gas-price gas-limit to data) + (TransactionEncoder/signMessage (creds)) + (Numeric/toHexString)))) (defn eth-gasstation-gas-price "Get max of average and average_calc from gas station and use that @@ -156,7 +158,8 @@ (atom 0)) (defn eth-rpc - [method params] + [{:keys [method params internal-tx-id]}] + {:pre [(string? method) (some? params)]} (let [request-id (swap! req-id-tracker inc) body {:jsonrpc "2.0" :method method @@ -166,9 +169,9 @@ :body (json/write-str body)} response @(post (eth-rpc-url) options) result (safe-read-str (:body response))] - (log/infof "eth-rpc req(%s) body: %s\neth-rpc req(%s) result: %s" - request-id body request-id result) - + (log/infof "%s: eth-rpc %s" (or internal-tx-id "(no-tx-id)") method) + (log/debugf "eth-rpc req(%s) body: %s\neth-rpc req(%s) result: %s" + request-id body request-id result) (cond ;; Ignore any responses that have mismatching request ID (not= (:id result) request-id) @@ -176,7 +179,10 @@ ;; If request ID matches but contains error, throw (:error result) - (throw (ex-info "Error submitting transaction via eth-rpc" (:error result))) + (throw + (ex-info (format "%s: Error submitting transaction via eth-rpc %s" + (or internal-tx-id "(no-tx-id)") (:error result)) + (:error result))) :else (:result result)))) @@ -238,7 +244,8 @@ (defn get-balance-hex [account] - (eth-rpc "eth_getBalance" [account "latest"])) + (eth-rpc {:method "eth_getBalance" + :params [account "latest"]})) (defn get-balance-wei [account] @@ -257,7 +264,8 @@ (defn get-transaction-receipt [hash] - (eth-rpc "eth_getTransactionReceipt" [hash])) + (eth-rpc {:method "eth_getTransactionReceipt" + :params [hash]})) (defn format-call-params [method-id & params] @@ -267,7 +275,8 @@ (defn call [contract method-id & params] (let [data (apply format-call-params method-id params)] - (eth-rpc "eth_call" [{:to contract :data data} "latest"]))) + (eth-rpc {:method "eth_call" + :params [{:to contract :data data} "latest"]}))) (defn execute [{:keys [from contract method-id gas-limit params internal-tx-id]}] @@ -292,11 +301,13 @@ (assoc params :gas gas))] (if (offline-signing?) (eth-rpc - "eth_sendRawTransaction" - [params]) + {:method "eth_sendRawTransaction" + :params [params] + :internal-tx-id internal-tx-id}) (eth-rpc - "personal_sendTransaction" - [params (eth-password)])))) + {:method "personal_sendTransaction" + :params [params (eth-password)] + :internal-tx-id internal-tx-id})))) (defn hex-ch->num [ch] From 510ac9a709830a23fb17f3db38757f0e0a053e1f Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Tue, 17 Apr 2018 22:12:06 +0200 Subject: [PATCH 31/35] fix eth-rpc call --- src/clj/commiteth/eth/core.clj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index fc634bf..1ed524e 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -219,9 +219,10 @@ (defn estimate-gas [from to value & [params]] (let [geth-estimate (eth-rpc - "eth_estimateGas" [(merge params {:from from - :to to - :value value})]) + {:method "eth_estimateGas" + :params [(merge params {:from from + :to to + :value value})]}) adjusted-gas (adjust-gas-estimate geth-estimate)] (log/debug "estimated gas (geth):" geth-estimate) From 7d6ed779b84d00bb1a58302989db76ab36634713 Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Mon, 16 Apr 2018 11:00:20 -0400 Subject: [PATCH 32/35] fix padding for dropdown claims --- src/cljs/commiteth/bounties.cljs | 12 ++++++------ src/less/style.less | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index 0e30bd8..add2617 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -13,7 +13,7 @@ [commiteth.util :as util])) (defn display-bounty-claims [claims] - [:div.bounty-claims-container.pv3 + [:div.bounty-claims-container.ph4.pv3 (for [claim claims] (let [{:keys [avatar-url pr-title @@ -65,7 +65,7 @@ close-claims-click #(rf/dispatch [::handlers/close-bounty-claim issue-id]) matches-current-issue? (some #{issue-id} @open-bounty-claims)] [:div - [:div.open-bounty-item + [:div.open-bounty-item.ph4 [:div.open-bounty-item-content [:div.header issue-link] [:div.bounty-item-row @@ -254,7 +254,7 @@ [:div (let [left (inc (* (dec page-number) items-per-page)) right (dec (+ left item-count))] - [:div.item-counts-label-and-sorting-container + [:div.item-counts-label-and-sorting-container.ph4 [:div.item-counts-label [:span (str "Showing " left "-" right " of " total-count)]] [bounties-sort-view]]) @@ -269,9 +269,9 @@ [:div.view-loading-container [:div.ui.active.inverted.dimmer [:div.ui.text.loader.view-loading-label "Loading"]]] - [:div.ui.container.open-bounties-container + [:div.ui.container.open-bounties-container. {:ref #(reset! container-element %1)} - [:div.open-bounties-header "Bounties"] - [:div.open-bounties-filter-and-sort + [:div.open-bounties-header.ph4.pt4 "Bounties"] + [:div.open-bounties-filter-and-sort.ph4 [bounty-filters-view]] [bounties-list @bounty-page-data container-element]])))) diff --git a/src/less/style.less b/src/less/style.less index 714fb7a..46e4c0e 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -415,7 +415,6 @@ label[for="input-hidden"] { background-color: #fff; border-radius: 10px; transform: translateY(-45px); - padding: 24px; .open-bounties-header { font-family: "PostGrotesk-Medium"; font-size: 21px; From e17aa10114e8a32b149b4fab3f5f2b7019eb248f Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Mon, 16 Apr 2018 11:33:45 -0400 Subject: [PATCH 33/35] fix typo --- src/cljs/commiteth/bounties.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cljs/commiteth/bounties.cljs b/src/cljs/commiteth/bounties.cljs index add2617..bdcd41e 100644 --- a/src/cljs/commiteth/bounties.cljs +++ b/src/cljs/commiteth/bounties.cljs @@ -269,7 +269,7 @@ [:div.view-loading-container [:div.ui.active.inverted.dimmer [:div.ui.text.loader.view-loading-label "Loading"]]] - [:div.ui.container.open-bounties-container. + [:div.ui.container.open-bounties-container {:ref #(reset! container-element %1)} [:div.open-bounties-header.ph4.pt4 "Bounties"] [:div.open-bounties-filter-and-sort.ph4 From a70696f26b24d9335efed679264d338eecae5ae2 Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Tue, 17 Apr 2018 20:24:43 -0400 Subject: [PATCH 34/35] padding for nav container (pagination) --- src/cljs/commiteth/common.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cljs/commiteth/common.cljs b/src/cljs/commiteth/common.cljs index 4eec7c9..194e75e 100644 --- a/src/cljs/commiteth/common.cljs +++ b/src/cljs/commiteth/common.cljs @@ -135,7 +135,7 @@ :else [:div [draw-items] - [:div.page-nav-container + [:div.page-nav-container.ph4.pb4 [:div.page-direction-container [draw-rect :backward] [draw-rect :forward]] From 726a3309b717295974587a8150151491d307b4b9 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Wed, 18 Apr 2018 10:27:42 +0200 Subject: [PATCH 35/35] minor logging changes --- src/clj/commiteth/eth/core.clj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 1ed524e..93c9352 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -169,9 +169,10 @@ :body (json/write-str body)} response @(post (eth-rpc-url) options) result (safe-read-str (:body response))] - (log/infof "%s: eth-rpc %s" (or internal-tx-id "(no-tx-id)") method) - (log/debugf "eth-rpc req(%s) body: %s\neth-rpc req(%s) result: %s" - request-id body request-id result) + (when internal-tx-id + (log/infof "%s: eth-rpc %s" internal-tx-id method)) + (log/debugf "%s: eth-rpc req(%s) body: %s" internal-tx-id request-id body) + (log/debugf "%s: eth-rpc req(%s) result: %s" internal-tx-id request-id result) (cond ;; Ignore any responses that have mismatching request ID (not= (:id result) request-id)