Skip to content

Commit

Permalink
Fix: OnRamp discovery (#249)
Browse files Browse the repository at this point in the history
Use another chainSelector other than self to get the destChainConfig
Fix onRampDynamicConfig type to match on-chain
Note: It was silently failing to get the onRampDynamicConfig so we were seeing only the symptoms when we were not able to read NativeToken as the flow is:

Get Router address
Get OnRamp Address
Get wrapped token address from Router (step 1)
Get FeeQuoter address from OnRamp (step 2)
Get native token using fee quoter and the wrapped token address.
  • Loading branch information
asoliman92 authored Oct 21, 2024
1 parent 4ab500f commit e5f3ecb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ccip-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ jobs:
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
with:
repository: smartcontractkit/chainlink
ref: develop
# ref: develop
ref: fix-fee-quoter
path: chainlink
- name: Get the correct commit SHA via GitHub API
id: get_sha
Expand Down
38 changes: 26 additions & 12 deletions pkg/reader/ccip.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ func (r *ccipChainReader) DiscoverContracts(ctx context.Context) (ContractAddres
return nil, fmt.Errorf("unable to lookup source fee quoters (onRamp dynamic config): %w", err)
} else {
for chain, cfg := range dynamicConfigs {
resp = resp.Append(consts.ContractNameFeeQuoter, chain, cfg.FeeQuoter)
resp = resp.Append(consts.ContractNameFeeQuoter, chain, cfg.DynamicConfig.FeeQuoter)
}
}
}
Expand Down Expand Up @@ -1087,22 +1087,31 @@ func (r *ccipChainReader) getDestinationData(
}

// See DynamicChainConfig in OnRamp.sol
type onRampDynamicChainConfig struct {
FeeQuoter []byte `json:"feeQuoter"`
MessageValidator []byte `json:"messageValidator"`
FeeAggregator []byte `json:"feeAggregator"`
AllowListAdmin []byte `json:"allowListAdmin"`
type onRampDynamicConfig struct {
FeeQuoter []byte `json:"feeQuoter"`
ReentrancyGuardEntered bool `json:"reentrancyGuardEntered"`
MessageInterceptor []byte `json:"messageInterceptor"`
FeeAggregator []byte `json:"feeAggregator"`
AllowListAdmin []byte `json:"allowListAdmin"`
}

// We're wrapping the onRampDynamicConfig this way to map to on-chain return type which is a named struct
// https://github.com/smartcontractkit/chainlink/blob/12af1de88238e0e918177d6b5622070417f48adf/contracts/src/v0.8/ccip/onRamp/OnRamp.sol#L328
//
//nolint:lll
type getOnRampDynamicConfigResponse struct {
DynamicConfig onRampDynamicConfig `json:"dynamicConfig"`
}

func (r *ccipChainReader) getOnRampDynamicConfigs(
ctx context.Context,
srcChains []cciptypes.ChainSelector,
) (map[cciptypes.ChainSelector]onRampDynamicChainConfig, error) {
) (map[cciptypes.ChainSelector]getOnRampDynamicConfigResponse, error) {
if err := validateExtendedReaderExistence(r.contractReaders, srcChains...); err != nil {
return nil, err
}

result := make(map[cciptypes.ChainSelector]onRampDynamicChainConfig)
result := make(map[cciptypes.ChainSelector]getOnRampDynamicConfigResponse)

mu := new(sync.Mutex)
eg := new(errgroup.Group)
Expand All @@ -1115,7 +1124,7 @@ func (r *ccipChainReader) getOnRampDynamicConfigs(
chainSel := chainSel
eg.Go(func() error {
// read onramp dynamic config
resp := onRampDynamicChainConfig{}
resp := getOnRampDynamicConfigResponse{}
err := r.contractReaders[chainSel].ExtendedGetLatestValue(
ctx,
consts.ContractNameOnRamp,
Expand All @@ -1124,6 +1133,9 @@ func (r *ccipChainReader) getOnRampDynamicConfigs(
map[string]any{},
&resp,
)
r.lggr.Debugw("got onramp dynamic config",
"chain", chainSel,
"resp", resp)
if err != nil {
return fmt.Errorf("failed to get onramp dynamic config: %w", err)
}
Expand Down Expand Up @@ -1166,22 +1178,24 @@ func (r *ccipChainReader) getOnRampDestChainConfig(
continue
}

// For chain X, all DestChainConfigs will have one of 2 values for the Router address
// 1. Chain X Test Router in case we're testing a new lane
// 2. Chain X Router
chainSel := chainSel
eg.Go(func() error {
// read onramp dynamic config
resp := onRampDestChainConfig{}
err := r.contractReaders[chainSel].ExtendedGetLatestValue(
ctx,
consts.ContractNameOnRamp,
consts.MethodNameOnRampGetDestChainConfig,
primitives.Unconfirmed,
map[string]any{
"destChainSelector": chainSel,
"destChainSelector": r.destChain,
},
&resp,
)
if err != nil {
return fmt.Errorf("failed to get onramp dynamic config: %w", err)
return fmt.Errorf("failed to get onramp dest chain config: %w", err)
}
mu.Lock()
result[chainSel] = resp
Expand Down
8 changes: 4 additions & 4 deletions pkg/reader/ccip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ func TestCCIPChainReader_DiscoverContracts_HappyPath_Round1(t *testing.T) {
consts.MethodNameOnRampGetDestChainConfig,
primitives.Unconfirmed,
map[string]any{
"destChainSelector": selector,
"destChainSelector": destChain,
},
mock.Anything,
).Return(contractreader.ErrNoBindings)
Expand Down Expand Up @@ -600,8 +600,8 @@ func TestCCIPChainReader_DiscoverContracts_HappyPath_Round2(t *testing.T) {
map[string]any{},
mock.Anything,
).Return(nil).Run(withReturnValueOverridden(func(returnVal interface{}) {
v := returnVal.(*onRampDynamicChainConfig)
v.FeeQuoter = srcFeeQuoters[i]
v := returnVal.(*getOnRampDynamicConfigResponse)
v.DynamicConfig.FeeQuoter = srcFeeQuoters[i]
}))

mockReaders[selector].EXPECT().ExtendedGetLatestValue(
Expand All @@ -610,7 +610,7 @@ func TestCCIPChainReader_DiscoverContracts_HappyPath_Round2(t *testing.T) {
consts.MethodNameOnRampGetDestChainConfig,
primitives.Unconfirmed,
map[string]any{
"destChainSelector": selector,
"destChainSelector": destChain,
},
mock.Anything,
).Return(nil).Run(withReturnValueOverridden(func(returnVal interface{}) {
Expand Down

0 comments on commit e5f3ecb

Please sign in to comment.