Skip to content

Commit

Permalink
test link transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
graham-chainlink committed Feb 5, 2025
1 parent 853b7b1 commit 159713e
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 14 deletions.
25 changes: 11 additions & 14 deletions deployment/common/changeset/example/link_transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import (
ethTypes "github.com/ethereum/go-ethereum/core/types"
owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"
chain_selectors "github.com/smartcontractkit/chain-selectors"
mcms2 "github.com/smartcontractkit/mcms"
"github.com/smartcontractkit/mcms/sdk/evm"
types2 "github.com/smartcontractkit/mcms/types"

"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/common/changeset"
Expand Down Expand Up @@ -177,7 +179,7 @@ func LinkTransfer(e deployment.Environment, cfg *LinkTransferConfig) (deployment
// Initialize state for each chain
linkStatePerChain, mcmsStatePerChain, err := initStatePerChain(cfg, e)

allBatches := []timelock.BatchChainOperation{}
allBatches := []types2.BatchOperation{}
for chainSelector := range cfg.Transfers {
chainID := mcms.ChainIdentifier(chainSelector)
chain := e.Chains[chainSelector]
Expand All @@ -190,9 +192,9 @@ func LinkTransfer(e deployment.Environment, cfg *LinkTransferConfig) (deployment
mcmsPerChain[uint64(chainID)] = mcmsState.ProposerMcm

timelockAddresses[chainSelector] = timelockAddress
batch := timelock.BatchChainOperation{
ChainIdentifier: chainID,
Batch: []mcms.Operation{},
batch := types2.BatchOperation{
ChainSelector: types2.ChainSelector(chainID),
Transactions: []types2.Transaction{},
}

opts := getDeployer(e, chainSelector, cfg.McmsConfig)
Expand All @@ -202,21 +204,16 @@ func LinkTransfer(e deployment.Environment, cfg *LinkTransferConfig) (deployment
if err != nil {
return deployment.ChangesetOutput{}, err
}
op := mcms.Operation{
To: linkAddress,
Data: tx.Data(),
Value: big.NewInt(0),
ContractType: string(types.LinkToken),
}
batch.Batch = append(batch.Batch, op)
op := evm.NewTransaction(linkAddress, tx.Data(), big.NewInt(0), string(types.LinkToken), []string{})
batch.Transactions = append(batch.Transactions, op)
totalAmount.Add(totalAmount, transfer.Value)
}

allBatches = append(allBatches, batch)
}

if cfg.McmsConfig != nil {
proposal, err := proposalutils.BuildProposalFromBatches(
proposal, err := proposalutils.BuildProposalFromBatchesV2(
timelockAddresses,
mcmsPerChain,
allBatches,
Expand All @@ -228,7 +225,7 @@ func LinkTransfer(e deployment.Environment, cfg *LinkTransferConfig) (deployment
}

return deployment.ChangesetOutput{
Proposals: []timelock.MCMSWithTimelockProposal{*proposal},
MCMSTimelockProposals: []mcms2.TimelockProposal{*proposal},
}, nil
}

Expand Down
31 changes: 31 additions & 0 deletions deployment/common/changeset/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,37 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelockContractsPe
}
}
}
if out.MCMSTimelockProposals != nil {
for _, prop := range out.MCMSTimelockProposals {
chains := mapset.NewSet[uint64]()
for _, op := range prop.Operations {
chains.Add(uint64(op.ChainSelector))
}

p := proposalutils.SignMCMSTimelockProposal(t, e, &prop)
for _, sel := range chains.ToSlice() {
timelockContracts, ok := timelockContractsPerChain[sel]
if !ok || timelockContracts == nil {
return deployment.Environment{}, fmt.Errorf("timelock contracts not found for chain %d", sel)
}

proposalutils.ExecuteProposalV2(t, e, p, sel)
}
}
}
if out.MCMSProposals != nil {
for _, prop := range out.MCMSProposals {
chains := mapset.NewSet[uint64]()
for _, op := range prop.Operations {
chains.Add(uint64(op.ChainSelector))
}

p := proposalutils.SignMCMSProposal(t, e, &prop)
for _, sel := range chains.ToSlice() {
proposalutils.ExecuteProposalV2(t, e, p, sel)
}
}
}
currentEnv = deployment.Environment{
Name: e.Name,
Logger: e.Logger,
Expand Down
96 changes: 96 additions & 0 deletions deployment/common/proposalutils/mcms_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import (
"testing"

"github.com/ethereum/go-ethereum/common"
types2 "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/config"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"
chainsel "github.com/smartcontractkit/chain-selectors"
mcms2 "github.com/smartcontractkit/mcms"
"github.com/smartcontractkit/mcms/sdk"
"github.com/smartcontractkit/mcms/sdk/evm"
"github.com/smartcontractkit/mcms/types"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink/deployment"
Expand Down Expand Up @@ -82,6 +87,97 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex
require.NoError(t, RunTimelockExecutor(env, cfg))
}

func SignMCMSTimelockProposal(t *testing.T, env deployment.Environment, proposal *mcms2.TimelockProposal) *mcms2.Proposal {
converters := make(map[types.ChainSelector]sdk.TimelockConverter)
inspectorsMap := make(map[types.ChainSelector]sdk.Inspector)
for _, chain := range env.Chains {
chainselc, exists := chainsel.ChainBySelector(chain.Selector)
require.True(t, exists)
chainSel := types.ChainSelector(chainselc.Selector)
converters[chainSel] = &evm.TimelockConverter{}
inspectorsMap[chainSel] = evm.NewInspector(chain.Client)
}

p, _, err := proposal.Convert(env.GetContext(), converters)
require.NoError(t, err)

signable, err := mcms2.NewSignable(&p, inspectorsMap)
require.NoError(t, err)

err = signable.ValidateConfigs(env.GetContext())
require.NoError(t, err)

signer := mcms2.NewPrivateKeySigner(TestXXXMCMSSigner)
_, err = signable.SignAndAppend(signer)
require.NoError(t, err)

quorumMet, err := signable.ValidateSignatures(env.GetContext())
require.NoError(t, err)
require.True(t, quorumMet)

return &p
}

func SignMCMSProposal(t *testing.T, env deployment.Environment, p *mcms2.Proposal) *mcms2.Proposal {
converters := make(map[types.ChainSelector]sdk.TimelockConverter)
inspectorsMap := make(map[types.ChainSelector]sdk.Inspector)
for _, chain := range env.Chains {
chainselc, exists := chainsel.ChainBySelector(chain.Selector)
require.True(t, exists)
chainSel := types.ChainSelector(chainselc.Selector)
converters[chainSel] = &evm.TimelockConverter{}
inspectorsMap[chainSel] = evm.NewInspector(chain.Client)
}

signable, err := mcms2.NewSignable(p, inspectorsMap)
require.NoError(t, err)

err = signable.ValidateConfigs(env.GetContext())
require.NoError(t, err)

signer := mcms2.NewPrivateKeySigner(TestXXXMCMSSigner)
_, err = signable.SignAndAppend(signer)
require.NoError(t, err)

quorumMet, err := signable.ValidateSignatures(env.GetContext())
require.NoError(t, err)
require.True(t, quorumMet)

return p
}

func ExecuteProposalV2(t *testing.T, env deployment.Environment, proposal *mcms2.Proposal, sel uint64) {
t.Log("Executing proposal on chain", sel)

encoders, err := proposal.GetEncoders()
require.NoError(t, err)

selector := types.ChainSelector(sel)
evmExecutor := evm.NewExecutor(encoders[selector].(*evm.Encoder), env.Chains[sel].Client, env.Chains[sel].DeployerKey)
executorsMap := map[types.ChainSelector]sdk.Executor{
selector: evmExecutor,
}
executable, err := mcms2.NewExecutable(proposal, executorsMap)
require.NoError(t, err)

chain := env.Chains[sel]
root, err := executable.SetRoot(env.GetContext(), selector)
require.NoError(t, deployment.MaybeDataErr(err))

evmTransaction := root.RawTransaction.(*types2.Transaction)
_, err = chain.Confirm(evmTransaction)
require.NoError(t, err)

for i := 0; i < len(proposal.Operations); i++ {
result, err := executable.Execute(env.GetContext(), i)
require.NoError(t, err)

evmTransaction = result.RawTransaction.(*types2.Transaction)
_, err = chain.Confirm(evmTransaction)
require.NoError(t, err)
}
}

func SingleGroupTimelockConfig(t *testing.T) commontypes.MCMSWithTimelockConfig {
return commontypes.MCMSWithTimelockConfig{
Canceller: SingleGroupMCMS(t),
Expand Down

0 comments on commit 159713e

Please sign in to comment.