Skip to content

Commit

Permalink
Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kylesmartin committed Jan 30, 2025
1 parent cb0fe56 commit 8d1f336
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 136 deletions.
12 changes: 6 additions & 6 deletions deployment/ccip/changeset/cs_deploy_usdc_token_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ func (i DeployUSDCTokenPoolInput) Validate(ctx context.Context, chain deployment

// DeployUSDCTokenPoolContractsConfig defines the USDC token pool contracts that need to be deployed on each chain.
type DeployUSDCTokenPoolContractsConfig struct {
// NewUSDCPools defines the per-chain configuration of each new USDC pool.
NewUSDCPools map[uint64]DeployUSDCTokenPoolInput
// USDCPools defines the per-chain configuration of each new USDC pool.
USDCPools map[uint64]DeployUSDCTokenPoolInput
}

func (c DeployUSDCTokenPoolContractsConfig) Validate(env deployment.Environment) error {
state, err := LoadOnchainState(env)
if err != nil {
return fmt.Errorf("failed to load onchain state: %w", err)
}
for chainSelector, poolConfig := range c.NewUSDCPools {
for chainSelector, poolConfig := range c.USDCPools {
err := deployment.IsValidChainSelector(chainSelector)
if err != nil {
return fmt.Errorf("failed to validate chain selector %d: %w", chainSelector, err)
Expand All @@ -98,10 +98,10 @@ func (c DeployUSDCTokenPoolContractsConfig) Validate(env deployment.Environment)
if !ok {
return fmt.Errorf("chain with selector %d does not exist in state", chainSelector)
}
if router := chainState.Router; router == nil {
if chainState.Router == nil {
return fmt.Errorf("missing router on %s", chain)
}
if rmnProxy := chainState.RMNProxy; rmnProxy == nil {
if chainState.RMNProxy == nil {
return fmt.Errorf("missing rmnProxy on %s", chain)
}
err = poolConfig.Validate(env.GetContext(), chain, chainState)
Expand All @@ -124,7 +124,7 @@ func DeployUSDCTokenPoolContractsChangeset(env deployment.Environment, c DeployU
return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err)
}

for chainSelector, poolConfig := range c.NewUSDCPools {
for chainSelector, poolConfig := range c.USDCPools {
chain := env.Chains[chainSelector]
chainState := state.Chains[chainSelector]

Expand Down
8 changes: 4 additions & 4 deletions deployment/ccip/changeset/cs_deploy_usdc_token_pools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestValidateDeployUSDCTokenPoolContractsConfig(t *testing.T) {
{
Msg: "Chain selector is not valid",
Input: changeset.DeployUSDCTokenPoolContractsConfig{
NewUSDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
USDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
0: changeset.DeployUSDCTokenPoolInput{},
},
},
Expand All @@ -44,7 +44,7 @@ func TestValidateDeployUSDCTokenPoolContractsConfig(t *testing.T) {
{
Msg: "Chain selector doesn't exist in environment",
Input: changeset.DeployUSDCTokenPoolContractsConfig{
NewUSDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
USDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
5009297550715157269: changeset.DeployUSDCTokenPoolInput{},
},
},
Expand All @@ -53,7 +53,7 @@ func TestValidateDeployUSDCTokenPoolContractsConfig(t *testing.T) {
{
Msg: "Missing router",
Input: changeset.DeployUSDCTokenPoolContractsConfig{
NewUSDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
USDCPools: map[uint64]changeset.DeployUSDCTokenPoolInput{
e.AllChainSelectors()[0]: changeset.DeployUSDCTokenPoolInput{},
},
},
Expand Down Expand Up @@ -213,7 +213,7 @@ func TestDeployUSDCTokenPoolContracts(t *testing.T) {
commonchangeset.ChangesetApplication{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployUSDCTokenPoolContractsChangeset),
Config: changeset.DeployUSDCTokenPoolContractsConfig{
NewUSDCPools: newUSDCTokenPools,
USDCPools: newUSDCTokenPools,
},
},
})
Expand Down
89 changes: 39 additions & 50 deletions deployment/ccip/changeset/cs_sync_usdc_domains_with_chains.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package changeset

import (
"context"
"errors"
"fmt"

"github.com/Masterminds/semver/v3"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"

"github.com/smartcontractkit/chainlink/deployment"
commoncs "github.com/smartcontractkit/chainlink/deployment/common/changeset"
Expand All @@ -14,54 +15,25 @@ import (

var _ deployment.ChangeSet[SyncUSDCDomainsWithChainsConfig] = SyncUSDCDomainsWithChainsChangeset

type USDCChainConfig struct {
// Version is the version of the USDC token pool.
Version semver.Version
}

func (c USDCChainConfig) Validate(ctx context.Context, chain deployment.Chain, state CCIPChainState, useMcms bool, chainSelectorToDomainID map[uint64]uint32) error {
usdcTokenPool, ok := state.USDCTokenPools[c.Version]
if !ok {
return fmt.Errorf("no USDC token pool found on %s with version %s", chain, c.Version)
}

if len(usdcTokenPool.Address().Bytes()) > 32 {
// Will never be true for EVM
return fmt.Errorf("expected USDC token pool address on %s (%s) to be less than 32 bytes", chain, usdcTokenPool.Address())
}

// Validate that the USDC token pool is owned by the address that will be actioning the transactions (i.e. Timelock or deployer key)
if err := commoncs.ValidateOwnership(ctx, useMcms, chain.DeployerKey.From, state.Timelock.Address(), usdcTokenPool); err != nil {
return fmt.Errorf("token pool with address %s on %s failed ownership validation: %w", usdcTokenPool.Address(), chain, err)
}

// Validate that each supported chain has a domain ID defined
supportedChains, err := usdcTokenPool.GetSupportedChains(&bind.CallOpts{Context: ctx})
if err != nil {
return fmt.Errorf("failed to get supported chains from USDC token pool on %s with address %s: %w", chain, usdcTokenPool.Address(), err)
}
for _, supportedChain := range supportedChains {
if _, ok := chainSelectorToDomainID[supportedChain]; !ok {
return fmt.Errorf("no USDC domain ID defined for chain with selector %d", supportedChain)
}
}

return nil
}

// SyncUSDCDomainsWithChainsConfig defines the chain selector -> USDC domain mappings.
type SyncUSDCDomainsWithChainsConfig struct {
// USDCConfigsByChain defines the USDC domain and pool version for each chain selector.
USDCConfigsByChain map[uint64]USDCChainConfig
// USDCVersionByChain defines the USDC domain and pool version for each chain selector.
USDCVersionByChain map[uint64]semver.Version
// ChainSelectorToUSDCDomain maps chains selectors to their USDC domain identifiers.
ChainSelectorToUSDCDomain map[uint64]uint32
// MCMS defines the delay to use for Timelock (if absent, the changeset will attempt to use the deployer key).
MCMS *MCMSConfig
}

func (c SyncUSDCDomainsWithChainsConfig) Validate(env deployment.Environment, state CCIPOnChainState) error {
ctx := env.GetContext()

if c.ChainSelectorToUSDCDomain == nil {
return errors.New("chain selector to usdc domain must be defined")
}

// Validate that all USDC configs inputted are for valid chains that define USDC pools.
for chainSelector, config := range c.USDCConfigsByChain {
for chainSelector, version := range c.USDCVersionByChain {
err := deployment.IsValidChainSelector(chainSelector)
if err != nil {
return fmt.Errorf("failed to validate chain selector %d: %w", chainSelector, err)
Expand All @@ -83,13 +55,32 @@ func (c SyncUSDCDomainsWithChainsConfig) Validate(env deployment.Environment, st
if chainState.ProposerMcm == nil {
return fmt.Errorf("missing proposerMcm on %s", chain.String())
}
if err = config.Validate(env.GetContext(), chain, chainState, c.MCMS != nil, c.ChainSelectorToUSDCDomain); err != nil {
return fmt.Errorf("USDC config for %s is not valid: %w", chain, err)
usdcTokenPool, ok := chainState.USDCTokenPools[version]
if !ok {
return fmt.Errorf("no USDC token pool found on %s with version %s", chain, version)
}
if len(usdcTokenPool.Address().Bytes()) > 32 {
// Will never be true for EVM
return fmt.Errorf("expected USDC token pool address on %s (%s) to be less than 32 bytes", chain, usdcTokenPool.Address())
}
// Validate that the USDC token pool is owned by the address that will be actioning the transactions (i.e. Timelock or deployer key)
if err := commoncs.ValidateOwnership(ctx, c.MCMS != nil, chain.DeployerKey.From, chainState.Timelock.Address(), usdcTokenPool); err != nil {
return fmt.Errorf("token pool with address %s on %s failed ownership validation: %w", usdcTokenPool.Address(), chain, err)
}
// Validate that each supported chain has a domain ID defined
supportedChains, err := usdcTokenPool.GetSupportedChains(&bind.CallOpts{Context: ctx})
if err != nil {
return fmt.Errorf("failed to get supported chains from USDC token pool on %s with address %s: %w", chain, usdcTokenPool.Address(), err)
}
for _, supportedChain := range supportedChains {
if _, ok := c.ChainSelectorToUSDCDomain[supportedChain]; !ok {
return fmt.Errorf("no USDC domain ID defined for chain with selector %d", supportedChain)
}
}
}
// Check that our input covers all chains that define USDC pools.
for chainSelector, chainState := range state.Chains {
if _, ok := c.USDCConfigsByChain[chainSelector]; !ok && chainState.USDCTokenPools != nil {
if _, ok := c.USDCVersionByChain[chainSelector]; !ok && chainState.USDCTokenPools != nil {
return fmt.Errorf("no USDC chain config defined for %s, which does support USDC", env.Chains[chainSelector])
}
}
Expand All @@ -110,15 +101,15 @@ func SyncUSDCDomainsWithChainsChangeset(env deployment.Environment, c SyncUSDCDo

deployerGroup := NewDeployerGroup(env, state, c.MCMS)

for chainSelector, usdcChainConfig := range c.USDCConfigsByChain {
for chainSelector, version := range c.USDCVersionByChain {
chain := env.Chains[chainSelector]
chainState := state.Chains[chainSelector]
writeOpts, err := deployerGroup.GetDeployer(chainSelector)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to get transaction opts for %s", chain)
}

usdcTokenPool := chainState.USDCTokenPools[usdcChainConfig.Version]
usdcTokenPool := chainState.USDCTokenPools[version]
supportedChains, err := usdcTokenPool.GetSupportedChains(readOpts)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to fetch supported chains from USDC token pool with address %s on %s: %w", usdcTokenPool.Address(), chain, err)
Expand All @@ -127,14 +118,12 @@ func SyncUSDCDomainsWithChainsChangeset(env deployment.Environment, c SyncUSDCDo
domainUpdates := make([]usdc_token_pool.USDCTokenPoolDomainUpdate, 0)
for _, remoteChainSelector := range supportedChains {
remoteChainState := state.Chains[remoteChainSelector]
remoteUSDCChainConfig := c.USDCConfigsByChain[remoteChainSelector]
remoteUSDCTokenPool := remoteChainState.USDCTokenPools[remoteUSDCChainConfig.Version]
remoteUSDCVersion := c.USDCVersionByChain[remoteChainSelector]
remoteUSDCTokenPool := remoteChainState.USDCTokenPools[remoteUSDCVersion]

var desiredAllowedCaller [32]byte
remoteUSDCTokenPoolAddressBytes := remoteUSDCTokenPool.Address().Bytes()
for i, j := len(desiredAllowedCaller)-len(remoteUSDCTokenPoolAddressBytes), 0; i < len(desiredAllowedCaller); i, j = i+1, j+1 {
desiredAllowedCaller[i] = remoteUSDCTokenPoolAddressBytes[j]
}
copy(desiredAllowedCaller[:], common.LeftPadBytes(remoteUSDCTokenPool.Address().Bytes(), 32))

desiredDomainIdentifier := c.ChainSelectorToUSDCDomain[remoteChainSelector]

currentDomain, err := usdcTokenPool.GetDomain(readOpts, remoteChainSelector)
Expand Down
Loading

0 comments on commit 8d1f336

Please sign in to comment.