@@ -543,6 +543,94 @@ 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+ // Apply a dest chain config so otherChainSel is already enabled on-chain
591+ applyTx , err := fqV2 .ApplyDestChainConfigUpdates (evmChain .DeployerKey , []fqv2ops.DestChainConfigArgs {
592+ {
593+ DestChainSelector : otherChainSel ,
594+ DestChainConfig : fqv2ops.DestChainConfig {
595+ IsEnabled : true ,
596+ MaxDataBytes : 30_000 ,
597+ MaxPerMsgGasLimit : 3_000_000 ,
598+ DestGasOverhead : 50_000 ,
599+ DestGasPerPayloadByteBase : 16 ,
600+ ChainFamilySelector : [4 ]byte {0x28 , 0x12 , 0xd5 , 0x2c },
601+ DefaultTxGasLimit : 200_000 ,
602+ },
603+ },
604+ })
605+ require .NoError (t , err , "must apply dest chain config" )
606+ _ , err = evmChain .Confirm (applyTx )
607+ require .NoError (t , err , "must confirm dest chain config tx" )
608+
609+ unconfiguredChainSel := uint64 (999 )
610+
611+ // Call FilterOutExistingDestChainConfigs with both destinations
612+ input := []fqv2ops.DestChainConfigArgs {
613+ {
614+ DestChainSelector : otherChainSel ,
615+ DestChainConfig : fqv2ops.DestChainConfig {IsEnabled : true , MaxDataBytes : 50_000 },
616+ },
617+ {
618+ DestChainSelector : unconfiguredChainSel ,
619+ DestChainConfig : fqv2ops.DestChainConfig {IsEnabled : true , MaxDataBytes : 60_000 },
620+ },
621+ }
622+
623+ filtered , err := v1_6 .FilterOutExistingDestChainConfigs (e , fqV2Addr , chainSel , input )
624+ require .NoError (t , err , "FilterOutExistingDestChainConfigs must not error" )
625+
626+ // Only the unconfigured chain should remain
627+ require .Len (t , filtered , 1 , "must filter out the already-enabled destination" )
628+ assert .Equal (t , unconfiguredChainSel , filtered [0 ].DestChainSelector ,
629+ "remaining entry must be the unconfigured chain" )
630+ assert .Equal (t , uint32 (60_000 ), filtered [0 ].DestChainConfig .MaxDataBytes ,
631+ "remaining entry must preserve original config" )
632+ }
633+
546634func TestUpdateBidirectionalLanesChangesetWithV2FeeQuoterWithMCMS (t * testing.T ) {
547635 t .Parallel ()
548636
0 commit comments