Skip to content

Commit

Permalink
move transfer ownership cs to common
Browse files Browse the repository at this point in the history
  • Loading branch information
makramkd committed Nov 27, 2024
1 parent 5ad33a0 commit c474490
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 115 deletions.
49 changes: 41 additions & 8 deletions deployment/ccip/changeset/accept_ownership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,8 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) {
}, []commonchangeset.ChangesetApplication{
// note this doesn't have proposals.
{
Changeset: commonchangeset.WrapChangeSet(NewTransferOwnershipChangeset),
Config: TransferOwnershipConfig{
State: state,
ChainSelectors: allChains,
HomeChainSelector: e.HomeChainSel,
},
Changeset: commonchangeset.WrapChangeSet(commonchangeset.NewTransferOwnershipChangeset),
Config: genTestTransferOwnershipConfig(e, allChains, state),
},
// this has proposals, ApplyChangesets will sign & execute them.
// in practice, signing and executing are separated processes.
Expand All @@ -92,6 +88,43 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) {
assertTimelockOwnership(t, e, allChains, state)
}

func genTestTransferOwnershipConfig(
e DeployedEnv,
chains []uint64,
state CCIPOnChainState,
) commonchangeset.TransferOwnershipConfig {
var (
timelocksPerChain = make(map[uint64]common.Address)
contracts = make(map[uint64][]commonchangeset.OwnershipTransferrer)
)

// chain contracts
for _, chain := range chains {
timelocksPerChain[chain] = state.Chains[chain].Timelock.Address()
contracts[chain] = []commonchangeset.OwnershipTransferrer{
state.Chains[chain].OnRamp,
state.Chains[chain].OffRamp,
state.Chains[chain].FeeQuoter,
state.Chains[chain].NonceManager,
state.Chains[chain].RMNRemote,
}
}

// home chain
homeChainTimelockAddress := state.Chains[e.HomeChainSel].Timelock.Address()
timelocksPerChain[e.HomeChainSel] = homeChainTimelockAddress
contracts[e.HomeChainSel] = append(contracts[e.HomeChainSel],
state.Chains[e.HomeChainSel].CapabilityRegistry,
state.Chains[e.HomeChainSel].CCIPHome,
state.Chains[e.HomeChainSel].RMNHome,
)

return commonchangeset.TransferOwnershipConfig{
TimelocksPerChain: timelocksPerChain,
Contracts: contracts,
}
}

func genTestAcceptOwnershipConfig(
e DeployedEnv,
chains []uint64,
Expand Down Expand Up @@ -143,7 +176,7 @@ func assertTimelockOwnership(
ctx := tests.Context(t)
// check that the ownership has been transferred correctly
for _, chain := range chains {
for _, contract := range []ownershipTransferrer{
for _, contract := range []commonchangeset.OwnershipTransferrer{
state.Chains[chain].OnRamp,
state.Chains[chain].OffRamp,
state.Chains[chain].FeeQuoter,
Expand All @@ -160,7 +193,7 @@ func assertTimelockOwnership(

// check home chain contracts ownership
homeChainTimelockAddress := state.Chains[e.HomeChainSel].Timelock.Address()
for _, contract := range []ownershipTransferrer{
for _, contract := range []commonchangeset.OwnershipTransferrer{
state.Chains[e.HomeChainSel].CapabilityRegistry,
state.Chains[e.HomeChainSel].CCIPHome,
state.Chains[e.HomeChainSel].RMNHome,
Expand Down
8 changes: 2 additions & 6 deletions deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,8 @@ func TestActiveCandidate(t *testing.T) {
_, err = commonchangeset.ApplyChangesets(t, e, timelocks, []commonchangeset.ChangesetApplication{
// note this doesn't have proposals.
{
Changeset: commonchangeset.WrapChangeSet(NewTransferOwnershipChangeset),
Config: TransferOwnershipConfig{
State: state,
ChainSelectors: allChains,
HomeChainSelector: tenv.HomeChainSel,
},
Changeset: commonchangeset.WrapChangeSet(commonchangeset.NewTransferOwnershipChangeset),
Config: genTestTransferOwnershipConfig(tenv, allChains, state),
},
// this has proposals, ApplyChangesets will sign & execute them.
// in practice, signing and executing are separated processes.
Expand Down
8 changes: 2 additions & 6 deletions deployment/ccip/changeset/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,8 @@ func TestAddChainInbound(t *testing.T) {
}, []commonchangeset.ChangesetApplication{
// note this doesn't have proposals.
{
Changeset: commonchangeset.WrapChangeSet(NewTransferOwnershipChangeset),
Config: TransferOwnershipConfig{
State: state,
ChainSelectors: initialDeploy,
HomeChainSelector: e.HomeChainSel,
},
Changeset: commonchangeset.WrapChangeSet(commonchangeset.NewTransferOwnershipChangeset),
Config: genTestTransferOwnershipConfig(e, initialDeploy, state),
},
// this has proposals, ApplyChangesets will sign & execute them.
// in practice, signing and executing are separated processes.
Expand Down
95 changes: 0 additions & 95 deletions deployment/ccip/changeset/transfer_ownership.go

This file was deleted.

70 changes: 70 additions & 0 deletions deployment/common/changeset/transfer_ownership.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package changeset

import (
"fmt"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/smartcontractkit/chainlink/deployment"
)

type OwnershipTransferrer interface {
TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*gethtypes.Transaction, error)
Owner(opts *bind.CallOpts) (common.Address, error)
}

type TransferOwnershipConfig struct {
// TimelocksPerChain is a mapping from chain selector to the timelock contract address on that chain.
TimelocksPerChain map[uint64]common.Address

// Contracts is a mapping from chain selector to the ownership transferrers on that chain.
Contracts map[uint64][]OwnershipTransferrer
}

func (t TransferOwnershipConfig) Validate() error {
// check that we have timelocks for the chains in the Contracts field.
for chainSelector := range t.Contracts {
if _, ok := t.TimelocksPerChain[chainSelector]; !ok {
return fmt.Errorf("missing timelock for chain %d", chainSelector)
}
}

return nil
}

var _ deployment.ChangeSet[TransferOwnershipConfig] = NewTransferOwnershipChangeset

// NewTransferOwnershipChangeset creates a changeset that transfers ownership of all the
// contracts in the provided configuration to the the appropriate timelock on that chain.
// If the owner is already the timelock contract, no transaction is sent.
func NewTransferOwnershipChangeset(
e deployment.Environment,
cfg TransferOwnershipConfig,
) (deployment.ChangesetOutput, error) {
if err := cfg.Validate(); err != nil {
return deployment.ChangesetOutput{}, err
}

for chainSelector, contracts := range cfg.Contracts {
timelock := cfg.TimelocksPerChain[chainSelector]
for _, contract := range contracts {
owner, err := contract.Owner(nil)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to get owner of contract %T: %v", contract, err)
}
if owner != timelock {
tx, err := contract.TransferOwnership(e.Chains[chainSelector].DeployerKey, timelock)
_, err = deployment.ConfirmIfNoError(e.Chains[chainSelector], tx, err)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to transfer ownership of contract %T: %v", contract, err)
}
}
}
}

// no new addresses or proposals or jobspecs, so changeset output is empty.
// NOTE: onchain state has technically changed for above contracts, maybe that should
// be captured?
return deployment.ChangesetOutput{}, nil
}

0 comments on commit c474490

Please sign in to comment.