Skip to content
Closed
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
86 changes: 13 additions & 73 deletions cmd/workflow/simulate/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ package simulate

import (
"context"
"crypto/ecdsa"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"

chaintype "github.com/smartcontractkit/chainlink-common/keystore/corekeys"
"github.com/smartcontractkit/chainlink-common/keystore/corekeys/ocr2key"
confhttpserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/actions/confidentialhttp/server"
httpserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/actions/http/server"
evmserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/evm/server"
consensusserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/consensus/server"
crontrigger "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/cron/server"
httptrigger "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/http/server"
Expand All @@ -21,121 +18,64 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/capabilities/fakes"
)

type ManualTriggerCapabilitiesConfig struct {
Clients map[uint64]*ethclient.Client
Forwarders map[uint64]common.Address
PrivateKey *ecdsa.PrivateKey
}

// ManualTriggers holds chain-agnostic trigger services used in simulation.
type ManualTriggers struct {
ManualCronTrigger *fakes.ManualCronTriggerService
ManualHTTPTrigger *fakes.ManualHTTPTriggerService
ManualEVMChains map[uint64]*fakes.FakeEVMChain
}

func NewManualTriggerCapabilities(
ctx context.Context,
lggr logger.Logger,
registry *capabilities.Registry,
cfg ManualTriggerCapabilitiesConfig,
dryRunChainWrite bool,
limits *SimulationLimits,
) (*ManualTriggers, error) {
// Cron
// NewManualTriggers creates and registers cron and HTTP trigger capabilities.
// These are chain-agnostic and shared across all chain families.
func NewManualTriggers(ctx context.Context, lggr logger.Logger, registry *capabilities.Registry) (*ManualTriggers, error) {
manualCronTrigger := fakes.NewManualCronTriggerService(lggr)
manualCronTriggerServer := crontrigger.NewCronServer(manualCronTrigger)
if err := registry.Add(ctx, manualCronTriggerServer); err != nil {
return nil, err
}

// HTTP
manualHTTPTrigger := fakes.NewManualHTTPTriggerService(lggr)
manualHTTPTriggerServer := httptrigger.NewHTTPServer(manualHTTPTrigger)
if err := registry.Add(ctx, manualHTTPTriggerServer); err != nil {
return nil, err
}

// EVM
evmChains := make(map[uint64]*fakes.FakeEVMChain)
for sel, client := range cfg.Clients {
fwd, ok := cfg.Forwarders[sel]
if !ok {
lggr.Infow("Forwarder not found for chain", "selector", sel)
continue
}

evm := fakes.NewFakeEvmChain(
lggr,
client,
cfg.PrivateKey,
fwd,
sel,
dryRunChainWrite,
)

// Wrap with limits enforcement if limits are enabled
var evmCap evmserver.ClientCapability = evm
if limits != nil {
evmCap = NewLimitedEVMChain(evm, limits)
}

evmServer := evmserver.NewClientServer(evmCap)
if err := registry.Add(ctx, evmServer); err != nil {
return nil, err
}

evmChains[sel] = evm
}

return &ManualTriggers{
ManualCronTrigger: manualCronTrigger,
ManualHTTPTrigger: manualHTTPTrigger,
ManualEVMChains: evmChains,
}, nil
}

func (m *ManualTriggers) Start(ctx context.Context) error {
err := m.ManualCronTrigger.Start(ctx)
// Start starts cron and HTTP trigger services.
func (t *ManualTriggers) Start(ctx context.Context) error {
err := t.ManualCronTrigger.Start(ctx)
if err != nil {
return err
}

err = m.ManualHTTPTrigger.Start(ctx)
err = t.ManualHTTPTrigger.Start(ctx)
if err != nil {
return err
}

// Start all configured EVM chains
for _, evm := range m.ManualEVMChains {
if err := evm.Start(ctx); err != nil {
return err
}
}

return nil
}

func (m *ManualTriggers) Close() error {
err := m.ManualCronTrigger.Close()
// Close closes cron and HTTP trigger services.
func (t *ManualTriggers) Close() error {
err := t.ManualCronTrigger.Close()
if err != nil {
return err
}

err = m.ManualHTTPTrigger.Close()
err = t.ManualHTTPTrigger.Close()
if err != nil {
return err
}

// Close all EVM chains
for _, evm := range m.ManualEVMChains {
if err := evm.Close(); err != nil {
return err
}
}
return nil
}

// NewFakeCapabilities builds faked capabilities, then registers them with the capability registry.
// NewFakeActionCapabilities builds faked capabilities, then registers them with the capability registry.
func NewFakeActionCapabilities(ctx context.Context, lggr logger.Logger, registry *capabilities.Registry, secretsPath string, limits *SimulationLimits) ([]services.Service, error) {
caps := make([]services.Service, 0)

Expand Down
88 changes: 88 additions & 0 deletions cmd/workflow/simulate/chain/evm/capabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package evm

import (
"context"
"crypto/ecdsa"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"

evmserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/evm/server"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/v2/core/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/fakes"
)

// EVMChainCapabilities holds the EVM chain capability servers created for simulation.
type EVMChainCapabilities struct {
EVMChains map[uint64]*fakes.FakeEVMChain
}

// NewEVMChainCapabilities creates EVM chain capability servers and registers them
// with the capability registry. Cron and HTTP triggers are not created here — they
// are chain-agnostic and managed by the simulate command directly.
func NewEVMChainCapabilities(
ctx context.Context,
lggr logger.Logger,
registry *capabilities.Registry,
clients map[uint64]*ethclient.Client,
forwarders map[uint64]common.Address,
privateKey *ecdsa.PrivateKey,
dryRunChainWrite bool,
limits EVMChainLimits,
) (*EVMChainCapabilities, error) {
evmChains := make(map[uint64]*fakes.FakeEVMChain)
for sel, client := range clients {
fwd, ok := forwarders[sel]
if !ok {
lggr.Infow("Forwarder not found for chain", "selector", sel)
continue
}

evm := fakes.NewFakeEvmChain(
lggr,
client,
privateKey,
fwd,
sel,
dryRunChainWrite,
)

// Wrap with limits enforcement if limits are provided
var evmCap evmserver.ClientCapability = evm
if limits != nil {
evmCap = NewLimitedEVMChain(evm, limits)
}

evmServer := evmserver.NewClientServer(evmCap)
if err := registry.Add(ctx, evmServer); err != nil {
return nil, err
}

evmChains[sel] = evm
}

return &EVMChainCapabilities{
EVMChains: evmChains,
}, nil
}

// Start starts all configured EVM chains.
func (c *EVMChainCapabilities) Start(ctx context.Context) error {
for _, evm := range c.EVMChains {
if err := evm.Start(ctx); err != nil {
return err
}
}
return nil
}

// Close closes all EVM chains.
func (c *EVMChainCapabilities) Close() error {
for _, evm := range c.EVMChains {
if err := evm.Close(); err != nil {
return err
}
}
return nil
}
Loading
Loading