Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mcms/evm/internal/gasboost/gas_boost.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
package gasboost

import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
cldfevm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
opscontract "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/operations2/contract"
cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
)

// CloneTransactOptsWithGas returns a copy of opts with optional gas limit and price overrides.
func CloneTransactOptsWithGas(opts *bind.TransactOpts, gasLimit, gasPrice uint64) *bind.TransactOpts {
if opts == nil {
return nil
}

newOpts := *opts
if gasLimit > 0 {
newOpts.GasLimit = gasLimit
}
if gasPrice > 0 {
newOpts.GasPrice = new(big.Int).SetUint64(gasPrice)
}

return &newOpts
}

// ToContractConfig converts proposal gas-boost settings to framework contract gas-boost config.
func ToContractConfig(cfg *cldfproposalutils.GasBoostConfig) *opscontract.GasBoostConfig {
if cfg == nil {
Expand Down
18 changes: 18 additions & 0 deletions mcms/evm/internal/gasboost/gas_boost_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
package gasboost

import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils"
"github.com/stretchr/testify/require"
)

func TestCloneTransactOptsWithGas(t *testing.T) {
t.Parallel()

require.Nil(t, CloneTransactOptsWithGas(nil, 100, 200))

opts := &bind.TransactOpts{GasLimit: 1, GasPrice: big.NewInt(1)}
got := CloneTransactOptsWithGas(opts, 0, 0)
require.Equal(t, uint64(1), got.GasLimit)
require.Equal(t, int64(1), got.GasPrice.Int64())
require.NotSame(t, opts, got)

got = CloneTransactOptsWithGas(opts, 500_000, 30_000_000_000)
require.Equal(t, uint64(500_000), got.GasLimit)
require.Equal(t, uint64(30_000_000_000), got.GasPrice.Uint64())
}

func TestToContractConfig(t *testing.T) {
t.Parallel()

Expand Down
33 changes: 0 additions & 33 deletions mcms/evm/set-config/evm_call.go

This file was deleted.

59 changes: 36 additions & 23 deletions mcms/evm/set-config/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ package evmsetconfig

import (
"fmt"
"math/big"

"github.com/Masterminds/semver/v3"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
mcmsevm "github.com/smartcontractkit/mcms/sdk/evm"
mcmsbindings "github.com/smartcontractkit/mcms/sdk/evm/bindings"
mcmstypes "github.com/smartcontractkit/mcms/types"

cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
opscontract "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/operations2/contract"
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
mcmsevm "github.com/smartcontractkit/mcms/sdk/evm"
mcmsbindings "github.com/smartcontractkit/mcms/sdk/evm/bindings"
mcmstypes "github.com/smartcontractkit/mcms/types"

"github.com/smartcontractkit/cld-changesets/mcms/evm/internal/gasboost"
)
Expand Down Expand Up @@ -50,50 +51,62 @@ var OpEVMSetConfigMCM = operations.NewOperation(
"evm-mcm-set-config",
semver.MustParse("1.0.0"),
"Sets MCMS config on an EVM MCM contract",
func(b operations.Bundle, deps cldf_evm.Chain, in OpEVMSetConfigInput) (EVMCallOutput, error) {
func(b operations.Bundle, deps cldf_evm.Chain, in OpEVMSetConfigInput) (opscontract.WriteOutput, error) {
if !in.NoSend && deps.DeployerKey == nil {
return EVMCallOutput{}, fmt.Errorf("missing deployer key for chain %d", deps.Selector)
return opscontract.WriteOutput{}, fmt.Errorf("missing deployer key for chain %d", deps.Selector)
}

var opts *bind.TransactOpts
if in.NoSend {
opts = cldf.SimTransactOpts()
} else {
opts = cloneTransactOptsWithGas(deps.DeployerKey, in.GasLimit, in.GasPrice)
opts = gasboost.CloneTransactOptsWithGas(deps.DeployerKey, in.GasLimit, in.GasPrice)
}
if opts == nil {
return EVMCallOutput{}, fmt.Errorf("failed to build transact opts for chain %d", deps.Selector)
return opscontract.WriteOutput{}, fmt.Errorf("failed to build transact opts for chain %d", deps.Selector)
}
opts.Context = b.GetContext()

configurer := mcmsevm.NewConfigurer(deps.Client, opts)
res, err := configurer.SetConfig(b.GetContext(), in.Target.Address.Hex(), &in.Target.Config, false)
if err != nil {
return EVMCallOutput{}, fmt.Errorf("failed to set config on %s: %w", in.Target.Address, err)
return opscontract.WriteOutput{}, fmt.Errorf("failed to set config on %s: %w", in.Target.Address, err)
}

tx, ok := res.RawData.(*types.Transaction)
if !ok {
return EVMCallOutput{}, fmt.Errorf("unexpected raw data type %T from SetConfig", res.RawData)
return opscontract.WriteOutput{}, fmt.Errorf("unexpected raw data type %T from SetConfig", res.RawData)
}

confirmed := false
if !in.NoSend {
if _, err = cldf.ConfirmIfNoErrorWithABI(deps, tx, mcmsbindings.ManyChainMultiSigABI, err); err != nil {
return EVMCallOutput{}, fmt.Errorf("failed to confirm set config tx against %s: %w", in.Target.Address, err)
}
b.Logger.Infow("SetConfig tx confirmed", "txHash", res.Hash, "address", in.Target.Address.Hex())
confirmed = true
out := writeOutputFromSetConfig(deps.Selector, in.Target, tx)
if in.NoSend {
return out, nil
}

if _, err = cldf.ConfirmIfNoErrorWithABI(deps, tx, mcmsbindings.ManyChainMultiSigABI, err); err != nil {
return opscontract.WriteOutput{}, fmt.Errorf("failed to confirm set config tx against %s: %w", in.Target.Address, err)
}
b.Logger.Infow("SetConfig tx confirmed", "txHash", res.Hash, "address", in.Target.Address.Hex())

out.ExecInfo = &opscontract.ExecInfo{Hash: res.Hash}

return EVMCallOutput{
To: in.Target.Address,
Data: tx.Data(),
ContractType: in.Target.ContractType,
Confirmed: confirmed,
}, nil
return out, nil
},
)

func writeOutputFromSetConfig(chainSelector uint64, target MCMSetConfigTarget, tx *types.Transaction) opscontract.WriteOutput {
return opscontract.WriteOutput{
ChainSelector: chainSelector,
Tx: mcmsevm.NewTransaction(
target.Address,
tx.Data(),
big.NewInt(0),
string(target.ContractType),
[]string{},
),
}
}

func retrySetConfigWithGasBoost(cfg *cldfproposalutils.GasBoostConfig) operations.ExecuteOption[OpEVMSetConfigInput, cldf_evm.Chain] {
if cfg == nil {
return operations.WithRetry[OpEVMSetConfigInput, cldf_evm.Chain]()
Expand Down
27 changes: 5 additions & 22 deletions mcms/evm/set-config/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package evmsetconfig

import (
"crypto/ecdsa"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"

chainselectors "github.com/smartcontractkit/chain-selectors"
cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
opscontract "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/operations2/contract"
mcmscontracts "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/contracts/mcms"
cldftesthelpers "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils/testhelpers"
"github.com/smartcontractkit/chainlink-deployments-framework/engine/test/runtime"
Expand All @@ -37,22 +36,6 @@ func TestOpEVMSetConfigMCM_missingDeployerKey(t *testing.T) {
require.ErrorContains(t, err, "missing deployer key")
}

func TestCloneTransactOptsWithGas(t *testing.T) {
t.Parallel()

require.Nil(t, cloneTransactOptsWithGas(nil, 100, 200))

opts := &bind.TransactOpts{GasLimit: 1, GasPrice: big.NewInt(1)}
got := cloneTransactOptsWithGas(opts, 0, 0)
require.Equal(t, uint64(1), got.GasLimit)
require.Equal(t, int64(1), got.GasPrice.Int64())
require.NotSame(t, opts, got)

got = cloneTransactOptsWithGas(opts, 500_000, 30_000_000_000)
require.Equal(t, uint64(500_000), got.GasLimit)
require.Equal(t, uint64(30_000_000_000), got.GasPrice.Uint64())
}

func TestOpEVMSetConfigInputGasOverridable(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -108,12 +91,12 @@ func TestOpEVMSetConfigMCM(t *testing.T) {
},
)
require.NoError(t, err)
require.Equal(t, refs.Canceller, report.Output.To)
require.NotEmpty(t, report.Output.Data)
require.Equal(t, !tt.noSend, report.Output.Confirmed)
require.Equal(t, refs.Canceller.Hex(), report.Output.Tx.To)
require.NotEmpty(t, report.Output.Tx.Data)
require.Equal(t, !tt.noSend, report.Output.Executed())

if tt.noSend {
batch, err := evmCallOutputsToBatch(selector, []EVMCallOutput{report.Output})
batch, err := opscontract.NewBatchOperationFromWrites([]opscontract.WriteOutput{report.Output})
require.NoError(t, err)
require.Len(t, batch.Transactions, 1)
require.NoError(t, rt.Exec(
Expand Down
61 changes: 16 additions & 45 deletions mcms/evm/set-config/sequence.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package evmsetconfig

import (
"fmt"
"math/big"
"strconv"

"github.com/Masterminds/semver/v3"
"github.com/ethereum/go-ethereum/common"
cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
opscontract "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/operations2/contract"
"github.com/smartcontractkit/chainlink-deployments-framework/changeset/sequenceutils"
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
mcmstypes "github.com/smartcontractkit/mcms/types"

Expand Down Expand Up @@ -40,11 +39,7 @@ func runEVMSetConfig(
}

useMCMS := in.MCMS != nil

var outs []EVMCallOutput
if useMCMS {
outs = make([]EVMCallOutput, 0, len(targets))
}
var writes []opscontract.WriteOutput

for _, target := range targets {
opReport, execErr := operations.ExecuteOperation(
Expand All @@ -62,29 +57,33 @@ func runEVMSetConfig(
return sequenceutils.OnChainOutput{}, execErr
}

if !useMCMS {
if useMCMS {
writes = append(writes, opReport.Output)
continue
}

out := opReport.Output
out.ContractType = target.ContractType
outs = append(outs, out)
if opReport.Output.Executed() {
b.Logger.Infow("SetConfig tx confirmed",
"chainSelector", chain.Selector,
"address", target.Address.Hex(),
"txHash", opReport.Output.ExecInfo.Hash,
)
}
}

out := sequenceutils.OnChainOutput{}
if !useMCMS {
return out, nil
return sequenceutils.OnChainOutput{}, nil
}

batch, err := evmCallOutputsToBatch(in.ChainSelector, outs)
batch, err := opscontract.NewBatchOperationFromWrites(writes)
if err != nil {
return sequenceutils.OnChainOutput{}, err
}
if len(batch.Transactions) > 0 {
out.BatchOps = []mcmstypes.BatchOperation{batch}
if len(batch.Transactions) == 0 {
return sequenceutils.OnChainOutput{}, nil
}

return out, nil
return sequenceutils.OnChainOutput{BatchOps: []mcmstypes.BatchOperation{batch}}, nil
}

func setConfigTargets(e cldf.Environment, configs []setconfig.ContractSetConfig) ([]MCMSetConfigTarget, error) {
Expand All @@ -108,31 +107,3 @@ func setConfigTargets(e cldf.Environment, configs []setconfig.ContractSetConfig)

return targets, nil
}

func evmCallOutputsToBatch(chainSelector uint64, outs []EVMCallOutput) (mcmstypes.BatchOperation, error) {
result := mcmstypes.BatchOperation{
ChainSelector: mcmstypes.ChainSelector(chainSelector),
Transactions: []mcmstypes.Transaction{},
}

for _, out := range outs {
if out.Confirmed {
continue
}

batchOperation, err := cldfproposalutils.BatchOperationForChain(
chainSelector,
out.To.Hex(),
out.Data,
big.NewInt(0),
string(out.ContractType),
[]string{},
)
if err != nil {
return mcmstypes.BatchOperation{}, fmt.Errorf("failed to create batch operation for chain %d: %w", chainSelector, err)
}
result.Transactions = append(result.Transactions, batchOperation.Transactions...)
}

return result, nil
}
Loading