Skip to content

Commit

Permalink
CCIP Load Test utilizing crib setup (#15954)
Browse files Browse the repository at this point in the history
* add new ccip load test, compiles

* fix build

* make test runnable

* rename

* in progress

* build

* load test transmitting

* load test, have transaction, need to use event watcher

* progress, going to rebase

* changeset applies only once

* should nto use testrouter when adding lanes

* test changes

* set ocr3 configuration so the bootstrap can create a don

* load test WORKING

* use changeset cspairs in the ccip tests

* optimizations for load test

* cleanup

* re-add fallback.toml

* fix build failures, go mod tidy

* goimports

* fix build failures in integ tests

* testing with working subscription

* need to use flag to determine if all complete

* move ticker time to a variable

* go mods

* go mods

* fix some tests

* lint

* lint

* integration tests build passing

* add README

* add a skip to the test so it doesn't get ran automatically

* golangci

* nolint needs a directive to ignore

* sonarqube issues

* changes

* PR comments

* lint

* remove empty change import

* go mod tidy

* resolve changed state/interfaces
  • Loading branch information
0xAustinWang authored Jan 23, 2025
1 parent 47ecf57 commit c682bd7
Show file tree
Hide file tree
Showing 19 changed files with 1,159 additions and 64 deletions.
12 changes: 6 additions & 6 deletions deployment/ccip/changeset/testhelpers/test_assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,21 @@ func ConfirmCommitForAllWithExpectedSeqNums(
)
}

type commitReportTracker struct {
type CommitReportTracker struct {
seenMessages map[uint64]map[uint64]bool
}

func newCommitReportTracker(sourceChainSelector uint64, seqNrs ccipocr3.SeqNumRange) commitReportTracker {
func NewCommitReportTracker(sourceChainSelector uint64, seqNrs ccipocr3.SeqNumRange) CommitReportTracker {
seenMessages := make(map[uint64]map[uint64]bool)
seenMessages[sourceChainSelector] = make(map[uint64]bool)

for i := seqNrs.Start(); i <= seqNrs.End(); i++ {
seenMessages[sourceChainSelector][uint64(i)] = false
}
return commitReportTracker{seenMessages: seenMessages}
return CommitReportTracker{seenMessages: seenMessages}
}

func (c *commitReportTracker) visitCommitReport(sourceChainSelector uint64, minSeqNr uint64, maxSeqNr uint64) {
func (c *CommitReportTracker) visitCommitReport(sourceChainSelector uint64, minSeqNr uint64, maxSeqNr uint64) {
if _, ok := c.seenMessages[sourceChainSelector]; !ok {
return
}
Expand All @@ -255,7 +255,7 @@ func (c *commitReportTracker) visitCommitReport(sourceChainSelector uint64, minS
}
}

func (c *commitReportTracker) allCommited(sourceChainSelector uint64) bool {
func (c *CommitReportTracker) allCommited(sourceChainSelector uint64) bool {
for _, v := range c.seenMessages[sourceChainSelector] {
if !v {
return false
Expand Down Expand Up @@ -319,7 +319,7 @@ func ConfirmCommitWithExpectedSeqNumRange(
return nil, fmt.Errorf("error to subscribe CommitReportAccepted : %w", err)
}

seenMessages := newCommitReportTracker(src.Selector, expectedSeqNumRange)
seenMessages := NewCommitReportTracker(src.Selector, expectedSeqNumRange)

defer subscription.Unsubscribe()
var duration time.Duration
Expand Down
163 changes: 124 additions & 39 deletions deployment/environment/crib/ccip_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"fmt"
"math/big"

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

"github.com/ethereum/go-ethereum/common"

"github.com/smartcontractkit/ccip-owner-contracts/pkg/config"

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"

"github.com/smartcontractkit/chainlink/deployment"
Expand Down Expand Up @@ -40,7 +42,24 @@ func DeployHomeChainContracts(ctx context.Context, lggr logger.Logger, envConfig
return deployment.CapabilityRegistryConfig{}, e.ExistingAddresses, fmt.Errorf("failed to get node info from env: %w", err)
}
p2pIds := nodes.NonBootstraps().PeerIDs()
cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for _, chain := range e.AllChainSelectors() {
mcmsConfig, err := config.NewConfig(1, []common.Address{e.Chains[chain].DeployerKey.From}, []config.Config{})
if err != nil {
return deployment.CapabilityRegistryConfig{}, e.ExistingAddresses, fmt.Errorf("failed to create mcms config: %w", err)
}
cfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: *mcmsConfig,
Bypasser: *mcmsConfig,
Proposer: *mcmsConfig,
TimelockMinDelay: big.NewInt(0),
}
}
*e, err = commonchangeset.ApplyChangesets(nil, *e, nil, []commonchangeset.ChangesetApplication{
{
Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock),
Config: cfg,
},
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployHomeChainChangeset),
Config: changeset.DeployHomeChainConfig{
Expand Down Expand Up @@ -73,25 +92,14 @@ func DeployHomeChainContracts(ctx context.Context, lggr logger.Logger, envConfig

// DeployCCIPAndAddLanes is the actual ccip setup once the nodes are initialized.
func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig devenv.EnvironmentConfig, homeChainSel, feedChainSel uint64, ab deployment.AddressBook) (DeployCCIPOutput, error) {
e, _, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, envConfig)
e, don, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, envConfig)
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to initiate new environment: %w", err)
}
e.ExistingAddresses = ab
chainSelectors := e.AllChainSelectors()
cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
var prereqCfgs []changeset.DeployPrerequisiteConfigPerChain
for _, chain := range e.AllChainSelectors() {
mcmsConfig, err := config.NewConfig(1, []common.Address{e.Chains[chain].DeployerKey.From}, []config.Config{})
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to create mcms config: %w", err)
}
cfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: *mcmsConfig,
Bypasser: *mcmsConfig,
Proposer: *mcmsConfig,
TimelockMinDelay: big.NewInt(0),
}
prereqCfgs = append(prereqCfgs, changeset.DeployPrerequisiteConfigPerChain{
ChainSelector: chain,
})
Expand Down Expand Up @@ -139,17 +147,19 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
Configs: prereqCfgs,
},
},
{
Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock),
Config: cfg,
},
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
HomeChainSelector: homeChainSel,
ContractParamsPerChain: contractParams,
},
},
{
Changeset: commonchangeset.WrapChangeSet(changeset.SetRMNRemoteOnRMNProxyChangeset),
Config: changeset.SetRMNRemoteOnRMNProxyConfig{
ChainSelectors: chainSelectors,
},
},
{
Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspecChangeset),
Config: struct{}{},
Expand All @@ -159,20 +169,88 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to load onchain state: %w", err)
}

var ocrConfigPerSelector = make(map[uint64]changeset.CCIPOCRParams)
for selector := range e.Chains {
ocrConfigPerSelector[selector] = changeset.DeriveCCIPOCRParams(changeset.WithDefaultCommitOffChainConfig(feedChainSel, nil),
changeset.WithDefaultExecuteOffChainConfig(nil),
)
}

*e, err = commonchangeset.ApplyChangesets(nil, *e, nil, []commonchangeset.ChangesetApplication{
{
// Add the DONs and candidate commit OCR instances for the chain.
Changeset: commonchangeset.WrapChangeSet(changeset.AddDonAndSetCandidateChangeset),
Config: changeset.AddDonAndSetCandidateChangesetConfig{
SetCandidateConfigBase: changeset.SetCandidateConfigBase{
HomeChainSelector: homeChainSel,
FeedChainSelector: feedChainSel,
},
PluginInfo: changeset.SetCandidatePluginInfo{
OCRConfigPerRemoteChainSelector: ocrConfigPerSelector,
PluginType: types.PluginTypeCCIPCommit,
},
},
},
{
// Add the exec OCR instances for the new chains.
Changeset: commonchangeset.WrapChangeSet(changeset.SetCandidateChangeset),
Config: changeset.SetCandidateChangesetConfig{
SetCandidateConfigBase: changeset.SetCandidateConfigBase{
HomeChainSelector: homeChainSel,
FeedChainSelector: feedChainSel,
},
PluginInfo: []changeset.SetCandidatePluginInfo{
{
OCRConfigPerRemoteChainSelector: ocrConfigPerSelector,
PluginType: types.PluginTypeCCIPExec,
},
},
},
},
{
// Promote everything
Changeset: commonchangeset.WrapChangeSet(changeset.PromoteCandidateChangeset),
Config: changeset.PromoteCandidateChangesetConfig{
HomeChainSelector: homeChainSel,
PluginInfo: []changeset.PromoteCandidatePluginInfo{
{
RemoteChainSelectors: chainSelectors,
PluginType: types.PluginTypeCCIPCommit,
},
{
RemoteChainSelectors: chainSelectors,
PluginType: types.PluginTypeCCIPExec,
},
},
},
},
{
// Enable the OCR config on the remote chains.
Changeset: commonchangeset.WrapChangeSet(changeset.SetOCR3OffRampChangeset),
Config: changeset.SetOCR3OffRampConfig{
HomeChainSel: homeChainSel,
RemoteChainSels: chainSelectors,
},
},
})
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to apply changesets: %w", err)
}

// Add all lanes
for from := range e.Chains {
for to := range e.Chains {
if from != to {
stateChain1 := state.Chains[from]
for src := range e.Chains {
for dst := range e.Chains {
if src != dst {
stateChain1 := state.Chains[src]
newEnv, err := commonchangeset.ApplyChangesets(nil, *e, nil, []commonchangeset.ChangesetApplication{
{
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateOnRampsDestsChangeset),
Config: changeset.UpdateOnRampDestsConfig{
UpdatesByChain: map[uint64]map[uint64]changeset.OnRampDestinationUpdate{
from: {
to: {
src: {
dst: {
IsEnabled: true,
TestRouter: false,
AllowListEnabled: false,
},
},
Expand All @@ -183,13 +261,13 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateFeeQuoterPricesChangeset),
Config: changeset.UpdateFeeQuoterPricesConfig{
PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{
from: {
src: {
TokenPrices: map[common.Address]*big.Int{
stateChain1.LinkToken.Address(): testhelpers.DefaultLinkPrice,
stateChain1.Weth9.Address(): testhelpers.DefaultWethPrice,
},
GasPrices: map[uint64]*big.Int{
to: testhelpers.DefaultGasPrice,
dst: testhelpers.DefaultGasPrice,
},
},
},
Expand All @@ -199,8 +277,8 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateFeeQuoterDestsChangeset),
Config: changeset.UpdateFeeQuoterDestsConfig{
UpdatesByChain: map[uint64]map[uint64]fee_quoter.FeeQuoterDestChainConfig{
from: {
to: changeset.DefaultFeeQuoterDestChainConfig(),
src: {
dst: changeset.DefaultFeeQuoterDestChainConfig(),
},
},
},
Expand All @@ -209,10 +287,9 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateOffRampSourcesChangeset),
Config: changeset.UpdateOffRampSourcesConfig{
UpdatesByChain: map[uint64]map[uint64]changeset.OffRampSourceUpdate{
to: {
from: {
IsEnabled: true,
TestRouter: true,
dst: {
src: {
IsEnabled: true,
},
},
},
Expand All @@ -221,18 +298,21 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
{
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateRouterRampsChangeset),
Config: changeset.UpdateRouterRampsConfig{
TestRouter: true,
UpdatesByChain: map[uint64]changeset.RouterUpdates{
// onRamp update on source chain
from: {
src: {
OffRampUpdates: map[uint64]bool{
dst: true,
},
OnRampUpdates: map[uint64]bool{
to: true,
dst: true,
},
},
// off
from: {
dst: {
OffRampUpdates: map[uint64]bool{
to: true,
src: true,
},
OnRampUpdates: map[uint64]bool{
src: true,
},
},
},
Expand All @@ -247,6 +327,11 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
}
}

// distribute funds to transmitters
// we need to use the nodeinfo from the envConfig here, because multiAddr is not
// populated in the environment variable
distributeFunds(lggr, don.PluginNodes(), *e)

addresses, err := e.ExistingAddresses.Addresses()
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to get convert address book to address book map: %w", err)
Expand Down
12 changes: 10 additions & 2 deletions deployment/environment/crib/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,23 @@ func NewDevspaceEnvFromStateDir(envStateDir string) CRIBEnv {
}
}

func (c CRIBEnv) GetConfig() DeployOutput {
func (c CRIBEnv) GetConfig(key string) (DeployOutput, error) {
reader := NewOutputReader(c.envStateDir)
nodesDetails := reader.ReadNodesDetails()
chainConfigs := reader.ReadChainConfigs()
for i, chain := range chainConfigs {
err := chain.SetDeployerKey(&key)
if err != nil {
return DeployOutput{}, err
}
chainConfigs[i] = chain
}

return DeployOutput{
AddressBook: reader.ReadAddressBook(),
NodeIDs: nodesDetails.NodeIDs,
Chains: chainConfigs,
}
}, nil
}

type RPC struct {
Expand Down
3 changes: 2 additions & 1 deletion deployment/environment/crib/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
func TestShouldProvideEnvironmentConfig(t *testing.T) {
t.Parallel()
env := NewDevspaceEnvFromStateDir("testdata/lanes-deployed-state")
config := env.GetConfig()
config, err := env.GetConfig("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
require.NoError(t, err)
require.NotNil(t, config)
assert.NotEmpty(t, config.NodeIDs)
assert.NotNil(t, config.AddressBook)
Expand Down
Loading

0 comments on commit c682bd7

Please sign in to comment.