diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..486693a --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,43 @@ +name: golangci-lint +on: + push: + branches: + - main + - dev + - release-* + pull_request: + +permissions: + contents: read + # Optional: allow write access to checks to allow the action to annotate code in the PR. + checks: write + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: stable + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.60.3 + args: --timeout=10m + + custom-linters: + name: custom-linters + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: stable + - name: check-defer-close + run: go run ./linter/check-defer-close . + timeout-minutes: 10 + - name: check-fuzz-transitions + run: go run ./linter/fuzz-transitions + timeout-minutes: 10 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..8480c4a --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,106 @@ +run: + timeout: 5m + +linters: + disable-all: true + # Enable specific linter + # https://golangci-lint.run/usage/linters/#enabled-by-default-linters + enable: + - asciicheck + - bidichk + - durationcheck + - errcheck + - errname + - copyloopvar + - exhaustruct + - forcetypeassert + - goconst + - gofmt + - goimports + - goheader + - gomodguard + - goprintffuncname + - gosimple + - govet + - importas + - ineffassign + - makezero + - misspell + - nakedret + - nilnil + - promlinter + - staticcheck + - stylecheck + - tenv + - thelper + - tparallel + - typecheck + - thelper + - unconvert + - unused + - unparam + - revive + - gosec + - testifylint + +linters-settings: + revive: + rules: + - name: var-naming + severity: warning + disabled: false + exclude: [""] + arguments: + - ["ID", "RPC", "IDS", "JSON"] # AllowList + - [] # DenyList + - - upperCaseConst: true + gosec: + config: + G101: + pattern: "(?i)passwd|pass|password|pwd|secret|private_key|token|pw|apiKey|bearer|cred|mneumonic|seed|seedphrase|entropy" + ignore_entropy: false + # Maximum allowed entropy of the string. + entropy_threshold: "80.0" + # Maximum allowed value of entropy/string length. + # Is taken into account if entropy >= entropy_threshold/2. + per_char_threshold: "3.0" + # Calculate entropy for first N chars of the string. + truncate: "32" + +issues: + exclude-rules: + - linters: + - staticcheck + text: "SA1024: cutset contains duplicate characters" # proved to not provide much value, only false positives. + - linters: + - staticcheck + text: "SA9004: only the first constant in this group has an explicit type" # explicitly recommended in go syntax + - linters: + - stylecheck + text: "ST1003:" # requires identifiers with "id" to be "ID". + - linters: + - stylecheck + text: "ST1005:" # punctuation in error messages + - linters: + - staticcheck + text: "SA1019: \"github.com/cosmos/ibc-go/v8/modules/core/02-client/types\" is deprecated`" + - path: _test\.go + text: "var-naming: don't use underscores in Go names;" + linters: + - revive + - path: _test\.go + linters: + - goconst + - path: _test\.go + text: "G404: Use of weak random number generator" + linters: + - gosec + + max-issues-per-linter: 10000 + max-same-issues: 10000 + + exclude-files: + - ".*\\.pb\\.go" + - ".*\\.pb\\.gw\\.go" + - ".*\\.pulsar\\.go" + - ".*_mocks\\.go" diff --git a/adapter/api/worker-reputer/README.md b/adapter/api/apiadapter/README.md similarity index 100% rename from adapter/api/worker-reputer/README.md rename to adapter/api/apiadapter/README.md diff --git a/adapter/api/worker-reputer/main.go b/adapter/api/apiadapter/main.go similarity index 97% rename from adapter/api/worker-reputer/main.go rename to adapter/api/apiadapter/main.go index 3acfdd2..c5251ab 100644 --- a/adapter/api/worker-reputer/main.go +++ b/adapter/api/apiadapter/main.go @@ -1,4 +1,4 @@ -package api_worker_reputer +package apiadapter import ( "allora_offchain_node/lib" @@ -46,7 +46,7 @@ func replaceExtendedPlaceholders(urlTemplate string, params map[string]string, b func requestEndpoint(url string) (string, error) { // make request to url - resp, err := http.Get(url) + resp, err := http.Get(url) // nolint: gosec if err != nil { return "", fmt.Errorf("failed to make request to %s: %w", url, err) } @@ -145,7 +145,7 @@ func (a *AlloraAdapter) GroundTruth(node lib.ReputerConfig, blockHeight int64) ( } } log.Info().Str("url", url).Str("groundTruth", groundTruthDec.String()).Msg("Ground truth") - return lib.Truth(groundTruthDec.String()), nil + return groundTruthDec.String(), nil } func (a *AlloraAdapter) LossFunction(node lib.ReputerConfig, groundTruth string, inferenceValue string, options map[string]string) (string, error) { @@ -178,7 +178,7 @@ func (a *AlloraAdapter) LossFunction(node lib.ReputerConfig, groundTruth string, req.Header.Set("Content-Type", "application/json") // Send the request - client := &http.Client{} + client := &http.Client{} // nolint: exhaustruct resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("failed to send request: %w", err) @@ -235,7 +235,7 @@ func (a *AlloraAdapter) IsLossFunctionNeverNegative(node lib.ReputerConfig, opti req.Header.Set("Content-Type", "application/json") // Send the request - client := &http.Client{} + client := &http.Client{} // nolint: exhaustruct resp, err := client.Do(req) if err != nil { return false, fmt.Errorf("failed to send request: %w", err) diff --git a/adapter_factory.go b/adapter_factory.go index 18c9b8c..99c7cb4 100644 --- a/adapter_factory.go +++ b/adapter_factory.go @@ -1,7 +1,7 @@ package main import ( - api_worker_reputer "allora_offchain_node/adapter/api/worker-reputer" + apiAdapter "allora_offchain_node/adapter/api/apiadapter" lib "allora_offchain_node/lib" "fmt" ) @@ -9,7 +9,7 @@ import ( func NewAlloraAdapter(name string) (lib.AlloraAdapter, error) { switch name { case "api-worker-reputer": - return api_worker_reputer.NewAlloraAdapter(), nil + return apiAdapter.NewAlloraAdapter(), nil // Add other cases for different adapters here default: return nil, fmt.Errorf("unknown adapter name: %s", name) diff --git a/lib/constant.go b/lib/constant.go index 5715fdb..fc17a37 100644 --- a/lib/constant.go +++ b/lib/constant.go @@ -17,7 +17,7 @@ const ( ) // A struct that holds the name and help text for a prometheus counter -var COUNTER_DATA = []MetricsCounter{ +var CounterData = []MetricsCounter{ {InferenceRequestCount, "The total number of times worker requests inference from source"}, {ForecastRequestCount, "The total number of times worker requests forecast from source"}, {TruthRequestCount, "The total number of times reputer requests truth from source"}, diff --git a/lib/domain_config.go b/lib/domain_config.go index c709766..afd8f39 100644 --- a/lib/domain_config.go +++ b/lib/domain_config.go @@ -61,8 +61,8 @@ type WorkerConfig struct { } // Implement TopicActor interface for WorkerConfig -func (w WorkerConfig) GetTopicId() emissions.TopicId { - return w.TopicId +func (workerConfig WorkerConfig) GetTopicId() emissions.TopicId { + return workerConfig.TopicId } type ReputerConfig struct { @@ -81,8 +81,8 @@ type ReputerConfig struct { } // Implement TopicActor interface for ReputerConfig -func (r ReputerConfig) GetTopicId() emissions.TopicId { - return r.TopicId +func (reputerConfig ReputerConfig) GetTopicId() emissions.TopicId { + return reputerConfig.TopicId } type LossFunctionParameters struct { @@ -153,16 +153,16 @@ func (c *UserConfig) ValidateConfigAdapters() error { func (c *UserConfig) ValidateWalletConfig() error { if c.Wallet.WindowCorrectionFactor < WindowCorrectionFactorSuggestedMin { - return errors.New(fmt.Sprintf("window correction factor lower than suggested minimum: %f < %f", c.Wallet.WindowCorrectionFactor, WindowCorrectionFactorSuggestedMin)) + return fmt.Errorf("window correction factor lower than suggested minimum: %f < %f", c.Wallet.WindowCorrectionFactor, WindowCorrectionFactorSuggestedMin) } if c.Wallet.BlockDurationEstimated < BlockDurationEstimatedMin { - return errors.New(fmt.Sprintf("block duration estimated lower than the minimum: %f < %f", c.Wallet.BlockDurationEstimated, BlockDurationEstimatedMin)) + return fmt.Errorf("block duration estimated lower than the minimum: %f < %f", c.Wallet.BlockDurationEstimated, BlockDurationEstimatedMin) } if c.Wallet.RetryDelay < RetryDelayMin { - return errors.New(fmt.Sprintf("retry delay lower than the minimum: %d < %d", c.Wallet.RetryDelay, RetryDelayMin)) + return fmt.Errorf("retry delay lower than the minimum: %d < %d", c.Wallet.RetryDelay, RetryDelayMin) } if c.Wallet.AccountSequenceRetryDelay < AccountSequenceRetryDelayMin { - return errors.New(fmt.Sprintf("account sequence retry delay lower than the minimum: %d < %d", c.Wallet.AccountSequenceRetryDelay, AccountSequenceRetryDelayMin)) + return fmt.Errorf("account sequence retry delay lower than the minimum: %d < %d", c.Wallet.AccountSequenceRetryDelay, AccountSequenceRetryDelayMin) } return nil diff --git a/lib/factory_config.go b/lib/factory_config.go index daf7b27..a7846f6 100644 --- a/lib/factory_config.go +++ b/lib/factory_config.go @@ -51,33 +51,33 @@ func getAlloraClient(config *UserConfig) (*cosmosclient.Client, error) { return &client, nil } -func (config *UserConfig) GenerateNodeConfig() (*NodeConfig, error) { - client, err := getAlloraClient(config) +func (c *UserConfig) GenerateNodeConfig() (*NodeConfig, error) { + client, err := getAlloraClient(c) if err != nil { - config.Wallet.SubmitTx = false + c.Wallet.SubmitTx = false return nil, err } var account *cosmosaccount.Account // if we're giving a keyring ring name, with no mnemonic restore - if config.Wallet.AddressRestoreMnemonic == "" && config.Wallet.AddressKeyName != "" { + if c.Wallet.AddressRestoreMnemonic == "" && c.Wallet.AddressKeyName != "" { // get account from the keyring - acc, err := client.Account(config.Wallet.AddressKeyName) + acc, err := client.Account(c.Wallet.AddressKeyName) if err != nil { - config.Wallet.SubmitTx = false + c.Wallet.SubmitTx = false log.Error().Err(err).Msg("could not retrieve account from keyring") } else { account = &acc } - } else if config.Wallet.AddressRestoreMnemonic != "" && config.Wallet.AddressKeyName != "" { + } else if c.Wallet.AddressRestoreMnemonic != "" && c.Wallet.AddressKeyName != "" { // restore from mnemonic - acc, err := client.AccountRegistry.Import(config.Wallet.AddressKeyName, config.Wallet.AddressRestoreMnemonic, "") + acc, err := client.AccountRegistry.Import(c.Wallet.AddressKeyName, c.Wallet.AddressRestoreMnemonic, "") if err != nil { if err.Error() == "account already exists" { - acc, err = client.Account(config.Wallet.AddressKeyName) + acc, err = client.Account(c.Wallet.AddressKeyName) } if err != nil { - config.Wallet.SubmitTx = false + c.Wallet.SubmitTx = false log.Err(err).Msg("could not restore account from mnemonic") } else { account = &acc @@ -95,7 +95,7 @@ func (config *UserConfig) GenerateNodeConfig() (*NodeConfig, error) { address, err := account.Address(ADDRESS_PREFIX) if err != nil { - config.Wallet.SubmitTx = false + c.Wallet.SubmitTx = false log.Err(err).Msg("could not retrieve allora blockchain address, transactions will not be submitted to chain") } else { log.Info().Str("address", address).Msg("allora blockchain address loaded") @@ -107,12 +107,12 @@ func (config *UserConfig) GenerateNodeConfig() (*NodeConfig, error) { // Create bank client bankClient := banktypes.NewQueryClient(client.Context()) - // this is terrible, no isConnected as part of this code path + // Check chainId is set if client.Context().ChainID == "" { - return nil, nil + return nil, errors.New("ChainId is empty") } - config.Wallet.Address = address // Overwrite the address with the one from the keystore + c.Wallet.Address = address // Overwrite the address with the one from the keystore log.Info().Msg("Allora client created successfully") log.Info().Msg("Wallet address: " + address) @@ -129,9 +129,9 @@ func (config *UserConfig) GenerateNodeConfig() (*NodeConfig, error) { Node := NodeConfig{ Chain: alloraChain, - Wallet: config.Wallet, - Worker: config.Worker, - Reputer: config.Reputer, + Wallet: c.Wallet, + Worker: c.Worker, + Reputer: c.Reputer, } return &Node, nil diff --git a/lib/metrics_config.go b/lib/metrics_config.go index 7cdeb54..2e7901e 100644 --- a/lib/metrics_config.go +++ b/lib/metrics_config.go @@ -3,6 +3,7 @@ package lib import ( "net/http" "strconv" + "time" "github.com/rs/zerolog/log" @@ -31,7 +32,7 @@ func (metrics *Metrics) RegisterMetricsCounters() { for _, counter := range metrics.Counters { counterVec := prometheus.NewCounterVec( - prometheus.CounterOpts{ + prometheus.CounterOpts{ // nolint: exhaustruct Name: counter.Name, Help: counter.Help, }, @@ -47,7 +48,15 @@ func (metrics Metrics) StartMetricsServer(port string) { http.Handle("/metrics", promhttp.Handler()) go func() { log.Info().Msgf("Starting metrics server on %s", port) - if err := http.ListenAndServe(port, nil); err != nil { + srv := &http.Server{ // nolint: exhaustruct + Addr: port, + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + IdleTimeout: 60 * time.Second, + ReadHeaderTimeout: 10 * time.Second, + } + + if err := srv.ListenAndServe(); err != nil { log.Error().Err(err).Msg("Could not start metric server") return } diff --git a/lib/repo_query_actor_whitelist.go b/lib/repo_query_actor_whitelist.go index 252cc6c..b0f7158 100644 --- a/lib/repo_query_actor_whitelist.go +++ b/lib/repo_query_actor_whitelist.go @@ -22,7 +22,7 @@ func (node *NodeConfig) IsWorkerWhitelisted(topicId emissionstypes.TopicId, addr Address: address, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "check worker whitelist", ) if err != nil { @@ -46,7 +46,7 @@ func (node *NodeConfig) IsReputerWhitelisted(topicId emissionstypes.TopicId, add Address: address, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "check reputer whitelist", ) if err != nil { @@ -69,7 +69,7 @@ func (node *NodeConfig) IsWhitelistedGlobalActor(address string) (bool, error) { Address: address, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "check global actor whitelist", ) if err != nil { diff --git a/lib/repo_query_balance.go b/lib/repo_query_balance.go index c660e78..cf747fe 100644 --- a/lib/repo_query_balance.go +++ b/lib/repo_query_balance.go @@ -22,7 +22,7 @@ func (node *NodeConfig) GetBalance() (cosmossdk_io_math.Int, error) { Denom: node.Chain.DefaultBondDenom, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get balance", ) if err != nil { diff --git a/lib/repo_query_block.go b/lib/repo_query_block.go index 5a2de01..764d666 100644 --- a/lib/repo_query_block.go +++ b/lib/repo_query_block.go @@ -21,7 +21,7 @@ func (node *NodeConfig) GetReputerValuesAtBlock(topicId emissionstypes.TopicId, BlockHeightLastInference: nonce, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get reputer values at block", ) if err != nil { diff --git a/lib/repo_query_nonce.go b/lib/repo_query_nonce.go index 0be011b..f43bf69 100644 --- a/lib/repo_query_nonce.go +++ b/lib/repo_query_nonce.go @@ -21,15 +21,15 @@ func (node *NodeConfig) GetLatestOpenWorkerNonceByTopicId(topicId emissionstypes TopicId: topicId, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get open worker nonce", ) if err != nil { - return &emissionstypes.Nonce{}, err + return &emissionstypes.Nonce{}, err // nolint: exhaustruct } if len(resp.Nonces.Nonces) == 0 { - return &emissionstypes.Nonce{}, nil + return &emissionstypes.Nonce{}, nil // nolint: exhaustruct } // Per `AddWorkerNonce()` in `allora-chain/x/emissions/keeper.go`, the latest nonce is first return resp.Nonces.Nonces[0], nil @@ -48,15 +48,15 @@ func (node *NodeConfig) GetOldestReputerNonceByTopicId(topicId emissionstypes.To TopicId: topicId, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get open reputer nonce", ) if err != nil { - return &emissionstypes.Nonce{}, err + return &emissionstypes.Nonce{}, err // nolint: exhaustruct } if len(resp.Nonces.Nonces) == 0 { - return &emissionstypes.Nonce{}, nil + return &emissionstypes.Nonce{}, nil // nolint: exhaustruct } // Per `AddWorkerNonce()` in `allora-chain/x/emissions/keeper.go`, the oldest nonce is last return resp.Nonces.Nonces[len(resp.Nonces.Nonces)-1].ReputerNonce, nil diff --git a/lib/repo_query_registration.go b/lib/repo_query_registration.go index a9e2998..b48dfb5 100644 --- a/lib/repo_query_registration.go +++ b/lib/repo_query_registration.go @@ -27,7 +27,7 @@ func (node *NodeConfig) IsWorkerRegistered(topicId uint64) (bool, error) { Address: node.Wallet.Address, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "is worker registered in topic", ) if err != nil { @@ -55,7 +55,7 @@ func (node *NodeConfig) IsReputerRegistered(topicId uint64) (bool, error) { Address: node.Wallet.Address, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "is reputer registered in topic", ) if err != nil { diff --git a/lib/repo_query_stake.go b/lib/repo_query_stake.go index b6857cf..3f43737 100644 --- a/lib/repo_query_stake.go +++ b/lib/repo_query_stake.go @@ -26,7 +26,7 @@ func (node *NodeConfig) GetReputerStakeInTopic( TopicId: topicId, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get reputer stake in topic", ) if err != nil { diff --git a/lib/repo_query_topic.go b/lib/repo_query_topic.go index 434a6a1..2984427 100644 --- a/lib/repo_query_topic.go +++ b/lib/repo_query_topic.go @@ -22,7 +22,7 @@ func (node *NodeConfig) GetTopicInfo(topicId emissionstypes.TopicId) (*emissions TopicId: topicId, }) }, - query.PageRequest{}, + query.PageRequest{}, // nolint: exhaustruct "get topic info", ) if err != nil { diff --git a/lib/repo_tx_utils.go b/lib/repo_tx_utils.go index 114f36d..731ab9f 100644 --- a/lib/repo_tx_utils.go +++ b/lib/repo_tx_utils.go @@ -159,7 +159,7 @@ func (node *NodeConfig) SendDataWithRetry(ctx context.Context, req sdktypes.Msg, for retryCount := int64(0); retryCount <= node.Wallet.MaxRetries; retryCount++ { log.Debug().Msgf("SendDataWithRetry iteration started (%d/%d)", retryCount, node.Wallet.MaxRetries) // Create tx without fees - txOptions := cosmosclient.TxOptions{} + txOptions := cosmosclient.TxOptions{} // nolint: exhaustruct if globalExpectedSeqNum > 0 && node.Chain.Client.TxFactory.Sequence() != globalExpectedSeqNum { log.Debug(). Uint64("expected", globalExpectedSeqNum). @@ -230,7 +230,7 @@ func (node *NodeConfig) SendDataWithRetry(ctx context.Context, req sdktypes.Msg, log.Warn().Uint64("gas", txService.Gas()).Uint64("limit", node.Wallet.MaxFees).Msg("Gas limit exceeded, using maxFees instead") fees = node.Wallet.MaxFees } - txOptions := cosmosclient.TxOptions{ + txOptions := cosmosclient.TxOptions{ // nolint: exhaustruct Fees: fmt.Sprintf("%duallo", fees), } log.Info().Str("fees", txOptions.Fees).Msg("Attempting tx with calculated fees") diff --git a/main.go b/main.go index e85c2cb..73c98e5 100644 --- a/main.go +++ b/main.go @@ -65,11 +65,11 @@ func main() { log.Info().Msg("Starting allora offchain node...") - metrics := lib.NewMetrics(lib.COUNTER_DATA) + metrics := lib.NewMetrics(lib.CounterData) metrics.RegisterMetricsCounters() metrics.StartMetricsServer(":2112") - finalUserConfig := lib.UserConfig{} + finalUserConfig := lib.UserConfig{} // nolint: exhaustruct alloraJsonConfig := os.Getenv(lib.ALLORA_OFFCHAIN_NODE_CONFIG_JSON) if alloraJsonConfig != "" { log.Info().Msg("Config using JSON env var") diff --git a/usecase/build_commit_reputer_payload.go b/usecase/build_commit_reputer_payload.go index 19108a1..2ff1a49 100644 --- a/usecase/build_commit_reputer_payload.go +++ b/usecase/build_commit_reputer_payload.go @@ -91,20 +91,20 @@ func (suite *UseCaseSuite) ComputeLossBundle(sourceTruth string, vb *emissionsty lossMethodOptions := reputer.LossFunctionParameters.LossMethodOptions // Use the cached IsNeverNegative value - is_never_negative := false + isNeverNegative := false if reputer.LossFunctionParameters.IsNeverNegative != nil { - is_never_negative = *reputer.LossFunctionParameters.IsNeverNegative + isNeverNegative = *reputer.LossFunctionParameters.IsNeverNegative } else { var err error - is_never_negative, err = reputer.LossFunctionEntrypoint.IsLossFunctionNeverNegative(reputer, lossMethodOptions) + isNeverNegative, err = reputer.LossFunctionEntrypoint.IsLossFunctionNeverNegative(reputer, lossMethodOptions) if err != nil { return emissionstypes.ValueBundle{}, errorsmod.Wrapf(err, "failed to determine if loss function is never negative") } // cache the result - reputer.LossFunctionParameters.IsNeverNegative = &is_never_negative + reputer.LossFunctionParameters.IsNeverNegative = &isNeverNegative } - losses := emissionstypes.ValueBundle{ + losses := emissionstypes.ValueBundle{ // nolint: exhaustruct TopicId: vb.TopicId, ReputerRequestNonce: vb.ReputerRequestNonce, Reputer: vb.Reputer, @@ -122,7 +122,7 @@ func (suite *UseCaseSuite) ComputeLossBundle(sourceTruth string, vb *emissionsty return alloraMath.Dec{}, errorsmod.Wrapf(err, "error parsing loss value for %s", description) } - if is_never_negative { + if isNeverNegative { loss, err = alloraMath.Log10(loss) if err != nil { return alloraMath.Dec{}, errorsmod.Wrapf(err, "error Log10 for %s", description) diff --git a/usecase/build_commit_reputer_payload_test.go b/usecase/build_commit_reputer_payload_test.go index 1e2d7d2..c413e38 100644 --- a/usecase/build_commit_reputer_payload_test.go +++ b/usecase/build_commit_reputer_payload_test.go @@ -1,3 +1,4 @@ +// nolint:all // TODO: fix package usecase import ( diff --git a/usecase/build_commit_worker_payload.go b/usecase/build_commit_worker_payload.go index dc95510..935569b 100644 --- a/usecase/build_commit_worker_payload.go +++ b/usecase/build_commit_worker_payload.go @@ -22,7 +22,7 @@ func (suite *UseCaseSuite) BuildCommitWorkerPayload(worker lib.WorkerConfig, non return errors.New("Worker has no valid Inference or Forecast entrypoints") } - var workerResponse = lib.WorkerResponse{ + var workerResponse = lib.WorkerResponse{ // nolint: exhaustruct WorkerConfig: worker, } @@ -36,7 +36,6 @@ func (suite *UseCaseSuite) BuildCommitWorkerPayload(worker lib.WorkerConfig, non } if worker.ForecastEntrypoint != nil { - forecasts := []lib.NodeValue{} forecasts, err := worker.ForecastEntrypoint.CalcForecast(worker, nonce.BlockHeight) if err != nil { return errorsmod.Wrapf(err, "Error computing forecast for worker, topicId: %d, blockHeight: %d", worker.TopicId, nonce.BlockHeight) @@ -87,14 +86,14 @@ func (suite *UseCaseSuite) BuildCommitWorkerPayload(worker lib.WorkerConfig, non func (suite *UseCaseSuite) BuildWorkerPayload(workerResponse lib.WorkerResponse, nonce emissionstypes.BlockHeight) (emissionstypes.InferenceForecastBundle, error) { - inferenceForecastsBundle := emissionstypes.InferenceForecastBundle{} + inferenceForecastsBundle := emissionstypes.InferenceForecastBundle{} // nolint: exhaustruct if workerResponse.InfererValue != "" { infererValue, err := alloraMath.NewDecFromString(workerResponse.InfererValue) if err != nil { - return emissionstypes.InferenceForecastBundle{}, errorsmod.Wrapf(err, "error converting infererValue to Dec") + return emissionstypes.InferenceForecastBundle{}, errorsmod.Wrapf(err, "error converting infererValue to Dec") // nolint: exhaustruct } - builtInference := &emissionstypes.Inference{ + builtInference := &emissionstypes.Inference{ // nolint: exhaustruct TopicId: workerResponse.TopicId, Inferer: suite.Node.Wallet.Address, Value: infererValue, @@ -104,11 +103,11 @@ func (suite *UseCaseSuite) BuildWorkerPayload(workerResponse lib.WorkerResponse, } if len(workerResponse.ForecasterValues) > 0 { - var forecasterElements []*emissionstypes.ForecastElement + var forecasterElements []*emissionstypes.ForecastElement // nolint: exhaustruct for _, val := range workerResponse.ForecasterValues { decVal, err := alloraMath.NewDecFromString(val.Value) if err != nil { - return emissionstypes.InferenceForecastBundle{}, errorsmod.Wrapf(err, "error converting forecasterValue to Dec") + return emissionstypes.InferenceForecastBundle{}, errorsmod.Wrapf(err, "error converting forecasterValue to Dec") // nolint: exhaustruct } forecasterElements = append(forecasterElements, &emissionstypes.ForecastElement{ Inferer: val.Worker, @@ -117,7 +116,7 @@ func (suite *UseCaseSuite) BuildWorkerPayload(workerResponse lib.WorkerResponse, } if len(forecasterElements) > 0 { - forecasterValues := &emissionstypes.Forecast{ + forecasterValues := &emissionstypes.Forecast{ // nolint: exhaustruct TopicId: workerResponse.TopicId, BlockHeight: nonce, Forecaster: suite.Node.Wallet.Address, @@ -134,15 +133,15 @@ func (suite *UseCaseSuite) SignWorkerPayload(workerPayload *emissionstypes.Infer protoBytesIn := make([]byte, 0) // Create a byte slice with initial length 0 and capacity greater than 0 protoBytesIn, err := workerPayload.XXX_Marshal(protoBytesIn, true) if err != nil { - return &emissionstypes.WorkerDataBundle{}, errorsmod.Wrapf(err, "error marshalling workerPayload") + return &emissionstypes.WorkerDataBundle{}, errorsmod.Wrapf(err, "error marshalling workerPayload") // nolint: exhaustruct } sig, pk, err := suite.Node.Chain.Client.Context().Keyring.Sign(suite.Node.Chain.Account.Name, protoBytesIn, signing.SignMode_SIGN_MODE_DIRECT) if err != nil { - return &emissionstypes.WorkerDataBundle{}, errorsmod.Wrapf(err, "error signing the InferenceForecastsBundle message") + return &emissionstypes.WorkerDataBundle{}, errorsmod.Wrapf(err, "error signing the InferenceForecastsBundle message") // nolint: exhaustruct } pkStr := hex.EncodeToString(pk.Bytes()) // Create workerDataBundle with signature - workerDataBundle := &emissionstypes.WorkerDataBundle{ + workerDataBundle := &emissionstypes.WorkerDataBundle{ // nolint: exhaustruct Worker: suite.Node.Wallet.Address, InferenceForecastsBundle: workerPayload, InferencesForecastsBundleSignature: sig, diff --git a/usecase/build_commit_worker_payload_test.go b/usecase/build_commit_worker_payload_test.go index ae00bfd..83e6600 100644 --- a/usecase/build_commit_worker_payload_test.go +++ b/usecase/build_commit_worker_payload_test.go @@ -1,3 +1,4 @@ +// nolint:all // TODO: fix package usecase import ( diff --git a/usecase/mock_allora_adapter_test.go b/usecase/mock_allora_adapter_test.go index 8584f5e..fdb80a8 100644 --- a/usecase/mock_allora_adapter_test.go +++ b/usecase/mock_allora_adapter_test.go @@ -1,5 +1,6 @@ package usecase +// nolint:all // TODO: fix import ( "allora_offchain_node/lib" @@ -22,12 +23,12 @@ func (m *MockAlloraAdapter) CalcInference(config lib.WorkerConfig, timestamp int func (m *MockAlloraAdapter) CalcForecast(config lib.WorkerConfig, timestamp int64) ([]lib.NodeValue, error) { args := m.Called(config, timestamp) - return args.Get(0).([]lib.NodeValue), args.Error(1) + return args.Get(0).([]lib.NodeValue), args.Error(1) // nolint: forcetypeassert } func (m *MockAlloraAdapter) GroundTruth(config lib.ReputerConfig, timestamp int64) (lib.Truth, error) { args := m.Called(config, timestamp) - return args.Get(0).(lib.Truth), args.Error(1) + return args.Get(0).(lib.Truth), args.Error(1) // nolint: forcetypeassert } // Update LossFunction to match the new signature @@ -58,7 +59,7 @@ func (m *MockAlloraAdapter) IsLossFunctionNeverNegative(node lib.ReputerConfig, } func NewMockAlloraAdapter() *MockAlloraAdapter { - m := &MockAlloraAdapter{} + m := &MockAlloraAdapter{} // nolint: exhaustruct return m } diff --git a/usecase/spawn_actor_processes.go b/usecase/spawn_actor_processes.go index 68231d1..8319f02 100644 --- a/usecase/spawn_actor_processes.go +++ b/usecase/spawn_actor_processes.go @@ -111,7 +111,7 @@ func (suite *UseCaseSuite) processWorkerPayload(worker lib.WorkerConfig, latestN if err != nil { return latestNonceHeightActedUpon, errorsmod.Wrapf(err, "error building and committing worker payload for topic") } - log.Debug().Uint64("topicId", uint64(worker.TopicId)). + log.Debug().Uint64("topicId", worker.TopicId). Str("actorType", "worker"). Msg("Successfully finished processing payload") return latestOpenWorkerNonce.BlockHeight, nil @@ -173,7 +173,7 @@ func calculateTimeDistanceInSeconds(distanceUntilNextEpoch int64, blockDurationA // Generates a conservative random offset within the submission window func generateRandomOffset(submissionWindow int64) int64 { // Ensure the random number generator is seeded - source := rand.NewSource(uint64(time.Now().UnixNano())) + source := rand.NewSource(uint64(time.Now().UnixNano())) // nolint: gosec rng := rand.New(source) // Calculate the center of the window @@ -198,7 +198,7 @@ func (suite *UseCaseSuite) runWorkerProcess(worker lib.WorkerConfig) { log.Debug().Uint64("topicId", worker.TopicId).Msg("Worker registered") // Using the helper function - topicInfo, err := queryTopicInfo(suite, worker, "worker", "topic info: worker") + topicInfo, err := queryTopicInfo(suite, worker) if err != nil { log.Error().Err(err).Uint64("topicId", worker.TopicId).Msg("Failed to get topic info for worker") return @@ -241,7 +241,7 @@ func (suite *UseCaseSuite) runReputerProcess(reputer lib.ReputerConfig) { log.Debug().Uint64("topicId", reputer.TopicId).Msg("Reputer registered and staked") // Using the helper function - topicInfo, err := queryTopicInfo(suite, reputer, "reputer", "topic info: reputer") + topicInfo, err := queryTopicInfo(suite, reputer) if err != nil { log.Error().Err(err).Uint64("topicId", reputer.TopicId).Msg("Failed to get topic info for reputer") return @@ -276,15 +276,15 @@ func (suite *UseCaseSuite) runReputerProcess(reputer lib.ReputerConfig) { // using ActorProcessParams to handle the different configurations and functions needed for each actor type func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessParams[T]) { log.Debug(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Running actor process for topic") - topicInfo, err := queryTopicInfo(suite, params.Config, params.ActorType, "topic info: actor process") + topicInfo, err := queryTopicInfo(suite, params.Config) if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Failed to get topic info after retries") return @@ -306,11 +306,11 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP } currentBlockHeight = status.SyncInfo.LatestBlockHeight - topicInfo, err := queryTopicInfo(suite, params.Config, params.ActorType, "topic info: actor process") + topicInfo, err := queryTopicInfo(suite, params.Config) if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error getting topic info") return @@ -327,11 +327,11 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP // timeoutHeight is one epoch length away timeoutHeight := currentBlockHeight + epochLength - latestNonceHeightSentTxFor, err = params.ProcessPayload(params.Config, latestNonceHeightSentTxFor, uint64(timeoutHeight)) + latestNonceHeightSentTxFor, err = params.ProcessPayload(params.Config, latestNonceHeightSentTxFor, uint64(timeoutHeight)) // nolint: gosec if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error processing payload - could not complete transaction") } @@ -344,7 +344,7 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("waitingTimeInSeconds", waitingTimeInSeconds). Msg("Error calculating time distance to next epoch after sending tx - wait epochLength") @@ -366,11 +366,11 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP // Check if block is within the submission window if currentBlockHeight-epochLastEnded <= params.SubmissionWindowLength { // Within the submission window, attempt to process payload - latestNonceHeightSentTxFor, err = params.ProcessPayload(params.Config, latestNonceHeightSentTxFor, uint64(timeoutHeight)) + latestNonceHeightSentTxFor, err = params.ProcessPayload(params.Config, latestNonceHeightSentTxFor, uint64(timeoutHeight)) // nolint: gosec if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error processing payload - could not complete transaction") } @@ -378,7 +378,7 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP distanceUntilNextEpoch := epochEnd - currentBlockHeight if distanceUntilNextEpoch < 0 { log.Warn(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("distanceUntilNextEpoch", distanceUntilNextEpoch). Int64("submissionWindowLength", params.SubmissionWindowLength). @@ -394,14 +394,14 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error calculating time distance to next epoch after sending tx") return } log.Info(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("currentBlockHeight", currentBlockHeight). Int64("distanceUntilNextEpoch", distanceUntilNextEpoch). @@ -418,13 +418,13 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error calculating time distance to next epoch after sending tx") return } log.Warn(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("waitingTimeInSeconds", waitingTimeInSeconds). Int64("currentBlockHeight", currentBlockHeight). @@ -446,13 +446,13 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error calculating close distance to epochLength") return } log.Info(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("SubmissionWindowLength", params.SubmissionWindowLength). Int64("offset", offset). @@ -472,13 +472,13 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP if err != nil { log.Error(). Err(err). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Msg("Error calculating far distance to epochLength") return } log.Info(). - Uint64("topicId", uint64(params.Config.GetTopicId())). + Uint64("topicId", params.Config.GetTopicId()). Str("actorType", params.ActorType). Int64("currentBlockHeight", currentBlockHeight). Int64("distanceUntilNextEpoch", distanceUntilNextEpoch). @@ -495,8 +495,6 @@ func runActorProcess[T lib.TopicActor](suite *UseCaseSuite, params ActorProcessP func queryTopicInfo[T lib.TopicActor]( suite *UseCaseSuite, config T, - actorType string, - infoMsg string, ) (*emissionstypes.Topic, error) { topicInfo, err := suite.Node.GetTopicInfo(config.GetTopicId()) if err != nil { diff --git a/usecase/spawn_actor_processes_test.go b/usecase/spawn_actor_processes_test.go index 7bdd224..73e0895 100644 --- a/usecase/spawn_actor_processes_test.go +++ b/usecase/spawn_actor_processes_test.go @@ -1,9 +1,12 @@ +// nolint:all // TODO: fix + package usecase import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCalculateTimeDistanceInSeconds(t *testing.T) { @@ -110,10 +113,10 @@ func TestCalculateTimeDistanceInSeconds(t *testing.T) { t.Run(test.name, func(t *testing.T) { result, err := calculateTimeDistanceInSeconds(test.distanceUntilNextEpoch, test.blockAvgSeconds, test.correctionFactor) if test.expectedError { - assert.Error(t, err, "Expected an error for negative input") + require.Error(t, err, "Expected an error for negative input") assert.Equal(t, int64(0), result, "Expected 0 result when error occurs") } else { - assert.NoError(t, err, "Did not expect an error") + require.NoError(t, err, "Did not expect an error") assert.Equal(t, test.expectedTimeDistance, result, "Calculated time distance should match expected value") } }) diff --git a/usecase/usecase_suite.go b/usecase/usecase_suite.go index b350ae5..0850736 100644 --- a/usecase/usecase_suite.go +++ b/usecase/usecase_suite.go @@ -19,5 +19,5 @@ func NewUseCaseSuite(userConfig lib.UserConfig) (*UseCaseSuite, error) { if err != nil { return nil, err } - return &UseCaseSuite{Node: *nodeConfig}, nil + return &UseCaseSuite{Node: *nodeConfig}, nil // nolint: exhaustruct }