@@ -339,7 +339,7 @@ func (c CCIPChainState) validateAllDestChainConfigs(
339339 }
340340
341341 if v16Cfg != nil {
342- if err := c .validateV16DestChainConfig (callOpts , sourceChainSel , destChainSel , * v16Cfg , legacyCfg , v16FeeTokens ); err != nil {
342+ if err := c .validateV16DestChainConfig (callOpts , sourceChainSel , destChainSel , * v16Cfg , legacyCfg ); err != nil {
343343 errs = append (errs , err )
344344 }
345345 }
@@ -359,7 +359,6 @@ func (c CCIPChainState) validateV16DestChainConfig(
359359 sourceChainSel , destChainSel uint64 ,
360360 destCfg fee_quoter.FeeQuoterDestChainConfig ,
361361 legacyCfg * evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig ,
362- feeTokens []common.Address ,
363362) error {
364363 header := fmt .Sprintf ("FeeQuoter v1.6 %s dest chain %d" , c .FeeQuoter .Address ().Hex (), destChainSel )
365364
@@ -380,56 +379,44 @@ func (c CCIPChainState) validateV16DestChainConfig(
380379 {"MaxDataBytes" , uint64 (destCfg .MaxDataBytes ), uint64 (legacyCfg .MaxDataBytes )},
381380 {"MaxPerMsgGasLimit" , uint64 (destCfg .MaxPerMsgGasLimit ), uint64 (legacyCfg .MaxPerMsgGasLimit )},
382381 {"DefaultTokenDestGasOverhead" , uint64 (destCfg .DefaultTokenDestGasOverhead ), uint64 (legacyCfg .DefaultTokenDestGasOverhead )},
383- {"DefaultTokenFeeUSDCents" , uint64 (destCfg .DefaultTokenFeeUSDCents ), uint64 (legacyCfg .DefaultTokenFeeUSDCents )},
384382 {"EnforceOutOfOrder" , destCfg .EnforceOutOfOrder , legacyCfg .EnforceOutOfOrder },
385383 {"DestGasPerPayloadByteBase" , uint64 (destCfg .DestGasPerPayloadByteBase ), uint64 (uint8 (legacyCfg .DestGasPerPayloadByte ))}, //nolint:gosec // G115: intentional v1.5 uint16->uint8 truncation during migration
386384 }); err != nil {
387385 errs = append (errs , err )
388386 }
389-
390- // GasMultiplierWeiPerEth moved from per-token to per-dest in v1.6
391- for _ , ft := range feeTokens {
392- legacyOnRamp := c .EVM2EVMOnRamp [destChainSel ]
393- if legacyOnRamp == nil {
394- break
395- }
396- legacyFTCfg , err := legacyOnRamp .GetFeeTokenConfig (callOpts , ft )
397- if err != nil || ! legacyFTCfg .Enabled {
398- continue
399- }
400- if destCfg .GasMultiplierWeiPerEth != legacyFTCfg .GasMultiplierWeiPerEth {
401- errs = append (errs , fmt .Errorf ("GasMultiplierWeiPerEth: v1.6=%d, v1.5 FeeTokenConfig=%d" ,
402- destCfg .GasMultiplierWeiPerEth , legacyFTCfg .GasMultiplierWeiPerEth ))
403- }
404- break
405- }
406- } else {
407- // No legacy to cross-check — validate fee-related fields against expected values
408- expectedFee := expectedDefaultTokenFeeUSDCents (sourceChainSel , destChainSel )
409- if uint64 (destCfg .DefaultTokenFeeUSDCents ) != uint64 (expectedFee ) {
410- errs = append (errs , fmt .Errorf ("DefaultTokenFeeUSDCents: got=%d, want=%d" , destCfg .DefaultTokenFeeUSDCents , expectedFee ))
411- }
412387 }
413388
414- // v1.6 business-rule fields (always checked )
389+ // v1.6 field checks (always applied )
415390 if destCfg .ChainFamilySelector == [4 ]byte {} {
416391 errs = append (errs , errors .New ("ChainFamilySelector is empty" ))
417392 }
418- if destCfg .GasPriceStalenessThreshold == 0 {
393+ // GasPriceStalenessThreshold: compare against v1.5 PriceRegistry when present; else require non-zero.
394+ if c .PriceRegistry != nil {
395+ st , stErr := c .PriceRegistry .GetStalenessThreshold (callOpts )
396+ if stErr != nil {
397+ errs = append (errs , fmt .Errorf ("failed to get staleness threshold from v1.5 PriceRegistry: %w" , stErr ))
398+ } else if ! st .IsUint64 () || st .Uint64 () > uint64 (^ uint32 (0 )) {
399+ errs = append (errs , fmt .Errorf ("v1.5 PriceRegistry StalenessThreshold %s overflows uint32" , st .String ()))
400+ } else if want := uint32 (st .Uint64 ()); want != destCfg .GasPriceStalenessThreshold { //nolint:gosec // G115: safe, verified <= MaxUint32
401+ errs = append (errs , fmt .Errorf ("v1.5<->v1.6:\n GasPriceStalenessThreshold: got=%d, want=%d" ,
402+ destCfg .GasPriceStalenessThreshold , want ))
403+ }
404+ } else if destCfg .GasPriceStalenessThreshold == 0 {
419405 errs = append (errs , errors .New ("GasPriceStalenessThreshold is 0" ))
420406 }
421- if err := compareFieldChecks ("business rules " , []fieldCheck {
407+ if err := compareFieldChecks ("deploy-constants " , []fieldCheck {
422408 {"DestGasPerPayloadByteHigh" , uint64 (destCfg .DestGasPerPayloadByteHigh ), uint64 (ccipevm .CalldataGasPerByteHigh )},
423409 {"DestGasPerPayloadByteThreshold" , uint64 (destCfg .DestGasPerPayloadByteThreshold ), uint64 (ccipevm .CalldataGasPerByteThreshold )},
424410 {"DefaultTxGasLimit" , uint64 (destCfg .DefaultTxGasLimit ), uint64 (200_000 )},
425- {"NetworkFeeUSDCents " , uint64 ( destCfg .NetworkFeeUSDCents ) , uint64 (expectedNetworkFeeUSDCents ( sourceChainSel , destChainSel ) )},
411+ {"GasMultiplierWeiPerEth " , destCfg .GasMultiplierWeiPerEth , uint64 (11e17 )},
426412 }); err != nil {
427413 errs = append (errs , err )
428414 }
429-
430- destFamily , _ := chain_selectors .GetSelectorFamily (destChainSel )
431- if destFamily != chain_selectors .FamilyEVM && ! destCfg .EnforceOutOfOrder {
432- errs = append (errs , fmt .Errorf ("EnforceOutOfOrder must be true for non-EVM dest (family %s)" , destFamily ))
415+ if err := compareFieldChecks ("topology" , []fieldCheck {
416+ {"NetworkFeeUSDCents" , uint64 (destCfg .NetworkFeeUSDCents ), uint64 (expectedNetworkFeeUSDCents (sourceChainSel , destChainSel ))},
417+ {"DefaultTokenFeeUSDCents" , uint64 (destCfg .DefaultTokenFeeUSDCents ), uint64 (expectedDefaultTokenFeeUSDCents (sourceChainSel , destChainSel ))},
418+ }); err != nil {
419+ errs = append (errs , err )
433420 }
434421
435422 return groupErrors (header , errs )
@@ -456,27 +443,30 @@ func (c CCIPChainState) validateV20DestChainConfig(
456443 if destCfgV2 .ChainFamilySelector == [4 ]byte {} {
457444 errs = append (errs , errors .New ("ChainFamilySelector is empty" ))
458445 }
459- if err := compareFieldChecks ("business rules " , []fieldCheck {
446+ if err := compareFieldChecks ("deploy-constants " , []fieldCheck {
460447 {"LinkFeeMultiplierPercent" , uint64 (destCfgV2 .LinkFeeMultiplierPercent ), uint64 (fqv2seq .LinkFeeMultiplierPercent )},
461- {"NetworkFeeUSDCents" , uint64 (destCfgV2 .NetworkFeeUSDCents ), uint64 (expectedNetworkFeeUSDCents (sourceChainSel , destChainSel ))},
462448 {"DefaultTxGasLimit" , uint64 (destCfgV2 .DefaultTxGasLimit ), uint64 (200_000 )},
463449 }); err != nil {
464450 errs = append (errs , err )
465451 }
452+ if err := compareFieldChecks ("topology" , []fieldCheck {
453+ {"NetworkFeeUSDCents" , uint64 (destCfgV2 .NetworkFeeUSDCents ), uint64 (expectedNetworkFeeUSDCents (sourceChainSel , destChainSel ))},
454+ {"DefaultTokenFeeUSDCents" , uint64 (destCfgV2 .DefaultTokenFeeUSDCents ), uint64 (expectedDefaultTokenFeeUSDCents (sourceChainSel , destChainSel ))},
455+ }); err != nil {
456+ errs = append (errs , err )
457+ }
466458
467- // Cross-version field mapping: v1.6 <-> v2.0
459+ // Cross-version field mapping: v1.6 <-> v2.0 (v2.0 is got, v1.6 is want)
468460 if v16Cfg != nil {
469461 if err := compareFieldChecks ("v1.6<->v2.0" , []fieldCheck {
470- {"IsEnabled" , v16Cfg .IsEnabled , destCfgV2 .IsEnabled },
471- {"MaxDataBytes" , uint64 (v16Cfg .MaxDataBytes ), uint64 (destCfgV2 .MaxDataBytes )},
472- {"MaxPerMsgGasLimit" , uint64 (v16Cfg .MaxPerMsgGasLimit ), uint64 (destCfgV2 .MaxPerMsgGasLimit )},
473- {"DestGasOverhead" , uint64 (v16Cfg .DestGasOverhead ), uint64 (destCfgV2 .DestGasOverhead )},
474- {"DestGasPerPayloadByteBase" , uint64 (v16Cfg .DestGasPerPayloadByteBase ), uint64 (destCfgV2 .DestGasPerPayloadByteBase )},
475- {"ChainFamilySelector" , v16Cfg .ChainFamilySelector , destCfgV2 .ChainFamilySelector },
476- {"DefaultTokenFeeUSDCents" , uint64 (v16Cfg .DefaultTokenFeeUSDCents ), uint64 (destCfgV2 .DefaultTokenFeeUSDCents )},
477- {"DefaultTokenDestGasOverhead" , uint64 (v16Cfg .DefaultTokenDestGasOverhead ), uint64 (destCfgV2 .DefaultTokenDestGasOverhead )},
478- {"DefaultTxGasLimit" , uint64 (v16Cfg .DefaultTxGasLimit ), uint64 (destCfgV2 .DefaultTxGasLimit )},
479- {"NetworkFeeUSDCents" , uint64 (v16Cfg .NetworkFeeUSDCents ), uint64 (destCfgV2 .NetworkFeeUSDCents )},
462+ {"IsEnabled" , destCfgV2 .IsEnabled , v16Cfg .IsEnabled },
463+ {"MaxDataBytes" , uint64 (destCfgV2 .MaxDataBytes ), uint64 (v16Cfg .MaxDataBytes )},
464+ {"MaxPerMsgGasLimit" , uint64 (destCfgV2 .MaxPerMsgGasLimit ), uint64 (v16Cfg .MaxPerMsgGasLimit )},
465+ {"DestGasOverhead" , uint64 (destCfgV2 .DestGasOverhead ), uint64 (v16Cfg .DestGasOverhead )},
466+ {"DestGasPerPayloadByteBase" , uint64 (destCfgV2 .DestGasPerPayloadByteBase ), uint64 (v16Cfg .DestGasPerPayloadByteBase )},
467+ {"ChainFamilySelector" , destCfgV2 .ChainFamilySelector , v16Cfg .ChainFamilySelector },
468+ {"DefaultTokenDestGasOverhead" , uint64 (destCfgV2 .DefaultTokenDestGasOverhead ), uint64 (v16Cfg .DefaultTokenDestGasOverhead )},
469+ {"DefaultTxGasLimit" , uint64 (destCfgV2 .DefaultTxGasLimit ), uint64 (v16Cfg .DefaultTxGasLimit )},
480470 }); err != nil {
481471 errs = append (errs , err )
482472 }
@@ -489,25 +479,8 @@ func (c CCIPChainState) validateV20DestChainConfig(
489479 {"MaxDataBytes" , uint64 (destCfgV2 .MaxDataBytes ), uint64 (legacyCfg .MaxDataBytes )},
490480 {"MaxPerMsgGasLimit" , uint64 (destCfgV2 .MaxPerMsgGasLimit ), uint64 (legacyCfg .MaxPerMsgGasLimit )},
491481 {"DefaultTokenDestGasOverhead" , uint64 (destCfgV2 .DefaultTokenDestGasOverhead ), uint64 (legacyCfg .DefaultTokenDestGasOverhead )},
492- {"DefaultTokenFeeUSDCents" , uint64 (destCfgV2 .DefaultTokenFeeUSDCents ), uint64 (legacyCfg .DefaultTokenFeeUSDCents )},
493482 {"DestGasPerPayloadByteBase" , uint64 (destCfgV2 .DestGasPerPayloadByteBase ), uint64 (uint8 (legacyCfg .DestGasPerPayloadByte ))}, //nolint:gosec // G115: intentional v1.5 uint16->uint8 truncation during migration
494483 }
495- // NetworkFeeUSDCents: per-token in v1.5, per-dest in v2.0. Fetch from v1.5 FeeTokenConfig
496- if legacyOnRamp := c .EVM2EVMOnRamp [destChainSel ]; legacyOnRamp != nil {
497- v16FeeTokens , ftErr := c .FeeQuoter .GetFeeTokens (callOpts )
498- if ftErr == nil {
499- for _ , ft := range v16FeeTokens {
500- legacyFTCfg , err := legacyOnRamp .GetFeeTokenConfig (callOpts , ft )
501- if err != nil || ! legacyFTCfg .Enabled {
502- continue
503- }
504- v15Checks = append (v15Checks ,
505- fieldCheck {"NetworkFeeUSDCents" , uint64 (destCfgV2 .NetworkFeeUSDCents ), uint64 (legacyFTCfg .NetworkFeeUSDCents )},
506- )
507- break
508- }
509- }
510- }
511484 if err := compareFieldChecks ("v1.5<->v2.0" , v15Checks ); err != nil {
512485 errs = append (errs , err )
513486 }
0 commit comments