aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arbiter/Dockerfile6
-rw-r--r--arbiter/arbiter.go165
-rwxr-xr-xarbiter/tests.sh3
-rw-r--r--docker-compose-test.yaml13
-rw-r--r--docker-compose.yaml13
-rw-r--r--hived/Dockerfile6
-rw-r--r--hived/hived.go10
-rw-r--r--telebot/Dockerfile6
8 files changed, 187 insertions, 35 deletions
diff --git a/arbiter/Dockerfile b/arbiter/Dockerfile
index fe3fb31..849b345 100644
--- a/arbiter/Dockerfile
+++ b/arbiter/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.13 as builder
+FROM alpine:3.16 as builder
ENV GOPROXY=https://goproxy.io
RUN apk update && apk upgrade
RUN apk add go git
@@ -8,13 +8,13 @@ RUN cd /arbiter && go mod download
COPY *.go /arbiter/
RUN cd /arbiter && go build
-FROM alpine:3.15 as certbuilder
+FROM alpine:3.16 as certbuilder
RUN apk add openssl
WORKDIR /certs
RUN openssl req -nodes -new -x509 -subj="/C=US/ST=Denial/L=springfield/O=Dis/CN=localhost" -keyout server.key -out server.cert
# FROM gcr.io/distroless/static-debian10
-FROM alpine:3.13
+FROM alpine:3.16
COPY --from=certbuilder /certs /certs
COPY --from=builder /arbiter/arbiter /arbiter/
ENTRYPOINT ["/arbiter/arbiter"]
diff --git a/arbiter/arbiter.go b/arbiter/arbiter.go
index 2806842..9cb3ad0 100644
--- a/arbiter/arbiter.go
+++ b/arbiter/arbiter.go
@@ -3,12 +3,16 @@ package main
import (
"context"
"crypto/tls"
+ "encoding/json"
"errors"
"flag"
"fmt"
+ "io/ioutil"
"net/http"
+ "net/url"
"os"
"os/signal"
+ "sync"
"time"
"github.com/go-redis/redis/v8"
@@ -28,8 +32,26 @@ var (
const (
SERVER_DEPLOYMENT_TYPE = "SERVER_DEPLOYMENT_TYPE"
+ coingeckoAPIURLv3 = "https://api.coingecko.com/api/v3"
)
+type HttpHandlerFunc func(http.ResponseWriter, *http.Request)
+
+type HttpHandler struct {
+ name string
+ function HttpHandlerFunc
+}
+
+type priceChanStruct struct {
+ name string
+ price float64
+}
+
+type errorChanStruct struct {
+ hasError bool
+ err error
+}
+
// OWASP: https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
func addSecureHeaders(w *http.ResponseWriter) {
(*w).Header().Set("Cache-Control", "no-store")
@@ -40,49 +62,152 @@ func addSecureHeaders(w *http.ResponseWriter) {
(*w).Header().Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
}
+//binance
+func getPriceFromBinance(name, unit string,
+ wg *sync.WaitGroup,
+ priceChan chan<- priceChanStruct,
+ errChan chan<- errorChanStruct) {
+
+}
+
+//kucoin
+func getPriceFromKu(name, uni string,
+ wg *sync.WaitGroup,
+ priceChan chan<- priceChanStruct,
+ errChan chan<- errorChanStruct) {
+
+}
+
+func getPriceFromCoinGecko(
+ name, unit string,
+ wg *sync.WaitGroup,
+ priceChan chan<- priceChanStruct,
+ errChan chan<- errorChanStruct) {
+ defer wg.Done()
+
+ params := "/simple/price?ids=" + url.QueryEscape(name) + "&" +
+ "vs_currencies=" + url.QueryEscape(unit)
+ path := coingeckoAPIURLv3 + params
+ fmt.Println(path)
+ resp, err := http.Get(path)
+ if err != nil {
+ priceChan <- priceChanStruct{name: name, price: 0.}
+ errChan <- errorChanStruct{hasError: true, err: err}
+ log.Error().Err(err)
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ priceChan <- priceChanStruct{name: name, price: 0.}
+ errChan <- errorChanStruct{hasError: true, err: err}
+ log.Error().Err(err)
+ }
+
+ jsonBody := make(map[string]interface{})
+ err = json.Unmarshal(body, &jsonBody)
+ if err != nil {
+ priceChan <- priceChanStruct{name: name, price: 0.}
+ errChan <- errorChanStruct{hasError: true, err: err}
+ log.Error().Err(err)
+ }
+
+ price := jsonBody[name].(map[string]interface{})[unit].(float64)
+
+ log.Info().Msg(string(body))
+
+ priceChan <- priceChanStruct{name: name, price: price}
+ errChan <- errorChanStruct{hasError: false, err: nil}
+}
+
func arbHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
if r.Method != "GET" {
http.Error(w, "Method is not supported.", http.StatusNotFound)
}
addSecureHeaders(&w)
- //binance
- //kucoin
+
+ var name string
+ var unit string
+ params := r.URL.Query()
+ for key, value := range params {
+ switch key {
+ case "name":
+ name = value[0]
+ case "unit":
+ unit = value[0]
+ default:
+ log.Error().Err(errors.New("Got unexpected parameter."))
+ }
+ }
+
+ priceChan := make(chan priceChanStruct, 1)
+ errChan := make(chan errorChanStruct, 1)
+ var wg sync.WaitGroup
+ wg.Add(1)
+ getPriceFromCoinGecko(name, unit, &wg, priceChan, errChan)
+ wg.Wait()
+
+ select {
+ case err := <-errChan:
+ if err.hasError != false {
+ log.Error().Err(err.err)
+ }
+ default:
+ log.Error().Err(errors.New("We shouldnt be here"))
+ }
+
+ var price priceChanStruct
+ select {
+ case priceCh := <-priceChan:
+ price = priceCh
+ default:
+ log.Fatal().Err(errors.New("We shouldnt be here"))
+ }
+
+ json.NewEncoder(w).Encode(map[string]interface{}{
+ "name": price.name,
+ "price": price.price,
+ "unit": unit,
+ "err": "",
+ "isSuccessful": true,
+ })
}
-func startServer(gracefulWait time.Duration) {
+func setupLogging() {
+ zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
+}
+
+func startServer(gracefulWait time.Duration,
+ handlers []HttpHandler,
+ serverDeploymentType string, port string) {
r := mux.NewRouter()
cfg := &tls.Config{
MinVersion: tls.VersionTLS13,
- // CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
- // PreferServerCipherSuites: true,
- // CipherSuites: []uint16{
- // tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- // tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- // tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
- // tls.TLS_RSA_WITH_AES_256_CBC_SHA,
- // },
}
srv := &http.Server{
- Addr: "0.0.0.0:" + *flagPort,
+ Addr: "0.0.0.0:" + port,
WriteTimeout: time.Second * 15,
ReadTimeout: time.Second * 15,
Handler: r,
TLSConfig: cfg,
}
- r.HandleFunc("/crypto/arb", arbHandler)
+
+ for i := 0; i < len(handlers); i++ {
+ r.HandleFunc(handlers[i].name, handlers[i].function)
+ }
go func() {
var certPath, keyPath string
- if os.Getenv(SERVER_DEPLOYMENT_TYPE) == "deployment" {
+ if os.Getenv(serverDeploymentType) == "deployment" {
certPath = "/certs/fullchain1.pem"
keyPath = "/certs/privkey1.pem"
- } else if os.Getenv(SERVER_DEPLOYMENT_TYPE) == "test" {
+ } else if os.Getenv(serverDeploymentType) == "test" {
certPath = "/certs/server.cert"
keyPath = "/certs/server.key"
} else {
- log.Fatal().Err(errors.New(fmt.Sprintf("unknown deployment kind: %s", SERVER_DEPLOYMENT_TYPE)))
+ log.Fatal().Err(errors.New(fmt.Sprintf("unknown deployment kind: %s", serverDeploymentType)))
}
if err := srv.ListenAndServeTLS(certPath, keyPath); err != nil {
log.Fatal().Err(err)
@@ -99,10 +224,6 @@ func startServer(gracefulWait time.Duration) {
log.Info().Msg("gracefully shut down the server")
}
-func setupLogging() {
- zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
-}
-
func main() {
var gracefulWait time.Duration
flag.DurationVar(&gracefulWait, "gracefulwait", time.Second*15, "the duration to wait during the graceful shutdown")
@@ -115,5 +236,7 @@ func main() {
defer rdb.Close()
setupLogging()
- startServer(gracefulWait)
+ var handlerFuncs = []HttpHandler{{name: "/arb", function: arbHandler}}
+
+ startServer(gracefulWait, handlerFuncs, SERVER_DEPLOYMENT_TYPE, *flagPort)
}
diff --git a/arbiter/tests.sh b/arbiter/tests.sh
new file mode 100755
index 0000000..1fe9792
--- /dev/null
+++ b/arbiter/tests.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+curl -X GET "https://localhost:8009/arb?name=ethereum&unit=usd"
diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml
index afee17a..99d9a76 100644
--- a/docker-compose-test.yaml
+++ b/docker-compose-test.yaml
@@ -36,6 +36,19 @@ services:
- ALL
environment:
- SERVER_DEPLOYMENT_TYPE=test
+ arbiter:
+ image: arbiter
+ build:
+ context: ./arbiter
+ networks:
+ - mainnet
+ ports:
+ - "8009:8009"
+ entrypoint: ["/arbiter/arbiter"]
+ cap_drop:
+ - ALL
+ environment:
+ - SERVER_DEPLOYMENT_TYPE=test
redis:
image: redis:6.2-alpine
networks:
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 90ff90d..7ce5495 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -51,6 +51,19 @@ services:
- ALLOW_EMPTY_PASSWORD=yes
volumes:
- redis-data:/data/
+ arbiter:
+ image: arbiter
+ build:
+ context: ./arbiter
+ networks:
+ - mainnet
+ ports:
+ - "8009:8009"
+ entrypoint: ["/arbiter/abiter"]
+ cap_drop:
+ - ALL
+ environment:
+ - SERVER_DEPLOYMENT_TYPE=deployment
networks:
mainnet:
driver: bridge
diff --git a/hived/Dockerfile b/hived/Dockerfile
index 7eb1a8d..1eaf999 100644
--- a/hived/Dockerfile
+++ b/hived/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.13 as builder
+FROM alpine:3.16 as builder
ENV GOPROXY=https://goproxy.io
RUN apk update && apk upgrade
RUN apk add go git
@@ -8,13 +8,13 @@ RUN cd /hived && go mod download
COPY *.go /hived/
RUN cd /hived && go build
-FROM alpine:3.15 as certbuilder
+FROM alpine:3.16 as certbuilder
RUN apk add openssl
WORKDIR /certs
RUN openssl req -nodes -new -x509 -subj="/C=US/ST=Denial/L=springfield/O=Dis/CN=localhost" -keyout server.key -out server.cert
# FROM gcr.io/distroless/static-debian10
-FROM alpine:3.13
+FROM alpine:3.16
COPY --from=certbuilder /certs /certs
COPY --from=builder /hived/hived /hived/
COPY ./docker-entrypoint.sh /hived/
diff --git a/hived/hived.go b/hived/hived.go
index 940c2ed..a205352 100644
--- a/hived/hived.go
+++ b/hived/hived.go
@@ -130,7 +130,7 @@ func getPriceFromCoinGecko(
errChan <- errorChanStruct{hasError: false, err: nil}
}
-func sendGetToCryptoCompare(
+func getPriceFromCryptoCompare(
name, unit string,
wg *sync.WaitGroup,
priceChan chan<- priceChanStruct,
@@ -204,7 +204,7 @@ func priceHandler(w http.ResponseWriter, r *http.Request) {
defer close(errChan)
defer close(priceChan)
wg.Add(1)
- go sendGetToCryptoCompare(name, unit, &wg, priceChan, errChan)
+ go getPriceFromCryptoCompare(name, unit, &wg, priceChan, errChan)
wg.Wait()
select {
@@ -271,8 +271,8 @@ func pairHandler(w http.ResponseWriter, r *http.Request) {
defer close(errChan)
wg.Add(2)
- go sendGetToCryptoCompare(one, "USD", &wg, priceChan, errChan)
- go sendGetToCryptoCompare(two, "USD", &wg, priceChan, errChan)
+ go getPriceFromCryptoCompare(one, "USD", &wg, priceChan, errChan)
+ go getPriceFromCryptoCompare(two, "USD", &wg, priceChan, errChan)
wg.Wait()
for i := 0; i < 2; i++ {
@@ -362,7 +362,7 @@ func alertManager() {
wg.Add(len(vars))
for i := range vars {
- go sendGetToCryptoCompare(vars[i], "USD", &wg, priceChan, errChan)
+ go getPriceFromCryptoCompare(vars[i], "USD", &wg, priceChan, errChan)
}
wg.Wait()
diff --git a/telebot/Dockerfile b/telebot/Dockerfile
index d358ed7..a3cebf9 100644
--- a/telebot/Dockerfile
+++ b/telebot/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.13 as builder
+FROM alpine:3.16 as builder
ENV GOPROXY=https://goproxy.io
RUN apk update && apk upgrade
RUN apk add go git
@@ -8,13 +8,13 @@ RUN cd /telebot && go mod download
COPY *.go /telebot/
RUN cd /telebot && go build
-FROM alpine:3.15 as certbuilder
+FROM alpine:3.16 as certbuilder
RUN apk add openssl
WORKDIR /certs
RUN openssl req -nodes -new -x509 -subj="/C=US/ST=Denial/L=springfield/O=Dis/CN=localhost" -keyout server.key -out server.cert
# FROM gcr.io/distroless/static-debian10
-FROM alpine:3.13
+FROM alpine:3.16
COPY --from=certbuilder /certs /certs
COPY --from=builder /telebot/telebot /telebot/
COPY ./docker-entrypoint.sh /telebot/