diff --git a/Dockerfile-localnet b/Dockerfile-localnet index 793b555c22..65ca4188b4 100644 --- a/Dockerfile-localnet +++ b/Dockerfile-localnet @@ -11,21 +11,12 @@ RUN ssh-keygen -b 2048 -t rsa -f /root/.ssh/localtest.pem -q -N "" WORKDIR /go/delivery/zeta-node COPY go.mod . COPY go.sum . -#RUN --mount=type=cache,target=/root/.cache/go-build \ -# go mod download RUN go mod download COPY . . -#RUN --mount=type=cache,target=/root/.cache/go-build \ -# make install -#RUN --mount=type=cache,target=/root/.cache/go-build \ -# make install-zetae2e RUN make install RUN make install-zetae2e -# -#FROM golang:1.20-alpine -#RUN apk --no-cache add openssh jq tmux vim curl bash RUN ssh-keygen -A WORKDIR /root diff --git a/cmd/zetae2e/local/admin.go b/cmd/zetae2e/local/admin.go index 50c8b2b8f7..fa2df0b75c 100644 --- a/cmd/zetae2e/local/admin.go +++ b/cmd/zetae2e/local/admin.go @@ -38,7 +38,7 @@ func adminTestRoutine( deployerRunner, UserAdminAddress, UserAdminPrivateKey, - runner.NewLogger(verbose, color.FgGreen, "admin"), + runner.NewLogger(verbose, color.FgHiGreen, "admin"), ) if err != nil { return err @@ -48,7 +48,8 @@ func adminTestRoutine( startTime := time.Now() // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 1000) + // we transfer around the total supply of Zeta to the admin for the chain migration test + txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) txERC20Send := deployerRunner.SendERC20OnEvm(UserAdminAddress, 1000) adminRunner.WaitForTxReceiptOnEvm(txZetaSend) adminRunner.WaitForTxReceiptOnEvm(txERC20Send) diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 9a0718e83a..09cdadd6c9 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -2,11 +2,11 @@ version: "3" # This docker-compose file overrides the orchestrator service to specify the flag to test the admin functions # and skip the regular tests -# it also adds another local Ethereum network to test EVM chain migration +# it also adds another local Ethereum network to test EVM chain migration and use the additional-evm flag services: orchestrator: - entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-eth"] + entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-evm"] eth2: image: ethereum/client-go:v1.10.26 @@ -17,4 +17,10 @@ services: networks: mynetwork: ipv4_address: 172.20.0.102 - entrypoint: ["geth", "--dev", "--http", "--http.addr", "172.20.0.102", "--http.vhosts", "*", "--http.api", "eth,web3,net", "--http.corsdomain", "https://remix.ethereum.org", "--dev.period", "2"] \ No newline at end of file + entrypoint: ["geth", "--dev", "--http", "--http.addr", "172.20.0.102", "--http.vhosts", "*", "--http.api", "eth,web3,net", "--http.corsdomain", "https://remix.ethereum.org", "--dev.period", "2"] + + zetaclient0: + entrypoint: [ "/root/start-zetaclientd.sh", "additional-evm" ] + + zetaclient1: + entrypoint: [ "/root/start-zetaclientd.sh", "additional-evm" ] \ No newline at end of file diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 51af031710..12f91ee63c 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -46,9 +46,9 @@ echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Et geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth:8545 -# check if the option is additional-eth +# check if the option is additional-evm # in this case an additional eth network is spun up and the deployer and TSS accounts are funded with Ether -if [ "$OPTION" == "additional-eth" ]; then +if [ "$OPTION" == "additional-evm" ]; then # unlock the admin account echo "funding admin address 0xcC8487562AAc220ea4406196Ee902C7c076966af with 100 Ether on ETH2" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea4406196Ee902C7c076966af", value: web3.toWei(100,"ether")})' attach http://eth2:8545 diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index 761a58098d..a43e8e120f 100755 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -9,6 +9,11 @@ HOSTNAME=$(hostname) OPTION=$1 +# sepolia is used in chain migration tests, this functions set the sepolia endpoint in the zetaclient_config.json +set_sepolia_endpoint() { + jq '.EVMChainConfigs."11155111".Endpoint = "http://eth2:8545"' /root/.zetacored/config/zetaclient_config.json > tmp.json && mv tmp.json /root/.zetacored/config/zetaclient_config.json +} + # read HOTKEY_BACKEND env var for hotkey keyring backend and set default to test BACKEND="test" if [ "$HOTKEY_BACKEND" == "file" ]; then @@ -30,6 +35,14 @@ then rm ~/.tss/* MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --keyring-backend "$BACKEND" + + # check if the option is additional-evm + # in this case, the additional evm is represented with the sepolia chain, we set manually the eth2 endpoint to the sepolia chain (11155111 -> http://eth2:8545) + # in /root/.zetacored/config/zetaclient_config.json + if [ "$OPTION" == "additional-evm" ]; then + set_sepolia_endpoint + fi + zetaclientd start < /root/password.file else num=$(echo $HOSTNAME | tr -dc '0-9') @@ -42,11 +55,20 @@ else done rm ~/.tss/* zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" + + # check if the option is additional-evm + # in this case, the additional evm is represented with the sepolia chain, we set manually the eth2 endpoint to the sepolia chain (11155111 -> http://eth2:8545) + # in /root/.zetacored/config/zetaclient_config.json + if [ "$OPTION" == "additional-evm" ]; then + set_sepolia_endpoint + fi + zetaclientd start < /root/password.file fi +# check if the option is background +# in this case, we tail the zetaclientd log file if [ "$OPTION" == "background" ]; then sleep 3 tail -f $HOME/zetaclient.log fi - diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 6b6976624c..71a65b0f82 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -2,6 +2,9 @@ package e2etests import ( "context" + + "github.com/fatih/color" + "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -10,12 +13,14 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/e2e/runner" + "github.com/zeta-chain/zetacore/e2e/utils" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) // EVM2RPCURL is the RPC URL for the additional EVM localnet // Only this test currently uses a additional EVM localnet, and this test is only run locally // Therefore, we hardcode RPC urls and addresses for simplicity -const EVM2RPCURL = "http://0.0.0.0:8546" +const EVM2RPCURL = "http://eth2:8545" // EVM2ChainID is the chain ID for the additional EVM localnet // We set Sepolia testnet although the value is not important, only used to differentiate @@ -39,6 +44,18 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { newRunner.MintERC20OnEvm(10000) // update the chain params to set up the chain + chainParams := getNewEVMChainParams(r) + adminAddr, err := r.ZetaTxServer.GetAccountAddressFromName(utils.FungibleAdminName) + if err != nil { + panic(err) + } + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgUpdateChainParams( + adminAddr, + chainParams, + )) + if err != nil { + panic(err) + } // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) @@ -54,20 +71,40 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // configureEVM2 takes a runner and configures it to use the additional EVM localnet func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { - var newRunner runner.E2ERunner - - err := newRunner.CopyAddressesFrom(r) + // initialize a new runner with previous runner values + newRunner := runner.NewE2ERunner( + r.Ctx, + "admin-evm2", + r.CtxCancel, + r.DeployerAddress, + r.DeployerPrivateKey, + r.FungibleAdminMnemonic, + r.EVMClient, + r.ZEVMClient, + r.CctxClient, + r.ZetaTxServer, + r.FungibleClient, + r.AuthClient, + r.BankClient, + r.ObserverClient, + r.EVMAuth, + r.ZEVMAuth, + r.BtcRPCClient, + runner.NewLogger(false, color.FgHiYellow, "admin-evm2"), + ) + + // All existing fields of the runner are the same except for the RPC URL and client for EVM + ewvmClient, evmAuth, err := getEVMClient(newRunner.Ctx, EVM2RPCURL, r.DeployerPrivateKey) if err != nil { return nil, err } + newRunner.EVMClient = ewvmClient + newRunner.EVMAuth = evmAuth - // All existing fields of the runner are kept except for the RPC URL and client for EVM - client, auth, err := getEVMClient(newRunner.Ctx, EVM2RPCURL, r.DeployerPrivateKey) - if err != nil { + // Copy the ZetaChain contract addresses from the original runner + if err := newRunner.CopyAddressesFrom(r); err != nil { return nil, err } - newRunner.EVMClient = client - newRunner.EVMAuth = auth // reset evm contracts to ensure they are re-initialized newRunner.ZetaEthAddr = ethcommon.Address{} @@ -79,7 +116,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { newRunner.ERC20Addr = ethcommon.Address{} newRunner.ERC20 = nil - return &newRunner, nil + return newRunner, nil } // getEVMClient get evm client @@ -105,3 +142,22 @@ func getEVMClient(ctx context.Context, rpc, privKey string) (*ethclient.Client, return evmClient, evmAuth, nil } + +// getNewEVMChainParams returns the chain params for the new EVM chain +func getNewEVMChainParams(r *runner.E2ERunner) *observertypes.ChainParams { + // goerli local as base + chainParams := observertypes.GetDefaultGoerliLocalnetChainParams() + + // set the chain id to the new chain id + chainParams.ChainId = EVM2ChainID + + // set contracts + chainParams.ConnectorContractAddress = r.ConnectorEthAddr.Hex() + chainParams.Erc20CustodyContractAddress = r.ERC20CustodyAddr.Hex() + chainParams.ZetaTokenContractAddress = r.ZetaEthAddr.Hex() + + // set supported + chainParams.IsSupported = true + + return chainParams +} diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 07dd526225..79f95e9709 100644 --- a/e2e/runner/runner.go +++ b/e2e/runner/runner.go @@ -109,7 +109,7 @@ type E2ERunner struct { Logger *Logger WG sync.WaitGroup BitcoinParams *chaincfg.Params - mutex *sync.Mutex + mutex sync.Mutex } func NewE2ERunner( diff --git a/e2e/runner/setup_zeta.go b/e2e/runner/setup_zeta.go index 16f8f3b64e..74bbd6df21 100644 --- a/e2e/runner/setup_zeta.go +++ b/e2e/runner/setup_zeta.go @@ -4,21 +4,19 @@ import ( "math/big" "time" - "github.com/zeta-chain/zetacore/e2e/contracts/contextapp" - "github.com/zeta-chain/zetacore/e2e/contracts/zevmswap" - utils2 "github.com/zeta-chain/zetacore/e2e/utils" - - "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" - "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" - "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-core/contracts/uniswapv2factory.sol" uniswapv2router "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/e2e/contracts/contextapp" + "github.com/zeta-chain/zetacore/e2e/contracts/zevmswap" + "github.com/zeta-chain/zetacore/e2e/utils" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -71,7 +69,7 @@ func (runner *E2ERunner) SetZEVMContracts() { // deploy system contracts and ZRC20 contracts on ZetaChain uniswapV2FactoryAddr, uniswapV2RouterAddr, zevmConnectorAddr, wzetaAddr, erc20zrc20Addr, err := runner.ZetaTxServer.DeploySystemContractsAndZRC20( - utils2.FungibleAdminName, + utils.FungibleAdminName, runner.ERC20Addr.Hex(), ) if err != nil { @@ -154,14 +152,14 @@ func (runner *E2ERunner) SetZEVMContracts() { panic(err) } - receipt := utils2.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, txZEVMSwapApp, runner.Logger, runner.ReceiptTimeout) + receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, txZEVMSwapApp, runner.Logger, runner.ReceiptTimeout) if receipt.Status != 1 { panic("ZEVMSwapApp deployment failed") } runner.ZEVMSwapAppAddr = zevmSwapAppAddr runner.ZEVMSwapApp = zevmSwapApp - receipt = utils2.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, txContextApp, runner.Logger, runner.ReceiptTimeout) + receipt = utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, txContextApp, runner.Logger, runner.ReceiptTimeout) if receipt.Status != 1 { panic("ContextApp deployment failed") } diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index 4aedf29c92..2c5af55a2f 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -121,6 +121,20 @@ func (zts ZetaTxServer) GetAccountAddress(index int) string { return zts.address[index] } +// GetAccountAddressFromName returns the account address from the given name +func (zts ZetaTxServer) GetAccountAddressFromName(name string) (string, error) { + acc, err := zts.clientCtx.Keyring.Key(name) + if err != nil { + return "", err + } + addr, err := acc.GetAddress() + if err != nil { + return "", err + } + return addr.String(), nil +} + +// GetAllAccountAddress returns all account addresses func (zts ZetaTxServer) GetAllAccountAddress() []string { return zts.address diff --git a/zetaclient/config/config_chain.go b/zetaclient/config/config_chain.go index 329c650023..5972dffc8a 100644 --- a/zetaclient/config/config_chain.go +++ b/zetaclient/config/config_chain.go @@ -56,6 +56,10 @@ var evmChainsConfigs = map[int64]EVMConfig{ Chain: common.GoerliChain(), Endpoint: "", }, + common.SepoliaChain().ChainId: { + Chain: common.SepoliaChain(), + Endpoint: "", + }, common.BscTestnetChain().ChainId: { Chain: common.BscTestnetChain(), Endpoint: "",