@@ -543,6 +543,89 @@ func TestUpdateBidirectionalLanesChangesetWithV2FeeQuoter(t *testing.T) {
543543 }
544544}
545545
546+ func TestFilterOutExistingDestChainConfigs (t * testing.T ) {
547+ t .Parallel ()
548+
549+ deployedEnvironment , _ := testhelpers .NewMemoryEnvironment (t , func (testCfg * testhelpers.TestConfigs ) {
550+ testCfg .Chains = 2
551+ })
552+ e := deployedEnvironment .Env
553+
554+ state , err := stateview .LoadOnchainState (e )
555+ require .NoError (t , err , "must load onchain state" )
556+
557+ selectors := e .BlockChains .ListChainSelectors (cldf_chain .WithFamily (chain_selectors .FamilyEVM ))
558+ require .Len (t , selectors , 2 , "must have 2 chains" )
559+
560+ chainSel := selectors [0 ]
561+ otherChainSel := selectors [1 ]
562+ evmChain := e .BlockChains .EVMChains ()[chainSel ]
563+
564+ parsedABI , err := abi .JSON (strings .NewReader (fqv2ops .FeeQuoterABI ))
565+ require .NoError (t , err , "must parse v2 FeeQuoter ABI" )
566+
567+ // Deploy a v2 FeeQuoter, then configure one destination (otherChainSel) after deployment.
568+ // Constructor-time dest config with sparse fields reverts, so we apply it post-deploy.
569+ fqV2Addr , tx , _ , err := bind .DeployContract (
570+ evmChain .DeployerKey ,
571+ parsedABI ,
572+ common .FromHex (fqv2ops .FeeQuoterBin ),
573+ evmChain .Client ,
574+ fqv2ops.StaticConfig {
575+ MaxFeeJuelsPerMsg : big .NewInt (1e18 ),
576+ LinkToken : state .Chains [chainSel ].LinkToken .Address (),
577+ },
578+ []common.Address {evmChain .DeployerKey .From },
579+ []fqv2ops.TokenTransferFeeConfigArgs {},
580+ []fqv2ops.DestChainConfigArgs {},
581+ )
582+ require .NoError (t , err , "must deploy v2 FeeQuoter" )
583+
584+ _ , err = evmChain .Confirm (tx )
585+ require .NoError (t , err , "must confirm v2 FeeQuoter deployment" )
586+
587+ fqV2 , err := fqv2ops .NewFeeQuoterContract (fqV2Addr , evmChain .Client )
588+ require .NoError (t , err , "must bind v2 FeeQuoter" )
589+
590+ // Convert a default v1.6 config to v2 format and apply it so otherChainSel is already enabled
591+ v2Cfgs , err := v1_6 .ConvertV16FeeQuoterDestUpdatesToV2 ([]fee_quoter.FeeQuoterDestChainConfigArgs {
592+ {
593+ DestChainSelector : otherChainSel ,
594+ DestChainConfig : v1_6 .DefaultFeeQuoterDestChainConfig (true ),
595+ },
596+ })
597+ require .NoError (t , err , "must convert v1.6 dest config to v2" )
598+
599+ applyTx , err := fqV2 .ApplyDestChainConfigUpdates (evmChain .DeployerKey , v2Cfgs )
600+ require .NoError (t , err , "must apply dest chain config" )
601+ _ , err = evmChain .Confirm (applyTx )
602+ require .NoError (t , err , "must confirm dest chain config tx" )
603+
604+ unconfiguredChainSel := uint64 (999 )
605+
606+ // Call FilterOutExistingDestChainConfigs with both destinations
607+ input := []fqv2ops.DestChainConfigArgs {
608+ {
609+ DestChainSelector : otherChainSel ,
610+ DestChainConfig : fqv2ops.DestChainConfig {IsEnabled : true , MaxDataBytes : 50_000 },
611+ },
612+ {
613+ DestChainSelector : unconfiguredChainSel ,
614+ DestChainConfig : fqv2ops.DestChainConfig {IsEnabled : true , MaxDataBytes : 60_000 },
615+ },
616+ }
617+
618+ filtered , err := v1_6 .FilterOutExistingDestChainConfigs (e , fqV2Addr , chainSel , input )
619+ require .NoError (t , err , "FilterOutExistingDestChainConfigs must not error" )
620+
621+ // Only the unconfigured chain should remain
622+ require .Len (t , filtered , 1 , "must filter out the already-enabled destination" )
623+ assert .Equal (t , unconfiguredChainSel , filtered [0 ].DestChainSelector ,
624+ "remaining entry must be the unconfigured chain" )
625+ assert .Equal (t , uint32 (60_000 ), filtered [0 ].DestChainConfig .MaxDataBytes ,
626+ "remaining entry must preserve original config" )
627+ }
628+
546629func TestUpdateBidirectionalLanesChangesetWithV2FeeQuoterWithMCMS (t * testing.T ) {
547630 t .Parallel ()
548631
0 commit comments