From 04d40a45e6992b6597afb5784632d0e4963aba9f Mon Sep 17 00:00:00 2001 From: aalu1418 <50029043+aalu1418@users.noreply.github.com> Date: Fri, 29 Mar 2024 14:10:56 -0600 Subject: [PATCH] test: add gauntlet logic + convert wallets to addresses only --- integration-tests/common/test_common.go | 91 +++++++++++++++---- integration-tests/gauntlet/gauntlet_solana.go | 2 +- integration-tests/smoke/ocr2_test.go | 17 ++-- integration-tests/soak/ocr2_soak_test.go | 2 +- integration-tests/solclient/deployer.go | 10 +- integration-tests/solclient/ocr2.go | 16 ++-- integration-tests/solclient/store.go | 25 ++--- integration-tests/utils/offchainConfig.go | 4 + 8 files changed, 112 insertions(+), 55 deletions(-) diff --git a/integration-tests/common/test_common.go b/integration-tests/common/test_common.go index 4e0d071fb..57a2523d4 100644 --- a/integration-tests/common/test_common.go +++ b/integration-tests/common/test_common.go @@ -4,11 +4,13 @@ import ( "fmt" "math/big" "os" + "sort" "strings" "sync" "testing" "time" + "github.com/gagliardetto/solana-go" "github.com/onsi/gomega" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -126,7 +128,7 @@ func (m *OCRv2TestState) LabelChaosGroups() { m.LabelChaosGroup(10, 19, ChaosGroupRightHalf) } -func (m *OCRv2TestState) DeployCluster(contractsDir string) { +func (m *OCRv2TestState) DeployCluster(contractsDir string, enableGauntlet bool) { if m.Common.IsK8s { m.DeployEnv(contractsDir) } else { @@ -155,7 +157,7 @@ func (m *OCRv2TestState) DeployCluster(contractsDir string) { Killgrave: env.MockAdapter, } } - m.SetupClients() + m.SetupClients(enableGauntlet) m.DeployContracts(contractsDir) m.CreateJobs() } @@ -206,7 +208,7 @@ func (m *OCRv2TestState) NewSolanaClientSetup(networkSettings *solclient.SolNetw } func (m *OCRv2TestState) NewGauntletSetup() (*gauntlet.SolanaGauntlet, error) { - cfg := m.ConfigureGauntlet("this is an testing only secret") // TODO: move secret + cfg := m.ConfigureGauntlet(utils.TestingSecret) g, err := gauntlet.NewSolanaGauntlet(fmt.Sprintf("%s/gauntlet", utils.ProjectRoot)) if err != nil { return nil, err @@ -304,27 +306,76 @@ func (m *OCRv2TestState) DeployFeedWithGauntlet(i int) error { _, err := m.Gauntlet.DeployOCR2() require.NoError(m.T, err, "Error deploying OCR") - var nodeCount int - if m.Common.IsK8s { - nodeCount = len(m.ContractsNodeSetup[i].NodesK8s) - } else { - nodeCount = len(m.ContractsNodeSetup[i].Nodes) - } - ocConfig, err := OffChainConfigParamsFromNodes(nodeCount, m.ContractsNodeSetup[i].NodeKeysBundle) + gauntletConfig := m.ConfigureGauntlet(utils.TestingSecret) + bundleData := make([]client.NodeKeysBundle, len(m.ContractsNodeSetup[i].NodeKeysBundle)) + copy(bundleData, m.ContractsNodeSetup[i].NodeKeysBundle) + + // We have to sort by on_chain_pub_key for the config digest + sort.Slice(bundleData, func(i, j int) bool { + return bundleData[i].OCR2Key.Data.Attributes.OnChainPublicKey < bundleData[j].OCR2Key.Data.Attributes.OnChainPublicKey + }) + + onChainConfig, err := m.GenerateOnChainConfig(bundleData, gauntletConfig["VAULT"], m.Gauntlet.ProposalAddress) require.NoError(m.T, err) - // TODO: use gauntlet + reportingConfig := utils.ReportingPluginConfig{ + AlphaReportInfinite: false, + AlphaReportPpb: 0, + AlphaAcceptInfinite: false, + AlphaAcceptPpb: 0, + DeltaCNanoseconds: 0, + } + offChainConfig := m.GenerateOffChainConfig( + bundleData, + m.Gauntlet.ProposalAddress, + reportingConfig, + int64(20000000000), + int64(50000000000), + int64(1000000000), + int64(4000000000), + int64(50000000000), + 3, + int64(0), + int64(3000000000), + int64(3000000000), + int64(100000000), + int64(100000000), + utils.TestingSecret, + ) + + payees := m.GeneratePayees(bundleData, gauntletConfig["VAULT"], m.Gauntlet.ProposalAddress) + proposalAccept := m.GenerateProposalAcceptConfig(m.Gauntlet.ProposalAddress, 2, 1, onChainConfig.Oracles, offChainConfig.OffchainConfig, utils.TestingSecret) + + err = m.Gauntlet.ConfigureOCR2(onChainConfig, offChainConfig, payees, proposalAccept) + require.NoError(m.T, err) + + // TODO: standardize config generation + // var nodeCount int + // if m.Common.IsK8s { + // nodeCount = len(m.ContractsNodeSetup[i].NodesK8s) + // } else { + // nodeCount = len(m.ContractsNodeSetup[i].Nodes) + // } + // ocConfig, err := OffChainConfigParamsFromNodes(nodeCount, m.ContractsNodeSetup[i].NodeKeysBundle) + // require.NoError(m.T, err) // err = ocr2.Configure(ocConfig) // require.NoError(m.T, err) - // m.Mu.Lock() - // m.Contracts = append(m.Contracts, Contracts{ - // BAC: bac, - // RAC: rac, - // OCR2: ocr2, - // Store: store, - // StoreAuth: storeAuth, - // }) - // m.Mu.Unlock() + + m.Mu.Lock() + m.Contracts = append(m.Contracts, Contracts{ + OCR2: &solclient.OCRv2{ + Client: m.Client, + State: solana.MustPublicKeyFromBase58(m.Gauntlet.OcrAddress), + ProgramWallet: m.Client.ProgramWallets["ocr2-keypair.json"].PublicKey(), + }, + Store: &solclient.Store{ + Client: m.Client, + Store: solana.MustPublicKeyFromBase58(m.Gauntlet.StoreAddress), + Feed: solana.MustPublicKeyFromBase58(m.Gauntlet.FeedAddress), + ProgramWallet: m.Client.ProgramWallets["store-keypair.json"].PublicKey(), + }, + }) + m.Mu.Unlock() return nil } diff --git a/integration-tests/gauntlet/gauntlet_solana.go b/integration-tests/gauntlet/gauntlet_solana.go index 1aed7b208..f255c72bf 100644 --- a/integration-tests/gauntlet/gauntlet_solana.go +++ b/integration-tests/gauntlet/gauntlet_solana.go @@ -481,7 +481,7 @@ func (sg *SolanaGauntlet) ConfigureOCR2(onChainConfig utils.OCR2OnChainConfig, o if err != nil { return err } - _, err = sg.AcceptProposal(sg.ProposalAddress, "this is an testing only secret", proposalAccept, sg.OcrAddress) + _, err = sg.AcceptProposal(sg.ProposalAddress, utils.TestingSecret, proposalAccept, sg.OcrAddress) if err != nil { return err } diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 8ac9b15b4..1dd629c3e 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -34,14 +34,16 @@ import ( func TestSolanaOCRV2Smoke(t *testing.T) { for _, test := range []struct { - name string - env map[string]string + name string + env map[string]string + enableGauntlet bool }{ {name: "embedded"}, {name: "plugins", env: map[string]string{ "CL_MEDIAN_CMD": "chainlink-feeds", "CL_SOLANA_CMD": "chainlink-solana", }}, + {name: "embedded-gauntlet", enableGauntlet: true}, } { config, err := tc.GetConfig("Smoke", tc.OCR2) if err != nil { @@ -62,7 +64,7 @@ func TestSolanaOCRV2Smoke(t *testing.T) { maps.Copy(n.ContainerEnvs, test.env) }) } - state.DeployCluster(utils.ContractsDir) + state.DeployCluster(utils.ContractsDir, test.enableGauntlet) state.ValidateRoundsAfter(time.Now(), common.NewRoundCheckTimeout, 1) }) @@ -75,7 +77,6 @@ func TestSolanaGauntletOCRV2Smoke(t *testing.T) { t.Fatal(err) } l := logging.GetTestLogger(t) - secret := "this is an testing only secret" state, err := common.NewOCRv2State(t, 1, "gauntlet", "devnet", true, &config) require.NoError(t, err, "Could not setup the ocrv2 state") if state.Common.Env.WillUseRemoteRunner() { @@ -94,13 +95,13 @@ func TestSolanaGauntletOCRV2Smoke(t *testing.T) { l.Error().Err(err).Msg("Error tearing down environment") } }) - state.SetupClients() + state.SetupClients(false) // not setting up gauntlet because it is set up outside state.NodeKeysBundle, err = state.Common.CreateNodeKeysBundle(state.GetChainlinkNodes()) require.NoError(t, err) err = state.Common.CreateSolanaChainAndNode(state.GetChainlinkNodes()) require.NoError(t, err) - gauntletConfig := state.ConfigureGauntlet(secret) + gauntletConfig := state.ConfigureGauntlet(utils.TestingSecret) err = sg.SetupNetwork(gauntletConfig) require.NoError(t, err, "Error setting gauntlet network") @@ -145,11 +146,11 @@ func TestSolanaGauntletOCRV2Smoke(t *testing.T) { int64(3000000000), int64(100000000), int64(100000000), - secret, + utils.TestingSecret, ) payees := state.GeneratePayees(bundleData, gauntletConfig["VAULT"], sg.ProposalAddress) - proposalAccept := state.GenerateProposalAcceptConfig(sg.ProposalAddress, 2, 1, onChainConfig.Oracles, offChainConfig.OffchainConfig, secret) + proposalAccept := state.GenerateProposalAcceptConfig(sg.ProposalAddress, 2, 1, onChainConfig.Oracles, offChainConfig.OffchainConfig, utils.TestingSecret) require.NoError(t, err) err = sg.ConfigureOCR2(onChainConfig, offChainConfig, payees, proposalAccept) diff --git a/integration-tests/soak/ocr2_soak_test.go b/integration-tests/soak/ocr2_soak_test.go index 837f42c53..3fd8a01f9 100644 --- a/integration-tests/soak/ocr2_soak_test.go +++ b/integration-tests/soak/ocr2_soak_test.go @@ -25,6 +25,6 @@ func TestSolanaOCRV2SoakTest(t *testing.T) { require.NoError(t, err) return } - state.DeployCluster(utils.ContractsDir) + state.DeployCluster(utils.ContractsDir, false) state.ValidateRoundsAfter(time.Now(), common.NewSoakRoundsCheckTimeout, 20000) } diff --git a/integration-tests/solclient/deployer.go b/integration-tests/solclient/deployer.go index 63089f1f5..edce0c067 100644 --- a/integration-tests/solclient/deployer.go +++ b/integration-tests/solclient/deployer.go @@ -186,10 +186,10 @@ func (c *ContractDeployer) DeployOCRv2Store(billingAC string) (*Store, error) { } return &Store{ Client: c.Client, - Store: c.Accounts.Store, - Feed: c.Accounts.Feed, + Store: c.Accounts.Store.PublicKey(), + Feed: c.Accounts.Feed.PublicKey(), Owner: c.Accounts.Owner, - ProgramWallet: programWallet, + ProgramWallet: programWallet.PublicKey(), }, nil } @@ -347,13 +347,13 @@ func (c *ContractDeployer) InitOCR2(billingControllerAddr string, requesterContr return &OCRv2{ ContractDeployer: c, Client: c.Client, - State: c.Accounts.OCR, + State: c.Accounts.OCR.PublicKey(), Authorities: c.Accounts.Authorities, Owner: c.Accounts.Owner, Proposal: c.Accounts.Proposal, OCRVaultAssociatedPubKey: *assocVault, Mint: c.Accounts.Mint, - ProgramWallet: programWallet, + ProgramWallet: programWallet.PublicKey(), }, nil } diff --git a/integration-tests/solclient/ocr2.go b/integration-tests/solclient/ocr2.go index 2c8ac7598..a5c17b2db 100644 --- a/integration-tests/solclient/ocr2.go +++ b/integration-tests/solclient/ocr2.go @@ -20,18 +20,18 @@ import ( type OCRv2 struct { Client *Client ContractDeployer *ContractDeployer - State *solana.Wallet + State solana.PublicKey Authorities map[string]*Authority Payees []*solana.Wallet Owner *solana.Wallet Proposal *solana.Wallet Mint *solana.Wallet OCRVaultAssociatedPubKey solana.PublicKey - ProgramWallet *solana.Wallet + ProgramWallet solana.PublicKey } func (m *OCRv2) ProgramAddress() string { - return m.ProgramWallet.PublicKey().String() + return m.ProgramWallet.String() } func (m *OCRv2) writeOffChainConfig(ocConfigBytes []byte) error { @@ -71,7 +71,7 @@ func (m *OCRv2) acceptProposal(digest []byte) error { []solana.Instruction{ ocr_2.NewAcceptProposalInstruction( digest, - m.State.PublicKey(), + m.State, m.Proposal.PublicKey(), m.Owner.PublicKey(), m.OCRVaultAssociatedPubKey, @@ -112,7 +112,7 @@ func (m *OCRv2) SetBilling(observationPayment uint32, transmissionPayment uint32 ocr_2.NewSetBillingInstruction( observationPayment, transmissionPayment, - m.State.PublicKey(), + m.State, m.Owner.PublicKey(), m.Owner.PublicKey(), billingACPubKey, @@ -302,7 +302,7 @@ func (m *OCRv2) DumpState() error { var stateDump ocr_2.State err := m.Client.RPC.GetAccountDataInto( context.Background(), - m.State.PublicKey(), + m.State, &stateDump, ) if err != nil { @@ -318,7 +318,7 @@ func (m *OCRv2) GetContractData(ctx context.Context) (*contracts.OffchainAggrega // ProposeConfig sets oracles with payee addresses func (m *OCRv2) proposeConfig(ocConfig contracts.OffChainAggregatorV2Config) error { - log.Info().Str("Program Address", m.ProgramWallet.PublicKey().String()).Msg("Proposing new config") + log.Info().Str("Program Address", m.ProgramWallet.String()).Msg("Proposing new config") payer := m.Client.DefaultWallet oracles := make([]ocr_2.NewOracle, 0) for _, oc := range ocConfig.Oracles { @@ -407,7 +407,7 @@ func (m *OCRv2) RequestNewRound() error { } func (m *OCRv2) Address() string { - return m.State.PublicKey().String() + return m.State.String() } func (m *OCRv2) TransferOwnership(to string) error { diff --git a/integration-tests/solclient/store.go b/integration-tests/solclient/store.go index abc9eebe8..79fdc0c80 100644 --- a/integration-tests/solclient/store.go +++ b/integration-tests/solclient/store.go @@ -11,14 +11,14 @@ import ( type Store struct { Client *Client - Store *solana.Wallet - Feed *solana.Wallet + Store solana.PublicKey + Feed solana.PublicKey Owner *solana.Wallet - ProgramWallet *solana.Wallet + ProgramWallet solana.PublicKey } func (m *Store) GetLatestRoundData() (uint64, uint64, uint64, error) { - a, _, err := relaySol.GetLatestTransmission(context.Background(), m.Client.RPC, m.Feed.PublicKey(), rpc.CommitmentConfirmed) + a, _, err := relaySol.GetLatestTransmission(context.Background(), m.Client.RPC, m.Feed, rpc.CommitmentConfirmed) if err != nil { return 0, 0, 0, err } @@ -26,7 +26,7 @@ func (m *Store) GetLatestRoundData() (uint64, uint64, uint64, error) { } func (m *Store) TransmissionsAddress() string { - return m.Feed.PublicKey().String() + return m.Feed.String() } func (m *Store) SetValidatorConfig(flaggingThreshold uint32) error { @@ -36,7 +36,7 @@ func (m *Store) SetValidatorConfig(flaggingThreshold uint32) error { []solana.Instruction{ store.NewSetValidatorConfigInstruction( flaggingThreshold, - m.Feed.PublicKey(), + m.Feed, m.Owner.PublicKey(), m.Owner.PublicKey(), ).Build(), @@ -69,7 +69,7 @@ func (m *Store) SetWriter(writerAuthority string) error { []solana.Instruction{ store.NewSetWriterInstruction( writerAuthPubKey, - m.Feed.PublicKey(), + m.Feed, m.Owner.PublicKey(), m.Owner.PublicKey(), ).Build(), @@ -78,9 +78,10 @@ func (m *Store) SetWriter(writerAuthority string) error { if key.Equals(m.Owner.PublicKey()) { return &m.Owner.PrivateKey } - if key.Equals(m.Feed.PublicKey()) { - return &m.Feed.PrivateKey - } + // TODO: is this needed? + // if key.Equals(m.Feed)) { + // return &m.Feed.PrivateKey + // } if key.Equals(payer.PublicKey()) { return &payer.PrivateKey } @@ -95,9 +96,9 @@ func (m *Store) SetWriter(writerAuthority string) error { } func (m *Store) ProgramAddress() string { - return m.ProgramWallet.PublicKey().String() + return m.ProgramWallet.String() } func (m *Store) Address() string { - return m.Store.PublicKey().String() + return m.Store.String() } diff --git a/integration-tests/utils/offchainConfig.go b/integration-tests/utils/offchainConfig.go index acd8dd4e9..bfa1be7d9 100644 --- a/integration-tests/utils/offchainConfig.go +++ b/integration-tests/utils/offchainConfig.go @@ -1,5 +1,9 @@ package utils +const ( + TestingSecret = "this is an testing only secret" +) + type OCR2OnChainConfig struct { Oracles []Operator `json:"oracles"` F int `json:"f"`