From 879c9e2cb2bb7e4364b0e3a36660a4615f2c4160 Mon Sep 17 00:00:00 2001 From: John Cairns Date: Fri, 13 Sep 2024 14:26:47 -0500 Subject: [PATCH] lint and check, cleanup idiomatic go issues --- .devcontainer/devcontainer.json | 33 ++++++ .dockerignore | 11 ++ .github/dependabot.yml | 20 ++++ .github/workflows/main.yml | 2 - .gitignore | 1 + .golangci.yml | 6 + .vscode/tasks.json | 106 ++++++++++++++++++ Dockerfile | 34 ++++-- Makefile | 41 ++++++- go.mod | 4 +- go.sum | 2 - internal/clients/ethereum/client.go | 48 ++++---- internal/config/config.go | 4 - internal/contractCaller/contractCaller.go | 6 +- internal/contractManager/contractManager.go | 33 ++++-- .../sqliteContractStore.go | 5 +- .../eigenState/avsOperators/avsOperators.go | 11 +- .../avsOperators/avsOperators_test.go | 7 +- .../operatorShares/operatorShares_test.go | 11 +- .../rewardSubmissions/rewardSubmissions.go | 17 ++- .../rewardSubmissions_test.go | 13 ++- .../stakerDelegations_test.go | 2 +- .../stakerShares/stakerShares_test.go | 23 ++-- .../stateManager/stateManager_test.go | 5 +- .../submittedDistributionRoots.go | 15 +-- internal/fetcher/fetcher.go | 6 +- internal/indexer/transactionLogs.go | 9 +- internal/sidecar/blockIndexer.go | 12 +- internal/sidecar/sidecar.go | 22 ++-- internal/storage/sqlite/sqlite_test.go | 10 +- internal/storage/sqlite/storage.go | 11 +- internal/utils/utils.go | 2 +- main.go | 5 +- 33 files changed, 386 insertions(+), 151 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 .github/dependabot.yml create mode 100644 .golangci.yml create mode 100644 .vscode/tasks.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..33bba3f6 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile +{ + "name": "Existing Dockerfile", + "build": { + // Sets the run context to one level up instead of the .devcontainer folder. + "context": "..", + // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. + "dockerfile": "../Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": [ + "golang.go" + ] + } + } + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Uncomment the next line to run commands after the container is created. + // "postCreateCommand": "cat /etc/os-release", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "devcontainer" +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..bb368824 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +.idea +*.sw* +*.terraform +*.terraform* +/bin +/scripts/runLocal +sidecar.db* +*.db* +/sqlite +/sqlite* +go-sidecar diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..a9e6863b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for more information: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +# https://containers.dev/guide/dependabot + +version: 2 +updates: + - package-ecosystem: "devcontainers" + directory: "/" + schedule: + interval: weekly + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: weekly + - package-ecosystem: "go" + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81dcbd50..c16fc790 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,5 @@ name: build-container - on: push - jobs: test: runs-on: ubuntu-24.04 diff --git a/.gitignore b/.gitignore index 52746896..bb368824 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ sidecar.db* *.db* /sqlite /sqlite* +go-sidecar diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..6f3faf69 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,6 @@ +linters: + enable: + - govet + - staticcheck + - unused + - errcheck diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..0814abaa --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,106 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "install", + "type": "shell", + "command": "make deps/go", + "options": { + "cwd": "${workspaceFolder}", + }, + "group": { + "kind": "build" + } + }, + { + "label": "fmt", + "type": "shell", + "command": "gofmt -l .", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "install", + "group": { + "kind": "build" + } + }, + { + "label": "vet", + "type": "shell", + "command": "go vet ./...", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "fmtcheck", + "group": { + "kind": "build" + } + }, + { + "label": "lint", + "type": "shell", + "command": "golangci-lint run -c .golangci.yml", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "vet", + "group": { + "kind": "build" + } + }, + { + "label": "build", + "type": "shell", + "command": "go build ./...", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "lint", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "clean", + "type": "shell", + "command": "go clean ./...", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "build", + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "test", + "type": "shell", + "command": "go test ./...", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "lint", + "group": { + "kind": "test", + "isDefault": true + } + }, + { + "label": "staticcheck", + "type": "shell", + "command": "staticcheck ./...", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": "test", + "group": { + "kind": "test", + "isDefault": false + } + }, + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1d60ba5c..663d26bb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,31 @@ -FROM golang:1.22-bullseye as build +FROM golang:1.22-bullseye AS build RUN apt-get update RUN apt-get install -y make postgresql-client -RUN mkdir /build +RUN useradd --create-home -s /bin/bash gobuild +RUN usermod -a -G sudo gobuild +RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers -COPY . /build - -WORKDIR /build +ARG PROJECT=go-sidecar +RUN mkdir -p /workspaces/${PROJECT} +WORKDIR /workspaces/${PROJECT} +COPY --chown=gobuild:gobuild . . +# system and linux dependencies RUN make deps-linux +RUN chown -R gobuild:gobuild /go + +# local dependencies +ENV USER=gobuild +ENV GOBIN=/go/bin +ENV PATH=$PATH:${GOBIN} +USER gobuild -RUN make build +RUN git config --global --add safe.directory /workspaces/${PROJECT} -# FROM golang:1.22-bullseye as run -# -# RUN apt-get update -# RUN apt-get install -y vim postgresql-client -# -# COPY --from=build /build/bin/cmd /bin +RUN make yamlfmt +RUN make fmtcheck +RUN make vet +RUN make lint +RUN make test diff --git a/Makefile b/Makefile index 5643da68..9237f8e5 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ .PHONY: deps proto +deps/dev: + go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 + go install honnef.co/go/tools/cmd/staticcheck@latest + go install github.com/google/yamlfmt/cmd/yamlfmt@latest + deps/go: go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 @@ -16,7 +21,7 @@ deps/go: google.golang.org/grpc/cmd/protoc-gen-go-grpc go mod tidy -deps-linux: deps/go +deps-linux: deps/go deps/dev BIN="/usr/local/bin" VERSION="1.32.2" && \ curl -sSL "https://github.com/bufbuild/buf/releases/download/v${VERSION}/buf-$(uname -s)-$(uname -m)" -o "${BIN}/buf" && \ chmod +x "${BIN}/buf" @@ -35,7 +40,7 @@ clean: .PHONY: build/cmd/sidecar build/cmd/sidecar: - go build -o bin/cmd/sidecar cmd/sidecar/main.go + go build -ldflags="-s -w" -o bin/cmd/sidecar cmd/sidecar/main.go .PHONY: build build: build/cmd/sidecar @@ -46,9 +51,39 @@ docker-buildx-self: docker-buildx: docker-buildx build --platform linux/amd64 --push -t 767397703211.dkr.ecr.us-east-1.amazonaws.com/go-sidecar:$(shell date +%s) -t 767397703211.dkr.ecr.us-east-1.amazonaws.com/go-sidecar:latest . +.PHONY: yamlfmt +yamlfmt: + yamlfmt -lint .github/workflows/*.yml .github/*.yml + +.PHONY: fmt +fmt: + gofmt -l . + + +.PHONY: fmtcheck +fmtcheck: + @unformatted_files=$$(gofmt -l .); \ + if [ -n "$$unformatted_files" ]; then \ + echo "The following files are not properly formatted:"; \ + echo "$$unformatted_files"; \ + echo "Please run 'gofmt -w .' to format them."; \ + exit 1; \ + fi +.PHONY: vet +vet: + go vet ./... + +.PHONY: lint +lint: + golangci-lint run + .PHONY: test test: TESTING=true go test -v -p 1 -parallel 1 ./... +.PHONY: staticcheck +staticcheck: + staticcheck ./... + .PHONY: ci-test -ci-test: test +ci-test: test lint vet fmtcheck yamlfmt diff --git a/go.mod b/go.mod index b9f700dd..f5ce71f9 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/ethereum/go-ethereum v1.14.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 - github.com/holiman/uint256 v1.3.1 + github.com/mattn/go-sqlite3 v1.14.23 github.com/rs/cors v1.7.0 github.com/stretchr/testify v1.9.0 github.com/wealdtech/go-merkletree/v2 v2.6.0 @@ -40,13 +40,13 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/iden3/go-iden3-crypto v0.0.16 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-sqlite3 v1.14.23 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 05724e40..bb28e9fc 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= diff --git a/internal/clients/ethereum/client.go b/internal/clients/ethereum/client.go index 615558a5..fcec9f9f 100644 --- a/internal/clients/ethereum/client.go +++ b/internal/clients/ethereum/client.go @@ -5,16 +5,17 @@ import ( "context" "encoding/json" "fmt" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" - "go.uber.org/zap" - "golang.org/x/xerrors" "io" "net/http" "strings" "sync" "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "go.uber.org/zap" + "golang.org/x/xerrors" ) const ( @@ -113,7 +114,10 @@ func (c *Client) ListenForNewBlocks( case err := <-sub.Err(): c.Logger.Sugar().Errorw("Received error", zap.Error(err)) case header := <-ch: - recvBlockHandler(header) + err = recvBlockHandler(header) + if err != nil { + c.Logger.Sugar().Errorw("Failed to handle block on exit", zap.Error(err)) + } case <-quitChan: c.Logger.Sugar().Infow("Received quit") return nil @@ -121,10 +125,6 @@ func (c *Client) ListenForNewBlocks( } } -func (c *Client) buildUrlWithPath(path string) string { - return fmt.Sprintf("%s%s", c.BaseURL, path) -} - func (c *Client) GetBlockNumber(ctx context.Context) (string, error) { res, err := c.Call(ctx, GetBlockRequest(1)) @@ -250,7 +250,7 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR } requestBody, err := json.Marshal(requests) if err != nil { - return nil, xerrors.Errorf("Failed to marshal requests", err) + return nil, xerrors.Errorf("Failed to marshal requests: %s", err) } ctx, cancel := context.WithTimeout(ctx, time.Second*20) @@ -258,7 +258,7 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR request, err := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL, bytes.NewReader(requestBody)) if err != nil { - return nil, xerrors.Errorf("Failed to make request", err) + return nil, xerrors.Errorf("Failed to make request: %s", err) } request.Header.Set("Content-Type", "application/json") @@ -266,12 +266,12 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR response, err := c.httpClient.Do(request) if err != nil { - return nil, xerrors.Errorf("Request failed", err) + return nil, xerrors.Errorf("Request failed: %s", err) } responseBody, err := io.ReadAll(response.Body) if err != nil { - return nil, xerrors.Errorf("Failed to read body", err) + return nil, xerrors.Errorf("Failed to read body: %s", err) } if response.StatusCode != http.StatusOK { @@ -283,13 +283,13 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR if strings.HasPrefix(string(responseBody), "{") { errorResponse := RPCResponse{} if err := json.Unmarshal(responseBody, &errorResponse); err != nil { - return nil, xerrors.Errorf("failed to unmarshal error response", err) + return nil, xerrors.Errorf("failed to unmarshal error response: %s", err) } c.Logger.Sugar().Debugw("Error payload returned from batch call", zap.String("error", string(responseBody)), ) if errorResponse.Error.Message != "empty batch" { - return nil, xerrors.Errorf("Error payload returned from batch call", string(responseBody)) + return nil, xerrors.Errorf("Error payload returned from batch call: %s", string(responseBody)) } } else { if err := json.Unmarshal(responseBody, &destination); err != nil { @@ -297,7 +297,7 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR zap.Error(err), zap.String("response", string(responseBody)), ) - return nil, xerrors.Errorf("failed to unmarshal response", err) + return nil, xerrors.Errorf("failed to unmarshal response: %s", err) } } response.Body.Close() @@ -311,7 +311,7 @@ func (c *Client) BatchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR batches := [][]*RPCRequest{} currentIndex := 0 - for true { + for { endIndex := currentIndex + batchSize if endIndex >= len(requests) { endIndex = len(requests) @@ -339,9 +339,7 @@ func (c *Client) BatchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR return } c.Logger.Sugar().Debugw(fmt.Sprintf("[batch %d] Received '%d' results", i, len(res))) - for _, r := range res { - results = append(results, r) - } + results = append(results, res...) }(batch) } wg.Wait() @@ -362,7 +360,7 @@ func (c *Client) Call(ctx context.Context, rpcRequest *RPCRequest) (*RPCResponse request, err := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL, bytes.NewReader(requestBody)) if err != nil { - return nil, xerrors.Errorf("Failed to make request", err) + return nil, xerrors.Errorf("Failed to make request %s", err) } request.Header.Set("Content-Type", "application/json") @@ -370,12 +368,12 @@ func (c *Client) Call(ctx context.Context, rpcRequest *RPCRequest) (*RPCResponse response, err := c.httpClient.Do(request) if err != nil { - return nil, xerrors.Errorf("Request failed", err) + return nil, xerrors.Errorf("Request failed %s", err) } responseBody, err := io.ReadAll(response.Body) if err != nil { - return nil, xerrors.Errorf("Failed to read body", err) + return nil, xerrors.Errorf("Failed to read body %s", err) } // var prettyBody bytes.Buffer // json.Indent(&prettyBody, responseBody, "", "\t") @@ -386,7 +384,7 @@ func (c *Client) Call(ctx context.Context, rpcRequest *RPCRequest) (*RPCResponse destination := &RPCResponse{} if err := json.Unmarshal(responseBody, destination); err != nil { - return nil, xerrors.Errorf("failed to unmarshal response", err) + return nil, xerrors.Errorf("failed to unmarshal response: %s", err) } if destination.Error != nil { diff --git a/internal/config/config.go b/internal/config/config.go index 04a02b4e..6dcca818 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -71,10 +71,6 @@ func getPrefixedEnvVar(key string) string { return os.Getenv(ENV_VAR_PREFIX + "_" + key) } -func getScopedEnvVar(scope EnvScope, key string) string { - return getPrefixedEnvVar(fmt.Sprintf("%s_%s", scope, key)) -} - func parseListEnvVar(envVar string) []string { if envVar == "" { return []string{} diff --git a/internal/contractCaller/contractCaller.go b/internal/contractCaller/contractCaller.go index f088c1ff..4b7b8c54 100644 --- a/internal/contractCaller/contractCaller.go +++ b/internal/contractCaller/contractCaller.go @@ -3,13 +3,14 @@ package contractCaller import ( "context" "fmt" + "math/big" + "strings" + "github.com/Layr-Labs/go-sidecar/internal/clients/ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "go.uber.org/zap" - "math/big" - "strings" ) type IContractCaller interface { @@ -78,7 +79,6 @@ func NewRecociledContractCaller(ec []*ethereum.Client, l *zap.Logger) (*Reconcil func (rcc *ReconciledContractCaller) GetOperatorRestakedStrategies(ctx context.Context, avs string, operator string, blockNumber uint64) ([]common.Address, error) { allResults := make([][]common.Address, 0) for i, ec := range rcc.EthereumClients { - ec = ec results, err := getOperatorRestakedStrategies(ctx, avs, operator, blockNumber, ec, rcc.Logger) if err != nil { rcc.Logger.Sugar().Errorw("Error fetching results for client", zap.Error(err), zap.Int("clientIndex", i)) diff --git a/internal/contractManager/contractManager.go b/internal/contractManager/contractManager.go index 4589d30a..31481cf2 100644 --- a/internal/contractManager/contractManager.go +++ b/internal/contractManager/contractManager.go @@ -3,6 +3,7 @@ package contractManager import ( "context" "fmt" + "github.com/DataDog/datadog-go/v5/statsd" "github.com/Layr-Labs/go-sidecar/internal/clients/ethereum" "github.com/Layr-Labs/go-sidecar/internal/clients/etherscan" @@ -105,7 +106,7 @@ func (cm *ContractManager) CreateContract( } // Record the contract in the contracts table - contract, _, err := cm.ContractStore.FindOrCreateContract( + _, _, err := cm.ContractStore.FindOrCreateContract( contractAddress, "", false, @@ -122,7 +123,7 @@ func (cm *ContractManager) CreateContract( cm.Logger.Sugar().Debugf(fmt.Sprintf("Created new contract '%s'", contractAddress)) } - contract = cm.FindAndSetContractAbi(contractAddress) + contract := cm.FindAndSetContractAbi(contractAddress) cm.FindAndSetLookalikeContract(contractAddress, bytecodeHash) @@ -167,15 +168,20 @@ func (cm *ContractManager) FindAndSetLookalikeContract( func (cm *ContractManager) FindAndSetContractAbi(contractAddress string) *contractStore.Contract { // Attempt to find the ABI for the contract on Etherscan - cm.Statsd.Incr(metrics.Etherscan_ContractAbi, nil, 1) + err := cm.Statsd.Incr(metrics.Etherscan_ContractAbi, nil, 1) + if err != nil { + cm.Logger.Sugar().Warnw("Failed to increment metric", + zap.Error(err), + zap.String("metric", metrics.Etherscan_ContractAbi), + ) + } + abi, err := cm.EtherscanClient.ContractABI(contractAddress) if err == nil && abi != "" { - if err != nil { - cm.Logger.Sugar().Errorw("Failed to update contract ABI", - zap.Error(err), - zap.String("contractAddress", contractAddress), - ) - } + cm.Logger.Sugar().Errorw("Failed to update contract ABI", + zap.Error(err), + zap.String("contractAddress", contractAddress), + ) } if err != nil { @@ -289,5 +295,12 @@ func (cm *ContractManager) HandleProxyContractCreation( return } - cm.CreateProxyContract(contractAddress, proxyContractAddress, blockNumber, reindexContract) + _, err := cm.CreateProxyContract(contractAddress, proxyContractAddress, blockNumber, reindexContract) + if err != nil { + cm.Logger.Sugar().Errorw("Failed to create proxy contract", + zap.Error(err), + zap.String("contractAddress", contractAddress), + zap.String("proxyContractAddress", proxyContractAddress), + ) + } } diff --git a/internal/contractStore/sqliteContractStore/sqliteContractStore.go b/internal/contractStore/sqliteContractStore/sqliteContractStore.go index 6e7a5f7e..701f26e3 100644 --- a/internal/contractStore/sqliteContractStore/sqliteContractStore.go +++ b/internal/contractStore/sqliteContractStore/sqliteContractStore.go @@ -5,6 +5,8 @@ import ( "encoding/json" "errors" "fmt" + "strings" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/contractStore" "github.com/Layr-Labs/go-sidecar/internal/sqlite" @@ -12,7 +14,6 @@ import ( "golang.org/x/xerrors" "gorm.io/gorm" "gorm.io/gorm/clause" - "strings" ) type SqliteContractStore struct { @@ -275,7 +276,7 @@ func (s *SqliteContractStore) loadContractData() (*contractStore.CoreContractsDa case config.Environment_PreProd: filename = "preprod.json" default: - return nil, xerrors.Errorf("Unknown environment: %s", s.globalConfig.Environment) + return nil, xerrors.Errorf("Unknown environment.") } jsonData, err := contractStore.CoreContracts.ReadFile(fmt.Sprintf("coreContracts/%s", filename)) if err != nil { diff --git a/internal/eigenState/avsOperators/avsOperators.go b/internal/eigenState/avsOperators/avsOperators.go index 229f57ee..7310381d 100644 --- a/internal/eigenState/avsOperators/avsOperators.go +++ b/internal/eigenState/avsOperators/avsOperators.go @@ -3,6 +3,11 @@ package avsOperators import ( "database/sql" "fmt" + "slices" + "sort" + "strings" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/base" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" @@ -16,10 +21,6 @@ import ( "golang.org/x/xerrors" "gorm.io/gorm" "gorm.io/gorm/clause" - "slices" - "sort" - "strings" - "time" ) // Schema for registered_avs_operators block state table @@ -141,7 +142,7 @@ func (a *AvsOperatorsModel) GetStateTransitions() (types.StateTransitions[Accumu } a.stateAccumulator[log.BlockNumber][slotId] = record } - if registered == false && ok { + if !registered && ok { // In this situation, we've encountered a register and unregister in the same block // which functionally results in no state change at all so we want to remove the record // from the accumulated state. diff --git a/internal/eigenState/avsOperators/avsOperators_test.go b/internal/eigenState/avsOperators/avsOperators_test.go index 74438d69..dfaa48a8 100644 --- a/internal/eigenState/avsOperators/avsOperators_test.go +++ b/internal/eigenState/avsOperators/avsOperators_test.go @@ -2,6 +2,9 @@ package avsOperators import ( "database/sql" + "testing" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" "github.com/Layr-Labs/go-sidecar/internal/logger" @@ -11,8 +14,6 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "testing" - "time" ) func setup() ( @@ -71,7 +72,7 @@ func Test_AvsOperatorState(t *testing.T) { DeletedAt: time.Time{}, } - avsOperatorState, err := NewAvsOperators(esm, grm, cfg.Network, cfg.Environment, l, cfg) + avsOperatorState, _ := NewAvsOperators(esm, grm, cfg.Network, cfg.Environment, l, cfg) assert.Equal(t, true, avsOperatorState.IsInterestingLog(&log)) diff --git a/internal/eigenState/operatorShares/operatorShares_test.go b/internal/eigenState/operatorShares/operatorShares_test.go index 3a559a73..9c9622e7 100644 --- a/internal/eigenState/operatorShares/operatorShares_test.go +++ b/internal/eigenState/operatorShares/operatorShares_test.go @@ -2,6 +2,11 @@ package operatorShares import ( "database/sql" + "math/big" + "strings" + "testing" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" "github.com/Layr-Labs/go-sidecar/internal/logger" @@ -11,10 +16,6 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "math/big" - "strings" - "testing" - "time" ) func setup() ( @@ -73,7 +74,7 @@ func Test_OperatorSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewOperatorSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewOperatorSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) err = model.InitBlockProcessing(blockNumber) assert.Nil(t, err) diff --git a/internal/eigenState/rewardSubmissions/rewardSubmissions.go b/internal/eigenState/rewardSubmissions/rewardSubmissions.go index bfeee87b..5527cb0e 100644 --- a/internal/eigenState/rewardSubmissions/rewardSubmissions.go +++ b/internal/eigenState/rewardSubmissions/rewardSubmissions.go @@ -4,6 +4,11 @@ import ( "database/sql" "encoding/json" "fmt" + "slices" + "sort" + "strings" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/base" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" @@ -18,10 +23,6 @@ import ( "golang.org/x/xerrors" "gorm.io/gorm" "gorm.io/gorm/clause" - "slices" - "sort" - "strings" - "time" ) type RewardSubmission struct { @@ -402,12 +403,8 @@ func (rs *RewardSubmissionsModel) GenerateStateRoot(blockNumber uint64) (types.S } combinedResults := make([]*RewardSubmissionDiff, 0) - for _, record := range inserts { - combinedResults = append(combinedResults, record) - } - for _, record := range deletes { - combinedResults = append(combinedResults, record) - } + combinedResults = append(combinedResults, inserts...) + combinedResults = append(combinedResults, deletes...) fullTree, err := rs.merkelizeState(blockNumber, combinedResults) if err != nil { diff --git a/internal/eigenState/rewardSubmissions/rewardSubmissions_test.go b/internal/eigenState/rewardSubmissions/rewardSubmissions_test.go index 5029da55..7b96e12c 100644 --- a/internal/eigenState/rewardSubmissions/rewardSubmissions_test.go +++ b/internal/eigenState/rewardSubmissions/rewardSubmissions_test.go @@ -2,6 +2,11 @@ package rewardSubmissions import ( "fmt" + "math/big" + "strings" + "testing" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" "github.com/Layr-Labs/go-sidecar/internal/logger" @@ -11,10 +16,6 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "math/big" - "strings" - "testing" - "time" ) func setup() ( @@ -386,7 +387,7 @@ func Test_RewardSubmissions(t *testing.T) { t.Run("multi-block test", func(t *testing.T) { esm := stateManager.NewEigenStateManager(l, grm) - model, err := NewRewardSubmissionsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewRewardSubmissionsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) submissionCounter := 0 @@ -583,7 +584,7 @@ func Test_RewardSubmissions(t *testing.T) { t.Run("single block, multiple events", func(t *testing.T) { esm := stateManager.NewEigenStateManager(l, grm) - model, err := NewRewardSubmissionsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewRewardSubmissionsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) submissionCounter := 0 diff --git a/internal/eigenState/stakerDelegations/stakerDelegations_test.go b/internal/eigenState/stakerDelegations/stakerDelegations_test.go index a59c73e6..8690c4b7 100644 --- a/internal/eigenState/stakerDelegations/stakerDelegations_test.go +++ b/internal/eigenState/stakerDelegations/stakerDelegations_test.go @@ -71,7 +71,7 @@ func Test_DelegatedStakersState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerDelegationsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerDelegationsModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) assert.Equal(t, true, model.IsInterestingLog(&log)) diff --git a/internal/eigenState/stakerShares/stakerShares_test.go b/internal/eigenState/stakerShares/stakerShares_test.go index 503db133..2cf4620c 100644 --- a/internal/eigenState/stakerShares/stakerShares_test.go +++ b/internal/eigenState/stakerShares/stakerShares_test.go @@ -1,6 +1,11 @@ package stakerShares import ( + "math/big" + "strings" + "testing" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" "github.com/Layr-Labs/go-sidecar/internal/logger" @@ -11,10 +16,6 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "math/big" - "strings" - "testing" - "time" ) func setup() ( @@ -81,7 +82,7 @@ func Test_StakerSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) err = model.InitBlockProcessing(blockNumber) assert.Nil(t, err) @@ -118,7 +119,7 @@ func Test_StakerSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) err = model.InitBlockProcessing(blockNumber) assert.Nil(t, err) @@ -154,7 +155,7 @@ func Test_StakerSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) err = model.InitBlockProcessing(blockNumber) assert.Nil(t, err) @@ -190,9 +191,9 @@ func Test_StakerSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) - err = model.InitBlockProcessing(blockNumber) + err := model.InitBlockProcessing(blockNumber) assert.Nil(t, err) change, err := model.HandleStateChange(&log) @@ -287,9 +288,9 @@ func Test_StakerSharesState(t *testing.T) { DeletedAt: time.Time{}, } - model, err := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) + model, _ := NewStakerSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg) - err = model.InitBlockProcessing(blockNumber) + err := model.InitBlockProcessing(blockNumber) assert.Nil(t, err) change, err := model.HandleStateChange(&log) diff --git a/internal/eigenState/stateManager/stateManager_test.go b/internal/eigenState/stateManager/stateManager_test.go index 2c13c876..55b667d2 100644 --- a/internal/eigenState/stateManager/stateManager_test.go +++ b/internal/eigenState/stateManager/stateManager_test.go @@ -1,6 +1,8 @@ package stateManager import ( + "testing" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/types" "github.com/Layr-Labs/go-sidecar/internal/logger" @@ -9,7 +11,6 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "testing" ) func setup() ( @@ -80,4 +81,6 @@ func Test_StateManager(t *testing.T) { assert.Equal(t, insertedStateRoots[0].EthBlockHash, root.EthBlockHash) assert.Equal(t, insertedStateRoots[0].StateRoot, root.StateRoot) }) + + teardown(NewEigenStateManager(l, grm)) } diff --git a/internal/eigenState/submittedDistributionRoots/submittedDistributionRoots.go b/internal/eigenState/submittedDistributionRoots/submittedDistributionRoots.go index 17c29e00..4e49a53d 100644 --- a/internal/eigenState/submittedDistributionRoots/submittedDistributionRoots.go +++ b/internal/eigenState/submittedDistributionRoots/submittedDistributionRoots.go @@ -4,6 +4,12 @@ import ( "database/sql" "encoding/json" "fmt" + "reflect" + "slices" + "sort" + "strconv" + "strings" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/base" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" @@ -17,11 +23,6 @@ import ( "golang.org/x/xerrors" "gorm.io/gorm" "gorm.io/gorm/clause" - "reflect" - "slices" - "sort" - "strconv" - "strings" ) type SubmittedDistributionRoots struct { @@ -157,14 +158,14 @@ func (sdr *SubmittedDistributionRootsModel) GetStateTransitions() (types.StateTr activatedAt := outputData.ActivatedAt slotId := NewSlotId(root, rootIndex) - record, ok := sdr.stateAccumulator[log.BlockNumber][slotId] + _, ok := sdr.stateAccumulator[log.BlockNumber][slotId] if ok { err := xerrors.Errorf("Duplicate distribution root submitted for slot %s at block %d", slotId, log.BlockNumber) sdr.logger.Sugar().Errorw("Duplicate distribution root submitted", zap.Error(err)) return nil, err } - record = &SubmittedDistributionRoots{ + record := &SubmittedDistributionRoots{ Root: root, BlockNumber: log.BlockNumber, RootIndex: rootIndex, diff --git a/internal/fetcher/fetcher.go b/internal/fetcher/fetcher.go index eff8dae0..10398d03 100644 --- a/internal/fetcher/fetcher.go +++ b/internal/fetcher/fetcher.go @@ -2,12 +2,13 @@ package fetcher import ( "context" + "slices" + "sync" + "github.com/Layr-Labs/go-sidecar/internal/clients/ethereum" "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/ethereum/go-ethereum/common/hexutil" "go.uber.org/zap" - "slices" - "sync" ) type Fetcher struct { @@ -43,7 +44,6 @@ func (f *Fetcher) FetchBlock(ctx context.Context, blockNumber uint64) (*FetchedB f.Logger.Sugar().Debugf("Fetching '%d' transactions from block '%d'", len(block.Transactions), blockNumber) for i, tx := range block.Transactions { - tx = tx txReceiptRequests = append(txReceiptRequests, ethereum.GetTransactionReceiptRequest(tx.Hash.Value(), uint(i))) } diff --git a/internal/indexer/transactionLogs.go b/internal/indexer/transactionLogs.go index 60a1c15b..e333e8e1 100644 --- a/internal/indexer/transactionLogs.go +++ b/internal/indexer/transactionLogs.go @@ -6,6 +6,8 @@ import ( "encoding/json" "errors" "fmt" + "regexp" + "github.com/Layr-Labs/go-sidecar/internal/clients/ethereum" "github.com/Layr-Labs/go-sidecar/internal/parser" "github.com/Layr-Labs/go-sidecar/internal/utils" @@ -13,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "go.uber.org/zap" - "regexp" ) func (idx *Indexer) getAbi(json string) (*abi.ABI, error) { @@ -35,7 +36,7 @@ func (idx *Indexer) getAbi(json string) (*abi.ABI, error) { } } // Ignore really common compilation error - if foundMatch != true { + if !foundMatch { idx.Logger.Sugar().Warnw("Error unmarshaling abi json", zap.Error(err)) } } @@ -112,7 +113,7 @@ func (idx *Indexer) ParseTransactionLogs( idx.Logger.Sugar().Errorw("Failed to decode signature") } - if decodedSig != nil && len(decodedSig) > 0 { + if len(decodedSig) > 0 { method, err = a.MethodById(decodedSig) if err != nil { idx.Logger.Sugar().Debugw(fmt.Sprintf("Failed to find method by ID '%s'", common.BytesToHash(decodedSig).String())) @@ -363,8 +364,6 @@ func ParseLogValueForType(argument abi.Argument, value string) (interface{}, err return value, nil default: return value, nil - // return value as-is - return value, nil } } diff --git a/internal/sidecar/blockIndexer.go b/internal/sidecar/blockIndexer.go index 4e591f78..d424ea86 100644 --- a/internal/sidecar/blockIndexer.go +++ b/internal/sidecar/blockIndexer.go @@ -3,9 +3,10 @@ package sidecar import ( "context" "fmt" - "go.uber.org/zap" "sync" "time" + + "go.uber.org/zap" ) func (s *Sidecar) GetLastIndexedBlock() (int64, error) { @@ -105,12 +106,9 @@ func (s *Sidecar) IndexFromCurrentToTip(ctx context.Context) error { shouldShutdown := false go func() { - for { - select { - case <-s.ShutdownChan: - s.Logger.Sugar().Infow("Received shutdown signal") - shouldShutdown = true - } + for range s.ShutdownChan { + s.Logger.Sugar().Infow("Received shutdown signal") + shouldShutdown = true } }() diff --git a/internal/sidecar/sidecar.go b/internal/sidecar/sidecar.go index 6203245d..4d3373b0 100644 --- a/internal/sidecar/sidecar.go +++ b/internal/sidecar/sidecar.go @@ -4,6 +4,11 @@ import ( "context" "errors" "fmt" + "net" + "net/http" + "regexp" + "time" + "github.com/Layr-Labs/go-sidecar/internal/clients/ethereum" "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager" @@ -18,10 +23,6 @@ import ( "golang.org/x/xerrors" "google.golang.org/grpc" "google.golang.org/grpc/reflection" - "net" - "net/http" - "regexp" - "time" ) type SidecarConfig struct { @@ -145,6 +146,7 @@ func (s *Sidecar) WithRpcServer( Addr: fmt.Sprintf(":%d", httpPort), Handler: cors.AllowAll().Handler(HttpLoggerMiddleware(mux, s.Logger)), BaseContext: func(listener net.Listener) context.Context { + //nolint:staticcheck ctx = context.WithValue(ctx, "httpServer", listener.Addr().String()) return ctx }, @@ -171,12 +173,12 @@ func (s *Sidecar) WithRpcServer( }() go func() { - for { - select { - case <-gracefulShutdown: - s.Logger.Sugar().Info("Shutting down servers") - grpcServer.GracefulStop() - httpServer.Shutdown(ctx) + for range gracefulShutdown { + s.Logger.Sugar().Info("Shutting down servers") + grpcServer.GracefulStop() + err = httpServer.Shutdown(ctx) + if err != nil { + s.Logger.Sugar().Errorw("Failed to shutdown http server", zap.Error(err)) } } }() diff --git a/internal/storage/sqlite/sqlite_test.go b/internal/storage/sqlite/sqlite_test.go index c017c180..cd531437 100644 --- a/internal/storage/sqlite/sqlite_test.go +++ b/internal/storage/sqlite/sqlite_test.go @@ -2,6 +2,10 @@ package sqlite import ( "encoding/json" + "strings" + "testing" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/logger" "github.com/Layr-Labs/go-sidecar/internal/parser" @@ -11,14 +15,11 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "gorm.io/gorm" - "strings" - "testing" - "time" ) func setup() (*gorm.DB, *zap.Logger, *config.Config) { cfg := config.NewConfig() - l, err := logger.NewLogger(&logger.LoggerConfig{Debug: true}) + l, _ := logger.NewLogger(&logger.LoggerConfig{Debug: true}) db, err := tests.GetSqliteDatabaseConnection() if err != nil { panic(err) @@ -221,4 +222,5 @@ func Test_SqliteBlockstore(t *testing.T) { assert.Contains(t, err.Error(), "UNIQUE constraint failed") }) }) + teardown(db, l) } diff --git a/internal/storage/sqlite/storage.go b/internal/storage/sqlite/storage.go index fe227233..cddb91cd 100644 --- a/internal/storage/sqlite/storage.go +++ b/internal/storage/sqlite/storage.go @@ -5,6 +5,9 @@ import ( "encoding/json" "errors" "fmt" + "strings" + "time" + "github.com/Layr-Labs/go-sidecar/internal/config" "github.com/Layr-Labs/go-sidecar/internal/parser" "github.com/Layr-Labs/go-sidecar/internal/storage" @@ -12,8 +15,6 @@ import ( "golang.org/x/xerrors" "gorm.io/gorm" "gorm.io/gorm/clause" - "strings" - "time" ) type SqliteBlockStoreConfig struct { @@ -21,7 +22,8 @@ type SqliteBlockStoreConfig struct { } type SqliteBlockStore struct { - Db *gorm.DB + Db *gorm.DB + // nolint:unused migrated bool Logger *zap.Logger GlobalConfig *config.Config @@ -98,8 +100,7 @@ func (s *SqliteBlockStore) InsertTransactionLog( s.Logger.Sugar().Errorw("Failed to marshal arguments", zap.Error(err)) } - outputDataJson := []byte{} - outputDataJson, err = json.Marshal(outputData) + outputDataJson, err := json.Marshal(outputData) if err != nil { s.Logger.Sugar().Errorw("Failed to marshal output data", zap.Error(err)) } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index d58d21f7..5a169cd8 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -12,7 +12,7 @@ var ( ) func AreAddressesEqual(a, b string) bool { - return strings.ToLower(a) == strings.ToLower(b) + return strings.EqualFold(a, b) } func ConvertBytesToString(b []byte) string { diff --git a/main.go b/main.go index 2b0ad8a7..cc865b09 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,9 @@ import ( // "encoding/json" "fmt" - "github.com/ethereum/go-ethereum/ethclient" "log" + + "github.com/ethereum/go-ethereum/ethclient" ) func main() { @@ -34,7 +35,7 @@ func main() { fmt.Printf("Got block: %+v\n", block.Transactions()[0]) - tx, _, err := client.TransactionByHash(context.Background(), block.Transactions()[0].Hash()) + tx, _, _ := client.TransactionByHash(context.Background(), block.Transactions()[0].Hash()) jsonTx, _ := json.MarshalIndent(tx, "", "\t") fmt.Printf("Transaction: %+v\n", string(jsonTx))