Skip to content

Commit

Permalink
evm exaction: use agnostic keystore
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Mar 11, 2025
1 parent fd635e9 commit 58ba638
Show file tree
Hide file tree
Showing 135 changed files with 1,898 additions and 2,426 deletions.
136 changes: 37 additions & 99 deletions common/txmgr/types/mocks/key_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 8 additions & 11 deletions core/capabilities/ccip/ocrimpls/contract_transmitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import (
"github.com/smartcontractkit/chainlink-integrations/evm/config/toml"
"github.com/smartcontractkit/chainlink-integrations/evm/gas"
"github.com/smartcontractkit/chainlink-integrations/evm/heads"
"github.com/smartcontractkit/chainlink-integrations/evm/keystore"
"github.com/smartcontractkit/chainlink-integrations/evm/keys"
"github.com/smartcontractkit/chainlink-integrations/evm/keys/keystest"
"github.com/smartcontractkit/chainlink-integrations/evm/logpoller"
evmtestutils "github.com/smartcontractkit/chainlink-integrations/evm/testutils"
evmtypes "github.com/smartcontractkit/chainlink-integrations/evm/types"
Expand All @@ -40,7 +41,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/v1_6_0/multi_ocr3_helper"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
Expand Down Expand Up @@ -207,14 +207,15 @@ func newTestUniverse(t *testing.T, ks *keyringsAndSigners[[]byte]) *testUniverse
db := pgtest.NewSqlxDB(t)
owner := evmtestutils.MustNewSimTransactor(t)

keyStore := keystest.NewMemoryChainStore()
// create many transmitters but only need to fund one, rest are to get
// setOCR3Config to pass.
keyStore := cltest.NewKeyStore(t, db)
chainStore := keys.NewChainStore(keyStore, big.NewInt(1337))
var transmitters []common.Address
for i := 0; i < 4; i++ {
key, err := keyStore.Eth().Create(testutils.Context(t), big.NewInt(1337))
addr, err := keyStore.Create()
require.NoError(t, err, "failed to create key")
transmitters = append(transmitters, key.Address)
transmitters = append(transmitters, addr)
}

backend := simulated.NewBackend(types.GenesisAlloc{
Expand Down Expand Up @@ -297,7 +298,7 @@ func newTestUniverse(t *testing.T, ks *keyringsAndSigners[[]byte]) *testUniverse
simClient := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID)

// create the chain writer service
txm, gasEstimator := makeTestEvmTxm(t, db, simClient, keyStore.Eth())
txm, gasEstimator := makeTestEvmTxm(t, db, simClient, chainStore)
require.NoError(t, txm.Start(testutils.Context(t)), "failed to start tx manager")
t.Cleanup(func() { require.NoError(t, txm.Close()) })

Expand Down Expand Up @@ -408,11 +409,7 @@ func chainWriterConfigRaw(fromAddress common.Address, maxGasPrice *assets.Wei) e
}
}

func makeTestEvmTxm(
t *testing.T,
db *sqlx.DB,
ethClient client.Client,
keyStore keystore.Eth) (txmgr.TxManager, gas.EvmFeeEstimator) {
func makeTestEvmTxm(t *testing.T, db *sqlx.DB, ethClient client.Client, keyStore keys.ChainStore) (txmgr.TxManager, gas.EvmFeeEstimator) {
config, dbConfig, evmConfig := MakeTestConfigs(t)

estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config.ChainType(), ethClient.ConfiguredChainID(), evmConfig.GasEstimator(), nil)
Expand Down
42 changes: 17 additions & 25 deletions core/capabilities/gateway_connector/service_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@ package gatewayconnector

import (
"context"
"crypto/ecdsa"
"errors"
"math/big"
"slices"

"github.com/ethereum/go-ethereum/common"
"github.com/jonboulle/clockwork"

"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-integrations/evm/keys"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
gwcommon "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/network"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
)

type Keystore interface {
keys.AddressChecker
keys.MessageSigner
}

type ServiceWrapper struct {
services.StateMachine
stopCh services.StopChan

config config.GatewayConnector
keystore keystore.Eth
keystore Keystore
connector connector.GatewayConnector
signerKey *ecdsa.PrivateKey
lggr logger.Logger
clock clockwork.Clock
}
Expand All @@ -50,8 +50,9 @@ func translateConfigs(f config.GatewayConnector) connector.ConnectorConfig {
}

// NOTE: this wrapper is needed to make sure that our services are started after Keystore.
func NewGatewayConnectorServiceWrapper(config config.GatewayConnector, keystore keystore.Eth, clock clockwork.Clock, lggr logger.Logger) *ServiceWrapper {
func NewGatewayConnectorServiceWrapper(config config.GatewayConnector, keystore Keystore, clock clockwork.Clock, lggr logger.Logger) *ServiceWrapper {
return &ServiceWrapper{
stopCh: make(services.StopChan),
config: config,
keystore: keystore,
clock: clock,
Expand All @@ -63,24 +64,11 @@ func (e *ServiceWrapper) Start(ctx context.Context) error {
return e.StartOnce("GatewayConnectorServiceWrapper", func() error {
conf := e.config
nodeAddress := conf.NodeAddress()
chainID, _ := new(big.Int).SetString(conf.ChainIDForNodeKey(), 0)
enabledKeys, err := e.keystore.EnabledKeysForChain(ctx, chainID)
configuredNodeAddress := common.HexToAddress(nodeAddress)
err := e.keystore.CheckEnabled(ctx, configuredNodeAddress)
if err != nil {
return err
}
if len(enabledKeys) == 0 {
return errors.New("no available keys found")
}
configuredNodeAddress := common.HexToAddress(nodeAddress)
idx := slices.IndexFunc(enabledKeys, func(key ethkey.KeyV2) bool { return key.Address == configuredNodeAddress })

if idx == -1 {
return errors.New("key for configured node address not found")
}
e.signerKey = enabledKeys[idx].ToEcdsaPrivKey()
if enabledKeys[idx].ID() != nodeAddress {
return errors.New("node address mismatch")
}

translated := translateConfigs(conf)
e.connector, err = connector.NewGatewayConnector(&translated, e, e.clock, e.lggr)
Expand All @@ -92,11 +80,15 @@ func (e *ServiceWrapper) Start(ctx context.Context) error {
}

func (e *ServiceWrapper) Sign(data ...[]byte) ([]byte, error) {
return gwcommon.SignData(e.signerKey, data...)
ctx, cancel := e.stopCh.NewCtx()
defer cancel()
account := common.HexToAddress(e.config.NodeAddress())
return e.keystore.SignMessage(ctx, account, gwcommon.Flatten(data...))
}

func (e *ServiceWrapper) Close() error {
return e.StopOnce("GatewayConnectorServiceWrapper", func() (err error) {
close(e.stopCh)
return e.connector.Close()
})
}
Expand Down
Loading

0 comments on commit 58ba638

Please sign in to comment.