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
2 changes: 1 addition & 1 deletion core/scripts/cre/environment/configs/workflow-don.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
[nodesets.chain_capabilities]
write-evm = ["1337", "2337"]
read-contract = ["1337", "2337"]
evm = ["1337"]
evm = ["1337", "2337"]

# See ./examples/workflow-don-overrides.toml to learn how to override capability configs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@
override_mode = "each"
http_port_range_start = 10100

# even though this DON is not using any capability for chain with ID 2337 we still need it to be connected to it,
# because bootstrap job for capability DON will be created on the boostrap node from this DON
supported_evm_chains = [1337, 2337]

env_vars = { CL_EVM_CMD = "" }
capabilities = ["ocr3", "custom-compute", "web-api-trigger", "cron", "http-action", "http-trigger", "consensus", "don-time"]

[nodesets.chain_capabilities]
# we want to write only to the home chain, so that we can test whether remote write-evm-2337 capability of the 'capabilities DON' is used
# we want to write only to the home chain, so that we can test whether remote capabilities of the 'capabilities DON' are used
write-evm = ["1337"]
read-contract = ["1337"]
evm = ["1337"]

# See ./examples/workflow-don-overrides.toml to learn how to override capability configs

Expand Down Expand Up @@ -108,13 +113,17 @@
override_mode = "all"
http_port_range_start = 10200

# we need to have chain 1337 configured (even if no capability uses it), because we use node addresses on chain 1337
# to identify nodes in the gateway configuration (required by both web-api-target and vault capabilities)
supported_evm_chains = [1337, 2337]

env_vars = { CL_EVM_CMD = "" }
capabilities = ["web-api-target","vault"]

[nodesets.chain_capabilities]
write-evm = ["2337"]
read-contract = ["2337"]
evm = ["1337"]
evm = ["2337"]

[nodesets.db]
image = "postgres:12.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
[nodesets.chain_capabilities]
write-evm = ["1337", "2337"]
read-contract = ["1337", "2337"]
evm = ["1337"]
evm = ["1337", "2337"]

# See ./examples/workflow-don-overrides.toml to learn how to override capability configs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.25.5

require (
github.com/ethereum/go-ethereum v1.16.2
github.com/smartcontractkit/chain-selectors v1.0.67
github.com/smartcontractkit/chainlink-common v0.9.6-0.20251028192540-2ac3c24aa883
github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251022073203-7d8ae8cf67c1
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20251021010742-3f8d3dba17d8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,6 @@ github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKl
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/smartcontractkit/chain-selectors v1.0.67 h1:gxTqP/JC40KDe3DE1SIsIKSTKTZEPyEU1YufO1admnw=
github.com/smartcontractkit/chain-selectors v1.0.67/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8=
github.com/smartcontractkit/chainlink-common v0.9.6-0.20251028192540-2ac3c24aa883 h1:MbuTvXfQtde3qsynoMSC9tP8fRpqUoaAfZtT0mpXVgg=
github.com/smartcontractkit/chainlink-common v0.9.6-0.20251028192540-2ac3c24aa883/go.mod h1:al5VNrscTtWnxJaYJN6E3jixY17CvazC4VA6rOpLEHI=
github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251022073203-7d8ae8cf67c1 h1:NTODgwAil7BLoijS7y6KnEuNbQ9v60VUhIR9FcAzIhg=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"

chain_selectors "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-protos/cre/go/values"

"github.com/smartcontractkit/cre-sdk-go/capabilities/blockchain/evm"
Expand All @@ -43,7 +41,7 @@ func onTrigger(config types.WorkflowConfig, runtime cre.Runtime, payload *cron.P
runtime.Logger().Info("PoR workflow started", "payload", payload)

// get balance with BalanceAt()
evmClient := evm.Client{ChainSelector: chain_selectors.GETH_TESTNET.Selector}
evmClient := evm.Client{ChainSelector: config.ChainSelector}
runtime.Logger().Info("Got EVM client", "chainSelector", evmClient.ChainSelector)
addressesToRead := config.BalanceReaderConfig.AddressesToRead
runtime.Logger().Info("Got addresses to read", "addresses", addressesToRead)
Expand Down
187 changes: 9 additions & 178 deletions system-tests/lib/cre/features/evm/v2/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (o *EVM) PreEnvStartup(
if exist {
selectorsToDeploy := make([]uint64, 0)
for _, selector := range evmForwardersSelectors {
// filter out EVM forwarder selectors that might have been already deployed by evm_v2 capability
// filter out EVM forwarder selectors that might have been already deployed by evm_v1 capability
forwarderAddr := contracts.MightGetAddressFromDataStore(creEnv.CldfEnvironment.DataStore, selector, keystone_changeset.KeystoneForwarder.String(), creEnv.ContractVersions[keystone_changeset.KeystoneForwarder.String()], "")
if forwarderAddr == nil {
selectorsToDeploy = append(selectorsToDeploy, selector)
Expand Down Expand Up @@ -181,7 +181,7 @@ func (o *EVM) PostEnvStartup(
chainsWithEVMCapability := chainsWithEVMCapability(creEnv.Blockchains, dons.DonsWithFlag(flag))
for chainID, selector := range chainsWithEVMCapability {
qualifier := ks_contracts_op.CapabilityContractIdentifier(uint64(chainID))
_, _, seqErr := contracts.DeployOCR3Contract(testLogger, qualifier, creEnv.RegistryChainSelector, creEnv.CldfEnvironment, creEnv.ContractVersions)
_, _, seqErr := contracts.DeployOCR3Contract(testLogger, qualifier, uint64(selector), creEnv.CldfEnvironment, creEnv.ContractVersions)
if seqErr != nil {
return fmt.Errorf("failed to deploy EVM OCR3 contract for chainID %d, selector %d: %w", chainID, selector, seqErr)
}
Expand All @@ -200,11 +200,9 @@ func (o *EVM) PostEnvStartup(
// TODO should we make sure that log poller is listening before we try to configure contracts?

// configure OCR3 contracts
for chainID := range chainsWithEVMCapability {
for chainID, selector := range chainsWithEVMCapability {
qualifier := ks_contracts_op.CapabilityContractIdentifier(uint64(chainID))
// we have deployed OCR3 contract for each EVM chain on the registry chain to avoid a situation when more than 1 OCR contract (of any type) has the same address
// because in past that violeted a DB constraint for offchain reporting jobs. Now there is no such limitation, but still it's better to have unique addresses to avoid confusion.
evmOCR3Addr := contracts.MustGetAddressFromDataStore(creEnv.CldfEnvironment.DataStore, creEnv.RegistryChainSelector, keystone_changeset.OCR3Capability.String(), semver.MustParse("1.0.0"), qualifier)
evmOCR3Addr := contracts.MustGetAddressFromDataStore(creEnv.CldfEnvironment.DataStore, uint64(selector), keystone_changeset.OCR3Capability.String(), semver.MustParse("1.0.0"), qualifier)
var evmDON *cre.Don
for _, don := range dons.DonsWithFlag(cre.EVMCapability) {
if flags.HasFlagForChain(don.Flags, cre.EVMCapability, uint64(chainID)) {
Expand All @@ -222,9 +220,9 @@ func (o *EVM) PostEnvStartup(
return fmt.Errorf("failed to get default OCR3 config: %w", ocr3confErr)
}

chain, ok := creEnv.CldfEnvironment.BlockChains.EVMChains()[creEnv.RegistryChainSelector]
chain, ok := creEnv.CldfEnvironment.BlockChains.EVMChains()[uint64(selector)]
if !ok {
return fmt.Errorf("chain with selector %d not found in environment", creEnv.RegistryChainSelector)
return fmt.Errorf("chain with selector %d not found in environment", selector)
}

strategy, err := strategies.CreateStrategy(
Expand All @@ -248,7 +246,7 @@ func (o *EVM) PostEnvStartup(
},
ks_contracts_op.ConfigureOCR3OpInput{
ContractAddress: ptr.Ptr(common.HexToAddress(evmOCR3Addr)),
ChainSelector: creEnv.RegistryChainSelector,
ChainSelector: uint64(selector),
DON: evmDON.KeystoneDONConfig(),
Config: evmDON.ResolveORC3Config(ocr3Config),
DryRun: false,
Expand Down Expand Up @@ -350,17 +348,14 @@ func createJobs(
qualifier := ks_contracts_op.CapabilityContractIdentifier(chainID)

ocr3Key := datastore.NewAddressRefKey(
// we have deployed OCR3 contract for each EVM chain on the registry chain to avoid a situation when more than 1 OCR contract (of any type) has the same address
// because that violates a DB constraint for offchain reporting jobs
// this can be removed once https://smartcontract-it.atlassian.net/browse/PRODCRE-804 is done and we can deploy OCR3 contract for each EVM chain on that chain
creEnv.RegistryChainSelector,
chainSelector,
datastore.ContractType(keystone_changeset.OCR3Capability.String()),
semver.MustParse("1.0.0"),
qualifier,
)
ocr3ConfigContractAddress, err := creEnv.CldfEnvironment.DataStore.Addresses().Get(ocr3Key)
if err != nil {
return errors.Wrapf(err, "failed contract address for key %s and chainID %d", ocr3Key, chainID)
return errors.Wrapf(err, "failed to get contract address for key %s and chainID %d", ocr3Key, chainID)
}

bootInput := cre_jobs.ProposeJobSpecInput{
Expand Down Expand Up @@ -518,170 +513,6 @@ func createJobs(
return nil
}

// func createJobs(
// ctx context.Context,
// don *cre.Don,
// dons *cre.Dons,
// creEnv *cre.Environment,
// ) error {
// jobSpecs := []*jobv1.ProposeJobRequest{}

// capabilityConfig, ok := creEnv.CapabilityConfigs[flag]
// if !ok {
// return fmt.Errorf("%s config not found in capabilities config: %v", flag, creEnv.CapabilityConfigs)
// }

// bootstrapNode, isBootstrap := dons.Bootstrap()
// if !isBootstrap {
// return errors.New("could not find bootstrap node in topology, exactly one bootstrap node is required")
// }

// workerNodes, wErr := don.Workers()
// if wErr != nil {
// return errors.Wrap(wErr, "failed to find worker nodes")
// }

// var nodeSet cre.NodeSetWithCapabilityConfigs
// for _, ns := range dons.AsNodeSetWithChainCapabilities() {
// if ns.GetName() == don.Name {
// nodeSet = ns
// break
// }
// }
// if nodeSet == nil {
// return fmt.Errorf("could not find node set for Don named '%s'", don.Name)
// }

// command, cErr := standardcapability.GetCommand(capabilityConfig.BinaryPath, creEnv.Provider)
// if cErr != nil {
// return errors.Wrap(cErr, "failed to get command for cron capability")
// }

// chainConfig, ok := nodeSet.GetChainCapabilityConfigs()[flag]
// if !ok {
// return fmt.Errorf("could not find capability config for capability %s in node set %s", flag, nodeSet.GetName())
// }

// for _, chainID := range chainConfig.EnabledChains {
// chainIDStr := strconv.FormatUint(chainID, 10)
// chain, ok := chainselectors.ChainByEvmChainID(chainID)
// if !ok {
// return fmt.Errorf("failed to get chain selector for chain ID %d", chainID)
// }

// _, templateData, rErr := envconfig.ResolveCapabilityForChain(flag, nodeSet.GetChainCapabilityConfigs(), capabilityConfig.Config, chainID)
// if rErr != nil {
// return errors.Wrap(rErr, "failed to resolve capability config for chain")
// }

// ocr3Key := datastore.NewAddressRefKey(
// // we have deployed OCR3 contract for each EVM chain on the registry chain to avoid a situation when more than 1 OCR contract (of any type) has the same address
// // because that violates a DB constraint for offchain reporting jobs
// // this can be removed once https://smartcontract-it.atlassian.net/browse/PRODCRE-804 is done and we can deploy OCR3 contract for each EVM chain on that chain
// creEnv.RegistryChainSelector,
// datastore.ContractType(keystone_changeset.OCR3Capability.String()),
// semver.MustParse("1.0.0"),
// ks_contracts_op.CapabilityContractIdentifier(chainID),
// )
// ocr3ConfigContractAddress, err := creEnv.CldfEnvironment.DataStore.Addresses().Get(ocr3Key)
// if err != nil {
// return errors.Wrapf(err, "failed contract address for key %s and chainID %d", ocr3Key, chainID)
// }

// jobSpecs = append(jobSpecs, ocr.BootstrapJobSpec(bootstrapNode.JobDistributorDetails.NodeID, flag, ocr3ConfigContractAddress.Address, chainID))

// for _, workerNode := range workerNodes {
// evmKey, ok := workerNode.Keys.EVM[chainID]
// if !ok {
// return fmt.Errorf("failed to get EVM key (chainID %d, node index %d)", chainID, workerNode.Index)
// }
// nodeAddress := evmKey.PublicAddress.Hex()

// evmKeyBundle, ok := workerNode.Keys.OCR2BundleIDs[chainselectors.FamilyEVM] // we can always expect evm bundle key id present since evm is the registry chain
// if !ok {
// return errors.New("failed to get key bundle id for evm family")
// }

// bootstrapPeers := []string{fmt.Sprintf("%s@%s:%d", strings.TrimPrefix(bootstrapNode.Keys.PeerID(), "p2p_"), bootstrapNode.Host, cre.OCRPeeringPort)}

// strategyName := "single-chain"
// if len(workerNode.Keys.OCR2BundleIDs) > 1 {
// strategyName = "multi-chain"
// }

// oracleFactoryConfigInstance := job.OracleFactoryConfig{
// Enabled: true,
// ChainID: chainIDStr,
// BootstrapPeers: bootstrapPeers,
// OCRContractAddress: ocr3ConfigContractAddress.Address,
// OCRKeyBundleID: evmKeyBundle,
// TransmitterID: nodeAddress,
// OnchainSigning: job.OnchainSigningStrategy{
// StrategyName: strategyName,
// Config: workerNode.Keys.OCR2BundleIDs,
// },
// }

// type OracleFactoryConfigWrapper struct {
// OracleFactory job.OracleFactoryConfig `toml:"oracle_factory"`
// }
// wrapper := OracleFactoryConfigWrapper{OracleFactory: oracleFactoryConfigInstance}

// var oracleBuffer bytes.Buffer
// if errEncoder := toml.NewEncoder(&oracleBuffer).Encode(wrapper); errEncoder != nil {
// return errors.Wrap(errEncoder, "failed to encode oracle factory config to TOML")
// }
// oracleStr := strings.ReplaceAll(oracleBuffer.String(), "\n", "\n\t")

// creForwarderKey := datastore.NewAddressRefKey(
// chain.Selector,
// datastore.ContractType(keystone_changeset.KeystoneForwarder.String()),
// semver.MustParse("1.0.0"),
// "",
// )
// creForwarderAddress, err := creEnv.CldfEnvironment.DataStore.Addresses().Get(creForwarderKey)
// if err != nil {
// return errors.Wrap(err, "failed to get CRE Forwarder address")
// }

// runtimeFallbacks := buildRuntimeValues(chainID, "evm", creForwarderAddress.Address, nodeAddress)
// var aErr error
// templateData, aErr = credon.ApplyRuntimeValues(templateData, runtimeFallbacks)
// if aErr != nil {
// return errors.Wrap(aErr, "failed to apply runtime values")
// }

// tmpl, err := template.New("evmConfig").Parse(configTemplate)
// if err != nil {
// return errors.Wrapf(err, "failed to parse %s config template", flag)
// }

// var configBuffer bytes.Buffer
// if err := tmpl.Execute(&configBuffer, templateData); err != nil {
// return errors.Wrapf(err, "failed to execute %s config template", flag)
// }

// configStr := configBuffer.String()

// if err := credon.ValidateTemplateSubstitution(configStr, flag); err != nil {
// return errors.Wrapf(err, "%s template validation failed", flag)
// }

// jobSpec := standardcapability.WorkerJobSpec(workerNode.JobDistributorDetails.NodeID, fmt.Sprintf("%s-%d", flag, chainID), command, configStr, oracleStr)
// jobSpec.Labels = []*ptypes.Label{{Key: cre.CapabilityLabelKey, Value: ptr.Ptr(flag)}}
// jobSpecs = append(jobSpecs, jobSpec)
// }
// }

// jobErr := jobs.Create(ctx, creEnv.CldfEnvironment.Offchain, dons, jobSpecs)

// if jobErr != nil {
// return fmt.Errorf("failed to create EVM OCR3 jobs for don %s: %w", don.Name, jobErr)
// }

// return nil
// }

// buildRuntimeValues creates runtime-generated values for any keys not specified in TOML
func buildRuntimeValues(chainID uint64, networkFamily, creForwarderAddress, nodeAddress string) map[string]any {
return map[string]any{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"strings"
"testing"

"github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment/blockchains"
t_helpers "github.com/smartcontractkit/chainlink/system-tests/tests/test-helpers"

"github.com/smartcontractkit/chainlink-testing-framework/framework"
Expand Down Expand Up @@ -68,8 +67,6 @@ func runEVMNegativeTestSuite(t *testing.T, testCases []evmNegativeTest) {
testName := fmt.Sprintf(evmTestNameTemplate, tCase.functionToTest, tCase.name)
t.Run(testName, func(t *testing.T) {
testEnv := t_helpers.SetupTestEnvironmentWithConfig(t, t_helpers.GetDefaultTestConfig(t), v2RegistriesFlags...)
// TODO remove this when OCR works properly with multiple chains in Local CRE
testEnv.CreEnvironment.Blockchains = []blockchains.Blockchain{testEnv.CreEnvironment.Blockchains[0]}

// Check if test name contains "write" to determine which test function to run
if strings.Contains(strings.ToLower(testName), "writereport") {
Expand Down Expand Up @@ -140,9 +137,6 @@ func Test_CRE_V2_HTTP_Action_CRUD_Regression(t *testing.T) {
testName := "[v2] HTTP Action fails with " + tCase.name
t.Run(testName, func(t *testing.T) {
testEnv := t_helpers.SetupTestEnvironmentWithConfig(t, t_helpers.GetDefaultTestConfig(t), v2RegistriesFlags...)
// TODO remove this when OCR works properly with multiple chains in Local CRE
testEnv.CreEnvironment.Blockchains = []blockchains.Blockchain{testEnv.CreEnvironment.Blockchains[0]}

HTTPActionFailureTest(t, testEnv, tCase)
})
}
Expand Down
Loading
Loading