From 6b6955662921d3cbb2e9e616b06cf4689d1dc376 Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 16:55:23 +0300 Subject: [PATCH 1/6] open tendermint RPC port in docker --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 6f867fc0b..b1d7bbdb9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: - ~/.tendermint:/tendermint ports: - "46656:46656" + - "46657:46657" restart: always healthcheck: test: ["CMD", "curl", "-f", "http://localhost:46657/health"] From fe162e5d3b8c62e27eab297f85e9f40756392400 Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 17:01:26 +0300 Subject: [PATCH 2/6] add height specification to api --- api/api.go | 14 ++++++++++++++ api/balance.go | 4 +++- api/candidate.go | 11 ++--------- api/coin_info.go | 4 +++- api/estimate_coin_exchange_return.go | 10 ++++++---- api/transaction_count.go | 4 +++- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/api/api.go b/api/api.go index 4830082db..7b26df362 100644 --- a/api/api.go +++ b/api/api.go @@ -12,6 +12,8 @@ import ( "github.com/tendermint/tendermint/rpc/core/types" "github.com/tendermint/tendermint/rpc/lib/client" "time" + "github.com/MinterTeam/minter-go-node/core/state" + "strconv" ) var ( @@ -68,3 +70,15 @@ type Response struct { Result interface{} `json:"result,omitempty"` Log string `json:"log,omitempty"` } + +func GetStateForRequest(r *http.Request) *state.StateDB { + height, _ := strconv.Atoi(r.URL.Query().Get("height")) + + cState := blockchain.CurrentState() + + if height > 0 { + cState, _ = blockchain.GetStateForHeight(height) + } + + return cState +} \ No newline at end of file diff --git a/api/balance.go b/api/balance.go index ad55b3f1c..8bf56bf96 100644 --- a/api/balance.go +++ b/api/balance.go @@ -16,11 +16,13 @@ type BalanceRequest struct { func GetBalance(w http.ResponseWriter, r *http.Request) { + cState := GetStateForRequest(r) + vars := mux.Vars(r) address := types.HexToAddress(vars["address"]) balance := BalanceResponse{} - balances := blockchain.CurrentState().GetBalances(address) + balances := cState.GetBalances(address) for k, v := range balances.Data { balance[k.String()] = v.String() diff --git a/api/candidate.go b/api/candidate.go index 3caa2d361..c99eb45ee 100644 --- a/api/candidate.go +++ b/api/candidate.go @@ -7,8 +7,7 @@ import ( "github.com/MinterTeam/minter-go-node/core/types" "github.com/gorilla/mux" "net/http" - "strconv" - "strings" + "strings" ) func GetCandidate(w http.ResponseWriter, r *http.Request) { @@ -16,13 +15,7 @@ func GetCandidate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) pubkey := types.Hex2Bytes(strings.TrimLeft(vars["pubkey"], "Mx")) - height, _ := strconv.Atoi(r.URL.Query().Get("height")) - - cState := blockchain.CurrentState() - - if height > 0 { - cState, _ = blockchain.GetStateForHeight(height) - } + cState := GetStateForRequest(r) candidate := cState.GetStateCandidate(pubkey) diff --git a/api/coin_info.go b/api/coin_info.go index d3462ac7c..326dfa5a3 100644 --- a/api/coin_info.go +++ b/api/coin_info.go @@ -19,6 +19,8 @@ type CoinInfoResponse struct { func GetCoinInfo(w http.ResponseWriter, r *http.Request) { + cState := GetStateForRequest(r) + vars := mux.Vars(r) symbol := vars["symbol"] @@ -26,7 +28,7 @@ func GetCoinInfo(w http.ResponseWriter, r *http.Request) { copy(coinSymbol[:], []byte(symbol)) - coin := blockchain.CurrentState().GetStateCoin(coinSymbol).Data() + coin := cState.GetStateCoin(coinSymbol).Data() w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) diff --git a/api/estimate_coin_exchange_return.go b/api/estimate_coin_exchange_return.go index 3a3bf5d8f..222667b1f 100644 --- a/api/estimate_coin_exchange_return.go +++ b/api/estimate_coin_exchange_return.go @@ -10,6 +10,8 @@ import ( func EstimateCoinExchangeReturn(w http.ResponseWriter, r *http.Request) { + cState := GetStateForRequest(r) + query := r.URL.Query() fromCoin := query.Get("from_coin") toCoin := query.Get("to_coin") @@ -24,14 +26,14 @@ func EstimateCoinExchangeReturn(w http.ResponseWriter, r *http.Request) { var result *big.Int if fromCoinSymbol == blockchain.BaseCoin { - coin := blockchain.CurrentState().GetStateCoin(toCoinSymbol).Data() + coin := cState.GetStateCoin(toCoinSymbol).Data() result = formula.CalculatePurchaseReturn(coin.Volume, coin.ReserveBalance, coin.Crr, value) } else if toCoinSymbol == blockchain.BaseCoin { - coin := blockchain.CurrentState().GetStateCoin(fromCoinSymbol).Data() + coin := cState.GetStateCoin(fromCoinSymbol).Data() result = formula.CalculateSaleReturn(coin.Volume, coin.ReserveBalance, coin.Crr, value) } else { - coinFrom := blockchain.CurrentState().GetStateCoin(fromCoinSymbol).Data() - coinTo := blockchain.CurrentState().GetStateCoin(toCoinSymbol).Data() + coinFrom := cState.GetStateCoin(fromCoinSymbol).Data() + coinTo := cState.GetStateCoin(toCoinSymbol).Data() val := formula.CalculateSaleReturn(coinFrom.Volume, coinFrom.ReserveBalance, coinFrom.Crr, value) result = formula.CalculatePurchaseReturn(coinTo.Volume, coinTo.ReserveBalance, coinTo.Crr, val) diff --git a/api/transaction_count.go b/api/transaction_count.go index 549a0994b..33f67538e 100644 --- a/api/transaction_count.go +++ b/api/transaction_count.go @@ -11,6 +11,8 @@ type TransactionCountResponse uint64 func GetTransactionCount(w http.ResponseWriter, r *http.Request) { + cState := GetStateForRequest(r) + vars := mux.Vars(r) address := types.HexToAddress(vars["address"]) @@ -19,6 +21,6 @@ func GetTransactionCount(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(Response{ Code: 0, - Result: blockchain.CurrentState().GetNonce(address), + Result: cState.GetNonce(address), }) } From 727806350c1df481a73f4f764c3966d1cb186085 Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 17:01:57 +0300 Subject: [PATCH 3/6] run fmt --- api/api.go | 6 +++--- api/candidate.go | 2 +- api/estimate_coin_exchange_return.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/api.go b/api/api.go index 7b26df362..b8c4229fe 100644 --- a/api/api.go +++ b/api/api.go @@ -9,11 +9,11 @@ import ( "github.com/MinterTeam/minter-go-node/cmd/utils" "github.com/MinterTeam/minter-go-node/core/minter" + "github.com/MinterTeam/minter-go-node/core/state" "github.com/tendermint/tendermint/rpc/core/types" "github.com/tendermint/tendermint/rpc/lib/client" - "time" - "github.com/MinterTeam/minter-go-node/core/state" "strconv" + "time" ) var ( @@ -81,4 +81,4 @@ func GetStateForRequest(r *http.Request) *state.StateDB { } return cState -} \ No newline at end of file +} diff --git a/api/candidate.go b/api/candidate.go index c99eb45ee..f1d31482e 100644 --- a/api/candidate.go +++ b/api/candidate.go @@ -7,7 +7,7 @@ import ( "github.com/MinterTeam/minter-go-node/core/types" "github.com/gorilla/mux" "net/http" - "strings" + "strings" ) func GetCandidate(w http.ResponseWriter, r *http.Request) { diff --git a/api/estimate_coin_exchange_return.go b/api/estimate_coin_exchange_return.go index 222667b1f..5b9e7d192 100644 --- a/api/estimate_coin_exchange_return.go +++ b/api/estimate_coin_exchange_return.go @@ -11,7 +11,7 @@ import ( func EstimateCoinExchangeReturn(w http.ResponseWriter, r *http.Request) { cState := GetStateForRequest(r) - + query := r.URL.Query() fromCoin := query.Get("from_coin") toCoin := query.Get("to_coin") From ba1b7e355b18c83e9eebb1aac74ef6615fc376da Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 17:06:01 +0300 Subject: [PATCH 4/6] add json marshalling to transactions --- core/transaction/transaction.go | 36 +++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/core/transaction/transaction.go b/core/transaction/transaction.go index 893572f3c..36979897c 100644 --- a/core/transaction/transaction.go +++ b/core/transaction/transaction.go @@ -141,8 +141,16 @@ type DeclareCandidacyData struct { func (s DeclareCandidacyData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - // TODO: complete marshal function - }{}) + Address types.Address + PubKey string + Commission uint + Stake string + }{ + Address: s.Address, + PubKey: fmt.Sprintf("Mp%x", s.PubKey), + Commission: s.Commission, + Stake: s.Stake.String(), + }) } type DelegateData struct { @@ -152,8 +160,12 @@ type DelegateData struct { func (s DelegateData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - // TODO: complete marshal function - }{}) + PubKey string + Stake string + }{ + PubKey: fmt.Sprintf("Mp%x", s.PubKey), + Stake: s.Stake.String(), + }) } type RedeemCheckData struct { @@ -163,8 +175,12 @@ type RedeemCheckData struct { func (s RedeemCheckData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - // TODO: complete marshal function - }{}) + RawCheck string + Proof string + }{ + RawCheck: fmt.Sprintf("Mc%x", s.RawCheck), + Proof: fmt.Sprintf("%x", s.Proof), + }) } type UnbondData struct { @@ -174,8 +190,12 @@ type UnbondData struct { func (s UnbondData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - // TODO: complete marshal function - }{}) + PubKey string + Value string + }{ + PubKey: fmt.Sprintf("Mp%x", s.PubKey), + Value: s.Value.String(), + }) } func (tx *Transaction) Serialize() ([]byte, error) { From b33f4580f349decf45f1c27c690b12855b591a58 Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 17:54:40 +0300 Subject: [PATCH 5/6] error handling in api --- api/block.go | 12 ++++++++---- api/transaction.go | 12 ++++++++---- api/transactions.go | 14 +++++++++----- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/api/block.go b/api/block.go index 2dfaf5231..ec9f15741 100644 --- a/api/block.go +++ b/api/block.go @@ -18,13 +18,17 @@ func Block(w http.ResponseWriter, r *http.Request) { "height": height, }, result) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if err != nil { - panic(err) + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(Response{ + Code: 0, + Result: err.Error(), + }) + return } - // TODO: check error - - w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(Response{ diff --git a/api/transaction.go b/api/transaction.go index 230c41a78..1e1660f74 100644 --- a/api/transaction.go +++ b/api/transaction.go @@ -30,13 +30,17 @@ func Transaction(w http.ResponseWriter, r *http.Request) { "hash": decoded, }, result) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if err != nil { - panic(err) + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(Response{ + Code: 0, + Result: err.Error(), + }) + return } - // TODO: check error - - w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(Response{ diff --git a/api/transactions.go b/api/transactions.go index 5a9557b8e..412695217 100644 --- a/api/transactions.go +++ b/api/transactions.go @@ -58,11 +58,18 @@ func Transactions(w http.ResponseWriter, r *http.Request) { "per_page": 100, }, rpcResult) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if err != nil { - panic(err) + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(Response{ + Code: 0, + Result: err.Error(), + }) + return } - // TODO: check error + w.WriteHeader(http.StatusOK) result := make([]TransactionResponse, len(rpcResult.Txs)) @@ -92,9 +99,6 @@ func Transactions(w http.ResponseWriter, r *http.Request) { } } - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) - err = json.NewEncoder(w).Encode(Response{ Code: 0, Result: result, From 0e9a7d14a9f7b8d1251022b4b606af92a0748170 Mon Sep 17 00:00:00 2001 From: Daniil Lashin Date: Wed, 13 Jun 2018 18:04:53 +0300 Subject: [PATCH 6/6] update install instructions --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bc2393aca..c14319c5d 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,55 @@ _NOTE: This is alpha software. Please contact us if you intend to run it in prod You'll need [docker](https://docker.com/) and [docker compose](https://docs.docker.com/compose/) installed. Clone Minter to your machine -``` -git clone https://github.com/MinterTeam/minter-go-node.git -cd minter +```bash +$ git clone https://github.com/MinterTeam/minter-go-node.git +$ cd minter-go-node ``` Prepare configs -``` -mkdir -p ~/.tendermint/data -mkdir -p ~/.minter/data +```bash +$ mkdir -p ~/.tendermint/data +$ mkdir -p ~/.minter/data -chmod -R 0777 ~/.tendermint -chmod -R 0777 ~/.minter +$ chmod -R 0777 ~/.tendermint +$ chmod -R 0777 ~/.minter -cp -R networks/testnet/ ~/.tendermint/config +$ cp -R networks/testnet/ ~/.tendermint/config ``` Start Minter +```bash +$ docker-compose up ``` -docker-compose up + +## Build and run manually + +Install [Tendermint 0.20](https://github.com/tendermint/tendermint/blob/master/docs/install.rst) + +```bash +$ mkdir $GOPATH/src/github.com/MinterTeam +$ cd $GOPATH/src/github.com/MinterTeam +$ git clone https://github.com/MinterTeam/minter-go-node.git + +$ cd minter-go-node +$ make get_tools +$ make get_vendor_deps + +$ make install + +$ mkdir -p ~/.tendermint/data +$ mkdir -p ~/.minter/data + +$ cp -R networks/testnet/ ~/.tendermint/config +``` + +Run Tendermint +```bash +$ tendermint node ``` + +Run Minter + +```bash +$ minter +``` \ No newline at end of file