Skip to content

Commit 3b87cec

Browse files
committed
adding test
1 parent b401802 commit 3b87cec

File tree

8 files changed

+301
-78
lines changed

8 files changed

+301
-78
lines changed

ccv/chains/evm/deployment/v1_7_0/adapters/feequoterupdater.go

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,47 +12,69 @@ import (
1212
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
1313
)
1414

15-
type FeeQuoterUpdater struct{}
15+
// feeQUpdateArgsFromConcrete converts the concrete v1.7 FeeQuoterUpdate to the type parameter (used as any when registered).
16+
func feeQUpdateArgsFromConcrete[T any](out sequence1_7.FeeQuoterUpdate) T {
17+
return any(out).(T)
18+
}
19+
20+
// FeeQuoterUpdater uses FeeQUpdateArgs any so it implements deploy.FeeQuoterUpdater[any] and can be registered directly.
21+
// The implementation is for v1.7.0 and uses sequence1_7.FeeQuoterUpdate internally.
22+
type FeeQuoterUpdater[FeeQUpdateArgs any] struct{}
1623

17-
func (fqu FeeQuoterUpdater) SequenceFeeQuoterInputCreation() *cldf_ops.Sequence[deploy.FeeQuoterUpdateInput, sequence1_7.FeeQuoterUpdate, cldf_chain.BlockChains] {
24+
func (fqu FeeQuoterUpdater[FeeQUpdateArgs]) SequenceFeeQuoterInputCreation() *cldf_ops.Sequence[deploy.FeeQuoterUpdateInput, FeeQUpdateArgs, cldf_chain.BlockChains] {
1825
return cldf_ops.NewSequence(
1926
"fee-quoter-updater:input-creation",
2027
semver.MustParse("1.7.0"),
2128
"Creates FeeQuoterUpdateInput for FeeQuoter update sequence",
22-
func(b cldf_ops.Bundle, chains cldf_chain.BlockChains, input deploy.FeeQuoterUpdateInput) (output sequence1_7.FeeQuoterUpdate, err error) {
29+
func(b cldf_ops.Bundle, chains cldf_chain.BlockChains, input deploy.FeeQuoterUpdateInput) (output FeeQUpdateArgs, err error) {
30+
var zero FeeQUpdateArgs
2331
chain, ok := chains.EVMChains()[input.ChainSelector]
2432
if !ok {
25-
return sequence1_7.FeeQuoterUpdate{}, fmt.Errorf("chain with selector %d not found in environment", input.ChainSelector)
33+
return zero, fmt.Errorf("chain with selector %d not found in environment", input.ChainSelector)
2634
}
2735
// get the FeeQuoterUpdateOutput from both v1.6.0 and v1.5.0 sequences and combine them to create the input for the fee quoter update sequence
2836
report, err := cldf_ops.ExecuteSequence(b, sequence1_7.CreateFeeQuoterUpdateInputFromV163, chain, input)
2937
if err != nil {
30-
return sequence1_7.FeeQuoterUpdate{}, fmt.Errorf("failed to create FeeQuoterUpdateInput from v1.6.0: %w", err)
38+
return zero, fmt.Errorf("failed to create FeeQuoterUpdateInput from v1.6.0: %w", err)
3139
}
3240
output16 := report.Output
3341

3442
report15, err := cldf_ops.ExecuteSequence(b, sequence1_7.CreateFeeQuoterUpdateInputFromV150, chain, input)
3543
if err != nil {
36-
return sequence1_7.FeeQuoterUpdate{}, fmt.Errorf("failed to create FeeQuoterUpdateInput from v1.5.0: %w", err)
44+
return zero, fmt.Errorf("failed to create FeeQuoterUpdateInput from v1.5.0: %w", err)
3745
}
3846
output15 := report15.Output
3947
// combine the outputs from both sequences to create the input for the fee quoter update sequence
40-
output, err = sequence1_7.MergeFeeQuoterUpdateOutputs(output16, output15)
48+
out, err := sequence1_7.MergeFeeQuoterUpdateOutputs(output16, output15)
4149
if err != nil {
42-
return sequence1_7.FeeQuoterUpdate{}, fmt.Errorf("failed to merge FeeQuoterUpdateInput from v1.6.0 and v1.5.0: %w", err)
50+
return zero, fmt.Errorf("failed to merge FeeQuoterUpdateInput from v1.6.0 and v1.5.0: %w", err)
4351
}
4452
// check if output is empty, if so, return an error
45-
if empty, err := output.IsEmpty(); err != nil || empty {
46-
return sequence1_7.FeeQuoterUpdate{},
47-
fmt.Errorf("could not create input for fee quoter 1.7 update sequence: %w", err)
53+
if empty, err := out.IsEmpty(); err != nil || empty {
54+
return zero, fmt.Errorf("could not create input for fee quoter 1.7 update sequence: %w", err)
4855
}
49-
output.ChainSelector = input.ChainSelector
50-
output.ExistingAddresses = input.ExistingAddresses
51-
return output, nil
56+
out.ChainSelector = input.ChainSelector
57+
out.ExistingAddresses = input.ExistingAddresses
58+
return any(out).(FeeQUpdateArgs), nil
5259
},
5360
)
5461
}
5562

56-
func (fqu FeeQuoterUpdater) SequenceDeployOrUpdateFeeQuoter() *cldf_ops.Sequence[sequence1_7.FeeQuoterUpdate, sequences.OnChainOutput, cldf_chain.BlockChains] {
57-
return sequence1_7.SequenceFeeQuoterUpdate
63+
func (fqu FeeQuoterUpdater[FeeQUpdateArgs]) SequenceDeployOrUpdateFeeQuoter() *cldf_ops.Sequence[FeeQUpdateArgs, sequences.OnChainOutput, cldf_chain.BlockChains] {
64+
return cldf_ops.NewSequence(
65+
"fee-quoter-v1.7.0:update-sequence",
66+
semver.MustParse("1.7.0"),
67+
"Deploys or fetches existing FeeQuoter contract and applies config updates",
68+
func(b cldf_ops.Bundle, chains cldf_chain.BlockChains, input FeeQUpdateArgs) (output sequences.OnChainOutput, err error) {
69+
fqInput, ok := any(input).(sequence1_7.FeeQuoterUpdate)
70+
if !ok {
71+
return sequences.OnChainOutput{}, fmt.Errorf("expected sequence1_7.FeeQuoterUpdate, got %T", input)
72+
}
73+
report, err := cldf_ops.ExecuteSequence(b, sequence1_7.SequenceFeeQuoterUpdate, chains, fqInput)
74+
if err != nil {
75+
return sequences.OnChainOutput{}, err
76+
}
77+
return report.Output, nil
78+
},
79+
)
5880
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package adapters
2+
3+
import (
4+
"github.com/Masterminds/semver/v3"
5+
chainsel "github.com/smartcontractkit/chain-selectors"
6+
7+
adapters1_5 "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_5_0/adapters"
8+
adapters1_6 "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/adapters"
9+
"github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
10+
)
11+
12+
func init() {
13+
fqReg := deploy.GetFQAndRampUpdaterRegistry()
14+
fqReg.RegisterFeeQuoterUpdater(chainsel.FamilyEVM, semver.MustParse("1.7.0"), FeeQuoterUpdater[any]{})
15+
fqReg.RegisterRampUpdater(chainsel.FamilyEVM, semver.MustParse("1.6.0"), adapters1_6.RampUpdateWithFQ{})
16+
fqReg.RegisterConfigImporter(chainsel.FamilyEVM, semver.MustParse("1.6.0"), &adapters1_6.ConfigImportAdapter{})
17+
fqReg.RegisterConfigImporter(chainsel.FamilyEVM, semver.MustParse("1.5.0"), &adapters1_5.ConfigImportAdapter{})
18+
}

ccv/chains/evm/deployment/v1_7_0/sequences/sequence_fee_quoter_input_creation_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,8 @@ func TestSequenceFeeQuoterInputCreation(t *testing.T) {
775775
// Seal the datastore for use in the test
776776
e.DataStore = ds.Seal()
777777

778-
// Get the FeeQuoterUpdater adapter
779-
fquUpdater := evmadapter.FeeQuoterUpdater{}
778+
// Get the FeeQuoterUpdater adapter (use concrete type so report.Output is sequence1_7.FeeQuoterUpdate)
779+
fquUpdater := evmadapter.FeeQuoterUpdater[sequence1_7.FeeQuoterUpdate]{}
780780

781781
// Test the sequence for each chain selector that has a FeeQuoter
782782
for _, chainSelector := range chainSelectorList {

chains/evm/deployment/v1_6_0/adapters/rampupdatewithfq.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ func (ru RampUpdateWithFQ) SequenceUpdateRampsWithFeeQuoter() *cldf_ops.Sequence
118118
// Update OnRamp's FeeQuoter address
119119
existingDynamicConfig.FeeQuoter = common.HexToAddress(input.FeeQuoterAddress.Address)
120120
onRampReport, err := cldf_ops.ExecuteOperation(b, onrampops.OnRampSetDynamicConfig, chain, contract.FunctionInput[onrampops.DynamicConfig]{
121-
Address: common.HexToAddress(input.OnRampAddressRef.Address),
122-
Args: existingDynamicConfig,
121+
ChainSelector: input.ChainSelector,
122+
Address: common.HexToAddress(input.OnRampAddressRef.Address),
123+
Args: existingDynamicConfig,
123124
})
124125
if err != nil {
125126
return sequences.OnChainOutput{}, err
@@ -139,8 +140,9 @@ func (ru RampUpdateWithFQ) SequenceUpdateRampsWithFeeQuoter() *cldf_ops.Sequence
139140
if existingOffDynamicConfig.FeeQuoter != common.HexToAddress(input.FeeQuoterAddress.Address) {
140141
existingOffDynamicConfig.FeeQuoter = common.HexToAddress(input.FeeQuoterAddress.Address)
141142
offRampReport, err := cldf_ops.ExecuteOperation(b, offrampops.OffRampSetDynamicConfig, chain, contract.FunctionInput[offrampops.DynamicConfig]{
142-
Address: common.HexToAddress(input.OffRampAddressRef.Address),
143-
Args: existingOffDynamicConfig,
143+
ChainSelector: input.ChainSelector,
144+
Address: common.HexToAddress(input.OffRampAddressRef.Address),
145+
Args: existingOffDynamicConfig,
144146
})
145147
if err != nil {
146148
return sequences.OnChainOutput{}, err

deployment/deploy/feequoterupdater.go

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ type UpdateFeeQuoterInput struct {
2929
}
3030

3131
type UpdateFeeQuoterInputPerChain struct {
32-
PopulateConfig bool
3332
ImportFeeQuoterConfigFromVersions []*semver.Version
3433
FeeQuoterVersion *semver.Version
3534
RampsVersion *semver.Version
@@ -143,6 +142,7 @@ func NewFQUpdaterRegistry() *FQAndRampUpdaterRegistry {
143142
return &FQAndRampUpdaterRegistry{
144143
FeeQuoterUpdater: make(map[string]FeeQuoterUpdater[any]),
145144
RampUpdater: make(map[string]RampUpdater),
145+
ConfigImporter: make(map[string]ConfigImporter),
146146
}
147147
}
148148

@@ -157,7 +157,7 @@ func GetFQAndRampUpdaterRegistry() *FQAndRampUpdaterRegistry {
157157
// It first optionally populates configuration values, then creates FeeQuoterUpdateInput,
158158
// deploys or updates the FeeQuoter contract, and finally updates the Ramps contracts to use the new FeeQuoter address.
159159
// If needed, it also updates OffRamp source chain configs ( specifically used when during updating feequoter only specific source chain needs to be added to offramp).
160-
func UpdateFeeQuoterChangeset(mcmsRegistry *changesets.MCMSReaderRegistry, fquRegistry *FQAndRampUpdaterRegistry) cldf.ChangeSetV2[UpdateFeeQuoterInput] {
160+
func UpdateFeeQuoterChangeset(fquRegistry *FQAndRampUpdaterRegistry, mcmsRegistry *changesets.MCMSReaderRegistry) cldf.ChangeSetV2[UpdateFeeQuoterInput] {
161161
return cldf.CreateChangeSet(updateFeeQuoterApply(fquRegistry, mcmsRegistry), updateFeeQuoterVerify(fquRegistry, mcmsRegistry))
162162
}
163163

@@ -194,41 +194,36 @@ func updateFeeQuoterApply(fquRegistry *FQAndRampUpdaterRegistry, mcmsRegistry *c
194194
return cldf.ChangesetOutput{}, utils.ErrNoAdapterRegistered("RampUpdater", perChainInput.RampsVersion)
195195
}
196196
contractMeta := e.DataStore.ContractMetadata().Filter(datastore.ContractMetadataByChainSelector(chainSel))
197-
// If PopulateConfig is true, need to first populate config values in contract metadata
198-
// otherwise proceed to create FeeQuoterUpdateInput directly from existing contract metadata - in this case
199-
// we assume that the config values are already present in the contract metadata
200-
if perChainInput.PopulateConfig {
201-
for _, version := range perChainInput.ImportFeeQuoterConfigFromVersions {
202-
configImporter, ok := fquRegistry.GetConfigImporter(chainSel, version)
203-
if !ok {
204-
return cldf.ChangesetOutput{}, utils.ErrNoAdapterRegistered("ConfigImporter", perChainInput.FeeQuoterVersion)
205-
}
206-
err := configImporter.InitializeAdapter(e, chainSel)
207-
if err != nil {
208-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to initialize config importer for chain %d: %w", chainSel, err)
209-
}
210-
supportedTokensPerRemoteChain, err := configImporter.SupportedTokensPerRemoteChain(e, chainSel)
211-
if err != nil {
212-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get supported tokens per remote chain for chain %d: %w", chainSel, err)
213-
}
214-
connectedChains, err := configImporter.ConnectedChains(e, chainSel)
215-
if err != nil {
216-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get connected chains for chain %d: %w", chainSel, err)
217-
}
218-
populateConfigReport, err := cldf_ops.ExecuteSequence(e.OperationsBundle, configImporter.SequenceImportConfig(), e.BlockChains, ImportConfigPerChainInput{
219-
ChainSelector: chainSel,
220-
RemoteChains: connectedChains,
221-
TokensPerRemoteChain: supportedTokensPerRemoteChain,
222-
})
223-
if err != nil {
224-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to populate config for FeeQuoter on chain %d: %w", chainSel, err)
225-
}
226-
if len(populateConfigReport.Output.Metadata.Contracts) == 0 {
227-
return cldf.ChangesetOutput{}, fmt.Errorf("no contract metadata returned from populate config for FeeQuoter on chain %d", chainSel)
228-
}
229-
contractMeta = append(contractMeta, populateConfigReport.Output.Metadata.Contracts...)
230-
contractMetadata = append(contractMetadata, populateConfigReport.Output.Metadata.Contracts...)
197+
for _, version := range perChainInput.ImportFeeQuoterConfigFromVersions {
198+
configImporter, ok := fquRegistry.GetConfigImporter(chainSel, version)
199+
if !ok {
200+
return cldf.ChangesetOutput{}, utils.ErrNoAdapterRegistered("ConfigImporter", perChainInput.FeeQuoterVersion)
231201
}
202+
err := configImporter.InitializeAdapter(e, chainSel)
203+
if err != nil {
204+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to initialize config importer for chain %d: %w", chainSel, err)
205+
}
206+
supportedTokensPerRemoteChain, err := configImporter.SupportedTokensPerRemoteChain(e, chainSel)
207+
if err != nil {
208+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get supported tokens per remote chain for chain %d: %w", chainSel, err)
209+
}
210+
connectedChains, err := configImporter.ConnectedChains(e, chainSel)
211+
if err != nil {
212+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get connected chains for chain %d: %w", chainSel, err)
213+
}
214+
populateConfigReport, err := cldf_ops.ExecuteSequence(e.OperationsBundle, configImporter.SequenceImportConfig(), e.BlockChains, ImportConfigPerChainInput{
215+
ChainSelector: chainSel,
216+
RemoteChains: connectedChains,
217+
TokensPerRemoteChain: supportedTokensPerRemoteChain,
218+
})
219+
if err != nil {
220+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to populate config for FeeQuoter on chain %d: %w", chainSel, err)
221+
}
222+
if len(populateConfigReport.Output.Metadata.Contracts) == 0 {
223+
return cldf.ChangesetOutput{}, fmt.Errorf("no contract metadata returned from populate config for FeeQuoter on chain %d", chainSel)
224+
}
225+
contractMeta = append(contractMeta, populateConfigReport.Output.Metadata.Contracts...)
226+
contractMetadata = append(contractMetadata, populateConfigReport.Output.Metadata.Contracts...)
232227
}
233228
// Create FeeQuoterUpdateInput
234229
reportFQInputCreation, err := cldf_ops.ExecuteSequence(e.OperationsBundle, fquUpdater.SequenceFeeQuoterInputCreation(), e.BlockChains, FeeQuoterUpdateInput{
@@ -253,27 +248,29 @@ func updateFeeQuoterApply(fquRegistry *FQAndRampUpdaterRegistry, mcmsRegistry *c
253248
// Update Ramps with new FeeQuoter address
254249
// fetch the address refs
255250
feeQuoterAddrRef := reportFQUpdate.Output.Addresses[len(reportFQUpdate.Output.Addresses)-1]
256-
rampsInput := UpdateRampsInput{
257-
ChainSelector: chainSel,
258-
FeeQuoterAddress: feeQuoterAddrRef,
259-
SourceChains: make(map[uint64]SourceChainConfig),
260-
}
261-
for _, srcChainSel := range perChainInput.SourceChainAddsToOffRamp {
262-
rampsInput.SourceChains[srcChainSel] = SourceChainConfig{}
263-
}
264-
// Resolve Ramps input
265-
resolvedRampsInput, err := rampUpdater.ResolveRampsInput(e, rampsInput)
266-
if err != nil {
267-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve ramps input for chain %d: %w", chainSel, err)
268-
}
269-
// Execute Ramps update sequence
270-
reportRampsUpdate, err := cldf_ops.ExecuteSequence(e.OperationsBundle, rampUpdater.SequenceUpdateRampsWithFeeQuoter(), e.BlockChains, resolvedRampsInput)
271-
if err != nil {
272-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to update ramps with FeeQuoter for chain %d: %w", chainSel, err)
251+
if perChainInput.RampsVersion != nil {
252+
rampsInput := UpdateRampsInput{
253+
ChainSelector: chainSel,
254+
FeeQuoterAddress: feeQuoterAddrRef,
255+
SourceChains: make(map[uint64]SourceChainConfig),
256+
}
257+
for _, srcChainSel := range perChainInput.SourceChainAddsToOffRamp {
258+
rampsInput.SourceChains[srcChainSel] = SourceChainConfig{}
259+
}
260+
// Resolve Ramps input
261+
resolvedRampsInput, err := rampUpdater.ResolveRampsInput(e, rampsInput)
262+
if err != nil {
263+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve ramps input for chain %d: %w", chainSel, err)
264+
}
265+
// Execute Ramps update sequence
266+
reportRampsUpdate, err := cldf_ops.ExecuteSequence(e.OperationsBundle, rampUpdater.SequenceUpdateRampsWithFeeQuoter(), e.BlockChains, resolvedRampsInput)
267+
if err != nil {
268+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to update ramps with FeeQuoter for chain %d: %w", chainSel, err)
269+
}
270+
batchOps = append(batchOps, reportRampsUpdate.Output.BatchOps...)
271+
addressRefs = append(addressRefs, reportRampsUpdate.Output.Addresses...)
272+
reports = append(reports, reportRampsUpdate.ExecutionReports...)
273273
}
274-
batchOps = append(batchOps, reportRampsUpdate.Output.BatchOps...)
275-
addressRefs = append(addressRefs, reportRampsUpdate.Output.Addresses...)
276-
reports = append(reports, reportRampsUpdate.ExecutionReports...)
277274
}
278275
// Prepare datastore with all address refs
279276
ds := datastore.NewMemoryDataStore()

0 commit comments

Comments
 (0)