diff --git a/integration-tests/common/client.go b/integration-tests/common/client.go index 9b9df99bf..8318fbeca 100644 --- a/integration-tests/common/client.go +++ b/integration-tests/common/client.go @@ -1,14 +1,20 @@ package common import ( + "crypto/sha256" + "encoding/hex" "errors" "fmt" "regexp" "strings" + "github.com/cometbft/cometbft/crypto" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/types/bech32" "github.com/google/uuid" "github.com/lib/pq" "github.com/rs/zerolog/log" + "golang.org/x/crypto/ripemd160" //nolint: staticcheck "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-env/environment" @@ -18,6 +24,7 @@ import ( ) type ChainlinkClient struct { + bech32Prefix string ChainlinkNodes []*client.ChainlinkClient NodeKeys []client.NodeKeysBundle bTypeAttr *client.BridgeTypeAttributes @@ -26,7 +33,7 @@ type ChainlinkClient struct { // TODO: Remove env. See https://github.com/smartcontractkit/chainlink-cosmos/pull/350#discussion_r1298071289 // CreateKeys Creates node keys and defines chain and nodes for each node -func NewChainlinkClient(env *environment.Environment, nodeName string, chainId string, tendermintURL string) (*ChainlinkClient, error) { +func NewChainlinkClient(env *environment.Environment, nodeName string, chainId string, tendermintURL string, bech32Prefix string) (*ChainlinkClient, error) { nodes, err := connectChainlinkNodes(env) if err != nil { return nil, err @@ -45,6 +52,7 @@ func NewChainlinkClient(env *environment.Environment, nodeName string, chainId s } return &ChainlinkClient{ + bech32Prefix: bech32Prefix, ChainlinkNodes: nodes, NodeKeys: nodeKeys, }, nil @@ -53,30 +61,50 @@ func NewChainlinkClient(env *environment.Environment, nodeName string, chainId s func (cc *ChainlinkClient) GetNodeAddresses() []string { var addresses []string for _, nodeKey := range cc.NodeKeys { - addresses = append(addresses, nodeKey.TXKey.Data.Attributes.PublicKey) + addresses = append(addresses, mustConvertToBech32(nodeKey.TXKey.Data.Attributes.PublicKey, cc.bech32Prefix)) } return addresses } +func mustConvertToBech32(pubKey, accountPrefix string) string { + pubKeyBytes, err := hex.DecodeString(pubKey) + if err != nil { + panic(err) + } + + if len(pubKeyBytes) != secp256k1.PubKeySize { + panic("length of pubkey is incorrect") + } + + sha := sha256.Sum256(pubKeyBytes) + hasherRIPEMD160 := ripemd160.New() + hasherRIPEMD160.Write(sha[:]) // does not error + address := crypto.Address(hasherRIPEMD160.Sum(nil)) + + bech32Addr, err := bech32.ConvertAndEncode(accountPrefix, address) + if err != nil { + panic(err) + } + return bech32Addr +} + func (cc *ChainlinkClient) LoadOCR2Config(proposalId string) (*OCR2Config, error) { var offChainKeys []string var onChainKeys []string var peerIds []string - var txKeys []string var cfgKeys []string for _, key := range cc.NodeKeys { offChainKeys = append(offChainKeys, key.OCR2Key.Data.Attributes.OffChainPublicKey) peerIds = append(peerIds, key.PeerID) - txKeys = append(txKeys, key.TXKey.Data.ID) - // txKeys = append(txKeys, key.TXKey.Data.ID) onChainKeys = append(onChainKeys, key.OCR2Key.Data.Attributes.OnChainPublicKey) cfgKeys = append(cfgKeys, key.OCR2Key.Data.Attributes.ConfigPublicKey) } var payload = TestOCR2Config payload.ProposalId = proposalId payload.Signers = onChainKeys - payload.Transmitters = txKeys - payload.Payees = txKeys // Set payees to same addresses as transmitters + addresses := cc.GetNodeAddresses() + payload.Transmitters = addresses + payload.Payees = addresses // Set payees to same addresses as transmitters payload.OffchainConfig.OffchainPublicKeys = offChainKeys payload.OffchainConfig.PeerIds = peerIds payload.OffchainConfig.ConfigPublicKeys = cfgKeys @@ -144,13 +172,14 @@ func (cc *ChainlinkClient) CreateJobsForContract(chainId, nodeName, p2pPort, moc "chainID": bootstrapRelayConfig["chainID"], } + transmitterAddress := mustConvertToBech32(cc.NodeKeys[nIdx].TXKey.Data.Attributes.PublicKey, cc.bech32Prefix) oracleSpec = job.OCR2OracleSpec{ ContractID: ocrControllerAddress, Relay: relay.Cosmos, RelayConfig: relayConfig, PluginType: "median", OCRKeyBundleID: null.StringFrom(cc.NodeKeys[nIdx].OCR2Key.Data.ID), - TransmitterID: null.StringFrom(cc.NodeKeys[nIdx].TXKey.Data.ID), + TransmitterID: null.StringFrom(transmitterAddress), P2PV2Bootstrappers: pq.StringArray{strings.Join(p2pBootstrappers, ",")}, ContractConfigConfirmations: 1, // don't wait for confirmation on devnet PluginConfig: job.JSONConfig{ diff --git a/integration-tests/ocr2_test.go b/integration-tests/ocr2_test.go index aeede707b..062694ab3 100644 --- a/integration-tests/ocr2_test.go +++ b/integration-tests/ocr2_test.go @@ -36,8 +36,9 @@ func TestOCRBasic(t *testing.T) { commonConfig := common.NewCommon(t) commonConfig.SetLocalEnvironment(t) + bech32Prefix := "wasm" params.InitCosmosSdk( - /* bech32Prefix= */ "wasm", + bech32Prefix, /* token= */ "cosm", ) clientLogger, err := relaylogger.New() @@ -50,7 +51,7 @@ func TestOCRBasic(t *testing.T) { require.NoError(t, err, "Could not create cosmos client") nodeName := "primary" - chainlinkClient, err := common.NewChainlinkClient(commonConfig.Env, commonConfig.ChainId, nodeName, commonConfig.NodeUrl) + chainlinkClient, err := common.NewChainlinkClient(commonConfig.Env, commonConfig.ChainId, nodeName, commonConfig.NodeUrl, bech32Prefix) require.NoError(t, err, "Could not create chainlink client") logger.Info().Str("node addresses", strings.Join(chainlinkClient.GetNodeAddresses(), " ")).Msg("Created chainlink client")