mirror of
https://github.com/status-im/open-bounty.git
synced 2025-02-08 23:53:39 +00:00
Merge branch 'develop' into fix/remove-dep-on-older-web3j-and-solc
This commit is contained in:
commit
e549725648
48
.circleci/config.yml
Normal file
48
.circleci/config.yml
Normal file
@ -0,0 +1,48 @@
|
||||
# Clojure CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/language-clojure/ for more details
|
||||
#
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/clojure:lein-2.8.1-browsers
|
||||
|
||||
# Specify service dependencies here if necessary
|
||||
# CircleCI maintains a library of pre-built images
|
||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
||||
# - image: circleci/postgres:9.4
|
||||
- image: circleci/postgres:9.6
|
||||
environment:
|
||||
- POSTGRES_USER=commiteth
|
||||
- POSTGRES_DB=commiteth
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
environment:
|
||||
LEIN_ROOT: "true"
|
||||
# Customize the JVM maximum heap limit
|
||||
JVM_OPTS: -Xmx3200m
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "project.clj" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v1-dependencies-
|
||||
|
||||
- run: lein deps
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.m2
|
||||
key: v1-dependencies-{{ checksum "project.clj" }}
|
||||
|
||||
- run: echo $ETH_WALLET_JSON > $ETH_WALLET_FILE
|
||||
|
||||
# run tests!
|
||||
- run: lein test
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,4 +26,3 @@ node_modules
|
||||
/config-prod.edn
|
||||
/config-dev.edn
|
||||
/config-test.edn
|
||||
/src/java
|
||||
|
43
README.md
43
README.md
@ -18,6 +18,7 @@ The `develop` branch is automatically deployed here.
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Application config](#application-config)
|
||||
- [GitHub integration](#github-integration)
|
||||
- [Contracts](#contracts)
|
||||
- [Running](#running)
|
||||
- [Testing](#testing)
|
||||
- [More info](#more-info)
|
||||
@ -37,28 +38,6 @@ psql postgres -c "CREATE USER commiteth WITH PASSWORD 'commiteth';"
|
||||
psql postgres -c "CREATE DATABASE commiteth;"
|
||||
```
|
||||
|
||||
### solc
|
||||
|
||||
Solidity compiler (latest version, currently [0.4.20](https://github.com/ethereum/solidity/releases/tag/v0.4.20)) is required and needs to be in $PATH.
|
||||
Detailed [installation instructions for various platforms](https://solidity.readthedocs.io/en/develop/installing-solidity.html) can be found in the official Solidity documentation.
|
||||
|
||||
In order to install version 0.4.20 on macOS using Homebrew:
|
||||
```
|
||||
brew tap ethereum/ethereum
|
||||
brew install https://raw.githubusercontent.com/ethereum/homebrew-ethereum/76432c9aa279b6907e5b1323b9195f2681c30844/solidity.rb
|
||||
```
|
||||
|
||||
### web3j
|
||||
|
||||
Web3j (latest version, currently [3.3.1](https://github.com/web3j/web3j/releases/tag/v3.3.1)) is required and the command line tools need to be in $PATH.
|
||||
Installation instructions for the command line tools can be found in the [Web3j Command Line Tools documentation](https://docs.web3j.io/command_line.html).
|
||||
|
||||
In order to install version 3.3.1 on macOS using Homebrew:
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/web3j/homebrew-web3j/master/web3j.rb
|
||||
```
|
||||
|
||||
|
||||
## Application config
|
||||
|
||||
Make sure to create `/config-dev.edn` and populate it correctly, which is based on `env/dev/resources/config.edn`. Description of config fields is given below:
|
||||
@ -93,6 +72,10 @@ Follow the steps [here](https://developer.github.com/apps/building-oauth-apps/cr
|
||||
### GitHub App
|
||||
Follow the steps [here](https://developer.github.com/apps/building-github-apps/creating-a-github-app/). Be sure to specify `:server-address` + `/webhook-app` as "Webhook URL", and `:webhook-secret` as "Webhook Secret".
|
||||
|
||||
## Contracts
|
||||
|
||||
All information related to development of OpenBounty smart contracts can be found in [`contracts/`](/contracts/)
|
||||
|
||||
## Running
|
||||
|
||||
### Ethereum node
|
||||
@ -196,7 +179,21 @@ lein with-profile test figwheel devcards
|
||||
|
||||
Open http://localhost:3449/cards.html
|
||||
|
||||
### Update landing page
|
||||
### CircleCI
|
||||
|
||||
We use CircleCI to run unit tests. The following env vars need to be set for this to work:
|
||||
|
||||
> These env vars override configuration parameters that are usually set using the `config.edn` file.
|
||||
|
||||
- `ETH_ACCOUNT` - as in `config.edn`
|
||||
- `ETH_PASSWORD` - as in `config.edn`
|
||||
- `ETH_RPC_URL` - as in `config.edn`
|
||||
- `ETH_WALLET_FILE` - as in `config.edn`
|
||||
- `ETH_WALLET_JSON` - contents of this will be written to `ETH_WALLET_FILE`
|
||||
|
||||
:bulb: Ideally we'd create those parameters in a script. PR welcome.
|
||||
|
||||
## Update landing page
|
||||
|
||||
Landing page is static and different CSS and JS due to time constraints.
|
||||
|
||||
|
31
contracts/README.md
Normal file
31
contracts/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# OpenBounty Contracts
|
||||
|
||||
This directory contains all the underlying smart contracts used by the OpenBounty platform.
|
||||
|
||||
- A script `contracts/build.sh` is part of this repository and can be used to
|
||||
compile the contracts and copy Java interfaces into `src/java/`.
|
||||
|
||||
In order to run the script the following dependencies have to be met:
|
||||
|
||||
- [solc](#solc)
|
||||
- [web3j](#web3j)
|
||||
|
||||
### solc
|
||||
|
||||
Solidity compiler [0.4.15](https://github.com/ethereum/solidity/releases/tag/v0.4.15) is required and needs to be in $PATH.
|
||||
Detailed [installation instructions for various platforms](https://solidity.readthedocs.io/en/develop/installing-solidity.html) can be found in the official Solidity documentation.
|
||||
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/ethereum/homebrew-ethereum/de1da16f7972a899fc8dd1f3f04299eced6f4312/solidity.rb
|
||||
brew pin solidity
|
||||
```
|
||||
|
||||
### web3j
|
||||
|
||||
Web3j [2.3.0](https://github.com/web3j/web3j/releases/tag/v2.3.0) is required and the command line tools need to be in $PATH.
|
||||
Installation instructions for the command line tools can be found in the [Web3j Command Line Tools documentation](https://docs.web3j.io/command_line.html).
|
||||
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/web3j/homebrew-web3j/881cf369b551a5f2557bd8fb02fa8b7b970256ca/web3j.rb
|
||||
brew pin web3j
|
||||
```
|
@ -6,14 +6,17 @@ How to test PR? Steps below could help a bit!
|
||||
### Prerequisites
|
||||
Requirements for PRs to be tested:
|
||||
* should be in `To test` column in `Pipeline For Pull Requests` project
|
||||
* should be updated to last develop. If button `Update` is avaivable on particular PR, click it and wait until it will be built.
|
||||
* shouldn't have conflicts with `develop` branch
|
||||
* should have a successful build in Jenkins [status-openbounty-app](https://jenkins.status.im/job/status-openbounty/job/status-openbounty-app/view/change-requests/)
|
||||
|
||||
|
||||
### Deployment
|
||||
In order to deploy feature to [testing env](https://testing.openbounty.status.im/) you should **rebuild** PR you are about to test.
|
||||
In order to deploy feature to [testing env](https://testing.openbounty.status.im/) you should **rebuild** PR you are about to test (all open PRs are in [Jenkins](https://jenkins.status.im/job/status-openbounty/job/status-openbounty-app/view/change-requests/)).
|
||||
|
||||
Only one PR can be deployed on [testing env](https://testing.openbounty.status.im/)
|
||||
When PR is successfully build and deployed, [testing env](https://testing.openbounty.status.im/) with deployed PR is accessible in 2-3 mins.
|
||||
|
||||
Only one at one time PR can be deployed on [testing env](https://testing.openbounty.status.im/)
|
||||
|
||||
Fresh develop branch with last changes is deployed automatically on [staging env](https://openbounty.status.im:444)
|
||||
|
||||
@ -21,7 +24,8 @@ Fresh develop branch with last changes is deployed automatically on [staging env
|
||||
1) Move appropriate PR card to IN TESTING on the [Board](https://github.com/status-im/open-bounty/projects/3) and let people know you are on it - assign it to yourself! :)
|
||||
2) Сheck the functionality current PR fixes / delivers (positive/negative tests related to the feature). In curtain cases it's worth to look in 'Files changed' tab in GitHub to check the list of what was changed to get understanding of the test coverage or "weak" places that have to be covered. Ask PR-author in #openbounty channel in slack what was changed if it's not clear from the notes in PR.
|
||||
3) Check reasonable regression using [SOB-general test suite](https://ethstatus.testrail.net/index.php?/suites/view/27&group_by=cases:section_id&group_order=asc)
|
||||
4) No issues? Perfect! Put appropriate label to the PR (`Tested - OK`), merge it to develop and move the PR instance to `Merged to develop`.
|
||||
5) Found issues? Check for duplicates before adding one. Hint: make sure the issue is really introduced by current PR - check latest `develop` branch on [staging env](https://openbounty.status.im:444) . Issue exists in develop? Check existing issues list and make sure you are not adding duplicates before creating your own bug :) **All PR-specific issues should be added as comments to tested PR.**
|
||||
4) No issues? Perfect! Put appropriate label to the PR (`Tested - OK`), merge it to develop (using `Rebase-Merge`) and move the PR instance to `Merged to develop`.
|
||||
5) Found issues? Check for duplicates before adding one. Hint: make sure the issue is really introduced by current PR - check latest `develop` branch on [staging env](https://openbounty.status.im:444) . Issue exists in develop? Check existing issues list and make sure you are not adding duplicates before creating your own bug :)
|
||||
**All PR-specific issues should be added as comments to tested PR.**
|
||||
Once all issues are logged put label `Tested-issues` to the PR and notify developer that there are several problems that are preventing the PR to merge. Move the PR to `Reviewing, waiting for contributor` on the board if PR is developed by external contributor, and to `Developing` - if it is presented by core contributor.
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
# 0003. Include Compiled Web3j Contracts in Git
|
||||
|
||||
| Date | Tags |
|
||||
|---|---|
|
||||
| 2018-03-20 | contracts, tooling |
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
The OpenBounty project utilizes smart contracts to make certain core
|
||||
aspects of it's product work without centralized trust.
|
||||
|
||||
In order to develop the platform a Java interface to these contracts needs to
|
||||
be built beforehand. To create those interfaces various tools are required
|
||||
(`web3j` & `solc`), often in specific versions that are not easily available
|
||||
via widespread package managers.
|
||||
|
||||
This hurdle also applies to any other situations where the application is set
|
||||
up from scratch, e.g. continuous integration.
|
||||
|
||||
## Decision
|
||||
|
||||
Instead of forcing every contributor to install those tools we will include
|
||||
the compiled Java interfaces in our Git repository. This removes a significant
|
||||
setup cost and hopefully allows people to get going much faster.
|
||||
|
||||
Installing `web3j` and `solc` will only be required when hacking on the
|
||||
contracts itself which are much more stable than the majority of the code.
|
||||
|
||||
An alternative would be implementing scripts that install those tools in a
|
||||
platform independent manner but this would require more work. Once we have
|
||||
the time or someone wants to work on creating those scripts we can easily
|
||||
revert the decision outlined in this document.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The compiled Java interfaces may get out of date.
|
||||
This could perhaps be addressed by some clever use of checksums.
|
||||
- By having changes to the contract interfaces be part of a changeset it may
|
||||
be easier to spot what changes are required/how APIs are changing.
|
@ -1,12 +0,0 @@
|
||||
|
||||
/*
|
||||
externs for web3 injected into js context. needed for things to work with advanced cljs compilation
|
||||
|
||||
TODO: probably not a good idea to maintain this manually in the long run*/
|
||||
|
||||
var web3 = {
|
||||
eth: {
|
||||
accounts: [],
|
||||
sendTransaction: function() {}
|
||||
}
|
||||
};
|
13
project.clj
13
project.clj
@ -9,7 +9,7 @@
|
||||
[reagent-utils "0.2.1"]
|
||||
[reagent "0.7.0"]
|
||||
[org.clojure/clojurescript "1.9.946"]
|
||||
[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/clojure "1.9.0"]
|
||||
[selmer "1.11.1"]
|
||||
[com.taoensso/tufte "1.3.0"]
|
||||
[markdown-clj "1.0.1"]
|
||||
@ -66,25 +66,18 @@
|
||||
:plugins [[lein-cprop "1.0.1"]
|
||||
[migratus-lein "0.4.1"]
|
||||
[lein-cljsbuild "1.1.7"]
|
||||
[lein-auto "0.1.2"]
|
||||
[lein-less "1.7.5"]
|
||||
[lein-shell "0.5.0"]
|
||||
[lein-sha-version "0.1.1"]]
|
||||
|
||||
|
||||
:less {:source-paths ["src/less"]
|
||||
:target-path "resources/public/css"}
|
||||
|
||||
:auto {"build-contracts" {:file-pattern #"\.(sol)\n"
|
||||
:paths ["./contracts"]}}
|
||||
|
||||
:aliases {"build-contracts" ["shell" "./build_contracts.sh"]}
|
||||
|
||||
:ring {:destroy commiteth.scheduler/stop-scheduler}
|
||||
|
||||
:uberjar-exclusions [#"public/README.md" #"public/cards.html"]
|
||||
:clean-targets ^{:protect false}
|
||||
[:target-path :java-source-paths [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]]
|
||||
[:target-path [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]]
|
||||
:figwheel
|
||||
{:http-server-root "public"
|
||||
:nrepl-port 7002
|
||||
@ -94,7 +87,7 @@
|
||||
:profiles
|
||||
{:uberjar {:jvm-opts ["-server" "-Dconf=config-prod.edn"]
|
||||
:omit-source true
|
||||
:prep-tasks ["build-contracts" "javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]]
|
||||
:prep-tasks ["javac" "compile" ["cljsbuild" "once" "min"] ["less" "once"]]
|
||||
:cljsbuild
|
||||
{:builds
|
||||
{:min
|
||||
|
@ -193,20 +193,6 @@ 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
|
||||
@ -249,7 +235,10 @@ WHERE pr_id = :pr_id;
|
||||
-- :doc bounty issues where deploy contract has failed
|
||||
SELECT
|
||||
i.issue_id AS issue_id,
|
||||
u.address AS owner_address
|
||||
i.issue_number AS issue_number,
|
||||
r.owner AS owner,
|
||||
u.address AS owner_address,
|
||||
r.repo AS repo
|
||||
FROM issues i, users u, repositories r
|
||||
WHERE
|
||||
r.user_id = u.id
|
||||
@ -464,8 +453,9 @@ SELECT
|
||||
i.updated AS updated,
|
||||
i.winner_login AS winner_login,
|
||||
r.repo AS repo_name,
|
||||
o.address AS owner_address
|
||||
FROM issues i, users o, repositories r
|
||||
o.address AS owner_address,
|
||||
u.address AS payout_address
|
||||
FROM users o, repositories r, issues i LEFT OUTER JOIN users u ON u.login = i.winner_login
|
||||
WHERE
|
||||
r.repo_id = i.repo_id
|
||||
AND r.user_id = o.id
|
||||
|
@ -20,6 +20,26 @@
|
||||
(let [labels (:labels issue)]
|
||||
(some #(= label-name (:name %)) labels)))
|
||||
|
||||
(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")
|
||||
(do
|
||||
(log/info "deploying contract to " owner-address)
|
||||
(if-let [transaction-hash (multisig/deploy-multisig owner-address)]
|
||||
(do
|
||||
(log/info "Contract deployed, transaction-hash:"
|
||||
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)]
|
||||
(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)))))
|
||||
|
||||
(defn add-bounty-for-issue [repo repo-id issue]
|
||||
(let [{issue-id :id
|
||||
issue-number :number
|
||||
@ -29,24 +49,7 @@
|
||||
owner :owner} (users/get-repo-owner repo-id)]
|
||||
(log/debug "Adding bounty for issue " repo issue-number "owner address: " owner-address)
|
||||
(if (= 1 created-issue)
|
||||
(if (empty? owner-address)
|
||||
(log/error "Unable to deploy bounty contract because"
|
||||
"repo owner has no Ethereum addres")
|
||||
(do
|
||||
(log/debug "deploying contract to " owner-address)
|
||||
(let [transaction-hash (multisig/deploy-multisig owner-address)]
|
||||
(if (nil? transaction-hash)
|
||||
(log/error "Failed to deploy contract to" owner-address)
|
||||
(do
|
||||
(log/info "Contract deployed, transaction-hash:"
|
||||
transaction-hash)
|
||||
(->> (github/post-deploying-comment owner
|
||||
repo
|
||||
issue-number
|
||||
transaction-hash)
|
||||
:id
|
||||
(issues/update-comment-id issue-id))))
|
||||
(issues/update-transaction-hash issue-id transaction-hash))))
|
||||
(deploy-contract owner owner-address repo issue-id issue-number)
|
||||
(log/debug "Issue already exists in DB, ignoring"))))
|
||||
|
||||
(defn maybe-add-bounty-for-issue [repo repo-id issue]
|
||||
@ -102,3 +105,44 @@
|
||||
(do
|
||||
(log/info "Updating changed title for issue" (:id gh-issue))
|
||||
(issues/update-issue-title (:id gh-issue) (:title gh-issue)))))))
|
||||
|
||||
(defn assert-keys [m ks]
|
||||
(doseq [k ks]
|
||||
(when-not (find m k)
|
||||
(throw (ex-info (format "Expected key missing from provided map: %s" k) {:map m})))))
|
||||
|
||||
(defn bounty-state
|
||||
"Given a map as returned by `owner-bounties` return the state the provided bounty is in.
|
||||
|
||||
The lifecycle of a bounty is a sequence of the following states:
|
||||
:opened > :funded > :claimed > :merged > :paid
|
||||
|
||||
As well as various states that are only reached under specific conditins:
|
||||
- :multiple-claims
|
||||
- :pending-contributor-address
|
||||
- :pending-maintainer-confirmation"
|
||||
[bounty]
|
||||
(assert-keys bounty [:winner_login :payout_address :confirm_hash :payout_hash
|
||||
:claims :tokens :contract_address])
|
||||
(if-let [merged? (:winner_login bounty)]
|
||||
(cond
|
||||
(nil? (:payout_address bounty)) :pending-contributor-address
|
||||
(nil? (:confirm_hash bounty)) :pending-maintainer-confirmation
|
||||
(:payout_hash bounty) :paid
|
||||
:else :merged)
|
||||
(cond ; not yet merged
|
||||
(< 1 (count (:claims bounty))) :multiple-claims
|
||||
(= 1 (count (:claims bounty))) :claimed
|
||||
(seq (:tokens bounty)) :funded
|
||||
(:contract_address bounty) :opened)))
|
||||
|
||||
(comment
|
||||
(def user 97496)
|
||||
|
||||
(clojure.pprint/pprint
|
||||
(count (bounties/owner-bounties user)))
|
||||
|
||||
(clojure.pprint/pprint
|
||||
(frequencies (map bounty-state (bounties/owner-bounties user))))
|
||||
|
||||
)
|
||||
|
@ -63,12 +63,6 @@
|
||||
(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 update-eth-balance
|
||||
[contract-address balance-eth]
|
||||
(jdbc/with-db-connection [con-db *db*]
|
||||
|
@ -127,13 +127,17 @@
|
||||
result (safe-read-str (:body response))]
|
||||
(log/debug body "\n" result)
|
||||
|
||||
(if (= (:id result) request-id)
|
||||
(:result result)
|
||||
(do
|
||||
(log/error "Geth returned an invalid json-rpc request ID,"
|
||||
"ignoring response")
|
||||
(when-let [error (:error result)]
|
||||
(log/error "Method: " method ", error: " error))))))
|
||||
(cond
|
||||
;; Ignore any responses that have mismatching request ID
|
||||
(not= (:id result) request-id)
|
||||
(log/error "Geth returned an invalid json-rpc request ID, ignoring response")
|
||||
|
||||
;; If request ID matches but contains error, throw
|
||||
(:error result)
|
||||
(throw (ex-info "Error submitting transaction via eth-rpc" (:error result)))
|
||||
|
||||
:else
|
||||
(:result result))))
|
||||
|
||||
(defn hex->big-integer
|
||||
[hex]
|
||||
|
@ -37,6 +37,7 @@
|
||||
([addr]
|
||||
(println "addr" addr)
|
||||
(let [contract (load-tokenreg-contract addr)]
|
||||
(assert contract (format "Could not load contract for addr %s" addr))
|
||||
;(assert (.isValid contract)) ;; web3j's isValid can't be trusted...
|
||||
(let [token-count (-> contract .tokenCount .get .getValue)]
|
||||
(log/debug "token-count" token-count)
|
||||
|
@ -275,7 +275,7 @@
|
||||
(defn post-deploying-comment
|
||||
[owner repo issue-number tx-id]
|
||||
(let [comment (generate-deploying-comment owner repo issue-number tx-id)]
|
||||
(log/debug "Posting comment to" (str owner "/" repo "/" issue-number) ":" comment)
|
||||
(log/info "Posting comment to" (str owner "/" repo "/" issue-number) ":" comment)
|
||||
(issues/create-comment owner repo issue-number comment (self-auth-params))))
|
||||
|
||||
(defn make-patch-request [end-point positional query]
|
||||
|
@ -61,18 +61,21 @@
|
||||
github-repos))))
|
||||
|
||||
|
||||
(defn ^:private enrich-owner-bounties [owner-bounty]
|
||||
(let [claims (map
|
||||
#(update % :value_usd usd-decimal->str)
|
||||
(bounties-db/bounty-claims (:issue_id owner-bounty)))
|
||||
with-claims (assoc owner-bounty :claims claims)]
|
||||
(-> with-claims
|
||||
(update :value_usd usd-decimal->str)
|
||||
(assoc :state (bounties/bounty-state with-claims)))))
|
||||
|
||||
(defn user-bounties [user]
|
||||
(let [owner-bounties (bounties-db/owner-bounties (:id user))]
|
||||
(into {}
|
||||
(for [ob owner-bounties
|
||||
:let [b (update ob :value_usd usd-decimal->str)]]
|
||||
[(:issue_id b)
|
||||
(conj b
|
||||
(let [claims (map
|
||||
#(update % :value_usd usd-decimal->str)
|
||||
(bounties-db/bounty-claims (:issue_id b)))]
|
||||
{:claims claims}))]))))
|
||||
|
||||
(->> owner-bounties
|
||||
(map enrich-owner-bounties)
|
||||
(map (juxt :issue_id identity))
|
||||
(into {}))))
|
||||
|
||||
(defn top-hunters []
|
||||
(let [renames {:user_name :display-name
|
||||
|
@ -82,28 +82,33 @@
|
||||
(when (issues/is-bounty-issue? issue-id)
|
||||
(issues/update-open-status issue-id true)))
|
||||
|
||||
(def ^:const keywords
|
||||
[#"(?i)close:?\s+#(\d+)"
|
||||
#"(?i)closes:?\s+#(\d+)"
|
||||
#"(?i)closed:?\s+#(\d+)"
|
||||
#"(?i)fix:?\s+#(\d+)"
|
||||
#"(?i)fixes:?\s+#(\d+)"
|
||||
#"(?i)fixed:?\s+#(\d+)"
|
||||
#"(?i)resolve:?\s?#(\d+)"
|
||||
#"(?i)resolves:?\s+#(\d+)"
|
||||
#"(?i)resolved:?\s+#(\d+)"])
|
||||
(defn pr-keywords [prefix]
|
||||
(mapv
|
||||
#(re-pattern (str "(?i)" %1 ":?\\s+" prefix "(\\d+)"))
|
||||
["close"
|
||||
"closes"
|
||||
"closed"
|
||||
"fix"
|
||||
"fixes"
|
||||
"fixed"
|
||||
"resolve"
|
||||
"resolves"
|
||||
"resolved"]))
|
||||
|
||||
(defn extract-issue-number
|
||||
[pr-body pr-title]
|
||||
[owner repo pr-body pr-title]
|
||||
(let [cleaned-body (str/replace pr-body #"(?m)^\[comment.*$" "")
|
||||
keywords (concat (pr-keywords "#")
|
||||
(when-not (or (str/blank? owner) (str/blank? repo))
|
||||
(pr-keywords (str "https://github.com/" owner "/" repo "/issues/"))))
|
||||
extract (fn [source]
|
||||
(mapcat #(keep
|
||||
(fn [s]
|
||||
(try (let [issue-number (Integer/parseInt (second s))]
|
||||
(when (pos? issue-number)
|
||||
issue-number))
|
||||
(catch NumberFormatException _)))
|
||||
(re-seq % source)) keywords))]
|
||||
(fn [s]
|
||||
(try (let [issue-number (Integer/parseInt (second s))]
|
||||
(when (pos? issue-number)
|
||||
issue-number))
|
||||
(catch NumberFormatException _)))
|
||||
(re-seq % source)) keywords))]
|
||||
(log/debug cleaned-body)
|
||||
(concat (extract cleaned-body)
|
||||
(extract pr-title))))
|
||||
@ -169,7 +174,7 @@
|
||||
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->> (extract-issue-number pr-body pr-title)
|
||||
(if-let [issue (some->> (extract-issue-number owner repo pr-body pr-title)
|
||||
(first)
|
||||
(issues/get-issue repo-id))]
|
||||
(if-not (:commit_sha issue) ; no PR has been merged yet referencing this issue
|
||||
|
@ -84,34 +84,17 @@
|
||||
(log/info "Exit update-issue-contract-address"))
|
||||
|
||||
|
||||
(defn deploy-contract [owner-address issue-id]
|
||||
(let [transaction-hash (multisig/deploy-multisig 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-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))))
|
||||
|
||||
|
||||
(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
|
||||
owner-address :owner_address} (db-bounties/pending-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)
|
||||
(deploy-contract owner-address 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"
|
||||
@ -400,8 +383,7 @@
|
||||
;; TODO: disabled for now. looks like it may cause extraneus
|
||||
;; contract deployments and costs
|
||||
(run-tasks
|
||||
[;;redeploy-failed-contracts
|
||||
deploy-pending-contracts
|
||||
[deploy-pending-contracts
|
||||
update-issue-contract-address
|
||||
update-confirm-hash
|
||||
update-payout-receipt
|
||||
|
@ -2,10 +2,14 @@
|
||||
(:require [reagent.core :as r]
|
||||
[re-frame.core :as rf]
|
||||
[clojure.string :as str]
|
||||
[goog.object :as gobj]
|
||||
[goog.date.relative]
|
||||
[goog.i18n.DateTimePatterns :as DateTimePatterns])
|
||||
(:import (goog.i18n DateTimeFormat)))
|
||||
|
||||
(defn web3 []
|
||||
(gobj/get js/window "web3"))
|
||||
|
||||
(defn input [val-ratom props]
|
||||
(fn []
|
||||
[:input
|
||||
|
@ -74,19 +74,17 @@
|
||||
|
||||
(defn tabs [mobile?]
|
||||
(let [user (rf/subscribe [:user])
|
||||
owner-bounties (rf/subscribe [:owner-bounties])
|
||||
current-page (rf/subscribe [:page])]
|
||||
(fn []
|
||||
(let [tabs (apply conj [[:bounties (str (when-not @user "Open ") "Bounties")]
|
||||
[:activity "Activity"]]
|
||||
(when @user
|
||||
[
|
||||
;; NOTE(oskarth) Disabling this as repo management happens through GH app
|
||||
#_[:repos "Repositories"]
|
||||
[:manage-payouts (str (when-not mobile? "Manage ") "Payouts")]
|
||||
(when (:status-team-member? @user)
|
||||
[:usage-metrics "Usage metrics"])]))]
|
||||
(fn tabs-render []
|
||||
(let [tabs [[:bounties (str (when-not @user "Open ") "Bounties")]
|
||||
[:activity "Activity"]
|
||||
(when (seq @owner-bounties)
|
||||
[:manage-payouts (str (when-not mobile? "Manage ") "Payouts")])
|
||||
(when (:status-team-member? @user)
|
||||
[:usage-metrics "Usage metrics"])]]
|
||||
(into [:div.ui.attached.tabular.menu.tiny]
|
||||
(for [[page caption] tabs]
|
||||
(for [[page caption] (remove nil? tabs)]
|
||||
(let [props {:class (str "ui item"
|
||||
(when (= @current-page page) " active"))
|
||||
:on-click #(commiteth.routes/nav! page)}]
|
||||
|
@ -12,7 +12,8 @@
|
||||
[akiroz.re-frame.storage
|
||||
:as rf-storage
|
||||
:refer [reg-co-fx!]]
|
||||
[commiteth.ui-model :as ui-model]))
|
||||
[commiteth.ui-model :as ui-model]
|
||||
[commiteth.common :as common]))
|
||||
|
||||
|
||||
(rf-storage/reg-co-fx! :commiteth-sob {:fx :store
|
||||
@ -49,7 +50,7 @@
|
||||
(reg-event-fx
|
||||
:initialize-web3
|
||||
(fn [{:keys [db]} [_]]
|
||||
(let [injected-web3 (-> js/window .-web3)
|
||||
(let [injected-web3 (common/web3)
|
||||
w3 (when (boolean injected-web3)
|
||||
(do
|
||||
(println "Using injected Web3 constructor with current provider")
|
||||
|
@ -78,10 +78,9 @@
|
||||
[:container
|
||||
[:div.ui.active.inverted.dimmer
|
||||
[:div.ui.text.loader "Loading"]]]
|
||||
(let [web3 (.-web3 js/window)
|
||||
bounties (vals @owner-bounties)]
|
||||
(let [bounties (vals @owner-bounties)]
|
||||
[:div.ui.container
|
||||
(when (nil? web3)
|
||||
(when (nil? (common/web3))
|
||||
[:div.ui.warning.message
|
||||
[:i.warning.icon]
|
||||
"To sign off claims, please view Status Open Bounty in Status, Mist or Metamask"])
|
||||
|
183
src/java/commiteth/eth/contracts/ERC20.java
Normal file
183
src/java/commiteth/eth/contracts/ERC20.java
Normal file
@ -0,0 +1,183 @@
|
||||
package commiteth.eth.contracts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import org.web3j.abi.EventEncoder;
|
||||
import org.web3j.abi.EventValues;
|
||||
import org.web3j.abi.TypeReference;
|
||||
import org.web3j.abi.datatypes.Address;
|
||||
import org.web3j.abi.datatypes.Event;
|
||||
import org.web3j.abi.datatypes.Function;
|
||||
import org.web3j.abi.datatypes.Type;
|
||||
import org.web3j.abi.datatypes.generated.Uint256;
|
||||
import org.web3j.crypto.Credentials;
|
||||
import org.web3j.protocol.Web3j;
|
||||
import org.web3j.protocol.core.DefaultBlockParameter;
|
||||
import org.web3j.protocol.core.methods.request.EthFilter;
|
||||
import org.web3j.protocol.core.methods.response.Log;
|
||||
import org.web3j.protocol.core.methods.response.TransactionReceipt;
|
||||
import org.web3j.tx.Contract;
|
||||
import org.web3j.tx.TransactionManager;
|
||||
import rx.Observable;
|
||||
import rx.functions.Func1;
|
||||
|
||||
/**
|
||||
* Auto generated code.<br>
|
||||
* <strong>Do not modify!</strong><br>
|
||||
* Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update.
|
||||
*
|
||||
* <p>Generated with web3j version 2.3.0.
|
||||
*/
|
||||
public final class ERC20 extends Contract {
|
||||
private static final String BINARY = "";
|
||||
|
||||
private ERC20(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
private ERC20(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public List<TransferEventResponse> getTransferEvents(TransactionReceipt transactionReceipt) {
|
||||
final Event event = new Event("Transfer",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
List<EventValues> valueList = extractEventParameters(event, transactionReceipt);
|
||||
ArrayList<TransferEventResponse> responses = new ArrayList<TransferEventResponse>(valueList.size());
|
||||
for (EventValues eventValues : valueList) {
|
||||
TransferEventResponse typedResponse = new TransferEventResponse();
|
||||
typedResponse.from = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.to = (Address) eventValues.getIndexedValues().get(1);
|
||||
typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0);
|
||||
responses.add(typedResponse);
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
public Observable<TransferEventResponse> transferEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
|
||||
final Event event = new Event("Transfer",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
|
||||
filter.addSingleTopic(EventEncoder.encode(event));
|
||||
return web3j.ethLogObservable(filter).map(new Func1<Log, TransferEventResponse>() {
|
||||
@Override
|
||||
public TransferEventResponse call(Log log) {
|
||||
EventValues eventValues = extractEventParameters(event, log);
|
||||
TransferEventResponse typedResponse = new TransferEventResponse();
|
||||
typedResponse.from = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.to = (Address) eventValues.getIndexedValues().get(1);
|
||||
typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0);
|
||||
return typedResponse;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<ApprovalEventResponse> getApprovalEvents(TransactionReceipt transactionReceipt) {
|
||||
final Event event = new Event("Approval",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
List<EventValues> valueList = extractEventParameters(event, transactionReceipt);
|
||||
ArrayList<ApprovalEventResponse> responses = new ArrayList<ApprovalEventResponse>(valueList.size());
|
||||
for (EventValues eventValues : valueList) {
|
||||
ApprovalEventResponse typedResponse = new ApprovalEventResponse();
|
||||
typedResponse.owner = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.spender = (Address) eventValues.getIndexedValues().get(1);
|
||||
typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0);
|
||||
responses.add(typedResponse);
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
public Observable<ApprovalEventResponse> approvalEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
|
||||
final Event event = new Event("Approval",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
|
||||
filter.addSingleTopic(EventEncoder.encode(event));
|
||||
return web3j.ethLogObservable(filter).map(new Func1<Log, ApprovalEventResponse>() {
|
||||
@Override
|
||||
public ApprovalEventResponse call(Log log) {
|
||||
EventValues eventValues = extractEventParameters(event, log);
|
||||
ApprovalEventResponse typedResponse = new ApprovalEventResponse();
|
||||
typedResponse.owner = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.spender = (Address) eventValues.getIndexedValues().get(1);
|
||||
typedResponse.value = (Uint256) eventValues.getNonIndexedValues().get(0);
|
||||
return typedResponse;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<TransactionReceipt> approve(Address spender, Uint256 value) {
|
||||
Function function = new Function("approve", Arrays.<Type>asList(spender, value), Collections.<TypeReference<?>>emptyList());
|
||||
return executeTransactionAsync(function);
|
||||
}
|
||||
|
||||
public Future<Uint256> totalSupply() {
|
||||
Function function = new Function("totalSupply",
|
||||
Arrays.<Type>asList(),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
return executeCallSingleValueReturnAsync(function);
|
||||
}
|
||||
|
||||
public Future<TransactionReceipt> transferFrom(Address from, Address to, Uint256 value) {
|
||||
Function function = new Function("transferFrom", Arrays.<Type>asList(from, to, value), Collections.<TypeReference<?>>emptyList());
|
||||
return executeTransactionAsync(function);
|
||||
}
|
||||
|
||||
public Future<Uint256> balanceOf(Address who) {
|
||||
Function function = new Function("balanceOf",
|
||||
Arrays.<Type>asList(who),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
return executeCallSingleValueReturnAsync(function);
|
||||
}
|
||||
|
||||
public Future<TransactionReceipt> transfer(Address to, Uint256 value) {
|
||||
Function function = new Function("transfer", Arrays.<Type>asList(to, value), Collections.<TypeReference<?>>emptyList());
|
||||
return executeTransactionAsync(function);
|
||||
}
|
||||
|
||||
public Future<Uint256> allowance(Address owner, Address spender) {
|
||||
Function function = new Function("allowance",
|
||||
Arrays.<Type>asList(owner, spender),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
|
||||
return executeCallSingleValueReturnAsync(function);
|
||||
}
|
||||
|
||||
public static Future<ERC20> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
|
||||
return deployAsync(ERC20.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue);
|
||||
}
|
||||
|
||||
public static Future<ERC20> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
|
||||
return deployAsync(ERC20.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue);
|
||||
}
|
||||
|
||||
public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new ERC20(contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new ERC20(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static class TransferEventResponse {
|
||||
public Address from;
|
||||
|
||||
public Address to;
|
||||
|
||||
public Uint256 value;
|
||||
}
|
||||
|
||||
public static class ApprovalEventResponse {
|
||||
public Address owner;
|
||||
|
||||
public Address spender;
|
||||
|
||||
public Uint256 value;
|
||||
}
|
||||
}
|
660
src/java/commiteth/eth/contracts/MultiSigTokenWallet.java
Normal file
660
src/java/commiteth/eth/contracts/MultiSigTokenWallet.java
Normal file
File diff suppressed because one or more lines are too long
111
src/java/commiteth/eth/contracts/Owned.java
Normal file
111
src/java/commiteth/eth/contracts/Owned.java
Normal file
@ -0,0 +1,111 @@
|
||||
package commiteth.eth.contracts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import org.web3j.abi.EventEncoder;
|
||||
import org.web3j.abi.EventValues;
|
||||
import org.web3j.abi.TypeReference;
|
||||
import org.web3j.abi.datatypes.Address;
|
||||
import org.web3j.abi.datatypes.Event;
|
||||
import org.web3j.abi.datatypes.Function;
|
||||
import org.web3j.abi.datatypes.Type;
|
||||
import org.web3j.crypto.Credentials;
|
||||
import org.web3j.protocol.Web3j;
|
||||
import org.web3j.protocol.core.DefaultBlockParameter;
|
||||
import org.web3j.protocol.core.methods.request.EthFilter;
|
||||
import org.web3j.protocol.core.methods.response.Log;
|
||||
import org.web3j.protocol.core.methods.response.TransactionReceipt;
|
||||
import org.web3j.tx.Contract;
|
||||
import org.web3j.tx.TransactionManager;
|
||||
import rx.Observable;
|
||||
import rx.functions.Func1;
|
||||
|
||||
/**
|
||||
* Auto generated code.<br>
|
||||
* <strong>Do not modify!</strong><br>
|
||||
* Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update.
|
||||
*
|
||||
* <p>Generated with web3j version 2.3.0.
|
||||
*/
|
||||
public final class Owned extends Contract {
|
||||
private static final String BINARY = "606060405260008054600160a060020a03191633600160a060020a0316179055341561002a57600080fd5b5b6101578061003a6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313af403581146100485780638da5cb5b14610069575b600080fd5b341561005357600080fd5b610067600160a060020a0360043516610098565b005b341561007457600080fd5b61007c61011c565b604051600160a060020a03909116815260200160405180910390f35b60005433600160a060020a039081169116146100b357610118565b600054600160a060020a0380831691167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405160405180910390a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b50565b600054600160a060020a0316815600a165627a7a723058206bbc12c5f2dde30ed4acaaf0df4c0bc44e5909ce3b8ab82da7f226137465b3fd0029";
|
||||
|
||||
private Owned(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
private Owned(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public List<NewOwnerEventResponse> getNewOwnerEvents(TransactionReceipt transactionReceipt) {
|
||||
final Event event = new Event("NewOwner",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList());
|
||||
List<EventValues> valueList = extractEventParameters(event, transactionReceipt);
|
||||
ArrayList<NewOwnerEventResponse> responses = new ArrayList<NewOwnerEventResponse>(valueList.size());
|
||||
for (EventValues eventValues : valueList) {
|
||||
NewOwnerEventResponse typedResponse = new NewOwnerEventResponse();
|
||||
typedResponse.old = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.current = (Address) eventValues.getIndexedValues().get(1);
|
||||
responses.add(typedResponse);
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
public Observable<NewOwnerEventResponse> newOwnerEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
|
||||
final Event event = new Event("NewOwner",
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
|
||||
Arrays.<TypeReference<?>>asList());
|
||||
EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
|
||||
filter.addSingleTopic(EventEncoder.encode(event));
|
||||
return web3j.ethLogObservable(filter).map(new Func1<Log, NewOwnerEventResponse>() {
|
||||
@Override
|
||||
public NewOwnerEventResponse call(Log log) {
|
||||
EventValues eventValues = extractEventParameters(event, log);
|
||||
NewOwnerEventResponse typedResponse = new NewOwnerEventResponse();
|
||||
typedResponse.old = (Address) eventValues.getIndexedValues().get(0);
|
||||
typedResponse.current = (Address) eventValues.getIndexedValues().get(1);
|
||||
return typedResponse;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<TransactionReceipt> setOwner(Address _new) {
|
||||
Function function = new Function("setOwner", Arrays.<Type>asList(_new), Collections.<TypeReference<?>>emptyList());
|
||||
return executeTransactionAsync(function);
|
||||
}
|
||||
|
||||
public Future<Address> owner() {
|
||||
Function function = new Function("owner",
|
||||
Arrays.<Type>asList(),
|
||||
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}));
|
||||
return executeCallSingleValueReturnAsync(function);
|
||||
}
|
||||
|
||||
public static Future<Owned> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
|
||||
return deployAsync(Owned.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue);
|
||||
}
|
||||
|
||||
public static Future<Owned> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
|
||||
return deployAsync(Owned.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue);
|
||||
}
|
||||
|
||||
public static Owned load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new Owned(contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static Owned load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||
return new Owned(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||
}
|
||||
|
||||
public static class NewOwnerEventResponse {
|
||||
public Address old;
|
||||
|
||||
public Address current;
|
||||
}
|
||||
}
|
315
src/java/commiteth/eth/contracts/TokenReg.java
Normal file
315
src/java/commiteth/eth/contracts/TokenReg.java
Normal file
File diff suppressed because one or more lines are too long
@ -34,5 +34,7 @@
|
||||
:email nil
|
||||
:avatar_url ""
|
||||
:address "address"
|
||||
:created nil}
|
||||
:created nil
|
||||
:welcome_email_sent 0
|
||||
:is_hidden_in_hunters false}
|
||||
(db/get-user t-conn {:id 1})))))
|
||||
|
@ -4,14 +4,20 @@
|
||||
|
||||
(deftest test-github-keywords
|
||||
(testing "Several keywords in mixed case"
|
||||
(let [res (set (extract-issue-number "body"
|
||||
(let [res (set (extract-issue-number "" "" "body"
|
||||
"Fixes #12 and cloSes #000028 and also resolved \n#32"))]
|
||||
(is (= #{12 28 32} res))))
|
||||
(testing "Ignoring big numbers and zeroes"
|
||||
(let [res (set (extract-issue-number "body"
|
||||
(let [res (set (extract-issue-number "" "" "body"
|
||||
"Fixes #298374298229087345 and closes #0xFFEF"))]
|
||||
(is (= #{} res))))
|
||||
(testing "Consider both body and title"
|
||||
(let [res (set (extract-issue-number "Fixes #1"
|
||||
(let [res (set (extract-issue-number "" ""
|
||||
"Fixes #1"
|
||||
"Fixes #2"))]
|
||||
(is (= #{1 2} res))))
|
||||
(testing "Use issue URL instead of number"
|
||||
(let [res (set (extract-issue-number "status-im" "status-react"
|
||||
"Fixes https://github.com/status-im/status-react/issues/1"
|
||||
"Fixes https://github.com/status-im/status-react/issues/2"))]
|
||||
(is (= #{1 2} res)))))
|
||||
|
@ -17,12 +17,14 @@
|
||||
(if (< (System/currentTimeMillis) end-time)
|
||||
(recur)))))))
|
||||
|
||||
;; deploys a multisig and gets it's address. assumes test environment configured correctly (access to running geth, eth wallet, password etc)
|
||||
;; deploys a multisig and gets it's address
|
||||
;; assumes test environment configured correctly
|
||||
;; (eth wallet with some eth, password etc)
|
||||
(deftest test-deploy
|
||||
(testing "Deploying a multisig"
|
||||
(let [tx-id (multisig/deploy-multisig OWNER_ADDRESS)
|
||||
tx-receipt (wait-for (fn [] (eth/get-transaction-receipt tx-id)))
|
||||
addr (-> tx-receipt
|
||||
(multisig/find-created-multisig-address))]
|
||||
(println "Created multisig address" addr)
|
||||
(is (not-empty addr)))))
|
||||
(println "WARN multisig deployment test currently disabled as it requires gas")
|
||||
#_(let [tx-id (multisig/deploy-multisig OWNER_ADDRESS)
|
||||
tx-receipt (wait-for (fn [] (eth/get-transaction-receipt tx-id)))
|
||||
addr (multisig/find-created-multisig-address tx-receipt)]
|
||||
(println "Created multisig address" addr)
|
||||
(is (not-empty addr)))))
|
||||
|
@ -7,15 +7,15 @@
|
||||
(testing "Basic fixes case from PR body"
|
||||
(let [title "foo"
|
||||
body "fixes #123"]
|
||||
(is (= '(123) (webhooks/extract-issue-number body title)))))
|
||||
(is (= '(123) (webhooks/extract-issue-number "" "" body title)))))
|
||||
(testing "Basic fixes case from PR title"
|
||||
(let [title "My title (fixes: #123)"
|
||||
body "no use for a body"]
|
||||
(is (= '(123) (webhooks/extract-issue-number body title)))))
|
||||
(is (= '(123) (webhooks/extract-issue-number "" "" body title)))))
|
||||
(testing "Commented issue number ignored in PR body"
|
||||
(let [title "foo"
|
||||
body "
|
||||
fixes #123
|
||||
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
||||
"]
|
||||
(is (= '(123) (webhooks/extract-issue-number body title))))))
|
||||
(is (= '(123) (webhooks/extract-issue-number "" "" body title))))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user