diff --git a/.appveyor.yml b/.appveyor.yml index 122e2005..dcda595c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -36,7 +36,7 @@ services: init: - set PATH=%POSTGRES_PATH%\bin;%PATH% - - set PATH=C:\go118\bin;%PATH% + - set PATH=C:\go119\bin;%PATH% install: - set Path=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%Path% @@ -55,7 +55,7 @@ before_test: test_script: # test back-end - - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.2 + - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0 - '%GOPATH%\bin\golangci-lint.exe run --verbose' - ps: >- if($env:APPVEYOR_SCHEDULED_BUILD -eq 'true') { diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index e95c7b3a..bd40d8c8 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -8,8 +8,8 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '1.18.x' + go-version: '1.19.x' - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.46.2 + version: v1.48.0 diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 35fa86f1..68f45526 100644 --- a/.github/workflows/proto-lint.yml +++ b/.github/workflows/proto-lint.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.18.x + go-version: 1.19.x - name: Setup build depends run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index abc67933..03f40307 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,7 +1,7 @@ on: [push, pull_request] name: CI env: - GO_VERSION: 1.18.x + GO_VERSION: 1.19.x jobs: backend-psql: name: GoCryptoTrader back-end with PSQL @@ -115,6 +115,7 @@ jobs: PSQL_SSLMODE: disable GOARCH: 386 CGO_ENABLED: 1 + CGO_CFLAGS: -fno-stack-protector - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 diff --git a/.golangci.yml b/.golangci.yml index 59392aaf..4264bc95 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,12 +18,12 @@ linters: - govet - ineffassign - staticcheck - - structcheck - typecheck # - unused # - varcheck # disabled by default linters +# - asasalint - asciicheck - bidichk - bodyclose @@ -38,8 +38,10 @@ linters: - errchkjson - errname # - errorlint + - execinquery # - exhaustive -# - exhaustivestruct +# - exhaustivestruct // abandoned by its owner, replaced with exhaustruct +# - exhaustruct - exportloopref # - forbidigo - forcetypeassert @@ -65,7 +67,7 @@ linters: - goprintffuncname - gosec - grouper - - ifshort +# - ifshort // deprecated by its owner # - importas # - interfacer // deprecated by its owner # - ireturn @@ -77,9 +79,13 @@ linters: - nakedret # - nestif - nilerr +# - nilnil # - nlreturn - noctx - nolintlint +# - nonamedreturns +# - nosnakecase + - nosprintfhostport # - paralleltest - prealloc - predeclared @@ -87,14 +93,18 @@ linters: - revive - rowserrcheck # - scopelint // deprecated since v1.39.0, replaced by exportloopref -# - sqlclosecheck + - sqlclosecheck + - structcheck - stylecheck # - tagliatelle + - tenv # - testpackage - thelper - tparallel - unconvert - unparam + - usestdlibvars +# - varnamelen - wastedassign - whitespace # - wrapcheck @@ -103,8 +113,6 @@ linters: linters-settings: govet: check-shadowing: true - golint: - min-confidence: 0 goconst: min-occurrences: 6 depguard: @@ -139,3 +147,6 @@ issues: # The following silences false positives in table tests # https://github.com/kyoh86/scopelint/issues/4 - Using the variable on range scope `ti` in function literal + include: + - EXC0012 # revive: Comment exported (.+) should have comment( \(or a comment on this block\))? or be unexported + - EXC0014 # revive: Comment on exported (.+) should be of the form "(.+)..." diff --git a/Dockerfile b/Dockerfile index d06c22e3..6cbbec70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18 as build +FROM golang:1.19 as build WORKDIR /go/src/github.com/thrasher-corp/gocryptotrader COPY . . RUN GO111MODULE=on go mod vendor diff --git a/Makefile b/Makefile index 2265d82f..3dcf161a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LDFLAGS = -ldflags "-w -s" GCTPKG = github.com/thrasher-corp/gocryptotrader -LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.2 +LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0 LINTBIN = $(GOPATH)/bin/golangci-lint GCTLISTENPORT=9050 GCTPROFILERLISTENPORT=8085 diff --git a/backtester/common/common_types.go b/backtester/common/common_types.go index 83596106..2439d13f 100644 --- a/backtester/common/common_types.go +++ b/backtester/common/common_types.go @@ -20,7 +20,8 @@ const ( TradeStr = "trade" // DataCandle is an int64 representation of a candle data type - DataCandle = iota + DataCandle int64 = iota + // DataTrade is an int64 representation of a trade data type DataTrade ) diff --git a/backtester/config/config_test.go b/backtester/config/config_test.go index a16f2abe..8675ccc2 100644 --- a/backtester/config/config_test.go +++ b/backtester/config/config_test.go @@ -3,7 +3,6 @@ package config import ( "encoding/json" "errors" - "io/ioutil" "os" "path/filepath" "testing" @@ -458,7 +457,7 @@ func TestValidate(t *testing.T) { func TestReadConfigFromFile(t *testing.T) { tempDir := t.TempDir() - passFile, err := ioutil.TempFile(tempDir, "*.start") + passFile, err := os.CreateTemp(tempDir, "*.start") if err != nil { t.Fatalf("Problem creating temp file at %v: %s\n", passFile, err) } diff --git a/backtester/config/configbuilder/main.go b/backtester/config/configbuilder/main.go index 456ef391..aca38ce5 100644 --- a/backtester/config/configbuilder/main.go +++ b/backtester/config/configbuilder/main.go @@ -108,7 +108,7 @@ func main() { yn := quickParse(reader) if yn == y || yn == yes { var fp, wd string - extension := "strat" // nolint:misspell // its shorthand for strategy + extension := "strat" //nolint:misspell // its shorthand for strategy for { wd, err = os.Getwd() if err != nil { @@ -427,9 +427,9 @@ func parseDatabase(reader *bufio.Reader, cfg *config.Config) error { } fmt.Println("What is the database Port? eg 1337") input = quickParse(reader) - var port float64 + var port uint64 if input != "" { - port, err = strconv.ParseFloat(input, 64) + port, err = strconv.ParseUint(input, 10, 16) if err != nil { return err } diff --git a/backtester/data/kline/database/database_test.go b/backtester/data/kline/database/database_test.go index df8b37c6..8d513271 100644 --- a/backtester/data/kline/database/database_test.go +++ b/backtester/data/kline/database/database_test.go @@ -3,7 +3,6 @@ package database import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -39,7 +38,7 @@ func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) @@ -85,16 +84,7 @@ func TestLoadDataCandles(t *testing.T) { } database.MigrationDir = filepath.Join("..", "..", "..", "..", "database", "migrations") testhelpers.MigrationDir = filepath.Join("..", "..", "..", "..", "database", "migrations") - _, err = testhelpers.ConnectToDatabase(&dbConfg) - if err != nil { - t.Error(err) - } - - bot.DatabaseManager, err = engine.SetupDatabaseConnectionManager(&bot.Config.Database) - if err != nil { - t.Error(err) - } - err = bot.DatabaseManager.Start(&bot.ServicesWG) + conn, err := testhelpers.ConnectToDatabase(&dbConfg) if err != nil { t.Error(err) } @@ -133,6 +123,10 @@ func TestLoadDataCandles(t *testing.T) { if err != nil { t.Error(err) } + + if err = conn.SQL.Close(); err != nil { + t.Error(err) + } } func TestLoadDataTrades(t *testing.T) { @@ -165,16 +159,7 @@ func TestLoadDataTrades(t *testing.T) { } database.MigrationDir = filepath.Join("..", "..", "..", "..", "database", "migrations") testhelpers.MigrationDir = filepath.Join("..", "..", "..", "..", "database", "migrations") - _, err = testhelpers.ConnectToDatabase(&dbConfg) - if err != nil { - t.Error(err) - } - - bot.DatabaseManager, err = engine.SetupDatabaseConnectionManager(&bot.Config.Database) - if err != nil { - t.Error(err) - } - err = bot.DatabaseManager.Start(&bot.ServicesWG) + conn, err := testhelpers.ConnectToDatabase(&dbConfg) if err != nil { t.Error(err) } @@ -206,6 +191,10 @@ func TestLoadDataTrades(t *testing.T) { if err != nil { t.Error(err) } + + if err = conn.SQL.Close(); err != nil { + t.Error(err) + } } func TestLoadDataInvalid(t *testing.T) { diff --git a/backtester/eventhandlers/exchange/slippage/slippage.go b/backtester/eventhandlers/exchange/slippage/slippage.go index 364e7edf..3932da81 100644 --- a/backtester/eventhandlers/exchange/slippage/slippage.go +++ b/backtester/eventhandlers/exchange/slippage/slippage.go @@ -22,7 +22,7 @@ func EstimateSlippagePercentage(maximumSlippageRate, minimumSlippageRate decimal // eg 80 means for every dollar, keep 80% randSeed := int(minimumSlippageRate.IntPart()) - int(maximumSlippageRate.IntPart()) if randSeed > 0 { - result := int64(rand.Intn(randSeed)) // nolint:gosec // basic number generation required, no need for crypto/rand + result := int64(rand.Intn(randSeed)) //nolint:gosec // basic number generation required, no need for crypto/rand return maximumSlippageRate.Add(decimal.NewFromInt(result)).Div(decimal.NewFromInt(100)) } diff --git a/backtester/eventhandlers/strategies/base/base_types.go b/backtester/eventhandlers/strategies/base/base_types.go index ad7ecfe2..3026bad7 100644 --- a/backtester/eventhandlers/strategies/base/base_types.go +++ b/backtester/eventhandlers/strategies/base/base_types.go @@ -11,7 +11,7 @@ var ( // ErrSimultaneousProcessingOnly is raised when a strategy is improperly configured ErrSimultaneousProcessingOnly = errors.New("this strategy only supports simultaneous processing") // ErrStrategyNotFound used when strategy specified in strategy config does not exist - ErrStrategyNotFound = errors.New("not found. Please ensure the strategy-settings field 'name' is spelled properly in your .strat config") // nolint:misspell // its shorthand for strategy + ErrStrategyNotFound = errors.New("not found. Please ensure the strategy-settings field 'name' is spelled properly in your .strat config") //nolint:misspell // its shorthand for strategy // ErrInvalidCustomSettings used when bad custom settings are found in the strategy config ErrInvalidCustomSettings = errors.New("invalid custom settings in config") // ErrTooMuchBadData used when there is too much missing data diff --git a/backtester/eventtypes/event/event.go b/backtester/eventtypes/event/event.go index 95946d41..b9611562 100644 --- a/backtester/eventtypes/event/event.go +++ b/backtester/eventtypes/event/event.go @@ -77,6 +77,7 @@ func (b *Base) GetReasons() []string { return b.Reasons } +// GetBase returns an event base func (b *Base) GetBase() *Base { return b } diff --git a/backtester/report/report.go b/backtester/report/report.go index 1505d651..3f1315eb 100644 --- a/backtester/report/report.go +++ b/backtester/report/report.go @@ -138,7 +138,7 @@ func (d *Data) enhanceCandles() error { Asset: lookup.Asset, Pair: lookup.Pair, Interval: lookup.Interval, - Watermark: fmt.Sprintf("%s - %s - %s", strings.Title(lookup.Exchange), lookup.Asset.String(), lookup.Pair.Upper()), // nolint // Title usage + Watermark: fmt.Sprintf("%s - %s - %s", strings.Title(lookup.Exchange), lookup.Asset.String(), lookup.Pair.Upper()), //nolint // Title usage } statsForCandles := diff --git a/cmd/apichecker/apicheck.go b/cmd/apichecker/apicheck.go index 59de6383..9c364332 100644 --- a/cmd/apichecker/apicheck.go +++ b/cmd/apichecker/apicheck.go @@ -1717,7 +1717,7 @@ func htmlScrapeBitfinex(htmlData *HTMLScrapingData) ([]string, error) { return resp, nil } -// htmlScrapeBinance gets checkstring for binance exchange +// htmlScrapeBinance gets checkstring for binance exchange func htmlScrapeBinance(htmlData *HTMLScrapingData) ([]string, error) { temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { diff --git a/cmd/documentation/documentation.go b/cmd/documentation/documentation.go index f058b1b5..f2dcef06 100644 --- a/cmd/documentation/documentation.go +++ b/cmd/documentation/documentation.go @@ -486,7 +486,7 @@ func GetPackageName(name string, capital bool) string { i = len(newStrings) - 1 } if capital { - return strings.Replace(strings.Title(newStrings[i]), "_", " ", -1) // nolint // ignore staticcheck strings.Title warning + return strings.Replace(strings.Title(newStrings[i]), "_", " ", -1) //nolint // ignore staticcheck strings.Title warning } return newStrings[i] } diff --git a/cmd/exchange_template/exchange_template.go b/cmd/exchange_template/exchange_template.go index 8fbefa40..da806d2b 100644 --- a/cmd/exchange_template/exchange_template.go +++ b/cmd/exchange_template/exchange_template.go @@ -146,7 +146,7 @@ func makeExchange(exchangeDirectory string, configTestFile *config.Config, exch fmt.Printf("Output directory: %s\n", exchangeDirectory) - exch.CapitalName = strings.Title(exch.Name) // nolint:staticcheck // Ignore Title usage warning + exch.CapitalName = strings.Title(exch.Name) //nolint:staticcheck // Ignore Title usage warning exch.Variable = exch.Name[0:2] newExchConfig := &config.Exchange{} newExchConfig.Name = exch.CapitalName diff --git a/cmd/exchange_wrapper_issues/main.go b/cmd/exchange_wrapper_issues/main.go index 53c89f8c..4a035688 100644 --- a/cmd/exchange_wrapper_issues/main.go +++ b/cmd/exchange_wrapper_issues/main.go @@ -878,7 +878,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) } func jsonifyInterface(params []interface{}) json.RawMessage { - response, _ := json.MarshalIndent(params, "", " ") // nolint:errchkjson // TODO: ignore this for now + response, _ := json.MarshalIndent(params, "", " ") //nolint:errchkjson // TODO: ignore this for now return response } diff --git a/cmd/websocket_client/main.go b/cmd/websocket_client/main.go index 5bda3bb3..769ff35b 100644 --- a/cmd/websocket_client/main.go +++ b/cmd/websocket_client/main.go @@ -5,7 +5,9 @@ import ( "errors" "fmt" "log" + "net" "net/http" + "strconv" "github.com/gorilla/websocket" "github.com/thrasher-corp/gocryptotrader/common" @@ -83,8 +85,8 @@ func main() { } listenAddr := cfg.RemoteControl.WebsocketRPC.ListenAddress - wsHost := fmt.Sprintf("ws://%s:%d/ws", common.ExtractHost(listenAddr), - common.ExtractPort(listenAddr)) + wsHost := fmt.Sprintf("ws://%s/ws", net.JoinHostPort(common.ExtractHost(listenAddr), + strconv.Itoa(common.ExtractPort(listenAddr)))) log.Printf("Connecting to websocket host: %s", wsHost) var dialer websocket.Dialer diff --git a/common/common.go b/common/common.go index d64c4cee..422d255e 100644 --- a/common/common.go +++ b/common/common.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "os" @@ -305,7 +306,7 @@ func EncodeURLValues(urlPath string, values url.Values) string { // ExtractHost returns the hostname out of a string func ExtractHost(address string) string { - host := strings.Split(address, ":")[0] + host, _, _ := net.SplitHostPort(address) if host == "" { return "localhost" } @@ -314,12 +315,12 @@ func ExtractHost(address string) string { // ExtractPort returns the port name out of a string func ExtractPort(host string) int { - portStrs := strings.Split(host, ":") - if len(portStrs) == 1 { + _, port, _ := net.SplitHostPort(host) + if port == "" { return 80 } - port, _ := strconv.Atoi(portStrs[1]) - return port + portInt, _ := strconv.Atoi(port) + return portInt } // GetURIPath returns the path of a URL given a URI diff --git a/common/crypto/crypto.go b/common/crypto/crypto.go index 3912d3f1..44a1e599 100644 --- a/common/crypto/crypto.go +++ b/common/crypto/crypto.go @@ -1,6 +1,6 @@ package crypto -// nolint:gosec // md5/sha1 hash functions used by some exchanges +//nolint:gosec // md5/sha1 hash functions used by some exchanges import ( "crypto/hmac" "crypto/md5" @@ -63,7 +63,7 @@ func GetRandomSalt(input []byte, saltLen int) ([]byte, error) { // GetMD5 returns a MD5 hash of a byte array func GetMD5(input []byte) ([]byte, error) { - m := md5.New() // nolint:gosec // hash function used by some exchanges + m := md5.New() //nolint:gosec // hash function used by some exchanges _, err := m.Write(input) return m.Sum(nil), err } @@ -108,7 +108,7 @@ func GetHMAC(hashType int, input, key []byte) ([]byte, error) { // Sha1ToHex takes a string, sha1 hashes it and return a hex string of the // result func Sha1ToHex(data string) (string, error) { - h := sha1.New() // nolint:gosec // hash function used by some exchanges + h := sha1.New() //nolint:gosec // hash function used by some exchanges _, err := h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)), err } diff --git a/common/file/archive/zip.go b/common/file/archive/zip.go index 6adc99aa..ac3c3792 100644 --- a/common/file/archive/zip.go +++ b/common/file/archive/zip.go @@ -33,7 +33,7 @@ func UnZip(src, dest string) (fileList []string, err error) { } for x := range z.File { - fPath := filepath.Join(dest, z.File[x].Name) // nolint // We ignore + fPath := filepath.Join(dest, z.File[x].Name) //nolint // We ignore // gosec linter above because the code below files the file traversal // bug when extracting archives if !strings.HasPrefix(fPath, filepath.Clean(dest)+string(os.PathSeparator)) { diff --git a/common/file/file_test.go b/common/file/file_test.go index 9671245a..4c391957 100644 --- a/common/file/file_test.go +++ b/common/file/file_test.go @@ -2,7 +2,6 @@ package file import ( "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -162,7 +161,7 @@ func TestWriteAsCSV(t *testing.T) { {"Sup", "bra"}, } - testFile, err := ioutil.TempFile(os.TempDir(), "gct-csv-test.*.csv") + testFile, err := os.CreateTemp(os.TempDir(), "gct-csv-test.*.csv") if err != nil { t.Fatal(err) } diff --git a/config/config.go b/config/config.go index 9bb5b617..c9a07f64 100644 --- a/config/config.go +++ b/config/config.go @@ -1771,7 +1771,7 @@ func (c *Config) AssetTypeEnabled(a asset.Item, exch string) (bool, error) { err = cfg.CurrencyPairs.IsAssetEnabled(a) if err != nil { - return false, nil // nolint:nilerr // non-fatal error + return false, nil //nolint:nilerr // non-fatal error } return true, nil } diff --git a/config/config_encryption_test.go b/config/config_encryption_test.go index 0547d76d..db210857 100644 --- a/config/config_encryption_test.go +++ b/config/config_encryption_test.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -142,7 +141,7 @@ func TestEncryptTwiceReusesSaltButNewCipher(t *testing.T) { tempDir := t.TempDir() // Prepare input - passFile, err := ioutil.TempFile(tempDir, "*.pw") + passFile, err := os.CreateTemp(tempDir, "*.pw") if err != nil { t.Fatalf("Problem creating temp file at %s: %s\n", tempDir, err) } @@ -318,7 +317,7 @@ func TestSaveConfigToFileWithErrorInPasswordPrompt(t *testing.T) { EncryptConfig: fileEncryptionEnabled, } testData := []byte("testdata") - f, err := ioutil.TempFile("", "") + f, err := os.CreateTemp("", "") if err != nil { t.Fatal(err) } @@ -355,7 +354,7 @@ func TestSaveConfigToFileWithErrorInPasswordPrompt(t *testing.T) { func withInteractiveResponse(t *testing.T, response string, body func() error) error { t.Helper() // Answers to the prompt - responseFile, err := ioutil.TempFile("", "*.in") + responseFile, err := os.CreateTemp("", "*.in") if err != nil { return fmt.Errorf("problem creating temp file: %w", err) } diff --git a/config/config_test.go b/config/config_test.go index b8cefd8d..4b5c1b8c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2,7 +2,6 @@ package config import ( "errors" - "io/ioutil" "os" "path/filepath" "runtime" @@ -1576,7 +1575,7 @@ func TestCheckExchangeConfigValues(t *testing.T) { } // Make a sneaky copy for bank account testing - // nolint: gocritic + //nolint: gocritic cpy := append(cfg.Exchanges[:0:0], cfg.Exchanges...) // Test empty exchange name for an enabled exchange @@ -1729,7 +1728,7 @@ func TestSaveConfigToFile(t *testing.T) { if err != nil { t.Errorf("TestSaveConfig.LoadConfig: %s", err.Error()) } - f, err := ioutil.TempFile("", "") + f, err := os.CreateTemp("", "") if err != nil { t.Errorf("TestSaveConfig create file: %s", err) } diff --git a/currency/code_types.go b/currency/code_types.go index d4997952..ebbf436e 100644 --- a/currency/code_types.go +++ b/currency/code_types.go @@ -114,7 +114,7 @@ var ( BAT = NewCode("BAT") ETP = NewCode("ETP") HOT = NewCode("HOT") - STRAT = NewCode("STRAT") // nolint // Cryptocurrency code + STRAT = NewCode("STRAT") //nolint // Cryptocurrency code GNT = NewCode("GNT") REP = NewCode("REP") SNT = NewCode("SNT") @@ -372,9 +372,9 @@ var ( STQ = NewCode("STQ") INK = NewCode("INK") HBZ = NewCode("HBZ") - USDT_ETH = NewCode("USDT_ETH") // nolint // Cryptocurrency code - QTUM_ETH = NewCode("QTUM_ETH") // nolint // Cryptocurrency code - BTM_ETH = NewCode("BTM_ETH") // nolint // Cryptocurrency code + USDT_ETH = NewCode("USDT_ETH") //nolint // Cryptocurrency code + QTUM_ETH = NewCode("QTUM_ETH") //nolint // Cryptocurrency code + BTM_ETH = NewCode("BTM_ETH") //nolint // Cryptocurrency code FIL = NewCode("FIL") STX = NewCode("STX") BOT = NewCode("BOT") @@ -387,7 +387,7 @@ var ( GOD = NewCode("GOD") SMT = NewCode("SMT") BTF = NewCode("BTF") - NAS_ETH = NewCode("NAS_ETH") // nolint // Cryptocurrency code + NAS_ETH = NewCode("NAS_ETH") //nolint // Cryptocurrency code TSL = NewCode("TSL") BIFI = NewCode("BIFI") BNTY = NewCode("BNTY") @@ -413,7 +413,7 @@ var ( MOBI = NewCode("MOBI") LEDU = NewCode("LEDU") DBC = NewCode("DBC") - MKR_OLD = NewCode("MKR_OLD") // nolint // Cryptocurrency code + MKR_OLD = NewCode("MKR_OLD") //nolint // Cryptocurrency code DPY = NewCode("DPY") BCDN = NewCode("BCDN") EOSDAC = NewCode("EOSDAC") @@ -422,7 +422,7 @@ var ( PPS = NewCode("PPS") BOE = NewCode("BOE") MEDX = NewCode("MEDX") - SMT_ETH = NewCode("SMT_ETH") // nolint // Cryptocurrency code + SMT_ETH = NewCode("SMT_ETH") //nolint // Cryptocurrency code CS = NewCode("CS") MAN = NewCode("MAN") REM = NewCode("REM") @@ -442,7 +442,7 @@ var ( SWTH = NewCode("SWTH") NKN = NewCode("NKN") SOUL = NewCode("SOUL") - GALA_NEO = NewCode("GALA_NEO") // nolint // Cryptocurrency code + GALA_NEO = NewCode("GALA_NEO") //nolint // Cryptocurrency code LRN = NewCode("LRN") GSE = NewCode("GSE") RATING = NewCode("RATING") @@ -1669,7 +1669,7 @@ var ( YER = NewCode("YER") ZWD = NewCode("ZWD") XETH = NewCode("XETH") - FX_BTC = NewCode("FX_BTC") // nolint // Cryptocurrency code + FX_BTC = NewCode("FX_BTC") //nolint // Cryptocurrency code AAVE = NewCode("AAVE") YFI = NewCode("YFI") BAL = NewCode("BAL") @@ -2512,7 +2512,7 @@ var ( NAFT = NewCode("NAFT") SHIBLITE = NewCode("SHIBLITE") BHD = NewCode("BHD") - THN = NewCode("THN") // nolint:misspell // false positive + THN = NewCode("THN") //nolint:misspell // false positive DOGEDASH = NewCode("DOGEDASH") FARA = NewCode("FARA") FIL120 = NewCode("FIL120") @@ -2811,7 +2811,7 @@ var ( SBR = NewCode("SBR") BMARS = NewCode("BMARS") GOMI = NewCode("GOMI") - ONOT = NewCode("ONOT") // nolint:misspell // false positive + ONOT = NewCode("ONOT") //nolint:misspell // false positive GOKU = NewCode("GOKU") MINTYS = NewCode("MINTYS") PONYO = NewCode("PONYO") diff --git a/currency/coinmarketcap/coinmarketcap.go b/currency/coinmarketcap/coinmarketcap.go index 47464dc0..3d837744 100644 --- a/currency/coinmarketcap/coinmarketcap.go +++ b/currency/coinmarketcap/coinmarketcap.go @@ -130,24 +130,24 @@ func (c *Coinmarketcap) GetCryptocurrencyHistoricalListings() ([]CryptocurrencyH // Status Status `json:"status"` // }{} - // nolint:gocritic // unused code, used as example + //nolint:gocritic // unused code, used as example // err := c.CheckAccountPlan(0) // if err != nil { // return resp.Data, err // } - // nolint:gocritic // unused code, used as example + //nolint:gocritic // unused code, used as example // err = c.SendHTTPRequest(http.MethodGet, endpointCryptocurrencyHistoricalListings, nil, &resp) // if err != nil { // return resp.Data, err // } - // nolint:gocritic // unused code, used as example + //nolint:gocritic // unused code, used as example // if resp.Status.ErrorCode != 0 { // return resp.Data, errors.New(resp.Status.ErrorMessage) // } - // nolint:gocritic // unused code, used as example + //nolint:gocritic // unused code, used as example // return resp.Data, nil } diff --git a/currency/pairs.go b/currency/pairs.go index 734c6cb1..c4cee7d1 100644 --- a/currency/pairs.go +++ b/currency/pairs.go @@ -240,7 +240,7 @@ func (p Pairs) FindDifferences(pairs Pairs) (newPairs, removedPairs Pairs) { // GetRandomPair returns a random pair from a list of pairs func (p Pairs) GetRandomPair() Pair { if pairsLen := len(p); pairsLen != 0 { - return p[rand.Intn(pairsLen)] // nolint:gosec // basic number generation required, no need for crypo/rand + return p[rand.Intn(pairsLen)] //nolint:gosec // basic number generation required, no need for crypo/rand } return EMPTYPAIR } diff --git a/currency/storage_test.go b/currency/storage_test.go index 093fd447..8481ac4a 100644 --- a/currency/storage_test.go +++ b/currency/storage_test.go @@ -3,7 +3,6 @@ package currency import ( "errors" "fmt" - "io/ioutil" "os" "testing" @@ -12,7 +11,7 @@ import ( func TestMain(m *testing.M) { var err error - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/database/drivers/postgres/postgres.go b/database/drivers/postgres/postgres.go index 5d616a38..377b6698 100644 --- a/database/drivers/postgres/postgres.go +++ b/database/drivers/postgres/postgres.go @@ -3,6 +3,8 @@ package postgres import ( "database/sql" "fmt" + "net" + "strconv" // import go libpq driver package _ "github.com/lib/pq" @@ -21,11 +23,11 @@ func Connect(cfg *database.Config) (*database.Instance, error) { cfg.SSLMode = "disable" } - configDSN := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s", + host := net.JoinHostPort(cfg.Host, strconv.FormatUint(uint64(cfg.Port), 10)) + configDSN := fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s", cfg.Username, cfg.Password, - cfg.Host, - cfg.Port, + host, cfg.Database, cfg.SSLMode) diff --git a/database/repository/audit/audit_test.go b/database/repository/audit/audit_test.go index d2aa85a0..22292602 100644 --- a/database/repository/audit/audit_test.go +++ b/database/repository/audit/audit_test.go @@ -2,7 +2,6 @@ package audit import ( "fmt" - "io/ioutil" "os" "sync" "testing" @@ -16,7 +15,7 @@ import ( func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/database/repository/candle/candle_test.go b/database/repository/candle/candle_test.go index b4cd600f..525656ae 100644 --- a/database/repository/candle/candle_test.go +++ b/database/repository/candle/candle_test.go @@ -3,7 +3,6 @@ package candle import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -39,7 +38,7 @@ func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/database/repository/datahistoryjob/datahistoryjob_test.go b/database/repository/datahistoryjob/datahistoryjob_test.go index e3f458da..74f8f0d4 100644 --- a/database/repository/datahistoryjob/datahistoryjob_test.go +++ b/database/repository/datahistoryjob/datahistoryjob_test.go @@ -3,7 +3,6 @@ package datahistoryjob import ( "errors" "fmt" - "io/ioutil" "log" "os" "strings" @@ -41,7 +40,7 @@ func TestMain(m *testing.M) { } var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { log.Fatal(err) } diff --git a/database/repository/datahistoryjobresult/datahistoryjobresult_test.go b/database/repository/datahistoryjobresult/datahistoryjobresult_test.go index 2ce65f20..503ade2a 100644 --- a/database/repository/datahistoryjobresult/datahistoryjobresult_test.go +++ b/database/repository/datahistoryjobresult/datahistoryjobresult_test.go @@ -3,7 +3,6 @@ package datahistoryjobresult import ( "database/sql" "fmt" - "io/ioutil" "log" "os" "testing" @@ -38,7 +37,7 @@ func TestMain(m *testing.M) { } var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { log.Fatal(err) } diff --git a/database/repository/exchange/exchange_test.go b/database/repository/exchange/exchange_test.go index 8b3826b4..a11152ab 100644 --- a/database/repository/exchange/exchange_test.go +++ b/database/repository/exchange/exchange_test.go @@ -2,7 +2,6 @@ package exchange import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -39,7 +38,7 @@ func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/database/repository/script/script_test.go b/database/repository/script/script_test.go index 21366646..534eff5b 100644 --- a/database/repository/script/script_test.go +++ b/database/repository/script/script_test.go @@ -2,7 +2,6 @@ package script import ( "fmt" - "io/ioutil" "os" "sync" "testing" @@ -21,7 +20,7 @@ var ( func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/database/repository/trade/trade_test.go b/database/repository/trade/trade_test.go index 2a100891..b43bb6ad 100644 --- a/database/repository/trade/trade_test.go +++ b/database/repository/trade/trade_test.go @@ -2,7 +2,6 @@ package trade import ( "fmt" - "io/ioutil" "log" "os" "testing" @@ -41,11 +40,16 @@ func TestMain(m *testing.M) { } var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { log.Fatal(err) } - os.Exit(m.Run()) + + exitCode := m.Run() + if err = os.RemoveAll(testhelpers.TempDir); err != nil { + fmt.Printf("failed to remove temp dir: %s", err) + } + os.Exit(exitCode) } func TestTrades(t *testing.T) { diff --git a/database/repository/withdraw/withdraw_test.go b/database/repository/withdraw/withdraw_test.go index 6ac5e1ae..3cb04869 100644 --- a/database/repository/withdraw/withdraw_test.go +++ b/database/repository/withdraw/withdraw_test.go @@ -3,7 +3,6 @@ package withdraw import ( "errors" "fmt" - "io/ioutil" "math/rand" "os" "testing" @@ -38,7 +37,7 @@ func TestMain(m *testing.M) { var err error testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) @@ -139,7 +138,7 @@ func seedWithdrawData() { }, }, } - rnd := rand.Intn(2) // nolint:gosec // used for generating test data, no need to import crypo/rand + rnd := rand.Intn(2) //nolint:gosec // used for generating test data, no need to import crypo/rand if rnd == 0 { resp.RequestDetails.Currency = currency.AUD resp.RequestDetails.Type = 1 diff --git a/database/testhelpers/test_helpers_test.go b/database/testhelpers/test_helpers_test.go index 02723a6c..c1151b77 100644 --- a/database/testhelpers/test_helpers_test.go +++ b/database/testhelpers/test_helpers_test.go @@ -2,7 +2,6 @@ package testhelpers import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -14,7 +13,7 @@ import ( func TestMain(m *testing.M) { var err error PostgresTestDatabase = GetConnectionDetails() - TempDir, err = ioutil.TempDir("", "gct-temp") + TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { fmt.Printf("failed to create temp file: %v", err) os.Exit(1) diff --git a/engine/apiserver.go b/engine/apiserver.go index c088ed48..982b82f8 100644 --- a/engine/apiserver.go +++ b/engine/apiserver.go @@ -169,8 +169,9 @@ func (m *apiServerManager) StartRESTServer() error { m.restRouter = m.newRouter(true) if m.restHTTPServer == nil { m.restHTTPServer = &http.Server{ - Addr: m.restListenAddress, - Handler: m.restRouter, + Addr: m.restListenAddress, + Handler: m.restRouter, + ReadHeaderTimeout: time.Minute, } } m.wgRest.Add(1) @@ -429,8 +430,9 @@ func (m *apiServerManager) StartWebsocketServer() error { m.websocketRouter = m.newRouter(false) if m.websocketHTTPServer == nil { m.websocketHTTPServer = &http.Server{ - Addr: m.websocketListenAddress, - Handler: m.websocketRouter, + Addr: m.websocketListenAddress, + Handler: m.websocketRouter, + ReadHeaderTimeout: time.Minute, } } diff --git a/engine/datahistory_manager.go b/engine/datahistory_manager.go index 856656a6..cb5d1f25 100644 --- a/engine/datahistory_manager.go +++ b/engine/datahistory_manager.go @@ -710,7 +710,7 @@ func (m *DataHistoryManager) processCandleData(job *DataHistoryJob, exch exchang if err != nil { r.Result += "could not get candles: " + err.Error() + ". " r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } job.rangeHolder.SetHasDataFromCandles(candles.Candles) for i := range job.rangeHolder.Ranges[intervalIndex].Intervals { @@ -759,13 +759,13 @@ func (m *DataHistoryManager) processTradeData(job *DataHistoryJob, exch exchange if err != nil { r.Result += "could not get trades: " + err.Error() + ". " r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } candles, err := trade.ConvertTradesToCandles(job.Interval, trades...) if err != nil { r.Result += "could not convert candles to trades: " + err.Error() + ". " r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } job.rangeHolder.SetHasDataFromCandles(candles.Candles) for i := range job.rangeHolder.Ranges[intervalIndex].Intervals { @@ -826,13 +826,13 @@ func (m *DataHistoryManager) convertTradesToCandles(job *DataHistoryJob, startRa if err != nil { r.Result = "could not get trades in range: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } candles, err := trade.ConvertTradesToCandles(job.Interval, trades...) if err != nil { r.Result = "could not convert trades in range: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } candles.SourceJobID = job.ID err = m.saveCandlesInBatches(job, &candles, r) @@ -865,13 +865,13 @@ func (m *DataHistoryManager) convertCandleData(job *DataHistoryJob, startRange, if err != nil { r.Result = "could not get candles in range: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } newCandles, err := kline.ConvertToNewInterval(&candles, job.ConversionInterval) if err != nil { r.Result = "could not convert candles in range: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } newCandles.SourceJobID = job.ID err = m.saveCandlesInBatches(job, &candles, r) @@ -913,14 +913,14 @@ func (m *DataHistoryManager) validateCandles(job *DataHistoryJob, exch exchange. if err != nil { r.Result = "could not get API candles: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } apiCandles.ValidationJobID = job.ID dbCandles, err := m.candleLoader(job.Exchange, job.Pair, job.Asset, job.Interval, startRange, endRange) if err != nil { r.Result = "could not get database candles: " + err.Error() r.Status = dataHistoryStatusFailed - return r, nil // nolint:nilerr // error is returned in the job result + return r, nil //nolint:nilerr // error is returned in the job result } if len(dbCandles.Candles) == 0 { r.Result = fmt.Sprintf("missing database candles for period %v-%v", startRange, endRange) diff --git a/engine/datahistory_manager_test.go b/engine/datahistory_manager_test.go index 42fd502d..8cac05f5 100644 --- a/engine/datahistory_manager_test.go +++ b/engine/datahistory_manager_test.go @@ -654,7 +654,7 @@ func TestCompareJobsToData(t *testing.T) { } } -func TestRunJob(t *testing.T) { // nolint // TO-DO: Fix race t.Parallel() usage +func TestRunJob(t *testing.T) { //nolint // TO-DO: Fix race t.Parallel() usage testCases := []*DataHistoryJob{ { Nickname: "TestRunJobDataHistoryCandleDataType", diff --git a/engine/helpers_test.go b/engine/helpers_test.go index 11565032..acc13966 100644 --- a/engine/helpers_test.go +++ b/engine/helpers_test.go @@ -118,7 +118,7 @@ func TestGetRPCEndpoints(t *testing.T) { } } -func TestSetSubsystem(t *testing.T) { // nolint // TO-DO: Fix race t.Parallel() usage +func TestSetSubsystem(t *testing.T) { //nolint // TO-DO: Fix race t.Parallel() usage testCases := []struct { Subsystem string Engine *Engine diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 9907489c..3d4b555b 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -2579,7 +2579,7 @@ func (s *RPCServer) GCTScriptQuery(_ context.Context, r *gctrpc.GCTScriptQueryRe UUID, err := uuid.FromString(r.Script.Uuid) if err != nil { - // nolint:nilerr // error is returned in the GCTScriptQueryResponse + //nolint:nilerr // error is returned in the GCTScriptQueryResponse return &gctrpc.GCTScriptQueryResponse{Status: MsgStatusError, Data: err.Error()}, nil } @@ -2626,7 +2626,7 @@ func (s *RPCServer) GCTScriptExecute(_ context.Context, r *gctrpc.GCTScriptExecu script := filepath.Join(r.Script.Path, r.Script.Name) if err := gctVM.Load(script); err != nil { - return &gctrpc.GenericResponse{ // nolint:nilerr // error is returned in the generic response + return &gctrpc.GenericResponse{ //nolint:nilerr // error is returned in the generic response Status: MsgStatusError, Data: err.Error(), }, nil @@ -2648,7 +2648,7 @@ func (s *RPCServer) GCTScriptStop(_ context.Context, r *gctrpc.GCTScriptStopRequ UUID, err := uuid.FromString(r.Script.Uuid) if err != nil { - return &gctrpc.GenericResponse{Status: MsgStatusError, Data: err.Error()}, nil // nolint:nilerr // error is returned in the generic response + return &gctrpc.GenericResponse{Status: MsgStatusError, Data: err.Error()}, nil //nolint:nilerr // error is returned in the generic response } v, f := gctscript.AllVMSync.Load(UUID) @@ -2818,7 +2818,7 @@ func (s *RPCServer) GCTScriptStopAll(context.Context, *gctrpc.GCTScriptStopAllRe err := s.gctScriptManager.ShutdownAll() if err != nil { - return &gctrpc.GenericResponse{Status: "error", Data: err.Error()}, nil // nolint:nilerr // error is returned in the generic response + return &gctrpc.GenericResponse{Status: "error", Data: err.Error()}, nil //nolint:nilerr // error is returned in the generic response } return &gctrpc.GenericResponse{ @@ -2836,7 +2836,7 @@ func (s *RPCServer) GCTScriptAutoLoadToggle(_ context.Context, r *gctrpc.GCTScri if r.Status { err := s.gctScriptManager.Autoload(r.Script, true) if err != nil { - // nolint:nilerr // error is returned in the generic response + //nolint:nilerr // error is returned in the generic response return &gctrpc.GenericResponse{Status: "error", Data: err.Error()}, nil } return &gctrpc.GenericResponse{Status: "success", Data: "script " + r.Script + " removed from autoload list"}, nil @@ -2844,7 +2844,7 @@ func (s *RPCServer) GCTScriptAutoLoadToggle(_ context.Context, r *gctrpc.GCTScri err := s.gctScriptManager.Autoload(r.Script, false) if err != nil { - return &gctrpc.GenericResponse{Status: "error", Data: err.Error()}, nil // nolint:nilerr // error is returned in the generic response + return &gctrpc.GenericResponse{Status: "error", Data: err.Error()}, nil //nolint:nilerr // error is returned in the generic response } return &gctrpc.GenericResponse{Status: "success", Data: "script " + r.Script + " added to autoload list"}, nil } diff --git a/exchanges/account/credentials.go b/exchanges/account/credentials.go index c3455b1c..5578db96 100644 --- a/exchanges/account/credentials.go +++ b/exchanges/account/credentials.go @@ -22,14 +22,17 @@ const ( // changed while the same keys can be used. ContextSubAccountFlag contextCredential = "subaccountoverride" + apiKeyDisplaySize = 16 +) + +// Default credential values +const ( Key = "key" Secret = "secret" SubAccountSTR = "subaccount" ClientID = "clientid" OneTimePassword = "otp" PEMKey = "pemkey" - - apiKeyDisplaySize = 16 ) var ( diff --git a/exchanges/alert/alert.go b/exchanges/alert/alert.go index af88d615..35abaab7 100644 --- a/exchanges/alert/alert.go +++ b/exchanges/alert/alert.go @@ -13,7 +13,9 @@ const ( alerting dataToActuatorDefaultBuffer = 1 - PreAllocCommsDefaultBuffer = 5 + + // PreAllocCommsDefaultBuffer is the default buffer size for comms + PreAllocCommsDefaultBuffer = 5 ) var ( diff --git a/exchanges/alert/alert_test.go b/exchanges/alert/alert_test.go index c4ed2080..b5ed2a2c 100644 --- a/exchanges/alert/alert_test.go +++ b/exchanges/alert/alert_test.go @@ -101,8 +101,10 @@ func BenchmarkAlert(b *testing.B) { } } -// 150352 9916 ns/op 681 B/op 4 allocs/op // PREV -// 87436 14724 ns/op 682 B/op 4 allocs/op // CURRENT +// BenchmarkWait benchmark +// +// 150352 9916 ns/op 681 B/op 4 allocs/op // PREV +// 87436 14724 ns/op 682 B/op 4 allocs/op // CURRENT func BenchmarkWait(b *testing.B) { n := Notice{} for x := 0; x < b.N; x++ { diff --git a/exchanges/asset/asset.go b/exchanges/asset/asset.go index b1bd9947..e1ef5cbe 100644 --- a/exchanges/asset/asset.go +++ b/exchanges/asset/asset.go @@ -62,7 +62,7 @@ func Supported() Items { return supportedList } -// returns an Item to string +// String converts an Item to its string representation func (a Item) String() string { switch a { case Spot: diff --git a/exchanges/binanceus/binanceus.go b/exchanges/binanceus/binanceus.go index 47997c90..634bf104 100644 --- a/exchanges/binanceus/binanceus.go +++ b/exchanges/binanceus/binanceus.go @@ -775,8 +775,9 @@ func (bi *Binanceus) GetTradeFee(ctx context.Context, recvWindow uint, symbol st // GetAssetDistributionHistory this endpoint to query // asset distribution records, including for staking, referrals and airdrops etc. +// // INPUTS: -// asset: string , startTime & endTime unix time in Milli seconds, recvWindow(duration in milli seconds > 2000 to < 6000) +// asset: string , startTime & endTime unix time in Milli seconds, recvWindow(duration in milli seconds > 2000 to < 6000) func (bi *Binanceus) GetAssetDistributionHistory(ctx context.Context, asset string, startTime, endTime uint64, recvWindow uint) (*AssetDistributionHistories, error) { params := url.Values{} timestamp := time.Now().UnixMilli() diff --git a/exchanges/bitflyer/bitflyer.go b/exchanges/bitflyer/bitflyer.go index 1ec9a3f6..5a6aaefc 100644 --- a/exchanges/bitflyer/bitflyer.go +++ b/exchanges/bitflyer/bitflyer.go @@ -309,7 +309,7 @@ func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st // if you have access and update the authenticated requests // TODO: Fill out this function once API access is obtained func (b *Bitflyer) SendAuthHTTPRequest() { - // nolint:gocritic // code example + //nolint:gocritic // code example // headers := make(map[string]string) // headers["ACCESS-KEY"] = b.API.Credentials.Key // headers["ACCESS-TIMESTAMP"] = strconv.FormatInt(time.Now().UnixNano(), 10) diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index 51acd5c1..48b3de8d 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -254,14 +254,7 @@ func TestMarketSellOrder(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.QTUM, currency.KRW) - _, err := b.UpdateTicker(context.Background(), cp, asset.Spot) - if err != nil { - t.Fatal(err) - } - - cp = currency.NewPair(currency.BTC, currency.KRW) - _, err = b.UpdateTicker(context.Background(), cp, asset.Spot) - if err != nil { + if _, err := b.UpdateTicker(context.Background(), cp, asset.Spot); err != nil { t.Fatal(err) } } diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 9672b5ec..9943989b 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -58,8 +58,8 @@ const ( // Authenticated endpoints bitmexEndpointAPIkeys = "/apiKey" - bitmexEndpointDisableAPIkey = "/apiKey/disable" // nolint:gosec // false positive - bitmexEndpointEnableAPIkey = "/apiKey/enable" // nolint:gosec // false positive + bitmexEndpointDisableAPIkey = "/apiKey/disable" //nolint:gosec // false positive + bitmexEndpointEnableAPIkey = "/apiKey/enable" //nolint:gosec // false positive bitmexEndpointTrollboxSend = "/chat" bitmexEndpointExecution = "/execution" bitmexEndpointExecutionTradeHistory = "/execution/tradeHistory" diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index c3599d6f..7067c73c 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -783,7 +783,7 @@ func TestWithdraw(t *testing.T) { Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", - OneTimePassword: 000000, // nolint // gocritic false positive + OneTimePassword: 000000, //nolint // gocritic false positive } if areTestAPIKeysSet() && !canManipulateRealOrders { diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index ad4d07dc..1093d245 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -17,7 +17,9 @@ import ( "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/order" + "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/request" + "github.com/thrasher-corp/gocryptotrader/log" ) const ( @@ -654,3 +656,12 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange func parseTime(dateTime string) (time.Time, error) { return time.Parse(bitstampTimeLayout, dateTime) } + +func filterOrderbookZeroBidPrice(ob *orderbook.Base) { + if len(ob.Bids) == 0 || ob.Bids[len(ob.Bids)-1].Price != 0 { + return + } + + log.Warnf(log.ExchangeSys, "%s %s %s orderbook has zero bid price, filtering.", ob.Exchange, ob.Pair, ob.Asset) + ob.Bids = ob.Bids[0 : len(ob.Bids)-1] +} diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index a11139e2..299646b4 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -14,6 +14,7 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" + "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/portfolio/banking" "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" ) @@ -757,3 +758,37 @@ func TestGetHistoricTrades(t *testing.T) { t.Error(err) } } + +func TestOrderbookZeroBidPrice(t *testing.T) { + t.Parallel() + ob := &orderbook.Base{ + Exchange: "Bitstamp", + Pair: currency.NewPair(currency.BTC, currency.USD), + Asset: asset.Spot, + } + + filterOrderbookZeroBidPrice(ob) + + ob.Bids = orderbook.Items{ + {Price: 69, Amount: 1337}, + {Price: 0, Amount: 69}, + } + + filterOrderbookZeroBidPrice(ob) + + if ob.Bids[0].Price != 69 || ob.Bids[0].Amount != 1337 || len(ob.Bids) != 1 { + t.Error("invalid orderbook bid values") + } + + ob.Bids = orderbook.Items{ + {Price: 59, Amount: 1337}, + {Price: 42, Amount: 8595}, + } + + filterOrderbookZeroBidPrice(ob) + + if ob.Bids[0].Price != 59 || ob.Bids[0].Amount != 1337 || + ob.Bids[1].Price != 42 || ob.Bids[1].Amount != 8595 || len(ob.Bids) != 2 { + t.Error("invalid orderbook bid values") + } +} diff --git a/exchanges/bitstamp/bitstamp_websocket.go b/exchanges/bitstamp/bitstamp_websocket.go index a15ec6d5..01882364 100644 --- a/exchanges/bitstamp/bitstamp_websocket.go +++ b/exchanges/bitstamp/bitstamp_websocket.go @@ -21,7 +21,7 @@ import ( ) const ( - bitstampWSURL = "wss://ws.bitstamp.net" // nolint // gosec false positive + bitstampWSURL = "wss://ws.bitstamp.net" //nolint // gosec false positive ) // WsConnect connects to a websocket feed @@ -118,7 +118,7 @@ func (b *Bitstamp) wsHandleData(respRaw []byte) error { return err } - err = b.wsUpdateOrderbook(wsOrderBookTemp.Data, p, asset.Spot) + err = b.wsUpdateOrderbook(&wsOrderBookTemp.Data, p, asset.Spot) if err != nil { return err } @@ -251,12 +251,21 @@ func (b *Bitstamp) Unsubscribe(channelsToUnsubscribe []stream.ChannelSubscriptio return nil } -func (b *Bitstamp) wsUpdateOrderbook(update websocketOrderBook, p currency.Pair, assetType asset.Item) error { +func (b *Bitstamp) wsUpdateOrderbook(update *websocketOrderBook, p currency.Pair, assetType asset.Item) error { if len(update.Asks) == 0 && len(update.Bids) == 0 { return errors.New("no orderbook data") } - asks := make([]orderbook.Item, len(update.Asks)) - bids := make([]orderbook.Item, len(update.Bids)) + + obUpdate := &orderbook.Base{ + Bids: make(orderbook.Items, len(update.Bids)), + Asks: make(orderbook.Items, len(update.Asks)), + Pair: p, + LastUpdated: time.Unix(update.Timestamp, 0), + Asset: assetType, + Exchange: b.Name, + VerifyOrderbook: b.CanVerifyOrderbook, + } + for i := range update.Asks { target, err := strconv.ParseFloat(update.Asks[i][0], 64) if err != nil { @@ -266,7 +275,7 @@ func (b *Bitstamp) wsUpdateOrderbook(update websocketOrderBook, p currency.Pair, if err != nil { return err } - asks[i] = orderbook.Item{Price: target, Amount: amount} + obUpdate.Asks[i] = orderbook.Item{Price: target, Amount: amount} } for i := range update.Bids { target, err := strconv.ParseFloat(update.Bids[i][0], 64) @@ -277,17 +286,10 @@ func (b *Bitstamp) wsUpdateOrderbook(update websocketOrderBook, p currency.Pair, if err != nil { return err } - bids[i] = orderbook.Item{Price: target, Amount: amount} + obUpdate.Bids[i] = orderbook.Item{Price: target, Amount: amount} } - return b.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ - Bids: bids, - Asks: asks, - Pair: p, - LastUpdated: time.Unix(update.Timestamp, 0), - Asset: assetType, - Exchange: b.Name, - VerifyOrderbook: b.CanVerifyOrderbook, - }) + filterOrderbookZeroBidPrice(obUpdate) + return b.Websocket.Orderbook.LoadSnapshot(obUpdate) } func (b *Bitstamp) seedOrderBook(ctx context.Context) error { @@ -306,27 +308,31 @@ func (b *Bitstamp) seedOrderBook(ctx context.Context) error { return err } - var newOrderBook orderbook.Base - newOrderBook.Asks = make(orderbook.Items, len(orderbookSeed.Asks)) + newOrderBook := &orderbook.Base{ + Pair: p[x], + Asset: asset.Spot, + Exchange: b.Name, + VerifyOrderbook: b.CanVerifyOrderbook, + Bids: make(orderbook.Items, len(orderbookSeed.Bids)), + Asks: make(orderbook.Items, len(orderbookSeed.Asks)), + } + for i := range orderbookSeed.Asks { newOrderBook.Asks[i] = orderbook.Item{ Price: orderbookSeed.Asks[i].Price, Amount: orderbookSeed.Asks[i].Amount, } } - newOrderBook.Bids = make(orderbook.Items, len(orderbookSeed.Bids)) for i := range orderbookSeed.Bids { newOrderBook.Bids[i] = orderbook.Item{ Price: orderbookSeed.Bids[i].Price, Amount: orderbookSeed.Bids[i].Amount, } } - newOrderBook.Pair = p[x] - newOrderBook.Asset = asset.Spot - newOrderBook.Exchange = b.Name - newOrderBook.VerifyOrderbook = b.CanVerifyOrderbook - err = b.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + filterOrderbookZeroBidPrice(newOrderBook) + + err = b.Websocket.Orderbook.LoadSnapshot(newOrderBook) if err != nil { return err } diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 0e34d486..f1f6d4ed 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -414,6 +414,8 @@ func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy } } + filterOrderbookZeroBidPrice(book) + book.Asks = make(orderbook.Items, len(orderbookNew.Asks)) for x := range orderbookNew.Asks { book.Asks[x] = orderbook.Item{ @@ -421,6 +423,7 @@ func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy Price: orderbookNew.Asks[x].Price, } } + err = book.Process() if err != nil { return book, err diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index db2d9b9d..8250ea9e 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -379,7 +379,7 @@ func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a Amount: a.SellQuote[x].Size, }) } - book.Asks.Reverse() // Reverse asks for correct alignment + book.Asks.SortAsks() // Sort asks for correct alignment book.Pair = p book.Exchange = b.Name book.Asset = assetType diff --git a/exchanges/bybit/bybit_types.go b/exchanges/bybit/bybit_types.go index 2ce6c2eb..48a028ee 100644 --- a/exchanges/bybit/bybit_types.go +++ b/exchanges/bybit/bybit_types.go @@ -370,11 +370,13 @@ type orderbookResponse struct { Error } +// DepositWalletInfo stores wallet deposit info type DepositWalletInfo struct { Coin string `json:"coin"` Chains []ChainInfo `json:"chains"` } +// ChainInfo stores a coins chain info type ChainInfo struct { ChainType string `json:"chain_type"` DepositAddress string `json:"address_deposit"` diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index 7a19becd..fff6fd8b 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -497,5 +497,5 @@ func (i *instrumentMap) GetInstrumentIDs() []int64 { } func getNonce() int64 { - return rand.Int63n(coinutMaxNonce-1) + 1 // nolint:gosec // basic number generation required, no need for crypo/rand + return rand.Int63n(coinutMaxNonce-1) + 1 //nolint:gosec // basic number generation required, no need for crypo/rand } diff --git a/exchanges/exchange.go b/exchanges/exchange.go index ef635508..0082d844 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -28,7 +28,7 @@ import ( ) const ( - warningBase64DecryptSecretKeyFailed = "exchange %s unable to base64 decode secret key.. Disabling Authenticated API support" // nolint // False positive (G101: Potential hardcoded credentials) + warningBase64DecryptSecretKeyFailed = "exchange %s unable to base64 decode secret key.. Disabling Authenticated API support" //nolint // False positive (G101: Potential hardcoded credentials) // DefaultHTTPTimeout is the default HTTP/HTTPS Timeout for exchange requests DefaultHTTPTimeout = time.Second * 15 // DefaultWebsocketResponseCheckTimeout is the default delay in checking for an expected websocket response @@ -330,7 +330,7 @@ func (b *Base) GetPairFormat(assetType asset.Item, requestFormat bool) (currency func (b *Base) GetEnabledPairs(a asset.Item) (currency.Pairs, error) { err := b.CurrencyPairs.IsAssetEnabled(a) if err != nil { - return nil, nil // nolint:nilerr // non-fatal error + return nil, nil //nolint:nilerr // non-fatal error } format, err := b.GetPairFormat(a, false) if err != nil { @@ -1117,7 +1117,7 @@ func (e *Endpoints) SetRunning(key, val string) error { key, val, e.Exchange) - return nil // nolint:nilerr // non-fatal error as we won't update the running URL + return nil //nolint:nilerr // non-fatal error as we won't update the running URL } e.defaults[key] = val return nil diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 6053dac0..b7b6221e 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -133,11 +133,17 @@ func (g *Gemini) GetAuction(ctx context.Context, currencyPair string) (Auction, // // currencyPair - example "btcusd" // params -- [optional] -// since - [timestamp] Only returns auction events after the specified +// +// since - [timestamp] Only returns auction events after the specified +// // timestamp. -// limit_auction_results - [integer] The maximum number of auction +// +// limit_auction_results - [integer] The maximum number of auction +// // events to return. -// include_indicative - [bool] Whether to include publication of +// +// include_indicative - [bool] Whether to include publication of +// // indicative prices and quantities. func (g *Gemini) GetAuctionHistory(ctx context.Context, currencyPair string, params url.Values) ([]AuctionHistory, error) { path := common.EncodeURLValues(fmt.Sprintf("/v%s/%s/%s/%s", geminiAPIVersion, geminiAuction, currencyPair, geminiAuctionHistory), params) diff --git a/exchanges/huobi/huobi_cfutures.go b/exchanges/huobi/huobi_cfutures.go index 2eb7e2f3..88200a07 100644 --- a/exchanges/huobi/huobi_cfutures.go +++ b/exchanges/huobi/huobi_cfutures.go @@ -42,7 +42,7 @@ const ( huobiBasisData = "/index/market/history/swap_basis" huobiSwapAccInfo = "/swap-api/v1/swap_account_info" huobiSwapPosInfo = "/swap-api/v1/swap_position_info" - huobiSwapAssetsAndPos = "/swap-api/v1/swap_account_position_info" // nolint // false positive gosec + huobiSwapAssetsAndPos = "/swap-api/v1/swap_account_position_info" //nolint // false positive gosec huobiSwapSubAccList = "/swap-api/v1/swap_sub_account_list" huobiSwapSubAccInfo = "/swap-api/v1/swap_sub_account_info" huobiSwapSubAccPosInfo = "/swap-api/v1/swap_sub_position_info" diff --git a/exchanges/itbit/itbit.go b/exchanges/itbit/itbit.go index 204e9928..66ad6891 100644 --- a/exchanges/itbit/itbit.go +++ b/exchanges/itbit/itbit.go @@ -75,8 +75,9 @@ func (i *ItBit) GetTradeHistory(ctx context.Context, currencyPair, tradeID strin // GetWallets returns information about all wallets associated with the account. // // params -- -// page - [optional] page to return example 1. default 1 -// perPage - [optional] items per page example 50, default 50 max 50 +// +// page - [optional] page to return example 1. default 1 +// perPage - [optional] items per page example 50, default 50 max 50 func (i *ItBit) GetWallets(ctx context.Context, params url.Values) ([]Wallet, error) { creds, err := i.GetCredentials(ctx) if err != nil { diff --git a/exchanges/kline/kline_test.go b/exchanges/kline/kline_test.go index 5a0d36ed..640a379e 100644 --- a/exchanges/kline/kline_test.go +++ b/exchanges/kline/kline_test.go @@ -3,7 +3,6 @@ package kline import ( "errors" "fmt" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -106,11 +105,11 @@ func TestCreateKline(t *testing.T) { rand.Seed(time.Now().Unix()) for i := 0; i < 24000; i++ { trades = append(trades, order.TradeHistory{ - Timestamp: time.Now().Add((time.Duration(rand.Intn(10)) * time.Minute) + // nolint:gosec // no need to import crypo/rand for testing - (time.Duration(rand.Intn(10)) * time.Second)), // nolint:gosec // no need to import crypo/rand for testing + Timestamp: time.Now().Add((time.Duration(rand.Intn(10)) * time.Minute) + //nolint:gosec // no need to import crypo/rand for testing + (time.Duration(rand.Intn(10)) * time.Second)), //nolint:gosec // no need to import crypo/rand for testing TID: crypto.HexEncodeToString([]byte(string(rune(i)))), - Amount: float64(rand.Intn(20)) + 1, // nolint:gosec // no need to import crypo/rand for testing - Price: 1000 + float64(rand.Intn(1000)), // nolint:gosec // no need to import crypo/rand for testing + Amount: float64(rand.Intn(20)) + 1, //nolint:gosec // no need to import crypo/rand for testing + Price: 1000 + float64(rand.Intn(1000)), //nolint:gosec // no need to import crypo/rand for testing }) } @@ -461,7 +460,7 @@ func TestItem_SortCandlesByTimestamp(t *testing.T) { } for x := 0; x < 100; x++ { - y := rand.Float64() // nolint:gosec // used for generating test data, no need to import crypo/rand + y := rand.Float64() //nolint:gosec // used for generating test data, no need to import crypo/rand tempKline.Candles = append(tempKline.Candles, Candle{ Time: time.Now().AddDate(0, 0, -x), @@ -497,7 +496,7 @@ func setupTest(t *testing.T) { var err error testhelpers.MigrationDir = filepath.Join("..", "..", "database", "migrations") testhelpers.PostgresTestDatabase = testhelpers.GetConnectionDetails() - testhelpers.TempDir, err = ioutil.TempDir("", "gct-temp") + testhelpers.TempDir, err = os.MkdirTemp("", "gct-temp") if err != nil { t.Fatalf("failed to create temp file: %v", err) } @@ -857,7 +856,7 @@ func BenchmarkJustifyIntervalTimeStoringUnixValues1(b *testing.B) { tt2 := time.Now().Add(-time.Hour) tt3 := time.Now().Add(time.Hour) for i := 0; i < b.N; i++ { - if tt1.Unix() == tt2.Unix() || // nolint:staticcheck // it is a benchmark to demonstrate inefficiency in calling + if tt1.Unix() == tt2.Unix() || //nolint:staticcheck // it is a benchmark to demonstrate inefficiency in calling (tt1.Unix() > tt2.Unix() && tt1.Unix() < tt3.Unix()) { } @@ -873,7 +872,7 @@ func BenchmarkJustifyIntervalTimeStoringUnixValues2(b *testing.B) { tt2 := time.Now().Add(-time.Hour).Unix() tt3 := time.Now().Add(time.Hour).Unix() for i := 0; i < b.N; i++ { - if tt1 >= tt2 && tt1 <= tt3 { // nolint:staticcheck // it is a benchmark to demonstrate inefficiency in calling + if tt1 >= tt2 && tt1 <= tt3 { //nolint:staticcheck // it is a benchmark to demonstrate inefficiency in calling } } diff --git a/exchanges/kline/technical_analysis.go b/exchanges/kline/technical_analysis.go index 7fadf242..adb2e9f0 100644 --- a/exchanges/kline/technical_analysis.go +++ b/exchanges/kline/technical_analysis.go @@ -185,7 +185,7 @@ func (o *OHLC) GetSimpleMovingAverage(option []float64, period int64) ([]float64 } // GetExponentialMovingAverageOnClose returns the EMA on the close price set for -// the given period. +// the given period. func (k *Item) GetExponentialMovingAverageOnClose(period int64) ([]float64, error) { ohlc := k.GetOHLC() return ohlc.GetExponentialMovingAverage(ohlc.Close, period) diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 504ed557..a7e9b3d8 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -977,11 +977,12 @@ func (k *Kraken) CancelExistingOrder(ctx context.Context, txid string) (CancelOr return response.Result, GetError(response.Error) } -// GetError parse Exchange errors in response and return the first one +// GetError parse Exchange errors in response and return the first one. +// // Error format from API doc: -// error = array of error messages in the format of: -// :[:] -// severity code can be E for error or W for warning +// - error = array of error messages in the format of: +// :[:] +// severity code can be E for error or W for warning func GetError(apiErrors []string) error { const exchangeName = "Kraken" for _, e := range apiErrors { diff --git a/exchanges/lbank/lbank_test.go b/exchanges/lbank/lbank_test.go index c5306e66..0e22c3f9 100644 --- a/exchanges/lbank/lbank_test.go +++ b/exchanges/lbank/lbank_test.go @@ -475,6 +475,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { } func Test_FormatExchangeKlineInterval(t *testing.T) { + t.Parallel() testCases := []struct { name string interval kline.Interval @@ -511,6 +512,7 @@ func Test_FormatExchangeKlineInterval(t *testing.T) { test := testCases[x] t.Run(test.name, func(t *testing.T) { + t.Parallel() ret := l.FormatExchangeKlineInterval(test.interval) if ret != test.output { diff --git a/exchanges/order/order_test.go b/exchanges/order/order_test.go index d529e259..54419681 100644 --- a/exchanges/order/order_test.go +++ b/exchanges/order/order_test.go @@ -404,7 +404,9 @@ var filterOrdersByTypeBenchmark = &[]Detail{ {Type: Limit}, } -// 392455 3226 ns/op 15840 B/op 5 allocs/op // PREV +// BenchmarkFilterOrdersByType benchmark +// +// 392455 3226 ns/op 15840 B/op 5 allocs/op // PREV // 9486490 109.5 ns/op 0 B/op 0 allocs/op // CURRENT func BenchmarkFilterOrdersByType(b *testing.B) { for x := 0; x < b.N; x++ { @@ -454,7 +456,9 @@ var filterOrdersBySideBenchmark = &[]Detail{ {Side: Ask}, } -// 372594 3049 ns/op 15840 B/op 5 allocs/op // PREV +// BenchmarkFilterOrdersBySide benchmark +// +// 372594 3049 ns/op 15840 B/op 5 allocs/op // PREV // 7412187 148.8 ns/op 0 B/op 0 allocs/op // CURRENT func BenchmarkFilterOrdersBySide(b *testing.B) { for x := 0; x < b.N; x++ { @@ -537,7 +541,9 @@ var filterOrdersByTimeRangeBenchmark = &[]Detail{ {Date: time.Unix(100, 0)}, } -// 390822 3335 ns/op 15840 B/op 5 allocs/op // PREV +// BenchmarkFilterOrdersByTimeRange benchmark +// +// 390822 3335 ns/op 15840 B/op 5 allocs/op // PREV // 6201034 172.1 ns/op 0 B/op 0 allocs/op // CURRENT func BenchmarkFilterOrdersByTimeRange(b *testing.B) { for x := 0; x < b.N; x++ { @@ -615,7 +621,9 @@ var filterOrdersByPairsBenchmark = &[]Detail{ {Pair: currency.NewPair(currency.BTC, currency.USD)}, } -// 400032 2977 ns/op 15840 B/op 5 allocs/op // PREV +// BenchmarkFilterOrdersByPairs benchmark +// +// 400032 2977 ns/op 15840 B/op 5 allocs/op // PREV // 6977242 172.8 ns/op 0 B/op 0 allocs/op // CURRENT func BenchmarkFilterOrdersByPairs(b *testing.B) { pairs := []currency.Pair{currency.NewPair(currency.BTC, currency.USD)} diff --git a/exchanges/order/orders.go b/exchanges/order/orders.go index ed424509..20ccdef5 100644 --- a/exchanges/order/orders.go +++ b/exchanges/order/orders.go @@ -622,7 +622,7 @@ func (t Type) Lower() string { // Title returns the type titleized, eg "Limit" func (t Type) Title() string { - return strings.Title(strings.ToLower(t.String())) // nolint:staticcheck // Ignore Title usage warning + return strings.Title(strings.ToLower(t.String())) //nolint:staticcheck // Ignore Title usage warning } // String implements the stringer interface @@ -675,7 +675,7 @@ func (s Side) Lower() string { // Title returns the side titleized, eg "Buy" func (s Side) Title() string { - return strings.Title(strings.ToLower(s.String())) // nolint:staticcheck // Ignore Title usage warning + return strings.Title(strings.ToLower(s.String())) //nolint:staticcheck // Ignore Title usage warning } // IsShort returns if the side is short diff --git a/exchanges/orderbook/node_test.go b/exchanges/orderbook/node_test.go index 5baa7ed1..a5851915 100644 --- a/exchanges/orderbook/node_test.go +++ b/exchanges/orderbook/node_test.go @@ -62,7 +62,7 @@ func (s *stack) Display() { fmt.Println("TOTAL COUNT:", s.getCount()) } -// 158 9,521,717 ns/op 9600104 B/op 100001 allocs/op +// 158 9,521,717 ns/op 9600104 B/op 100001 allocs/op func BenchmarkWithoutStack(b *testing.B) { var n *Node b.ReportAllocs() diff --git a/exchanges/orderbook/orderbook_test.go b/exchanges/orderbook/orderbook_test.go index 3075e6d8..46981280 100644 --- a/exchanges/orderbook/orderbook_test.go +++ b/exchanges/orderbook/orderbook_test.go @@ -492,12 +492,12 @@ func TestProcessOrderbook(t *testing.T) { m.Unlock() wg.Add(1) go func() { - newName := "Exchange" + strconv.FormatInt(rand.Int63(), 10) // nolint:gosec // no need to import crypo/rand for testing + newName := "Exchange" + strconv.FormatInt(rand.Int63(), 10) //nolint:gosec // no need to import crypo/rand for testing newPairs := currency.NewPair(currency.NewCode("BTC"+strconv.FormatInt(rand.Int63(), 10)), - currency.NewCode("USD"+strconv.FormatInt(rand.Int63(), 10))) // nolint:gosec // no need to import crypo/rand for testing + currency.NewCode("USD"+strconv.FormatInt(rand.Int63(), 10))) //nolint:gosec // no need to import crypo/rand for testing - asks := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} // nolint:gosec // no need to import crypo/rand for testing - bids := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} // nolint:gosec // no need to import crypo/rand for testing + asks := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing + bids := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} //nolint:gosec // no need to import crypo/rand for testing base := &Base{ Pair: newPairs, Asks: asks, @@ -558,7 +558,7 @@ func deployUnorderedSlice() Items { var items []Item rand.Seed(time.Now().UnixNano()) for i := 0; i < 1000; i++ { - items = append(items, Item{Amount: 1, Price: rand.Float64(), ID: rand.Int63()}) // nolint:gosec // Not needed in tests + items = append(items, Item{Amount: 1, Price: rand.Float64(), ID: rand.Int63()}) //nolint:gosec // Not needed in tests } return items } @@ -596,7 +596,7 @@ func deploySliceOrdered() Items { rand.Seed(time.Now().UnixNano()) var items []Item for i := 0; i < 1000; i++ { - items = append(items, Item{Amount: 1, Price: float64(i + 1), ID: rand.Int63()}) // nolint:gosec // Not needed in tests + items = append(items, Item{Amount: 1, Price: float64(i + 1), ID: rand.Int63()}) //nolint:gosec // Not needed in tests } return items } @@ -620,7 +620,7 @@ func TestReverse(t *testing.T) { t.Fatal(err) } - b.Asks = append(b.Bids[:0:0], b.Bids...) // nolint:gocritic // Short hand + b.Asks = append(b.Bids[:0:0], b.Bids...) //nolint:gocritic // Short hand err = b.Verify() if !errors.Is(err, errPriceOutOfOrder) { t.Fatalf("error expected %v received %v", errPriceOutOfOrder, err) @@ -645,11 +645,11 @@ func BenchmarkReverse(b *testing.B) { } } -// 20209 56385 ns/op 49189 B/op 2 allocs/op +// 20209 56385 ns/op 49189 B/op 2 allocs/op func BenchmarkSortAsksDecending(b *testing.B) { s := deploySliceOrdered() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortAsks() } @@ -660,7 +660,7 @@ func BenchmarkSortBidsAscending(b *testing.B) { s := deploySliceOrdered() s.Reverse() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortBids() } @@ -670,7 +670,7 @@ func BenchmarkSortBidsAscending(b *testing.B) { func BenchmarkSortAsksStandard(b *testing.B) { s := deployUnorderedSlice() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortAsks() } @@ -680,7 +680,7 @@ func BenchmarkSortAsksStandard(b *testing.B) { func BenchmarkSortBidsStandard(b *testing.B) { s := deployUnorderedSlice() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortBids() } @@ -690,7 +690,7 @@ func BenchmarkSortBidsStandard(b *testing.B) { func BenchmarkSortAsksAscending(b *testing.B) { s := deploySliceOrdered() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortAsks() } @@ -701,7 +701,7 @@ func BenchmarkSortBidsDescending(b *testing.B) { s := deploySliceOrdered() s.Reverse() for i := 0; i < b.N; i++ { - // nolint: gocritic + //nolint: gocritic ts := append(s[:0:0], s...) ts.SortBids() } diff --git a/exchanges/orderbook/unsafe_test.go b/exchanges/orderbook/unsafe_test.go index 7a43ebef..552e5549 100644 --- a/exchanges/orderbook/unsafe_test.go +++ b/exchanges/orderbook/unsafe_test.go @@ -25,7 +25,7 @@ func TestUnsafe(t *testing.T) { ob2 := &externalBook{} ob.Lock() - ob.Unlock() // nolint:staticcheck, gocritic // Not needed in test + ob.Unlock() //nolint:staticcheck, gocritic // Not needed in test ob.LockWith(ob2) ob.UnlockWith(ob2) } diff --git a/exchanges/sharedtestvalues/customex.go b/exchanges/sharedtestvalues/customex.go index 017bf6a3..4bf9711d 100644 --- a/exchanges/sharedtestvalues/customex.go +++ b/exchanges/sharedtestvalues/customex.go @@ -20,268 +20,335 @@ import ( "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" ) +// CustomEx creates a mock custom exchange type CustomEx struct { exchange.Base } +// Setup is a mock method for CustomEx func (c *CustomEx) Setup(exch *config.Exchange) error { return nil } +// Start is a mock method for CustomEx func (c *CustomEx) Start(wg *sync.WaitGroup) error { return nil } +// SetDefaults is a mock method for CustomEx func (c *CustomEx) SetDefaults() { } +// GetName is a mock method for CustomEx func (c *CustomEx) GetName() string { return "customex" } +// IsEnabled is a mock method for CustomEx func (c *CustomEx) IsEnabled() bool { return true } +// SetEnabled is a mock method for CustomEx func (c *CustomEx) SetEnabled(bool) { } +// ValidateCredentials is a mock method for CustomEx func (c *CustomEx) ValidateCredentials(ctx context.Context, a asset.Item) error { return nil } +// FetchTicker is a mock method for CustomEx func (c *CustomEx) FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { return nil, nil } +// UpdateTickers is a mock method for CustomEx func (c *CustomEx) UpdateTickers(ctx context.Context, a asset.Item) error { return nil } +// UpdateTicker is a mock method for CustomEx func (c *CustomEx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { return nil, nil } +// FetchOrderbook is a mock method for CustomEx func (c *CustomEx) FetchOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { return nil, nil } +// UpdateOrderbook is a mock method for CustomEx func (c *CustomEx) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { return nil, nil } +// FetchTradablePairs is a mock method for CustomEx func (c *CustomEx) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { return nil, nil } +// UpdateTradablePairs is a mock method for CustomEx func (c *CustomEx) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { return nil } +// GetEnabledPairs is a mock method for CustomEx func (c *CustomEx) GetEnabledPairs(a asset.Item) (currency.Pairs, error) { return nil, nil } +// GetAvailablePairs is a mock method for CustomEx func (c *CustomEx) GetAvailablePairs(a asset.Item) (currency.Pairs, error) { return nil, nil } +// FetchAccountInfo is a mock method for CustomEx func (c *CustomEx) FetchAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { return account.Holdings{}, nil } +// UpdateAccountInfo is a mock method for CustomEx func (c *CustomEx) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { return account.Holdings{}, nil } +// SetPairs is a mock method for CustomEx func (c *CustomEx) SetPairs(pairs currency.Pairs, a asset.Item, enabled bool) error { return nil } +// GetAssetTypes is a mock method for CustomEx func (c *CustomEx) GetAssetTypes(enabled bool) asset.Items { return nil } +// GetRecentTrades is a mock method for CustomEx func (c *CustomEx) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { return nil, nil } +// GetHistoricTrades is a mock method for CustomEx func (c *CustomEx) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) { return nil, nil } +// SupportsAutoPairUpdates is a mock method for CustomEx func (c *CustomEx) SupportsAutoPairUpdates() bool { return false } +// SupportsRESTTickerBatchUpdates is a mock method for CustomEx func (c *CustomEx) SupportsRESTTickerBatchUpdates() bool { return false } +// GetFeeByType is a mock method for CustomEx func (c *CustomEx) GetFeeByType(ctx context.Context, f *exchange.FeeBuilder) (float64, error) { return 0.0, nil } +// GetLastPairsUpdateTime is a mock method for CustomEx func (c *CustomEx) GetLastPairsUpdateTime() int64 { return 0 } +// GetWithdrawPermissions is a mock method for CustomEx func (c *CustomEx) GetWithdrawPermissions() uint32 { return 0 } +// FormatWithdrawPermissions is a mock method for CustomEx func (c *CustomEx) FormatWithdrawPermissions() string { return "" } +// SupportsWithdrawPermissions is a mock method for CustomEx func (c *CustomEx) SupportsWithdrawPermissions(permissions uint32) bool { return false } +// GetFundingHistory is a mock method for CustomEx func (c *CustomEx) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, nil } +// SubmitOrder is a mock method for CustomEx func (c *CustomEx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { return nil, nil } +// ModifyOrder is a mock method for CustomEx func (c *CustomEx) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, nil } +// CancelOrder is a mock method for CustomEx func (c *CustomEx) CancelOrder(ctx context.Context, o *order.Cancel) error { return nil } +// CancelBatchOrders is a mock method for CustomEx func (c *CustomEx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, nil } +// CancelAllOrders is a mock method for CustomEx func (c *CustomEx) CancelAllOrders(ctx context.Context, orders *order.Cancel) (order.CancelAllResponse, error) { return order.CancelAllResponse{}, nil } +// GetOrderInfo is a mock method for CustomEx func (c *CustomEx) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { return order.Detail{}, nil } +// GetDepositAddress is a mock method for CustomEx func (c *CustomEx) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, accountID, chain string) (*deposit.Address, error) { return nil, nil } +// GetOrderHistory is a mock method for CustomEx func (c *CustomEx) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { return nil, nil } +// GetWithdrawalsHistory is a mock method for CustomEx func (c *CustomEx) GetWithdrawalsHistory(ctx context.Context, code currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { return []exchange.WithdrawalHistory{}, nil } +// GetActiveOrders is a mock method for CustomEx func (c *CustomEx) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { return []order.Detail{}, nil } +// WithdrawCryptocurrencyFunds is a mock method for CustomEx func (c *CustomEx) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } +// WithdrawFiatFunds is a mock method for CustomEx func (c *CustomEx) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } +// WithdrawFiatFundsToInternationalBank is a mock method for CustomEx func (c *CustomEx) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } +// SetHTTPClientUserAgent is a mock method for CustomEx func (c *CustomEx) SetHTTPClientUserAgent(ua string) error { return nil } +// GetHTTPClientUserAgent is a mock method for CustomEx func (c *CustomEx) GetHTTPClientUserAgent() (string, error) { return "", nil } +// SetClientProxyAddress is a mock method for CustomEx func (c *CustomEx) SetClientProxyAddress(addr string) error { return nil } +// SupportsREST is a mock method for CustomEx func (c *CustomEx) SupportsREST() bool { return true } +// GetSubscriptions is a mock method for CustomEx func (c *CustomEx) GetSubscriptions() ([]stream.ChannelSubscription, error) { return nil, nil } +// GetDefaultConfig is a mock method for CustomEx func (c *CustomEx) GetDefaultConfig() (*config.Exchange, error) { return nil, nil } +// GetBase is a mock method for CustomEx func (c *CustomEx) GetBase() *exchange.Base { return nil } +// SupportsAsset is a mock method for CustomEx func (c *CustomEx) SupportsAsset(assetType asset.Item) bool { return false } +// GetHistoricCandles is a mock method for CustomEx func (c *CustomEx) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, nil } +// GetHistoricCandlesExtended is a mock method for CustomEx func (c *CustomEx) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, nil } +// DisableRateLimiter is a mock method for CustomEx func (c *CustomEx) DisableRateLimiter() error { return nil } +// EnableRateLimiter is a mock method for CustomEx func (c *CustomEx) EnableRateLimiter() error { return nil } +// GetWebsocket is a mock method for CustomEx func (c *CustomEx) GetWebsocket() (*stream.Websocket, error) { return nil, nil } +// IsWebsocketEnabled is a mock method for CustomEx func (c *CustomEx) IsWebsocketEnabled() bool { return false } +// SupportsWebsocket is a mock method for CustomEx func (c *CustomEx) SupportsWebsocket() bool { return false } +// SubscribeToWebsocketChannels is a mock method for CustomEx func (c *CustomEx) SubscribeToWebsocketChannels(channels []stream.ChannelSubscription) error { return nil } +// UnsubscribeToWebsocketChannels is a mock method for CustomEx func (c *CustomEx) UnsubscribeToWebsocketChannels(channels []stream.ChannelSubscription) error { return nil } +// IsAssetWebsocketSupported is a mock method for CustomEx func (c *CustomEx) IsAssetWebsocketSupported(aType asset.Item) bool { return false } +// FlushWebsocketChannels is a mock method for CustomEx func (c *CustomEx) FlushWebsocketChannels() error { return nil } +// AuthenticateWebsocket is a mock method for CustomEx func (c *CustomEx) AuthenticateWebsocket(ctx context.Context) error { return nil } +// GetOrderExecutionLimits is a mock method for CustomEx func (c *CustomEx) GetOrderExecutionLimits(a asset.Item, cp currency.Pair) (order.MinMaxLevel, error) { return order.MinMaxLevel{}, nil } +// CheckOrderExecutionLimits is a mock method for CustomEx func (c *CustomEx) CheckOrderExecutionLimits(a asset.Item, cp currency.Pair, price, amount float64, orderType order.Type) error { return nil } +// UpdateOrderExecutionLimits is a mock method for CustomEx func (c *CustomEx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { return nil } diff --git a/exchanges/stream/buffer/buffer_test.go b/exchanges/stream/buffer/buffer_test.go index 12571275..afa366b4 100644 --- a/exchanges/stream/buffer/buffer_test.go +++ b/exchanges/stream/buffer/buffer_test.go @@ -63,12 +63,12 @@ func bidAskGenerator() []orderbook.Item { var response []orderbook.Item randIterator := 100 for i := 0; i < randIterator; i++ { - price := float64(rand.Intn(1000)) // nolint:gosec // no need to import crypo/rand for testing + price := float64(rand.Intn(1000)) //nolint:gosec // no need to import crypo/rand for testing if price == 0 { price = 1 } response = append(response, orderbook.Item{ - Amount: float64(rand.Intn(10)), // nolint:gosec // no need to import crypo/rand for testing + Amount: float64(rand.Intn(10)), //nolint:gosec // no need to import crypo/rand for testing Price: price, ID: int64(i), }) @@ -134,7 +134,7 @@ func BenchmarkBufferPerformance(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - randomIndex := rand.Intn(4) // nolint:gosec // no need to import crypo/rand for testing + randomIndex := rand.Intn(4) //nolint:gosec // no need to import crypo/rand for testing update.Asks = itemArray[randomIndex] update.Bids = itemArray[randomIndex] err = holder.Update(update) @@ -145,7 +145,8 @@ func BenchmarkBufferPerformance(b *testing.B) { } // BenchmarkBufferSortingPerformance benchmark -// 613964 2093 ns/op 440 B/op 4 allocs/op +// +// 613964 2093 ns/op 440 B/op 4 allocs/op func BenchmarkBufferSortingPerformance(b *testing.B) { holder, asks, bids, err := createSnapshot() if err != nil { @@ -162,7 +163,7 @@ func BenchmarkBufferSortingPerformance(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - randomIndex := rand.Intn(4) // nolint:gosec // no need to import crypo/rand for testing + randomIndex := rand.Intn(4) //nolint:gosec // no need to import crypo/rand for testing update.Asks = itemArray[randomIndex] update.Bids = itemArray[randomIndex] err = holder.Update(update) @@ -191,7 +192,7 @@ func BenchmarkBufferSortingByIDPerformance(b *testing.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - randomIndex := rand.Intn(4) // nolint:gosec // no need to import crypo/rand for testing + randomIndex := rand.Intn(4) //nolint:gosec // no need to import crypo/rand for testing update.Asks = itemArray[randomIndex] update.Bids = itemArray[randomIndex] err = holder.Update(update) @@ -221,7 +222,7 @@ func BenchmarkNoBufferPerformance(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - randomIndex := rand.Intn(4) // nolint:gosec // no need to import crypo/rand for testing + randomIndex := rand.Intn(4) //nolint:gosec // no need to import crypo/rand for testing update.Asks = itemArray[randomIndex] update.Bids = itemArray[randomIndex] err = obl.Update(update) @@ -897,7 +898,7 @@ func deploySliceOrdered(size int) orderbook.Items { rand.Seed(time.Now().UnixNano()) var items []orderbook.Item for i := 0; i < size; i++ { - items = append(items, orderbook.Item{Amount: 1, Price: rand.Float64() + float64(i), ID: rand.Int63()}) // nolint:gosec // Not needed for tests + items = append(items, orderbook.Item{Amount: 1, Price: rand.Float64() + float64(i), ID: rand.Int63()}) //nolint:gosec // Not needed for tests } return items } @@ -907,7 +908,7 @@ func TestUpdateByIDAndAction(t *testing.T) { holder := orderbookHolder{} asks := deploySliceOrdered(100) - // nolint: gocritic + //nolint: gocritic bids := append(asks[:0:0], asks...) bids.Reverse() @@ -1053,7 +1054,7 @@ func TestUpdateByIDAndAction(t *testing.T) { t.Fatal("did not adjust ask item placement and details") } - book.LoadSnapshot(append(bids[:0:0], bids...), append(bids[:0:0], bids...), 0, time.Time{}, true) // nolint:gocritic + book.LoadSnapshot(append(bids[:0:0], bids...), append(bids[:0:0], bids...), 0, time.Time{}, true) //nolint:gocritic // Delete - not found err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Delete, @@ -1069,7 +1070,7 @@ func TestUpdateByIDAndAction(t *testing.T) { t.Fatalf("received: '%v' but expected: '%v'", err, errDeleteFailure) } - book.LoadSnapshot(append(bids[:0:0], bids...), append(bids[:0:0], bids...), 0, time.Time{}, true) // nolint:gocritic + book.LoadSnapshot(append(bids[:0:0], bids...), append(bids[:0:0], bids...), 0, time.Time{}, true) //nolint:gocritic // Delete - found err = holder.updateByIDAndAction(&orderbook.Update{ Action: orderbook.Delete, diff --git a/exchanges/ticker/ticker.go b/exchanges/ticker/ticker.go index 169343e8..51e5ac78 100644 --- a/exchanges/ticker/ticker.go +++ b/exchanges/ticker/ticker.go @@ -180,7 +180,7 @@ func (s *Service) update(p *Price) error { } t.Price = *p - // nolint: gocritic + //nolint: gocritic ids := append(t.Assoc, t.Main) s.mu.Unlock() return s.mux.Publish(p, ids...) diff --git a/exchanges/ticker/ticker_test.go b/exchanges/ticker/ticker_test.go index 2ab1ac4e..183fc8ae 100644 --- a/exchanges/ticker/ticker_test.go +++ b/exchanges/ticker/ticker_test.go @@ -342,17 +342,17 @@ func TestProcessTicker(t *testing.T) { // non-appending function to tickers wg.Add(1) go func() { - // nolint:gosec // no need to import crypo/rand for testing + //nolint:gosec // no need to import crypo/rand for testing newName := "Exchange" + strconv.FormatInt(rand.Int63(), 10) - newPairs, err := currency.NewPairFromStrings("BTC"+strconv.FormatInt(rand.Int63(), 10), // nolint:gosec // no need to import crypo/rand for testing - "USD"+strconv.FormatInt(rand.Int63(), 10)) // nolint:gosec // no need to import crypo/rand for testing + newPairs, err := currency.NewPairFromStrings("BTC"+strconv.FormatInt(rand.Int63(), 10), //nolint:gosec // no need to import crypo/rand for testing + "USD"+strconv.FormatInt(rand.Int63(), 10)) //nolint:gosec // no need to import crypo/rand for testing if err != nil { log.Fatal(err) } tp := Price{ Pair: newPairs, - Last: rand.Float64(), // nolint:gosec // no need to import crypo/rand for testing + Last: rand.Float64(), //nolint:gosec // no need to import crypo/rand for testing ExchangeName: newName, AssetType: asset.Spot, } diff --git a/exchanges/trade/trade.go b/exchanges/trade/trade.go index a789689c..80592773 100644 --- a/exchanges/trade/trade.go +++ b/exchanges/trade/trade.go @@ -129,7 +129,7 @@ func (p *Processor) Run(wg *sync.WaitGroup) { for { <-ticker.C p.mutex.Lock() - // nolint: gocritic + //nolint: gocritic bufferCopy := append(p.buffer[:0:0], p.buffer...) p.buffer = nil p.mutex.Unlock() diff --git a/gctscript/modules/ta/indicators/indicators_test.go b/gctscript/modules/ta/indicators/indicators_test.go index be84b56c..17b96774 100644 --- a/gctscript/modules/ta/indicators/indicators_test.go +++ b/gctscript/modules/ta/indicators/indicators_test.go @@ -23,7 +23,7 @@ var ( func TestMain(m *testing.M) { for x := 0; x < 100; x++ { - v := rand.Float64() // nolint:gosec // no need to import crypo/rand for testing + v := rand.Float64() //nolint:gosec // no need to import crypo/rand for testing candle := &objects.Array{} candle.Value = append(candle.Value, &objects.Time{Value: time.Now()}, &objects.Float{Value: v}, diff --git a/gctscript/modules/wrapper_types.go b/gctscript/modules/wrapper_types.go index b1038c9c..7b5c8777 100644 --- a/gctscript/modules/wrapper_types.go +++ b/gctscript/modules/wrapper_types.go @@ -25,7 +25,7 @@ const ( // Wrapper instance of GCT to use for modules var Wrapper GCTExchange -// Exchange interface requirements +// GCTExchange interface requirements type GCTExchange interface { Exchanges(enabledOnly bool) []string IsEnabled(exch string) bool diff --git a/gctscript/wrappers/validator/validator.go b/gctscript/wrappers/validator/validator.go index a068893b..0d5b9cc4 100644 --- a/gctscript/wrappers/validator/validator.go +++ b/gctscript/wrappers/validator/validator.go @@ -263,7 +263,7 @@ func (w Wrapper) OHLCV(ctx context.Context, exch string, p currency.Pair, a asse }) for x := 1; x < 200; x++ { - r := validatorLow + rand.Float64()*(validatorHigh-validatorLow) // nolint:gosec // no need to import crypo/rand + r := validatorLow + rand.Float64()*(validatorHigh-validatorLow) //nolint:gosec // no need to import crypo/rand candle := kline.Candle{ Time: candles[x-1].Time.Add(-i.Duration()), Open: r, diff --git a/log/logger_test.go b/log/logger_test.go index 9e821d32..5e2d50be 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "io" - "io/ioutil" "log" "os" "strings" @@ -18,7 +17,7 @@ func TestMain(m *testing.M) { if err != nil { log.Fatal("cannot set up test loggers", err) } - tempDir, err := ioutil.TempDir(os.TempDir(), "") + tempDir, err := os.MkdirTemp(os.TempDir(), "") if err != nil { log.Fatal("Cannot create temporary file", err) } diff --git a/testdata/configtest.json b/testdata/configtest.json index 2e286dea..f90e9446 100644 --- a/testdata/configtest.json +++ b/testdata/configtest.json @@ -591,8 +591,8 @@ ], "pairs": { "spot": { - "enabled": "BTCKRW,ETHKRW,LTCKRW,ETCKRW,XRPKRW,BCHKRW,QTUMKRW,BTGKRW,EOSKRW", - "available": "BHPKRW,STEEMKRW,GTOKRW,ETCKRW,STRATKRW,FXKRW,LTCKRW,MIXKRW,THETAKRW,QTUMKRW,ADAKRW,MCOKRW,INSKRW,RDNKRW,CONKRW,FABKRW,ETHKRW,HDACKRW,BTCKRW,POWRKRW,CMTKRW,LBAKRW,ETHOSKRW,HCKRW,ETZKRW,PPTKRW,XVGKRW,WTCKRW,TMTGKRW,LOOMKRW,WETKRW,ABTKRW,ITCKRW,GXCKRW,ORBSKRW,ICXKRW,BSVKRW,MXCKRW,MITHKRW,AEKRW,SALTKRW,ARNKRW,TRUEKRW,ENJKRW,GNTKRW,PLYKRW,REPKRW,ZRXKRW,BTGKRW,APISKRW,QKCKRW,LRCKRW,DVPKRW,DADKRW,CHRKRW,BCHKRW,NPXSKRW,PIVXKRW,AMOKRW,RNTKRW,XEMKRW,FCTKRW,WOMKRW,WAXPKRW,DACKRW,OMGKRW,PCMKRW,CROKRW,FNBKRW,ANKRKRW,EOSKRW,KNCKRW,OCNKRW,MTLKRW,XSRKRW,VALORKRW,TRVKRW,AUTOKRW,HYCKRW,AOAKRW,BTTKRW,MBLKRW,VETKRW,XRPKRW,ZILKRW,ELFKRW,LAMBKRW,POLYKRW,IOSTKRW,BZNTKRW,CTXCKRW,BATKRW,FZZKRW,PAYKRW,BCDKRW,SNTKRW,WAVESKRW,XLMKRW,LINKKRW,OGOKRW,WICCKRW,TRXKRW" + "enabled": "BTCKRW,ETHKRW,ETCKRW,XRPKRW,BCHKRW,QTUMKRW,BTGKRW,EOSKRW", + "available": "BHPKRW,STEEMKRW,GTOKRW,ETCKRW,STRATKRW,FXKRW,MIXKRW,THETAKRW,QTUMKRW,ADAKRW,MCOKRW,INSKRW,RDNKRW,CONKRW,FABKRW,ETHKRW,HDACKRW,BTCKRW,POWRKRW,CMTKRW,LBAKRW,ETHOSKRW,HCKRW,ETZKRW,PPTKRW,XVGKRW,WTCKRW,TMTGKRW,LOOMKRW,WETKRW,ABTKRW,ITCKRW,GXCKRW,ORBSKRW,ICXKRW,BSVKRW,MXCKRW,MITHKRW,AEKRW,SALTKRW,ARNKRW,TRUEKRW,ENJKRW,GNTKRW,PLYKRW,REPKRW,ZRXKRW,BTGKRW,APISKRW,QKCKRW,LRCKRW,DVPKRW,DADKRW,CHRKRW,BCHKRW,NPXSKRW,PIVXKRW,AMOKRW,RNTKRW,XEMKRW,FCTKRW,WOMKRW,WAXPKRW,DACKRW,OMGKRW,PCMKRW,CROKRW,FNBKRW,ANKRKRW,EOSKRW,KNCKRW,OCNKRW,MTLKRW,XSRKRW,VALORKRW,TRVKRW,AUTOKRW,HYCKRW,AOAKRW,BTTKRW,MBLKRW,VETKRW,XRPKRW,ZILKRW,ELFKRW,LAMBKRW,POLYKRW,IOSTKRW,BZNTKRW,CTXCKRW,BATKRW,FZZKRW,PAYKRW,BCDKRW,SNTKRW,WAVESKRW,XLMKRW,LINKKRW,OGOKRW,WICCKRW,TRXKRW" } } },