Skip to content

Commit

Permalink
Add deployment.ExistingAddresses field (#15079)
Browse files Browse the repository at this point in the history
* Wip

* Test view function

* Use constructor everywhere

* Fix some tests

* Simplify ks config

* Update integration tests

* Fix more tests
  • Loading branch information
connorwstein authored Nov 2, 2024
1 parent 0e199bb commit c6c8fbd
Show file tree
Hide file tree
Showing 29 changed files with 300 additions and 239 deletions.
25 changes: 11 additions & 14 deletions deployment/ccip/add_lane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestAddLane(t *testing.T) {
// We add more chains to the chainlink nodes than the number of chains where CCIP is deployed.
e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4, 4)
// Here we have CR + nodes set up, but no CCIP contracts deployed.
state, err := LoadOnchainState(e.Env, e.Ab)
state, err := LoadOnchainState(e.Env)
require.NoError(t, err)

selectors := e.Env.AllChainSelectors()
Expand All @@ -30,24 +30,21 @@ func TestAddLane(t *testing.T) {
feeds := state.Chains[e.FeedChainSel].USDFeeds
tokenConfig := NewTestTokenConfig(feeds)

feeTokenContracts := make(map[uint64]FeeTokenContracts)
for _, sel := range []uint64{chain1, chain2} {
feeTokenContracts[sel] = e.FeeTokenContracts[sel]
}
// Set up CCIP contracts and a DON per chain.
err = DeployCCIPContracts(e.Env, e.Ab, DeployCCIPContractConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
TokenConfig: tokenConfig,
MCMSConfig: NewTestMCMSConfig(t, e.Env),
ExistingAddressBook: e.Ab,
ChainsToDeploy: []uint64{chain1, chain2},
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
newAddresses := deployment.NewMemoryAddressBook()
err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
TokenConfig: tokenConfig,
MCMSConfig: NewTestMCMSConfig(t, e.Env),
ChainsToDeploy: []uint64{chain1, chain2},
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses))

// We expect no lanes available on any chain.
state, err = LoadOnchainState(e.Env, e.Ab)
state, err = LoadOnchainState(e.Env)
require.NoError(t, err)
for _, sel := range []uint64{chain1, chain2} {
chain := state.Chains[sel]
Expand Down
41 changes: 11 additions & 30 deletions deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import (

cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink-ccip/pluginconfig"

"github.com/smartcontractkit/chainlink/deployment"

"github.com/stretchr/testify/require"
Expand All @@ -32,41 +29,25 @@ func TestActiveCandidate(t *testing.T) {
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 5)
e := tenv.Env

state, err := ccdeploy.LoadOnchainState(tenv.Env, tenv.Ab)
state, err := ccdeploy.LoadOnchainState(tenv.Env)
require.NoError(t, err)
require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken)

feeds := state.Chains[tenv.FeedChainSel].USDFeeds
tokenConfig := ccdeploy.NewTokenConfig()

tokenConfig.UpsertTokenInfo(ccdeploy.LinkSymbol,
pluginconfig.TokenInfo{
AggregatorAddress: cciptypes.UnknownEncodedAddress(feeds[ccdeploy.LinkSymbol].Address().String()),
Decimals: ccdeploy.LinkDecimals,
DeviationPPB: cciptypes.NewBigIntFromInt64(1e9),
},
)
tokenConfig.UpsertTokenInfo(ccdeploy.WethSymbol,
pluginconfig.TokenInfo{
AggregatorAddress: cciptypes.UnknownEncodedAddress(feeds[ccdeploy.WethSymbol].Address().String()),
Decimals: ccdeploy.WethDecimals,
DeviationPPB: cciptypes.NewBigIntFromInt64(4e9),
},
)
tokenConfig := ccdeploy.NewTestTokenConfig(feeds)

output, err := InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: tokenConfig,
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
ExistingAddressBook: tenv.Ab,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: tokenConfig,
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
// Get new state after migration.
require.NoError(t, tenv.Ab.Merge(output.AddressBook))
state, err = ccdeploy.LoadOnchainState(e, tenv.Ab)
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))
state, err = ccdeploy.LoadOnchainState(tenv.Env)
require.NoError(t, err)
homeCS, destCS := tenv.HomeChainSel, tenv.FeedChainSel

Expand Down Expand Up @@ -143,7 +124,7 @@ func TestActiveCandidate(t *testing.T) {
require.Equal(t, 5, len(donInfo.NodeP2PIds))
require.Equal(t, uint32(4), donInfo.ConfigCount)

state, err = ccdeploy.LoadOnchainState(e, tenv.Ab)
state, err = ccdeploy.LoadOnchainState(e)
require.NoError(t, err)

// delete a non-bootstrap node
Expand Down
36 changes: 22 additions & 14 deletions deployment/ccip/changeset/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,26 @@ import (
func TestAddChainInbound(t *testing.T) {
// 4 chains where the 4th is added after initial deployment.
e := ccipdeployment.NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4, 4)
state, err := ccipdeployment.LoadOnchainState(e.Env, e.Ab)
state, err := ccipdeployment.LoadOnchainState(e.Env)
require.NoError(t, err)
// Take first non-home chain as the new chain.
newChain := e.Env.AllChainSelectorsExcluding([]uint64{e.HomeChainSel})[0]
// We deploy to the rest.
initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain})

tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds)
err = ccipdeployment.DeployCCIPContracts(e.Env, e.Ab, ccipdeployment.DeployCCIPContractConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
ChainsToDeploy: initialDeploy,
TokenConfig: tokenConfig,
MCMSConfig: ccipdeployment.NewTestMCMSConfig(t, e.Env),
ExistingAddressBook: e.Ab,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
newAddresses := deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
ChainsToDeploy: initialDeploy,
TokenConfig: tokenConfig,
MCMSConfig: ccipdeployment.NewTestMCMSConfig(t, e.Env),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
state, err = ccipdeployment.LoadOnchainState(e.Env, e.Ab)
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses))
state, err = ccipdeployment.LoadOnchainState(e.Env)
require.NoError(t, err)

// Connect all the existing lanes.
Expand All @@ -59,16 +60,23 @@ func TestAddChainInbound(t *testing.T) {
}
}

rmnHomeAddress, err := deployment.SearchAddressBook(e.Ab, e.HomeChainSel, ccipdeployment.RMNHome)
rmnHomeAddress, err := deployment.SearchAddressBook(e.Env.ExistingAddresses, e.HomeChainSel, ccipdeployment.RMNHome)
require.NoError(t, err)
require.True(t, common.IsHexAddress(rmnHomeAddress))
rmnHome, err := rmn_home.NewRMNHome(common.HexToAddress(rmnHomeAddress), e.Env.Chains[e.HomeChainSel].Client)
require.NoError(t, err)

// Deploy contracts to new chain
err = ccipdeployment.DeployChainContracts(e.Env, e.Env.Chains[newChain], e.Ab, e.FeeTokenContracts[newChain], ccipdeployment.NewTestMCMSConfig(t, e.Env), rmnHome)
newChainAddresses := deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployChainContracts(e.Env,
e.Env.Chains[newChain], newChainAddresses,
ccipdeployment.FeeTokenContracts{
LinkToken: state.Chains[newChain].LinkToken,
Weth9: state.Chains[newChain].Weth9,
}, ccipdeployment.NewTestMCMSConfig(t, e.Env), rmnHome)
require.NoError(t, err)
state, err = ccipdeployment.LoadOnchainState(e.Env, e.Ab)
require.NoError(t, e.Env.ExistingAddresses.Merge(newChainAddresses))
state, err = ccipdeployment.LoadOnchainState(e.Env)
require.NoError(t, err)

// Transfer onramp/fq ownership to timelock.
Expand Down Expand Up @@ -187,7 +195,7 @@ func TestAddChainInbound(t *testing.T) {
require.NoError(t, err)

// Assert the inbound lanes to the new chain are wired correctly.
state, err = ccipdeployment.LoadOnchainState(e.Env, e.Ab)
state, err = ccipdeployment.LoadOnchainState(e.Env)
require.NoError(t, err)
for _, chain := range initialDeploy {
cfg, err2 := state.Chains[chain].OnRamp.GetDestChainConfig(nil, newChain)
Expand Down
12 changes: 6 additions & 6 deletions deployment/ccip/changeset/initial_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ func InitialDeploy(env deployment.Environment, config interface{}) (deployment.C
if !ok {
return deployment.ChangesetOutput{}, deployment.ErrInvalidConfig
}
ab := deployment.NewMemoryAddressBook()
err := ccipdeployment.DeployCCIPContracts(env, ab, c)
newAddresses := deployment.NewMemoryAddressBook()
err := ccipdeployment.DeployCCIPContracts(env, newAddresses, c)
if err != nil {
env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "addresses", ab)
return deployment.ChangesetOutput{AddressBook: ab}, deployment.MaybeDataErr(err)
env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses)
return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err)
}
js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain)
if err != nil {
return deployment.ChangesetOutput{AddressBook: ab}, err
return deployment.ChangesetOutput{AddressBook: newAddresses}, err
}
return deployment.ChangesetOutput{
Proposals: []timelock.MCMSWithTimelockProposal{},
AddressBook: ab,
AddressBook: newAddresses,
// Mapping of which nodes get which jobs.
JobSpecs: js,
}, nil
Expand Down
19 changes: 9 additions & 10 deletions deployment/ccip/changeset/initial_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@ func TestInitialDeploy(t *testing.T) {
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 4)
e := tenv.Env

state, err := ccdeploy.LoadOnchainState(tenv.Env, tenv.Ab)
state, err := ccdeploy.LoadOnchainState(tenv.Env)
require.NoError(t, err)
require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken)

output, err := InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
ExistingAddressBook: tenv.Ab,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
// Get new state after migration.
require.NoError(t, tenv.Ab.Merge(output.AddressBook))
state, err = ccdeploy.LoadOnchainState(e, tenv.Ab)
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))
state, err = ccdeploy.LoadOnchainState(e)
require.NoError(t, err)

// Ensure capreg logs are up to date.
Expand Down
4 changes: 2 additions & 2 deletions deployment/ccip/changeset/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

var _ deployment.ViewState = ViewCCIP

func ViewCCIP(e deployment.Environment, ab deployment.AddressBook) (json.Marshaler, error) {
state, err := ccipdeployment.LoadOnchainState(e, ab)
func ViewCCIP(e deployment.Environment) (json.Marshaler, error) {
state, err := ccipdeployment.LoadOnchainState(e)
if err != nil {
return nil, err
}
Expand Down
21 changes: 9 additions & 12 deletions deployment/ccip/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,10 @@ func deployContract[C Contracts](
}

type DeployCCIPContractConfig struct {
HomeChainSel uint64
FeedChainSel uint64
ChainsToDeploy []uint64
TokenConfig TokenConfig
ExistingAddressBook deployment.AddressBook
HomeChainSel uint64
FeedChainSel uint64
ChainsToDeploy []uint64
TokenConfig TokenConfig
// I believe it makes sense to have the same signers across all chains
// since that's the point MCMS.
MCMSConfig MCMSConfig
Expand All @@ -148,7 +147,7 @@ func DeployCCIPContracts(e deployment.Environment, ab deployment.AddressBook, c
e.Logger.Errorw("Failed to get node info", "err", err)
return err
}
existingState, err := LoadOnchainState(e, c.ExistingAddressBook)
existingState, err := LoadOnchainState(e)
if err != nil {
e.Logger.Errorw("Failed to load existing onchain state", "err")
return err
Expand Down Expand Up @@ -364,16 +363,14 @@ func DeployMCMSContracts(
}, nil
}

func DeployFeeTokensToChains(lggr logger.Logger, ab deployment.AddressBook, chains map[uint64]deployment.Chain) (map[uint64]FeeTokenContracts, error) {
feeTokenContractsByChain := make(map[uint64]FeeTokenContracts)
func DeployFeeTokensToChains(lggr logger.Logger, ab deployment.AddressBook, chains map[uint64]deployment.Chain) error {
for _, chain := range chains {
feeTokenContracts, err := DeployFeeTokens(lggr, chain, ab)
_, err := DeployFeeTokens(lggr, chain, ab)
if err != nil {
return nil, err
return err
}
feeTokenContractsByChain[chain.Selector] = feeTokenContracts
}
return feeTokenContractsByChain, nil
return nil
}

// DeployFeeTokens deploys link and weth9. This is _usually_ for test environments only,
Expand Down
24 changes: 12 additions & 12 deletions deployment/ccip/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@ func TestDeployCCIPContracts(t *testing.T) {
Nodes: 4,
})
// Deploy all the CCIP contracts.
ab := deployment.NewMemoryAddressBook()
homeChainSel, feedChainSel := allocateCCIPChainSelectors(e.Chains)
_, _ = DeployTestContracts(t, lggr, ab, homeChainSel, feedChainSel, e.Chains)
_ = DeployTestContracts(t, lggr, e.ExistingAddresses, homeChainSel, feedChainSel, e.Chains)

// Load the state after deploying the cap reg and feeds.
s, err := LoadOnchainState(e, ab)
s, err := LoadOnchainState(e)
require.NoError(t, err)
require.NotNil(t, s.Chains[homeChainSel].CapabilityRegistry)
require.NotNil(t, s.Chains[homeChainSel].CCIPHome)
require.NotNil(t, s.Chains[feedChainSel].USDFeeds)

err = DeployCCIPContracts(e, ab, DeployCCIPContractConfig{
HomeChainSel: homeChainSel,
FeedChainSel: feedChainSel,
ChainsToDeploy: e.AllChainSelectors(),
TokenConfig: NewTokenConfig(),
ExistingAddressBook: ab,
MCMSConfig: NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
newAddresses := deployment.NewMemoryAddressBook()
err = DeployCCIPContracts(e, newAddresses, DeployCCIPContractConfig{
HomeChainSel: homeChainSel,
FeedChainSel: feedChainSel,
ChainsToDeploy: e.AllChainSelectors(),
TokenConfig: NewTokenConfig(),
MCMSConfig: NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
state, err := LoadOnchainState(e, ab)
require.NoError(t, e.ExistingAddresses.Merge(newAddresses))
state, err := LoadOnchainState(e)
require.NoError(t, err)
snap, err := state.View(e.AllChainSelectors())
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions deployment/ccip/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ func (s CCIPOnChainState) View(chains []uint64) (map[string]view.ChainView, erro
return m, nil
}

func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) {
func LoadOnchainState(e deployment.Environment) (CCIPOnChainState, error) {
state := CCIPOnChainState{
Chains: make(map[uint64]CCIPChainState),
}
for chainSelector, chain := range e.Chains {
addresses, err := ab.AddressesForChain(chainSelector)
addresses, err := e.ExistingAddresses.AddressesForChain(chainSelector)
if err != nil {
// Chain not found in address book, initialize empty
if errors.Is(err, deployment.ErrChainNotFound) {
Expand Down
Loading

0 comments on commit c6c8fbd

Please sign in to comment.