From f171259ed40a77d63c7c12bb5f998c391306cd94 Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 09:32:46 +0300 Subject: [PATCH 1/6] Recover from bot account ETH balance running out Recover from situation where Commit ETH bot account's ETH balance runs out and gets replenished by re-deploying contracts that were not actually written to the blockchain. Fixes: #58 --- resources/sql/queries.sql | 3 ++- src/clj/commiteth/scheduler.clj | 28 ++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 0b5709b..ac95044 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -165,7 +165,8 @@ WHERE issue_id = :issue_id; -- :doc retrieves pending transaction ids SELECT issue_id, - transaction_hash + transaction_hash, + owner_address FROM issues WHERE contract_address IS NULL AND issues.transaction_hash IS NOT NULL; diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 3fbfb4b..175dafa 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -45,18 +45,33 @@ balance-str)))))) +(defn deploy-contract [owner-address issue-id] + (let [transaction-hash (eth/deploy-contract owner-address)] + (if (nil? transaction-hash) + (log/error "Failed to deploy contract to" owner-address) + (log/info "Contract deployed, transaction-hash:" + transaction-hash )) + (issues/update-transaction-hash issue-id transaction-hash))) + + +(defn redeploy-failed-contracts + "If the bot account runs out of gas, we end up with transaction-id in db, but with nothing written to blockchain. In this case we should try to re-deploy the contract." + [] + (doseq [{issue-id :issue_id + transaction-hash :transaction_hash + owner-address :owner_address} (issues/list-pending-deployments)] + (when (nil? (eth/get-transaction-receipt transaction-hash)) + (log/info "Detected nil transaction receipt for pending contract deployment for issue" issue-id ", re-deploying contract") + (deploy-contract owner-address issue-id)))) + + (defn deploy-pending-contracts "Under high-concurrency circumstances or in case geth is in defunct state, a bounty contract may not deploy successfully when the bounty label is addded to an issue. This function deploys such contracts." [] (doseq [{issue-id :issue_id owner-address :owner_address} (db-bounties/pending-contracts)] (log/debug "Trying to re-deploy failed bounty contract deployment, issue-id:" issue-id) - (let [transaction-hash (eth/deploy-contract owner-address)] - (if (nil? transaction-hash) - (log/error "Failed to deploy contract to" owner-address) - (log/info "Contract deployed, transaction-hash:" - transaction-hash )) - (issues/update-transaction-hash issue-id transaction-hash)))) + (deploy-contract owner-address issue-id))) (defn self-sign-bounty "Walks through all issues eligible for bounty payout and signs corresponding transaction" @@ -169,6 +184,7 @@ (defn run-periodic-tasks [time] (do (log/debug "run-periodic-tasks" time) + (redeploy-failed-contracts) (deploy-pending-contracts) (update-issue-contract-address) (update-confirm-hash) From c5cc94fd814d5e8f790d53ab40c8ecda26c0afaf Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 10:02:07 +0300 Subject: [PATCH 2/6] SQL fix --- resources/sql/queries.sql | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index ac95044..c79e555 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -164,12 +164,14 @@ WHERE issue_id = :issue_id; -- :name list-pending-deployments :? :* -- :doc retrieves pending transaction ids SELECT - issue_id, - transaction_hash, - owner_address -FROM issues -WHERE contract_address IS NULL -AND issues.transaction_hash IS NOT NULL; + i.issue_id as issue_id, + i.transaction_hash as transaction_hash, + u.address as owner_address +FROM issues i, users u, repositories r +WHERE r.user_id = u.id +AND i.repo_id = r.repo_id +AND i.contract_address IS NULL +AND i.transaction_hash IS NOT NULL; -- Pull Requests ------------------------------------------------------------------- From 728598729296b8048b00a38685342f3594950ab2 Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 10:44:45 +0300 Subject: [PATCH 3/6] Improve recovery mechanism Only consider un-mined contract deployments older than 1 hour as failed --- resources/sql/queries.sql | 15 +++++++++++++++ src/clj/commiteth/db/issues.clj | 6 ++++++ src/clj/commiteth/scheduler.clj | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index c79e555..2e5db73 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -173,6 +173,21 @@ AND i.repo_id = r.repo_id AND i.contract_address IS NULL AND i.transaction_hash IS NOT NULL; + +-- :name list-failed-deployments :? :* +-- :doc retrieves failed contract deployments +SELECT + i.issue_id as issue_id, + i.transaction_hash as transaction_hash, + u.address as owner_address +FROM issues i, users u, repositories r +WHERE r.user_id = u.id +AND i.repo_id = r.repo_id +AND i.contract_address IS NULL +AND i.transaction_hash IS NOT NULL +AND i.updated < now() at time zone 'UTC' < interval '1 hour'; + + -- Pull Requests ------------------------------------------------------------------- -- :name save-pull-request! :! :n diff --git a/src/clj/commiteth/db/issues.clj b/src/clj/commiteth/db/issues.clj index b9138ae..9a2b777 100644 --- a/src/clj/commiteth/db/issues.clj +++ b/src/clj/commiteth/db/issues.clj @@ -46,6 +46,12 @@ (jdbc/with-db-connection [con-db *db*] (db/list-pending-deployments con-db))) + +(defn list-failed-deployments + [] + (jdbc/with-db-connection [con-db *db*] + (db/list-failed-deployments con-db))) + (defn get-balance [contract-address] (jdbc/with-db-connection [con-db *db*] diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index 175dafa..d57003b 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -59,7 +59,7 @@ [] (doseq [{issue-id :issue_id transaction-hash :transaction_hash - owner-address :owner_address} (issues/list-pending-deployments)] + owner-address :owner_address} (issues/list-failed-deployments)] (when (nil? (eth/get-transaction-receipt transaction-hash)) (log/info "Detected nil transaction receipt for pending contract deployment for issue" issue-id ", re-deploying contract") (deploy-contract owner-address issue-id)))) From a4e4a80f31153ba7ea9cd0b9c1e8814ba2161d6a Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 11:27:48 +0300 Subject: [PATCH 4/6] SQL fix --- 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 2e5db73..e664709 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -185,7 +185,7 @@ WHERE r.user_id = u.id AND i.repo_id = r.repo_id AND i.contract_address IS NULL AND i.transaction_hash IS NOT NULL -AND i.updated < now() at time zone 'UTC' < interval '1 hour'; +AND i.updated < now() at time zone 'UTC' - interval '1 hour'; -- Pull Requests ------------------------------------------------------------------- From babca324606de66586da01814e7b4334801a8a7d Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 11:50:24 +0300 Subject: [PATCH 5/6] Disable re-deploying of failed contracts * do not try to automatically re-deploy failed bounty contracts --- src/clj/commiteth/scheduler.clj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index d57003b..b03d08b 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -184,7 +184,9 @@ (defn run-periodic-tasks [time] (do (log/debug "run-periodic-tasks" time) - (redeploy-failed-contracts) + ;; TODO: disabled for now. looks like it may cause extraneus + ;; contract deployments and costs + #_(redeploy-failed-contracts) (deploy-pending-contracts) (update-issue-contract-address) (update-confirm-hash) From 52eb4471fe7a1a45baa83496264dfbcfe012f4bc Mon Sep 17 00:00:00 2001 From: Teemu Patja Date: Wed, 31 May 2017 16:39:29 +0300 Subject: [PATCH 6/6] Configurable gas price, eth RPC URL * config params for gas price and geth RPC URL Fixes: #59 --- src/clj/commiteth/eth/core.clj | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/clj/commiteth/eth/core.clj b/src/clj/commiteth/eth/core.clj index 64c2601..6f38b7f 100644 --- a/src/clj/commiteth/eth/core.clj +++ b/src/clj/commiteth/eth/core.clj @@ -8,9 +8,10 @@ [clojure.string :as str] [pandect.core :as pandect])) -(def eth-rpc-url "http://localhost:8545") +(defn eth-rpc-url [] (env :eth-rpc-url "http://localhost:8545")) (defn eth-account [] (:eth-account env)) (defn eth-password [] (:eth-password env)) +(defn gas-price [] (:gas-price env)) (defn eth-rpc [method params] @@ -21,7 +22,7 @@ :id request-id}) options {:headers {"content-type" "application/json"} :body body} - response (:body @(post eth-rpc-url options)) + response (:body @(post (eth-rpc-url) options)) result (json/read-str response :key-fn keyword)] (log/debug body "\n" result) (if (= (:id result) request-id) @@ -65,9 +66,12 @@ (defn send-transaction [from to value & [params]] (let [gas (estimate-gas from to value params) - args (merge params {:from from - :value value - :gas gas})] + args (merge params + {:from from + :value value + :gas gas} + (when-not (nil? (gas-price)) + {:gasPrice gas-price}))] (eth-rpc "personal_sendTransaction" [(if-not (nil? to)