From 526c18f39dc97e0c0ae87562e93631598bfc6786 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 10 Oct 2023 08:50:44 -0500 Subject: [PATCH] BCF-2685: move LOOPP command from core --- go.mod | 4 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- pkg/solana/chain.go | 6 +- pkg/solana/chain_test.go | 6 +- pkg/solana/cmd/chainlink-solana/main.go | 75 +++++++++++++++++++++++++ pkg/solana/config.go | 60 +++++++++++--------- 8 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 pkg/solana/cmd/chainlink-solana/main.go diff --git a/go.mod b/go.mod index c3c606019..af7262048 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,11 @@ require ( github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 github.com/gagliardetto/treeout v0.1.4 github.com/google/uuid v1.3.0 + github.com/hashicorp/go-plugin v1.5.2 github.com/pelletier/go-toml/v2 v2.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.15.0 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80 github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 github.com/stretchr/testify v1.8.4 go.uber.org/multierr v1.11.0 @@ -42,7 +43,6 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/hashicorp/go-hclog v0.14.1 // indirect - github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index 2f515cc32..023e1ead9 100644 --- a/go.sum +++ b/go.sum @@ -420,8 +420,8 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4 h1:/1M3ofWOKnMetdwZQkCdgs3YNRTYwsDPNriGJ+k9xPQ= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4/go.mod h1:uIwfoRl8ehNkNWKXffVgG11XAeRG607zAYxA32wxOPo= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80 h1:8PjgZZ8357SxbT826yTqXLU4e0tBVBB2yBmB+V928aM= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80/go.mod h1:uIwfoRl8ehNkNWKXffVgG11XAeRG607zAYxA32wxOPo= 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/go.mod b/integration-tests/go.mod index 6c136af7e..a6877a192 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -370,7 +370,7 @@ require ( github.com/slack-go/slack v0.12.2 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/ocr2keepers v0.7.27 // indirect github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 756cf93d9..7b406b4e2 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2314,8 +2314,8 @@ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc4 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= github.com/smartcontractkit/chainlink-env v0.38.2 h1:xS3p4Ev5j8KNWtQhzTMv47fWDIo82WkXoNYBAb9S+lY= github.com/smartcontractkit/chainlink-env v0.38.2/go.mod h1:7z4sw/hN8TxioQCLwFqQdhK3vaOV0a22Qe99z4bRUcg= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4 h1:/1M3ofWOKnMetdwZQkCdgs3YNRTYwsDPNriGJ+k9xPQ= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231004164700-02b76df27fb4/go.mod h1:uIwfoRl8ehNkNWKXffVgG11XAeRG607zAYxA32wxOPo= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80 h1:8PjgZZ8357SxbT826yTqXLU4e0tBVBB2yBmB+V928aM= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20231010132942-eb035bc12a80/go.mod h1:uIwfoRl8ehNkNWKXffVgG11XAeRG607zAYxA32wxOPo= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= github.com/smartcontractkit/chainlink-testing-framework v1.17.6 h1:hcsP1eyzrqQf3veK4xh0T37PFkq5AasDwlgJfl11atY= diff --git a/pkg/solana/chain.go b/pkg/solana/chain.go index 2c81e877a..b4d9885e0 100644 --- a/pkg/solana/chain.go +++ b/pkg/solana/chain.go @@ -66,7 +66,7 @@ func (o *ChainOpts) GetLogger() logger.Logger { return o.Logger } -func NewChain(cfg *SolanaConfig, opts ChainOpts) (Chain, error) { +func NewChain(cfg *TOMLConfig, opts ChainOpts) (Chain, error) { if !cfg.IsEnabled() { return nil, fmt.Errorf("cannot create new chain with ID %s: chain is disabled", *cfg.ChainID) } @@ -82,7 +82,7 @@ var _ Chain = (*chain)(nil) type chain struct { utils.StartStopOnce id string - cfg *SolanaConfig + cfg *TOMLConfig txm *txm.Txm balanceMonitor types.Service lggr logger.Logger @@ -215,7 +215,7 @@ func (v *verifiedCachedClient) GetAccountInfoWithOpts(ctx context.Context, addr return v.ReaderWriter.GetAccountInfoWithOpts(ctx, addr, opts) } -func newChain(id string, cfg *SolanaConfig, ks loop.Keystore, lggr logger.Logger) (*chain, error) { +func newChain(id string, cfg *TOMLConfig, ks loop.Keystore, lggr logger.Logger) (*chain, error) { lggr = logger.With(lggr, "chainID", id, "chain", "solana") var ch = chain{ id: id, diff --git a/pkg/solana/chain_test.go b/pkg/solana/chain_test.go index 67522b2e2..33dc849bc 100644 --- a/pkg/solana/chain_test.go +++ b/pkg/solana/chain_test.go @@ -46,7 +46,7 @@ func TestSolanaChain_GetClient(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &SolanaConfig{ + cfg := &TOMLConfig{ ChainID: ptr("devnet"), Chain: ch, } @@ -143,7 +143,7 @@ func TestSolanaChain_VerifiedClient(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &SolanaConfig{ + cfg := &TOMLConfig{ ChainID: ptr("devnet"), Chain: ch, } @@ -186,7 +186,7 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) { ch := solcfg.Chain{} ch.SetDefaults() - cfg := &SolanaConfig{ + cfg := &TOMLConfig{ ChainID: ptr("devnet"), Enabled: ptr(true), Chain: ch, diff --git a/pkg/solana/cmd/chainlink-solana/main.go b/pkg/solana/cmd/chainlink-solana/main.go new file mode 100644 index 000000000..3fcef8641 --- /dev/null +++ b/pkg/solana/cmd/chainlink-solana/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/go-plugin" + "github.com/pelletier/go-toml/v2" + + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + "github.com/smartcontractkit/chainlink-solana/pkg/solana" +) + +const ( + loggerName = "PluginSolana" +) + +func main() { + s := loop.MustNewStartedServer(loggerName) + defer s.Stop() + + p := &pluginRelayer{Plugin: loop.Plugin{Logger: s.Logger}} + defer s.Logger.ErrorIfFn(p.Close, "Failed to close") + + s.MustRegister(p) + + stopCh := make(chan struct{}) + defer close(stopCh) + + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: loop.PluginRelayerHandshakeConfig(), + Plugins: map[string]plugin.Plugin{ + loop.PluginRelayerName: &loop.GRPCPluginRelayer{ + PluginServer: p, + BrokerConfig: loop.BrokerConfig{ + StopCh: stopCh, + Logger: s.Logger, + GRPCOpts: s.GRPCOpts, + }, + }, + }, + GRPCServer: s.GRPCOpts.NewServer, + }) +} + +type pluginRelayer struct { + loop.Plugin +} + +func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore loop.Keystore) (loop.Relayer, error) { + d := toml.NewDecoder(strings.NewReader(config)) + d.DisallowUnknownFields() + var cfg struct { + Solana solana.TOMLConfig + } + + if err := d.Decode(&cfg); err != nil { + return nil, fmt.Errorf("failed to decode config toml: %w:\n\t%s", err, config) + } + + opts := solana.ChainOpts{ + Logger: c.Logger, + KeyStore: keystore, + } + chain, err := solana.NewChain(&cfg.Solana, opts) + if err != nil { + return nil, fmt.Errorf("failed to create chain: %w", err) + } + ra := loop.NewRelayerAdapter(solana.NewRelayer(c.Logger, chain), chain) + + c.SubService(ra) + + return ra, nil +} diff --git a/pkg/solana/config.go b/pkg/solana/config.go index 7887fbc4b..200017aff 100644 --- a/pkg/solana/config.go +++ b/pkg/solana/config.go @@ -17,13 +17,16 @@ import ( soldb "github.com/smartcontractkit/chainlink-solana/pkg/solana/db" ) -type SolanaConfigs []*SolanaConfig +// Deprecated: use TOMLConfigs +type SolanaConfigs TOMLConfigs -func (cs SolanaConfigs) ValidateConfig() (err error) { +type TOMLConfigs []*TOMLConfig + +func (cs TOMLConfigs) ValidateConfig() (err error) { return cs.validateKeys() } -func (cs SolanaConfigs) validateKeys() (err error) { +func (cs TOMLConfigs) validateKeys() (err error) { // Unique chain IDs chainIDs := config.UniqueStrings{} for i, c := range cs { @@ -55,14 +58,14 @@ func (cs SolanaConfigs) validateKeys() (err error) { return } -func (cs *SolanaConfigs) SetFrom(fs *SolanaConfigs) (err error) { +func (cs *TOMLConfigs) SetFrom(fs *TOMLConfigs) (err error) { if err1 := fs.validateKeys(); err1 != nil { return err1 } for _, f := range *fs { if f.ChainID == nil { *cs = append(*cs, f) - } else if i := slices.IndexFunc(*cs, func(c *SolanaConfig) bool { + } else if i := slices.IndexFunc(*cs, func(c *TOMLConfig) bool { return c.ChainID != nil && *c.ChainID == *f.ChainID }); i == -1 { *cs = append(*cs, f) @@ -118,7 +121,10 @@ func legacySolNode(n *solcfg.Node, id string) soldb.Node { } } -type SolanaConfig struct { +// Deprecated: use TOMLConfig +type SolanaConfig = TOMLConfig + +type TOMLConfig struct { ChainID *string // Do not access directly, use [IsEnabled] Enabled *bool @@ -126,11 +132,11 @@ type SolanaConfig struct { Nodes SolanaNodes } -func (c *SolanaConfig) IsEnabled() bool { +func (c *TOMLConfig) IsEnabled() bool { return c.Enabled == nil || *c.Enabled } -func (c *SolanaConfig) SetFrom(f *SolanaConfig) { +func (c *TOMLConfig) SetFrom(f *TOMLConfig) { if f.ChainID != nil { c.ChainID = f.ChainID } @@ -174,7 +180,7 @@ func setFromChain(c, f *solcfg.Chain) { } } -func (c *SolanaConfig) ValidateConfig() (err error) { +func (c *TOMLConfig) ValidateConfig() (err error) { if c.ChainID == nil { err = multierr.Append(err, config.ErrMissing{Name: "ChainID", Msg: "required for all chains"}) } else if *c.ChainID == "" { @@ -187,7 +193,7 @@ func (c *SolanaConfig) ValidateConfig() (err error) { return } -func (c *SolanaConfig) TOMLString() (string, error) { +func (c *TOMLConfig) TOMLString() (string, error) { b, err := toml.Marshal(c) if err != nil { return "", err @@ -195,45 +201,45 @@ func (c *SolanaConfig) TOMLString() (string, error) { return string(b), nil } -var _ solcfg.Config = &SolanaConfig{} +var _ solcfg.Config = &TOMLConfig{} -func (c *SolanaConfig) BalancePollPeriod() time.Duration { +func (c *TOMLConfig) BalancePollPeriod() time.Duration { return c.Chain.BalancePollPeriod.Duration() } -func (c *SolanaConfig) ConfirmPollPeriod() time.Duration { +func (c *TOMLConfig) ConfirmPollPeriod() time.Duration { return c.Chain.ConfirmPollPeriod.Duration() } -func (c *SolanaConfig) OCR2CachePollPeriod() time.Duration { +func (c *TOMLConfig) OCR2CachePollPeriod() time.Duration { return c.Chain.OCR2CachePollPeriod.Duration() } -func (c *SolanaConfig) OCR2CacheTTL() time.Duration { +func (c *TOMLConfig) OCR2CacheTTL() time.Duration { return c.Chain.OCR2CacheTTL.Duration() } -func (c *SolanaConfig) TxTimeout() time.Duration { +func (c *TOMLConfig) TxTimeout() time.Duration { return c.Chain.TxTimeout.Duration() } -func (c *SolanaConfig) TxRetryTimeout() time.Duration { +func (c *TOMLConfig) TxRetryTimeout() time.Duration { return c.Chain.TxRetryTimeout.Duration() } -func (c *SolanaConfig) TxConfirmTimeout() time.Duration { +func (c *TOMLConfig) TxConfirmTimeout() time.Duration { return c.Chain.TxConfirmTimeout.Duration() } -func (c *SolanaConfig) SkipPreflight() bool { +func (c *TOMLConfig) SkipPreflight() bool { return *c.Chain.SkipPreflight } -func (c *SolanaConfig) Commitment() rpc.CommitmentType { +func (c *TOMLConfig) Commitment() rpc.CommitmentType { return rpc.CommitmentType(*c.Chain.Commitment) } -func (c *SolanaConfig) MaxRetries() *uint { +func (c *TOMLConfig) MaxRetries() *uint { if c.Chain.MaxRetries == nil { return nil } @@ -241,27 +247,27 @@ func (c *SolanaConfig) MaxRetries() *uint { return &mr } -func (c *SolanaConfig) FeeEstimatorMode() string { +func (c *TOMLConfig) FeeEstimatorMode() string { return *c.Chain.FeeEstimatorMode } -func (c *SolanaConfig) ComputeUnitPriceMax() uint64 { +func (c *TOMLConfig) ComputeUnitPriceMax() uint64 { return *c.Chain.ComputeUnitPriceMax } -func (c *SolanaConfig) ComputeUnitPriceMin() uint64 { +func (c *TOMLConfig) ComputeUnitPriceMin() uint64 { return *c.Chain.ComputeUnitPriceMin } -func (c *SolanaConfig) ComputeUnitPriceDefault() uint64 { +func (c *TOMLConfig) ComputeUnitPriceDefault() uint64 { return *c.Chain.ComputeUnitPriceDefault } -func (c *SolanaConfig) FeeBumpPeriod() time.Duration { +func (c *TOMLConfig) FeeBumpPeriod() time.Duration { return c.Chain.FeeBumpPeriod.Duration() } -func (c *SolanaConfig) ListNodes() ([]soldb.Node, error) { +func (c *TOMLConfig) ListNodes() ([]soldb.Node, error) { var allNodes []soldb.Node for _, n := range c.Nodes { allNodes = append(allNodes, legacySolNode(n, *c.ChainID))