Skip to content

Commit

Permalink
Merge branch 'development' into deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Jan 14, 2020
2 parents 2d0d0f0 + 8d87c24 commit 9d8013a
Show file tree
Hide file tree
Showing 541 changed files with 34,692 additions and 12,105 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ clean-test:
go clean -testcache ./...

clean: clean-test
go clean -cache ./...
go clean ./...

test: clean-test
Expand Down
2 changes: 1 addition & 1 deletion api/address/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func GetBalance(c *gin.Context) {
return
}

c.JSON(http.StatusOK, gin.H{"balance": balance})
c.JSON(http.StatusOK, gin.H{"balance": balance.String()})
}

func accountResponseFromBaseAccount(address string, account *state.Account) accountResponse {
Expand Down
19 changes: 14 additions & 5 deletions api/address/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ type GeneralResponse struct {
//addressResponse structure
type addressResponse struct {
GeneralResponse
Balance *big.Int `json:"balance"`
Balance string `json:"balance"`
}

func NewAddressResponse() *addressResponse {
return &addressResponse{
Balance: big.NewInt(0),
Balance: "0",
}
}

Expand Down Expand Up @@ -84,7 +84,10 @@ func TestGetBalance_WithCorrectAddressShouldNotReturnError(t *testing.T) {
addressResponse := NewAddressResponse()
loadResponse(resp.Body, &addressResponse)
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, amount, addressResponse.Balance)

balanceResponse, ok := big.NewInt(0).SetString(addressResponse.Balance, 10)
assert.True(t, ok)
assert.Equal(t, amount, balanceResponse)
assert.Equal(t, "", addressResponse.Error)
}

Expand All @@ -106,7 +109,10 @@ func TestGetBalance_WithWrongAddressShouldReturnZero(t *testing.T) {
addressResponse := NewAddressResponse()
loadResponse(resp.Body, &addressResponse)
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, big.NewInt(0), addressResponse.Balance)

balanceResponse, ok := big.NewInt(0).SetString(addressResponse.Balance, 10)
assert.True(t, ok)
assert.Equal(t, big.NewInt(0), balanceResponse)
assert.Equal(t, "", addressResponse.Error)
}

Expand Down Expand Up @@ -150,7 +156,10 @@ func TestGetBalance_WithEmptyAddressShouldReturnZeroAndError(t *testing.T) {
addressResponse := NewAddressResponse()
loadResponse(resp.Body, &addressResponse)
assert.Equal(t, http.StatusBadRequest, resp.Code)
assert.Equal(t, big.NewInt(0), addressResponse.Balance)

balanceResponse, ok := big.NewInt(0).SetString(addressResponse.Balance, 10)
assert.True(t, ok)
assert.Equal(t, big.NewInt(0), balanceResponse)
assert.NotEmpty(t, addressResponse.Error)
assert.True(t, strings.Contains(addressResponse.Error,
fmt.Sprintf("%s: %s", errors2.ErrGetBalance.Error(), errors2.ErrEmptyAddress.Error()),
Expand Down
51 changes: 1 addition & 50 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package api

import (
"bytes"
"net/http"
"reflect"

Expand All @@ -18,9 +17,7 @@ import (
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/gin-gonic/gin/json"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus/promhttp"
"gopkg.in/go-playground/validator.v8"
)

Expand All @@ -31,19 +28,11 @@ type validatorInput struct {
Validator validator.Func
}

type prometheus struct {
NodePort string
NetworkID string
}

// MainApiHandler interface defines methods that can be used from `elrondFacade` context variable
type MainApiHandler interface {
RestApiInterface() string
RestAPIServerDebugMode() bool
PprofEnabled() bool
PrometheusMonitoring() bool
PrometheusJoinURL() string
PrometheusNetworkID() string
IsInterfaceNil() bool
}

Expand Down Expand Up @@ -84,43 +73,9 @@ func Start(elrondFacade MainApiHandler) error {

registerRoutes(ws, elrondFacade)

if elrondFacade.PrometheusMonitoring() {
err = joinMonitoringSystem(elrondFacade)
if err != nil {
return err
}
}

return ws.Run(elrondFacade.RestApiInterface())
}

func joinMonitoringSystem(elrondFacade MainApiHandler) error {
prometheusJoinUrl := elrondFacade.PrometheusJoinURL()
structToSend := prometheus{
NodePort: elrondFacade.RestApiInterface(),
NetworkID: elrondFacade.PrometheusNetworkID(),
}

jsonValue, err := json.Marshal(structToSend)
if err != nil {
return err
}

req, err := http.NewRequest("POST", prometheusJoinUrl, bytes.NewBuffer(jsonValue))
if err != nil {
return err
}

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}

err = resp.Body.Close()
return err
}

func registerRoutes(ws *gin.Engine, elrondFacade middleware.ElrondHandler) {
nodeRoutes := ws.Group("/node")
nodeRoutes.Use(middleware.WithElrondFacade(elrondFacade))
Expand All @@ -143,11 +98,7 @@ func registerRoutes(ws *gin.Engine, elrondFacade middleware.ElrondHandler) {
valStats.Routes(validatorRoutes)

apiHandler, ok := elrondFacade.(MainApiHandler)
if ok && apiHandler.PrometheusMonitoring() {
nodeRoutes.GET("/metrics", gin.WrapH(promhttp.Handler()))
}

if apiHandler.PprofEnabled() {
if ok && apiHandler.PprofEnabled() {
pprof.Register(ws)
}

Expand Down
13 changes: 6 additions & 7 deletions api/mock/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type Facade struct {
GetAccountHandler func(address string) (*state.Account, error)
GenerateTransactionHandler func(sender string, receiver string, value *big.Int, code string) (*transaction.Transaction, error)
GetTransactionHandler func(hash string) (*transaction.Transaction, error)
SendTransactionHandler func(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, code string, signature []byte) (string, error)
CreateTransactionHandler func(nonce uint64, value string, receiverHex string, senderHex string, gasPrice uint64, gasLimit uint64, data string, signatureHex string, challenge string) (*transaction.Transaction, error)
SendTransactionHandler func(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, data []byte, signature []byte) (string, error)
CreateTransactionHandler func(nonce uint64, value string, receiverHex string, senderHex string, gasPrice uint64, gasLimit uint64, data []byte, signatureHex string) (*transaction.Transaction, error)
SendBulkTransactionsHandler func(txs []*transaction.Transaction) (uint64, error)
ExecuteSCQueryHandler func(query *process.SCQuery) (*vmcommon.VMOutput, error)
StatusMetricsHandler func() external.StatusMetricsHandler
Expand Down Expand Up @@ -96,12 +96,11 @@ func (f *Facade) CreateTransaction(
senderHex string,
gasPrice uint64,
gasLimit uint64,
data string,
data []byte,
signatureHex string,
challenge string,
) (*transaction.Transaction, error) {

return f.CreateTransactionHandler(nonce, value, receiverHex, senderHex, gasPrice, gasLimit, data, signatureHex, challenge)
return f.CreateTransactionHandler(nonce, value, receiverHex, senderHex, gasPrice, gasLimit, data, signatureHex)
}

// GetTransaction is the mock implementation of a handler's GetTransaction method
Expand All @@ -110,8 +109,8 @@ func (f *Facade) GetTransaction(hash string) (*transaction.Transaction, error) {
}

// SendTransaction is the mock implementation of a handler's SendTransaction method
func (f *Facade) SendTransaction(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, code string, signature []byte) (string, error) {
return f.SendTransactionHandler(nonce, sender, receiver, value, gasPrice, gasLimit, code, signature)
func (f *Facade) SendTransaction(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, data []byte, signature []byte) (string, error) {
return f.SendTransactionHandler(nonce, sender, receiver, value, gasPrice, gasLimit, data, signature)
}

// SendBulkTransactions is the mock implementation of a handler's SendBulkTransactions method
Expand Down
21 changes: 0 additions & 21 deletions api/node/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package node
import (
"math/big"
"net/http"
"net/url"

"github.com/ElrondNetwork/elrond-go/api/errors"
"github.com/ElrondNetwork/elrond-go/core/statistics"
Expand All @@ -16,7 +15,6 @@ import (
type FacadeHandler interface {
IsNodeRunning() bool
StartNode() error
GetCurrentPublicKey() string
GetHeartbeats() ([]heartbeat.PubKeyHeartbeat, error)
TpsBenchmark() *statistics.TpsBenchmark
StatusMetrics() external.StatusMetricsHandler
Expand Down Expand Up @@ -50,30 +48,11 @@ type shardStatisticsResponse struct {

// Routes defines node related routes
func Routes(router *gin.RouterGroup) {
router.GET("/address", Address)
router.GET("/heartbeatstatus", HeartbeatStatus)
router.GET("/statistics", Statistics)
router.GET("/status", StatusMetrics)
}

// Address returns the information about the address passed as parameter
func Address(c *gin.Context) {
ef, ok := c.MustGet("elrondFacade").(FacadeHandler)
if !ok {
c.JSON(http.StatusInternalServerError, gin.H{"error": errors.ErrInvalidAppContext.Error()})
return
}

currentAddress := ef.GetCurrentPublicKey()
address, err := url.Parse(currentAddress)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": errors.ErrCouldNotParsePubKey.Error()})
return
}

c.JSON(http.StatusOK, gin.H{"address": address.String()})
}

// HeartbeatStatus respond with the heartbeat status of the node
func HeartbeatStatus(c *gin.Context) {
ef, ok := c.MustGet("elrondFacade").(FacadeHandler)
Expand Down
65 changes: 0 additions & 65 deletions api/node/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ type StatusResponse struct {
Running bool `json:"running"`
}

type AddressResponse struct {
GeneralResponse
Address string `json:"address"`
}

type StatisticsResponse struct {
GeneralResponse
Statistics struct {
Expand Down Expand Up @@ -69,66 +64,6 @@ func TestStartNode_FailsWithoutFacade(t *testing.T) {
ws.ServeHTTP(resp, req)
}

func TestAddress_FailsWithoutFacade(t *testing.T) {
t.Parallel()
ws := startNodeServer(nil)
defer func() {
r := recover()
assert.NotNil(t, r, "Not providing elrondFacade context should panic")
}()
req, _ := http.NewRequest("GET", "/node/address", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)
}

func TestAddress_FailsWithWrongFacadeTypeConversion(t *testing.T) {
t.Parallel()
ws := startNodeServerWrongFacade()
req, _ := http.NewRequest("GET", "/node/address", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

addressRsp := AddressResponse{}
loadResponse(resp.Body, &addressRsp)
assert.Equal(t, resp.Code, http.StatusInternalServerError)
assert.Equal(t, addressRsp.Error, errors.ErrInvalidAppContext.Error())
}

func TestAddress_FailsWithInvalidUrlString(t *testing.T) {
facade := mock.Facade{}
facade.GetCurrentPublicKeyHandler = func() string {
// we return a malformed scheme so that url.Parse will error
return "cache_object:foo/bar"
}
ws := startNodeServer(&facade)
req, _ := http.NewRequest("GET", "/node/address", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

addressRsp := AddressResponse{}
loadResponse(resp.Body, &addressRsp)
assert.Equal(t, resp.Code, http.StatusInternalServerError)
assert.Equal(t, addressRsp.Error, errors.ErrCouldNotParsePubKey.Error())
}

func TestAddress_ReturnsSuccessfully(t *testing.T) {
facade := mock.Facade{}
address := "abcdefghijklmnopqrstuvwxyz"
facade.GetCurrentPublicKeyHandler = func() string {
// we return a malformed scheme so that url.Parse will error
return address
}
ws := startNodeServer(&facade)
req, _ := http.NewRequest("GET", "/node/address", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

addressRsp := AddressResponse{}
loadResponse(resp.Body, &addressRsp)
assert.Equal(t, resp.Code, http.StatusOK)
assert.Equal(t, addressRsp.Address, address)
}

//------- Heartbeatstatus

func TestHeartbeatStatus_FailsWithoutFacade(t *testing.T) {
Expand Down
11 changes: 4 additions & 7 deletions api/transaction/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (

// TxService interface defines methods that can be used from `elrondFacade` context variable
type TxService interface {
CreateTransaction(nonce uint64, value string, receiverHex string, senderHex string, gasPrice uint64, gasLimit uint64, data string, signatureHex string, challenge string) (*transaction.Transaction, error)
SendTransaction(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, code string, signature []byte) (string, error)
CreateTransaction(nonce uint64, value string, receiverHex string, senderHex string, gasPrice uint64, gasLimit uint64, data []byte, signatureHex string) (*transaction.Transaction, error)
SendTransaction(nonce uint64, sender string, receiver string, value string, gasPrice uint64, gasLimit uint64, txData []byte, signature []byte) (string, error)
SendBulkTransactions([]*transaction.Transaction) (uint64, error)
GetTransaction(hash string) (*transaction.Transaction, error)
IsInterfaceNil() bool
Expand All @@ -40,12 +40,11 @@ type SendTxRequest struct {
Sender string `form:"sender" json:"sender"`
Receiver string `form:"receiver" json:"receiver"`
Value string `form:"value" json:"value"`
Data string `form:"data" json:"data"`
Data []byte `form:"data" json:"data"`
Nonce uint64 `form:"nonce" json:"nonce"`
GasPrice uint64 `form:"gasPrice" json:"gasPrice"`
GasLimit uint64 `form:"gasLimit" json:"gasLimit"`
Signature string `form:"signature" json:"signature"`
Challenge string `form:"challenge" json:"challenge"`
}

//TxResponse represents the structure on which the response will be validated against
Expand Down Expand Up @@ -88,7 +87,7 @@ func SendTransaction(c *gin.Context) {

txHash, err := ef.SendTransaction(gtx.Nonce, gtx.Sender, gtx.Receiver, gtx.Value, gtx.GasPrice, gtx.GasLimit, gtx.Data, signature)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("%s: %s", errors.ErrTxGenerationFailed.Error(), err.Error())})
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("%s: %s", errors.ErrTxGenerationFailed.Error(), err.Error())})
return
}

Expand Down Expand Up @@ -121,7 +120,6 @@ func SendMultipleTransactions(c *gin.Context) {
receivedTx.GasLimit,
receivedTx.Data,
receivedTx.Signature,
receivedTx.Challenge,
)
if err != nil {
continue
Expand Down Expand Up @@ -175,7 +173,6 @@ func txResponseFromTransaction(tx *transaction.Transaction) TxResponse {
response.Receiver = hex.EncodeToString(tx.RcvAddr)
response.Data = tx.Data
response.Signature = hex.EncodeToString(tx.Signature)
response.Challenge = string(tx.Challenge)
response.Value = tx.Value.String()
response.GasLimit = tx.GasLimit
response.GasPrice = tx.GasPrice
Expand Down
Loading

0 comments on commit 9d8013a

Please sign in to comment.