mirror of
https://github.com/status-im/open-bounty.git
synced 2025-02-26 16:10:50 +00:00
Merge branch 'develop' of https://github.com/status-im/open-bounty into 193-hide-myself
This commit is contained in:
commit
38ecb91710
28
CONTRIBUTING.md
Normal file
28
CONTRIBUTING.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
This document describes process guidelines to be followed when contributing to Status Open Bounty repo.
|
||||||
|
|
||||||
|
First, make sure to familiarize yourself with the [README](https://github.com/status-im/open-bounty/blob/develop/README.md) and [Testing](https://github.com/status-im/open-bounty/blob/develop/doc/testing.md) documents in order to setup the project properly.
|
||||||
|
|
||||||
|
# Issues
|
||||||
|
- Issues should have type, priority and size (difficulty) assigned via corresponding labels
|
||||||
|
- Issue descriptions should include the following fields:
|
||||||
|
- **Summary**
|
||||||
|
- **Type**
|
||||||
|
- (*Features or enhancements only*) **User story**
|
||||||
|
- (*Bugs only*) **Expected behavior**
|
||||||
|
- (*Bugs only*) **Actual behavior**
|
||||||
|
- **Additional information**
|
||||||
|
|
||||||
|
# Pull requests
|
||||||
|
- Branch names should include:
|
||||||
|
- prefixes indicating issue type (`bug`, `feature`, `doc`, `test`)
|
||||||
|
- short description in lisp-case
|
||||||
|
- and include associated issue number
|
||||||
|
|
||||||
|
For instance, `bug/messy-problem-#1234`
|
||||||
|
- Start the title of the PR with [FIX #NNN], where #NNN is the issue number
|
||||||
|
- Always include `Status:` in the PR description to indicate whether PR is `WIP` or `Finished`.
|
||||||
|
- PR description should include the following sections:
|
||||||
|
- **Summary**
|
||||||
|
- **Notes**
|
||||||
|
- **Status**
|
||||||
|
- Merges into `develop` branch should be approved by at least 1 person, into `master` - by 2.
|
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
@ -25,7 +25,11 @@ def dockerreponame = "statusim/openbounty-app"
|
|||||||
}
|
}
|
||||||
|
|
||||||
stage('Deploy') {
|
stage('Deploy') {
|
||||||
|
if ( currentBuild.rawBuild.getCauses()[0].toString().contains('UserIdCause') ){
|
||||||
build job: 'status-openbounty/openbounty-cluster', parameters: [[$class: 'StringParameterValue', name: 'DEPLOY_ENVIRONMENT', value: "dev"], [$class: 'StringParameterValue', name: 'BRANCH', value: env.BRANCH_NAME]]
|
build job: 'status-openbounty/openbounty-cluster', parameters: [[$class: 'StringParameterValue', name: 'DEPLOY_ENVIRONMENT', value: "dev"], [$class: 'StringParameterValue', name: 'BRANCH', value: env.BRANCH_NAME]]
|
||||||
|
} else {
|
||||||
|
echo "No deployment on automatic trigger, go to Jenkins and push build button to deliver it."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
63
README.md
63
README.md
@ -13,6 +13,15 @@ Live testnet (Ropsten) version:
|
|||||||
https://openbounty.status.im:444
|
https://openbounty.status.im:444
|
||||||
The `develop` branch is automatically deployed here.
|
The `develop` branch is automatically deployed here.
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
- [Prerequisites](#prerequisites)
|
||||||
|
- [Application config](#application-config)
|
||||||
|
- [GitHub integration](#github-integration)
|
||||||
|
- [Running](#running)
|
||||||
|
- [Testing](#testing)
|
||||||
|
- [More info](#more-info)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@ -23,35 +32,29 @@ You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above
|
|||||||
Make sure you install [PostgreSQL](https://www.postgresql.org/) and properly set it up:
|
Make sure you install [PostgreSQL](https://www.postgresql.org/) and properly set it up:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo -u postgres psql -c "CREATE USER commiteth WITH PASSWORD 'commiteth';"
|
psql postgres -c "CREATE USER commiteth WITH PASSWORD 'commiteth';"
|
||||||
sudo -u postgres createdb commiteth
|
psql postgres -c "CREATE DATABASE commiteth;"
|
||||||
```
|
|
||||||
|
|
||||||
## Running
|
|
||||||
|
|
||||||
Launch following commands each in its own shell:
|
|
||||||
|
|
||||||
```
|
|
||||||
lein run
|
|
||||||
lein figwheel
|
|
||||||
lein less auto
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Make sure you install [PostgreSQL](https://www.postgresql.org/) and properly set it up:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo -u postgres psql -c "CREATE USER commiteth WITH PASSWORD 'commiteth';"
|
|
||||||
sudo -u postgres createdb commiteth
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### solc
|
### solc
|
||||||
|
|
||||||
Solidity compiler [0.4.15](https://github.com/ethereum/solidity/releases/tag/v0.4.15) is required and needs to be in $PATH.
|
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
|
||||||
|
|
||||||
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.
|
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
|
||||||
|
```
|
||||||
|
|
||||||
## Application config
|
## Application config
|
||||||
|
|
||||||
@ -88,20 +91,32 @@ Follow the steps [here](https://developer.github.com/apps/building-github-apps/c
|
|||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
Lauch a local geth node with the bot account unlocked:
|
### Geth
|
||||||
|
Launch a local geth node with the bot account unlocked:
|
||||||
|
|
||||||
```
|
```
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
geth --fast --testnet --cache=1024 --datadir=$HOME/.ropsten --verbosity 4 --port 50100 --ipcpath ~/.ropsten/geth.ipc --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --rpcapi db,eth,net,web3,personal --rpccorsdomain "https://wallet.ethereum.org" --unlock "0xYOUR_ADDR" --password <(echo "YOUR_PASSPHRASE")
|
geth --fast --testnet --cache=1024 --datadir=$HOME/.ropsten --verbosity 4 --port 50100 --ipcpath ~/.ropsten/geth.ipc --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --rpcapi db,eth,net,web3,personal --rpccorsdomain "https://wallet.ethereum.org" --unlock "0xYOUR_ADDR" --password <(echo "YOUR_PASSPHRASE")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### CSS auto-compilation
|
||||||
Launch the following command in a separate shell:
|
Launch the following command in a separate shell:
|
||||||
|
|
||||||
```
|
```
|
||||||
lein less auto
|
lein less auto
|
||||||
```
|
```
|
||||||
|
|
||||||
Next you want to start a REPL on the backend and the frontend.
|
### Clojure app without REPL
|
||||||
|
Launch following commands each in its own shell:
|
||||||
|
|
||||||
|
```
|
||||||
|
lein run
|
||||||
|
lein figwheel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clojure app with REPL
|
||||||
|
|
||||||
|
You'll have to start a REPL on the backend and the frontend.
|
||||||
|
|
||||||
```
|
```
|
||||||
lein repl
|
lein repl
|
||||||
@ -170,8 +185,8 @@ Landing page is static and different CSS and JS due to time constraints.
|
|||||||
This copies over necessary artifacts to `resources` dir.
|
This copies over necessary artifacts to `resources` dir.
|
||||||
|
|
||||||
|
|
||||||
### Troubleshooting
|
## More info
|
||||||
See the [Cookbook](doc/cookbook.md).
|
Detailed information on code structure, troubleshooting, etc. can be found [here](doc/README.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
7
doc/README.md
Normal file
7
doc/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Table of contents
|
||||||
|
|
||||||
|
- [Testing guide](doc/testing.md)
|
||||||
|
- [Troubleshooting](doc/cookbook.md)
|
||||||
|
- [Deployment flow](doc/deployment_flow.md)
|
||||||
|
- [Payout flow](doc/payout_flow.md)
|
||||||
|
- [Common sync issues](doc/sync_issues.md)
|
16
doc/deployment_flow.md
Normal file
16
doc/deployment_flow.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Deployment flow
|
||||||
|
|
||||||
|
This briefly describes events that occur when an issue is labeled as bounty and a new contract has to be deployed.
|
||||||
|
|
||||||
|
1. Issue is labeled
|
||||||
|
2. Event is received via GitHub App webhook
|
||||||
|
3. Contract is deployed
|
||||||
|
4. GitHub issue comment "Deploying contract..." is posted
|
||||||
|
5. `transaction_hash` is stored in the `issues` table
|
||||||
|
|
||||||
|
The following items execute in scheduler threads that run each minute, so up to 60 sec delay can be expected.
|
||||||
|
|
||||||
|
6. `update-issue-contract-address` scheduler thread fetches transaction receipt, updates `contract_address` and updates GitHub comment with a new image and current balance
|
||||||
|
7. `deploy-pending-contracts` scheduler thread checks if there are issues that did not have corresponding contracts deployed and attempts to redeploy
|
||||||
|
8. `update-balances` scheduler thread checks balances and updates GitHub comment accordingly
|
||||||
|
9. `update-contract-internal-balances` scheduler threads updates internal ERC20 token balances for all deployed contracts. This is required by current contract code
|
57
doc/payout_flow.md
Normal file
57
doc/payout_flow.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Payout flow
|
||||||
|
|
||||||
|
This describes the sequence of events happening once a PR for an issue with a bounty was merged by repo maintainer.
|
||||||
|
|
||||||
|
### Quick info on transaction hashes
|
||||||
|
In the sequence described below, several types of hashes are used. SOB checks presence of different hashes on records in the `issues` table to decide which action to take on an issue and associated contract. These hashes are:
|
||||||
|
- `transaction_hash`: set when contract is deployed to the labeled issue
|
||||||
|
- `execute_hash`: set when PR for an issue with a bounty was merged
|
||||||
|
- `confirm_hash`: fetched from receipt from transaction invoked in previous step
|
||||||
|
- `payout_hash`: set when payout was confirmed via `Manage Payouts`
|
||||||
|
|
||||||
|
The event flow is given below. For the bounty to be paid, each issue has to go through the steps in given order.
|
||||||
|
|
||||||
|
### 1. PR closed and merged
|
||||||
|
- app receives notification via GitHub App webhook (endpoint: `/webhook-app`)
|
||||||
|
- `handle-claim` fn is invoked which will:
|
||||||
|
- save PR in the `pull_requests` DB table, where state=1 for merged PRs
|
||||||
|
- update issue in the DB with commit SHA, if PR was merged
|
||||||
|
|
||||||
|
Afterwards two interleaving sequences of actions come into play: scheduler threads and manual user interaction in the `Manage Payouts` tab.
|
||||||
|
|
||||||
|
### 2. `self-sign-bounty` scheduler thread
|
||||||
|
- input query name: `pending-bounties`. This selects pending bounties (where `execute_hash` is nil and `commit_sha` is set)
|
||||||
|
- execute payout transactions
|
||||||
|
- store `execute_hash` and `winner_login` in `issues` DB table
|
||||||
|
- update GitHub comment to "Pending maintainer confirmation"
|
||||||
|
### 3. `update-confirm-hash` scheduler thread
|
||||||
|
- input query name: `pending-payouts`. This selects bounties with `execute_hash` set and no `confirm_hash`
|
||||||
|
- fetch `confirm_hash` from transaction receipt
|
||||||
|
- store `confirm_hash` in `issues` DB table
|
||||||
|
|
||||||
|
### 4. Manage Payouts view
|
||||||
|
In order to confirm a payout, following conditions have to be met for an issue:
|
||||||
|
- it is merged
|
||||||
|
- not paid yet (meaning its `payout_hash` is nil)
|
||||||
|
- not being confirmed at the moment (`:confirming?` flag is true)
|
||||||
|
OR
|
||||||
|
- already confirmed by a scheduler thread(`confirm_hash` is not nil)
|
||||||
|
|
||||||
|
Note that `confirm_hash` issue field and confirmation action in the UI are different things, albeit identically named. In order to confirm a payout from the UI, `confirm_hash` has to be already set by scheduler thread (see above).
|
||||||
|
|
||||||
|
Payout confirmation action results in a `:confirm-payout` event. Its handler will
|
||||||
|
- use `confirm_hash` to construct transaction payload
|
||||||
|
- set `:confirming?` flag to `true`
|
||||||
|
- execute `confirmTransaction()` call
|
||||||
|
- pass transaction callback to `confirmTransaction()`. Once invoked, the callback will:
|
||||||
|
- get `payout_hash` passed as an argument
|
||||||
|
- dispatch `:save-payout-hash` event. Its handler will:
|
||||||
|
- POST to /api/user/bounty/%s/payout
|
||||||
|
- This will update `payout_hash` in `issues` DB table
|
||||||
|
- if POST is successful, dispatch `:payout-confirmed`
|
||||||
|
- `:payout-confirmed` will update `:confirmed?` to `true` and remove `:confirming?` flag
|
||||||
|
|
||||||
|
### 5. `update-payout-receipt` scheduler thread
|
||||||
|
- input query name: `confirmed-payouts`. This selects confirmed payouts (the ones that have `payout_hash` and do not have `payout_receipt` set)
|
||||||
|
- store `payout_receipt` in `issues` DB table
|
||||||
|
- and update GitHub comment to "Paid to:..."
|
11
doc/sync_issues.md
Normal file
11
doc/sync_issues.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Common sync issues
|
||||||
|
|
||||||
|
- Repo rename. Related issue: https://github.com/status-im/open-bounty/issues/219.
|
||||||
|
- Transaction callback not executed, hence payout-hash not set.
|
||||||
|
- App downtime, multiple GitHub App deliveries failing. These can be afterwards replayed from GitHub App's Advanced tab.
|
||||||
|
- Geth issue. Not solvable on app end, Geth restart usually fixes these.
|
||||||
|
- Bot out of gas. Relevant issue: https://github.com/status-im/open-bounty/issues/195.
|
||||||
|
- Sometimes repos are disabled in DB (state=0), probably only happens to repos that were added earlier through OAuth App.
|
||||||
|
- PRs might end up in state=0 (opened) instead of state=1(merged), if PR did not have a proper text ("Fixes #..."). This one needs more investigation and more cases to reproduce.
|
||||||
|
- Sometimes contract_address cannot be fetched for a long period of time.
|
||||||
|
|
@ -4,6 +4,7 @@
|
|||||||
(def default-db
|
(def default-db
|
||||||
{:page :bounties
|
{:page :bounties
|
||||||
:user nil
|
:user nil
|
||||||
|
:user-profile-loaded? false
|
||||||
:repos-loading? false
|
:repos-loading? false
|
||||||
:repos {}
|
:repos {}
|
||||||
:activity-feed-loading? false
|
:activity-feed-loading? false
|
||||||
|
@ -224,7 +224,8 @@
|
|||||||
:set-user-profile
|
:set-user-profile
|
||||||
(fn [{:keys [db]} [_ user-profile]]
|
(fn [{:keys [db]} [_ user-profile]]
|
||||||
{:db
|
{:db
|
||||||
(assoc db :user (:user user-profile))
|
(assoc db :user (:user user-profile)
|
||||||
|
:user-profile-loaded? true)
|
||||||
:dispatch-n [[:load-user-repos]
|
:dispatch-n [[:load-user-repos]
|
||||||
[:load-owner-bounties]]}))
|
[:load-owner-bounties]]}))
|
||||||
|
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
(fn [db _]
|
(fn [db _]
|
||||||
(:user db)))
|
(:user db)))
|
||||||
|
|
||||||
|
(reg-sub
|
||||||
|
:user-profile-loaded?
|
||||||
|
(fn [db _]
|
||||||
|
(:user-profile-loaded? db)))
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:repos-loading?
|
:repos-loading?
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
|
@ -87,10 +87,12 @@
|
|||||||
::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options
|
::bounty-filter-type.category ::bounty-filter-type-category|multiple-dynamic-options
|
||||||
::bounty-filter-type.re-frame-subs-key-for-options :commiteth.subscriptions/open-bounties-currencies
|
::bounty-filter-type.re-frame-subs-key-for-options :commiteth.subscriptions/open-bounties-currencies
|
||||||
::bounty-filter-type.predicate (fn [filter-value bounty]
|
::bounty-filter-type.predicate (fn [filter-value bounty]
|
||||||
(and (or (not-any? #{"ETH"} filter-value)
|
(or (and (contains? #{"ETH"} filter-value)
|
||||||
(< 0 (:balance-eth bounty)))
|
(< 0 (:balance-eth bounty)))
|
||||||
(set/subset? (->> filter-value (remove #{"ETH"}) set)
|
(not-empty
|
||||||
(-> bounty :tokens keys set))))}
|
(set/intersection
|
||||||
|
(->> filter-value (remove #{"ETH"}) set)
|
||||||
|
(-> bounty :tokens keys set)))))}
|
||||||
|
|
||||||
::bounty-filter-type|date
|
::bounty-filter-type|date
|
||||||
{::bounty-filter-type.name "Date"
|
{::bounty-filter-type.name "Date"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[reagent.crypt :as crypt]
|
[reagent.crypt :as crypt]
|
||||||
[cljs-web3.eth :as web3-eth]))
|
[cljs-web3.eth :as web3-eth]))
|
||||||
|
|
||||||
(defn update-address-page []
|
(defn update-address-page-contents []
|
||||||
(let [db (rf/subscribe [:db])
|
(let [db (rf/subscribe [:db])
|
||||||
updating-user (rf/subscribe [:get-in [:updating-user]])
|
updating-user (rf/subscribe [:get-in [:updating-user]])
|
||||||
address (r/atom @(rf/subscribe [:get-in [:user :address]]))
|
address (r/atom @(rf/subscribe [:get-in [:user :address]]))
|
||||||
@ -55,6 +55,12 @@
|
|||||||
:class (str "ui button small update-address-button"
|
:class (str "ui button small update-address-button"
|
||||||
(when @updating-user
|
(when @updating-user
|
||||||
" busy loading"))})
|
" busy loading"))})
|
||||||
"UPDATE"]
|
"UPDATE"]]]))))
|
||||||
|
|
||||||
]]))))
|
(defn update-address-page []
|
||||||
|
(let [loaded? @(rf/subscribe [:user-profile-loaded?])]
|
||||||
|
(if loaded?
|
||||||
|
[update-address-page-contents]
|
||||||
|
[:div.view-loading-container
|
||||||
|
[:div.ui.active.inverted.dimmer
|
||||||
|
[:div.ui.text.loader.view-loading-label "Loading"]]])))
|
||||||
|
@ -457,6 +457,8 @@ label[for="input-hidden"] {
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
margin: 8px 12px;
|
margin: 8px 12px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user