diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 18f1cbe66..772dc434e 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -16,6 +16,10 @@ jobs: nix_path: nixpkgs=channel:nixos-unstable - name: golangci-lint run: nix develop -c make lint-go-integration-tests + - name: Print lint report artifact + if: failure() + shell: bash + run: cat ./integration-tests/golangci-lint-integration-tests-report.xml - name: Store lint report artifact if: always() uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 @@ -35,9 +39,13 @@ jobs: nix_path: nixpkgs=channel:nixos-unstable - name: golangci-lint run: nix develop -c make lint-go-relay + - name: Print lint report artifact + if: failure() + shell: bash + run: cat ./pkg/golangci-lint-relay-report.xml - name: Store lint report artifact if: always() uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: golangci-lint-relay-report - path: ./pkg/golangci-lint-relay-report.xml \ No newline at end of file + path: ./pkg/golangci-lint-relay-report.xml diff --git a/.tool-versions b/.tool-versions index 5e36b9439..52ebfcbb2 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,8 +1,8 @@ nodejs 18.13.0 yarn 1.22.19 rust 1.59.0 -golang 1.21.1 -golangci-lint 1.52.1 +golang 1.21.6 +golangci-lint 1.55.2 pulumi 3.40.1 ginkgo 2.5.1 actionlint 1.6.22 diff --git a/Makefile b/Makefile index 43acdd31a..4030022bd 100644 --- a/Makefile +++ b/Makefile @@ -94,11 +94,11 @@ gomodtidy: .PHONY: lint-go-integration-tests lint-go-integration-tests: - cd ./integration-tests && golangci-lint --max-issues-per-linter 0 --max-same-issues 0 --color=always --exclude=dot-imports --timeout 10m --out-format checkstyle:golangci-lint-integration-tests-report.xml run || true + cd ./integration-tests && golangci-lint --max-issues-per-linter 0 --max-same-issues 0 --color=always --exclude=dot-imports --timeout 10m --out-format checkstyle:golangci-lint-integration-tests-report.xml run .PHONY: lint-go-relay lint-go-relay: - cd ./pkg && golangci-lint --max-issues-per-linter 0 --max-same-issues 0 --color=always --exclude=dot-imports --timeout 10m --out-format checkstyle:golangci-lint-relay-report.xml run || true + cd ./pkg && golangci-lint --max-issues-per-linter 0 --max-same-issues 0 --color=always --exclude=dot-imports --timeout 10m --out-format checkstyle:golangci-lint-relay-report.xml run .PHONY: upgrade-e2e-solana-image upgrade-e2e-solana-image: diff --git a/flake.lock b/flake.lock index 5aacf0d5e..0b9d870fd 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1692799911, - "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -23,11 +23,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -38,11 +38,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1694183432, - "narHash": "sha256-YyPGNapgZNNj51ylQMw9lAgvxtM2ai1HZVUu3GS8Fng=", + "lastModified": 1707689078, + "narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "db9208ab987cdeeedf78ad9b4cf3c55f5ebd269b", + "rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8", "type": "github" }, "original": { @@ -54,11 +54,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1681358109, - "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", + "lastModified": 1706487304, + "narHash": "sha256-LE8lVX28MV2jWJsidW13D2qrHU/RUUONendL2Q/WlJg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", + "rev": "90f456026d284c22b3e3497be980b2e47d0b28ac", "type": "github" }, "original": { @@ -81,11 +81,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1694398298, - "narHash": "sha256-Hi904+2V5DJhFdEy9DcARSRrGJOlYSILHUC6CgTtuZU=", + "lastModified": 1707790272, + "narHash": "sha256-KQXPNl3BLdRbz7xx+mwIq/017fxLRk6JhXHxVWCKsTU=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "6c520f2e31f4bebeb29cc4563543de7187013575", + "rev": "8dfbe2dffc28c1a18a29ffa34d5d0b269622b158", "type": "github" }, "original": { diff --git a/go.mod b/go.mod index a2d9d9405..ee369de8e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink-solana -go 1.21 +go 1.21.6 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc diff --git a/integration-tests/common/common.go b/integration-tests/common/common.go index 9985b1fe9..bcafb9b4e 100644 --- a/integration-tests/common/common.go +++ b/integration-tests/common/common.go @@ -41,7 +41,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/test_env" + test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/testenv" "github.com/smartcontractkit/chainlink-solana/integration-tests/solclient" cl_solana "github.com/smartcontractkit/chainlink-solana/pkg/solana" solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" diff --git a/integration-tests/common/test_common.go b/integration-tests/common/test_common.go index 985cc8288..b2a92b7ad 100644 --- a/integration-tests/common/test_common.go +++ b/integration-tests/common/test_common.go @@ -18,7 +18,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" - test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/test_env" + test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/testenv" "github.com/smartcontractkit/chainlink-solana/integration-tests/solclient" test_env_ctf "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" @@ -128,9 +128,9 @@ func (m *OCRv2TestState) DeployCluster(contractsDir string) { require.NoError(m.Config.T, err) // Setting the External RPC url for Gauntlet - m.Common.ChainDetails.RPCUrl = sol.InternalHttpUrl - m.Common.ChainDetails.RPCURLExternal = sol.ExternalHttpUrl - m.Common.ChainDetails.WSURLExternal = sol.ExternalWsUrl + m.Common.ChainDetails.RPCUrl = sol.InternalHTTPURL + m.Common.ChainDetails.RPCURLExternal = sol.ExternalHTTPURL + m.Common.ChainDetails.WSURLExternal = sol.ExternalWsURL if *m.Config.TestConfig.Common.Network == "devnet" { m.Common.ChainDetails.RPCUrl = *m.Config.TestConfig.Common.RPC_URL @@ -192,8 +192,8 @@ func (m *OCRv2TestState) NewSolanaClientSetup(networkSettings *solclient.SolNetw networkSettings.URLs = m.Common.Env.URLs[networkSettings.Name] } else { networkSettings.URLs = []string{ - m.Common.DockerEnv.Sol.ExternalHttpUrl, - m.Common.DockerEnv.Sol.ExternalWsUrl, + m.Common.DockerEnv.Sol.ExternalHTTPURL, + m.Common.DockerEnv.Sol.ExternalWsURL, } } ec, err := solclient.NewClient(networkSettings) @@ -357,7 +357,7 @@ func formatBuffer(buf []byte) string { func GetLatestRound(transmissions []gauntlet.Transmission) gauntlet.Transmission { highestRound := transmissions[0] for _, t := range transmissions[1:] { - if t.RoundId > highestRound.RoundId { + if t.RoundID > highestRound.RoundID { highestRound = t } } diff --git a/integration-tests/docker/test_env/sol.go b/integration-tests/docker/testenv/sol.go similarity index 80% rename from integration-tests/docker/test_env/sol.go rename to integration-tests/docker/testenv/sol.go index 99da3bc36..9233d1cde 100644 --- a/integration-tests/docker/test_env/sol.go +++ b/integration-tests/docker/testenv/sol.go @@ -1,4 +1,4 @@ -package test_env +package testenv import ( "context" @@ -28,11 +28,11 @@ import ( ) const ( - SOL_HTTP_PORT = "8899" - SOL_WS_PORT = "8900" + SolHTTPPort = "8899" + SolWSPort = "8900" ) -var config_yml = ` +var configYmlRaw = ` json_rpc_url: http://0.0.0.0:8899 websocket_url: ws://0.0.0.0:8900 keypair_path: /root/.config/solana/cli/id.json @@ -41,16 +41,16 @@ address_labels: commitment: finalized ` -var id_json = ` +var idJSONRaw = ` [94,214,238,83,144,226,75,151,226,20,5,188,42,110,64,180,196,244,6,199,29,231,108,112,67,175,110,182,3,242,102,83,103,72,221,132,137,219,215,192,224,17,146,227,94,4,173,67,173,207,11,239,127,174,101,204,65,225,90,88,224,45,205,117] ` type Solana struct { test_env.EnvComponent - ExternalHttpUrl string - ExternalWsUrl string - InternalHttpUrl string - InternalWsUrl string + ExternalHTTPURL string + ExternalWsURL string + InternalHTTPURL string + InternalWsURL string t *testing.T l zerolog.Logger Image string @@ -112,29 +112,29 @@ func (s *Solana) StartContainer() error { if err != nil { return err } - httpPort, err := c.MappedPort(testcontext.Get(s.t), test_env.NatPort(SOL_HTTP_PORT)) + httpPort, err := c.MappedPort(testcontext.Get(s.t), test_env.NatPort(SolHTTPPort)) if err != nil { return err } - wsPort, err := c.MappedPort(testcontext.Get(s.t), test_env.NatPort(SOL_WS_PORT)) + wsPort, err := c.MappedPort(testcontext.Get(s.t), test_env.NatPort(SolWSPort)) if err != nil { return err } - s.ExternalHttpUrl = fmt.Sprintf("http://%s:%s", host, httpPort.Port()) - s.InternalHttpUrl = fmt.Sprintf("http://%s:%s", s.ContainerName, SOL_HTTP_PORT) - s.ExternalWsUrl = fmt.Sprintf("ws://%s:%s", host, wsPort.Port()) - s.InternalWsUrl = fmt.Sprintf("ws://%s:%s", s.ContainerName, SOL_WS_PORT) + s.ExternalHTTPURL = fmt.Sprintf("http://%s:%s", host, httpPort.Port()) + s.InternalHTTPURL = fmt.Sprintf("http://%s:%s", s.ContainerName, SolHTTPPort) + s.ExternalWsURL = fmt.Sprintf("ws://%s:%s", host, wsPort.Port()) + s.InternalWsURL = fmt.Sprintf("ws://%s:%s", s.ContainerName, SolWSPort) s.l.Info(). - Any("ExternalHttpUrl", s.ExternalHttpUrl). - Any("InternalHttpUrl", s.InternalHttpUrl). - Any("ExternalWsUrl", s.ExternalWsUrl). - Any("InternalWsUrl", s.InternalWsUrl). + Any("ExternalHTTPURL", s.ExternalHTTPURL). + Any("InternalHTTPURL", s.InternalHTTPURL). + Any("ExternalWsURL", s.ExternalWsURL). + Any("InternalWsURL", s.InternalWsURL). Str("containerName", s.ContainerName). Msgf("Started Solana container") // validate features are properly set - inactiveLocalFeatures, err := GetInactiveFeatureHashes(s.ExternalHttpUrl) + inactiveLocalFeatures, err := GetInactiveFeatureHashes(s.ExternalHTTPURL) if err != nil { return err } @@ -144,33 +144,33 @@ func (s *Solana) StartContainer() error { return nil } -func (ms *Solana) getContainerRequest(inactiveFeatures InactiveFeatures) (*tc.ContainerRequest, error) { +func (s *Solana) getContainerRequest(inactiveFeatures InactiveFeatures) (*tc.ContainerRequest, error) { configYml, err := os.CreateTemp("", "config.yml") if err != nil { return nil, err } - _, err = configYml.WriteString(config_yml) + _, err = configYml.WriteString(configYmlRaw) if err != nil { return nil, err } - idJson, err := os.CreateTemp("", "id.json") + idJSON, err := os.CreateTemp("", "id.json") if err != nil { return nil, err } - _, err = idJson.WriteString(id_json) + _, err = idJSON.WriteString(idJSONRaw) if err != nil { return nil, err } return &tc.ContainerRequest{ - Name: ms.ContainerName, - Image: ms.Image, - ExposedPorts: []string{test_env.NatPortFormat(SOL_HTTP_PORT), test_env.NatPortFormat(SOL_WS_PORT)}, + Name: s.ContainerName, + Image: s.Image, + ExposedPorts: []string{test_env.NatPortFormat(SolHTTPPort), test_env.NatPortFormat(SolWSPort)}, Env: map[string]string{ "SERVER_PORT": "1080", }, - Networks: ms.Networks, + Networks: s.Networks, WaitingFor: tcwait.ForLog("Processed Slot: 1"). WithStartupTimeout(30 * time.Second). WithPollInterval(100 * time.Millisecond), @@ -190,13 +190,13 @@ func (ms *Solana) getContainerRequest(inactiveFeatures InactiveFeatures) (*tc.Co if err != nil { return err } - err = container.CopyFileToContainer(ctx, idJson.Name(), "/root/.config/solana/cli/id.json", 0644) + err = container.CopyFileToContainer(ctx, idJSON.Name(), "/root/.config/solana/cli/id.json", 0644) return err }, }, }, }, - Entrypoint: []string{"sh", "-c", "mkdir -p /root/.config/solana/cli && solana-test-validator -r --mint=" + ms.PublicKey + " " + inactiveFeatures.CLIString()}, + Entrypoint: []string{"sh", "-c", "mkdir -p /root/.config/solana/cli && solana-test-validator -r --mint=" + s.PublicKey + " " + inactiveFeatures.CLIString()}, }, nil } @@ -222,7 +222,7 @@ func (f InactiveFeatures) CLIString() string { // This is used in conjunction with the solana-test-validator command to produce a solana network that has the same features as mainnet // the solana-test-validator has all features on by default (released + unreleased) func GetInactiveFeatureHashes(url string) (output InactiveFeatures, err error) { - cmd := exec.Command("solana", "feature", "status", "-u="+url, "--output=json") // -um is for mainnet url + cmd := exec.Command("solana", "feature", "status", "-u="+url, "--output=json") //nolint:gosec // -um is for mainnet url stdout, err := cmd.Output() if err != nil { return nil, fmt.Errorf("Failed to get feature status: %w", err) diff --git a/integration-tests/gauntlet/gauntlet_solana.go b/integration-tests/gauntlet/gauntlet_solana.go index 4fc114517..82d0bba54 100644 --- a/integration-tests/gauntlet/gauntlet_solana.go +++ b/integration-tests/gauntlet/gauntlet_solana.go @@ -18,7 +18,7 @@ type SolanaGauntlet struct { Dir string NetworkFilePath string G *gauntlet.Gauntlet - gr *GauntletResponse + gr *Response options *gauntlet.ExecCommandOptions AccessControllerAddress string BillingControllerAddress string @@ -31,8 +31,8 @@ type SolanaGauntlet struct { VaultAddress string } -// GauntletResponse Default response output for starknet gauntlet commands -type GauntletResponse struct { +// Response Default response output for starknet gauntlet commands +type Response struct { Responses []struct { Tx struct { Hash string `json:"hash"` @@ -57,7 +57,7 @@ type GauntletResponse struct { type Transmission struct { LatestTransmissionNo int64 `json:"latestTransmissionNo"` - RoundId int64 `json:"roundId"` + RoundID int64 `json:"roundId"` Answer int64 `json:"answer"` Transmitter string `json:"transmitter"` } @@ -73,7 +73,7 @@ func NewSolanaGauntlet(workingDir string) (*SolanaGauntlet, error) { Dir: workingDir, NetworkFilePath: workingDir + "/packages/gauntlet-solana-contracts/networks", G: g, - gr: &GauntletResponse{}, + gr: &Response{}, options: &gauntlet.ExecCommandOptions{ ErrHandling: []string{}, CheckErrorsInRead: true, @@ -88,9 +88,9 @@ func NewSolanaGauntlet(workingDir string) (*SolanaGauntlet, error) { return sg, nil } -// FetchGauntletJsonOutput Parse gauntlet json response that is generated after yarn gauntlet command execution -func (sg *SolanaGauntlet) FetchGauntletJsonOutput() (*GauntletResponse, error) { - var payload = &GauntletResponse{} +// FetchGauntletJSONOutput Parse gauntlet json response that is generated after yarn gauntlet command execution +func (sg *SolanaGauntlet) FetchGauntletJSONOutput() (*Response, error) { + var payload = &Response{} gauntletOutput, err := os.ReadFile(sg.Dir + "/report.json") if err != nil { return payload, err @@ -130,7 +130,7 @@ func (sg *SolanaGauntlet) InitializeAccessController() (string, error) { if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -142,7 +142,7 @@ func (sg *SolanaGauntlet) DeployLinkToken() error { if err != nil { return err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return err } @@ -157,7 +157,7 @@ func (sg *SolanaGauntlet) InitializeStore(billingController string) (string, err if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -173,7 +173,7 @@ func (sg *SolanaGauntlet) StoreCreateFeed(length int, feedConfig *ocr2_config.St if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -186,7 +186,7 @@ func (sg *SolanaGauntlet) StoreSetValidatorConfig(feedAddress string, threshold if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -206,7 +206,7 @@ func (sg *SolanaGauntlet) InitializeOCR2(requesterAccessController string, billi if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -230,7 +230,7 @@ func (sg *SolanaGauntlet) StoreSetWriter(storeConfig *ocr2_config.StoreWriterCon if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -254,7 +254,7 @@ func (sg *SolanaGauntlet) OCR2SetBilling(ocr2BillingConfig *ocr2_config.OCR2Bill if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -273,7 +273,7 @@ func (sg *SolanaGauntlet) OCR2CreateProposal(version int) (string, error) { if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -281,14 +281,14 @@ func (sg *SolanaGauntlet) OCR2CreateProposal(version int) (string, error) { return *sg.gr.Data.Proposal, nil } -func (sg *SolanaGauntlet) ProposeOnChainConfig(proposalId string, onChainConfig ocr2_config.OCR2OnChainConfig, ocrFeedAddress string) (string, error) { +func (sg *SolanaGauntlet) ProposeOnChainConfig(proposalID string, onChainConfig ocr2_config.OCR2OnChainConfig, ocrFeedAddress string) (string, error) { config, err := json.Marshal(onChainConfig) if err != nil { return "", err } _, err = sg.G.ExecCommand([]string{ "ocr2:propose_config", - fmt.Sprintf("--proposalId=%s", proposalId), + fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), ocrFeedAddress, }, @@ -298,7 +298,7 @@ func (sg *SolanaGauntlet) ProposeOnChainConfig(proposalId string, onChainConfig if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -306,7 +306,7 @@ func (sg *SolanaGauntlet) ProposeOnChainConfig(proposalId string, onChainConfig return sg.gr.Responses[0].Contract, nil } -func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalId string, offChainConfig ocr2_config.OCROffChainConfig, ocrFeedAddress string) (string, error) { +func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalID string, offChainConfig ocr2_config.OCROffChainConfig, ocrFeedAddress string) (string, error) { config, err := json.Marshal(offChainConfig) if err != nil { return "", err @@ -314,7 +314,7 @@ func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalId string, offChainConfi _, err = sg.G.ExecCommand([]string{ "ocr2:propose_offchain_config", - fmt.Sprintf("--proposalId=%s", proposalId), + fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), ocrFeedAddress, }, @@ -324,7 +324,7 @@ func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalId string, offChainConfi if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -332,7 +332,7 @@ func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalId string, offChainConfi return sg.gr.Responses[0].Contract, nil } -func (sg *SolanaGauntlet) ProposePayees(proposalId string, payeesConfig ocr2_config.PayeeConfig, ocrFeedAddress string) (string, error) { +func (sg *SolanaGauntlet) ProposePayees(proposalID string, payeesConfig ocr2_config.PayeeConfig, ocrFeedAddress string) (string, error) { config, err := json.Marshal(payeesConfig) if err != nil { return "", err @@ -340,7 +340,7 @@ func (sg *SolanaGauntlet) ProposePayees(proposalId string, payeesConfig ocr2_con _, err = sg.G.ExecCommand([]string{ "ocr2:propose_payees", - fmt.Sprintf("--proposalId=%s", proposalId), + fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), ocrFeedAddress, }, @@ -350,7 +350,7 @@ func (sg *SolanaGauntlet) ProposePayees(proposalId string, payeesConfig ocr2_con if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -358,10 +358,10 @@ func (sg *SolanaGauntlet) ProposePayees(proposalId string, payeesConfig ocr2_con return sg.gr.Responses[0].Contract, nil } -func (sg *SolanaGauntlet) FinalizeProposal(proposalId string) (string, error) { +func (sg *SolanaGauntlet) FinalizeProposal(proposalID string) (string, error) { _, err := sg.G.ExecCommand([]string{ "ocr2:finalize_proposal", - fmt.Sprintf("--proposalId=%s", proposalId), + fmt.Sprintf("--proposalId=%s", proposalID), }, *sg.options, ) @@ -369,7 +369,7 @@ func (sg *SolanaGauntlet) FinalizeProposal(proposalId string) (string, error) { if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -377,7 +377,7 @@ func (sg *SolanaGauntlet) FinalizeProposal(proposalId string) (string, error) { return sg.gr.Responses[0].Contract, nil } -func (sg *SolanaGauntlet) AcceptProposal(proposalId string, secret string, proposalAcceptConfig ocr2_config.ProposalAcceptConfig, ocrFeedAddres string) (string, error) { +func (sg *SolanaGauntlet) AcceptProposal(proposalID string, secret string, proposalAcceptConfig ocr2_config.ProposalAcceptConfig, ocrFeedAddres string) (string, error) { config, err := json.Marshal(proposalAcceptConfig) if err != nil { return "", err @@ -385,7 +385,7 @@ func (sg *SolanaGauntlet) AcceptProposal(proposalId string, secret string, propo _, err = sg.G.ExecCommand([]string{ "ocr2:accept_proposal", - fmt.Sprintf("--proposalId=%s", proposalId), + fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--secret=%s", secret), fmt.Sprintf("--input=%s", string(config)), ocrFeedAddres, @@ -396,7 +396,7 @@ func (sg *SolanaGauntlet) AcceptProposal(proposalId string, secret string, propo if err != nil { return "", err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return "", err } @@ -416,7 +416,7 @@ func (sg *SolanaGauntlet) FetchTransmissions(ocrState string) ([]Transmission, e if err != nil { return nil, err } - sg.gr, err = sg.FetchGauntletJsonOutput() + sg.gr, err = sg.FetchGauntletJSONOutput() if err != nil { return nil, err } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 121b1099e..43e4a43b4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -7,7 +7,6 @@ replace github.com/smartcontractkit/chainlink-solana => ../ require ( github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/docker/docker v25.0.2+incompatible - github.com/ethereum/go-ethereum v1.13.8 github.com/gagliardetto/binary v0.7.7 github.com/gagliardetto/solana-go v1.8.4 github.com/go-resty/resty/v2 v2.11.0 @@ -139,6 +138,7 @@ require ( github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/go-ethereum v1.13.8 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 88bb90091..04ad82837 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -113,7 +113,7 @@ func TestSolanaOCRV2Smoke(t *testing.T) { stuck := 0 successFullRounds := 0 prevRound := gauntlet.Transmission{ - RoundId: 0, + RoundID: 0, } for successFullRounds < *config.OCR2.Smoke.NumberOfRounds { require.Less(t, stuck, 10, "Rounds have been stuck for more than 10 iterations") @@ -126,23 +126,22 @@ func TestSolanaOCRV2Smoke(t *testing.T) { continue } currentRound := common.GetLatestRound(transmissions) - if prevRound.RoundId == 0 { + if prevRound.RoundID == 0 { prevRound = currentRound } - if currentRound.RoundId <= prevRound.RoundId { + if currentRound.RoundID <= prevRound.RoundID { log.Info().Str("Transmission", sg.OcrAddress).Msg("No new transmissions") stuck++ continue } log.Info().Str("Contract", sg.OcrAddress).Interface("Answer", currentRound.Answer).Int64("RoundID", currentRound.Answer).Msg("New answer found") require.Equal(t, currentRound.Answer, int64(5), fmt.Sprintf("Actual: %d, Expected: 5", currentRound.Answer)) - require.Less(t, prevRound.RoundId, currentRound.RoundId, fmt.Sprintf("Expected round %d to be less than %d", prevRound.RoundId, currentRound.RoundId)) + require.Less(t, prevRound.RoundID, currentRound.RoundID, fmt.Sprintf("Expected round %d to be less than %d", prevRound.RoundID, currentRound.RoundID)) prevRound = currentRound successFullRounds++ time.Sleep(time.Second * 6) stuck = 0 } }) - } } diff --git a/integration-tests/solclient/deployer.go b/integration-tests/solclient/deployer.go index 63089f1f5..f24a18a27 100644 --- a/integration-tests/solclient/deployer.go +++ b/integration-tests/solclient/deployer.go @@ -19,7 +19,7 @@ import ( access_controller2 "github.com/smartcontractkit/chainlink-solana/contracts/generated/access_controller" ocr_2 "github.com/smartcontractkit/chainlink-solana/contracts/generated/ocr2" store2 "github.com/smartcontractkit/chainlink-solana/contracts/generated/store" - test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/test_env" + test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/testenv" ) // All account sizes are calculated from Rust structures, ex. programs/access-controller/src/lib.rs:L80 @@ -234,17 +234,6 @@ func (c *ContractDeployer) CreateFeed(desc string, decimals uint8, granularity i return nil } -func (c *ContractDeployer) addMintToAccInstr(instr *[]solana.Instruction, dest solana.PublicKey, amount uint64) error { - *instr = append(*instr, token.NewMintToInstruction( - amount, - c.Accounts.Mint.PublicKey(), - dest, - c.Accounts.MintAuthority.PublicKey(), - nil, - ).Build()) - return nil -} - func (c *ContractDeployer) DeployLinkTokenContract() (*LinkToken, error) { var err error payer := c.Client.DefaultWallet diff --git a/integration-tests/solclient/ocr2.go b/integration-tests/solclient/ocr2.go index 2c8ac7598..c2f0f7e29 100644 --- a/integration-tests/solclient/ocr2.go +++ b/integration-tests/solclient/ocr2.go @@ -190,12 +190,6 @@ func (m *OCRv2) makeDigest() ([]byte, error) { func (m *OCRv2) fetchProposalAccount() (*ocr_2.Proposal, error) { var proposal ocr_2.Proposal - err := m.Client.RPC.GetAccountDataInto( - context.Background(), - m.Proposal.PublicKey(), - &proposal, - ) - // reimplement GetAccountDataInto with options resp, err := m.Client.RPC.GetAccountInfoWithOpts( context.Background(), m.Proposal.PublicKey(), diff --git a/integration-tests/solclient/solclient.go b/integration-tests/solclient/solclient.go index ea54027bb..d2d3a638c 100644 --- a/integration-tests/solclient/solclient.go +++ b/integration-tests/solclient/solclient.go @@ -10,9 +10,6 @@ import ( "path/filepath" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/gagliardetto/solana-go" @@ -89,14 +86,6 @@ type Client struct { LinkToken *LinkToken } -func (c *Client) BalanceAt(ctx context.Context, address common.Address) (*big.Int, error) { - panic("implement me") -} - -func (c *Client) GetTxReceipt(txHash common.Hash) (*types.Receipt, error) { - panic("implement me") -} - func (c *Client) GetNetworkType() string { return c.Config.Type } @@ -472,22 +461,6 @@ func (c *Client) LatestBlockNumber(ctx context.Context) (uint64, error) { panic("implement me") } -func (c *Client) DeployContract(contractName string, deployer blockchain.ContractDeployer) (*common.Address, *types.Transaction, interface{}, error) { - panic("implement me") -} - -func (c *Client) TransactionOpts(from *blockchain.EthereumWallet) (*bind.TransactOpts, error) { - panic("implement me") -} - -func (c *Client) ProcessTransaction(tx *types.Transaction) error { - panic("implement me") -} - -func (c *Client) IsTxConfirmed(txHash common.Hash) (bool, error) { - panic("implement me") -} - func (c *Client) GasStats() *blockchain.GasStats { panic("implement me") } diff --git a/ops/monitoring/Dockerfile b/ops/monitoring/Dockerfile index 60092d296..7ae9a9c25 100644 --- a/ops/monitoring/Dockerfile +++ b/ops/monitoring/Dockerfile @@ -1,6 +1,6 @@ # Build image -FROM golang:1.21.5 AS build +FROM golang:1.21.10 AS build # OS dependencies RUN apt-get update && apt-get install -y wget gcc diff --git a/pkg/monitoring/testutils/testutils.go b/pkg/monitoring/testutils/testutils.go index d1998fef7..17e46b966 100644 --- a/pkg/monitoring/testutils/testutils.go +++ b/pkg/monitoring/testutils/testutils.go @@ -2,6 +2,7 @@ package testutils import ( "context" + crand "crypto/rand" "fmt" "math" "math/rand" @@ -59,7 +60,7 @@ func GenerateFeedConfig() config.SolanaFeedConfig { func Generate32ByteArr() [32]byte { buf := make([]byte, 32) - _, err := rand.Read(buf) + _, err := crand.Read(buf) if err != nil { panic("unable to Generate [32]byte from rand") } diff --git a/pkg/monitoring/types/txdetails.go b/pkg/monitoring/types/txdetails.go index d26ddd626..7788aca28 100644 --- a/pkg/monitoring/types/txdetails.go +++ b/pkg/monitoring/types/txdetails.go @@ -142,7 +142,7 @@ func ParseTx(tx *solanaGo.Transaction, programAddr solanaGo.PublicKey) (TxDetail } // find compute budget program instruction - if tx.Message.AccountKeys[instruction.ProgramIDIndex] == solanaGo.MustPublicKeyFromBase58(fees.COMPUTE_BUDGET_PROGRAM) { + if tx.Message.AccountKeys[instruction.ProgramIDIndex] == solanaGo.MustPublicKeyFromBase58(fees.ComputeBudgetProgram) { // parsing compute unit price var err error txDetails.ComputeUnitPrice, err = fees.ParseComputeUnitPrice(instruction.Data) diff --git a/pkg/solana/cache_test.go b/pkg/solana/cache_test.go index 59e6c7bb6..fb5605a40 100644 --- a/pkg/solana/cache_test.go +++ b/pkg/solana/cache_test.go @@ -158,13 +158,13 @@ func TestCache(t *testing.T) { // state query if bytes.Contains(body, []byte("11111111111111111111111111111111")) { // Drop error, client may cancel ctx. - w.Write(testStateResponse()) + w.Write(testStateResponse()) //nolint:errcheck return } // transmissions query // Drop error, client may cancel ctx. - w.Write(testTransmissionsResponse(t, body, 0)) + w.Write(testTransmissionsResponse(t, body, 0)) //nolint:errcheck })) lggr := logger.Test(t) diff --git a/pkg/solana/client/client_test.go b/pkg/solana/client/client_test.go index 0ac0ebcdb..d2e067cce 100644 --- a/pkg/solana/client/client_test.go +++ b/pkg/solana/client/client_test.go @@ -134,10 +134,10 @@ func TestClient_Writer_Integration(t *testing.T) { // create + sign transaction createTx := func(to solana.PublicKey) *solana.Transaction { - hash, err := c.LatestBlockhash() - assert.NoError(t, err) + hash, hashErr := c.LatestBlockhash() + assert.NoError(t, hashErr) - tx, err := solana.NewTransaction( + tx, txErr := solana.NewTransaction( []solana.Instruction{ system.NewTransferInstruction( 1, @@ -148,8 +148,8 @@ func TestClient_Writer_Integration(t *testing.T) { hash.Value.Blockhash, solana.TransactionPayer(pubKey), ) - assert.NoError(t, err) - _, err = tx.Sign( + assert.NoError(t, txErr) + _, signErr := tx.Sign( func(key solana.PublicKey) *solana.PrivateKey { if pubKey.Equals(key) { return &privKey @@ -157,7 +157,7 @@ func TestClient_Writer_Integration(t *testing.T) { return nil }, ) - assert.NoError(t, err) + assert.NoError(t, signErr) return tx } @@ -256,8 +256,8 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { for i := 0; i < n; i++ { go func(i int) { time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond) // randomly submit txs - sig, err := c.SendTx(ctx, tx) - assert.NoError(t, err) + sig, sendErr := c.SendTx(ctx, tx) + assert.NoError(t, sendErr) sigs[i] = sig wg.Done() }(i) @@ -271,8 +271,8 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { // try waiting for tx to execute - reduce flakiness require.Eventually(t, func() bool { - res, err := c.SignatureStatuses(ctx, []solana.Signature{sigs[0]}) - require.NoError(t, err) + res, statusErr := c.SignatureStatuses(ctx, []solana.Signature{sigs[0]}) + require.NoError(t, statusErr) require.Equal(t, 1, len(res)) if res[0] == nil { return false diff --git a/pkg/solana/config.go b/pkg/solana/config.go index 82c463b64..16e48b55e 100644 --- a/pkg/solana/config.go +++ b/pkg/solana/config.go @@ -17,9 +17,6 @@ import ( soldb "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) -// Deprecated: use TOMLConfigs -type SolanaConfigs = TOMLConfigs - type TOMLConfigs []*TOMLConfig func (cs TOMLConfigs) ValidateConfig() (err error) { @@ -88,6 +85,7 @@ func nodeStatus(n *solcfg.Node, id string) (relaytypes.NodeStatus, error) { return s, nil } +// revive:disable-next-line will be handled in https://github.com/smartcontractkit/chainlink-solana/pull/709 type SolanaNodes []*solcfg.Node func (ns *SolanaNodes) SetFrom(fs *SolanaNodes) { @@ -121,9 +119,6 @@ func legacySolNode(n *solcfg.Node, id string) soldb.Node { } } -// Deprecated: use TOMLConfig -type SolanaConfig = TOMLConfig - type TOMLConfig struct { ChainID *string // Do not access directly, use [IsEnabled] diff --git a/pkg/solana/fees/computebudget.go b/pkg/solana/fees/computebudget.go index ba980f0a2..fec4a4442 100644 --- a/pkg/solana/fees/computebudget.go +++ b/pkg/solana/fees/computebudget.go @@ -11,27 +11,27 @@ import ( // https://github.com/solana-labs/solana/blob/60858d043ca612334de300805d93ea3014e8ab37/sdk/src/compute_budget.rs#L25 const ( // deprecated: will not support for building instruction - Instruction_RequestUnitsDeprecated uint8 = iota + InstructionRequestUnitsDeprecated uint8 = iota // Request a specific transaction-wide program heap region size in bytes. // The value requested must be a multiple of 1024. This new heap region // size applies to each program executed in the transaction, including all // calls to CPIs. // note: uses ag_binary.Varuint32 - Instruction_RequestHeapFrame + InstructionRequestHeapFrame // Set a specific compute unit limit that the transaction is allowed to consume. // note: uses ag_binary.Varuint32 - Instruction_SetComputeUnitLimit + InstructionSetComputeUnitLimit // Set a compute unit price in "micro-lamports" to pay a higher transaction // fee for higher transaction prioritization. // note: uses ag_binary.Uint64 - Instruction_SetComputeUnitPrice + InstructionSetComputeUnitPrice ) const ( - COMPUTE_BUDGET_PROGRAM = "ComputeBudget111111111111111111111111111111" + ComputeBudgetProgram = "ComputeBudget111111111111111111111111111111" ) // https://docs.solana.com/developing/programming-model/runtime @@ -39,7 +39,7 @@ type ComputeUnitPrice uint64 // returns the compute budget program func (val ComputeUnitPrice) ProgramID() solana.PublicKey { - return solana.MustPublicKeyFromBase58(COMPUTE_BUDGET_PROGRAM) + return solana.MustPublicKeyFromBase58(ComputeBudgetProgram) } // No accounts needed @@ -52,7 +52,7 @@ func (val ComputeUnitPrice) Data() ([]byte, error) { buf := new(bytes.Buffer) // encode method identifier - if err := buf.WriteByte(Instruction_SetComputeUnitPrice); err != nil { + if err := buf.WriteByte(InstructionSetComputeUnitPrice); err != nil { return []byte{}, err } @@ -69,7 +69,7 @@ func ParseComputeUnitPrice(data []byte) (ComputeUnitPrice, error) { return 0, fmt.Errorf("invalid length: %d", len(data)) } - if data[0] != Instruction_SetComputeUnitPrice { + if data[0] != InstructionSetComputeUnitPrice { return 0, fmt.Errorf("not SetComputeUnitPrice identifier: %d", data[0]) } @@ -117,7 +117,7 @@ func SetComputeUnitPrice(tx *solana.Transaction, price ComputeUnitPrice) error { for i := range tx.Message.Instructions { if tx.Message.Instructions[i].ProgramIDIndex == programIdx && len(tx.Message.Instructions[i].Data) > 0 && - tx.Message.Instructions[i].Data[0] == Instruction_SetComputeUnitPrice { + tx.Message.Instructions[i].Data[0] == InstructionSetComputeUnitPrice { found = true instructionIdx = i break diff --git a/pkg/solana/fees/computebudget_test.go b/pkg/solana/fees/computebudget_test.go index 64ce7fdce..c80550297 100644 --- a/pkg/solana/fees/computebudget_test.go +++ b/pkg/solana/fees/computebudget_test.go @@ -32,7 +32,7 @@ func TestSetComputeUnitPrice(t *testing.T) { currentCount := len(tx.Message.Instructions) assert.Greater(t, currentCount, instructionCount) assert.Equal(t, 2, currentCount) - assert.Equal(t, COMPUTE_BUDGET_PROGRAM, tx.Message.AccountKeys[tx.Message.Instructions[0].ProgramIDIndex].String()) + assert.Equal(t, ComputeBudgetProgram, tx.Message.AccountKeys[tx.Message.Instructions[0].ProgramIDIndex].String()) data, err := ComputeUnitPrice(1).Data() assert.NoError(t, err) assert.Equal(t, data, []byte(tx.Message.Instructions[0].Data)) @@ -58,7 +58,7 @@ func TestSetComputeUnitPrice(t *testing.T) { // accounts should not have changed assert.Equal(t, accountCount, len(tx.Message.AccountKeys)) assert.Equal(t, 2, len(tx.Message.Instructions)) - assert.Equal(t, COMPUTE_BUDGET_PROGRAM, tx.Message.AccountKeys[tx.Message.Instructions[0].ProgramIDIndex].String()) + assert.Equal(t, ComputeBudgetProgram, tx.Message.AccountKeys[tx.Message.Instructions[0].ProgramIDIndex].String()) data, err := ComputeUnitPrice(1).Data() assert.NoError(t, err) assert.Equal(t, data, []byte(tx.Message.Instructions[0].Data)) @@ -115,7 +115,7 @@ func TestParseComputeUnitPrice(t *testing.T) { assert.ErrorContains(t, err, "invalid length") invalidData := data - invalidData[0] = Instruction_RequestHeapFrame + invalidData[0] = InstructionRequestHeapFrame _, err = ParseComputeUnitPrice(invalidData) assert.ErrorContains(t, err, "not SetComputeUnitPrice identifier") } diff --git a/pkg/solana/relay.go b/pkg/solana/relay.go index 8b5df44ad..68652fcd2 100644 --- a/pkg/solana/relay.go +++ b/pkg/solana/relay.go @@ -26,7 +26,7 @@ type TxManager interface { Enqueue(accountID string, msg *solana.Transaction) error } -var _ relaytypes.Relayer = &Relayer{} +var _ relaytypes.Relayer = &Relayer{} //nolint:staticcheck type Relayer struct { lggr logger.Logger diff --git a/shell.nix b/shell.nix index 83369d06f..dd6049a1d 100644 --- a/shell.nix +++ b/shell.nix @@ -3,7 +3,7 @@ pkgs.mkShell { nativeBuildInputs = with pkgs; [ (rust-bin.stable.latest.default.override { extensions = ["rust-src"]; }) - lld_10 + # lld_10 llvm_11 stdenv.cc.cc.lib pkg-config @@ -16,7 +16,7 @@ pkgs.mkShell { # Golang # Keep this golang version in sync with the version in .tool-versions please - go_1_20 + go_1_21 gopls delve golangci-lint