From cec0718b1ec2b698f9f0ac683730ef9ace34dc96 Mon Sep 17 00:00:00 2001 From: Rob Culliton Date: Tue, 1 May 2018 21:53:02 -0400 Subject: [PATCH] move update-confirm-hash back to scheduler, make sure job is in 1-min tasks --- src/clj/commiteth/routes/services.clj | 14 +--- src/clj/commiteth/scheduler.clj | 99 +++++++++++++++++---------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/clj/commiteth/routes/services.clj b/src/clj/commiteth/routes/services.clj index 3808e2d..9f37dcc 100644 --- a/src/clj/commiteth/routes/services.clj +++ b/src/clj/commiteth/routes/services.clj @@ -171,18 +171,6 @@ {:execute-hash execute-hash :execute-write execute-write})) -(defn update-confirm-hash - [issue-id execute-hash] - (log/infof "issue %s: pending payout: %s" issue-id execute-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) - {:confirm_hash confirm-hash})) - (catch Throwable ex - (log/errorf ex "issue %s: update-confirm-hash exception:" issue-id)))) (defapi service-routes (when (:dev env) @@ -278,7 +266,7 @@ (do (log/infof "calling revoke-initiate for %s with %s %s" issue-id contract-address owner-address) (if-let [{:keys [execute-hash execute-write]} (execute-revocation issue-id contract-address owner-address)] (if (scheduler/poll-transaction-logs execute-hash contract-address) - (if-let [{confirm-hash :confirm_hash} (update-confirm-hash issue-id execute-hash)] + (if-let [{confirm-hash :confirm_hash} (scheduler/update-confirm-hash issue-id execute-hash)] (ok {:confirm-hash confirm-hash}) (bad-request "The confirm hash could not be updated")) (bad-request "The transaction hash could not be confirmed in a reasonable amount of time")) diff --git a/src/clj/commiteth/scheduler.clj b/src/clj/commiteth/scheduler.clj index aefff23..27706a9 100644 --- a/src/clj/commiteth/scheduler.clj +++ b/src/clj/commiteth/scheduler.clj @@ -149,6 +149,30 @@ (log/error ex "issue %s: self-sign-bounty exception" issue-id))))) (log/info "Exit self-sign-bounty")) +(defn update-confirm-hash + [issue-id execute-hash] + (log/infof "issue %s: pending payout: %s" issue-id execute-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) + {:confirm_hash confirm-hash})) + (catch Throwable ex + (log/errorf ex "issue %s: update-confirm-hash exception:" issue-id)))) + +(defn update-confirm-hashes + "Gets transaction receipt for each pending payout and updates DB confirm_hash with tranaction ID of commiteth bot account's confirmation." + [] + (log/info "In update-confirm-hashes") + (p :update-confirm-hash + (doseq [{issue-id :issue_id + execute-hash :execute_hash} (db-bounties/pending-payouts)] + + (update-confirm-hash issue-id execute-hash))) + (log/info "Exit update-confirm-hash")) + (defn update-watch-hash "Sets watch-hash to NULL for bounties where watch tx has been mined. Used to avoid unneeded watch transactions in update-bounty-token-balances" [] @@ -252,6 +276,43 @@ (neg? n) (- n) :else n)) +(defn contract-confirmation-logs [contract-address] + "retrives all log events for the confirmation topic since contract creation" + (some-> contract-address + issues/get-issue-by-contract-address + :transaction_hash + eth/get-transaction-by-hash + :blockNumber + (eth/get-logs contract-address [(:confirmation multisig/topics)]))) + +(defn hash-in-logs? + "return true if the transaction hash is present in the queryable blockchain" + [hash logs] + (some #(= hash (:transactionHash %)) logs)) + +(defn execution-status [execute-hash contract-address] + "check to see if a given execute-hash has been confirmed" + (log/infof "checking contract for logs containing %s" execute-hash) + (let [logs (contract-confirmation-logs contract-address)] + (hash-in-logs? execute-hash logs))) + + +(defn poll-transaction-logs [execute-hash contract-address] + "check for execution hash in logs for a few minutes" + (let [found? (promise) + intervals (take 6 + (periodic-seq (t/now) + (t/seconds 30)))] + ;; polling will be slow but if we want to move to an event driven + ;; model then we can listen for events, rather than logs, once we're + ;; using a geth node again + (chime-at intervals + (fn [time] + (when (execution-status execute-hash contract-address) + (deliver found? true))) + {:on-finished (fn [] + (deliver found? false))}) + @found?)) (defn update-bounty-token-balances "Helper function for updating internal ERC20 token balances to token @@ -400,6 +461,7 @@ (run-tasks [deploy-pending-contracts update-issue-contract-address + update-confirm-hashes update-payout-receipts update-revoked-payout-receipts update-watch-hash @@ -441,40 +503,3 @@ (log/info "stopping scheduler") (scheduler))) -(defn contract-confirmation-logs [contract-address] - "retrives all log events for the confirmation topic since contract creation" - (some-> contract-address - issues/get-issue-by-contract-address - :transaction_hash - eth/get-transaction-by-hash - :blockNumber - (eth/get-logs contract-address [(:confirmation multisig/topics)]))) - -(defn hash-in-logs? - "return true if the transaction hash is present in the queryable blockchain" - [hash logs] - (some #(= hash (:transactionHash %)) logs)) - -(defn execution-status [execute-hash contract-address] - "check to see if a given execute-hash has been confirmed" - (log/infof "checking contract for logs containing %s" execute-hash) - (let [logs (contract-confirmation-logs contract-address)] - (hash-in-logs? execute-hash logs))) - - -(defn poll-transaction-logs [execute-hash contract-address] - "check for execution hash in logs for a few minutes" - (let [found? (promise) - intervals (take 6 - (periodic-seq (t/now) - (t/seconds 30)))] - ;; polling will be slow but if we want to move to an event driven - ;; model then we can listen for events, rather than logs, once we're - ;; using a geth node again - (chime-at intervals - (fn [time] - (when (execution-status execute-hash contract-address) - (deliver found? true))) - {:on-finished (fn [] - (deliver found? false))}) - @found?))