diff --git a/core/services/ocr3/plugins/ccip_integration_tests/helpers.go b/core/services/ocr3/plugins/ccip_integration_tests/helpers.go index b00f8086fd..2277a84be1 100644 --- a/core/services/ocr3/plugins/ccip_integration_tests/helpers.go +++ b/core/services/ocr3/plugins/ccip_integration_tests/helpers.go @@ -7,8 +7,10 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/jmoiron/sqlx" chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" @@ -28,13 +30,13 @@ import ( ) var ( - homeChainID = int64(chainsel.GETH_TESTNET.EvmChainID) + homeChainID = chainsel.GETH_TESTNET.EvmChainID ) type ocr3Node struct { app chainlink.Application peerID string - transmitters map[int64]common.Address + transmitters map[uint64]common.Address keybundle ocr2key.KeyBundle db *sqlx.DB } @@ -63,8 +65,8 @@ type onchainUniverse struct { func deployContracts( t *testing.T, owner *bind.TransactOpts, - chains map[int64]*backends.SimulatedBackend, -) (homeChainUni homeChain, universes map[int64]onchainUniverse) { + chains map[uint64]*backends.SimulatedBackend, +) (homeChainUni homeChain, universes map[uint64]onchainUniverse) { require.Len(t, chains, 4, "must have 4 chains total, 1 home chain and 3 non-home-chains") // deploy the capability registry on the home chain @@ -79,7 +81,7 @@ func deployContracts( require.NoError(t, err) // deploy the ccip contracts on the non-home-chain chains (total of 3). - universes = make(map[int64]onchainUniverse) + universes = make(map[uint64]onchainUniverse) for chainID, backend := range chains { if chainID == homeChainID { continue @@ -205,7 +207,7 @@ func deployContracts( universes[chainID] = onchainUniverse{ backend: backend, - chainID: uint64(chainID), + chainID: chainID, linkToken: linkToken, weth: weth, router: rout, @@ -220,7 +222,7 @@ func deployContracts( return homeChain{ backend: homeChainBackend, - chainID: uint64(homeChainID), + chainID: homeChainID, capabilityRegistry: capabilityRegistry, }, universes } @@ -228,28 +230,28 @@ func deployContracts( func fullyConnectCCIPContracts( t *testing.T, owner *bind.TransactOpts, - universes map[int64]onchainUniverse, + universes map[uint64]onchainUniverse, ) { chainIDs := maps.Keys(universes) - for chainID, uni := range universes { - chainsToConnectTo := filter(chainIDs, func(chainIDArg int64) bool { - return chainIDArg != chainID + for sourceChainID, uni := range universes { + chainsToConnectTo := filter(chainIDs, func(chainIDArg uint64) bool { + return chainIDArg != sourceChainID }) // we are forming a fully-connected graph, so in each iteration we connect - // the current chain (referenced by chainID) to all other chains that are not + // the current chain (referenced by sourceChainID) to all other chains that are not // ourselves. var ( - onrampDestChainConfigArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs - routerOnrampUpdates []router.RouterOnRamp - routerOfframpUpdates []router.RouterOffRamp - offrampSourceChainConfigArgs []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs + onrampDestChainConfigArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs + routerOnrampUpdates []router.RouterOnRamp + routerOfframpUpdates []router.RouterOffRamp + offrampSourceChainConfigArgs []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs + premiumMultiplierWeiPerEthUpdatesArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampPremiumMultiplierWeiPerEthArgs + priceUpdates price_registry.InternalPriceUpdates ) - for _, chainToConnect := range chainsToConnectTo { - chainSelector, ok := chainsel.EvmChainIdToChainSelector()[uint64(chainToConnect)] - require.Truef(t, ok, "chain selector not found for chain id %d", chainToConnect) + for _, destChainID := range chainsToConnectTo { onrampDestChainConfigArgs = append(onrampDestChainConfigArgs, evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ - DestChainSelector: chainSelector, + DestChainSelector: destChainID, DynamicConfig: evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainDynamicConfig{ IsEnabled: true, MaxNumberOfTokensPerMsg: 10, @@ -269,37 +271,64 @@ func fullyConnectCCIPContracts( }, }) - remoteUni, ok := universes[chainID] - require.Truef(t, ok, "could not find universe for chain id %d", chainID) + remoteUni, ok := universes[destChainID] + require.Truef(t, ok, "could not find universe for chain id %d", destChainID) offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ - SourceChainSelector: chainSelector, + SourceChainSelector: sourceChainID, IsEnabled: true, OnRamp: remoteUni.onramp.Address(), }) + premiumMultiplierWeiPerEthUpdatesArgs = append(premiumMultiplierWeiPerEthUpdatesArgs, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampPremiumMultiplierWeiPerEthArgs{ + PremiumMultiplierWeiPerEth: 2e18, + Token: remoteUni.linkToken.Address(), + }) + // onramps are multi-dest and offramps are multi-source. // so set the same ramp for all the chain selectors. routerOnrampUpdates = append(routerOnrampUpdates, router.RouterOnRamp{ - DestChainSelector: chainSelector, - OnRamp: uni.onramp.Address(), + DestChainSelector: destChainID, + OnRamp: remoteUni.onramp.Address(), }) routerOfframpUpdates = append(routerOfframpUpdates, router.RouterOffRamp{ - SourceChainSelector: chainSelector, + SourceChainSelector: sourceChainID, OffRamp: uni.offramp.Address(), }) + + priceUpdates.GasPriceUpdates = append(priceUpdates.GasPriceUpdates, price_registry.InternalGasPriceUpdate{ + DestChainSelector: destChainID, + UsdPerUnitGas: big.NewInt(1e18), + }) + + priceUpdates.TokenPriceUpdates = append(priceUpdates.TokenPriceUpdates, price_registry.InternalTokenPriceUpdate{ + SourceToken: uni.linkToken.Address(), + UsdPerToken: big.NewInt(1e18), + }) } + //===========================OnRamp===================================== _, err := uni.onramp.ApplyDestChainConfigUpdates(owner, onrampDestChainConfigArgs) - require.NoErrorf(t, err, "failed to apply dest chain config updates on onramp on chain id %d", chainID) + require.NoErrorf(t, err, "failed to apply dest chain config updates on onramp on chain id %d", sourceChainID) + uni.backend.Commit() + _, err = uni.onramp.ApplyPremiumMultiplierWeiPerEthUpdates(owner, premiumMultiplierWeiPerEthUpdatesArgs) + require.NoErrorf(t, err, "failed to apply premium multiplier wei per eth updates on onramp on chain id %d", sourceChainID) uni.backend.Commit() + //===========================OffRamp===================================== _, err = uni.offramp.ApplySourceChainConfigUpdates(owner, offrampSourceChainConfigArgs) - require.NoErrorf(t, err, "failed to apply source chain config updates on offramp on chain id %d", chainID) + require.NoErrorf(t, err, "failed to apply source chain config updates on offramp on chain id %d", sourceChainID) uni.backend.Commit() + //===========================RouterRamp===================================== _, err = uni.router.ApplyRampUpdates(owner, routerOnrampUpdates, []router.RouterOffRamp{}, routerOfframpUpdates) - require.NoErrorf(t, err, "failed to apply ramp updates on router on chain id %d", chainID) + require.NoErrorf(t, err, "failed to apply ramp updates on router on chain id %d", sourceChainID) + uni.backend.Commit() + + //===========================PriceRegistry===================================== + _, err = uni.priceRegistry.UpdatePrices(owner, priceUpdates) + require.NoErrorf(t, err, "failed to apply price registry updates on chain id %d", sourceChainID) uni.backend.Commit() } } @@ -312,3 +341,27 @@ func filter[T any](s []T, cond func(arg T) bool) (r []T) { } return } + +func createChains(t *testing.T, numChains int) (owner *bind.TransactOpts, chains map[uint64]*backends.SimulatedBackend) { + owner = testutils.MustNewSimTransactor(t) + chains = make(map[uint64]*backends.SimulatedBackend) + + chains[homeChainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6) + + for chainID := uint64(chainsel.TEST_90000001.EvmChainID); chainID < uint64(chainsel.TEST_90000020.EvmChainID); chainID++ { + chains[chainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10000).ToInt(), + }, + }, 30e6) + + if len(chains) == numChains { + break + } + } + return +} diff --git a/core/services/ocr3/plugins/ccip_integration_tests/helpers_old.go b/core/services/ocr3/plugins/ccip_integration_tests/helpers_old.go index c84df3b6e8..5c01f4c6e9 100644 --- a/core/services/ocr3/plugins/ccip_integration_tests/helpers_old.go +++ b/core/services/ocr3/plugins/ccip_integration_tests/helpers_old.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" gethtypes "github.com/ethereum/go-ethereum/core/types" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-common/pkg/config" @@ -44,7 +43,7 @@ func setupNodeOCR3( t *testing.T, owner *bind.TransactOpts, port int, - chainIDToBackend map[int64]*backends.SimulatedBackend, + chainIDToBackend map[uint64]*backends.SimulatedBackend, ) *ocr3Node { // Do not want to load fixtures as they contain a dummy chainID. config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { @@ -70,7 +69,7 @@ func setupNodeOCR3( var chains v2toml.EVMConfigs for chainID := range chainIDToBackend { - chains = append(chains, createConfigV2Chain(big.NewInt(chainID))) + chains = append(chains, createConfigV2Chain(big.NewInt(int64(chainID)))) } c.EVM = chains c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) @@ -79,10 +78,12 @@ func setupNodeOCR3( lggr := logger.TestLogger(t) lggr.SetLogLevel(zapcore.InfoLevel) ctx := testutils.Context(t) - clients := make(map[int64]client.Client) + clients := make(map[uint64]client.Client) for chainID, backend := range chainIDToBackend { - clients[chainID] = client.NewSimulatedBackendClient(t, backend, big.NewInt(chainID)) + cID := big.Int{} + cID.SetUint64(chainID) + clients[chainID] = client.NewSimulatedBackendClient(t, backend, &cID) } master := keystore.New(db, utils.FastScryptParams, lggr) @@ -100,7 +101,7 @@ func setupNodeOCR3( AppConfig: config, GenEthClient: func(i *big.Int) client.Client { t.Log("genning eth client for chain id:", i.String()) - client, ok := clients[i.Int64()] + client, ok := clients[i.Uint64()] if !ok { t.Fatal("no backend for chainID", i) } @@ -145,9 +146,11 @@ func setupNodeOCR3( peerID := p2pIDs[0].PeerID() // create a transmitter for each chain - transmitters := make(map[int64]common.Address) + transmitters := make(map[uint64]common.Address) for chainID, backend := range chainIDToBackend { - addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) + var cID big.Int + cID.SetUint64(chainID) + addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), &cID) require.NoError(t, err2) if len(addrs) == 1 { // just fund the address @@ -155,9 +158,9 @@ func setupNodeOCR3( transmitters[chainID] = addrs[0] } else { // create key and fund it - _, err3 := app.GetKeyStore().Eth().Create(testutils.Context(t), big.NewInt(chainID)) + _, err3 := app.GetKeyStore().Eth().Create(testutils.Context(t), &cID) require.NoError(t, err3, "failed to create key for chain", chainID) - sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) + sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), &cID) require.NoError(t, err3) require.Len(t, sendingKeys, 1) fundAddress(t, owner, sendingKeys[0], assets.Ether(10).ToInt(), backend) @@ -180,30 +183,6 @@ func setupNodeOCR3( } } -func createChains(t *testing.T, numChains int) (owner *bind.TransactOpts, chains map[int64]*backends.SimulatedBackend) { - owner = testutils.MustNewSimTransactor(t) - chains = make(map[int64]*backends.SimulatedBackend) - - chains[homeChainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ - owner.From: core.GenesisAccount{ - Balance: assets.Ether(10_000).ToInt(), - }, - }, 30e6) - - for chainID := int64(chainsel.TEST_90000001.EvmChainID); chainID < int64(chainsel.TEST_90000020.EvmChainID); chainID++ { - chains[chainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ - owner.From: core.GenesisAccount{ - Balance: assets.Ether(10000).ToInt(), - }, - }, 30e6) - - if len(chains) == numChains { - break - } - } - return -} - func ptr[T any](v T) *T { return &v } var _ keystore.Eth = &EthKeystoreSim{} diff --git a/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go b/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go index 768f0cc965..1fa7356d2f 100644 --- a/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go +++ b/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go @@ -4,25 +4,12 @@ import ( "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" pp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ping_pong_demo" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/link_token" ) var ( @@ -31,13 +18,8 @@ var ( ) func TestPingPong(t *testing.T) { - //ownerA, chainA := createChain(t) - //ownerB, chainB := createChain(t) owner, chains := createChains(t, 4) - //====================================================InitializeContracts======================================== - //pingPongA := initializeChainContracts(t, chainAID, ownerA, chainA) - //pingPongB := initializeChainContracts(t, chainBID, ownerB, chainB) homeChainUni, universes := deployContracts(t, owner, chains) fullyConnectCCIPContracts(t, owner, universes) _, err := homeChainUni.capabilityRegistry.AddCapabilities(owner, []kcr.CapabilitiesRegistryCapability{ @@ -52,143 +34,72 @@ func TestPingPong(t *testing.T) { require.NoError(t, err, "failed to add capabilities to the capability registry") homeChainUni.backend.Commit() - //====================================================Prepare PingPongs======================================== - //_, err := pingPongA.SetCounterpart(ownerA, chainBID, pingPongB.Address()) - //require.NoError(t, err) - //_, err = pingPongB.SetCounterpart(ownerB, chainAID, pingPongA.Address()) - //require.NoError(t, err) - // - ////====================================================Start PingPong======================================== - //_, err = pingPongA.StartPingPong(ownerA) - //require.NoError(t, err) - //_, err = pingPongB.StartPingPong(ownerB) - //require.NoError(t, err) + pingPongs := initializePingPongContracts(t, owner, universes) + for chainID, universe := range universes { + //backend := universe.backend + //simClient := client.NewSimulatedBackendClient(t, backend, big.NewInt(chainID)) + for otherChain, pingPong := range pingPongs[chainID] { + println(otherChain) + //chainSel, err := pingPong.GetCounterpartChainSelector(&bind.CallOpts{}) + //require.NoError(t, err) + //require.Equal(t, chainSel, otherChain) + // + //otherChainSel, err := pingPongs[otherChain][chainID].GetCounterpartChainSelector(&bind.CallOpts{}) + //require.NoError(t, err) + //require.Equal(t, otherChainSel, chainID) + // + //routerAddr, err := pingPong.GetRouter(&bind.CallOpts{}) + //require.NoError(t, err) + //require.NotEqual(t, routerAddr, nil) + + _, err := pingPong.StartPingPong(owner) + require.NoError(t, err) + universe.backend.Commit() + } + } } -func createChain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend) { - owner := testutils.MustNewSimTransactor(t) - - chain := backends.NewSimulatedBackend(core.GenesisAlloc{ - owner.From: core.GenesisAccount{ - Balance: assets.Ether(10_000).ToInt(), - }, - }, 30e6) - - chain.Commit() - return owner, chain -} - -func initializeChainContracts(t *testing.T, - chainID uint64, +// InitializeContracts initializes ping pong contracts on all chains and +// connects them all to each other. +func initializePingPongContracts( + t *testing.T, owner *bind.TransactOpts, - backend *backends.SimulatedBackend) *pp.PingPongDemo { - linkAddr, _, _, err := link_token.DeployLinkToken(owner, backend) - require.NoErrorf(t, err, "failed to deploy link token on chain id %d", chainID) - backend.Commit() - - linkToken, err := link_token.NewLinkToken(linkAddr, backend) - require.NoError(t, err) - require.NotEqual(t, linkToken, nil) - - rmnAddr, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) - require.NoErrorf(t, err, "failed to deploy mock arm on chain id %d", chainID) - backend.Commit() - - rmn, err := mock_arm_contract.NewMockARMContract(rmnAddr, backend) - require.NoError(t, err) - require.NotEqual(t, rmn, nil) - - rmnProxyAddr, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, rmnAddr) - require.NoErrorf(t, err, "failed to deploy arm proxy on chain id %d", chainID) - backend.Commit() - - rmnProxy, err := arm_proxy_contract.NewARMProxyContract(rmnProxyAddr, backend) - require.NoError(t, err) - require.NotEqual(t, rmnProxy, nil) - - wethAddr, _, _, err := weth9.DeployWETH9(owner, backend) - require.NoErrorf(t, err, "failed to deploy weth contract on chain id %d", chainID) - backend.Commit() - - weth, err := weth9.NewWETH9(wethAddr, backend) - require.NoError(t, err) - require.NotEqual(t, weth, nil) - - routerAddr, _, _, err := router.DeployRouter(owner, backend, wethAddr, rmnProxyAddr) - require.NoErrorf(t, err, "failed to deploy router on chain id %d", chainID) - backend.Commit() - - rout, err := router.NewRouter(routerAddr, backend) - require.NoError(t, err) - require.NotEqual(t, rout, nil) - priceRegistryAddr, _, _, err := price_registry.DeployPriceRegistry(owner, backend, []common.Address{}, []common.Address{ - linkToken.Address(), - }, 24*60*60, []price_registry.PriceRegistryTokenPriceFeedUpdate{}) - require.NoError(t, err, "failed to deploy price registry on chain id %d", chainID) - backend.Commit() - - priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, backend) - require.NoError(t, err) - require.NotEqual(t, priceRegistry, nil) - - tarAddr, _, _, err := token_admin_registry.DeployTokenAdminRegistry(owner, backend) - require.NoErrorf(t, err, "failed to deploy token admin registry on chain id %d", chainID) - backend.Commit() - - tokenAdminRegistry, err := token_admin_registry.NewTokenAdminRegistry(tarAddr, backend) - require.NoError(t, err) - require.NotEqual(t, tokenAdminRegistry, nil) - - chainSelector, ok := chainsel.EvmChainIdToChainSelector()[uint64(chainID)] - require.Truef(t, ok, "chain selector for chain id %d not found", chainID) - - onrampAddr, _, _, err := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( - owner, - backend, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ - LinkToken: linkAddr, - ChainSelector: chainSelector, - RmnProxy: rmnProxyAddr, - }, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ - Router: routerAddr, - PriceRegistry: priceRegistryAddr, - }, - // can set this later once all chains are deployed - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, - // disabled for simplicity - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampPremiumMultiplierWeiPerEthArgs{}, - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampTokenTransferFeeConfigArgs{}, - ) - require.NoErrorf(t, err, "failed to deploy onramp on chain id %d", chainID) - backend.Commit() - - onramp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(onrampAddr, backend) - require.NoError(t, err) - require.NotEqual(t, onramp, nil) - - offrampAddr, _, _, err := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( - owner, - backend, - evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ - ChainSelector: chainSelector, - RmnProxy: rmnProxyAddr, - TokenAdminRegistry: tarAddr, - }, - // can fill this in later once all chains are deployed - []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, - ) - require.NoErrorf(t, err, "failed to deploy offramp on chain id %d", chainID) - backend.Commit() - - offramp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(offrampAddr, backend) - require.NoError(t, err) - require.NotEqual(t, offramp, nil) - - pingPongAddr, _, _, err := pp.DeployPingPongDemo(owner, backend, routerAddr, linkAddr) - require.NoError(t, err) - pingPong, err := pp.NewPingPongDemo(pingPongAddr, backend) - require.NotEqual(t, pingPongAddr, nil) - - return pingPong + chainUniverses map[uint64]onchainUniverse, +) map[uint64]map[uint64]*pp.PingPongDemo { + pingPongs := make(map[uint64]map[uint64]*pp.PingPongDemo) + chainIDs := maps.Keys(chainUniverses) + // For each chain initialize N ping pong contracts, where N is the (number of chains - 1) + for chainID, universe := range chainUniverses { + chainsToConnectTo := filter(chainIDs, func(chainIDArg uint64) bool { + return chainIDArg != chainID + }) + pingPongs[chainID] = make(map[uint64]*pp.PingPongDemo) + for _, chainToConnect := range chainsToConnectTo { + backend := universe.backend + pingPongAddr, _, _, err := pp.DeployPingPongDemo(owner, backend, universe.router.Address(), universe.linkToken.Address()) + require.NoError(t, err) + backend.Commit() + pingPong, err := pp.NewPingPongDemo(pingPongAddr, backend) + require.NoError(t, err) + universe.backend.Commit() + + pingPongs[chainID][chainToConnect] = pingPong + } + } + + // Connect each ping pong contract to its counterpart on the other chain + for chainID, universe := range chainUniverses { + for chainToConnect, pingPong := range pingPongs[chainID] { + println("Setting counterpart ping pong contract on chain", chainID, "to chain", chainToConnect) + _, err := pingPong.SetCounterpart( + owner, + chainUniverses[chainToConnect].chainID, + // This is the address of the ping pong contract on the other chain + pingPongs[chainToConnect][chainID].Address(), + ) + require.NoError(t, err) + universe.backend.Commit() + } + } + return pingPongs }