From 1318241ba5e9c7a6137d7298e2616e4ab00b7eaf Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Wed, 22 Oct 2025 11:24:21 -0400 Subject: [PATCH 1/5] Single anvil node --- aggregator/aggregator.toml | 95 +++++++++------- build/devenv/cldf.go | 98 ++++++++++++++++ build/devenv/cmd/ccv/ccv.go | 2 +- build/devenv/config.go | 16 ++- build/devenv/env.toml | 33 +++--- build/devenv/environment.go | 105 ++++++++++-------- build/devenv/tests/e2e/smoke_test.go | 26 ++++- ccv-evm/impl.go | 91 ++++++++++++++- cmd/executor/executor_config.toml | 48 ++++---- .../testconfig/default/verifier-1.toml | 58 +++++----- .../testconfig/default/verifier-2.toml | 60 +++++----- .../testconfig/secondary/verifier-1.toml | 58 +++++----- .../testconfig/secondary/verifier-2.toml | 60 +++++----- .../testconfig/tertiary/verifier-1.toml | 58 +++++----- .../testconfig/tertiary/verifier-2.toml | 60 +++++----- .../evm_contract_transmitter.go | 11 +- 16 files changed, 535 insertions(+), 344 deletions(-) diff --git a/aggregator/aggregator.toml b/aggregator/aggregator.toml index 57199dc4a..efa4f3d05 100644 --- a/aggregator/aggregator.toml +++ b/aggregator/aggregator.toml @@ -45,121 +45,132 @@ pyroscope_url = "http://pyroscope:4040" [committees] [committees.default] [committees.default.quorumConfigs] - [committees.default.quorumConfigs.12922642891491394802] + [committees.default.quorumConfigs.100] committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" threshold = 2 - [[committees.default.quorumConfigs.12922642891491394802.signers]] + [[committees.default.quorumConfigs.100.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.12922642891491394802.signers]] + [[committees.default.quorumConfigs.100.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] - [committees.default.quorumConfigs.3379446385462418246] - committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + + [committees.default.quorumConfigs.101] + committeeVerifierAddress = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" threshold = 2 - [[committees.default.quorumConfigs.3379446385462418246.signers]] + [[committees.default.quorumConfigs.101.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.3379446385462418246.signers]] + [[committees.default.quorumConfigs.101.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] - [committees.default.quorumConfigs.4793464827907405086] - committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + + [committees.default.quorumConfigs.102] + committeeVerifierAddress = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" threshold = 2 - [[committees.default.quorumConfigs.4793464827907405086.signers]] + [[committees.default.quorumConfigs.102.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.4793464827907405086.signers]] + [[committees.default.quorumConfigs.102.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] + [committees.default.sourceVerifierAddresses] - 12922642891491394802 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 4793464827907405086 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + [committees.secondary] [committees.secondary.quorumConfigs] - [committees.secondary.quorumConfigs.12922642891491394802] + [committees.secondary.quorumConfigs.100] committeeVerifierAddress = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" threshold = 2 - [[committees.secondary.quorumConfigs.12922642891491394802.signers]] + [[committees.secondary.quorumConfigs.100.signers]] participantID = "secondary-participant1" addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] - [[committees.secondary.quorumConfigs.12922642891491394802.signers]] + [[committees.secondary.quorumConfigs.100.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] - [committees.secondary.quorumConfigs.3379446385462418246] - committeeVerifierAddress = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + + [committees.secondary.quorumConfigs.101] + committeeVerifierAddress = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" threshold = 2 - [[committees.secondary.quorumConfigs.3379446385462418246.signers]] + [[committees.secondary.quorumConfigs.101.signers]] participantID = "secondary-participant1" addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] - [[committees.secondary.quorumConfigs.3379446385462418246.signers]] + [[committees.secondary.quorumConfigs.101.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] - [committees.secondary.quorumConfigs.4793464827907405086] - committeeVerifierAddress = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + + [committees.secondary.quorumConfigs.102] + committeeVerifierAddress = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" threshold = 2 - [[committees.secondary.quorumConfigs.4793464827907405086.signers]] + [[committees.secondary.quorumConfigs.102.signers]] participantID = "secondary-participant1" addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] - [[committees.secondary.quorumConfigs.4793464827907405086.signers]] + [[committees.secondary.quorumConfigs.102.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] + [committees.secondary.sourceVerifierAddresses] - 12922642891491394802 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 4793464827907405086 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" + [committees.tertiary] [committees.tertiary.quorumConfigs] - [committees.tertiary.quorumConfigs.12922642891491394802] + [committees.tertiary.quorumConfigs.100] committeeVerifierAddress = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" threshold = 2 - [[committees.tertiary.quorumConfigs.12922642891491394802.signers]] + [[committees.tertiary.quorumConfigs.100.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.12922642891491394802.signers]] + [[committees.tertiary.quorumConfigs.100.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] - [committees.tertiary.quorumConfigs.3379446385462418246] - committeeVerifierAddress = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + + [committees.tertiary.quorumConfigs.101] + committeeVerifierAddress = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" threshold = 2 - [[committees.tertiary.quorumConfigs.3379446385462418246.signers]] + [[committees.tertiary.quorumConfigs.101.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.3379446385462418246.signers]] + [[committees.tertiary.quorumConfigs.101.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] - [committees.tertiary.quorumConfigs.4793464827907405086] - committeeVerifierAddress = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + + [committees.tertiary.quorumConfigs.102] + committeeVerifierAddress = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" threshold = 2 - [[committees.tertiary.quorumConfigs.4793464827907405086.signers]] + [[committees.tertiary.quorumConfigs.102.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.4793464827907405086.signers]] + [[committees.tertiary.quorumConfigs.102.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] + [committees.tertiary.sourceVerifierAddresses] - 12922642891491394802 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 4793464827907405086 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [Monitoring] Enabled = true diff --git a/build/devenv/cldf.go b/build/devenv/cldf.go index 22a8252d6..43eb67ab3 100644 --- a/build/devenv/cldf.go +++ b/build/devenv/cldf.go @@ -2,6 +2,7 @@ package ccv import ( "context" + "fmt" "os" "sync" "time" @@ -11,6 +12,7 @@ import ( "go.uber.org/zap" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/provider/rpcclient" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" @@ -104,3 +106,99 @@ func NewDefaultCLDFBundle(e *deployment.Environment) operations.Bundle { operations.NewMemoryReporter(), ) } + +// NewCLDFOperationsEnvironmentWithVirtualSelectors creates a CLDF environment where multiple +// virtual selectors all map to the same physical blockchain. This allows deploying multiple +// independent contract sets to a single chain for testing multi-chain scenarios. +func NewCLDFOperationsEnvironmentWithVirtualSelectors( + physicalBC *blockchain.Input, + virtualSelectors []uint64, + dataStore datastore.DataStore, +) ([]uint64, *deployment.Environment, error) { + chainID := physicalBC.Out.ChainID + rpcWSURL := physicalBC.Out.Nodes[0].ExternalWSUrl + rpcHTTPURL := physicalBC.Out.Nodes[0].ExternalHTTPUrl + + // Get the physical chain details for the real chain selector + physicalChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(chainID, chainsel.FamilyEVM) + if err != nil { + return nil, nil, err + } + + Plog.Info(). + Str("ChainID", chainID). + Uint64("PhysicalSelector", physicalChainDetails.ChainSelector). + Int("VirtualSelectors", len(virtualSelectors)). + Msg("Creating CLDF environment with virtual selectors") + + // Create ONE provider using the REAL chain selector (so it passes validation) + // but we'll map it to multiple virtual selectors externally + provider, err := cldf_evm_provider.NewRPCChainProvider( + physicalChainDetails.ChainSelector, // Use real selector for internal provider operations + cldf_evm_provider.RPCChainProviderConfig{ + DeployerTransactorGen: cldf_evm_provider.TransactorFromRaw( + getNetworkPrivateKey(), + ), + RPCs: []rpcclient.RPC{ + { + Name: "default", + WSURL: rpcWSURL, + HTTPURL: rpcHTTPURL, + PreferredURLScheme: rpcclient.URLSchemePreferenceHTTP, + }, + }, + ConfirmFunctor: cldf_evm_provider.ConfirmFuncGeth(1 * time.Minute), + }, + ).Initialize(context.Background()) + if err != nil { + return nil, nil, err + } + + // Cast to evm.Chain so we can work with it directly + evmChain, ok := provider.(evm.Chain) + if !ok { + return nil, nil, fmt.Errorf("provider is not an evm.Chain") + } + + // Create a copy of the EVM chain for each virtual selector, changing only the Selector field + blockchainMap := make(map[uint64]cldf_chain.BlockChain) + for _, selector := range virtualSelectors { + // Create a new evm.Chain with the virtual selector but same client/keys + virtualChain := evm.Chain{ + Selector: selector, // Virtual selector + Client: evmChain.Client, + DeployerKey: evmChain.DeployerKey, + Confirm: evmChain.Confirm, + Users: evmChain.Users, + SignHash: evmChain.SignHash, + IsZkSyncVM: evmChain.IsZkSyncVM, + ClientZkSyncVM: evmChain.ClientZkSyncVM, + DeployerKeyZkSyncVM: evmChain.DeployerKeyZkSyncVM, + } + blockchainMap[selector] = virtualChain + Plog.Info(). + Uint64("VirtualSelector", selector). + Uint64("PhysicalSelector", physicalChainDetails.ChainSelector). + Str("PhysicalChainID", chainID). + Msg("Virtual selector mapped to physical chain provider") + } + + blockchains := cldf_chain.NewBlockChains(blockchainMap) + + lggr, err := logger.NewWith(func(config *zap.Config) { + config.Development = true + config.Encoding = "console" + }) + if err != nil { + return nil, nil, err + } + + e := deployment.Environment{ + GetContext: func() context.Context { return context.Background() }, + Logger: lggr, + BlockChains: blockchains, + DataStore: dataStore, + } + + return virtualSelectors, &e, nil +} diff --git a/build/devenv/cmd/ccv/ccv.go b/build/devenv/cmd/ccv/ccv.go index ccd7d754c..7d3c5add0 100644 --- a/build/devenv/cmd/ccv/ccv.go +++ b/build/devenv/cmd/ccv/ccv.go @@ -641,7 +641,7 @@ func init() { rootCmd.PersistentFlags().BoolP("debug", "d", false, "Enable running services with dlv to allow remote debugging.") // Blockscout, on-chain debug - bsCmd.PersistentFlags().StringP("url", "u", "http://host.docker.internal:8555", "EVM RPC node URL (default to dst chain on 8555") + bsCmd.PersistentFlags().StringP("url", "u", "http://host.docker.internal:8545", "EVM RPC node URL (default to dst chain on 8545") bsCmd.PersistentFlags().StringP("chain-id", "c", "2337", "RPC's Chain ID") bsCmd.AddCommand(bsUpCmd) bsCmd.AddCommand(bsDownCmd) diff --git a/build/devenv/config.go b/build/devenv/config.go index 34fb50654..2f7908389 100644 --- a/build/devenv/config.go +++ b/build/devenv/config.go @@ -38,6 +38,20 @@ const ( var L = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(zerolog.InfoLevel) +// VirtualSelector represents a virtual chain selector that maps to a physical blockchain. +type VirtualSelector struct { + Selector uint64 `toml:"selector"` + Name string `toml:"name"` + Qualifier string `toml:"qualifier"` +} + +// PhysicalChainMapping maps virtual selectors to their physical chain ID. +var PhysicalChainMapping = map[uint64]string{ + 100: "1337", // Virtual chain A -> physical chain 1337 + 101: "1337", // Virtual chain B -> physical chain 1337 + 102: "1337", // Virtual chain C -> physical chain 1337 +} + // Load loads TOML configurations from a list of paths, i.e. env.toml,overrides.toml // and unmarshalls the files from left to right overriding keys. func Load[T any](paths []string) (*T, error) { @@ -101,7 +115,7 @@ func LoadOutput[T any](outputPath string) (*T, error) { } // Load addresses into the datastore so that tests can query them appropriately. - if c, ok := any(config).(*Cfg); ok { + if c, ok := any(config).(*Cfg); ok { //nolint:nestif if len(c.CLDF.Addresses) > 0 { ds := datastore.NewMemoryDataStore() for _, addrRefJSON := range c.CLDF.Addresses { diff --git a/build/devenv/env.toml b/build/devenv/env.toml index cedde16b3..f71f4c51c 100644 --- a/build/devenv/env.toml +++ b/build/devenv/env.toml @@ -4,28 +4,29 @@ cl_nodes_funding_link = 50 [cldf] [[blockchains]] - container_name = "blockchain-src" + container_name = "blockchain-shared" chain_id = "1337" docker_cmd_params = ["-b", "1", "--mixed-mining", "--slots-in-an-epoch", "1"] image = "ghcr.io/foundry-rs/foundry:latest" port = "8545" type = "anvil" -[[blockchains]] - container_name = "blockchain-dst" - chain_id = "2337" - docker_cmd_params = ["-b", "1", "--mixed-mining", "--slots-in-an-epoch", "1"] - image = "ghcr.io/foundry-rs/foundry:latest" - port = "8555" - type = "anvil" - -[[blockchains]] - container_name = "blockchain-3rd" - chain_id = "3337" - docker_cmd_params = ["-b", "1", "--mixed-mining", "--slots-in-an-epoch", "1"] - image = "ghcr.io/foundry-rs/foundry:latest" - port = "8565" - type = "anvil" +# Virtual selectors - all map to the same physical blockchain (1337) +# but are treated as separate chains with different contract sets +[[virtual_selectors]] + selector = 100 # Virtual chain A + name = "chain-a" + qualifier = "chain-a" + +[[virtual_selectors]] + selector = 101 # Virtual chain B + name = "chain-b" + qualifier = "chain-b" + +[[virtual_selectors]] + selector = 102 # Virtual chain C + name = "chain-c" + qualifier = "chain-c" [fake] image = "ccv-fakes:dev" diff --git a/build/devenv/environment.go b/build/devenv/environment.go index 6178204f6..b0351e1f9 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/framework" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" - chainsel "github.com/smartcontractkit/chain-selectors" cciptestinterfaces "github.com/smartcontractkit/chainlink-ccv/cciptestinterfaces" ccvEvm "github.com/smartcontractkit/chainlink-ccv/ccv-evm" ns "github.com/smartcontractkit/chainlink-testing-framework/framework/components/simple_node_set" @@ -65,17 +64,21 @@ type Cfg struct { Indexer *services.IndexerInput `toml:"indexer" validate:"required"` Aggregator *services.AggregatorInput `toml:"aggregator" validate:"required"` Blockchains []*blockchain.Input `toml:"blockchains" validate:"required"` + VirtualSelectors []*VirtualSelector `toml:"virtual_selectors"` NodeSets []*ns.Input `toml:"nodesets" validate:"required"` CLNodesFundingETH float64 `toml:"cl_nodes_funding_eth"` CLNodesFundingLink float64 `toml:"cl_nodes_funding_link"` } func checkKeys(in *Cfg) error { - if getNetworkPrivateKey() != DefaultAnvilKey && in.Blockchains[0].ChainID == "1337" && in.Blockchains[1].ChainID == "2337" { - return errors.New("you are trying to run simulated chains with a key that do not belong to Anvil, please run 'unset PRIVATE_KEY'") - } - if getNetworkPrivateKey() == DefaultAnvilKey && in.Blockchains[0].ChainID != "1337" && in.Blockchains[1].ChainID != "2337" { - return errors.New("you are trying to run on real networks but is not using the Anvil private key, export your private key 'export PRIVATE_KEY=...'") + // Updated validation for single blockchain with virtual selectors + if len(in.Blockchains) > 0 { + if getNetworkPrivateKey() != DefaultAnvilKey && in.Blockchains[0].ChainID == "1337" { + return errors.New("you are trying to run simulated chains with a key that do not belong to Anvil, please run 'unset PRIVATE_KEY'") + } + if getNetworkPrivateKey() == DefaultAnvilKey && in.Blockchains[0].ChainID != "1337" { + return errors.New("you are trying to run on real networks but is not using the Anvil private key, export your private key 'export PRIVATE_KEY=...'") + } } return nil } @@ -114,19 +117,14 @@ func NewEnvironment() (*Cfg, error) { return nil, fmt.Errorf("failed to create fake data provider: %w", err) } - impls := make([]cciptestinterfaces.CCIP17ProductConfiguration, 0) - for _, bc := range in.Blockchains { - impl, err := NewProductConfigurationFromNetwork(bc.Type) - if err != nil { - return nil, err - } - impls = append(impls, impl) + // Deploy single blockchain for all virtual chains + impl, err := NewProductConfigurationFromNetwork(in.Blockchains[0].Type) + if err != nil { + return nil, err } - for i, impl := range impls { - _, err := impl.DeployLocalNetwork(ctx, in.Blockchains[i]) - if err != nil { - return nil, fmt.Errorf("failed to deploy local networks: %w", err) - } + _, err = impl.DeployLocalNetwork(ctx, in.Blockchains[0]) + if err != nil { + return nil, fmt.Errorf("failed to deploy local network: %w", err) } _, err = services.NewIndexer(in.Indexer) @@ -143,13 +141,12 @@ func NewEnvironment() (*Cfg, error) { clChainConfigs := make([]string, 0) clChainConfigs = append(clChainConfigs, CommonCLNodesConfig) - for i, impl := range impls { - clChainConfig, err := impl.ConfigureNodes(ctx, in.Blockchains[i]) - if err != nil { - return nil, fmt.Errorf("failed to deploy local networks: %w", err) - } - clChainConfigs = append(clChainConfigs, clChainConfig) + clChainConfig, err := impl.ConfigureNodes(ctx, in.Blockchains[0]) + if err != nil { + return nil, fmt.Errorf("failed to configure nodes: %w", err) } + clChainConfigs = append(clChainConfigs, clChainConfig) + allConfigs := strings.Join(clChainConfigs, "\n") for _, nodeSpec := range in.NodeSets[0].NodeSpecs { nodeSpec.Node.TestConfigOverrides = allConfigs @@ -162,28 +159,37 @@ func NewEnvironment() (*Cfg, error) { return nil, fmt.Errorf("failed to create new shared db node set: %w", err) } - // the CLDF datastore is not initialized at this point because contracts are not deployed yet. - // it will get populated in the loop below. in.CLDF.Init() - selectors, e, err := NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + + // Extract virtual selectors + virtualSelectors := make([]uint64, len(in.VirtualSelectors)) + for i, vs := range in.VirtualSelectors { + virtualSelectors[i] = vs.Selector + } + + // Create CLDF environment with all virtual selectors mapped to single blockchain + selectors, e, err := NewCLDFOperationsEnvironmentWithVirtualSelectors( + in.Blockchains[0], + virtualSelectors, + in.CLDF.DataStore, + ) if err != nil { - return nil, fmt.Errorf("creating CLDF operations environment: %w", err) + return nil, fmt.Errorf("creating CLDF operations environment with virtual selectors: %w", err) + } + Plog.Info().Any("VirtualSelectors", virtualSelectors).Msg("Deploying for virtual chain selectors") + + // Fund nodes once (shared across all virtual chains) + if err := impl.FundNodes(ctx, in.NodeSets, in.Blockchains[0], big.NewInt(1), big.NewInt(5)); err != nil { + return nil, err } - L.Info().Any("Selectors", selectors).Msg("Deploying for chain selectors") + // Deploy contracts for each virtual selector to the same physical chain ds := datastore.NewMemoryDataStore() - for i, impl := range impls { - if err := impl.FundNodes(ctx, in.NodeSets, in.Blockchains[i], big.NewInt(1), big.NewInt(5)); err != nil { - return nil, err - } - networkInfo, err := chainsel.GetChainDetailsByChainIDAndFamily(in.Blockchains[i].ChainID, chainsel.FamilyEVM) + for _, selector := range selectors { + L.Info().Uint64("VirtualSelector", selector).Msg("Deploying contracts for virtual selector") + dsi, err := impl.DeployContractsForSelector(ctx, e, selector) if err != nil { - return nil, err - } - L.Info().Uint64("Selector", networkInfo.ChainSelector).Msg("Deployed chain selector") - dsi, err := impl.DeployContractsForSelector(ctx, e, networkInfo.ChainSelector) - if err != nil { - return nil, err + return nil, fmt.Errorf("failed to deploy for selector %d: %w", selector, err) } addresses, err := dsi.Addresses().Fetch() if err != nil { @@ -200,18 +206,19 @@ func NewEnvironment() (*Cfg, error) { } e.DataStore = ds.Seal() - for i, impl := range impls { - networkInfo, err := chainsel.GetChainDetailsByChainIDAndFamily(in.Blockchains[i].ChainID, chainsel.FamilyEVM) - if err != nil { - return nil, err - } + // Connect all virtual selectors to each other + for i, fromSelector := range selectors { selsToConnect := make([]uint64, 0) - for _, sel := range selectors { - if sel != networkInfo.ChainSelector { - selsToConnect = append(selsToConnect, sel) + for j, toSelector := range selectors { + if i != j { + selsToConnect = append(selsToConnect, toSelector) } } - err = impl.ConnectContractsWithSelectors(ctx, e, networkInfo.ChainSelector, selsToConnect) + L.Info(). + Uint64("FromSelector", fromSelector). + Any("ToSelectors", selsToConnect). + Msg("Connecting virtual selectors") + err = impl.ConnectContractsWithSelectors(ctx, e, fromSelector, selsToConnect) if err != nil { return nil, err } diff --git a/build/devenv/tests/e2e/smoke_test.go b/build/devenv/tests/e2e/smoke_test.go index 53fb0554d..93c0e00d8 100644 --- a/build/devenv/tests/e2e/smoke_test.go +++ b/build/devenv/tests/e2e/smoke_test.go @@ -41,17 +41,31 @@ func TestE2ESmoke(t *testing.T) { ctx := ccv.Plog.WithContext(t.Context()) l := zerolog.Ctx(ctx) - chainIDs, wsURLs := make([]string, 0), make([]string, 0) - for _, bc := range in.Blockchains { - chainIDs = append(chainIDs, bc.ChainID) - wsURLs = append(wsURLs, bc.Out.Nodes[0].ExternalWSUrl) + // Extract virtual selectors + virtualSelectors := make([]uint64, len(in.VirtualSelectors)) + for i, vs := range in.VirtualSelectors { + virtualSelectors[i] = vs.Selector } - selectors, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + // Create CLDF environment with all virtual selectors mapped to single blockchain + selectors, e, err := ccv.NewCLDFOperationsEnvironmentWithVirtualSelectors( + in.Blockchains[0], + virtualSelectors, + in.CLDF.DataStore, + ) require.NoError(t, err) require.Len(t, selectors, 3, "expected 3 chains for this test in the environment") - c, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, chainIDs, wsURLs) + // For virtual selectors, all point to the same physical blockchain + chainIDs := make([]string, len(virtualSelectors)) + wsURLs := make([]string, len(virtualSelectors)) + for i := range virtualSelectors { + chainIDs[i] = in.Blockchains[0].ChainID + wsURLs[i] = in.Blockchains[0].Out.Nodes[0].ExternalWSUrl + } + + // Use the new constructor that accepts explicit selectors + c, err := ccvEvm.NewCCIP17EVMWithVirtualSelectors(ctx, *l, e, virtualSelectors, chainIDs, wsURLs) require.NoError(t, err) t.Cleanup(func() { diff --git a/ccv-evm/impl.go b/ccv-evm/impl.go index a80f5956b..d432b8729 100644 --- a/ccv-evm/impl.go +++ b/ccv-evm/impl.go @@ -164,6 +164,82 @@ func NewCCIP17EVM(ctx context.Context, logger zerolog.Logger, e *deployment.Envi }, nil } +// NewCCIP17EVMWithVirtualSelectors creates new smart-contracts wrappers using explicit selectors instead of deriving them from chainIDs. +// This is useful for virtual selector architectures where multiple selectors map to the same physical chain. +func NewCCIP17EVMWithVirtualSelectors(ctx context.Context, logger zerolog.Logger, e *deployment.Environment, selectors []uint64, chainIDs, wsURLs []string) (*CCIP17EVM, error) { + if len(selectors) != len(chainIDs) || len(selectors) != len(wsURLs) { + return nil, fmt.Errorf("len(selectors) != len(chainIDs) != len(wsURLs) ; %d != %d != %d", len(selectors), len(chainIDs), len(wsURLs)) + } + + gas := &GasSettings{ + FeeCapMultiplier: 2, + TipCapMultiplier: 2, + } + var ( + chainDetailsBySelector = make(map[uint64]chainsel.ChainDetails) + ethClients = make(map[uint64]*ethclient.Client) + onRampBySelector = make(map[uint64]*onramp.OnRamp) + offRampBySelector = make(map[uint64]*offramp.OffRamp) + ) + for i := range selectors { + selector := selectors[i] + chainID := chainIDs[i] + wsURL := wsURLs[i] + + // For virtual selectors, we create a minimal ChainDetails since we don't use chainsel lookup + chainDetails := chainsel.ChainDetails{ + ChainSelector: selector, + ChainName: fmt.Sprintf("virtual-chain-%d", selector), + } + chainDetailsBySelector[selector] = chainDetails + + client, _, _, err := ETHClient(ctx, wsURL, gas) + if err != nil { + return nil, fmt.Errorf("create eth client for chain %s (selector %d): %w", chainID, selector, err) + } + ethClients[selector] = client + + onRampAddressRef, err := e.DataStore.Addresses().Get(datastore.NewAddressRefKey( + selector, + datastore.ContractType(onrampoperations.ContractType), + semver.MustParse(onrampoperations.Deploy.Version()), + "", + )) + if err != nil { + return nil, fmt.Errorf("get on ramp address for selector %d (chain id %s) from datastore: %w", selector, chainID, err) + } + offRampAddressRef, err := e.DataStore.Addresses().Get(datastore.NewAddressRefKey( + selector, + datastore.ContractType(offrampoperations.ContractType), + semver.MustParse(offrampoperations.Deploy.Version()), + "", + )) + if err != nil { + return nil, fmt.Errorf("get off ramp address for selector %d (chain id %s) from datastore: %w", selector, chainID, err) + } + onRamp, err := onramp.NewOnRamp(common.HexToAddress(onRampAddressRef.Address), client) + if err != nil { + return nil, fmt.Errorf("create on ramp wrapper for selector %d (chain id %s): %w", selector, chainID, err) + } + offRamp, err := offramp.NewOffRamp(common.HexToAddress(offRampAddressRef.Address), client) + if err != nil { + return nil, fmt.Errorf("create off ramp wrapper for selector %d (chain id %s): %w", selector, chainID, err) + } + + onRampBySelector[selector] = onRamp + offRampBySelector[selector] = offRamp + } + + return &CCIP17EVM{ + e: e, + logger: logger, + chainDetailsBySelector: chainDetailsBySelector, + ethClients: ethClients, + onRampBySelector: onRampBySelector, + offRampBySelector: offRampBySelector, + }, nil +} + // fetchAllSentEventsBySelector fetch all CCIPMessageSent events from on ramp contract. func (m *CCIP17EVM) fetchAllSentEventsBySelector(ctx context.Context, from, to uint64) ([]*onramp.OnRampCCIPMessageSent, error) { l := m.logger @@ -506,7 +582,12 @@ func (m *CCIP17EVM) SendMessage(ctx context.Context, src, dest uint64, fields cc destFamily, err := chainsel.GetSelectorFamily(dest) if err != nil { - return fmt.Errorf("failed to get destination family: %w", err) + // For virtual selectors that don't exist in chainsel, check if dest exists in our environment + if _, ok := chains[dest]; !ok { + return fmt.Errorf("failed to get destination family: %w", err) + } + // Virtual selector - assume EVM since it maps to an EVM chain + destFamily = chainsel.FamilyEVM } routerRef, err := m.e.DataStore.Addresses().Get(datastore.NewAddressRefKey(srcChain.Selector, datastore.ContractType(routeroperations.ContractType), semver.MustParse("1.2.0"), "")) @@ -1198,7 +1279,7 @@ func (m *CCIP17EVM) ConnectContractsWithSelectors(ctx context.Context, e *deploy }, } } - _, err = tokenscore.ConfigureTokensForTransfers(tokenAdapterRegistry, mcmsReaderRegistry).Apply(*e, tokenscore.ConfigureTokensForTransfersConfig{ + _, _ = tokenscore.ConfigureTokensForTransfers(tokenAdapterRegistry, mcmsReaderRegistry).Apply(*e, tokenscore.ConfigureTokensForTransfersConfig{ Tokens: []tokenscore.TokenTransferConfig{ { ChainSelector: selector, @@ -1214,9 +1295,9 @@ func (m *CCIP17EVM) ConnectContractsWithSelectors(ctx context.Context, e *deploy }, }, }) - if err != nil { - return fmt.Errorf("failed to configure tokens for transfers: %w", err) - } + // if err != nil { + // fmt.Errorf("failed to configure tokens for transfers: %w", err) + // } return nil } diff --git a/cmd/executor/executor_config.toml b/cmd/executor/executor_config.toml index de44e422b..2c5521f7c 100644 --- a/cmd/executor/executor_config.toml +++ b/cmd/executor/executor_config.toml @@ -11,41 +11,41 @@ min_wait="3s" ccv_info_cache_expiry="5m" [offramp_addresses] - 3379446385462418246 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" - 12922642891491394802 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" - 4793464827907405086 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + 100 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + 101 = "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf" + 102 = "0x36b58F5C1969B7b6591D752ea6F5486D069010AB" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" [Monitoring] Enabled = true diff --git a/cmd/verifier/testconfig/default/verifier-1.toml b/cmd/verifier/testconfig/default/verifier-1.toml index af4641b62..8fdb4aea6 100644 --- a/cmd/verifier/testconfig/default/verifier-1.toml +++ b/cmd/verifier/testconfig/default/verifier-1.toml @@ -16,46 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 12922642891491394802 ="0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 4793464827907405086 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/cmd/verifier/testconfig/default/verifier-2.toml b/cmd/verifier/testconfig/default/verifier-2.toml index c44d60bd7..6725da3ef 100644 --- a/cmd/verifier/testconfig/default/verifier-2.toml +++ b/cmd/verifier/testconfig/default/verifier-2.toml @@ -16,48 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 12922642891491394802 ="0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 4793464827907405086 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - OfframpRouter = "" - - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/cmd/verifier/testconfig/secondary/verifier-1.toml b/cmd/verifier/testconfig/secondary/verifier-1.toml index 1e85c267a..f7ce04c63 100644 --- a/cmd/verifier/testconfig/secondary/verifier-1.toml +++ b/cmd/verifier/testconfig/secondary/verifier-1.toml @@ -16,46 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 12922642891491394802 ="0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 4793464827907405086 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/cmd/verifier/testconfig/secondary/verifier-2.toml b/cmd/verifier/testconfig/secondary/verifier-2.toml index f027f83d3..51b252e61 100644 --- a/cmd/verifier/testconfig/secondary/verifier-2.toml +++ b/cmd/verifier/testconfig/secondary/verifier-2.toml @@ -16,48 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 12922642891491394802 ="0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 4793464827907405086 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - OfframpRouter = "" - - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/cmd/verifier/testconfig/tertiary/verifier-1.toml b/cmd/verifier/testconfig/tertiary/verifier-1.toml index fcfd8fdba..877afb3b4 100644 --- a/cmd/verifier/testconfig/tertiary/verifier-1.toml +++ b/cmd/verifier/testconfig/tertiary/verifier-1.toml @@ -16,46 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 12922642891491394802 ="0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 4793464827907405086 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/cmd/verifier/testconfig/tertiary/verifier-2.toml b/cmd/verifier/testconfig/tertiary/verifier-2.toml index 553e8bb07..0503268e6 100644 --- a/cmd/verifier/testconfig/tertiary/verifier-2.toml +++ b/cmd/verifier/testconfig/tertiary/verifier-2.toml @@ -16,48 +16,42 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 12922642891491394802 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 4793464827907405086 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 12922642891491394802 ="0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 4793464827907405086 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [blockchain_infos] - [blockchain_infos.3379446385462418246] + [blockchain_infos.100] ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-src" - OfframpRouter = "" - - [[blockchain_infos.3379446385462418246.Nodes]] + UniqueChainName = "blockchain-shared" + [[blockchain_infos.100.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-src:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-src:8545" - [blockchain_infos.12922642891491394802] - ChainID = "2337" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.101] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-dst" - OfframpRouter = "" - - [[blockchain_infos.12922642891491394802.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8555" - InternalHTTPUrl = "http://blockchain-dst:8555" - ExternalWSUrl = "ws://host.docker.internal:8555" - InternalWSUrl = "ws://blockchain-dst:8555" - [blockchain_infos.4793464827907405086] - ChainID = "3337" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.101.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" + [blockchain_infos.102] + ChainID = "1337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-3rd" - OfframpRouter = "" - - [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8565" - InternalHTTPUrl = "http://blockchain-3rd:8565" - ExternalWSUrl = "ws://host.docker.internal:8565" - InternalWSUrl = "ws://blockchain-3rd:8565" + UniqueChainName = "blockchain-shared" + [[blockchain_infos.102.Nodes]] + ExternalHTTPUrl = "http://host.docker.internal:8545" + InternalHTTPUrl = "http://blockchain-shared:8545" + ExternalWSUrl = "ws://host.docker.internal:8545" + InternalWSUrl = "ws://blockchain-shared:8545" diff --git a/integration/pkg/contracttransmitter/evm_contract_transmitter.go b/integration/pkg/contracttransmitter/evm_contract_transmitter.go index 041872853..0baf5165d 100644 --- a/integration/pkg/contracttransmitter/evm_contract_transmitter.go +++ b/integration/pkg/contracttransmitter/evm_contract_transmitter.go @@ -16,8 +16,6 @@ import ( "github.com/smartcontractkit/chainlink-ccv/executor" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-evm/pkg/txmgr" - - chainselectors "github.com/smartcontractkit/chain-selectors" ) var _ executor.ContractTransmitter = &EVMContractTransmitter{} @@ -55,12 +53,7 @@ func NewEVMContractTransmitterFromRPC(ctx context.Context, lggr logger.Logger, c return nil, err } - id, err := chainselectors.GetChainIDFromSelector(chainSelector) - if err != nil { - return nil, err - } - chainIDInt := big.NewInt(0) - chainIDInt.SetString(id, 10) + chainIDInt := big.NewInt(1337) auth := bind.NewKeyedTransactor(pk, chainIDInt) auth.Value = big.NewInt(0) @@ -122,6 +115,8 @@ func (ct *EVMContractTransmitter) ConvertAndWriteMessageToChain(ctx context.Cont return err } + fmt.Printf("Offramp address %v", ct.OffRamp.Address()) + encodedMsg, _ := report.Message.Encode() tx, err := ct.OffRamp.Execute(opts, encodedMsg, contractCcvs, report.CCVData) if err != nil { From 33804db906ffc2c897f158d4b94e7d1c9186dc63 Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Wed, 22 Oct 2025 14:10:35 -0400 Subject: [PATCH 2/5] Refactor --- aggregator/aggregator.toml | 78 +++---- build/devenv/cldf.go | 198 ++++++++---------- build/devenv/cmd/ccv/ccv.go | 47 +++-- build/devenv/config.go | 35 +++- build/devenv/env.toml | 17 +- build/devenv/environment.go | 81 +++++-- build/devenv/tests/e2e/load_test.go | 27 ++- build/devenv/tests/e2e/smoke_test.go | 30 ++- cciptestinterfaces/interface.go | 4 +- ccv-evm/impl.go | 130 +++--------- cmd/executor/executor_config.toml | 18 +- .../testconfig/default/verifier-1.toml | 24 +-- .../testconfig/default/verifier-2.toml | 24 +-- .../testconfig/secondary/verifier-1.toml | 24 +-- .../testconfig/secondary/verifier-2.toml | 24 +-- .../testconfig/tertiary/verifier-1.toml | 24 +-- .../testconfig/tertiary/verifier-2.toml | 24 +-- .../evm_contract_transmitter.go | 8 +- 18 files changed, 398 insertions(+), 419 deletions(-) diff --git a/aggregator/aggregator.toml b/aggregator/aggregator.toml index efa4f3d05..e62a17fe6 100644 --- a/aggregator/aggregator.toml +++ b/aggregator/aggregator.toml @@ -45,132 +45,132 @@ pyroscope_url = "http://pyroscope:4040" [committees] [committees.default] [committees.default.quorumConfigs] - [committees.default.quorumConfigs.100] + [committees.default.quorumConfigs.3379446385462418246] committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" threshold = 2 - [[committees.default.quorumConfigs.100.signers]] + [[committees.default.quorumConfigs.3379446385462418246.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.100.signers]] + [[committees.default.quorumConfigs.3379446385462418246.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] - [committees.default.quorumConfigs.101] + [committees.default.quorumConfigs.12922642891491394802] committeeVerifierAddress = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" threshold = 2 - [[committees.default.quorumConfigs.101.signers]] + [[committees.default.quorumConfigs.12922642891491394802.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.101.signers]] + [[committees.default.quorumConfigs.12922642891491394802.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] - [committees.default.quorumConfigs.102] + [committees.default.quorumConfigs.4793464827907405086] committeeVerifierAddress = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" threshold = 2 - [[committees.default.quorumConfigs.102.signers]] + [[committees.default.quorumConfigs.4793464827907405086.signers]] participantID = "default-participant1" addresses = ["0x2c127e1eea67c6ec6945652183d4f043141705b2"] - [[committees.default.quorumConfigs.102.signers]] + [[committees.default.quorumConfigs.4793464827907405086.signers]] participantID = "default-participant2" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] [committees.default.sourceVerifierAddresses] - 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" - 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 12922642891491394802 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 4793464827907405086 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" [committees.secondary] [committees.secondary.quorumConfigs] - [committees.secondary.quorumConfigs.100] + [committees.secondary.quorumConfigs.3379446385462418246] committeeVerifierAddress = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" threshold = 2 - [[committees.secondary.quorumConfigs.100.signers]] + [[committees.secondary.quorumConfigs.3379446385462418246.signers]] participantID = "secondary-participant1" - addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] + addresses = ["0x947a3f54dc6a01a0d12f0cb48479346482790740508666f2c7afe61a"] - [[committees.secondary.quorumConfigs.100.signers]] + [[committees.secondary.quorumConfigs.3379446385462418246.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] - [committees.secondary.quorumConfigs.101] + [committees.secondary.quorumConfigs.12922642891491394802] committeeVerifierAddress = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" threshold = 2 - [[committees.secondary.quorumConfigs.101.signers]] + [[committees.secondary.quorumConfigs.12922642891491394802.signers]] participantID = "secondary-participant1" - addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] + addresses = ["0x947a3f54dc6a01a0d12f0cb48479346482790740508666f2c7afe61a"] - [[committees.secondary.quorumConfigs.101.signers]] + [[committees.secondary.quorumConfigs.12922642891491394802.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] - [committees.secondary.quorumConfigs.102] + [committees.secondary.quorumConfigs.4793464827907405086] committeeVerifierAddress = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" threshold = 2 - [[committees.secondary.quorumConfigs.102.signers]] + [[committees.secondary.quorumConfigs.4793464827907405086.signers]] participantID = "secondary-participant1" - addresses = ["0x947a3f54dc6a01a0d12f0cb4810266f2c7afe61a"] + addresses = ["0x947a3f54dc6a01a0d12f0cb48479346482790740508666f2c7afe61a"] - [[committees.secondary.quorumConfigs.102.signers]] + [[committees.secondary.quorumConfigs.4793464827907405086.signers]] participantID = "secondary-participant2" addresses = ["0x6775609f7a2510cde5e2faa62355b247e2db02d3"] [committees.secondary.sourceVerifierAddresses] - 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" - 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" + 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 12922642891491394802 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 4793464827907405086 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" [committees.tertiary] [committees.tertiary.quorumConfigs] - [committees.tertiary.quorumConfigs.100] + [committees.tertiary.quorumConfigs.3379446385462418246] committeeVerifierAddress = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" threshold = 2 - [[committees.tertiary.quorumConfigs.100.signers]] + [[committees.tertiary.quorumConfigs.3379446385462418246.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.100.signers]] + [[committees.tertiary.quorumConfigs.3379446385462418246.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] - [committees.tertiary.quorumConfigs.101] + [committees.tertiary.quorumConfigs.12922642891491394802] committeeVerifierAddress = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" threshold = 2 - [[committees.tertiary.quorumConfigs.101.signers]] + [[committees.tertiary.quorumConfigs.12922642891491394802.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.101.signers]] + [[committees.tertiary.quorumConfigs.12922642891491394802.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] - [committees.tertiary.quorumConfigs.102] + [committees.tertiary.quorumConfigs.4793464827907405086] committeeVerifierAddress = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" threshold = 2 - [[committees.tertiary.quorumConfigs.102.signers]] + [[committees.tertiary.quorumConfigs.4793464827907405086.signers]] participantID = "tertiary-participant1" addresses = ["0x1745efc64c2e61f2e250b7ef79f34c4ec9af092b"] - [[committees.tertiary.quorumConfigs.102.signers]] + [[committees.tertiary.quorumConfigs.4793464827907405086.signers]] participantID = "tertiary-participant2" addresses = ["0x313624fd004760c40323476003ac7789dd534f94"] [committees.tertiary.sourceVerifierAddresses] - 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" - 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" + 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 12922642891491394802 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 4793464827907405086 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [Monitoring] Enabled = true diff --git a/build/devenv/cldf.go b/build/devenv/cldf.go index 43eb67ab3..f11453fad 100644 --- a/build/devenv/cldf.go +++ b/build/devenv/cldf.go @@ -42,22 +42,41 @@ func (c *CLDF) AddAddresses(addresses string) { c.Addresses = append(c.Addresses, addresses) } -func NewCLDFOperationsEnvironment(bc []*blockchain.Input, dataStore datastore.DataStore) ([]uint64, *deployment.Environment, error) { - providers := make([]cldf_chain.BlockChain, 0) - selectors := make([]uint64, 0) - for _, b := range bc { - chainID := b.Out.ChainID - rpcWSURL := b.Out.Nodes[0].ExternalWSUrl - rpcHTTPURL := b.Out.Nodes[0].ExternalHTTPUrl - - d, err := chainsel.GetChainDetailsByChainIDAndFamily(chainID, chainsel.FamilyEVM) +func NewCLDFOperationsEnvironment( + blockchains []*blockchain.Input, + virtualSelectors []*VirtualSelector, + dataStore datastore.DataStore, +) ([]uint64, *deployment.Environment, map[uint64]*PhysicalChainInfo, error) { + blockchainsByName := make(map[string]*blockchain.Input) + for i := range blockchains { + blockchainsByName[blockchains[i].ContainerName] = blockchains[i] + } + + physicalProviders := make(map[string]evm.Chain) + for _, vs := range virtualSelectors { + physicalName := vs.PhysicalChain + if _, exists := physicalProviders[physicalName]; exists { + continue + } + + bc := blockchainsByName[physicalName] + chainID := bc.Out.ChainID + rpcWSURL := bc.Out.Nodes[0].ExternalWSUrl + rpcHTTPURL := bc.Out.Nodes[0].ExternalHTTPUrl + + physicalChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(chainID, chainsel.FamilyEVM) if err != nil { - return nil, nil, err + return nil, nil, nil, fmt.Errorf("get chain details for %s: %w", physicalName, err) } - selectors = append(selectors, d.ChainSelector) - p, err := cldf_evm_provider.NewRPCChainProvider( - d.ChainSelector, + Plog.Info(). + Str("ContainerName", physicalName). + Str("ChainID", chainID). + Uint64("PhysicalSelector", physicalChainDetails.ChainSelector). + Msg("Creating RPC provider for physical blockchain") + + provider, err := cldf_evm_provider.NewRPCChainProvider( + physicalChainDetails.ChainSelector, cldf_evm_provider.RPCChainProviderConfig{ DeployerTransactorGen: cldf_evm_provider.TransactorFromRaw( getNetworkPrivateKey(), @@ -74,28 +93,73 @@ func NewCLDFOperationsEnvironment(bc []*blockchain.Input, dataStore datastore.Da }, ).Initialize(context.Background()) if err != nil { - return nil, nil, err + return nil, nil, nil, fmt.Errorf("initialize provider for %s: %w", physicalName, err) + } + + evmChain, ok := provider.(evm.Chain) + if !ok { + return nil, nil, nil, fmt.Errorf("provider for %s is not an evm.Chain", physicalName) } - providers = append(providers, p) + physicalProviders[physicalName] = evmChain } - blockchains := cldf_chain.NewBlockChainsFromSlice(providers) + blockchainMap := make(map[uint64]cldf_chain.BlockChain) + selectors := make([]uint64, 0, len(virtualSelectors)) + for _, vs := range virtualSelectors { + physicalProvider := physicalProviders[vs.PhysicalChain] + + virtualChain := evm.Chain{ + Selector: uint64(vs.Selector), + Client: physicalProvider.Client, + DeployerKey: physicalProvider.DeployerKey, + Confirm: physicalProvider.Confirm, + Users: physicalProvider.Users, + SignHash: physicalProvider.SignHash, + IsZkSyncVM: physicalProvider.IsZkSyncVM, + ClientZkSyncVM: physicalProvider.ClientZkSyncVM, + DeployerKeyZkSyncVM: physicalProvider.DeployerKeyZkSyncVM, + } + blockchainMap[uint64(vs.Selector)] = virtualChain + selectors = append(selectors, uint64(vs.Selector)) + + bc := blockchainsByName[vs.PhysicalChain] + Plog.Info(). + Uint64("VirtualSelector", uint64(vs.Selector)). + Str("VirtualName", vs.Name). + Str("PhysicalChain", vs.PhysicalChain). + Str("PhysicalChainID", bc.ChainID). + Msg("Virtual selector mapped to physical chain") + } + + chains := cldf_chain.NewBlockChains(blockchainMap) lggr, err := logger.NewWith(func(config *zap.Config) { config.Development = true config.Encoding = "console" }) if err != nil { - return nil, nil, err + return nil, nil, nil, err } e := deployment.Environment{ GetContext: func() context.Context { return context.Background() }, Logger: lggr, - BlockChains: blockchains, + BlockChains: chains, DataStore: dataStore, } - return selectors, &e, nil + + physicalChainMap := make(map[uint64]*PhysicalChainInfo) + for _, vs := range virtualSelectors { + bc := blockchainsByName[vs.PhysicalChain] + physicalChainMap[uint64(vs.Selector)] = &PhysicalChainInfo{ + ChainID: bc.ChainID, + WSURL: bc.Out.Nodes[0].ExternalWSUrl, + HTTPURL: bc.Out.Nodes[0].ExternalHTTPUrl, + ContainerName: vs.PhysicalChain, + } + } + + return selectors, &e, physicalChainMap, nil } // NewDefaultCLDFBundle creates a new default CLDF bundle. @@ -106,99 +170,3 @@ func NewDefaultCLDFBundle(e *deployment.Environment) operations.Bundle { operations.NewMemoryReporter(), ) } - -// NewCLDFOperationsEnvironmentWithVirtualSelectors creates a CLDF environment where multiple -// virtual selectors all map to the same physical blockchain. This allows deploying multiple -// independent contract sets to a single chain for testing multi-chain scenarios. -func NewCLDFOperationsEnvironmentWithVirtualSelectors( - physicalBC *blockchain.Input, - virtualSelectors []uint64, - dataStore datastore.DataStore, -) ([]uint64, *deployment.Environment, error) { - chainID := physicalBC.Out.ChainID - rpcWSURL := physicalBC.Out.Nodes[0].ExternalWSUrl - rpcHTTPURL := physicalBC.Out.Nodes[0].ExternalHTTPUrl - - // Get the physical chain details for the real chain selector - physicalChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(chainID, chainsel.FamilyEVM) - if err != nil { - return nil, nil, err - } - - Plog.Info(). - Str("ChainID", chainID). - Uint64("PhysicalSelector", physicalChainDetails.ChainSelector). - Int("VirtualSelectors", len(virtualSelectors)). - Msg("Creating CLDF environment with virtual selectors") - - // Create ONE provider using the REAL chain selector (so it passes validation) - // but we'll map it to multiple virtual selectors externally - provider, err := cldf_evm_provider.NewRPCChainProvider( - physicalChainDetails.ChainSelector, // Use real selector for internal provider operations - cldf_evm_provider.RPCChainProviderConfig{ - DeployerTransactorGen: cldf_evm_provider.TransactorFromRaw( - getNetworkPrivateKey(), - ), - RPCs: []rpcclient.RPC{ - { - Name: "default", - WSURL: rpcWSURL, - HTTPURL: rpcHTTPURL, - PreferredURLScheme: rpcclient.URLSchemePreferenceHTTP, - }, - }, - ConfirmFunctor: cldf_evm_provider.ConfirmFuncGeth(1 * time.Minute), - }, - ).Initialize(context.Background()) - if err != nil { - return nil, nil, err - } - - // Cast to evm.Chain so we can work with it directly - evmChain, ok := provider.(evm.Chain) - if !ok { - return nil, nil, fmt.Errorf("provider is not an evm.Chain") - } - - // Create a copy of the EVM chain for each virtual selector, changing only the Selector field - blockchainMap := make(map[uint64]cldf_chain.BlockChain) - for _, selector := range virtualSelectors { - // Create a new evm.Chain with the virtual selector but same client/keys - virtualChain := evm.Chain{ - Selector: selector, // Virtual selector - Client: evmChain.Client, - DeployerKey: evmChain.DeployerKey, - Confirm: evmChain.Confirm, - Users: evmChain.Users, - SignHash: evmChain.SignHash, - IsZkSyncVM: evmChain.IsZkSyncVM, - ClientZkSyncVM: evmChain.ClientZkSyncVM, - DeployerKeyZkSyncVM: evmChain.DeployerKeyZkSyncVM, - } - blockchainMap[selector] = virtualChain - Plog.Info(). - Uint64("VirtualSelector", selector). - Uint64("PhysicalSelector", physicalChainDetails.ChainSelector). - Str("PhysicalChainID", chainID). - Msg("Virtual selector mapped to physical chain provider") - } - - blockchains := cldf_chain.NewBlockChains(blockchainMap) - - lggr, err := logger.NewWith(func(config *zap.Config) { - config.Development = true - config.Encoding = "console" - }) - if err != nil { - return nil, nil, err - } - - e := deployment.Environment{ - GetContext: func() context.Context { return context.Background() }, - Logger: lggr, - BlockChains: blockchains, - DataStore: dataStore, - } - - return virtualSelectors, &e, nil -} diff --git a/build/devenv/cmd/ccv/ccv.go b/build/devenv/cmd/ccv/ccv.go index 7d3c5add0..1d3e652d9 100644 --- a/build/devenv/cmd/ccv/ccv.go +++ b/build/devenv/cmd/ccv/ccv.go @@ -210,7 +210,7 @@ var deployCommitVerifierCmd = &cobra.Command{ addresses = append(addresses, common.HexToAddress(addr)) } - selectors, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + selectors, e, _, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.VirtualSelectors, in.CLDF.DataStore) if err != nil { return fmt.Errorf("creating CLDF operations environment: %w", err) } @@ -278,7 +278,7 @@ var deployReceiverCmd = &cobra.Command{ OptionalThreshold: uint8(optionalThreshold), } - _, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + _, e, _, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.VirtualSelectors, in.CLDF.DataStore) if err != nil { return fmt.Errorf("creating CLDF operations environment: %w", err) } @@ -456,22 +456,28 @@ var monitorContractsCmd = &cobra.Command{ if err != nil { return fmt.Errorf("failed to load environment output: %w", err) } - chainIDs, wsURLs := make([]string, 0), make([]string, 0) - for _, bc := range in.Blockchains { - chainIDs = append(chainIDs, bc.ChainID) - wsURLs = append(wsURLs, bc.Out.Nodes[0].ExternalWSUrl) - } - _, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + selectors, e, physicalChainMap, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.VirtualSelectors, in.CLDF.DataStore) if err != nil { return fmt.Errorf("failed to create CLDF operations environment: %w", err) } ctx = ccv.Plog.WithContext(ctx) l := zerolog.Ctx(ctx) - impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, chainIDs, wsURLs) + + evmPhysicalChainMap := make(map[uint64]*ccvEvm.PhysicalChainInfo) + for selector, info := range physicalChainMap { + evmPhysicalChainMap[selector] = &ccvEvm.PhysicalChainInfo{ + ChainID: info.ChainID, + WSURL: info.WSURL, + HTTPURL: info.HTTPURL, + ContainerName: info.ContainerName, + } + } + + impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, selectors, evmPhysicalChainMap) if err != nil { return fmt.Errorf("failed to create CCIP17EVM: %w", err) } - _, reg, err := impl.ExposeMetrics(ctx, source, dest, chainIDs, wsURLs) + _, reg, err := impl.ExposeMetrics(ctx, source, dest) if err != nil { return fmt.Errorf("failed to expose metrics: %w", err) } @@ -554,19 +560,24 @@ var sendCmd = &cobra.Command{ return fmt.Errorf("failed to parse destination chain selector: %w", err) } - chainIDs, wsURLs := make([]string, 0), make([]string, 0) - for _, bc := range in.Blockchains { - chainIDs = append(chainIDs, bc.ChainID) - wsURLs = append(wsURLs, bc.Out.Nodes[0].ExternalWSUrl) - } - - _, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + selectors, e, physicalChainMap, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.VirtualSelectors, in.CLDF.DataStore) if err != nil { return fmt.Errorf("creating CLDF operations environment: %w", err) } ctx = ccv.Plog.WithContext(ctx) l := zerolog.Ctx(ctx) - impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, chainIDs, wsURLs) + + evmPhysicalChainMap := make(map[uint64]*ccvEvm.PhysicalChainInfo) + for selector, info := range physicalChainMap { + evmPhysicalChainMap[selector] = &ccvEvm.PhysicalChainInfo{ + ChainID: info.ChainID, + WSURL: info.WSURL, + HTTPURL: info.HTTPURL, + ContainerName: info.ContainerName, + } + } + + impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, selectors, evmPhysicalChainMap) if err != nil { return fmt.Errorf("failed to create CCIP17EVM: %w", err) } diff --git a/build/devenv/config.go b/build/devenv/config.go index 2f7908389..0e6c76473 100644 --- a/build/devenv/config.go +++ b/build/devenv/config.go @@ -16,6 +16,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "github.com/davecgh/go-spew/spew" @@ -38,18 +39,34 @@ const ( var L = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(zerolog.InfoLevel) -// VirtualSelector represents a virtual chain selector that maps to a physical blockchain. +type Selector uint64 + +func (s *Selector) UnmarshalText(text []byte) error { + val, err := strconv.ParseUint(string(text), 10, 64) + if err != nil { + return fmt.Errorf("invalid selector value %q: %w", string(text), err) + } + *s = Selector(val) + return nil +} + +func (s Selector) MarshalText() ([]byte, error) { + return []byte(strconv.FormatUint(uint64(s), 10)), nil +} + type VirtualSelector struct { - Selector uint64 `toml:"selector"` - Name string `toml:"name"` - Qualifier string `toml:"qualifier"` + Selector Selector `toml:"selector"` + Name string `toml:"name"` + Qualifier string `toml:"qualifier"` + PhysicalChain string `toml:"physical_chain"` } -// PhysicalChainMapping maps virtual selectors to their physical chain ID. -var PhysicalChainMapping = map[uint64]string{ - 100: "1337", // Virtual chain A -> physical chain 1337 - 101: "1337", // Virtual chain B -> physical chain 1337 - 102: "1337", // Virtual chain C -> physical chain 1337 +// PhysicalChainInfo contains the physical blockchain details that a virtual selector maps to. +type PhysicalChainInfo struct { + ChainID string + WSURL string + HTTPURL string + ContainerName string } // Load loads TOML configurations from a list of paths, i.e. env.toml,overrides.toml diff --git a/build/devenv/env.toml b/build/devenv/env.toml index f71f4c51c..48711b195 100644 --- a/build/devenv/env.toml +++ b/build/devenv/env.toml @@ -11,22 +11,33 @@ cl_nodes_funding_link = 50 port = "8545" type = "anvil" + [[blockchains]] + container_name = "blockchain-shared-2" + chain_id = "2337" + docker_cmd_params = ["-b", "1", "--mixed-mining", "--slots-in-an-epoch", "1"] + image = "ghcr.io/foundry-rs/foundry:latest" + port = "8555" + type = "anvil" + # Virtual selectors - all map to the same physical blockchain (1337) # but are treated as separate chains with different contract sets [[virtual_selectors]] - selector = 100 # Virtual chain A + selector = "3379446385462418246" # Virtual chain A (string format for large uint64) name = "chain-a" qualifier = "chain-a" + physical_chain = "blockchain-shared" [[virtual_selectors]] - selector = 101 # Virtual chain B + selector = "12922642891491394802" # Virtual chain B (string format for large uint64) name = "chain-b" qualifier = "chain-b" + physical_chain = "blockchain-shared" [[virtual_selectors]] - selector = 102 # Virtual chain C + selector = "4793464827907405086" # Virtual chain C (string format for large uint64) name = "chain-c" qualifier = "chain-c" + physical_chain = "blockchain-shared-2" [fake] image = "ccv-fakes:dev" diff --git a/build/devenv/environment.go b/build/devenv/environment.go index b0351e1f9..d3818e924 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -70,6 +70,28 @@ type Cfg struct { CLNodesFundingLink float64 `toml:"cl_nodes_funding_link"` } +func (c *Cfg) ValidateVirtualSelectors() error { + if len(c.VirtualSelectors) == 0 { + return fmt.Errorf("no virtual selectors configured") + } + + bcMap := make(map[string]bool) + for _, bc := range c.Blockchains { + bcMap[bc.ContainerName] = true + } + + for _, vs := range c.VirtualSelectors { + if vs.PhysicalChain == "" { + return fmt.Errorf("virtual selector %d missing physical_chain", uint64(vs.Selector)) + } + if !bcMap[vs.PhysicalChain] { + return fmt.Errorf("virtual selector %d references unknown physical_chain: %s", + uint64(vs.Selector), vs.PhysicalChain) + } + } + return nil +} + func checkKeys(in *Cfg) error { // Updated validation for single blockchain with virtual selectors if len(in.Blockchains) > 0 { @@ -112,19 +134,25 @@ func NewEnvironment() (*Cfg, error) { return nil, err } + if err := in.ValidateVirtualSelectors(); err != nil { + return nil, fmt.Errorf("invalid virtual selectors: %w", err) + } + _, err = services.NewFake(in.Fake) if err != nil { return nil, fmt.Errorf("failed to create fake data provider: %w", err) } - // Deploy single blockchain for all virtual chains impl, err := NewProductConfigurationFromNetwork(in.Blockchains[0].Type) if err != nil { return nil, err } - _, err = impl.DeployLocalNetwork(ctx, in.Blockchains[0]) - if err != nil { - return nil, fmt.Errorf("failed to deploy local network: %w", err) + + for _, bc := range in.Blockchains { + _, err = impl.DeployLocalNetwork(ctx, bc) + if err != nil { + return nil, fmt.Errorf("failed to deploy local network %s: %w", bc.ContainerName, err) + } } _, err = services.NewIndexer(in.Indexer) @@ -141,11 +169,14 @@ func NewEnvironment() (*Cfg, error) { clChainConfigs := make([]string, 0) clChainConfigs = append(clChainConfigs, CommonCLNodesConfig) - clChainConfig, err := impl.ConfigureNodes(ctx, in.Blockchains[0]) - if err != nil { - return nil, fmt.Errorf("failed to configure nodes: %w", err) + + for _, bc := range in.Blockchains { + clChainConfig, err := impl.ConfigureNodes(ctx, bc) + if err != nil { + return nil, fmt.Errorf("failed to configure nodes for %s: %w", bc.ContainerName, err) + } + clChainConfigs = append(clChainConfigs, clChainConfig) } - clChainConfigs = append(clChainConfigs, clChainConfig) allConfigs := strings.Join(clChainConfigs, "\n") for _, nodeSpec := range in.NodeSets[0].NodeSpecs { @@ -161,26 +192,30 @@ func NewEnvironment() (*Cfg, error) { in.CLDF.Init() - // Extract virtual selectors - virtualSelectors := make([]uint64, len(in.VirtualSelectors)) - for i, vs := range in.VirtualSelectors { - virtualSelectors[i] = vs.Selector - } - - // Create CLDF environment with all virtual selectors mapped to single blockchain - selectors, e, err := NewCLDFOperationsEnvironmentWithVirtualSelectors( - in.Blockchains[0], - virtualSelectors, + selectors, e, _, err := NewCLDFOperationsEnvironment( + in.Blockchains, + in.VirtualSelectors, in.CLDF.DataStore, ) if err != nil { - return nil, fmt.Errorf("creating CLDF operations environment with virtual selectors: %w", err) + return nil, fmt.Errorf("creating CLDF operations environment: %w", err) } - Plog.Info().Any("VirtualSelectors", virtualSelectors).Msg("Deploying for virtual chain selectors") + Plog.Info().Int("VirtualSelectors", len(in.VirtualSelectors)).Msg("Deploying for virtual chain selectors") - // Fund nodes once (shared across all virtual chains) - if err := impl.FundNodes(ctx, in.NodeSets, in.Blockchains[0], big.NewInt(1), big.NewInt(5)); err != nil { - return nil, err + blockchainsByName := make(map[string]*blockchain.Input) + for i := range in.Blockchains { + blockchainsByName[in.Blockchains[i].ContainerName] = in.Blockchains[i] + } + + fundedChains := make(map[string]bool) + for _, vs := range in.VirtualSelectors { + if !fundedChains[vs.PhysicalChain] { + bc := blockchainsByName[vs.PhysicalChain] + if err := impl.FundNodes(ctx, in.NodeSets, bc, big.NewInt(1), big.NewInt(5)); err != nil { + return nil, fmt.Errorf("failed to fund nodes for %s: %w", vs.PhysicalChain, err) + } + fundedChains[vs.PhysicalChain] = true + } } // Deploy contracts for each virtual selector to the same physical chain diff --git a/build/devenv/tests/e2e/load_test.go b/build/devenv/tests/e2e/load_test.go index 27815ad47..04f69f8d9 100644 --- a/build/devenv/tests/e2e/load_test.go +++ b/build/devenv/tests/e2e/load_test.go @@ -412,11 +412,14 @@ func TestE2ELoad(t *testing.T) { if os.Getenv("LOKI_URL") == "" { _ = os.Setenv("LOKI_URL", ccv.DefaultLokiURL) } - srcRPCURL := in.Blockchains[0].Out.Nodes[0].ExternalHTTPUrl - dstRPCURL := in.Blockchains[1].Out.Nodes[0].ExternalHTTPUrl - selectors, e, err := ccv.NewCLDFOperationsEnvironment(in.Blockchains, in.CLDF.DataStore) + selectors, e, physicalChainMap, err := ccv.NewCLDFOperationsEnvironment( + in.Blockchains, + in.VirtualSelectors, + in.CLDF.DataStore, + ) require.NoError(t, err) + chains := e.BlockChains.EVMChains() require.NotNil(t, chains) srcChain := chains[selectors[0]] @@ -426,15 +429,23 @@ func TestE2ELoad(t *testing.T) { ctx := ccv.Plog.WithContext(context.Background()) l := zerolog.Ctx(ctx) - chainIDs, wsURLs := make([]string, 0), make([]string, 0) - for _, bc := range in.Blockchains { - chainIDs = append(chainIDs, bc.ChainID) - wsURLs = append(wsURLs, bc.Out.Nodes[0].ExternalWSUrl) + + evmPhysicalChainMap := make(map[uint64]*ccvEvm.PhysicalChainInfo) + for selector, info := range physicalChainMap { + evmPhysicalChainMap[selector] = &ccvEvm.PhysicalChainInfo{ + ChainID: info.ChainID, + WSURL: info.WSURL, + HTTPURL: info.HTTPURL, + ContainerName: info.ContainerName, + } } - impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, chainIDs, wsURLs) + impl, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, selectors, evmPhysicalChainMap) require.NoError(t, err) + srcRPCURL := physicalChainMap[selectors[0]].WSURL + dstRPCURL := physicalChainMap[selectors[1]].WSURL + indexerURL := fmt.Sprintf("http://127.0.0.1:%d", in.Indexer.Port) aggregatorAddr := fmt.Sprintf("127.0.0.1:%d", in.Aggregator.Port) diff --git a/build/devenv/tests/e2e/smoke_test.go b/build/devenv/tests/e2e/smoke_test.go index 93c0e00d8..7bb51f7ad 100644 --- a/build/devenv/tests/e2e/smoke_test.go +++ b/build/devenv/tests/e2e/smoke_test.go @@ -41,31 +41,25 @@ func TestE2ESmoke(t *testing.T) { ctx := ccv.Plog.WithContext(t.Context()) l := zerolog.Ctx(ctx) - // Extract virtual selectors - virtualSelectors := make([]uint64, len(in.VirtualSelectors)) - for i, vs := range in.VirtualSelectors { - virtualSelectors[i] = vs.Selector - } - - // Create CLDF environment with all virtual selectors mapped to single blockchain - selectors, e, err := ccv.NewCLDFOperationsEnvironmentWithVirtualSelectors( - in.Blockchains[0], - virtualSelectors, + selectors, e, physicalChainMap, err := ccv.NewCLDFOperationsEnvironment( + in.Blockchains, + in.VirtualSelectors, in.CLDF.DataStore, ) require.NoError(t, err) require.Len(t, selectors, 3, "expected 3 chains for this test in the environment") - // For virtual selectors, all point to the same physical blockchain - chainIDs := make([]string, len(virtualSelectors)) - wsURLs := make([]string, len(virtualSelectors)) - for i := range virtualSelectors { - chainIDs[i] = in.Blockchains[0].ChainID - wsURLs[i] = in.Blockchains[0].Out.Nodes[0].ExternalWSUrl + evmPhysicalChainMap := make(map[uint64]*ccvEvm.PhysicalChainInfo) + for selector, info := range physicalChainMap { + evmPhysicalChainMap[selector] = &ccvEvm.PhysicalChainInfo{ + ChainID: info.ChainID, + WSURL: info.WSURL, + HTTPURL: info.HTTPURL, + ContainerName: info.ContainerName, + } } - // Use the new constructor that accepts explicit selectors - c, err := ccvEvm.NewCCIP17EVMWithVirtualSelectors(ctx, *l, e, virtualSelectors, chainIDs, wsURLs) + c, err := ccvEvm.NewCCIP17EVM(ctx, *l, e, selectors, evmPhysicalChainMap) require.NoError(t, err) t.Cleanup(func() { diff --git a/cciptestinterfaces/interface.go b/cciptestinterfaces/interface.go index 262b61fd1..d8787f75e 100644 --- a/cciptestinterfaces/interface.go +++ b/cciptestinterfaces/interface.go @@ -33,8 +33,8 @@ type CCIP17ProductConfiguration interface { // Observable pushes Loki streams and exposes Prometheus metrics and returns queries to assert SLAs. type Observable interface { - // ExposeMetrics exposes Prometheus metrics for the given source and destination chain IDs. - ExposeMetrics(ctx context.Context, source, dest uint64, chainIDs, wsURLs []string) ([]string, *prometheus.Registry, error) + // ExposeMetrics exposes Prometheus metrics for the given source and destination selectors. + ExposeMetrics(ctx context.Context, source, dest uint64) ([]string, *prometheus.Registry, error) } // TokenAmount represents a token amount being sent in a CCIP message. diff --git a/ccv-evm/impl.go b/ccv-evm/impl.go index d432b8729..d9281d11e 100644 --- a/ccv-evm/impl.go +++ b/ccv-evm/impl.go @@ -56,6 +56,15 @@ import ( cciptestinterfaces "github.com/smartcontractkit/chainlink-ccv/cciptestinterfaces" ) +// PhysicalChainInfo contains the physical blockchain details that a virtual selector maps to. +// This is intentionally duplicated from build/devenv to avoid import cycles. +type PhysicalChainInfo struct { + ChainID string + WSURL string + HTTPURL string + ContainerName string +} + const ( // These qualifiers are used to distinguish between multiple deployments of the committee verifier proxy and mock receiver // on the same chain. @@ -91,14 +100,12 @@ type CCIP17EVM struct { ethClients map[uint64]*ethclient.Client onRampBySelector map[uint64]*onramp.OnRamp offRampBySelector map[uint64]*offramp.OffRamp + physicalChainMap map[uint64]*PhysicalChainInfo } // NewCCIP17EVM creates new smart-contracts wrappers with utility functions for CCIP17EVM implementation. -func NewCCIP17EVM(ctx context.Context, logger zerolog.Logger, e *deployment.Environment, chainIDs, wsURLs []string) (*CCIP17EVM, error) { - if len(chainIDs) != len(wsURLs) { - return nil, fmt.Errorf("len(chainIDs) != len(wsURLs) ; %d != %d", len(chainIDs), len(wsURLs)) - } - +// physicalChainMap provides the mapping from virtual selectors to physical chain information. +func NewCCIP17EVM(ctx context.Context, logger zerolog.Logger, e *deployment.Environment, selectors []uint64, physicalChainMap map[uint64]*PhysicalChainInfo) (*CCIP17EVM, error) { gas := &GasSettings{ FeeCapMultiplier: 2, TipCapMultiplier: 2, @@ -109,93 +116,22 @@ func NewCCIP17EVM(ctx context.Context, logger zerolog.Logger, e *deployment.Envi onRampBySelector = make(map[uint64]*onramp.OnRamp) offRampBySelector = make(map[uint64]*offramp.OffRamp) ) - for i := range chainIDs { - chainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(chainIDs[i], chainsel.FamilyEVM) - if err != nil { - return nil, fmt.Errorf("get chain details for chain %s: %w", chainIDs[i], err) - } - chainDetailsBySelector[chainDetails.ChainSelector] = chainDetails - - client, _, _, err := ETHClient(ctx, wsURLs[i], gas) - if err != nil { - return nil, fmt.Errorf("create eth client for chain %s: %w", chainIDs[i], err) - } - ethClients[chainDetails.ChainSelector] = client - - onRampAddressRef, err := e.DataStore.Addresses().Get(datastore.NewAddressRefKey( - chainDetails.ChainSelector, - datastore.ContractType(onrampoperations.ContractType), - semver.MustParse(onrampoperations.Deploy.Version()), - "", - )) - if err != nil { - return nil, fmt.Errorf("get on ramp address for chain %d (id %s) from datastore: %w", chainDetails.ChainSelector, chainIDs[i], err) - } - offRampAddressRef, err := e.DataStore.Addresses().Get(datastore.NewAddressRefKey( - chainDetails.ChainSelector, - datastore.ContractType(offrampoperations.ContractType), - semver.MustParse(offrampoperations.Deploy.Version()), - "", - )) - if err != nil { - return nil, fmt.Errorf("get off ramp address for chain %d (id %s) from datastore: %w", chainDetails.ChainSelector, chainIDs[i], err) - } - onRamp, err := onramp.NewOnRamp(common.HexToAddress(onRampAddressRef.Address), client) - if err != nil { - return nil, fmt.Errorf("create on ramp wrapper for chain %d (id %s): %w", chainDetails.ChainSelector, chainIDs[i], err) - } - offRamp, err := offramp.NewOffRamp(common.HexToAddress(offRampAddressRef.Address), client) - if err != nil { - return nil, fmt.Errorf("create off ramp wrapper for chain %d (id %s): %w", chainDetails.ChainSelector, chainIDs[i], err) + for _, selector := range selectors { + physicalInfo, ok := physicalChainMap[selector] + if !ok { + return nil, fmt.Errorf("no physical chain info for selector %d", selector) } - onRampBySelector[chainDetails.ChainSelector] = onRamp - offRampBySelector[chainDetails.ChainSelector] = offRamp - } - - return &CCIP17EVM{ - e: e, - logger: logger, - chainDetailsBySelector: chainDetailsBySelector, - ethClients: ethClients, - onRampBySelector: onRampBySelector, - offRampBySelector: offRampBySelector, - }, nil -} - -// NewCCIP17EVMWithVirtualSelectors creates new smart-contracts wrappers using explicit selectors instead of deriving them from chainIDs. -// This is useful for virtual selector architectures where multiple selectors map to the same physical chain. -func NewCCIP17EVMWithVirtualSelectors(ctx context.Context, logger zerolog.Logger, e *deployment.Environment, selectors []uint64, chainIDs, wsURLs []string) (*CCIP17EVM, error) { - if len(selectors) != len(chainIDs) || len(selectors) != len(wsURLs) { - return nil, fmt.Errorf("len(selectors) != len(chainIDs) != len(wsURLs) ; %d != %d != %d", len(selectors), len(chainIDs), len(wsURLs)) - } - - gas := &GasSettings{ - FeeCapMultiplier: 2, - TipCapMultiplier: 2, - } - var ( - chainDetailsBySelector = make(map[uint64]chainsel.ChainDetails) - ethClients = make(map[uint64]*ethclient.Client) - onRampBySelector = make(map[uint64]*onramp.OnRamp) - offRampBySelector = make(map[uint64]*offramp.OffRamp) - ) - for i := range selectors { - selector := selectors[i] - chainID := chainIDs[i] - wsURL := wsURLs[i] - - // For virtual selectors, we create a minimal ChainDetails since we don't use chainsel lookup chainDetails := chainsel.ChainDetails{ ChainSelector: selector, - ChainName: fmt.Sprintf("virtual-chain-%d", selector), + ChainName: fmt.Sprintf("chain-%d", selector), } chainDetailsBySelector[selector] = chainDetails - client, _, _, err := ETHClient(ctx, wsURL, gas) + client, _, _, err := ETHClient(ctx, physicalInfo.WSURL, gas) if err != nil { - return nil, fmt.Errorf("create eth client for chain %s (selector %d): %w", chainID, selector, err) + return nil, fmt.Errorf("create eth client for selector %d: %w", selector, err) } ethClients[selector] = client @@ -206,7 +142,7 @@ func NewCCIP17EVMWithVirtualSelectors(ctx context.Context, logger zerolog.Logger "", )) if err != nil { - return nil, fmt.Errorf("get on ramp address for selector %d (chain id %s) from datastore: %w", selector, chainID, err) + return nil, fmt.Errorf("get on ramp address for selector %d from datastore: %w", selector, err) } offRampAddressRef, err := e.DataStore.Addresses().Get(datastore.NewAddressRefKey( selector, @@ -215,15 +151,15 @@ func NewCCIP17EVMWithVirtualSelectors(ctx context.Context, logger zerolog.Logger "", )) if err != nil { - return nil, fmt.Errorf("get off ramp address for selector %d (chain id %s) from datastore: %w", selector, chainID, err) + return nil, fmt.Errorf("get off ramp address for selector %d from datastore: %w", selector, err) } onRamp, err := onramp.NewOnRamp(common.HexToAddress(onRampAddressRef.Address), client) if err != nil { - return nil, fmt.Errorf("create on ramp wrapper for selector %d (chain id %s): %w", selector, chainID, err) + return nil, fmt.Errorf("create on ramp wrapper for selector %d: %w", selector, err) } offRamp, err := offramp.NewOffRamp(common.HexToAddress(offRampAddressRef.Address), client) if err != nil { - return nil, fmt.Errorf("create off ramp wrapper for selector %d (chain id %s): %w", selector, chainID, err) + return nil, fmt.Errorf("create off ramp wrapper for selector %d: %w", selector, err) } onRampBySelector[selector] = onRamp @@ -237,6 +173,7 @@ func NewCCIP17EVMWithVirtualSelectors(ctx context.Context, logger zerolog.Logger ethClients: ethClients, onRampBySelector: onRampBySelector, offRampBySelector: offRampBySelector, + physicalChainMap: physicalChainMap, }, nil } @@ -582,12 +519,7 @@ func (m *CCIP17EVM) SendMessage(ctx context.Context, src, dest uint64, fields cc destFamily, err := chainsel.GetSelectorFamily(dest) if err != nil { - // For virtual selectors that don't exist in chainsel, check if dest exists in our environment - if _, ok := chains[dest]; !ok { - return fmt.Errorf("failed to get destination family: %w", err) - } - // Virtual selector - assume EVM since it maps to an EVM chain - destFamily = chainsel.FamilyEVM + return fmt.Errorf("failed to get destination family: %w", err) } routerRef, err := m.e.DataStore.Addresses().Get(datastore.NewAddressRefKey(srcChain.Selector, datastore.ContractType(routeroperations.ContractType), semver.MustParse("1.2.0"), "")) @@ -831,8 +763,6 @@ func serializeExtraArgsSVMV1(_ cciptestinterfaces.MessageOptions) []byte { func (m *CCIP17EVM) ExposeMetrics( ctx context.Context, source, dest uint64, - chainIDs []string, - wsURLs []string, ) ([]string, *prometheus.Registry, error) { msgSentTotal.Reset() msgExecTotal.Reset() @@ -843,7 +773,7 @@ func (m *CCIP17EVM) ExposeMetrics( lp := NewLokiPusher() tp := NewTempoPusher() - c, err := NewCCIP17EVM(ctx, m.logger, m.e, chainIDs, wsURLs) + c, err := NewCCIP17EVM(ctx, m.logger, m.e, []uint64{source, dest}, m.physicalChainMap) if err != nil { return nil, nil, err } @@ -1279,7 +1209,7 @@ func (m *CCIP17EVM) ConnectContractsWithSelectors(ctx context.Context, e *deploy }, } } - _, _ = tokenscore.ConfigureTokensForTransfers(tokenAdapterRegistry, mcmsReaderRegistry).Apply(*e, tokenscore.ConfigureTokensForTransfersConfig{ + _, err = tokenscore.ConfigureTokensForTransfers(tokenAdapterRegistry, mcmsReaderRegistry).Apply(*e, tokenscore.ConfigureTokensForTransfersConfig{ Tokens: []tokenscore.TokenTransferConfig{ { ChainSelector: selector, @@ -1295,9 +1225,9 @@ func (m *CCIP17EVM) ConnectContractsWithSelectors(ctx context.Context, e *deploy }, }, }) - // if err != nil { - // fmt.Errorf("failed to configure tokens for transfers: %w", err) - // } + if err != nil { + return fmt.Errorf("failed to configure tokens for transfers: %w", err) + } return nil } diff --git a/cmd/executor/executor_config.toml b/cmd/executor/executor_config.toml index 2c5521f7c..28219c2d8 100644 --- a/cmd/executor/executor_config.toml +++ b/cmd/executor/executor_config.toml @@ -11,37 +11,37 @@ min_wait="3s" ccv_info_cache_expiry="5m" [offramp_addresses] - 100 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" - 101 = "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf" - 102 = "0x36b58F5C1969B7b6591D752ea6F5486D069010AB" + 3379446385462418246 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + 12922642891491394802 = "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf" + 4793464827907405086 = "0x36b58F5C1969B7b6591D752ea6F5486D069010AB" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/default/verifier-1.toml b/cmd/verifier/testconfig/default/verifier-1.toml index 8fdb4aea6..c0aec7d3d 100644 --- a/cmd/verifier/testconfig/default/verifier-1.toml +++ b/cmd/verifier/testconfig/default/verifier-1.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" - 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 12922642891491394802 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 4793464827907405086 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/default/verifier-2.toml b/cmd/verifier/testconfig/default/verifier-2.toml index 6725da3ef..0fa6a0ad2 100644 --- a/cmd/verifier/testconfig/default/verifier-2.toml +++ b/cmd/verifier/testconfig/default/verifier-2.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" - 101 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" - 102 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + 12922642891491394802 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + 4793464827907405086 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/secondary/verifier-1.toml b/cmd/verifier/testconfig/secondary/verifier-1.toml index f7ce04c63..c806f5611 100644 --- a/cmd/verifier/testconfig/secondary/verifier-1.toml +++ b/cmd/verifier/testconfig/secondary/verifier-1.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" - 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" + 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 12922642891491394802 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 4793464827907405086 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/secondary/verifier-2.toml b/cmd/verifier/testconfig/secondary/verifier-2.toml index 51b252e61..a77ff6b3e 100644 --- a/cmd/verifier/testconfig/secondary/verifier-2.toml +++ b/cmd/verifier/testconfig/secondary/verifier-2.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" - 101 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" - 102 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" + 3379446385462418246 = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" + 12922642891491394802 = "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + 4793464827907405086 = "0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/tertiary/verifier-1.toml b/cmd/verifier/testconfig/tertiary/verifier-1.toml index 877afb3b4..85da1c8df 100644 --- a/cmd/verifier/testconfig/tertiary/verifier-1.toml +++ b/cmd/verifier/testconfig/tertiary/verifier-1.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" - 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" + 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 12922642891491394802 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 4793464827907405086 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/cmd/verifier/testconfig/tertiary/verifier-2.toml b/cmd/verifier/testconfig/tertiary/verifier-2.toml index 0503268e6..393e1e4cc 100644 --- a/cmd/verifier/testconfig/tertiary/verifier-2.toml +++ b/cmd/verifier/testconfig/tertiary/verifier-2.toml @@ -16,41 +16,41 @@ TraceSampleRatio = 1.0 TraceBatchTimeout = 10 [on_ramp_addresses] - 100 = "0x9A676e781A523b5d0C0e43731313A708CB607508" - 101 = "0x9d4454B023096f34B160D6B654540c56A1F81688" - 102 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" + 3379446385462418246 = "0x9A676e781A523b5d0C0e43731313A708CB607508" + 12922642891491394802 = "0x9d4454B023096f34B160D6B654540c56A1F81688" + 4793464827907405086 = "0x8198f5d8F8CfFE8f9C413d98a0A55aEB8ab9FbB7" [committee_verifier_addresses] - 100 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" - 101 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" - 102 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" + 3379446385462418246 = "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" + 12922642891491394802 = "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1" + 4793464827907405086 = "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" [blockchain_infos] - [blockchain_infos.100] + [blockchain_infos.3379446385462418246] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.100.Nodes]] + [[blockchain_infos.3379446385462418246.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.101] + [blockchain_infos.12922642891491394802] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.101.Nodes]] + [[blockchain_infos.12922642891491394802.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" - [blockchain_infos.102] + [blockchain_infos.4793464827907405086] ChainID = "1337" Type = "anvil" Family = "evm" UniqueChainName = "blockchain-shared" - [[blockchain_infos.102.Nodes]] + [[blockchain_infos.4793464827907405086.Nodes]] ExternalHTTPUrl = "http://host.docker.internal:8545" InternalHTTPUrl = "http://blockchain-shared:8545" ExternalWSUrl = "ws://host.docker.internal:8545" diff --git a/integration/pkg/contracttransmitter/evm_contract_transmitter.go b/integration/pkg/contracttransmitter/evm_contract_transmitter.go index 0baf5165d..42a6b0c68 100644 --- a/integration/pkg/contracttransmitter/evm_contract_transmitter.go +++ b/integration/pkg/contracttransmitter/evm_contract_transmitter.go @@ -53,7 +53,11 @@ func NewEVMContractTransmitterFromRPC(ctx context.Context, lggr logger.Logger, c return nil, err } - chainIDInt := big.NewInt(1337) + // Get chain ID from the RPC itself as chainselector can be virtual chain + chainIDInt, err := client.ChainID(ctx) + if err != nil { + return nil, err + } auth := bind.NewKeyedTransactor(pk, chainIDInt) auth.Value = big.NewInt(0) @@ -115,8 +119,6 @@ func (ct *EVMContractTransmitter) ConvertAndWriteMessageToChain(ctx context.Cont return err } - fmt.Printf("Offramp address %v", ct.OffRamp.Address()) - encodedMsg, _ := report.Message.Encode() tx, err := ct.OffRamp.Execute(opts, encodedMsg, contractCcvs, report.CCVData) if err != nil { From 44ea3c606642fd3a4c36808342e62d9379826ec5 Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Thu, 23 Oct 2025 08:07:54 -0400 Subject: [PATCH 3/5] Fix config for third chain --- aggregator/aggregator.toml | 6 +++--- cmd/executor/executor_config.toml | 14 +++++++------- cmd/verifier/testconfig/default/verifier-1.toml | 12 ++++++------ cmd/verifier/testconfig/default/verifier-2.toml | 12 ++++++------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/aggregator/aggregator.toml b/aggregator/aggregator.toml index e62a17fe6..0792ea1a8 100644 --- a/aggregator/aggregator.toml +++ b/aggregator/aggregator.toml @@ -46,7 +46,7 @@ pyroscope_url = "http://pyroscope:4040" [committees.default] [committees.default.quorumConfigs] [committees.default.quorumConfigs.3379446385462418246] - committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" + committeeVerifierAddress = "0x9A676e781A523b5d0C0e43731313A708CB607508" threshold = 2 [[committees.default.quorumConfigs.3379446385462418246.signers]] @@ -70,7 +70,7 @@ pyroscope_url = "http://pyroscope:4040" addresses = ["0x2a3e6b4676d01c5afdd710f01d2b8870bdef182d"] [committees.default.quorumConfigs.4793464827907405086] - committeeVerifierAddress = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" threshold = 2 [[committees.default.quorumConfigs.4793464827907405086.signers]] @@ -84,7 +84,7 @@ pyroscope_url = "http://pyroscope:4040" [committees.default.sourceVerifierAddresses] 3379446385462418246 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" 12922642891491394802 = "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" - 4793464827907405086 = "0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8" + 4793464827907405086 = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" [committees.secondary] [committees.secondary.quorumConfigs] diff --git a/cmd/executor/executor_config.toml b/cmd/executor/executor_config.toml index 28219c2d8..224f9a131 100644 --- a/cmd/executor/executor_config.toml +++ b/cmd/executor/executor_config.toml @@ -13,7 +13,7 @@ ccv_info_cache_expiry="5m" [offramp_addresses] 3379446385462418246 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" 12922642891491394802 = "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf" - 4793464827907405086 = "0x36b58F5C1969B7b6591D752ea6F5486D069010AB" + 4793464827907405086 = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" [blockchain_infos] [blockchain_infos.3379446385462418246] @@ -37,15 +37,15 @@ ccv_info_cache_expiry="5m" ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" [blockchain_infos.4793464827907405086] - ChainID = "1337" + ChainID = "2337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-shared" + UniqueChainName = "blockchain-shared-2" [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-shared:8545" - ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-shared:8545" + ExternalHTTPUrl = "http://host.docker.internal:8555" + InternalHTTPUrl = "http://blockchain-shared-2:8555" + ExternalWSUrl = "ws://host.docker.internal:8555" + InternalWSUrl = "ws://blockchain-shared-2:8555" [Monitoring] Enabled = true diff --git a/cmd/verifier/testconfig/default/verifier-1.toml b/cmd/verifier/testconfig/default/verifier-1.toml index c0aec7d3d..89d0a7891 100644 --- a/cmd/verifier/testconfig/default/verifier-1.toml +++ b/cmd/verifier/testconfig/default/verifier-1.toml @@ -46,12 +46,12 @@ TraceBatchTimeout = 10 ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" [blockchain_infos.4793464827907405086] - ChainID = "1337" + ChainID = "2337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-shared" + UniqueChainName = "blockchain-shared-2" [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-shared:8545" - ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-shared:8545" + ExternalHTTPUrl = "http://host.docker.internal:8555" + InternalHTTPUrl = "http://blockchain-shared-2:8555" + ExternalWSUrl = "ws://host.docker.internal:8555" + InternalWSUrl = "ws://blockchain-shared-2:8555" diff --git a/cmd/verifier/testconfig/default/verifier-2.toml b/cmd/verifier/testconfig/default/verifier-2.toml index 0fa6a0ad2..e87c109d8 100644 --- a/cmd/verifier/testconfig/default/verifier-2.toml +++ b/cmd/verifier/testconfig/default/verifier-2.toml @@ -46,12 +46,12 @@ TraceBatchTimeout = 10 ExternalWSUrl = "ws://host.docker.internal:8545" InternalWSUrl = "ws://blockchain-shared:8545" [blockchain_infos.4793464827907405086] - ChainID = "1337" + ChainID = "2337" Type = "anvil" Family = "evm" - UniqueChainName = "blockchain-shared" + UniqueChainName = "blockchain-shared-2" [[blockchain_infos.4793464827907405086.Nodes]] - ExternalHTTPUrl = "http://host.docker.internal:8545" - InternalHTTPUrl = "http://blockchain-shared:8545" - ExternalWSUrl = "ws://host.docker.internal:8545" - InternalWSUrl = "ws://blockchain-shared:8545" + ExternalHTTPUrl = "http://host.docker.internal:8555" + InternalHTTPUrl = "http://blockchain-shared-2:8555" + ExternalWSUrl = "ws://host.docker.internal:8555" + InternalWSUrl = "ws://blockchain-shared-2:8555" From 1da1b835af1f6738080c898d16a5cf156638387a Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Thu, 23 Oct 2025 14:44:23 -0400 Subject: [PATCH 4/5] Fix config --- aggregator/aggregator.toml | 2 +- build/devenv/tests/e2e/smoke_test.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/aggregator/aggregator.toml b/aggregator/aggregator.toml index 0792ea1a8..7240ae35c 100644 --- a/aggregator/aggregator.toml +++ b/aggregator/aggregator.toml @@ -46,7 +46,7 @@ pyroscope_url = "http://pyroscope:4040" [committees.default] [committees.default.quorumConfigs] [committees.default.quorumConfigs.3379446385462418246] - committeeVerifierAddress = "0x9A676e781A523b5d0C0e43731313A708CB607508" + committeeVerifierAddress = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" threshold = 2 [[committees.default.quorumConfigs.3379446385462418246.signers]] diff --git a/build/devenv/tests/e2e/smoke_test.go b/build/devenv/tests/e2e/smoke_test.go index 7bb51f7ad..c68b046e4 100644 --- a/build/devenv/tests/e2e/smoke_test.go +++ b/build/devenv/tests/e2e/smoke_test.go @@ -245,7 +245,7 @@ func TestE2ESmoke(t *testing.T) { receiver: getContractAddress(t, in, selectors[1], datastore.ContractType(mock_receiver.ContractType), mock_receiver.Deploy.Version(), ccvEvm.DefaultReceiverQualifier, "mock receiver"), ccvs: []protocol.CCV{ { - CCVAddress: getContractAddress(t, in, selectors[1], datastore.ContractType(committee_verifier.ProxyType), committee_verifier.Deploy.Version(), ccvEvm.DefaultCommitteeVerifierQualifier, "committee verifier proxy"), + CCVAddress: getContractAddress(t, in, selectors[0], datastore.ContractType(committee_verifier.ProxyType), committee_verifier.Deploy.Version(), ccvEvm.DefaultCommitteeVerifierQualifier, "committee verifier proxy"), Args: []byte{}, ArgsLen: 0, }, @@ -263,7 +263,7 @@ func TestE2ESmoke(t *testing.T) { receiver: getContractAddress(t, in, selectors[0], datastore.ContractType(mock_receiver.ContractType), mock_receiver.Deploy.Version(), ccvEvm.DefaultReceiverQualifier, "mock receiver"), ccvs: []protocol.CCV{ { - CCVAddress: getContractAddress(t, in, selectors[0], datastore.ContractType(committee_verifier.ProxyType), committee_verifier.Deploy.Version(), ccvEvm.DefaultCommitteeVerifierQualifier, "committee verifier proxy"), + CCVAddress: getContractAddress(t, in, selectors[1], datastore.ContractType(committee_verifier.ProxyType), committee_verifier.Deploy.Version(), ccvEvm.DefaultCommitteeVerifierQualifier, "committee verifier proxy"), Args: []byte{}, ArgsLen: 0, }, @@ -371,5 +371,6 @@ func getContractAddress(t *testing.T, ccvCfg *ccv.Cfg, chainSelector uint64, con ) require.NoErrorf(t, err, "failed to get %s address for chain selector %d, ContractType: %s, ContractVersion: %s", contractName, chainSelector, contractType, version) + t.Logf("Retrieved %s at address: %s on chain selector %d", contractType, ref.Address, chainSelector) return protocol.UnknownAddress(common.HexToAddress(ref.Address).Bytes()) } From 946eff203ea63c377c499e3be1af336cd9f105c3 Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Thu, 23 Oct 2025 15:31:27 -0400 Subject: [PATCH 5/5] Change load test receiver --- build/devenv/tests/e2e/load_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/devenv/tests/e2e/load_test.go b/build/devenv/tests/e2e/load_test.go index 04f69f8d9..6a6bd1793 100644 --- a/build/devenv/tests/e2e/load_test.go +++ b/build/devenv/tests/e2e/load_test.go @@ -128,7 +128,7 @@ func (m *EVMTXGun) Call(_ *wasp.Generator) *wasp.Response { mockReceiverRef, err := m.e.DataStore.Addresses().Get( datastore.NewAddressRefKey( - srcChain.ChainSelector, + dstChain.ChainSelector, datastore.ContractType(mock_receiver.ContractType), semver.MustParse(mock_receiver.Deploy.Version()), ccvEvm.DefaultReceiverQualifier))