-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: keystone ownership transfer [KS-558] (#15451)
* wip * add test * make the proposal multichain * add transfer ownership changeset use these changesets in other tests and axe duplicate code * fix add_chain_test.go * extract common code to func * move changeset to common Refactor the proposal helpers a bit * move transfer ownership cs to common * fix * feat: add transfer and accept ownership changesets for keystone * chore: rename to OwnersPerChain * feat: add changeset for feeds consumer deployment and update ownership changesets with it. * feat: modify ownership changesets to work on multiple contracts per chain. * fix: comment * Update deployment/common/changeset/transfer_ownership.go Co-authored-by: Graham Goh <graham.goh@smartcontract.com> * fix: remove logger from deploy func in favor of contextualized logger on the deployment struct. * fix: use variadic for better readability. * fix: use variadic for appending, and add type assertions for functions signatures --------- Co-authored-by: Makram Kamaleddine <makramkd@users.noreply.github.com> Co-authored-by: Graham Goh <graham.goh@smartcontract.com>
- Loading branch information
1 parent
9deaaf5
commit 636e633
Showing
23 changed files
with
699 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package changeset | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
||
ccipowner "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" | ||
|
||
"github.com/smartcontractkit/chainlink/deployment" | ||
"github.com/smartcontractkit/chainlink/deployment/common/changeset" | ||
) | ||
|
||
func toOwnershipAcceptors[T changeset.OwnershipAcceptor](items []T) []changeset.OwnershipAcceptor { | ||
ownershipAcceptors := make([]changeset.OwnershipAcceptor, len(items)) | ||
for i, item := range items { | ||
ownershipAcceptors[i] = item | ||
} | ||
return ownershipAcceptors | ||
} | ||
|
||
type AcceptAllOwnershipRequest struct { | ||
ChainSelector uint64 | ||
MinDelay time.Duration | ||
} | ||
|
||
var _ deployment.ChangeSet[*AcceptAllOwnershipRequest] = AcceptAllOwnershipsProposal | ||
|
||
// AcceptAllOwnershipsProposal creates a MCMS proposal to call accept ownership on all the Keystone contracts in the address book. | ||
func AcceptAllOwnershipsProposal(e deployment.Environment, req *AcceptAllOwnershipRequest) (deployment.ChangesetOutput, error) { | ||
chainSelector := req.ChainSelector | ||
minDelay := req.MinDelay | ||
chain := e.Chains[chainSelector] | ||
addrBook := e.ExistingAddresses | ||
|
||
// Fetch contracts from the address book. | ||
timelocks, err := timelocksFromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
capRegs, err := capRegistriesFromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
ocr3, err := ocr3FromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
forwarders, err := forwardersFromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
consumers, err := feedsConsumersFromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
mcmsProposers, err := proposersFromAddrBook(addrBook, chain) | ||
if err != nil { | ||
return deployment.ChangesetOutput{}, err | ||
} | ||
|
||
// Initialize the OwnershipAcceptors slice | ||
var ownershipAcceptors []changeset.OwnershipAcceptor | ||
|
||
// Append all contracts | ||
ownershipAcceptors = append(ownershipAcceptors, toOwnershipAcceptors(capRegs)...) | ||
ownershipAcceptors = append(ownershipAcceptors, toOwnershipAcceptors(ocr3)...) | ||
ownershipAcceptors = append(ownershipAcceptors, toOwnershipAcceptors(forwarders)...) | ||
ownershipAcceptors = append(ownershipAcceptors, toOwnershipAcceptors(consumers)...) | ||
|
||
// Construct the configuration | ||
cfg := changeset.AcceptOwnershipConfig{ | ||
OwnersPerChain: map[uint64]common.Address{ | ||
// Assuming there is only one timelock per chain. | ||
chainSelector: timelocks[0].Address(), | ||
}, | ||
ProposerMCMSes: map[uint64]*ccipowner.ManyChainMultiSig{ | ||
// Assuming there is only one MCMS proposer per chain. | ||
chainSelector: mcmsProposers[0], | ||
}, | ||
Contracts: map[uint64][]changeset.OwnershipAcceptor{ | ||
chainSelector: ownershipAcceptors, | ||
}, | ||
MinDelay: minDelay, | ||
} | ||
|
||
// Create and return the changeset | ||
return changeset.NewAcceptOwnershipChangeset(e, cfg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package changeset_test | ||
|
||
import ( | ||
"math/big" | ||
"testing" | ||
"time" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap/zapcore" | ||
|
||
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" | ||
"github.com/smartcontractkit/chainlink/deployment/common/types" | ||
"github.com/smartcontractkit/chainlink/deployment/environment/memory" | ||
"github.com/smartcontractkit/chainlink/deployment/keystone/changeset" | ||
) | ||
|
||
func TestAcceptAllOwnership(t *testing.T) { | ||
t.Parallel() | ||
lggr := logger.Test(t) | ||
cfg := memory.MemoryEnvironmentConfig{ | ||
Nodes: 1, | ||
Chains: 2, | ||
} | ||
env := memory.NewMemoryEnvironment(t, lggr, zapcore.DebugLevel, cfg) | ||
registrySel := env.AllChainSelectors()[0] | ||
chCapReg, err := changeset.DeployCapabilityRegistry(env, registrySel) | ||
require.NoError(t, err) | ||
require.NotNil(t, chCapReg) | ||
err = env.ExistingAddresses.Merge(chCapReg.AddressBook) | ||
require.NoError(t, err) | ||
|
||
chOcr3, err := changeset.DeployOCR3(env, registrySel) | ||
require.NoError(t, err) | ||
require.NotNil(t, chOcr3) | ||
err = env.ExistingAddresses.Merge(chOcr3.AddressBook) | ||
require.NoError(t, err) | ||
|
||
chForwarder, err := changeset.DeployForwarder(env, registrySel) | ||
require.NoError(t, err) | ||
require.NotNil(t, chForwarder) | ||
err = env.ExistingAddresses.Merge(chForwarder.AddressBook) | ||
require.NoError(t, err) | ||
|
||
chConsumer, err := changeset.DeployFeedsConsumer(env, &changeset.DeployFeedsConsumerRequest{ | ||
ChainSelector: registrySel, | ||
}) | ||
require.NoError(t, err) | ||
require.NotNil(t, chConsumer) | ||
err = env.ExistingAddresses.Merge(chConsumer.AddressBook) | ||
require.NoError(t, err) | ||
|
||
chMcms, err := commonchangeset.DeployMCMSWithTimelock(env, map[uint64]types.MCMSWithTimelockConfig{ | ||
registrySel: { | ||
Canceller: commonchangeset.SingleGroupMCMS(t), | ||
Bypasser: commonchangeset.SingleGroupMCMS(t), | ||
Proposer: commonchangeset.SingleGroupMCMS(t), | ||
TimelockExecutors: env.AllDeployerKeys(), | ||
TimelockMinDelay: big.NewInt(0), | ||
}, | ||
}) | ||
err = env.ExistingAddresses.Merge(chMcms.AddressBook) | ||
require.NoError(t, err) | ||
|
||
require.NoError(t, err) | ||
require.NotNil(t, chMcms) | ||
|
||
resp, err := changeset.TransferAllOwnership(env, &changeset.TransferAllOwnershipRequest{ | ||
ChainSelector: registrySel, | ||
}) | ||
require.NoError(t, err) | ||
require.NotNil(t, resp) | ||
|
||
// Test the changeset | ||
output, err := changeset.AcceptAllOwnershipsProposal(env, &changeset.AcceptAllOwnershipRequest{ | ||
ChainSelector: registrySel, | ||
MinDelay: time.Duration(0), | ||
}) | ||
require.NoError(t, err) | ||
require.NotNil(t, output) | ||
require.Len(t, output.Proposals, 1) | ||
proposal := output.Proposals[0] | ||
require.Len(t, proposal.Transactions, 1) | ||
txs := proposal.Transactions[0] | ||
require.Len(t, txs.Batch, 4) | ||
} |
Oops, something went wrong.