From 879670c0e5c74a15cff5e48ae8285a7eb5ecd27b Mon Sep 17 00:00:00 2001 From: bruce-riley <96066700+bruce-riley@users.noreply.github.com> Date: Mon, 4 Apr 2022 17:11:03 -0500 Subject: [PATCH] Klaytn testnet support (#1038) * Klaytn support for testnet Change-Id: Id0647fd6c603ab298f860c2cae20481555467315 * token_bridge client changes Change-Id: If49ba994a67041044bdec054f19e69b4cfc2785b * Get rid of special handling * More cleanup * Need to add Klaytn to structs tests * Update SDK version * Add SDK version * fix klaytn bridge chain id Co-authored-by: Evan Gray --- clients/token_bridge/main.ts | 2 +- devnet/node.yaml | 2 ++ ethereum/.env.klaytn.testnet | 14 ++++++++++++++ ethereum/package.json | 2 +- ethereum/truffle-config.js | 11 +++++++++++ node/cmd/guardiand/adminnodes.go | 1 + node/cmd/guardiand/node.go | 26 ++++++++++++++++++++++++++ node/pkg/common/readiness.go | 1 + node/pkg/vaa/structs.go | 6 ++++++ node/pkg/vaa/structs_test.go | 3 +++ proto/publicrpc/v1/publicrpc.proto | 1 + sdk/js/CHANGELOG.md | 6 ++++++ sdk/js/package.json | 2 +- sdk/js/src/utils/array.ts | 4 +++- sdk/js/src/utils/consts.ts | 3 ++- 15 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 ethereum/.env.klaytn.testnet diff --git a/clients/token_bridge/main.ts b/clients/token_bridge/main.ts index 38b7fc425..c0ff2edcc 100644 --- a/clients/token_bridge/main.ts +++ b/clients/token_bridge/main.ts @@ -311,7 +311,7 @@ yargs(hideBin(process.argv)) ); console.log('SIGNATURE', signature); }) - .command('eth execute_governance_vaa [vaa]', 'execute a governance VAA on Solana', (yargs) => { + .command('eth execute_governance_vaa [vaa]', 'execute a governance VAA on evm', (yargs) => { return yargs .positional('vaa', { describe: 'vaa to post', diff --git a/devnet/node.yaml b/devnet/node.yaml index d9dc8cc30..d42036374 100644 --- a/devnet/node.yaml +++ b/devnet/node.yaml @@ -85,6 +85,8 @@ spec: - ws://eth-devnet:8545 - --acalaRPC - ws://eth-devnet:8545 + - --klaytnRPC + - ws://eth-devnet:8545 - --terraWS - ws://terra-terrad:26657/websocket - --terraLCD diff --git a/ethereum/.env.klaytn.testnet b/ethereum/.env.klaytn.testnet new file mode 100644 index 000000000..a59e04f1d --- /dev/null +++ b/ethereum/.env.klaytn.testnet @@ -0,0 +1,14 @@ +# Klaytn (Baobab) testnet env +# Rename to .env to use with truffle migrations + +# Wormhole Core Migrations +INIT_SIGNERS=["0x13947Bd48b18E53fdAeEe77F3473391aC727C638"] +INIT_CHAIN_ID=0xd +INIT_GOV_CHAIN_ID=0x1 +INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 + +# Bridge Migrations +BRIDGE_INIT_CHAIN_ID=0xd +BRIDGE_INIT_GOV_CHAIN_ID=0x1 +BRIDGE_INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 +BRIDGE_INIT_WETH=0x762ac6e8183db5a8e912a66fcc1a09f5a7ac96a9 diff --git a/ethereum/package.json b/ethereum/package.json index 5105d715b..0551902f5 100644 --- a/ethereum/package.json +++ b/ethereum/package.json @@ -13,7 +13,7 @@ "@truffle/hdwallet-provider": "^1.7.0", "chai": "^4.2.0", "mocha": "^8.2.1", - "truffle": "^5.3.14", + "truffle": "5.3.14", "truffle-assertions": "^0.9.2", "truffle-plugin-verify": "^0.5.11" }, diff --git a/ethereum/truffle-config.js b/ethereum/truffle-config.js index eff09839b..1272a5d31 100644 --- a/ethereum/truffle-config.js +++ b/ethereum/truffle-config.js @@ -188,6 +188,17 @@ module.exports = { gasLimit: 213192000, gas: 213192000, }, + klaytn_testnet: { // Note that Klaytn works with version 5.3.14 of truffle, but not some of the newer versions. + provider: () => { + return new HDWalletProvider( + process.env.MNEMONIC, + "https://api.baobab.klaytn.net:8651/" + ); + }, + network_id: '1001', + gas: '8500000', + gasPrice: null + }, }, compilers: { diff --git a/node/cmd/guardiand/adminnodes.go b/node/cmd/guardiand/adminnodes.go index 626d310c5..7504ebbf3 100644 --- a/node/cmd/guardiand/adminnodes.go +++ b/node/cmd/guardiand/adminnodes.go @@ -110,6 +110,7 @@ func runListNodes(cmd *cobra.Command, args []string) { networks = append(networks, network{"Aurora", vaa.ChainIDAurora}) networks = append(networks, network{"Karura", vaa.ChainIDKarura}) networks = append(networks, network{"Acala", vaa.ChainIDAcala}) + networks = append(networks, network{"Klaytn", vaa.ChainIDKlaytn}) } if len(only) > 0 { diff --git a/node/cmd/guardiand/node.go b/node/cmd/guardiand/node.go index ba33e03cb..0511c7ba9 100644 --- a/node/cmd/guardiand/node.go +++ b/node/cmd/guardiand/node.go @@ -93,6 +93,9 @@ var ( acalaRPC *string acalaContract *string + klaytnRPC *string + klaytnContract *string + terraWS *string terraLCD *string terraContract *string @@ -179,6 +182,9 @@ func init() { acalaRPC = NodeCmd.Flags().String("acalaRPC", "", "Acala RPC URL") acalaContract = NodeCmd.Flags().String("acalaContract", "", "Acala contract address") + klaytnRPC = NodeCmd.Flags().String("klaytnRPC", "", "Klaytn RPC URL") + klaytnContract = NodeCmd.Flags().String("klaytnContract", "", "Klaytn contract address") + terraWS = NodeCmd.Flags().String("terraWS", "", "Path to terrad root for websocket connection") terraLCD = NodeCmd.Flags().String("terraLCD", "", "Path to LCD service root for http calls") terraContract = NodeCmd.Flags().String("terraContract", "", "Wormhole contract address on Terra blockchain") @@ -310,6 +316,7 @@ func runNode(cmd *cobra.Command, args []string) { readiness.RegisterComponent(common.ReadinessAuroraSyncing) readiness.RegisterComponent(common.ReadinessKaruraSyncing) readiness.RegisterComponent(common.ReadinessAcalaSyncing) + readiness.RegisterComponent(common.ReadinessKlaytnSyncing) } if *statusAddr != "" { @@ -357,6 +364,7 @@ func runNode(cmd *cobra.Command, args []string) { *fantomContract = devnet.GanacheWormholeContractAddress.Hex() *karuraContract = devnet.GanacheWormholeContractAddress.Hex() *acalaContract = devnet.GanacheWormholeContractAddress.Hex() + *klaytnContract = devnet.GanacheWormholeContractAddress.Hex() } // Verify flags @@ -428,6 +436,12 @@ func runNode(cmd *cobra.Command, args []string) { if *acalaContract == "" { logger.Fatal("Please specify --acalaContract") } + if *klaytnRPC == "" { + logger.Fatal("Please specify --klaytnRPC") + } + if *klaytnContract == "" { + logger.Fatal("Please specify --klaytnContract") + } } else { if *ethRopstenRPC != "" { logger.Fatal("Please do not specify --ethRopstenRPC in non-testnet mode") @@ -453,6 +467,12 @@ func runNode(cmd *cobra.Command, args []string) { if *acalaContract != "" && !*unsafeDevMode { logger.Fatal("Please do not specify --acalaContract") } + if *klaytnRPC != "" && !*unsafeDevMode { + logger.Fatal("Please do not specify --klaytnRPC") + } + if *klaytnContract != "" && !*unsafeDevMode { + logger.Fatal("Please do not specify --klaytnContract") + } } if *nodeName == "" { logger.Fatal("Please specify --nodeName") @@ -541,6 +561,7 @@ func runNode(cmd *cobra.Command, args []string) { fantomContractAddr := eth_common.HexToAddress(*fantomContract) karuraContractAddr := eth_common.HexToAddress(*karuraContract) acalaContractAddr := eth_common.HexToAddress(*acalaContract) + klaytnContractAddr := eth_common.HexToAddress(*klaytnContract) solAddress, err := solana_types.PublicKeyFromBase58(*solanaContract) if err != nil { logger.Fatal("invalid Solana contract address", zap.Error(err)) @@ -629,6 +650,7 @@ func runNode(cmd *cobra.Command, args []string) { chainObsvReqC[vaa.ChainIDAurora] = make(chan *gossipv1.ObservationRequest) chainObsvReqC[vaa.ChainIDKarura] = make(chan *gossipv1.ObservationRequest) chainObsvReqC[vaa.ChainIDAcala] = make(chan *gossipv1.ObservationRequest) + chainObsvReqC[vaa.ChainIDKlaytn] = make(chan *gossipv1.ObservationRequest) chainObsvReqC[vaa.ChainIDEthereumRopsten] = make(chan *gossipv1.ObservationRequest) } @@ -789,6 +811,10 @@ func runNode(cmd *cobra.Command, args []string) { ethereum.NewEthWatcher(*acalaRPC, acalaContractAddr, "acala", common.ReadinessAcalaSyncing, vaa.ChainIDAcala, lockC, nil, 1, chainObsvReqC[vaa.ChainIDAcala]).Run); err != nil { return err } + if err := supervisor.Run(ctx, "klaytnwatch", + ethereum.NewEthWatcher(*klaytnRPC, klaytnContractAddr, "klaytn", common.ReadinessKlaytnSyncing, vaa.ChainIDKlaytn, lockC, nil, 1, chainObsvReqC[vaa.ChainIDKlaytn]).Run); err != nil { + return err + } } // Start Terra watcher only if configured diff --git a/node/pkg/common/readiness.go b/node/pkg/common/readiness.go index e33a88880..ab0f09813 100644 --- a/node/pkg/common/readiness.go +++ b/node/pkg/common/readiness.go @@ -16,4 +16,5 @@ const ( ReadinessFantomSyncing readiness.Component = "fantomSyncing" ReadinessKaruraSyncing readiness.Component = "karuraSyncing" ReadinessAcalaSyncing readiness.Component = "acalaSyncing" + ReadinessKlaytnSyncing readiness.Component = "klaytnSyncing" ) diff --git a/node/pkg/vaa/structs.go b/node/pkg/vaa/structs.go index dacd843eb..38143e807 100644 --- a/node/pkg/vaa/structs.go +++ b/node/pkg/vaa/structs.go @@ -110,6 +110,8 @@ func (c ChainID) String() string { return "karura" case ChainIDAcala: return "acala" + case ChainIDKlaytn: + return "klaytn" default: return fmt.Sprintf("unknown chain ID: %d", c) } @@ -145,6 +147,8 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDKarura, nil case "acala": return ChainIDAcala, nil + case "klaytn": + return ChainIDKlaytn, nil default: return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s) } @@ -176,6 +180,8 @@ const ( ChainIDKarura ChainID = 11 // ChainIDAcala is the ChainID of Acala ChainIDAcala ChainID = 12 + // ChainIDKlaytn is the ChainID of Klaytn + ChainIDKlaytn ChainID = 13 // ChainIDEthereumRopsten is the ChainID of Ethereum Ropsten ChainIDEthereumRopsten ChainID = 10001 diff --git a/node/pkg/vaa/structs_test.go b/node/pkg/vaa/structs_test.go index 945ef6564..7c8322c3c 100644 --- a/node/pkg/vaa/structs_test.go +++ b/node/pkg/vaa/structs_test.go @@ -53,6 +53,7 @@ func TestChainIDFromString(t *testing.T) { {input: "fantom", output: ChainIDFantom}, {input: "karura", output: ChainIDKarura}, {input: "acala", output: ChainIDAcala}, + {input: "klaytn", output: ChainIDKlaytn}, {input: "ethereum-ropsten", output: ChainIDEthereumRopsten}, {input: "Solana", output: ChainIDSolana}, @@ -67,6 +68,7 @@ func TestChainIDFromString(t *testing.T) { {input: "Fantom", output: ChainIDFantom}, {input: "Karura", output: ChainIDKarura}, {input: "Acala", output: ChainIDAcala}, + {input: "Klaytn", output: ChainIDKlaytn}, {input: "Ethereum-ropsten", output: ChainIDEthereumRopsten}, } @@ -147,6 +149,7 @@ func TestChainId_String(t *testing.T) { {input: 10, output: "fantom"}, {input: 11, output: "karura"}, {input: 12, output: "acala"}, + {input: 13, output: "klaytn"}, {input: 10001, output: "ethereum-ropsten"}, } diff --git a/proto/publicrpc/v1/publicrpc.proto b/proto/publicrpc/v1/publicrpc.proto index d2e94d1aa..3d9c1865c 100644 --- a/proto/publicrpc/v1/publicrpc.proto +++ b/proto/publicrpc/v1/publicrpc.proto @@ -21,6 +21,7 @@ enum ChainID { CHAIN_ID_FANTOM = 10; CHAIN_ID_KARURA = 11; CHAIN_ID_ACALA = 12; + CHAIN_ID_KLAYTN = 13; // Special case - Eth has two testnets. CHAIN_ID_ETHEREUM is Goerli, // but we also want to connect to Ropsten, so we add a separate chain. CHAIN_ID_ETHEREUM_ROPSTEN = 10001; diff --git a/sdk/js/CHANGELOG.md b/sdk/js/CHANGELOG.md index 9527d0a24..e576b7e63 100644 --- a/sdk/js/CHANGELOG.md +++ b/sdk/js/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.4 + +### Added + +Klaytn support + ## 0.2.3 ### Added diff --git a/sdk/js/package.json b/sdk/js/package.json index 3b3acdb59..7ad0900a6 100644 --- a/sdk/js/package.json +++ b/sdk/js/package.json @@ -1,6 +1,6 @@ { "name": "@certusone/wormhole-sdk", - "version": "0.2.3", + "version": "0.2.4", "description": "SDK for interacting with Wormhole", "homepage": "https://wormholenetwork.com", "main": "./lib/cjs/index.js", diff --git a/sdk/js/src/utils/array.ts b/sdk/js/src/utils/array.ts index 4a1ab7b72..eb2b4c17f 100644 --- a/sdk/js/src/utils/array.ts +++ b/sdk/js/src/utils/array.ts @@ -12,6 +12,7 @@ import { CHAIN_ID_ETHEREUM_ROPSTEN, CHAIN_ID_FANTOM, CHAIN_ID_KARURA, + CHAIN_ID_KLAYTN, CHAIN_ID_OASIS, CHAIN_ID_POLYGON, CHAIN_ID_SOLANA, @@ -29,7 +30,8 @@ export const isEVMChain = (chainId: ChainId) => { chainId === CHAIN_ID_AURORA || chainId === CHAIN_ID_FANTOM || chainId === CHAIN_ID_KARURA || - chainId === CHAIN_ID_ACALA + chainId === CHAIN_ID_ACALA || + chainId === CHAIN_ID_KLAYTN ); }; diff --git a/sdk/js/src/utils/consts.ts b/sdk/js/src/utils/consts.ts index 34e4adc17..287ce55df 100644 --- a/sdk/js/src/utils/consts.ts +++ b/sdk/js/src/utils/consts.ts @@ -1,4 +1,4 @@ -export type ChainId = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 10001; +export type ChainId = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 10001; export const CHAIN_ID_SOLANA: ChainId = 1; export const CHAIN_ID_ETH: ChainId = 2; export const CHAIN_ID_TERRA: ChainId = 3; @@ -11,6 +11,7 @@ export const CHAIN_ID_AURORA: ChainId = 9; export const CHAIN_ID_FANTOM: ChainId = 10; export const CHAIN_ID_KARURA: ChainId = 11; export const CHAIN_ID_ACALA: ChainId = 12; +export const CHAIN_ID_KLAYTN: ChainId = 13; export const CHAIN_ID_ETHEREUM_ROPSTEN: ChainId = 10001; export const WSOL_ADDRESS = "So11111111111111111111111111111111111111112";