Merge branch 'master' into develop

This commit is contained in:
Teemu Patja 2017-03-14 22:44:04 +02:00
commit bcae011231
No known key found for this signature in database
GPG Key ID: F5B7035E6580FD4C
14 changed files with 793 additions and 399 deletions

1007
LICENSE.md

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# commiteth # Commiteth
Allows you to set bounties for Github issues, paid out in Ether. Allows you to set bounties for Github issues, paid out in Ether.
@ -41,4 +41,4 @@ Open http://localhost:3449/cards.html
## License ## License
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/commiteth/blob/master/LICENSE.md) Licensed under the [Affero General Public License v3.0](https://github.com/status-im/commiteth/blob/master/LICENSE.md)

View File

@ -33,7 +33,7 @@
[clj.qrgen "0.4.0"] [clj.qrgen "0.4.0"]
[digest "1.4.5"] [digest "1.4.5"]
[tentacles "0.5.1"] [tentacles "0.5.1"]
[re-frisk "0.3.2"] [re-frisk "0.4.4"]
[bk/ring-gzip "0.2.1"] [bk/ring-gzip "0.2.1"]
[crypto-random "1.2.0"] [crypto-random "1.2.0"]
[crypto-equality "1.0.0"] [crypto-equality "1.0.0"]

View File

@ -0,0 +1,48 @@
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,
claims_view.updated
FROM claims_view
WHERE claims_view.pr_state in (0,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,
claims_view.updated
FROM claims_view
WHERE claims_view.pr_state = 1 AND claims_view.payout_receipt IS NOT NULL
UNION
SELECT 'new-bounty'::text AS type,
bounties_view.issue_title,
bounties_view.repo_name,
bounties_view.repo_owner,
bounties_view.issue_number,
bounties_view.user_name,
bounties_view.user_avatar_url,
bounties_view.balance,
bounties_view.updated
FROM bounties_view
WHERE bounties_view.balance = 0::numeric AND bounties_view.payout_receipt IS NULL
UNION
SELECT 'balance-update'::text AS type,
bounties_view.issue_title,
bounties_view.repo_name,
bounties_view.repo_owner,
bounties_view.issue_number,
bounties_view.user_name,
bounties_view.user_avatar_url,
bounties_view.balance,
bounties_view.updated
FROM bounties_view
WHERE bounties_view.balance > 0::numeric AND bounties_view.payout_receipt IS NULL
ORDER BY updated DESC;

View File

@ -206,6 +206,20 @@ SET
-- Bounties ------------------------------------------------------------------------ -- Bounties ------------------------------------------------------------------------
-- :name pending-contracts :? :*
-- :doc bounty issues where deploy contract has failed
SELECT
i.issue_id AS issue_id,
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.transaction_hash IS NULL
AND i.contract_address IS NULL;
-- :name pending-bounties-list :? :* -- :name pending-bounties-list :? :*
-- :doc lists all recently closed issues awaiting to be signed -- :doc lists all recently closed issues awaiting to be signed
SELECT SELECT

View File

@ -38,5 +38,13 @@
var commitethVersion = "{{commitethVersion}}"; var commitethVersion = "{{commitethVersion}}";
</script> </script>
{% script "/js/app.js" %} {% script "/js/app.js" %}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-79146816-2', 'auto');
ga('send', 'pageview');
</script>
</body> </body>
</html> </html>

View File

@ -5,6 +5,11 @@
(defn pending-contracts
[]
(jdbc/with-db-connection [con-db *db*]
(db/pending-contracts con-db)))
(defn list-owner-bounties (defn list-owner-bounties
[owner] [owner]
(jdbc/with-db-connection [con-db *db*] (jdbc/with-db-connection [con-db *db*]

View File

@ -27,7 +27,7 @@
(defn authorize-url [] (defn authorize-url []
(let [params (codec/form-encode {:client_id (client-id) (let [params (codec/form-encode {:client_id (client-id)
:redirect_uri (redirect-uri) :redirect_uri (redirect-uri)
:scope "admin:repo_hook user:email admin:org_hook" :scope "admin:repo_hook repo user:email admin:org_hook"
:allow_signup true :allow_signup true
:state (str (UUID/randomUUID))})] :state (str (UUID/randomUUID))})]
(str "https://github.com/login/oauth/authorize" "?" params))) (str "https://github.com/login/oauth/authorize" "?" params)))

View File

@ -43,6 +43,20 @@
balance balance
balance-str)))))) balance-str))))))
(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))))
(defn self-sign-bounty (defn self-sign-bounty
"Walks through all issues eligible for bounty payout and signs corresponding transaction" "Walks through all issues eligible for bounty payout and signs corresponding transaction"
[] []
@ -130,6 +144,7 @@
(defn run-periodic-tasks [time] (defn run-periodic-tasks [time]
(do (do
(log/debug "run-periodic-tasks" time) (log/debug "run-periodic-tasks" time)
(deploy-pending-contracts)
(update-issue-contract-address) (update-issue-contract-address)
(update-confirm-hash) (update-confirm-hash)
(update-payout-receipt) (update-payout-receipt)

View File

@ -141,8 +141,9 @@
[:h3 "Top hunters"] [:h3 "Top hunters"]
[top-hunters]]]] [top-hunters]]]]
[:div.ui.divider] [:div.ui.divider]
[:div.commiteth-footer "Built by " [:a {:href "https://status.im"} "Status"]
(when-not (= "unknown" version) (when-not (= "unknown" version)
[:div.version-footer "Commit ETH version " [:a {:href (str "https://github.com/status-im/commiteth/commit/" version)} version]])]]])) [:div.version-footer "version " [:a {:href (str "https://github.com/status-im/commiteth/commit/" version)} version]])]]]]))
(secretary/set-config! :prefix "#") (secretary/set-config! :prefix "#")

View File

@ -69,17 +69,6 @@
:redirect {:path "/logout"}})) :redirect {:path "/logout"}}))
(reg-event-fx
:save-payout-hash
(fn [{:keys [db]} [_ issue-id payout-hash]]
{:db db
:http {:method POST
:url (str/format "/api/user/bounty/%s/payout" issue-id)
:on-success #(dispatch [:payout-confirmed issue-id])
:on-error #(dispatch [:payout-confirm-failed issue-id])
:params {:payout-hash payout-hash}}}))
(reg-event-fx (reg-event-fx
:load-top-hunters :load-top-hunters
(fn [{:keys [db]} [_]] (fn [{:keys [db]} [_]]
@ -162,9 +151,7 @@
(defn update-repo-state [all-repos full-name data] (defn update-repo-state [all-repos full-name data]
(println full-name)
(let [[owner repo-name] (js->clj (.split full-name "/"))] (let [[owner repo-name] (js->clj (.split full-name "/"))]
(println "update-repo-busy-state" owner repo-name)
(update all-repos (update all-repos
owner owner
(fn [repos] (map (fn [repo] (if (= (:name repo) repo-name) (fn [repos] (map (fn [repo] (if (= (:name repo) repo-name)
@ -177,7 +164,6 @@
(reg-event-fx (reg-event-fx
:toggle-repo :toggle-repo
(fn [{:keys [db]} [_ repo]] (fn [{:keys [db]} [_ repo]]
(println repo)
{:db (assoc db :repos (update-repo-state {:db (assoc db :repos (update-repo-state
(:repos db) (:repos db)
(:full_name repo) (:full_name repo)
@ -194,7 +180,6 @@
(reg-event-db (reg-event-db
:repo-toggle-success :repo-toggle-success
(fn [db [_ repo]] (fn [db [_ repo]]
(println "repo-toggle-success" repo)
(assoc db :repos (update-repo-state (:repos db) (assoc db :repos (update-repo-state (:repos db)
(:full_name repo) (:full_name repo)
{:busy? false {:busy? false
@ -203,7 +188,6 @@
(reg-event-fx (reg-event-fx
:repo-toggle-error :repo-toggle-error
(fn [{:keys [db]} [_ repo response]] (fn [{:keys [db]} [_ repo response]]
(println "repo-toggle-error" response)
{:db (assoc db :repos (update-repo-state (:repos db) {:db (assoc db :repos (update-repo-state (:repos db)
(:full_name repo) (:full_name repo)
{:busy? false})) {:busy? false}))
@ -245,20 +229,31 @@
(dissoc db :updating-address))) (dissoc db :updating-address)))
(reg-event-fx
:save-payout-hash
(fn [{:keys [db]} [_ issue-id payout-hash]]
{:db db
:http {:method POST
:url (str/format "/api/user/bounty/%s/payout" issue-id)
:on-success #(dispatch [:payout-confirmed issue-id])
:on-error #(dispatch [:payout-confirm-failed issue-id])
:params {:payout-hash payout-hash}}}))
(defn send-transaction-callback (defn send-transaction-callback
[issue-id] [issue-id]
(println "send-transaction-callback")
(fn [error payout-hash] (fn [error payout-hash]
(println "send-transaction-callback fn")
(when error (when error
(do
(dispatch [:set-flash-message (dispatch [:set-flash-message
:error :error
(str "Error sending transaction: " error)])) (str "Error sending transaction: " error)])
(dispatch [:payout-confirm-failed issue-id])))
(when payout-hash (when payout-hash
(dispatch [:save-payout-hash issue-id payout-hash])))) (dispatch [:save-payout-hash issue-id payout-hash]))))
(reg-event-fx (reg-event-fx
:confirm-payout :confirm-payout
(fn [{:keys [db]} [_ {issue-id :issue_id (fn [{:keys [db]} [_ {issue-id :issue_id
@ -270,27 +265,29 @@
:to contract-address :to contract-address
:value 1 :value 1
:data (str "0x797af627" confirm-hash)}] :data (str "0x797af627" confirm-hash)}]
(println "confirm-payout" owner-address contract-address)
(try (try
(apply send-transaction-fn [(clj->js payload) (apply send-transaction-fn [(clj->js payload)
(send-transaction-callback issue-id)]) (send-transaction-callback issue-id)])
{:db (assoc-in db [:owner-bounties issue-id :confirming?] true)} {:db (assoc-in db [:owner-bounties issue-id :confirming?] true)}
(catch js/Error e (catch js/Error e
{:db (assoc-in db [:owner-bounties issue-id :confirm-failed?] true) {:db (assoc-in db [:owner-bounties issue-id :confirm-failed?] true)
:dispatch [:set-flash-message :dispatch-n [[:payout-confirm-failed issue-id]
[:set-flash-message
:error :error
(str "Failed to send transaction" e)]}))))) (str "Failed to send transaction" e)]]})))))
(reg-event-db (reg-event-fx
:payout-confirmed :payout-confirmed
(fn [db [_ issue-id]] (fn [{:keys [db]} [_ issue-id]]
(-> db {:dispatch [:load-owner-bounties]
(dissoc-in [:owner-bounties (:issue_id issue-id) :confirming?]) :db (-> db
(assoc-in [:owner-bounties (:issue_id issue-id) :confirmed?] true)))) (dissoc-in [:owner-bounties issue-id :confirming?])
(assoc-in [:owner-bounties issue-id :confirmed?] true))}))
(reg-event-db (reg-event-db
:payout-confirm-failed :payout-confirm-failed
(fn [db [_ issue-id]] (fn [db [_ issue-id]]
(println "payout-confirm-failed" issue-id)
(-> db (-> db
(dissoc-in [:owner-bounties (:issue_id issue-id) :confirming?]) (dissoc-in [:owner-bounties issue-id :confirming?])
(assoc-in [:owner-bounties (:issue_id issue-id) :confirm-failed?] true)))) (assoc-in [:owner-bounties issue-id :confirm-failed?] true))))

View File

@ -19,7 +19,7 @@
[:div.ui.container.grid [:div.ui.container.grid
[:div.ui.form.sixteen.wide.column [:div.ui.form.sixteen.wide.column
[:h3 "Update address"] [:h3 "Update address"]
[:p "Placeholder text for explaining what an Ethereum address is."] [:p "Insert your Ethereum address in hex format."]
[:div.field [:div.field
(if-not (empty? web3-accounts) (if-not (empty? web3-accounts)
[dropdown {:class "address-input"} "Select address" [dropdown {:class "address-input"} "Select address"

View File

@ -326,8 +326,19 @@ span.dropdown.icon {
} }
} }
.version-footer { .commiteth-footer {
color: #a8aab1; color: #a8aab1;
line-height: 1.8em;
a {
&:hover {
color: #a8aab1!important;
}
color: #a8aab1!important;
}
}
.version-footer {
font-size: .8em; font-size: .8em;
a { a {
&:hover { &:hover {