Skip to content

Commit

Permalink
[CCIP Merge] Capabilities fix [CCIP-2943] (#14048)
Browse files Browse the repository at this point in the history
* Fix compilation for launcher, diff

Make application.go ready for adding more fixes


* Fix launcher tests

* ks-409 fix the mock trigger to ensure events are sent (#14047)

* Add ccip to job orm

* Add capabilities directory under BUSL license

* Prep to instantiate separate registrysyncer for CCIP

* Move registrySyncer creation into ccip delegate

* [chore] Change registrysyncer config to bytes

* Fix launcher diff tests after changing structs in syncer

* Fix linting

* MAke simulated backend client work with chains other than 1337

* core/capabilities/ccip: use OCR offchain config (#1264)

We want to define and use the appropriate OCR offchain config for each
plugin.

Requires smartcontractkit/chainlink-ccip#36

* Cleaning up

* Add capabilities types to mockery

---------

Co-authored-by: Cedric Cordenier <[email protected]>
Co-authored-by: Matthew Pendrey <[email protected]>
Co-authored-by: Makram <[email protected]>
  • Loading branch information
4 people authored Aug 7, 2024
1 parent c509147 commit ba0e8c5
Show file tree
Hide file tree
Showing 42 changed files with 963 additions and 676 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-hats-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

#internal fix the mock trigger to ensure events are sent
4 changes: 4 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ packages:
github.com/smartcontractkit/chainlink/v2/core/bridges:
interfaces:
ORM:
github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types:
interfaces:
CCIPOracle:
OracleCreator:
github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types:
interfaces:
Dispatcher:
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ THE SOFTWARE.


*All content residing under (1) “/contracts/src/v0.8/ccip”; (2)
“/core/gethwrappers/ccip”; (3) “/core/services/ocr2/plugins/ccip” are licensed
“/core/gethwrappers/ccip”; (3) “/core/services/ocr2/plugins/ccip”; (4) "/core/capabilities/ccip" are licensed
under “Business Source License 1.1” with a Change Date of May 23, 2027 and
Change License to “MIT License”

Expand Down
136 changes: 93 additions & 43 deletions core/capabilities/ccip/ccip_integration_tests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import (
"encoding/hex"
"math/big"
"sort"
"strconv"
"testing"
"time"

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
"github.com/smartcontractkit/chainlink-ccip/pluginconfig"
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

Expand Down Expand Up @@ -53,9 +56,27 @@ const (
CapabilityLabelledName = "ccip"
CapabilityVersion = "v1.0.0"
NodeOperatorID = 1
// TODO: this is 8 hours now to match what is hardcoded in the exec plugin.
// Eventually this should drive what is set in the exec plugin.
FirstBlockAge = 8 * time.Hour

// These constants drive what is set in the plugin offchain configs.
FirstBlockAge = 8 * time.Hour
RemoteGasPriceBatchWriteFrequency = 30 * time.Minute
BatchGasLimit = 6_500_000
RelativeBoostPerWaitHour = 1.5
InflightCacheExpiry = 10 * time.Minute
RootSnoozeTime = 30 * time.Minute
BatchingStrategyID = 0
DeltaProgress = 30 * time.Second
DeltaResend = 10 * time.Second
DeltaInitial = 20 * time.Second
DeltaRound = 2 * time.Second
DeltaGrace = 2 * time.Second
DeltaCertifiedCommitRequest = 10 * time.Second
DeltaStage = 10 * time.Second
Rmax = 3
MaxDurationQuery = 50 * time.Millisecond
MaxDurationObservation = 5 * time.Second
MaxDurationShouldAcceptAttestedReport = 10 * time.Second
MaxDurationShouldTransmitAcceptedReport = 10 * time.Second
)

func e18Mult(amount uint64) *big.Int {
Expand Down Expand Up @@ -412,11 +433,18 @@ func AddChainConfig(
// Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail
sortP2PIDS(p2pIDs)
// First Add ChainConfig that includes all p2pIDs as readers
chainConfig := integrationhelpers.SetupConfigInfo(chainSelector, p2pIDs, f, []byte(strconv.FormatUint(chainSelector, 10)))
encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{
GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000),
DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0),
FinalityDepth: 10,
OptimisticConfirmations: 1,
})
require.NoError(t, err)
chainConfig := integrationhelpers.SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig)
inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{
chainConfig,
}
_, err := h.ccipConfig.ApplyChainConfigUpdates(h.owner, nil, inputConfig)
_, err = h.ccipConfig.ApplyChainConfigUpdates(h.owner, nil, inputConfig)
require.NoError(t, err)
h.backend.Commit()
return chainConfig
Expand All @@ -437,49 +465,71 @@ func (h *homeChain) AddDON(
for range oracles {
schedule = append(schedule, 1)
}
signers, transmitters, f, _, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests(
30*time.Second, // deltaProgress
10*time.Second, // deltaResend
20*time.Second, // deltaInitial
2*time.Second, // deltaRound
2*time.Second, // deltaGrace
10*time.Second, // deltaCertifiedCommitRequest TODO: whats a good value for this?
10*time.Second, // deltaStage
3, // rmax
schedule,
oracles,
[]byte{}, // empty offchain config
50*time.Millisecond, // maxDurationQuery
5*time.Second, // maxDurationObservation
10*time.Second, // maxDurationShouldAcceptAttestedReport
10*time.Second, // maxDurationShouldTransmitAcceptedReport
int(f),
[]byte{}) // empty OnChainConfig
require.NoError(t, err, "failed to create contract config")

tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi()
require.NoError(t, err)

signersBytes := make([][]byte, len(signers))
for i, signer := range signers {
signersBytes[i] = signer
}

transmittersBytes := make([][]byte, len(transmitters))
for i, transmitter := range transmitters {
// anotherErr because linting doesn't want to shadow err
parsed, anotherErr := common.ParseHexOrString(string(transmitter))
require.NoError(t, anotherErr)
transmittersBytes[i] = parsed
}

// Add DON on capability registry contract
var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config
for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} {
var encodedOffchainConfig []byte
var err2 error
if pluginType == cctypes.PluginTypeCCIPCommit {
encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{
RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency),
// TODO: implement token price writes
// TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency),
})
require.NoError(t, err2)
} else {
encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{
BatchGasLimit: BatchGasLimit,
RelativeBoostPerWaitHour: RelativeBoostPerWaitHour,
MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge),
InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry),
RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime),
BatchingStrategyID: BatchingStrategyID,
})
require.NoError(t, err2)
}
signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests(
DeltaProgress,
DeltaResend,
DeltaInitial,
DeltaRound,
DeltaGrace,
DeltaCertifiedCommitRequest,
DeltaStage,
Rmax,
schedule,
oracles,
encodedOffchainConfig,
MaxDurationQuery,
MaxDurationObservation,
MaxDurationShouldAcceptAttestedReport,
MaxDurationShouldTransmitAcceptedReport,
int(f),
[]byte{}, // empty OnChainConfig
)
require.NoError(t, err2, "failed to create contract config")

signersBytes := make([][]byte, len(signers))
for i, signer := range signers {
signersBytes[i] = signer
}

transmittersBytes := make([][]byte, len(transmitters))
for i, transmitter := range transmitters {
// anotherErr because linting doesn't want to shadow err
parsed, anotherErr := common.ParseHexOrString(string(transmitter))
require.NoError(t, anotherErr)
transmittersBytes[i] = parsed
}

ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{
PluginType: uint8(pluginType),
ChainSelector: chainSelector,
F: f,
F: configF,
OffchainConfigVersion: offchainConfigVersion,
OfframpAddress: uni.offramp.Address().Bytes(),
BootstrapP2PIds: [][32]byte{bootstrapP2PID},
Expand Down Expand Up @@ -522,13 +572,13 @@ func (h *homeChain) AddDON(
require.NotZero(t, donID, "failed to get donID from config set event")

var signerAddresses []common.Address
for _, signer := range signers {
signerAddresses = append(signerAddresses, common.BytesToAddress(signer))
for _, oracle := range oracles {
signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey))
}

var transmitterAddresses []common.Address
for _, transmitter := range transmitters {
transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(transmitter)))
for _, oracle := range oracles {
transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount)))
}

// get the config digest from the ccip config contract and set config on the offramp.
Expand Down
23 changes: 19 additions & 4 deletions core/capabilities/ccip/ccip_integration_tests/home_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

libocrtypes "github.com/smartcontractkit/libocr/ragep2p/types"

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
Expand All @@ -35,15 +36,22 @@ func TestHomeChainReader(t *testing.T) {
p2pIDs := integrationhelpers.P2pIDsFromInts(arr)
uni.AddCapability(p2pIDs)
//==============================Apply configs to Capability Contract=================================
chainAConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainA, p2pIDs, integrationhelpers.FChainA, []byte("ChainA"))
chainBConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainB, p2pIDs[1:], integrationhelpers.FChainB, []byte("ChainB"))
chainCConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainC, p2pIDs[2:], integrationhelpers.FChainC, []byte("ChainC"))
encodedChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{
GasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1000),
DAGasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1_000_000),
FinalityDepth: -1,
OptimisticConfirmations: 1,
})
require.NoError(t, err)
chainAConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainA, p2pIDs, integrationhelpers.FChainA, encodedChainConfig)
chainBConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainB, p2pIDs[1:], integrationhelpers.FChainB, encodedChainConfig)
chainCConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainC, p2pIDs[2:], integrationhelpers.FChainC, encodedChainConfig)
inputConfig := []capcfg.CCIPConfigTypesChainConfigInfo{
chainAConf,
chainBConf,
chainCConf,
}
_, err := uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, nil, inputConfig)
_, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, nil, inputConfig)
require.NoError(t, err)
uni.Backend.Commit()
//================================Setup HomeChainReader===============================
Expand All @@ -63,6 +71,7 @@ func TestHomeChainReader(t *testing.T) {
expectedChainConfigs[cciptypes.ChainSelector(c.ChainSelector)] = ccipreader.ChainConfig{
FChain: int(c.ChainConfig.FChain),
SupportedNodes: toPeerIDs(c.ChainConfig.Readers),
Config: mustDecodeChainConfig(t, c.ChainConfig.Config),
}
}
configs, err := homeChain.GetAllChainConfigs()
Expand All @@ -86,3 +95,9 @@ func toPeerIDs(readers [][32]byte) mapset.Set[libocrtypes.PeerID] {
}
return peerIDs
}

func mustDecodeChainConfig(t *testing.T, encodedChainConfig []byte) chainconfig.ChainConfig {
chainConfig, err := chainconfig.DecodeChainConfig(encodedChainConfig)
require.NoError(t, err)
return chainConfig
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ const (
CcipCapabilityVersion = "v1.0"
)

var CapabilityID = fmt.Sprintf("%s@%s", CcipCapabilityLabelledName, CcipCapabilityVersion)

type TestUniverse struct {
Transactor *bind.TransactOpts
Backend *backends.SimulatedBackend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"testing"
"time"

coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand Down Expand Up @@ -131,9 +132,10 @@ func setupNodeOCR3(
CSAETHKeystore: kStore,
}
relayerFactory := chainlink.RelayerFactory{
Logger: lggr,
LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()),
GRPCOpts: loop.GRPCOpts{},
Logger: lggr,
LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()),
GRPCOpts: loop.GRPCOpts{},
CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t),
}
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testutils.Context(t), relayerFactory, evmOpts)}
rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...)
Expand Down
22 changes: 15 additions & 7 deletions core/capabilities/ccip/configs/evm/chain_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ var (
offrampABI = evmtypes.MustGetABI(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI)
)

func MustChainWriterConfig(fromAddress common.Address, maxGasPrice *assets.Wei) []byte {
rawConfig := ChainWriterConfigRaw(fromAddress, maxGasPrice)
func MustChainWriterConfig(
fromAddress common.Address,
maxGasPrice *assets.Wei,
commitGasLimit,
execBatchGasLimit uint64,
) []byte {
rawConfig := ChainWriterConfigRaw(fromAddress, maxGasPrice, commitGasLimit, execBatchGasLimit)
encoded, err := json.Marshal(rawConfig)
if err != nil {
panic(fmt.Errorf("failed to marshal ChainWriterConfig: %w", err))
Expand All @@ -31,7 +36,12 @@ func MustChainWriterConfig(fromAddress common.Address, maxGasPrice *assets.Wei)
}

// ChainWriterConfigRaw returns a ChainWriterConfig that can be used to transmit commit and execute reports.
func ChainWriterConfigRaw(fromAddress common.Address, maxGasPrice *assets.Wei) evmrelaytypes.ChainWriterConfig {
func ChainWriterConfigRaw(
fromAddress common.Address,
maxGasPrice *assets.Wei,
commitGasLimit,
execBatchGasLimit uint64,
) evmrelaytypes.ChainWriterConfig {
return evmrelaytypes.ChainWriterConfig{
Contracts: map[string]*evmrelaytypes.ContractConfig{
consts.ContractNameOffRamp: {
Expand All @@ -40,14 +50,12 @@ func ChainWriterConfigRaw(fromAddress common.Address, maxGasPrice *assets.Wei) e
consts.MethodCommit: {
ChainSpecificName: mustGetMethodName("commit", offrampABI),
FromAddress: fromAddress,
// TODO: inject this into the method, should be fetched from the OCR config.
GasLimit: 500_000,
GasLimit: commitGasLimit,
},
consts.MethodExecute: {
ChainSpecificName: mustGetMethodName("execute", offrampABI),
FromAddress: fromAddress,
// TODO: inject this into the method, should be fetched from the OCR config.
GasLimit: 6_500_000,
GasLimit: execBatchGasLimit,
},
},
},
Expand Down
Loading

0 comments on commit ba0e8c5

Please sign in to comment.