From bccd45b7a0d0d354963e9d4f85a0079cf3d867ae Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 26 Mar 2020 15:49:50 +0300 Subject: [PATCH 01/19] /sign_transaction API method --- app.go | 53 +++++++++++++++++++++++++---- go.sum | 7 ++++ main.go | 16 ++++----- main_test.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 147 insertions(+), 23 deletions(-) diff --git a/app.go b/app.go index 5b227bf..3ca92ae 100644 --- a/app.go +++ b/app.go @@ -2,9 +2,10 @@ package main import ( "encoding/json" - "github.com/eoscanada/eos-go/ecc" + "github.com/eoscanada/eos-go" "github.com/gorilla/mux" "github.com/rs/zerolog/log" + "io/ioutil" "net/http" ) @@ -14,14 +15,23 @@ type JsonResponse = map[string]interface{} type App struct { Router *mux.Router - PrivateKey *ecc.PrivateKey - TopicOffsetPath string + Broker struct { + TopicOffsetPath string + } + BlockChain struct { + API *eos.API + KeyBag eos.KeyBag + ChainID string + } } -func (app *App) Initialize(pk *ecc.PrivateKey, offsetPath string, level string) { +func (app *App) Initialize(wif string, offsetPath string, blockChainUrl string, chainID string, + level string) { app.Router = mux.NewRouter() - app.PrivateKey = pk - app.TopicOffsetPath = offsetPath + app.BlockChain.API = eos.New(blockChainUrl) + app.BlockChain.ChainID = chainID + app.BlockChain.KeyBag.Add(wif) + app.Broker.TopicOffsetPath = offsetPath InitLogger(level) app.InitializeRoutes() @@ -49,7 +59,36 @@ func (app *App) PingQuery(writer ResponseWriter, req *Request) { func (app *App) SignQuery(writer ResponseWriter, req *Request) { log.Info().Msg("Called /sign_transaction") - // TODO + rawTransaction, _ := ioutil.ReadAll(req.Body) + tx := eos.SignedTransaction{} + err := json.Unmarshal(rawTransaction, &tx) + if err != nil { + log.Debug().Msg(err.Error()) + respondWithError(writer, http.StatusBadRequest, "failed to deserialize transaction") + return + } + + signedTx, signError := app.SignTransaction(&tx) + if signError != nil { + log.Warn().Msg(signError.Error()) + respondWithError(writer, http.StatusInternalServerError, "failed to sign transaction") + return + } + packedTrx, _ := signedTx.Pack(eos.CompressionNone) + _, sendError := app.BlockChain.API.PushTransaction(packedTrx) + if sendError != nil { + log.Debug().Msg(sendError.Error()) + respondWithError(writer, http.StatusBadRequest, "failed to send transaction to the blockchain " ) + return + } + + respondWithJSON(writer, http.StatusOK, JsonResponse{"result":"ok"}) +} + +func(app *App) SignTransaction (trx *eos.SignedTransaction) (*eos.SignedTransaction, error) { + blockchain := app.BlockChain + publicKeys, _ := blockchain.KeyBag.AvailableKeys() + return blockchain.KeyBag.Sign(trx, []byte(blockchain.ChainID), publicKeys[0]) } func (app *App) InitializeRoutes() { diff --git a/go.sum b/go.sum index a3589fd..ccc828d 100644 --- a/go.sum +++ b/go.sum @@ -121,16 +121,23 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= +github.com/tidwall/gjson v1.3.2 h1:+7p3qQFaH3fOMXAJSrdZwGKcOO/lYdGS0HqGhPqDdTI= github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg= github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= diff --git a/main.go b/main.go index 2057751..32bf00e 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/BurntSushi/toml" - "github.com/eoscanada/eos-go/ecc" "github.com/kelseyhightower/envconfig" "github.com/rs/zerolog/log" @@ -23,20 +22,18 @@ type Config struct { } BlockChain struct { PrivateKeyPath string `envconfig:"PRIVATEKEY_PATH"` + Url string + ChainID string } } -func readWIF(filename string) *ecc.PrivateKey { +func readWIF(filename string) string { content, err := ioutil.ReadFile(filename) if err != nil { log.Panic().Msg(err.Error()) } wif := strings.TrimSpace(strings.TrimSuffix(string(content), "\n")) - pk, err := ecc.NewPrivateKey(wif) - if err != nil { - log.Panic().Msg(err.Error()) - } - return pk + return wif } @@ -63,6 +60,9 @@ func main() { cfg := Config{} readConfigFile(&cfg) readEnv(&cfg) - app.Initialize(readWIF(cfg.BlockChain.PrivateKeyPath), cfg.Broker.TopicOffsetPath, cfg.Server.LogLevel) + log.Info().Msg(cfg.Broker.TopicOffsetPath) + app.Initialize( + readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, + cfg.Broker.TopicOffsetPath, cfg.Server.LogLevel) app.Run(getAddr(cfg.Server.Port)) } diff --git a/main_test.go b/main_test.go index 6f0eebc..49afefe 100644 --- a/main_test.go +++ b/main_test.go @@ -5,6 +5,8 @@ package main import ( "bytes" "encoding/json" + "github.com/eoscanada/eos-go" + "github.com/rs/zerolog/log" "github.com/stretchr/testify/assert" "net/http/httptest" "os" @@ -15,10 +17,16 @@ import ( ) var a App +const privateKey string = "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU" +const chainID string = "cda75f235aef76ad91ef0503421514d80d8dbb584cd07178022f0bc7deb964ff" func TestMain(m *testing.M) { - pk, _ := ecc.NewPrivateKey("5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU") - a.Initialize(pk, "/var/log/offsets", "DEBUG") + _, err := ecc.NewPrivateKey(privateKey) + if err != nil { + panic(err) + } + a.Initialize(privateKey, "/var/log/offsets", "https://api.daobet.org", + chainID, "DEBUG") code := m.Run() os.Exit(code) } @@ -31,14 +39,84 @@ func TestPingQuery(t *testing.T) { assert.Equal(response.Body.String(), "{\"result\":\"pong\"}", "/ping failed") } -func TestSignTransaction(t *testing.T) { +func TestSignTransactionNormal(t *testing.T) { assert := assert.New(t) - values := map[string]string{"transaction": "42"} - jsonValue, _ := json.Marshal(values) - req, _ := http.NewRequest("POST", "/sign_transaction", bytes.NewBuffer(jsonValue)) - executeRequest(req) - assert.Equal(true, true, "always true") + rawTransaction := []byte(` +{ + "expiration": "2020-03-25T17:41:38", + "ref_block_num": 33633, + "ref_block_prefix": 1346981524, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "transfer", + "authorization": [{ + "actor": "lordofdao", + "permission": "active" + } + ], + "data": "0000a0262d9a2e8d00a8498ba64b23301027000000000000044245540000000000" + } + ], + "transaction_extensions": [], + "signatures": [ + "SIG_K1_KZGbvWTgBGeidB1NUVjx3SFubLgCPeDrZztau9AWgUiNEknmT9ajNSEXoKpEbVtx4XuwLebxPWz6hDzUgYbEBxed2SkKGi" + ], + "context_free_data": [] +}`) + signedRawTx := []byte(`{"expiration":"2020-03-25T17:41:38","ref_block_num":33633,"ref_block_prefix":1346981524,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"eosio.token","name":"transfer","authorization":[{"actor":"lordofdao","permission":"active"}],"data":"0000a0262d9a2e8d00a8498ba64b23301027000000000000044245540000000000"}],"transaction_extensions":[],"signatures":["SIG_K1_KZGbvWTgBGeidB1NUVjx3SFubLgCPeDrZztau9AWgUiNEknmT9ajNSEXoKpEbVtx4XuwLebxPWz6hDzUgYbEBxed2SkKGi","SIG_K1_KVKV98c5Q7cCGqbSSHYsYYo473TeaibkDoLb5V26BHeioY623wAmNLgo9L86nqcy7gKLE8u9dnDnBLR5UVcL65wwaRF34H"],"context_free_data":[]}`) + origTx := eos.SignedTransaction{} + err := json.Unmarshal(rawTransaction, &origTx) + if err != nil { + log.Info().Msg(err.Error()) + return + } + + result, signError := a.SignTransaction(&origTx) + assert.Nil(signError, "failed to sign transaction") + byteString, _ := json.Marshal(result) + assert.Equal(signedRawTx, byteString) +} + +func TestSignTransactionBadRequest(t *testing.T) { + assert := assert.New(t) + + // added sender field + rawTransaction := []byte(` +{ + "sender": "iamthebest" + "expiration": "2020-03-25T17:41:38", + "ref_block_num": 33633, + "ref_block_prefix": 1346981524, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "transfer", + "authorization": [{ + "actor": "lordofdao", + "permission": "active" + } + ], + "data": "0000a0262d9a2e8d00a8498ba64b23301027000000000000044245540000000000" + } + ], + "transaction_extensions": [], + "signatures": [ + "SIG_K1_KZGbvWTgBGeidB1NUVjx3SFubLgCPeDrZztau9AWgUiNEknmT9ajNSEXoKpEbVtx4XuwLebxPWz6hDzUgYbEBxed2SkKGi" + ], + "context_free_data": [] +}`) + req, _ := http.NewRequest("POST", "/sign_transaction", bytes.NewBuffer(rawTransaction)) + response := executeRequest(req) + assert.Equal(response.Body.String(), `{"error":"failed to deserialize transaction"}`) + } func executeRequest(req *http.Request) *httptest.ResponseRecorder { From 2f3b5b6599c1d1ed5b2adec0b0a85d581c8e8e5b Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 26 Mar 2020 17:08:01 +0300 Subject: [PATCH 02/19] send error reason --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index 3ca92ae..00b10a2 100644 --- a/app.go +++ b/app.go @@ -78,7 +78,7 @@ func (app *App) SignQuery(writer ResponseWriter, req *Request) { _, sendError := app.BlockChain.API.PushTransaction(packedTrx) if sendError != nil { log.Debug().Msg(sendError.Error()) - respondWithError(writer, http.StatusBadRequest, "failed to send transaction to the blockchain " ) + respondWithError(writer, http.StatusBadRequest, "failed to send transaction to the blockchain: " + sendError.Error()) return } From bb724b82c0872f10050575516298f44114d86311 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Tue, 7 Apr 2020 20:23:09 +0300 Subject: [PATCH 03/19] [DPM-55] read events from broker --- app.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- go.mod | 14 ++++---- go.sum | 30 ++++++++++++++++ main.go | 16 ++++----- 4 files changed, 144 insertions(+), 20 deletions(-) diff --git a/app.go b/app.go index 00b10a2..d6f6d9e 100644 --- a/app.go +++ b/app.go @@ -1,9 +1,17 @@ package main import ( + "context" "encoding/json" + broker "github.com/DaoCasino/platform-action-monitor-client" "github.com/eoscanada/eos-go" "github.com/gorilla/mux" + "os" + "os/signal" + "strconv" + "strings" + "syscall" + "github.com/rs/zerolog/log" "io/ioutil" "net/http" @@ -17,6 +25,8 @@ type App struct { Router *mux.Router Broker struct { TopicOffsetPath string + Url string + TopicID broker.EventType } BlockChain struct { API *eos.API @@ -25,20 +35,102 @@ type App struct { } } -func (app *App) Initialize(wif string, offsetPath string, blockChainUrl string, chainID string, - level string) { +func readOffset(offsetPath string) uint64 { + log.Debug().Msg("reading from " + offsetPath) + data, err := ioutil.ReadFile(offsetPath) + if err != nil { + log.Panic().Msg("couldn't read offset from file") + } + result, _ := strconv.Atoi(strings.Trim(string(data), "\n")) + return uint64(result) +} + +func writeOffset(offsetPath string, offset uint64) { + log.Debug().Msg("writing offset to " + offsetPath) + err := ioutil.WriteFile(offsetPath, []byte(strconv.Itoa(int(offset))), 0644) + if err != nil { + log.Error().Msgf("couldnt save offeset %+v", err.Error()) + } +} + +func (app *App) Initialize(wif string, blockChainUrl string, chainID string, + offsetPath string, brokerURL string, topicID broker.EventType, level string) { + InitLogger(level) + log.Debug().Msg("initializing app") + app.Router = mux.NewRouter() app.BlockChain.API = eos.New(blockChainUrl) app.BlockChain.ChainID = chainID - app.BlockChain.KeyBag.Add(wif) + + log.Debug().Msg("Reading private key from file") + if app.BlockChain.KeyBag.Add(wif) != nil { + log.Panic().Msg("Malformed private key") + } + + app.Broker.Url = brokerURL app.Broker.TopicOffsetPath = offsetPath + app.Broker.TopicID = topicID - InitLogger(level) app.InitializeRoutes() } +func processEvent(event *broker.Event) { + // TODO send signature to the blockchain + log.Error().Msgf("Unknown event %+v", event) +} + +func RunEventListener(parentContext context.Context, brokerURL string, topicID broker.EventType, offsetPath string) { + + events := make(chan *broker.EventMessage) + + listener := broker.NewEventListener(brokerURL, events) + if err := listener.ListenAndServe(parentContext); err != nil { + log.Panic().Msg(err.Error()) + } + offset := readOffset(offsetPath) + log.Debug().Msgf("Subscribing to event type %+v with an offset of %+v", topicID, offset) + listener.Subscribe(topicID, offset) + + // start event listener goroutine + go func(ctx context.Context, events <-chan *broker.EventMessage) { + for { + select { + case <-ctx.Done(): + log.Info().Msg("Terminating event listener") + listener.Unsubscribe(topicID) + return + case eventMessage, ok := <-events: + if !ok { + log.Warn().Msg("Failed to read events") + return + } + log.Debug().Msgf("Processing %+v events", len(eventMessage.Events)) + for _, event := range eventMessage.Events { + processEvent(event) + } + offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset + writeOffset(offsetPath, offset) + } + } + }(parentContext, events) +} + func (app *App) Run(addr string) { - log.Error().Msg(http.ListenAndServe(addr, app.Router).Error()) + parentContext, cancel := context.WithCancel(context.Background()) + log.Debug().Msg("starting http server") + go func() { + log.Error().Msg(http.ListenAndServe(addr, app.Router).Error()) + }() + log.Debug().Msg("stating event listener") + RunEventListener(parentContext, app.Broker.Url, app.Broker.TopicID, app.Broker.TopicOffsetPath) + + // Handle signals + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + log.Debug().Msg("Waiting for signal") + <-done + log.Info().Msg("Terminating service") + cancel() } func respondWithError(writer ResponseWriter, code int, message string) { @@ -85,7 +177,7 @@ func (app *App) SignQuery(writer ResponseWriter, req *Request) { respondWithJSON(writer, http.StatusOK, JsonResponse{"result":"ok"}) } -func(app *App) SignTransaction (trx *eos.SignedTransaction) (*eos.SignedTransaction, error) { +func(app *App) SignTransaction(trx *eos.SignedTransaction) (*eos.SignedTransaction, error) { blockchain := app.BlockChain publicKeys, _ := blockchain.KeyBag.AvailableKeys() return blockchain.KeyBag.Sign(trx, []byte(blockchain.ChainID), publicKeys[0]) diff --git a/go.mod b/go.mod index 5bc7215..d2eae02 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,12 @@ module github.com/DaoCasino/casino-backend go 1.12 require ( - github.com/BurntSushi/toml v0.3.1 - github.com/eoscanada/eos-go v0.9.0 - github.com/gorilla/mux v1.7.4 - github.com/kelseyhightower/envconfig v1.4.0 - github.com/rs/zerolog v1.18.0 - github.com/stretchr/testify v1.4.0 + github.com/BurntSushi/toml v0.3.1 + github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d + github.com/eoscanada/eos-go v0.9.0 + github.com/gorilla/mux v1.7.4 + github.com/gorilla/websocket v1.4.2 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/rs/zerolog v1.18.0 + github.com/stretchr/testify v1.5.1 ) diff --git a/go.sum b/go.sum index ccc828d..17ca48a 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,10 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf945a117 h1:xR9Oszgt0A95J3Nb3bw9T1ps5owlB92MzYzhmx4qehQ= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf945a117/go.mod h1:NGkkfL3UorfxNeHy28xGI19nJwm/8aGZ5ZxxCLRilRI= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d h1:tvtqU88AX11DbwWcEt7zPLvKH5atPeUIW9jlBkxxWjQ= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -55,9 +59,13 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 h1:giknQ4mEuDFmmHSrGcbargOuLHQGtywqo4mheITex54= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -68,11 +76,14 @@ github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lucsky/cuid v1.0.2 h1:z4XlExeoderxoPj2/dxKOyPxe9RCOu7yNq9/XWxIUMQ= +github.com/lucsky/cuid v1.0.2/go.mod h1:QaaJqckboimOmhRSJXSx/+IT+VTfxfPGSo/6mfgUfmE= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= @@ -102,6 +113,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -120,6 +132,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tidwall/gjson v1.3.2 h1:+7p3qQFaH3fOMXAJSrdZwGKcOO/lYdGS0HqGhPqDdTI= github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -135,14 +148,25 @@ github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+m github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -158,11 +182,16 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= @@ -173,3 +202,4 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/main.go b/main.go index 32bf00e..9dac026 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,13 @@ package main import ( - "io/ioutil" - "strconv" - "strings" - "github.com/BurntSushi/toml" + broker "github.com/DaoCasino/platform-action-monitor-client" "github.com/kelseyhightower/envconfig" - "github.com/rs/zerolog/log" + "io/ioutil" + "strconv" + "strings" ) @@ -18,7 +17,9 @@ type Config struct { LogLevel string `envconfig:"LOG_LEVEL"` } Broker struct { - TopicOffsetPath string `envconfig:"OFFSET_PATH""` + TopicOffsetPath string `envconfig:"OFFSET_PATH"` + Url string `envconfig:"BROKER_URL"` + TopicID broker.EventType } BlockChain struct { PrivateKeyPath string `envconfig:"PRIVATEKEY_PATH"` @@ -60,9 +61,8 @@ func main() { cfg := Config{} readConfigFile(&cfg) readEnv(&cfg) - log.Info().Msg(cfg.Broker.TopicOffsetPath) app.Initialize( readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, - cfg.Broker.TopicOffsetPath, cfg.Server.LogLevel) + cfg.Broker.TopicOffsetPath, cfg.Broker.Url, cfg.Broker.TopicID, cfg.Server.LogLevel) app.Run(getAddr(cfg.Server.Port)) } From 544dc28aac6f6a292f5afeee40164f19311281a3 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Wed, 8 Apr 2020 13:52:38 +0300 Subject: [PATCH 04/19] fix empty events case --- app.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app.go b/app.go index d6f6d9e..31e2965 100644 --- a/app.go +++ b/app.go @@ -36,12 +36,15 @@ type App struct { } func readOffset(offsetPath string) uint64 { - log.Debug().Msg("reading from " + offsetPath) + log.Debug().Msg("reading offset from " + offsetPath) data, err := ioutil.ReadFile(offsetPath) if err != nil { log.Panic().Msg("couldn't read offset from file") } - result, _ := strconv.Atoi(strings.Trim(string(data), "\n")) + result, parseError := strconv.Atoi(strings.Trim(string(data), "\n")) + if parseError != nil { + log.Panic().Msgf("Failed to parse offset from %+v reason=%+v", offsetPath, parseError) + } return uint64(result) } @@ -62,7 +65,7 @@ func (app *App) Initialize(wif string, blockChainUrl string, chainID string, app.BlockChain.API = eos.New(blockChainUrl) app.BlockChain.ChainID = chainID - log.Debug().Msg("Reading private key from file") + log.Debug().Msg("Reading private key from wif") if app.BlockChain.KeyBag.Add(wif) != nil { log.Panic().Msg("Malformed private key") } @@ -104,6 +107,10 @@ func RunEventListener(parentContext context.Context, brokerURL string, topicID b log.Warn().Msg("Failed to read events") return } + if len(eventMessage.Events) == 0 { + log.Debug().Msg("Gotta event message with no events") + return + } log.Debug().Msgf("Processing %+v events", len(eventMessage.Events)) for _, event := range eventMessage.Events { processEvent(event) From d5266d515e39f3096f65f9e45d74132edd16bb6f Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Wed, 8 Apr 2020 17:29:24 +0300 Subject: [PATCH 05/19] graceful shutdown --- app.go | 83 ++++++++++++++++++++++++++++++++-------------------------- go.mod | 6 ++++- go.sum | 18 +++++++++++++ 3 files changed, 69 insertions(+), 38 deletions(-) diff --git a/app.go b/app.go index 31e2965..a9de4b0 100644 --- a/app.go +++ b/app.go @@ -6,13 +6,15 @@ import ( broker "github.com/DaoCasino/platform-action-monitor-client" "github.com/eoscanada/eos-go" "github.com/gorilla/mux" + "github.com/rs/zerolog/log" + "github.com/zenazn/goji/graceful" "os" "os/signal" "strconv" "strings" + "sync" "syscall" - "github.com/rs/zerolog/log" "io/ioutil" "net/http" ) @@ -79,57 +81,63 @@ func (app *App) Initialize(wif string, blockChainUrl string, chainID string, func processEvent(event *broker.Event) { // TODO send signature to the blockchain - log.Error().Msgf("Unknown event %+v", event) + log.Info().Msgf("Unknown event %+v", event) } -func RunEventListener(parentContext context.Context, brokerURL string, topicID broker.EventType, offsetPath string) { +func RunEventListener(parentContext context.Context, brokerURL string, topicID broker.EventType, offsetPath string, + wg *sync.WaitGroup) { - events := make(chan *broker.EventMessage) + go func(parentContext context.Context) { + defer wg.Done() - listener := broker.NewEventListener(brokerURL, events) - if err := listener.ListenAndServe(parentContext); err != nil { - log.Panic().Msg(err.Error()) - } - offset := readOffset(offsetPath) - log.Debug().Msgf("Subscribing to event type %+v with an offset of %+v", topicID, offset) - listener.Subscribe(topicID, offset) + events := make(chan *broker.EventMessage) + + listener := broker.NewEventListener(brokerURL, events) + ctx, cancel := context.WithCancel(context.Background()) + if err := listener.ListenAndServe(ctx); err != nil { + log.Panic().Msg(err.Error()) + } + offset := readOffset(offsetPath) + log.Debug().Msgf("Subscribing to event type %+v with an offset of %+v", topicID, offset) + listener.Subscribe(topicID, offset) - // start event listener goroutine - go func(ctx context.Context, events <-chan *broker.EventMessage) { for { - select { - case <-ctx.Done(): - log.Info().Msg("Terminating event listener") - listener.Unsubscribe(topicID) - return - case eventMessage, ok := <-events: - if !ok { - log.Warn().Msg("Failed to read events") - return - } - if len(eventMessage.Events) == 0 { - log.Debug().Msg("Gotta event message with no events") - return - } - log.Debug().Msgf("Processing %+v events", len(eventMessage.Events)) - for _, event := range eventMessage.Events { - processEvent(event) - } - offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset - writeOffset(offsetPath, offset) - } + select { + case <-parentContext.Done(): + log.Info().Msg("Terminating event listener") + listener.Unsubscribe(topicID) + cancel() + return + case eventMessage, ok := <-events: + if !ok { + log.Info().Msg("Failed to read events") + break + } + if len(eventMessage.Events) == 0 { + log.Debug().Msg("Gotta event message with no events") + break + } + log.Debug().Msgf("Processing %+v events", len(eventMessage.Events)) + for _, event := range eventMessage.Events { + processEvent(event) + } + offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset + writeOffset(offsetPath, offset) + } } - }(parentContext, events) + }(parentContext) } func (app *App) Run(addr string) { parentContext, cancel := context.WithCancel(context.Background()) log.Debug().Msg("starting http server") go func() { - log.Error().Msg(http.ListenAndServe(addr, app.Router).Error()) + log.Error().Msg(graceful.ListenAndServe(addr, app.Router).Error()) }() log.Debug().Msg("stating event listener") - RunEventListener(parentContext, app.Broker.Url, app.Broker.TopicID, app.Broker.TopicOffsetPath) + var wg sync.WaitGroup + wg.Add(1) + RunEventListener(parentContext, app.Broker.Url, app.Broker.TopicID, app.Broker.TopicOffsetPath, &wg) // Handle signals done := make(chan os.Signal, 1) @@ -138,6 +146,7 @@ func (app *App) Run(addr string) { <-done log.Info().Msg("Terminating service") cancel() + wg.Wait() } func respondWithError(writer ResponseWriter, code int, message string) { diff --git a/go.mod b/go.mod index d2eae02..fd8cff0 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,15 @@ go 1.12 require ( github.com/BurntSushi/toml v0.3.1 - github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d + github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838 github.com/eoscanada/eos-go v0.9.0 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 github.com/kelseyhightower/envconfig v1.4.0 + github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619 // indirect github.com/rs/zerolog v1.18.0 + github.com/satori/go.uuid v1.2.0 // indirect github.com/stretchr/testify v1.5.1 + github.com/zenazn/goji v0.9.0 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect ) diff --git a/go.sum b/go.sum index 17ca48a..daf422b 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= @@ -17,6 +18,8 @@ github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf9 github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf945a117/go.mod h1:NGkkfL3UorfxNeHy28xGI19nJwm/8aGZ5ZxxCLRilRI= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d h1:tvtqU88AX11DbwWcEt7zPLvKH5atPeUIW9jlBkxxWjQ= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838 h1:t7rr0VbZu839A/LunvGzzBQY8Q7zp376+FXrqeLzWGQ= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -56,6 +59,7 @@ github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dT github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c h1:zqAKixg3cTcIasAMJV+EcfVbWwLpOZ7LeoWJvcuD/5Q= github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -111,6 +115,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619 h1:fVrZXJsfrSbHN14BA6F0x2vk46sh7wZNgHUghmFbX4s= +github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619/go.mod h1:UKfPBpa0fuPjY5QagVNkCdwF0EXMmZj7Ku2PAcLXeN0= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -120,6 +126,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -132,6 +140,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tidwall/gjson v1.3.2 h1:+7p3qQFaH3fOMXAJSrdZwGKcOO/lYdGS0HqGhPqDdTI= @@ -145,6 +154,7 @@ github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7V github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -165,13 +175,19 @@ golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5 golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -188,6 +204,8 @@ golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 3fe9de6560038567a7e03c2b7d903197a0da612c Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Mon, 13 Apr 2020 17:50:20 +0300 Subject: [PATCH 06/19] [dpm-57] signidice event processor --- app.go | 86 ++++++++++++++++++++++++++++++--------------------- blockchain.go | 43 ++++++++++++++++++++++++++ go.mod | 8 ++--- go.sum | 4 +++ main.go | 36 ++------------------- utils.go | 59 +++++++++++++++++++++++++++++++++++ 6 files changed, 163 insertions(+), 73 deletions(-) create mode 100644 blockchain.go create mode 100644 utils.go diff --git a/app.go b/app.go index a9de4b0..d736ebf 100644 --- a/app.go +++ b/app.go @@ -10,7 +10,6 @@ import ( "github.com/zenazn/goji/graceful" "os" "os/signal" - "strconv" "strings" "sync" "syscall" @@ -34,44 +33,29 @@ type App struct { API *eos.API KeyBag eos.KeyBag ChainID string - } -} - -func readOffset(offsetPath string) uint64 { - log.Debug().Msg("reading offset from " + offsetPath) - data, err := ioutil.ReadFile(offsetPath) - if err != nil { - log.Panic().Msg("couldn't read offset from file") - } - result, parseError := strconv.Atoi(strings.Trim(string(data), "\n")) - if parseError != nil { - log.Panic().Msgf("Failed to parse offset from %+v reason=%+v", offsetPath, parseError) - } - return uint64(result) -} - -func writeOffset(offsetPath string, offset uint64) { - log.Debug().Msg("writing offset to " + offsetPath) - err := ioutil.WriteFile(offsetPath, []byte(strconv.Itoa(int(offset))), 0644) - if err != nil { - log.Error().Msgf("couldnt save offeset %+v", err.Error()) + CasinoAccountName string } } func (app *App) Initialize(wif string, blockChainUrl string, chainID string, - offsetPath string, brokerURL string, topicID broker.EventType, level string) { + offsetPath string, brokerURL string, topicID broker.EventType, casinoAccountName, level string) { + InitLogger(level) + if strings.ToLower(level) == "debug" { + broker.EnableDebugLogging() + } log.Debug().Msg("initializing app") app.Router = mux.NewRouter() app.BlockChain.API = eos.New(blockChainUrl) app.BlockChain.ChainID = chainID + app.BlockChain.CasinoAccountName = casinoAccountName log.Debug().Msg("Reading private key from wif") if app.BlockChain.KeyBag.Add(wif) != nil { log.Panic().Msg("Malformed private key") } - + app.BlockChain.API.SetSigner(&app.BlockChain.KeyBag) app.Broker.Url = brokerURL app.Broker.TopicOffsetPath = offsetPath app.Broker.TopicID = topicID @@ -79,34 +63,65 @@ func (app *App) Initialize(wif string, blockChainUrl string, chainID string, app.InitializeRoutes() } -func processEvent(event *broker.Event) { - // TODO send signature to the blockchain - log.Info().Msgf("Unknown event %+v", event) +type BrokerData struct { + Digest string `json:"digest"` +} + +func (app *App) processEvent(event *broker.Event) { + log.Info().Msgf("Processing event %+v", event) + var data BrokerData + parseError := json.Unmarshal(event.Data, &data) + + if parseError != nil { + log.Warn().Msg("Couldnt get digest from event") + return + } + + blockchain, api := app.BlockChain, app.BlockChain.API + signature, signError := blockchain.KeyBag.Keys[0].Sign([]byte(data.Digest)) + + if signError != nil { + log.Warn().Msg("Couldnt sign signidice_part_2, reason=" + signError.Error()) + return + } + + trx, packedTx := GetSigndiceTransaction(api, event.Sender, app.BlockChain.CasinoAccountName, event.RequestID, signature) + log.Debug().Msgf("%+v", trx) + + result, sendError := api.PushTransaction(packedTx) + if sendError != nil { + log.Warn().Msg("Failed to send transaction, reason: " + sendError.Error()) + } + log.Debug().Msg("Successfully signed and sent txn, id: " + result.TransactionID) } -func RunEventListener(parentContext context.Context, brokerURL string, topicID broker.EventType, offsetPath string, - wg *sync.WaitGroup) { +func (app *App) RunEventListener(parentContext context.Context, wg *sync.WaitGroup) { go func(parentContext context.Context) { defer wg.Done() events := make(chan *broker.EventMessage) - listener := broker.NewEventListener(brokerURL, events) + listener := broker.NewEventListener(app.Broker.Url, events) ctx, cancel := context.WithCancel(context.Background()) if err := listener.ListenAndServe(ctx); err != nil { log.Panic().Msg(err.Error()) } + + offsetPath := app.Broker.TopicOffsetPath offset := readOffset(offsetPath) + topicID := app.Broker.TopicID + log.Debug().Msgf("Subscribing to event type %+v with an offset of %+v", topicID, offset) listener.Subscribe(topicID, offset) for { select { case <-parentContext.Done(): - log.Info().Msg("Terminating event listener") + log.Debug().Msg("Terminating event listener") listener.Unsubscribe(topicID) cancel() + log.Debug().Msg("Event listener successfully terminated") return case eventMessage, ok := <-events: if !ok { @@ -119,7 +134,7 @@ func RunEventListener(parentContext context.Context, brokerURL string, topicID b } log.Debug().Msgf("Processing %+v events", len(eventMessage.Events)) for _, event := range eventMessage.Events { - processEvent(event) + go app.processEvent(event) } offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset writeOffset(offsetPath, offset) @@ -137,7 +152,7 @@ func (app *App) Run(addr string) { log.Debug().Msg("stating event listener") var wg sync.WaitGroup wg.Add(1) - RunEventListener(parentContext, app.Broker.Url, app.Broker.TopicID, app.Broker.TopicOffsetPath, &wg) + app.RunEventListener(parentContext, &wg) // Handle signals done := make(chan os.Signal, 1) @@ -147,6 +162,7 @@ func (app *App) Run(addr string) { log.Info().Msg("Terminating service") cancel() wg.Wait() + log.Info().Msg("Service successfully terminated") } func respondWithError(writer ResponseWriter, code int, message string) { @@ -183,14 +199,14 @@ func (app *App) SignQuery(writer ResponseWriter, req *Request) { return } packedTrx, _ := signedTx.Pack(eos.CompressionNone) - _, sendError := app.BlockChain.API.PushTransaction(packedTrx) + result, sendError := app.BlockChain.API.PushTransaction(packedTrx) if sendError != nil { log.Debug().Msg(sendError.Error()) respondWithError(writer, http.StatusBadRequest, "failed to send transaction to the blockchain: " + sendError.Error()) return } - respondWithJSON(writer, http.StatusOK, JsonResponse{"result":"ok"}) + respondWithJSON(writer, http.StatusOK, JsonResponse{"txid": result.TransactionID}) } func(app *App) SignTransaction(trx *eos.SignedTransaction) (*eos.SignedTransaction, error) { diff --git a/blockchain.go b/blockchain.go new file mode 100644 index 0000000..c7ab5db --- /dev/null +++ b/blockchain.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "github.com/eoscanada/eos-go" + "github.com/eoscanada/eos-go/ecc" +) + +func NewSigndice(contract, casinoAccount string, requestID uint64, signature string) *eos.Action { + return &eos.Action{ + Account: eos.AN(contract), + Name: eos.ActN("sgdicesecond"), + Authorization: []eos.PermissionLevel{ + {Actor: eos.AN(casinoAccount), Permission: eos.PN("active")}, + }, + ActionData: eos.NewActionData(Signidice{ + requestID, + signature, + }), + } +} + +// Game contract's sgdicesecond action parameters +type Signidice struct { + RequestID uint64 `json:"req_id"` + Signature string `json:"sign"` +} + + +func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string, requestID uint64, signature ecc.Signature) (*eos.SignedTransaction, *eos.PackedTransaction) { + action := NewSigndice(contract, casinoAccount, requestID, string(signature.Content)) + txOpts := &eos.TxOptions{} + + if err := txOpts.FillFromChain(api); err != nil { + panic(fmt.Errorf("filling tx opts: %s", err)) + } + tx := eos.NewTransaction([]*eos.Action{action}, txOpts) + signedTx, packedTx, err := api.SignTransaction(tx, txOpts.ChainID, eos.CompressionNone) + if err != nil { + panic(fmt.Errorf("sign transaction: %s", err)) + } + return signedTx, packedTx +} diff --git a/go.mod b/go.mod index fd8cff0..d12e2b1 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,16 @@ module github.com/DaoCasino/casino-backend -go 1.12 +go 1.14 require ( github.com/BurntSushi/toml v0.3.1 - github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838 + github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a github.com/eoscanada/eos-go v0.9.0 github.com/gorilla/mux v1.7.4 - github.com/gorilla/websocket v1.4.2 + github.com/gorilla/websocket v1.4.2 // indirect github.com/kelseyhightower/envconfig v1.4.0 - github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619 // indirect github.com/rs/zerolog v1.18.0 github.com/satori/go.uuid v1.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/zenazn/goji v0.9.0 - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect ) diff --git a/go.sum b/go.sum index daf422b..0cdf6c8 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,10 @@ github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7c github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838 h1:t7rr0VbZu839A/LunvGzzBQY8Q7zp376+FXrqeLzWGQ= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f2178ed14 h1:0J3NbHihh8rvZrxb73jJtsOWgIkAtGDwNR8piYKVxrQ= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f2178ed14/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a h1:+QgL6LOmc+v85OKBGts/XkZNHFYLCDDWdEyDO0d6b3Y= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= diff --git a/main.go b/main.go index 9dac026..749ef5e 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,7 @@ package main import ( - "github.com/BurntSushi/toml" broker "github.com/DaoCasino/platform-action-monitor-client" - "github.com/kelseyhightower/envconfig" - "github.com/rs/zerolog/log" - "io/ioutil" - "strconv" - "strings" ) @@ -25,36 +19,11 @@ type Config struct { PrivateKeyPath string `envconfig:"PRIVATEKEY_PATH"` Url string ChainID string + CasinoAccountName string } } -func readWIF(filename string) string { - content, err := ioutil.ReadFile(filename) - if err != nil { - log.Panic().Msg(err.Error()) - } - wif := strings.TrimSpace(strings.TrimSuffix(string(content), "\n")) - return wif -} - - -func readConfigFile(cfg *Config) { - _, err := toml.DecodeFile("/etc/casino/config.toml", &cfg) - if err != nil { - log.Panic().Msg(err.Error()) - } -} -func readEnv(cfg *Config) { - err := envconfig.Process("", cfg) - if err != nil { - log.Panic().Msg(err.Error()) - } -} - -func getAddr(port int) string { - return ":" + strconv.Itoa(port) -} func main() { app := App{} @@ -63,6 +32,7 @@ func main() { readEnv(&cfg) app.Initialize( readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, - cfg.Broker.TopicOffsetPath, cfg.Broker.Url, cfg.Broker.TopicID, cfg.Server.LogLevel) + cfg.Broker.TopicOffsetPath, cfg.Broker.Url, cfg.Broker.TopicID, cfg.BlockChain.CasinoAccountName, + cfg.Server.LogLevel) app.Run(getAddr(cfg.Server.Port)) } diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..3c870a3 --- /dev/null +++ b/utils.go @@ -0,0 +1,59 @@ +package main + +import ( + "github.com/BurntSushi/toml" + "github.com/kelseyhightower/envconfig" + "github.com/rs/zerolog/log" + "io/ioutil" + "strconv" + "strings" +) + +func readOffset(offsetPath string) uint64 { + log.Debug().Msg("reading offset from " + offsetPath) + data, err := ioutil.ReadFile(offsetPath) + if err != nil { + log.Panic().Msg("couldn't read offset from file") + } + result, parseError := strconv.Atoi(strings.Trim(string(data), "\n")) + if parseError != nil { + log.Panic().Msgf("Failed to parse offset from %+v reason=%+v", offsetPath, parseError) + } + return uint64(result) +} + +func writeOffset(offsetPath string, offset uint64) { + log.Debug().Msg("writing offset to " + offsetPath) + err := ioutil.WriteFile(offsetPath, []byte(strconv.Itoa(int(offset))), 0644) + if err != nil { + log.Error().Msgf("couldnt save offeset %+v", err.Error()) + } +} + +func readWIF(filename string) string { + content, err := ioutil.ReadFile(filename) + if err != nil { + log.Panic().Msg(err.Error()) + } + wif := strings.TrimSpace(strings.TrimSuffix(string(content), "\n")) + return wif +} + + +func readConfigFile(cfg *Config) { + _, err := toml.DecodeFile("/etc/casino/config.toml", &cfg) + if err != nil { + log.Panic().Msg(err.Error()) + } +} + +func readEnv(cfg *Config) { + err := envconfig.Process("", cfg) + if err != nil { + log.Panic().Msg(err.Error()) + } +} + +func getAddr(port int) string { + return ":" + strconv.Itoa(port) +} \ No newline at end of file From 19f9b6f2fa73ef6e202822467cedc5d28484a707 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Tue, 14 Apr 2020 11:40:25 +0300 Subject: [PATCH 07/19] PM signidice & up broker client --- blockchain.go | 2 +- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/blockchain.go b/blockchain.go index c7ab5db..0f05ecd 100644 --- a/blockchain.go +++ b/blockchain.go @@ -11,7 +11,7 @@ func NewSigndice(contract, casinoAccount string, requestID uint64, signature str Account: eos.AN(contract), Name: eos.ActN("sgdicesecond"), Authorization: []eos.PermissionLevel{ - {Actor: eos.AN(casinoAccount), Permission: eos.PN("active")}, + {Actor: eos.AN(casinoAccount), Permission: eos.PN("signidice")}, }, ActionData: eos.NewActionData(Signidice{ requestID, diff --git a/go.mod b/go.mod index d12e2b1..d4c6ab4 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( github.com/BurntSushi/toml v0.3.1 - github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a + github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc github.com/eoscanada/eos-go v0.9.0 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 // indirect diff --git a/go.sum b/go.sum index 0cdf6c8..12e0ca5 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f21 github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f2178ed14/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a h1:+QgL6LOmc+v85OKBGts/XkZNHFYLCDDWdEyDO0d6b3Y= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc h1:KpumOTuGgDkttODKAOwKeIw6EBvJ3v+2PaK6yrFumpQ= +github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= From aff8d1b0b721a68be1abaef5907364e434c825bc Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Tue, 14 Apr 2020 12:48:25 +0300 Subject: [PATCH 08/19] fix error handling --- app.go | 8 +++++++- blockchain.go | 9 ++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app.go b/app.go index d736ebf..62558a8 100644 --- a/app.go +++ b/app.go @@ -85,7 +85,13 @@ func (app *App) processEvent(event *broker.Event) { return } - trx, packedTx := GetSigndiceTransaction(api, event.Sender, app.BlockChain.CasinoAccountName, event.RequestID, signature) + trx, packedTx, err := GetSigndiceTransaction(api, event.Sender, app.BlockChain.CasinoAccountName, event.RequestID, signature) + + if err != nil { + log.Error().Msg("couldn't form transaction, reason: " + err.Error()) + return + } + log.Debug().Msgf("%+v", trx) result, sendError := api.PushTransaction(packedTx) diff --git a/blockchain.go b/blockchain.go index 0f05ecd..7f75d26 100644 --- a/blockchain.go +++ b/blockchain.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "github.com/eoscanada/eos-go" "github.com/eoscanada/eos-go/ecc" ) @@ -27,17 +26,17 @@ type Signidice struct { } -func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string, requestID uint64, signature ecc.Signature) (*eos.SignedTransaction, *eos.PackedTransaction) { +func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string, requestID uint64, signature ecc.Signature) (*eos.SignedTransaction, *eos.PackedTransaction, error) { action := NewSigndice(contract, casinoAccount, requestID, string(signature.Content)) txOpts := &eos.TxOptions{} if err := txOpts.FillFromChain(api); err != nil { - panic(fmt.Errorf("filling tx opts: %s", err)) + return nil, nil, err } tx := eos.NewTransaction([]*eos.Action{action}, txOpts) signedTx, packedTx, err := api.SignTransaction(tx, txOpts.ChainID, eos.CompressionNone) if err != nil { - panic(fmt.Errorf("sign transaction: %s", err)) + return nil, nil, err } - return signedTx, packedTx + return signedTx, packedTx, nil } From 7cb8f45fee9380b04c0f0be05ce521c552264d5f Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Tue, 14 Apr 2020 19:03:17 +0300 Subject: [PATCH 09/19] Travis CI --- .travis.yml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..048bfd3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,41 @@ +# use the latest ubuntu environment (18.04) available on travis +dist: bionic + +language: go + +# Force-enable Go modules. Also force go to use the code in vendor/ +# The first two envs will be unnecessary when Go 1.14 lands. +# LINTER_VERSION is the version of golangci-lint. See current releases +# here: +# https://github.com/golangci/golangci-lint/releases +env: GO111MODULE=on GOFLAGS='-mod vendor' + +# You don't need to test on very old versions of the Go compiler. It's the user's +# responsibility to keep their compiler up to date. +go: + - 1.14.x + +# Only clone the most recent commit. +git: + depth: 1 + +# Skip the install step. Don't `go get` dependencies. Only build with the code +# in vendor/ +install: true + +# Don't email me the results of the test runs. +notifications: + email: false + +# Anything in before_script that returns a nonzero exit code will flunk the +# build and immediately stop. It's sorta like having set -e enabled in bash. +# We can download and extract the golangci-lint binary in one (long) command. +before_script: + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $GOPATH/bin v1.23.1 + +# script always runs to completion (set +e). If we have linter issues AND a +# failing test, we want to see both. Configure golangci-lint with a +# .golangci.yml file at the top level of your repo. +script: + - golangci-lint run # run a bunch of code checkers/linters in parallel + - go test -v -race ./... # Run all the tests with the race detector enabled \ No newline at end of file From b0e8179db57cccfa2e8d200c608c7f39215bd1b9 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Tue, 14 Apr 2020 19:15:03 +0300 Subject: [PATCH 10/19] up travis --- .travis.yml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 048bfd3..d03cc99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,26 +2,14 @@ dist: bionic language: go - -# Force-enable Go modules. Also force go to use the code in vendor/ -# The first two envs will be unnecessary when Go 1.14 lands. -# LINTER_VERSION is the version of golangci-lint. See current releases -# here: -# https://github.com/golangci/golangci-lint/releases -env: GO111MODULE=on GOFLAGS='-mod vendor' - -# You don't need to test on very old versions of the Go compiler. It's the user's -# responsibility to keep their compiler up to date. go: - - 1.14.x + - 1.13.4 + # Only clone the most recent commit. git: depth: 1 -# Skip the install step. Don't `go get` dependencies. Only build with the code -# in vendor/ -install: true # Don't email me the results of the test runs. notifications: From 645617a1a0f93bed88f37b21c7c2947673c14cd3 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Wed, 15 Apr 2020 14:31:46 +0300 Subject: [PATCH 11/19] fix linter errors --- app.go | 29 +++++++++++++++++++++-------- go.mod | 2 +- logger.go | 14 ++++---------- main_test.go | 5 +++-- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app.go b/app.go index 62558a8..73c356b 100644 --- a/app.go +++ b/app.go @@ -88,7 +88,7 @@ func (app *App) processEvent(event *broker.Event) { trx, packedTx, err := GetSigndiceTransaction(api, event.Sender, app.BlockChain.CasinoAccountName, event.RequestID, signature) if err != nil { - log.Error().Msg("couldn't form transaction, reason: " + err.Error()) + log.Warn().Msg("couldn't form transaction, reason: " + err.Error()) return } @@ -105,29 +105,39 @@ func (app *App) RunEventListener(parentContext context.Context, wg *sync.WaitGro go func(parentContext context.Context) { defer wg.Done() - events := make(chan *broker.EventMessage) listener := broker.NewEventListener(app.Broker.Url, events) ctx, cancel := context.WithCancel(context.Background()) + if err := listener.ListenAndServe(ctx); err != nil { log.Panic().Msg(err.Error()) } + defer cancel() + offsetPath := app.Broker.TopicOffsetPath offset := readOffset(offsetPath) topicID := app.Broker.TopicID log.Debug().Msgf("Subscribing to event type %+v with an offset of %+v", topicID, offset) - listener.Subscribe(topicID, offset) + _, err := listener.Subscribe(topicID, offset) + + if err != nil { + log.Error().Msg("Failed to subscribe") + return + } for { select { case <-parentContext.Done(): log.Debug().Msg("Terminating event listener") - listener.Unsubscribe(topicID) - cancel() - log.Debug().Msg("Event listener successfully terminated") + _, err := listener.Unsubscribe(topicID) + if err != nil { + log.Warn().Msg("Failed to unsubscribe") + } else { + log.Debug().Msg("Event listener successfully terminated") + } return case eventMessage, ok := <-events: if !ok { @@ -142,7 +152,7 @@ func (app *App) RunEventListener(parentContext context.Context, wg *sync.WaitGro for _, event := range eventMessage.Events { go app.processEvent(event) } - offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset + offset = eventMessage.Events[len(eventMessage.Events) - 1].Offset + 1 writeOffset(offsetPath, offset) } } @@ -179,7 +189,10 @@ func respondWithJSON(writer ResponseWriter, code int, payload interface{}) { response, _ := json.Marshal(payload) writer.Header().Set("Content-Type", "application/json") writer.WriteHeader(code) - writer.Write(response) + _, err := writer.Write(response) + if err != nil { + log.Warn().Msg("Failed to respond to client") + } } func (app *App) PingQuery(writer ResponseWriter, req *Request) { diff --git a/go.mod b/go.mod index d4c6ab4..3245861 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/DaoCasino/casino-backend -go 1.14 +go 1.13 require ( github.com/BurntSushi/toml v0.3.1 diff --git a/logger.go b/logger.go index f22fecc..7643399 100644 --- a/logger.go +++ b/logger.go @@ -20,17 +20,11 @@ func InitLogger(level string) { colorGreen colorYellow colorBlue - colorMagenta - colorCyan - colorWhite - - colorBold = 1 - colorDarkGray = 90 ) - var colorMap = map[string]int { + var colorMap = map[string]int{ "debug": colorYellow, - "info": colorGreen, - "warn": colorBlue, + "info": colorGreen, + "warn": colorBlue, "error": colorRed, } colorize := func(s string, c int) string { @@ -66,4 +60,4 @@ func getLevel(level string) zerolog.Level { default: return zerolog.InfoLevel } -} \ No newline at end of file +} diff --git a/main_test.go b/main_test.go index 49afefe..051bd34 100644 --- a/main_test.go +++ b/main_test.go @@ -5,6 +5,7 @@ package main import ( "bytes" "encoding/json" + broker "github.com/DaoCasino/platform-action-monitor-client" "github.com/eoscanada/eos-go" "github.com/rs/zerolog/log" "github.com/stretchr/testify/assert" @@ -25,8 +26,8 @@ func TestMain(m *testing.M) { if err != nil { panic(err) } - a.Initialize(privateKey, "/var/log/offsets", "https://api.daobet.org", - chainID, "DEBUG") + a.Initialize(privateKey, "nodeURL", + chainID, "/some/path", "brokerUrl", broker.EventType(2), "a", "b") code := m.Run() os.Exit(code) } From 800e8451d439cf1389f3c8248ebaea9182b127c8 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Wed, 15 Apr 2020 15:41:13 +0300 Subject: [PATCH 12/19] add multiple jobs --- .travis.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d03cc99..15c6e20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,10 @@ before_script: # script always runs to completion (set +e). If we have linter issues AND a # failing test, we want to see both. Configure golangci-lint with a # .golangci.yml file at the top level of your repo. -script: - - golangci-lint run # run a bunch of code checkers/linters in parallel - - go test -v -race ./... # Run all the tests with the race detector enabled \ No newline at end of file +jobs: + include: + - stage: lint & test + if: (branch IN (master,develop)) AND (type IN (push, pull_request)) + script: + - golangci-lint run + - go test -v -race ./... \ No newline at end of file From cc327b2383724286f51916811c249b735e06043a Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 16 Apr 2020 15:28:44 +0300 Subject: [PATCH 13/19] dockerfile and push image --- .travis.yml | 25 +++++++++++++++++++++++-- Dockerfile | 11 +++++++++++ main.go | 6 ++++-- utils.go | 4 ++-- 4 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 Dockerfile diff --git a/.travis.yml b/.travis.yml index 15c6e20..5262de9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,19 @@ language: go go: - 1.13.4 +services: + - docker + +env: + - IMG_NAME=daocasino/casinoback DOCKER_TAG_LATEST=true DOCKER_REGISTRY=registry.hub.docker.com + +before_install: + - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + +cache: + directories: + - $HOME/.ccache + timeout: 1000 # Only clone the most recent commit. git: @@ -27,7 +40,15 @@ before_script: jobs: include: - stage: lint & test - if: (branch IN (master,develop)) AND (type IN (push, pull_request)) script: - golangci-lint run - - go test -v -race ./... \ No newline at end of file + - go test -v -race ./... + - stage: build & push + script: + - docker build -t $IMG_NAME:$TRAVIS_BRANCH -f Dockerfile . + - | + docker push $IMG_NAME:$TRAVIS_BRANCH + if [ $TRAVIS_BRANCH == "master" ]; then + docker tag $IMG_NAME:master $IMG_NAME:latest + docker push $IMG_NAME:latest + fi diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..179e23d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:latest AS builder +ENV GO111MODULE=on +RUN mkdir -p /build +ADD . /build +WORKDIR /build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o casino . + +FROM alpine:latest +RUN apk --no-cache add ca-certificates +COPY --from=builder /build/casino /usr/bin +CMD ["casino"] \ No newline at end of file diff --git a/main.go b/main.go index 749ef5e..feb58d0 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,10 @@ package main import ( + "flag" broker "github.com/DaoCasino/platform-action-monitor-client" ) - type Config struct { Server struct { Port int `envconfig:"SERVER_PORT"` @@ -26,9 +26,11 @@ type Config struct { func main() { + configPath := flag.String("config", "/etc/config", "config file path") + flag.Parse() app := App{} cfg := Config{} - readConfigFile(&cfg) + readConfigFile(&cfg, *configPath) readEnv(&cfg) app.Initialize( readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, diff --git a/utils.go b/utils.go index 3c870a3..62789ad 100644 --- a/utils.go +++ b/utils.go @@ -40,8 +40,8 @@ func readWIF(filename string) string { } -func readConfigFile(cfg *Config) { - _, err := toml.DecodeFile("/etc/casino/config.toml", &cfg) +func readConfigFile(cfg *Config, path string) { + _, err := toml.DecodeFile(path, &cfg) if err != nil { log.Panic().Msg(err.Error()) } From 9f4b35dfc5d430500b656ade92a9030013f4f17e Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 16 Apr 2020 17:16:30 +0300 Subject: [PATCH 14/19] add coverage report --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5262de9..76f23c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ jobs: - stage: lint & test script: - golangci-lint run - - go test -v -race ./... + - go test -v -race -coverprofile=coverage.txt -covermode=atomic . - stage: build & push script: - docker build -t $IMG_NAME:$TRAVIS_BRANCH -f Dockerfile . @@ -52,3 +52,6 @@ jobs: docker tag $IMG_NAME:master $IMG_NAME:latest docker push $IMG_NAME:latest fi + +after_success: + - bash <(curl -s https://codecov.io/bash \ No newline at end of file From 75a1a6a722c11a5e96da56999ad21664e2d7a8f8 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 16 Apr 2020 17:57:52 +0300 Subject: [PATCH 15/19] add build status in readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 8b6703d..dd0da5c 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ # Casino Backend + +## Build Status + +Branch|Build Status +---|--- +Master|[![master](https://travis-ci.org/DaoCasino/casino-backend?branch=master)](https://travis-ci.org/DaoCasino/casino-backend) +Develop|[![develop](https://travis-ci.org/DaoCasino/casino-backend?branch=develop)](https://travis-ci.org/DaoCasino/casino-backend) + From 0d218332975af2b2f23d7ea7db2dc4c42f07a639 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 16 Apr 2020 18:00:56 +0300 Subject: [PATCH 16/19] fix missing closing bracket --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 76f23c9..960aaba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,4 +54,4 @@ jobs: fi after_success: - - bash <(curl -s https://codecov.io/bash \ No newline at end of file + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file From c3c873b57f782d176938e85856ed51df6ccd1180 Mon Sep 17 00:00:00 2001 From: Emil Guseynov Date: Thu, 16 Apr 2020 18:21:41 +0300 Subject: [PATCH 17/19] config path --- main.go | 8 +++----- utils.go | 12 ++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index feb58d0..262db29 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "flag" broker "github.com/DaoCasino/platform-action-monitor-client" ) @@ -23,14 +22,13 @@ type Config struct { } } - +const defaultConfigPath = "/etc/casino/config.toml" +const configEnvVar = "CONFIG_PATH" func main() { - configPath := flag.String("config", "/etc/config", "config file path") - flag.Parse() app := App{} cfg := Config{} - readConfigFile(&cfg, *configPath) + readConfigFile(&cfg, getConfigPath(configEnvVar, defaultConfigPath)) readEnv(&cfg) app.Initialize( readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, diff --git a/utils.go b/utils.go index 62789ad..4e770f9 100644 --- a/utils.go +++ b/utils.go @@ -1,10 +1,12 @@ package main import ( + "flag" "github.com/BurntSushi/toml" "github.com/kelseyhightower/envconfig" "github.com/rs/zerolog/log" "io/ioutil" + "os" "strconv" "strings" ) @@ -54,6 +56,16 @@ func readEnv(cfg *Config) { } } +func getConfigPath(envVar, defaultValue string) string { + configPath := flag.String("config", defaultValue, "config file path") + flag.Parse() + cfgPath, isSet := os.LookupEnv(envVar) + if isSet { + configPath = &cfgPath + } + return *configPath +} + func getAddr(port int) string { return ":" + strconv.Itoa(port) } \ No newline at end of file From def5aec63b8d61983484a617128c0d8c087b62a9 Mon Sep 17 00:00:00 2001 From: Algys Ievlev Date: Tue, 21 Apr 2020 18:27:43 +0300 Subject: [PATCH 18/19] fix chainID in transaction sing func --- app.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index 73c356b..41360f7 100644 --- a/app.go +++ b/app.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/hex" "encoding/json" broker "github.com/DaoCasino/platform-action-monitor-client" "github.com/eoscanada/eos-go" @@ -231,7 +232,8 @@ func (app *App) SignQuery(writer ResponseWriter, req *Request) { func(app *App) SignTransaction(trx *eos.SignedTransaction) (*eos.SignedTransaction, error) { blockchain := app.BlockChain publicKeys, _ := blockchain.KeyBag.AvailableKeys() - return blockchain.KeyBag.Sign(trx, []byte(blockchain.ChainID), publicKeys[0]) + chainID, _ := hex.DecodeString(blockchain.ChainID) + return blockchain.KeyBag.Sign(trx, chainID, publicKeys[0]) } func (app *App) InitializeRoutes() { From 8c687fb93202e3c2790e90e2b2b6c68e5dbd31e3 Mon Sep 17 00:00:00 2001 From: Algys Ievlev Date: Tue, 21 Apr 2020 22:43:47 +0300 Subject: [PATCH 19/19] fix signidice signature (change from ECDSA to RSA) --- app.go | 15 ++++++++++----- blockchain.go | 6 +++--- go.mod | 2 -- go.sum | 30 ++++++++---------------------- main.go | 3 ++- main_test.go | 5 +++-- utils.go | 30 ++++++++++++++++++++++++++++++ 7 files changed, 56 insertions(+), 35 deletions(-) diff --git a/app.go b/app.go index 41360f7..92feb49 100644 --- a/app.go +++ b/app.go @@ -2,6 +2,7 @@ package main import ( "context" + "crypto/rsa" "encoding/hex" "encoding/json" broker "github.com/DaoCasino/platform-action-monitor-client" @@ -35,12 +36,14 @@ type App struct { KeyBag eos.KeyBag ChainID string CasinoAccountName string + SignidiceKey *rsa.PrivateKey } } func (app *App) Initialize(wif string, blockChainUrl string, chainID string, - offsetPath string, brokerURL string, topicID broker.EventType, casinoAccountName, level string) { - + offsetPath string, brokerURL string, topicID broker.EventType, + casinoAccountName, level string, signidiceKey *rsa.PrivateKey, +) { InitLogger(level) if strings.ToLower(level) == "debug" { broker.EnableDebugLogging() @@ -51,6 +54,7 @@ func (app *App) Initialize(wif string, blockChainUrl string, chainID string, app.BlockChain.API = eos.New(blockChainUrl) app.BlockChain.ChainID = chainID app.BlockChain.CasinoAccountName = casinoAccountName + app.BlockChain.SignidiceKey = signidiceKey log.Debug().Msg("Reading private key from wif") if app.BlockChain.KeyBag.Add(wif) != nil { @@ -65,7 +69,7 @@ func (app *App) Initialize(wif string, blockChainUrl string, chainID string, } type BrokerData struct { - Digest string `json:"digest"` + Digest eos.Checksum256 `json:"digest"` } func (app *App) processEvent(event *broker.Event) { @@ -78,8 +82,8 @@ func (app *App) processEvent(event *broker.Event) { return } - blockchain, api := app.BlockChain, app.BlockChain.API - signature, signError := blockchain.KeyBag.Keys[0].Sign([]byte(data.Digest)) + api := app.BlockChain.API + signature, signError := rsaSign(data.Digest, app.BlockChain.SignidiceKey) if signError != nil { log.Warn().Msg("Couldnt sign signidice_part_2, reason=" + signError.Error()) @@ -98,6 +102,7 @@ func (app *App) processEvent(event *broker.Event) { result, sendError := api.PushTransaction(packedTx) if sendError != nil { log.Warn().Msg("Failed to send transaction, reason: " + sendError.Error()) + return } log.Debug().Msg("Successfully signed and sent txn, id: " + result.TransactionID) } diff --git a/blockchain.go b/blockchain.go index 7f75d26..e816b8b 100644 --- a/blockchain.go +++ b/blockchain.go @@ -2,7 +2,6 @@ package main import ( "github.com/eoscanada/eos-go" - "github.com/eoscanada/eos-go/ecc" ) func NewSigndice(contract, casinoAccount string, requestID uint64, signature string) *eos.Action { @@ -26,8 +25,8 @@ type Signidice struct { } -func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string, requestID uint64, signature ecc.Signature) (*eos.SignedTransaction, *eos.PackedTransaction, error) { - action := NewSigndice(contract, casinoAccount, requestID, string(signature.Content)) +func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string,requestID uint64, signature string) (*eos.SignedTransaction, *eos.PackedTransaction, error) { + action := NewSigndice(contract, casinoAccount, requestID, signature) txOpts := &eos.TxOptions{} if err := txOpts.FillFromChain(api); err != nil { @@ -40,3 +39,4 @@ func GetSigndiceTransaction(api *eos.API, contract, casinoAccount string, reques } return signedTx, packedTx, nil } + diff --git a/go.mod b/go.mod index 3245861..d642c66 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,8 @@ require ( github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc github.com/eoscanada/eos-go v0.9.0 github.com/gorilla/mux v1.7.4 - github.com/gorilla/websocket v1.4.2 // indirect github.com/kelseyhightower/envconfig v1.4.0 github.com/rs/zerolog v1.18.0 - github.com/satori/go.uuid v1.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/zenazn/goji v0.9.0 ) diff --git a/go.sum b/go.sum index 12e0ca5..c76ef06 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= @@ -14,16 +13,6 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf945a117 h1:xR9Oszgt0A95J3Nb3bw9T1ps5owlB92MzYzhmx4qehQ= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200406103943-adacf945a117/go.mod h1:NGkkfL3UorfxNeHy28xGI19nJwm/8aGZ5ZxxCLRilRI= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d h1:tvtqU88AX11DbwWcEt7zPLvKH5atPeUIW9jlBkxxWjQ= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407103538-a9ef7ce3b10d/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838 h1:t7rr0VbZu839A/LunvGzzBQY8Q7zp376+FXrqeLzWGQ= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200407172818-3b77adacd838/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f2178ed14 h1:0J3NbHihh8rvZrxb73jJtsOWgIkAtGDwNR8piYKVxrQ= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200410000123-109f2178ed14/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a h1:+QgL6LOmc+v85OKBGts/XkZNHFYLCDDWdEyDO0d6b3Y= -github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413122422-83c362e7417a/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc h1:KpumOTuGgDkttODKAOwKeIw6EBvJ3v+2PaK6yrFumpQ= github.com/DaoCasino/platform-action-monitor-client v0.0.0-20200413133148-52406924efbc/go.mod h1:YxQzP8t+pdya1eeKRWf+5oLxhqtV2FXQTEqSH63vh0E= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -88,8 +77,10 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucsky/cuid v1.0.2 h1:z4XlExeoderxoPj2/dxKOyPxe9RCOu7yNq9/XWxIUMQ= @@ -113,6 +104,7 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -121,8 +113,6 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619 h1:fVrZXJsfrSbHN14BA6F0x2vk46sh7wZNgHUghmFbX4s= -github.com/qct/bitmex-go v0.0.0-20180809015409-d8251bd51619/go.mod h1:UKfPBpa0fuPjY5QagVNkCdwF0EXMmZj7Ku2PAcLXeN0= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -132,8 +122,6 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -170,6 +158,7 @@ go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -179,21 +168,17 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -208,12 +193,12 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -226,4 +211,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/main.go b/main.go index 262db29..f683b53 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ type Config struct { } BlockChain struct { PrivateKeyPath string `envconfig:"PRIVATEKEY_PATH"` + SignidiceKeyPath string `envconfig:"SIGNIDICEKEY_PATH"` Url string ChainID string CasinoAccountName string @@ -33,6 +34,6 @@ func main() { app.Initialize( readWIF(cfg.BlockChain.PrivateKeyPath), cfg.BlockChain.Url, cfg.BlockChain.ChainID, cfg.Broker.TopicOffsetPath, cfg.Broker.Url, cfg.Broker.TopicID, cfg.BlockChain.CasinoAccountName, - cfg.Server.LogLevel) + cfg.Server.LogLevel, readRsa(cfg.BlockChain.SignidiceKeyPath)) app.Run(getAddr(cfg.Server.Port)) } diff --git a/main_test.go b/main_test.go index 051bd34..302f3f8 100644 --- a/main_test.go +++ b/main_test.go @@ -27,7 +27,7 @@ func TestMain(m *testing.M) { panic(err) } a.Initialize(privateKey, "nodeURL", - chainID, "/some/path", "brokerUrl", broker.EventType(2), "a", "b") + chainID, "/some/path", "brokerUrl", broker.EventType(2), "a", "b", nil) code := m.Run() os.Exit(code) } @@ -69,7 +69,7 @@ func TestSignTransactionNormal(t *testing.T) { ], "context_free_data": [] }`) - signedRawTx := []byte(`{"expiration":"2020-03-25T17:41:38","ref_block_num":33633,"ref_block_prefix":1346981524,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"eosio.token","name":"transfer","authorization":[{"actor":"lordofdao","permission":"active"}],"data":"0000a0262d9a2e8d00a8498ba64b23301027000000000000044245540000000000"}],"transaction_extensions":[],"signatures":["SIG_K1_KZGbvWTgBGeidB1NUVjx3SFubLgCPeDrZztau9AWgUiNEknmT9ajNSEXoKpEbVtx4XuwLebxPWz6hDzUgYbEBxed2SkKGi","SIG_K1_KVKV98c5Q7cCGqbSSHYsYYo473TeaibkDoLb5V26BHeioY623wAmNLgo9L86nqcy7gKLE8u9dnDnBLR5UVcL65wwaRF34H"],"context_free_data":[]}`) + signedRawTx := []byte(`{"expiration":"2020-03-25T17:41:38","ref_block_num":33633,"ref_block_prefix":1346981524,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"eosio.token","name":"transfer","authorization":[{"actor":"lordofdao","permission":"active"}],"data":"0000a0262d9a2e8d00a8498ba64b23301027000000000000044245540000000000"}],"transaction_extensions":[],"signatures":["SIG_K1_KZGbvWTgBGeidB1NUVjx3SFubLgCPeDrZztau9AWgUiNEknmT9ajNSEXoKpEbVtx4XuwLebxPWz6hDzUgYbEBxed2SkKGi","SIG_K1_Ke9CHrWSYPeasvNqy6TCYgZkxe9m5aDtXDB1njTyvyjET2iqQfZkRk7HwdHmMDH9z6VAxcno3gJsZUF83cC8cT2L1fWRLK"],"context_free_data":[]}`) origTx := eos.SignedTransaction{} err := json.Unmarshal(rawTransaction, &origTx) if err != nil { @@ -78,6 +78,7 @@ func TestSignTransactionNormal(t *testing.T) { } result, signError := a.SignTransaction(&origTx) + assert.Nil(signError, "failed to sign transaction") byteString, _ := json.Marshal(result) assert.Equal(signedRawTx, byteString) diff --git a/utils.go b/utils.go index 4e770f9..7e5b93b 100644 --- a/utils.go +++ b/utils.go @@ -1,8 +1,15 @@ package main import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" "flag" "github.com/BurntSushi/toml" + "github.com/eoscanada/eos-go" "github.com/kelseyhightower/envconfig" "github.com/rs/zerolog/log" "io/ioutil" @@ -41,6 +48,19 @@ func readWIF(filename string) string { return wif } +func readRsa(filename string) *rsa.PrivateKey { + data, err := ioutil.ReadFile(filename) + if err != nil { + log.Panic().Msg(err.Error()) + } + block, _ := pem.Decode(data) + key, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + log.Panic().Msg(err.Error()) + } + return key +} + func readConfigFile(cfg *Config, path string) { _, err := toml.DecodeFile(path, &cfg) @@ -68,4 +88,14 @@ func getConfigPath(envVar, defaultValue string) string { func getAddr(port int) string { return ":" + strconv.Itoa(port) +} + +func rsaSign(digest eos.Checksum256, key *rsa.PrivateKey) (string, error) { + sign, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, digest) + if err != nil { + return "", err + } + + // contract require base64 string + return base64.StdEncoding.EncodeToString(sign), nil } \ No newline at end of file