From 45db170c1ccc5ee533d2dd0ec4c3b4dad4efaba4 Mon Sep 17 00:00:00 2001 From: Aaron Lu <50029043+aalu1418@users.noreply.github.com> Date: Thu, 23 May 2024 11:48:13 -0600 Subject: [PATCH] cleanup: remove db config (#709) * remove db config * gomodtidy * prevent overflow on MaxRetries * move config.go -> config/toml.go * bump + fix e2e tests * use multierr.append for proper delineation * bump core commit * SolanaNodes -> Nodes * use errors.Join * pin core integration tests * flatten validation errors * nobuild optimization for running gauntlet within e2e tests * parallelize e2e tests * reduce round count * add ticket to revisit errors.Join issue --- gauntlet/package.json | 1 + go.mod | 1 - go.sum | 2 - integration-tests/common/common.go | 5 +- integration-tests/gauntlet/gauntlet_solana.go | 59 +++--- integration-tests/go.mod | 6 +- integration-tests/go.sum | 8 +- integration-tests/smoke/ocr2_test.go | 16 +- integration-tests/testconfig/default.toml | 2 +- pkg/solana/cache_test.go | 7 +- pkg/solana/chain.go | 35 ++-- pkg/solana/chain_test.go | 28 ++- pkg/solana/client/client_test.go | 9 +- pkg/solana/client/test_helpers_test.go | 3 +- pkg/solana/cmd/chainlink-solana/main.go | 3 +- pkg/solana/config/config.go | 172 +----------------- pkg/solana/{config.go => config/toml.go} | 84 +++++---- pkg/solana/db/db.go | 54 ------ pkg/solana/txm/txm_internal_test.go | 5 +- pkg/solana/txm/txm_test.go | 8 +- 20 files changed, 162 insertions(+), 346 deletions(-) rename pkg/solana/{config.go => config/toml.go} (72%) delete mode 100644 pkg/solana/db/db.go diff --git a/gauntlet/package.json b/gauntlet/package.json index c71817d41..84485cf22 100644 --- a/gauntlet/package.json +++ b/gauntlet/package.json @@ -14,6 +14,7 @@ "bin": "packages/gauntlet-solana-contracts/dist/cli.js", "scripts": { "gauntlet": "yarn build && node ./packages/gauntlet-solana-contracts/dist/cli.js", + "gauntlet-nobuild": "node ./packages/gauntlet-solana-contracts/dist/cli.js", "gauntlet-serum-multisig": "yarn build && node ./packages/gauntlet-serum-multisig/dist/index.js", "lint": "tsc -b ./tsconfig.json", "eslint": "eslint -f json -o eslint-report.json ./packages || true", diff --git a/go.mod b/go.mod index ee369de8e..c9bbf8583 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.6.0 golang.org/x/text v0.14.0 - gopkg.in/guregu/null.v4 v4.0.0 ) require ( diff --git a/go.sum b/go.sum index a977cafcf..406196eb3 100644 --- a/go.sum +++ b/go.sum @@ -923,8 +923,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= -gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/integration-tests/common/common.go b/integration-tests/common/common.go index aad73596a..f9528fb34 100644 --- a/integration-tests/common/common.go +++ b/integration-tests/common/common.go @@ -45,7 +45,6 @@ import ( test_env_sol "github.com/smartcontractkit/chainlink-solana/integration-tests/docker/testenv" "github.com/smartcontractkit/chainlink-solana/integration-tests/solclient" tc "github.com/smartcontractkit/chainlink-solana/integration-tests/testconfig" - cl_solana "github.com/smartcontractkit/chainlink-solana/pkg/solana" solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" ) @@ -485,7 +484,7 @@ func BuildNodeContractPairID(node *client.ChainlinkClient, ocr2Addr string) (str } func (c *Common) DefaultNodeConfig() *cl.Config { - solConfig := cl_solana.TOMLConfig{ + solConfig := solcfg.TOMLConfig{ Enabled: ptr.Ptr(true), ChainID: ptr.Ptr(c.ChainDetails.ChainID), Nodes: []*solcfg.Node{ @@ -496,7 +495,7 @@ func (c *Common) DefaultNodeConfig() *cl.Config { }, } baseConfig := node.NewBaseConfig() - baseConfig.Solana = cl_solana.TOMLConfigs{ + baseConfig.Solana = solcfg.TOMLConfigs{ &solConfig, } baseConfig.OCR2.Enabled = ptr.Ptr(true) diff --git a/integration-tests/gauntlet/gauntlet_solana.go b/integration-tests/gauntlet/gauntlet_solana.go index c4f8bcb59..ef3884fe2 100644 --- a/integration-tests/gauntlet/gauntlet_solana.go +++ b/integration-tests/gauntlet/gauntlet_solana.go @@ -65,7 +65,6 @@ type Transmission struct { // NewSolanaGauntlet Creates a default gauntlet config func NewSolanaGauntlet(workingDir string) (*SolanaGauntlet, error) { g, err := gauntlet.NewGauntlet() - g.SetWorkingDir(workingDir) if err != nil { return nil, err } @@ -117,16 +116,35 @@ func (sg *SolanaGauntlet) SetupNetwork(args map[string]string) error { func (sg *SolanaGauntlet) InstallDependencies() error { sg.G.Command = "yarn" - _, err := sg.G.ExecCommand([]string{"install"}, *sg.options) + _, err := sg.G.ExecCommand([]string{"--cwd", sg.Dir, "install"}, *sg.options) if err != nil { return err } - sg.G.Command = "gauntlet" + _, err = sg.G.ExecCommand([]string{"--cwd", sg.Dir, "build"}, *sg.options) // initial build + if err != nil { + return err + } + sg.G.Command = "gauntlet-nobuild" // optimization to not rebuild packages each time return nil } +// exect is a custom wrapper to use custom set gauntlet command + error wrapping +func (sg *SolanaGauntlet) exec(args []string, options gauntlet.ExecCommandOptions) (string, error) { + updatedArgs := []string{"--cwd", sg.Dir, sg.G.Command, args[0], sg.G.Flag("network", sg.G.Network)} + if len(args) > 1 { + updatedArgs = append(updatedArgs, args[1:]...) + } + + out, err := sg.G.ExecCommand(updatedArgs, options) + // wrapping output into err if err present + if err != nil { + err = fmt.Errorf("%w\ngauntlet command: %s\nstdout: %s", err, updatedArgs, out) + } + return out, err +} + func (sg *SolanaGauntlet) InitializeAccessController() (string, error) { - _, err := sg.G.ExecCommand([]string{"access_controller:initialize"}, *sg.options) + _, err := sg.exec([]string{"access_controller:initialize"}, *sg.options) if err != nil { return "", err } @@ -138,7 +156,7 @@ func (sg *SolanaGauntlet) InitializeAccessController() (string, error) { } func (sg *SolanaGauntlet) DeployLinkToken() error { - _, err := sg.G.ExecCommand([]string{"token:deploy"}, *sg.options) + _, err := sg.exec([]string{"token:deploy"}, *sg.options) if err != nil { return err } @@ -153,7 +171,7 @@ func (sg *SolanaGauntlet) DeployLinkToken() error { } func (sg *SolanaGauntlet) InitializeStore(billingController string) (string, error) { - _, err := sg.G.ExecCommand([]string{"store:initialize", fmt.Sprintf("--accessController=%s", billingController)}, *sg.options) + _, err := sg.exec([]string{"store:initialize", fmt.Sprintf("--accessController=%s", billingController)}, *sg.options) if err != nil { return "", err } @@ -169,7 +187,7 @@ func (sg *SolanaGauntlet) StoreCreateFeed(length int, feedConfig *ocr2_config.St if err != nil { return "", err } - _, err = sg.G.ExecCommand([]string{"store:create_feed", fmt.Sprintf("--length=%d", length), fmt.Sprintf("--input=%v", string(config))}, *sg.options) + _, err = sg.exec([]string{"store:create_feed", fmt.Sprintf("--length=%d", length), fmt.Sprintf("--input=%v", string(config))}, *sg.options) if err != nil { return "", err } @@ -182,7 +200,7 @@ func (sg *SolanaGauntlet) StoreCreateFeed(length int, feedConfig *ocr2_config.St } func (sg *SolanaGauntlet) StoreSetValidatorConfig(feedAddress string, threshold int) (string, error) { - _, err := sg.G.ExecCommand([]string{"store:set_validator_config", fmt.Sprintf("--feed=%s", feedAddress), fmt.Sprintf("--threshold=%d", threshold)}, *sg.options) + _, err := sg.exec([]string{"store:set_validator_config", fmt.Sprintf("--feed=%s", feedAddress), fmt.Sprintf("--threshold=%d", threshold)}, *sg.options) if err != nil { return "", err } @@ -198,7 +216,7 @@ func (sg *SolanaGauntlet) InitializeOCR2(requesterAccessController string, billi if err != nil { return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:initialize", fmt.Sprintf("--requesterAccessController=%s", requesterAccessController), fmt.Sprintf("--billingAccessController=%s", billingAccessController), @@ -219,7 +237,7 @@ func (sg *SolanaGauntlet) StoreSetWriter(storeConfig *ocr2_config.StoreWriterCon if err != nil { return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "store:set_writer", fmt.Sprintf("--input=%v", string(config)), ocrAddress, @@ -243,7 +261,7 @@ func (sg *SolanaGauntlet) OCR2SetBilling(ocr2BillingConfig *ocr2_config.OCR2Bill if err != nil { return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:set_billing", fmt.Sprintf("--input=%v", string(config)), ocrAddress, @@ -263,7 +281,7 @@ func (sg *SolanaGauntlet) OCR2SetBilling(ocr2BillingConfig *ocr2_config.OCR2Bill } func (sg *SolanaGauntlet) OCR2CreateProposal(version int) (string, error) { - _, err := sg.G.ExecCommand([]string{ + _, err := sg.exec([]string{ "ocr2:create_proposal", fmt.Sprintf("--version=%d", version), }, @@ -286,7 +304,7 @@ func (sg *SolanaGauntlet) ProposeOnChainConfig(proposalID string, onChainConfig if err != nil { return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:propose_config", fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), @@ -312,7 +330,7 @@ func (sg *SolanaGauntlet) ProposeOffChainConfig(proposalID string, offChainConfi return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:propose_offchain_config", fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), @@ -338,7 +356,7 @@ func (sg *SolanaGauntlet) ProposePayees(proposalID string, payeesConfig ocr2_con return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:propose_payees", fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--input=%v", string(config)), @@ -359,7 +377,7 @@ func (sg *SolanaGauntlet) ProposePayees(proposalID string, payeesConfig ocr2_con } func (sg *SolanaGauntlet) FinalizeProposal(proposalID string) (string, error) { - _, err := sg.G.ExecCommand([]string{ + _, err := sg.exec([]string{ "ocr2:finalize_proposal", fmt.Sprintf("--proposalId=%s", proposalID), }, @@ -383,7 +401,7 @@ func (sg *SolanaGauntlet) AcceptProposal(proposalID string, secret string, propo return "", err } - _, err = sg.G.ExecCommand([]string{ + _, err = sg.exec([]string{ "ocr2:accept_proposal", fmt.Sprintf("--proposalId=%s", proposalID), fmt.Sprintf("--secret=%s", secret), @@ -406,7 +424,7 @@ func (sg *SolanaGauntlet) AcceptProposal(proposalID string, secret string, propo // FetchTransmissions returns the last 10 transmissions func (sg *SolanaGauntlet) FetchTransmissions(ocrState string) ([]Transmission, error) { - _, err := sg.G.ExecCommand([]string{ + _, err := sg.exec([]string{ "ocr2:inspect:responses", ocrState, }, @@ -426,11 +444,6 @@ func (sg *SolanaGauntlet) FetchTransmissions(ocrState string) ([]Transmission, e func (sg *SolanaGauntlet) DeployOCR2() (string, error) { var err error - err = sg.InstallDependencies() - if err != nil { - return "", err - } - sg.AccessControllerAddress, err = sg.InitializeAccessController() if err != nil { return "", err diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 13d79e8bb..44e450646 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -14,11 +14,11 @@ require ( github.com/lib/pq v1.10.9 github.com/pelletier/go-toml/v2 v2.1.1 github.com/rs/zerolog v1.30.0 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240516150131-e1be553a9d10 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240510181707-46b1311a5a83 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240517134904-f4446b816a28 + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240521200803-6c605f618787 github.com/smartcontractkit/chainlink-testing-framework v1.28.15 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240515225456-aeb9f4d50d65 - github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240515225456-aeb9f4d50d65 + github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240521201249-c00f33248fe4 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c github.com/smartcontractkit/seth v1.0.9 github.com/stretchr/testify v1.9.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e959f07bf..dba5d06f8 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1406,8 +1406,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240516150131-e1be553a9d10 h1:IwJKWZHPBJbbh4oI3BGX8VNT3c/ChNiPZ/XI4iq6c0E= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240516150131-e1be553a9d10/go.mod h1:sj0pjL+METqeYL9ibp0T8SXquymlaQsofa6bdfLgXX8= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240517134904-f4446b816a28 h1:Pr8/CdiTNnzRwpYc2z7NpHYbw3Dpl1eqiqt9/J/Bcqc= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240517134904-f4446b816a28/go.mod h1:s+68EchlrXqHKRW3JJgZLEARvzMSKRI5+cE5Zx7pVJA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 h1:Sec/GpBpUVaTEax1kSHlTvkzF/+d3w5roAQXaj5+SLA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69/go.mod h1:ZQKf+0OLzCLYIisH/OdOIQuFRI6bDuw+jPBTATyHfFM= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= @@ -1424,8 +1424,8 @@ github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1: github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240515225456-aeb9f4d50d65 h1:8AoBDPHOLgZA1JodqysYK/JxcVbjwNhyGfmwzQuep4s= github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240515225456-aeb9f4d50d65/go.mod h1:DOeyxJuvSV8No26UHAtmvZTycuGe0S4w/XMMj1EGMV8= -github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240515225456-aeb9f4d50d65 h1:ba2ZooA598i9P2qakTggT81f5TIFI9efPVsGy7MjY9Y= -github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240515225456-aeb9f4d50d65/go.mod h1:ICLCfUotU6Zk+S2kry3XE6i3lyhk30sr2rz89Y5QkGI= +github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240521201249-c00f33248fe4 h1:KrQxqehwHCpbJJtltv2iWlVR+cxNzEoBN8EFtbwWtPg= +github.com/smartcontractkit/chainlink/v2 v2.10.0-beta0.0.20240521201249-c00f33248fe4/go.mod h1:10XUZ0WuFDdW+RYD0PdTpHlnaxkh/sqeAtjrAV6vUvQ= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index f9c4f09d6..77ca5d0fa 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -3,6 +3,7 @@ package smoke import ( "fmt" "maps" + "os/exec" "testing" "time" @@ -37,7 +38,10 @@ func TestSolanaOCRV2Smoke(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { - state, err := common.NewOCRv2State(t, 1, "gauntlet-"+test.name, &config) + t.Parallel() + + name := "gauntlet-" + test.name + state, err := common.NewOCRv2State(t, 1, name, &config) require.NoError(t, err, "Could not setup the ocrv2 state") if len(test.env) > 0 { state.Common.TestEnvDetails.NodeOpts = append(state.Common.TestEnvDetails.NodeOpts, func(n *test_env.ClNode) { @@ -50,7 +54,13 @@ func TestSolanaOCRV2Smoke(t *testing.T) { state.DeployCluster(utils.ContractsDir) - sg, err := gauntlet.NewSolanaGauntlet(fmt.Sprintf("%s/gauntlet", utils.ProjectRoot)) + // copy gauntlet folder to run in parallel (gauntlet generates an output file that is read by the e2e tests - causes conflict if shared) + gauntletCopyPath := utils.ProjectRoot + "/" + name + if out, cpErr := exec.Command("cp", "-r", utils.ProjectRoot+"/gauntlet", gauntletCopyPath).Output(); cpErr != nil { // nolint:gosec + require.NoError(t, err, "output: "+string(out)) + } + + sg, err := gauntlet.NewSolanaGauntlet(gauntletCopyPath) require.NoError(t, err) state.Gauntlet = sg @@ -73,6 +83,8 @@ func TestSolanaOCRV2Smoke(t *testing.T) { err = sg.SetupNetwork(gauntletConfig) require.NoError(t, err, "Error setting gauntlet network") + err = sg.InstallDependencies() + require.NoError(t, err, "Error installing gauntlet dependencies") if *config.Common.Network == "devnet" { state.Common.ChainDetails.ProgramAddresses.OCR2 = *config.SolanaConfig.OCR2ProgramID diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 525ef3de9..c6744a9c2 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -44,5 +44,5 @@ node_count = 6 test_duration = "50m" [OCR2.Smoke] -number_of_rounds = 5 +number_of_rounds = 2 diff --git a/pkg/solana/cache_test.go b/pkg/solana/cache_test.go index fb5605a40..3351ecf68 100644 --- a/pkg/solana/cache_test.go +++ b/pkg/solana/cache_test.go @@ -23,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink-solana/pkg/solana/client" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) var mockTransmission = []byte{ @@ -94,7 +93,7 @@ func testTransmissionsResponse(t *testing.T, body []byte, sub uint64) []byte { func testSetupReader(t *testing.T, endpoint string) client.Reader { lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() client, err := client.NewClient(endpoint, cfg, 1*time.Second, lggr) require.NoError(t, err) return client @@ -170,7 +169,7 @@ func TestCache(t *testing.T) { lggr := logger.Test(t) stateCache := StateCache{ StateID: solana.MustPublicKeyFromBase58("11111111111111111111111111111111"), - cfg: config.NewConfig(db.ChainCfg{}, lggr), + cfg: config.NewDefault(), reader: testSetupReader(t, mockServer.URL), lggr: lggr, } @@ -182,7 +181,7 @@ func TestCache(t *testing.T) { transmissionsCache := TransmissionsCache{ TransmissionsID: solana.MustPublicKeyFromBase58("11111111111111111111111111111112"), - cfg: config.NewConfig(db.ChainCfg{}, lggr), + cfg: config.NewDefault(), reader: testSetupReader(t, mockServer.URL), lggr: lggr, } diff --git a/pkg/solana/chain.go b/pkg/solana/chain.go index bc69a453e..e62aa4531 100644 --- a/pkg/solana/chain.go +++ b/pkg/solana/chain.go @@ -24,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink-solana/pkg/solana/client" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" "github.com/smartcontractkit/chainlink-solana/pkg/solana/monitor" "github.com/smartcontractkit/chainlink-solana/pkg/solana/txm" ) @@ -65,7 +64,7 @@ func (o *ChainOpts) GetLogger() logger.Logger { return o.Logger } -func NewChain(cfg *TOMLConfig, opts ChainOpts) (Chain, error) { +func NewChain(cfg *config.TOMLConfig, opts ChainOpts) (Chain, error) { if !cfg.IsEnabled() { return nil, fmt.Errorf("cannot create new chain with ID %s: chain is disabled", *cfg.ChainID) } @@ -81,7 +80,7 @@ var _ Chain = (*chain)(nil) type chain struct { services.StateMachine id string - cfg *TOMLConfig + cfg *config.TOMLConfig txm *txm.Txm balanceMonitor services.Service lggr logger.Logger @@ -214,7 +213,7 @@ func (v *verifiedCachedClient) GetAccountInfoWithOpts(ctx context.Context, addr return v.ReaderWriter.GetAccountInfoWithOpts(ctx, addr, opts) } -func newChain(id string, cfg *TOMLConfig, ks loop.Keystore, lggr logger.Logger) (*chain, error) { +func newChain(id string, cfg *config.TOMLConfig, ks loop.Keystore, lggr logger.Logger) (*chain, error) { lggr = logger.With(lggr, "chainID", id, "chain", "solana") var ch = chain{ id: id, @@ -262,7 +261,7 @@ func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, } nodes := c.cfg.Nodes[start:end] for _, node := range nodes { - stat, err := nodeStatus(node, c.ChainID()) + stat, err := config.NodeStatus(node, c.ChainID()) if err != nil { return stats, total, err } @@ -297,12 +296,9 @@ func (c *chain) ChainID() string { // getClient returns a client, randomly selecting one from available and valid nodes func (c *chain) getClient() (client.ReaderWriter, error) { - var node db.Node + var node *config.Node var client client.ReaderWriter - nodes, err := c.cfg.ListNodes() - if err != nil { - return nil, fmt.Errorf("failed to get nodes: %w", err) - } + nodes := c.cfg.ListNodes() if len(nodes) == 0 { return nil, errors.New("no nodes available") } @@ -311,10 +307,11 @@ func (c *chain) getClient() (client.ReaderWriter, error) { for _, i := range index { node = nodes[i] // create client and check + var err error client, err = c.verifiedClient(node) // if error, try another node if err != nil { - c.lggr.Warnw("failed to create node", "name", node.Name, "solana-url", node.SolanaURL, "err", err.Error()) + c.lggr.Warnw("failed to create node", "name", node.Name, "solana-url", node.URL, "err", err.Error()) continue } // if all checks passed, mark found and break loop @@ -324,15 +321,23 @@ func (c *chain) getClient() (client.ReaderWriter, error) { if client == nil { return nil, errors.New("no node valid nodes available") } - c.lggr.Debugw("Created client", "name", node.Name, "solana-url", node.SolanaURL) + c.lggr.Debugw("Created client", "name", node.Name, "solana-url", node.URL) return client, nil } // verifiedClient returns a client for node or an error if fails to create the client. // The client will still be returned if the nodes are not valid, or the chain id doesn't match. // Further client calls will try and verify the client, and fail if the client is still not valid. -func (c *chain) verifiedClient(node db.Node) (client.ReaderWriter, error) { - url := node.SolanaURL +func (c *chain) verifiedClient(node *config.Node) (client.ReaderWriter, error) { + if node == nil { + return nil, fmt.Errorf("nil node") + } + + if node.Name == nil || node.URL == nil { + return nil, fmt.Errorf("node config contains nil: %+v", node) + } + + url := node.URL.String() var err error // check if cached client exists @@ -346,7 +351,7 @@ func (c *chain) verifiedClient(node db.Node) (client.ReaderWriter, error) { expectedChainID: c.id, } // create client - cl.ReaderWriter, err = client.NewClient(url, c.cfg, DefaultRequestTimeout, logger.Named(c.lggr, "Client."+node.Name)) + cl.ReaderWriter, err = client.NewClient(url, c.cfg, DefaultRequestTimeout, logger.Named(c.lggr, "Client."+*node.Name)) if err != nil { return nil, fmt.Errorf("failed to create client: %w", err) } diff --git a/pkg/solana/chain_test.go b/pkg/solana/chain_test.go index f01406e81..aa52b8b4d 100644 --- a/pkg/solana/chain_test.go +++ b/pkg/solana/chain_test.go @@ -10,6 +10,7 @@ import ( "sync" "testing" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -18,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink-solana/pkg/solana/client" solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) const TestSolanaGenesisHashTemplate = `{"jsonrpc":"2.0","result":"%s","id":1}` @@ -46,7 +46,7 @@ func TestSolanaChain_GetClient(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &TOMLConfig{ + cfg := &solcfg.TOMLConfig{ ChainID: ptr("devnet"), Chain: ch, } @@ -143,7 +143,7 @@ func TestSolanaChain_VerifiedClient(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &TOMLConfig{ + cfg := &solcfg.TOMLConfig{ ChainID: ptr("devnet"), Chain: ch, } @@ -152,28 +152,32 @@ func TestSolanaChain_VerifiedClient(t *testing.T) { lggr: logger.Test(t), clientCache: map[string]*verifiedCachedClient{}, } - node := db.Node{SolanaURL: mockServer.URL} + nName := t.Name() + "-" + uuid.NewString() + node := &solcfg.Node{ + Name: &nName, + URL: config.MustParseURL(mockServer.URL), + } // happy path testChain.id = "devnet" _, err := testChain.verifiedClient(node) - assert.NoError(t, err) + require.NoError(t, err) // retrieve cached client and retrieve slot height c, err := testChain.verifiedClient(node) - assert.NoError(t, err) + require.NoError(t, err) slot, err := c.SlotHeight() assert.NoError(t, err) assert.Equal(t, uint64(1234), slot) - node.SolanaURL = mockServer.URL + "/mismatch" + node.URL = config.MustParseURL(mockServer.URL + "/mismatch") testChain.id = "incorrect" c, err = testChain.verifiedClient(node) assert.NoError(t, err) _, err = c.ChainID() // expect error from id mismatch (even if using a cached client) when performing RPC calls assert.Error(t, err) - assert.Equal(t, fmt.Sprintf("client returned mismatched chain id (expected: %s, got: %s): %s", "incorrect", "devnet", node.SolanaURL), err.Error()) + assert.Equal(t, fmt.Sprintf("client returned mismatched chain id (expected: %s, got: %s): %s", "incorrect", "devnet", node.URL), err.Error()) } func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) { @@ -186,7 +190,7 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &TOMLConfig{ + cfg := &solcfg.TOMLConfig{ ChainID: ptr("devnet"), Enabled: ptr(true), Chain: ch, @@ -197,7 +201,11 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) { lggr: logger.Test(t), clientCache: map[string]*verifiedCachedClient{}, } - node := db.Node{SolanaURL: mockServer.URL} + nName := t.Name() + "-" + uuid.NewString() + node := &solcfg.Node{ + Name: &nName, + URL: config.MustParseURL(mockServer.URL), + } var wg sync.WaitGroup wg.Add(2) diff --git a/pkg/solana/client/client_test.go b/pkg/solana/client/client_test.go index d2e067cce..46b950d47 100644 --- a/pkg/solana/client/client_test.go +++ b/pkg/solana/client/client_test.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) func TestClient_Reader_Integration(t *testing.T) { @@ -31,7 +30,7 @@ func TestClient_Reader_Integration(t *testing.T) { requestTimeout := 5 * time.Second lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() c, err := NewClient(url, cfg, requestTimeout, lggr) require.NoError(t, err) @@ -105,7 +104,7 @@ func TestClient_Reader_ChainID(t *testing.T) { requestTimeout := 5 * time.Second lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() c, err := NewClient(mockServer.URL, cfg, requestTimeout, lggr) require.NoError(t, err) @@ -126,7 +125,7 @@ func TestClient_Writer_Integration(t *testing.T) { requestTimeout := 5 * time.Second lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() ctx := context.Background() c, err := NewClient(url, cfg, requestTimeout, lggr) @@ -212,7 +211,7 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { // create client requestTimeout := 5 * time.Second lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() c, err := NewClient(url, cfg, requestTimeout, lggr) require.NoError(t, err) diff --git a/pkg/solana/client/test_helpers_test.go b/pkg/solana/client/test_helpers_test.go index dd9e682a8..1f530da2b 100644 --- a/pkg/solana/client/test_helpers_test.go +++ b/pkg/solana/client/test_helpers_test.go @@ -11,7 +11,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) func TestSetupLocalSolNode_SimultaneousNetworks(t *testing.T) { @@ -25,7 +24,7 @@ func TestSetupLocalSolNode_SimultaneousNetworks(t *testing.T) { // client configs requestTimeout := 5 * time.Second lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() // check & fund address checkFunded := func(t *testing.T, url string) { diff --git a/pkg/solana/cmd/chainlink-solana/main.go b/pkg/solana/cmd/chainlink-solana/main.go index 22f614a18..e8a211af2 100644 --- a/pkg/solana/cmd/chainlink-solana/main.go +++ b/pkg/solana/cmd/chainlink-solana/main.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-solana/pkg/solana" + solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" ) const ( @@ -53,7 +54,7 @@ func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore d := toml.NewDecoder(strings.NewReader(config)) d.DisallowUnknownFields() var cfg struct { - Solana solana.TOMLConfig + Solana solcfg.TOMLConfig } if err := d.Decode(&cfg); err != nil { diff --git a/pkg/solana/config/config.go b/pkg/solana/config/config.go index 15a96c62d..df5be635f 100644 --- a/pkg/solana/config/config.go +++ b/pkg/solana/config/config.go @@ -2,15 +2,11 @@ package config import ( "errors" - "strings" "time" "github.com/gagliardetto/solana-go/rpc" "github.com/smartcontractkit/chainlink-common/pkg/config" - - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/logger" ) // Global solana defaults. @@ -24,7 +20,7 @@ var defaultConfigSet = configSet{ TxConfirmTimeout: 30 * time.Second, // duration before discarding tx as unconfirmed SkipPreflight: true, // to enable or disable preflight checks Commitment: rpc.CommitmentConfirmed, - MaxRetries: new(uint), // max number of retries, when nil - rpc node will do a reasonable number of retries + MaxRetries: new(uint), // max number of retries (default = *new(uint) = 0). when config.MaxRetries < 0, interpreted as MaxRetries = nil and rpc node will do a reasonable number of retries // fee estimator FeeEstimatorMode: "fixed", @@ -75,172 +71,6 @@ type configSet struct { FeeBumpPeriod time.Duration } -var _ Config = (*cfg)(nil) - -// Deprecated -type cfg struct { - defaults configSet - chain db.ChainCfg - lggr logger.Logger -} - -// NewConfig returns a Config with defaults overridden by dbcfg. -// Deprecated -func NewConfig(dbcfg db.ChainCfg, lggr logger.Logger) *cfg { - return &cfg{ - defaults: defaultConfigSet, - chain: dbcfg, - lggr: lggr, - } -} - -func (c *cfg) BalancePollPeriod() time.Duration { - ch := c.chain.BalancePollPeriod - if ch != nil { - return ch.Duration() - } - return c.defaults.BalancePollPeriod -} - -func (c *cfg) ConfirmPollPeriod() time.Duration { - ch := c.chain.ConfirmPollPeriod - if ch != nil { - return ch.Duration() - } - return c.defaults.ConfirmPollPeriod -} - -func (c *cfg) OCR2CachePollPeriod() time.Duration { - ch := c.chain.OCR2CachePollPeriod - if ch != nil { - return ch.Duration() - } - return c.defaults.OCR2CachePollPeriod -} - -func (c *cfg) OCR2CacheTTL() time.Duration { - ch := c.chain.OCR2CacheTTL - if ch != nil { - return ch.Duration() - } - return c.defaults.OCR2CacheTTL -} - -func (c *cfg) TxTimeout() time.Duration { - ch := c.chain.TxTimeout - if ch != nil { - return ch.Duration() - } - return c.defaults.TxTimeout -} - -func (c *cfg) TxRetryTimeout() time.Duration { - ch := c.chain.TxRetryTimeout - if ch != nil { - return ch.Duration() - } - return c.defaults.TxRetryTimeout -} - -func (c *cfg) TxConfirmTimeout() time.Duration { - ch := c.chain.TxConfirmTimeout - if ch != nil { - return ch.Duration() - } - return c.defaults.TxConfirmTimeout -} - -func (c *cfg) SkipPreflight() bool { - ch := c.chain.SkipPreflight - if ch.Valid { - return ch.Bool - } - return c.defaults.SkipPreflight -} - -func (c *cfg) Commitment() rpc.CommitmentType { - ch := c.chain.Commitment - if ch.Valid { - str := ch.String - var commitment rpc.CommitmentType - switch str { - case "processed": - commitment = rpc.CommitmentProcessed - case "confirmed": - commitment = rpc.CommitmentConfirmed - case "finalized": - commitment = rpc.CommitmentFinalized - default: - c.lggr.Warnf(`Invalid value provided for %s, "%s" - falling back to default "%s"`, "CommitmentType", str, c.defaults.Commitment) - commitment = rpc.CommitmentConfirmed - } - return commitment - } - return c.defaults.Commitment -} - -func (c *cfg) FeeEstimatorMode() string { - ch := c.chain.FeeEstimatorMode - if ch.Valid { - return strings.ToLower(ch.String) - } - return c.defaults.FeeEstimatorMode -} - -func (c *cfg) ComputeUnitPriceMax() uint64 { - ch := c.chain.ComputeUnitPriceMax - if ch.Valid { - if ch.Int64 >= 0 { - return uint64(ch.Int64) - } - c.lggr.Warnf("Negative value provided for ComputeUnitPriceMax, falling back to default: %d", c.defaults.ComputeUnitPriceMax) - } - return c.defaults.ComputeUnitPriceMax -} - -func (c *cfg) ComputeUnitPriceMin() uint64 { - ch := c.chain.ComputeUnitPriceMin - if ch.Valid { - if ch.Int64 >= 0 { - return uint64(ch.Int64) - } - c.lggr.Warnf("Negative value provided for ComputeUnitPriceMin, falling back to default: %d", c.defaults.ComputeUnitPriceMin) - } - return c.defaults.ComputeUnitPriceMin -} - -func (c *cfg) ComputeUnitPriceDefault() uint64 { - ch := c.chain.ComputeUnitPriceDefault - if ch.Valid { - if ch.Int64 >= 0 { - return uint64(ch.Int64) - } - c.lggr.Warnf("Negative value provided for ComputeUnitPriceDefault, falling back to default: %d", c.defaults.ComputeUnitPriceDefault) - } - return c.defaults.ComputeUnitPriceDefault -} - -func (c *cfg) MaxRetries() *uint { - ch := c.chain.MaxRetries - if ch.Valid { - if ch.Int64 < 0 { - c.lggr.Warnf(`Negative value provided for %s: %d, falling back to - let RPC node do a reasonable amount of tries`, "MaxRetries", ch.Int64) - return nil - } - val := uint(ch.Int64) - return &val - } - return c.defaults.MaxRetries -} - -func (c *cfg) FeeBumpPeriod() time.Duration { - ch := c.chain.FeeBumpPeriod - if ch != nil { - return ch.Duration() - } - return c.defaults.FeeBumpPeriod -} - type Chain struct { BalancePollPeriod *config.Duration ConfirmPollPeriod *config.Duration diff --git a/pkg/solana/config.go b/pkg/solana/config/toml.go similarity index 72% rename from pkg/solana/config.go rename to pkg/solana/config/toml.go index 16e48b55e..96302a45d 100644 --- a/pkg/solana/config.go +++ b/pkg/solana/config/toml.go @@ -1,4 +1,4 @@ -package solana +package config import ( "errors" @@ -12,9 +12,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types" - - solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - soldb "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) type TOMLConfigs []*TOMLConfig @@ -24,11 +21,13 @@ func (cs TOMLConfigs) ValidateConfig() (err error) { } func (cs TOMLConfigs) validateKeys() (err error) { + errA := []error{} // goal: remove and go back to only errors.Join (https://smartcontract-it.atlassian.net/browse/BCI-3330) + // Unique chain IDs chainIDs := config.UniqueStrings{} for i, c := range cs { if chainIDs.IsDupe(c.ChainID) { - err = errors.Join(err, config.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), *c.ChainID)) + errA = append(errA, config.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), *c.ChainID)) } } @@ -37,7 +36,7 @@ func (cs TOMLConfigs) validateKeys() (err error) { for i, c := range cs { for j, n := range c.Nodes { if names.IsDupe(n.Name) { - err = errors.Join(err, config.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name)) + errA = append(errA, config.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name)) } } } @@ -48,11 +47,11 @@ func (cs TOMLConfigs) validateKeys() (err error) { for j, n := range c.Nodes { u := (*url.URL)(n.URL) if urls.IsDupeFmt(u) { - err = errors.Join(err, config.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.URL", i, j), u.String())) + errA = append(errA, config.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.URL", i, j), u.String())) } } } - return + return errors.Join(errA...) } func (cs *TOMLConfigs) SetFrom(fs *TOMLConfigs) (err error) { @@ -73,7 +72,7 @@ func (cs *TOMLConfigs) SetFrom(fs *TOMLConfigs) (err error) { return } -func nodeStatus(n *solcfg.Node, id string) (relaytypes.NodeStatus, error) { +func NodeStatus(n *Node, id string) (relaytypes.NodeStatus, error) { var s relaytypes.NodeStatus s.ChainID = id s.Name = *n.Name @@ -85,14 +84,13 @@ 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 +type Nodes []*Node -func (ns *SolanaNodes) SetFrom(fs *SolanaNodes) { +func (ns *Nodes) SetFrom(fs *Nodes) { for _, f := range *fs { if f.Name == nil { *ns = append(*ns, f) - } else if i := slices.IndexFunc(*ns, func(n *solcfg.Node) bool { + } else if i := slices.IndexFunc(*ns, func(n *Node) bool { return n.Name != nil && *n.Name == *f.Name }); i == -1 { *ns = append(*ns, f) @@ -102,7 +100,7 @@ func (ns *SolanaNodes) SetFrom(fs *SolanaNodes) { } } -func setFromNode(n, f *solcfg.Node) { +func setFromNode(n, f *Node) { if f.Name != nil { n.Name = f.Name } @@ -111,20 +109,12 @@ func setFromNode(n, f *solcfg.Node) { } } -func legacySolNode(n *solcfg.Node, id string) soldb.Node { - return soldb.Node{ - Name: *n.Name, - SolanaChainID: id, - SolanaURL: (*url.URL)(n.URL).String(), - } -} - type TOMLConfig struct { ChainID *string // Do not access directly, use [IsEnabled] Enabled *bool - solcfg.Chain - Nodes SolanaNodes + Chain + Nodes Nodes } func (c *TOMLConfig) IsEnabled() bool { @@ -142,7 +132,7 @@ func (c *TOMLConfig) SetFrom(f *TOMLConfig) { c.Nodes.SetFrom(&f.Nodes) } -func setFromChain(c, f *solcfg.Chain) { +func setFromChain(c, f *Chain) { if f.BalancePollPeriod != nil { c.BalancePollPeriod = f.BalancePollPeriod } @@ -173,19 +163,36 @@ func setFromChain(c, f *solcfg.Chain) { if f.MaxRetries != nil { c.MaxRetries = f.MaxRetries } + if f.FeeEstimatorMode != nil { + c.FeeEstimatorMode = f.FeeEstimatorMode + } + if f.ComputeUnitPriceMax != nil { + c.ComputeUnitPriceMax = f.ComputeUnitPriceMax + } + if f.ComputeUnitPriceMin != nil { + c.ComputeUnitPriceMin = f.ComputeUnitPriceMin + } + if f.ComputeUnitPriceDefault != nil { + c.ComputeUnitPriceDefault = f.ComputeUnitPriceDefault + } + if f.FeeBumpPeriod != nil { + c.FeeBumpPeriod = f.FeeBumpPeriod + } } func (c *TOMLConfig) ValidateConfig() (err error) { + errA := []error{} + if c.ChainID == nil { - err = errors.Join(err, config.ErrMissing{Name: "ChainID", Msg: "required for all chains"}) + errA = append(errA, config.ErrMissing{Name: "ChainID", Msg: "required for all chains"}) } else if *c.ChainID == "" { - err = errors.Join(err, config.ErrEmpty{Name: "ChainID", Msg: "required for all chains"}) + errA = append(errA, config.ErrEmpty{Name: "ChainID", Msg: "required for all chains"}) } if len(c.Nodes) == 0 { - err = errors.Join(err, config.ErrMissing{Name: "Nodes", Msg: "must have at least one node"}) + errA = append(errA, config.ErrMissing{Name: "Nodes", Msg: "must have at least one node"}) } - return + return errors.Join(errA...) } func (c *TOMLConfig) TOMLString() (string, error) { @@ -196,7 +203,7 @@ func (c *TOMLConfig) TOMLString() (string, error) { return string(b), nil } -var _ solcfg.Config = &TOMLConfig{} +var _ Config = &TOMLConfig{} func (c *TOMLConfig) BalancePollPeriod() time.Duration { return c.Chain.BalancePollPeriod.Duration() @@ -238,6 +245,9 @@ func (c *TOMLConfig) MaxRetries() *uint { if c.Chain.MaxRetries == nil { return nil } + if *c.Chain.MaxRetries < 0 { + return nil // interpret negative numbers as nil (prevents unlikely case of overflow) + } mr := uint(*c.Chain.MaxRetries) return &mr } @@ -262,10 +272,12 @@ func (c *TOMLConfig) FeeBumpPeriod() time.Duration { return c.Chain.FeeBumpPeriod.Duration() } -func (c *TOMLConfig) ListNodes() ([]soldb.Node, error) { - var allNodes []soldb.Node - for _, n := range c.Nodes { - allNodes = append(allNodes, legacySolNode(n, *c.ChainID)) - } - return allNodes, nil +func (c *TOMLConfig) ListNodes() Nodes { + return c.Nodes +} + +func NewDefault() *TOMLConfig { + cfg := &TOMLConfig{} + cfg.SetDefaults() + return cfg } diff --git a/pkg/solana/db/db.go b/pkg/solana/db/db.go deleted file mode 100644 index 30c3e6a1a..000000000 --- a/pkg/solana/db/db.go +++ /dev/null @@ -1,54 +0,0 @@ -package db - -import ( - "database/sql/driver" - "encoding/json" - "errors" - "time" - - "gopkg.in/guregu/null.v4" - - "github.com/smartcontractkit/chainlink-common/pkg/config" -) - -type Node struct { - ID int32 - Name string - SolanaChainID string `json:"solanaChainId" db:"solana_chain_id"` - SolanaURL string `json:"solanaURL" db:"solana_url"` - CreatedAt time.Time - UpdatedAt time.Time -} - -// Deprecated -type ChainCfg struct { - BalancePollPeriod *config.Duration - ConfirmPollPeriod *config.Duration - OCR2CachePollPeriod *config.Duration - OCR2CacheTTL *config.Duration - TxTimeout *config.Duration - TxRetryTimeout *config.Duration - TxConfirmTimeout *config.Duration - SkipPreflight null.Bool // to enable or disable preflight checks - Commitment null.String - MaxRetries null.Int - - FeeEstimatorMode null.String - ComputeUnitPriceMax null.Int - ComputeUnitPriceMin null.Int - ComputeUnitPriceDefault null.Int - FeeBumpPeriod *config.Duration -} - -func (c *ChainCfg) Scan(value interface{}) error { - b, ok := value.([]byte) - if !ok { - return errors.New("type assertion to []byte failed") - } - - return json.Unmarshal(b, c) -} - -func (c *ChainCfg) Value() (driver.Value, error) { - return json.Marshal(c) -} diff --git a/pkg/solana/txm/txm_internal_test.go b/pkg/solana/txm/txm_internal_test.go index 8e303a712..3299e7da6 100644 --- a/pkg/solana/txm/txm_internal_test.go +++ b/pkg/solana/txm/txm_internal_test.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink-solana/pkg/solana/client" "github.com/smartcontractkit/chainlink-solana/pkg/solana/client/mocks" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" "github.com/smartcontractkit/chainlink-solana/pkg/solana/fees" keyMocks "github.com/smartcontractkit/chainlink-solana/pkg/solana/txm/mocks" @@ -94,7 +93,7 @@ func TestTxm(t *testing.T) { ctx := tests.Context(t) lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() mc := mocks.NewReaderWriter(t) // mock solana keystore @@ -577,7 +576,7 @@ func TestTxm(t *testing.T) { func TestTxm_Enqueue(t *testing.T) { // set up configs needed in txm lggr := logger.Test(t) - cfg := config.NewConfig(db.ChainCfg{}, lggr) + cfg := config.NewDefault() mc := mocks.NewReaderWriter(t) // mock solana keystore diff --git a/pkg/solana/txm/txm_test.go b/pkg/solana/txm/txm_test.go index 597f32043..85e84ba90 100644 --- a/pkg/solana/txm/txm_test.go +++ b/pkg/solana/txm/txm_test.go @@ -16,7 +16,6 @@ import ( solanaClient "github.com/smartcontractkit/chainlink-solana/pkg/solana/client" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" "github.com/smartcontractkit/chainlink-solana/pkg/solana/txm" keyMocks "github.com/smartcontractkit/chainlink-solana/pkg/solana/txm/mocks" @@ -59,11 +58,8 @@ func TestTxm_Integration(t *testing.T) { // set up txm lggr := logger.Test(t) - confirmDuration, err := relayconfig.NewDuration(500 * time.Millisecond) - require.NoError(t, err) - cfg := config.NewConfig(db.ChainCfg{ - ConfirmPollPeriod: &confirmDuration, - }, lggr) + cfg := config.NewDefault() + cfg.Chain.ConfirmPollPeriod = relayconfig.MustNewDuration(500 * time.Millisecond) client, err := solanaClient.NewClient(url, cfg, 2*time.Second, lggr) require.NoError(t, err) getClient := func() (solanaClient.ReaderWriter, error) {