Skip to content

Commit

Permalink
Merge pull request #2 from ElrondNetwork/feat/EN-2370-request-data-fr…
Browse files Browse the repository at this point in the history
…om-observers

Feat/en 2370 request data from observers
  • Loading branch information
iulianpascalau authored Jun 6, 2019
2 parents a8dc582 + 72db64b commit 16eb46c
Show file tree
Hide file tree
Showing 26 changed files with 1,220 additions and 66 deletions.
4 changes: 2 additions & 2 deletions api/mock/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// Facade is the mock implementation of a node router handler
type Facade struct {
GetAccountHandler func(address string) (*data.Account, error)
SendTransactionHandler func(nonce uint64, sender string, receiver string, value *big.Int, code string, signature []byte) (*data.Transaction, error)
SendTransactionHandler func(nonce uint64, sender string, receiver string, value *big.Int, code string, signature []byte) (string, error)
}

// GetAccount is the mock implementation of a handler's GetAccount method
Expand All @@ -18,7 +18,7 @@ func (f *Facade) GetAccount(address string) (*data.Account, error) {
}

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

Expand Down
4 changes: 1 addition & 3 deletions api/transaction/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package transaction

import (
"math/big"

"github.com/ElrondNetwork/elrond-proxy-go/data"
)

// FacadeHandler interface defines methods that can be used from `elrondProxyFacade` context variable
type FacadeHandler interface {
SendTransaction(nonce uint64, sender string, receiver string, value *big.Int, code string, signature []byte) (*data.Transaction, error)
SendTransaction(nonce uint64, sender string, receiver string, value *big.Int, code string, signature []byte) (string, error)
}
4 changes: 2 additions & 2 deletions api/transaction/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ func SendTransaction(c *gin.Context) {
return
}

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

c.JSON(http.StatusOK, gin.H{"transaction": tx})
c.JSON(http.StatusOK, gin.H{"txHash": txHash})
}
26 changes: 13 additions & 13 deletions api/transaction/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
apiErrors "github.com/ElrondNetwork/elrond-proxy-go/api/errors"
"github.com/ElrondNetwork/elrond-proxy-go/api/mock"
"github.com/ElrondNetwork/elrond-proxy-go/api/transaction"
"github.com/ElrondNetwork/elrond-proxy-go/data"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
Expand All @@ -26,6 +25,12 @@ type GeneralResponse struct {
Error string `json:"error"`
}

// TxHashResponse structure
type TxHashResponse struct {
Error string `json:"error"`
TxHash string `json:"txHash"`
}

func startNodeServerWrongFacade() *gin.Engine {
ws := gin.New()
ws.Use(cors.Default())
Expand Down Expand Up @@ -147,8 +152,8 @@ func TestSendTransaction_ErrorWhenFacadeSendTransactionError(t *testing.T) {

facade := mock.Facade{
SendTransactionHandler: func(nonce uint64, sender string, receiver string, value *big.Int,
code string, signature []byte) (transaction *data.Transaction, e error) {
return nil, errors.New(errorString)
code string, signature []byte) (string, error) {
return "", errors.New(errorString)
},
}
ws := startNodeServer(&facade)
Expand Down Expand Up @@ -181,18 +186,12 @@ func TestSendTransaction_ReturnsSuccessfully(t *testing.T) {
value := big.NewInt(10)
dataField := "data"
signature := "aabbccdd"
txHash := "tx hash"

facade := mock.Facade{
SendTransactionHandler: func(nonce uint64, sender string, receiver string, value *big.Int,
code string, signature []byte) (transaction *data.Transaction, e error) {
return &data.Transaction{
Nonce: nonce,
Sender: sender,
Receiver: receiver,
Value: value,
Data: code,
Signature: string(signature),
}, nil
code string, signature []byte) (string, error) {
return txHash, nil
},
}
ws := startNodeServer(&facade)
Expand All @@ -211,9 +210,10 @@ func TestSendTransaction_ReturnsSuccessfully(t *testing.T) {
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response := GeneralResponse{}
response := TxHashResponse{}
loadResponse(resp.Body, &response)

assert.Equal(t, http.StatusOK, resp.Code)
assert.Empty(t, response.Error)
assert.Equal(t, txHash, response.TxHash)
}
12 changes: 12 additions & 0 deletions cmd/proxy/config/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# GeneralSettings section of the proxy server
[GeneralSettings]
# ServerPort is the port used for the web server. The frontend will connect to this port
ServerPort = 8079

[[Observers]]
ShardId = 0
Address = "127.0.0.1:8080"

[[Observers]]
ShardId = 1
Address = "127.0.0.1:8081"
116 changes: 104 additions & 12 deletions cmd/proxy/main.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package main

import (
"fmt"
"os"
"os/signal"
"syscall"

"github.com/ElrondNetwork/elrond-go-sandbox/core"
"github.com/ElrondNetwork/elrond-go-sandbox/core/logger"
"github.com/ElrondNetwork/elrond-go-sandbox/data/state/addressConverters"
"github.com/ElrondNetwork/elrond-proxy-go/api"
"github.com/ElrondNetwork/elrond-proxy-go/config"
"github.com/ElrondNetwork/elrond-proxy-go/data"
"github.com/ElrondNetwork/elrond-proxy-go/facade"
"github.com/ElrondNetwork/elrond-proxy-go/process"
"github.com/ElrondNetwork/elrond-proxy-go/testing"
"github.com/pkg/profile"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -44,6 +50,13 @@ VERSION:
Usage: "The main configuration file to load",
Value: "./config/config.toml",
}
// testHttpServerEn used to enable a test (mock) http server that will handle all requests
testHttpServerEn = cli.BoolFlag{
Name: "test-http-server-enable",
Usage: "Enables a test http server that will handle all requests",
}

testServer *testing.TestHttpServer
)

func main() {
Expand All @@ -53,9 +66,13 @@ func main() {
app := cli.NewApp()
cli.AppHelpTemplate = proxyHelpTemplate
app.Name = "Elrond Node Proxy CLI App"
app.Version = "v0.0.1"
app.Version = "v1.0.0"
app.Usage = "This is the entry point for starting a new Elrond node proxy"
app.Flags = []cli.Flag{configurationFile, profileMode}
app.Flags = []cli.Flag{
configurationFile,
profileMode,
testHttpServerEn,
}
app.Authors = []cli.Author{
{
Name: "The Elrond Team",
Expand All @@ -67,6 +84,12 @@ func main() {
return startProxy(c)
}

defer func() {
if testServer != nil {
testServer.Close()
}
}()

err := app.Run(os.Args)
if err != nil {
log.Error(err.Error())
Expand All @@ -93,19 +116,23 @@ func startProxy(ctx *cli.Context) error {

log.Info("Starting proxy...")

configurationFileName := ctx.GlobalString(configurationFile.Name)
generalConfig, err := loadMainConfig(configurationFileName, log)
if err != nil {
return err
}
log.Info(fmt.Sprintf("Initialized with config from: %s", configurationFileName))

stop := make(chan bool, 1)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

epf, err := createElrondProxyFacade()
epf, err := createElrondProxyFacade(ctx, generalConfig)
if err != nil {
return err
}

err = startWebServer(epf, 8079)
if err != nil {
return err
}
startWebServer(epf, generalConfig.GeneralSettings.ServerPort)

go func() {
<-sigs
Expand All @@ -119,12 +146,77 @@ func startProxy(ctx *cli.Context) error {
return nil
}

func createElrondProxyFacade() (*facade.ElrondProxyFacade, error) {
accntProc := &process.GetAccountProcessor{}
func loadMainConfig(filepath string, log *logger.Logger) (*config.Config, error) {
cfg := &config.Config{}
err := core.LoadTomlFile(cfg, filepath, log)
if err != nil {
return nil, err
}
return cfg, nil
}

func createElrondProxyFacade(
ctx *cli.Context,
cfg *config.Config,
) (*facade.ElrondProxyFacade, error) {

var testHttpServerEnabled bool
if ctx.IsSet(testHttpServerEn.Name) {
testHttpServerEnabled = ctx.GlobalBool(testHttpServerEn.Name)
}

if testHttpServerEnabled {
log.Info("Starting test HTTP server handling the requests...")
testServer = testing.NewTestHttpServer()
log.Info("Test HTTP server running at " + testServer.URL())

testCfg := &config.Config{
Observers: []*data.Observer{
{
ShardId: 0,
Address: testServer.URL(),
},
},
}

return createFacade(testCfg)
}

return facade.NewElrondProxyFacade(accntProc, nil)
return createFacade(cfg)
}

func startWebServer(proxyHandler api.ElrondProxyHandler, port int) error {
return api.Start(proxyHandler, port)
func createFacade(cfg *config.Config) (*facade.ElrondProxyFacade, error) {
addrConv, err := addressConverters.NewPlainAddressConverter(32, "")
if err != nil {
return nil, err
}

bp, err := process.NewBaseProcessor(addrConv)
if err != nil {
return nil, err
}

err = bp.ApplyConfig(cfg)
if err != nil {
return nil, err
}

accntProc, err := process.NewAccountProcessor(bp)
if err != nil {
return nil, err
}

txProc, err := process.NewTransactionProcessor(bp)
if err != nil {
return nil, err
}

return facade.NewElrondProxyFacade(accntProc, txProc)
}

func startWebServer(proxyHandler api.ElrondProxyHandler, port int) {
go func() {
err := api.Start(proxyHandler, port)
log.LogIfError(err)
}()
}
15 changes: 15 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package config

import "github.com/ElrondNetwork/elrond-proxy-go/data"

// GeneralSettingsConfig will hold the general settings for a node
type GeneralSettingsConfig struct {
ServerPort int
CfgFileReadInterval int
}

// Config will hold the whole config file's data
type Config struct {
GeneralSettings GeneralSettingsConfig
Observers []*data.Observer
}
5 changes: 5 additions & 0 deletions data/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ type Account struct {
CodeHash []byte `json:"codeHash"`
RootHash []byte `json:"rootHash"`
}

// ResponseAccount defines a wrapped account that the node respond with
type ResponseAccount struct {
AccountData Account `json:"account"`
}
7 changes: 7 additions & 0 deletions data/observer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package data

// Observer holds an observer data
type Observer struct {
ShardId uint32
Address string
}
21 changes: 13 additions & 8 deletions data/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import "math/big"

// Transaction represents the structure that maps and validates user input for publishing a new transaction
type Transaction struct {
Sender string `form:"sender" json:"sender"`
Receiver string `form:"receiver" json:"receiver"`
Value *big.Int `form:"value" json:"value"`
Data string `form:"data" json:"data"`
Nonce uint64 `form:"nonce" json:"nonce"`
GasPrice *big.Int `form:"gasPrice" json:"gasPrice"`
GasLimit *big.Int `form:"gasLimit" json:"gasLimit"`
Signature string `form:"signature" json:"signature"`
Challenge string `form:"challenge" json:"challenge"`
Value *big.Int `form:"value" json:"value"`
Receiver string `form:"receiver" json:"receiver"`
Sender string `form:"sender" json:"sender"`
GasPrice *big.Int `form:"gasPrice" json:"gasPrice,omitempty"`
GasLimit *big.Int `form:"gasLimit" json:"gasLimit,omitempty"`
Data string `form:"data" json:"data,omitempty"`
Signature string `form:"signature" json:"signature,omitempty"`
Challenge string `form:"challenge" json:"challenge,omitempty"`
}

// ResponseTransaction defines a response tx holding the resulting hash
type ResponseTransaction struct {
TxHash string `json:"txHash"`
}
Loading

0 comments on commit 16eb46c

Please sign in to comment.