From 795da39673774399b1752d2a5a0b46d566dcd9b0 Mon Sep 17 00:00:00 2001 From: lumtis Date: Thu, 14 Mar 2024 18:32:15 +0100 Subject: [PATCH 01/35] init --- cmd/zetae2e/local/local.go | 7 ++-- contrib/localnet/docker-compose-admin.yml | 13 ++++++- .../localnet/orchestrator/start-zetae2e.sh | 12 ++++++ e2e/e2etests/e2etests.go | 17 +++++++-- e2e/e2etests/test_migrate_chain_support.go | 7 ++++ e2e/runner/runner.go | 37 ++++++++++--------- 6 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 e2e/e2etests/test_migrate_chain_support.go diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 3dd40d92c3..ddbc7323ec 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -325,9 +325,10 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, - e2etests.TestPauseZRC20Name, - e2etests.TestUpdateBytecodeName, - e2etests.TestDepositEtherLiquidityCapName, + //e2etests.TestPauseZRC20Name, + //e2etests.TestUpdateBytecodeName, + //e2etests.TestDepositEtherLiquidityCapName, + e2etests.TestMigrateChainSupportName, )) } if testPerformance { diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 46b24bfb24..8eadb3ad2f 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -2,8 +2,19 @@ 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 services: orchestrator: - entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin"] + entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-eth"] + eth2: + image: ethereum/client-go:v1.10.26 + container_name: eth2 + hostname: eth2 + ports: + - "8546:8545" + networks: + mynetwork: + ipv4_address: 172.20.0.100 + entrypoint: ["geth", "--dev", "--http", "--http.addr", "172.20.0.100", "--http.vhosts", "*", "--http.api", "eth,web3,net", "--http.corsdomain", "https://remix.ethereum.org", "--dev.period", "2"] \ No newline at end of file diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 129317932d..89916f9271 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -45,6 +45,18 @@ geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea44 echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether" 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 +# 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 +# unlock the deployer account + echo "funding deployer address 0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC with 100 Ether on ETH2" + geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", value: web3.toWei(100,"ether")})' attach http://eth2:8545 +# unlock the TSS account + echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH@" + geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth2:8545 +fi + ### Run zetae2e command depending on the option passed if [ "$OPTION" == "upgrade" ]; then diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 70bdc6de94..f7dbfd771b 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -21,17 +21,15 @@ const ( TestCrosschainSwapName = "crosschain_swap" TestMessagePassingRevertFailName = "message_passing_revert_fail" TestMessagePassingRevertSuccessName = "message_passing_revert_success" - TestPauseZRC20Name = "pause_zrc20" TestERC20DepositAndCallRefundName = "erc20_deposit_and_call_refund" - TestUpdateBytecodeName = "update_bytecode" TestEtherDepositAndCallName = "eth_deposit_and_call" TestDepositEtherLiquidityCapName = "deposit_eth_liquidity_cap" TestMyTestName = "my_test" TestERC20WithdrawName = "erc20_withdraw" TestERC20DepositName = "erc20_deposit" - // #nosec G101: Potential hardcoded credentials (gosec), not a credential - TestERC20DepositRestrictedName = "erc20_deposit_restricted" + + TestERC20DepositRestrictedName = "erc20_deposit_restricted" // #nosec G101: Potential hardcoded credentials (gosec), not a credential TestEtherDepositName = "eth_deposit" TestEtherWithdrawName = "eth_withdraw" TestEtherWithdrawRestrictedName = "eth_withdraw_restricted" @@ -45,6 +43,11 @@ const ( TestStressBTCWithdrawName = "stress_btc_withdraw" TestStressEtherDepositName = "stress_eth_deposit" TestStressBTCDepositName = "stress_btc_deposit" + + // Admin test + TestMigrateChainSupportName = "migrate_chain_support" + TestPauseZRC20Name = "pause_zrc20" + TestUpdateBytecodeName = "update_bytecode" ) // AllE2ETests is an ordered list of all e2e tests @@ -315,4 +318,10 @@ var AllE2ETests = []runner.E2ETest{ }, TestBitcoinWithdrawRestricted, ), + runner.NewE2ETest( + TestMigrateChainSupportName, + "migrate the evm chain from goerli to sepolia", + []runner.ArgDefinition{}, + TestMigrateChainSupport, + ), } diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go new file mode 100644 index 0000000000..f846916b8c --- /dev/null +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -0,0 +1,7 @@ +package e2etests + +import "github.com/zeta-chain/zetacore/e2e/runner" + +func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { + r.Logger.Print("🏃 starting migrate chain support test") +} diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 06b123c12f..79f95e9709 100644 --- a/e2e/runner/runner.go +++ b/e2e/runner/runner.go @@ -65,15 +65,17 @@ type E2ERunner struct { EVMAuth *bind.TransactOpts ZEVMAuth *bind.TransactOpts - // contracts - ZetaEthAddr ethcommon.Address - ZetaEth *zetaeth.ZetaEth - ConnectorEthAddr ethcommon.Address - ConnectorEth *zetaconnectoreth.ZetaConnectorEth - ERC20CustodyAddr ethcommon.Address - ERC20Custody *erc20custody.ERC20Custody - ERC20Addr ethcommon.Address - ERC20 *erc20.ERC20 + // contracts evm + ZetaEthAddr ethcommon.Address + ZetaEth *zetaeth.ZetaEth + ConnectorEthAddr ethcommon.Address + ConnectorEth *zetaconnectoreth.ZetaConnectorEth + ERC20CustodyAddr ethcommon.Address + ERC20Custody *erc20custody.ERC20Custody + ERC20Addr ethcommon.Address + ERC20 *erc20.ERC20 + + // contracts zevm ERC20ZRC20Addr ethcommon.Address ERC20ZRC20 *zrc20.ZRC20 ETHZRC20Addr ethcommon.Address @@ -88,14 +90,13 @@ type E2ERunner struct { ConnectorZEVM *connectorzevm.ZetaConnectorZEVM WZetaAddr ethcommon.Address WZeta *wzeta.WETH9 - - TestDAppAddr ethcommon.Address - ZEVMSwapAppAddr ethcommon.Address - ZEVMSwapApp *zevmswap.ZEVMSwapApp - ContextAppAddr ethcommon.Address - ContextApp *contextapp.ContextApp - SystemContractAddr ethcommon.Address - SystemContract *systemcontract.SystemContract + TestDAppAddr ethcommon.Address + ZEVMSwapAppAddr ethcommon.Address + ZEVMSwapApp *zevmswap.ZEVMSwapApp + ContextAppAddr ethcommon.Address + ContextApp *contextapp.ContextApp + SystemContractAddr ethcommon.Address + SystemContract *systemcontract.SystemContract // config CctxTimeout time.Duration @@ -261,7 +262,7 @@ func (runner *E2ERunner) RunE2ETests(e2eTests []E2ETest) (err error) { return nil } -// RunE2ETestsFromNamesIntoReport runs a list of e2e tests by name in a list of e2e tests and returns a report +// RunE2ETestsIntoReport runs a list of e2e tests by name in a list of e2e tests and returns a report // The function doesn't return an error, it returns a report with the error func (runner *E2ERunner) RunE2ETestsIntoReport(e2eTests []E2ETest) (TestReports, error) { // go through all tests From 69946f572a915d9dfbb9448f6ce3b6d463b987ce Mon Sep 17 00:00:00 2001 From: lumtis Date: Fri, 15 Mar 2024 11:24:02 +0100 Subject: [PATCH 02/35] add migration logic --- contrib/localnet/docker-compose-admin.yml | 4 +- .../localnet/orchestrator/start-zetae2e.sh | 10 +- e2e/e2etests/test_migrate_chain_support.go | 103 +++++++++++++++++- e2e/runner/runner.go | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 8eadb3ad2f..9a0718e83a 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -16,5 +16,5 @@ services: - "8546:8545" networks: mynetwork: - ipv4_address: 172.20.0.100 - entrypoint: ["geth", "--dev", "--http", "--http.addr", "172.20.0.100", "--http.vhosts", "*", "--http.api", "eth,web3,net", "--http.corsdomain", "https://remix.ethereum.org", "--dev.period", "2"] \ No newline at end of file + 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 diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 89916f9271..51af031710 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -37,7 +37,7 @@ geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x8D47Db7390AC4D3D449 echo "funding deployer address 0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf", value: web3.toWei(100,"ether")})' attach http://eth:8545 -# unlock advanced erc20 tests accounts +# unlock admin erc20 tests accounts echo "funding deployer address 0xcC8487562AAc220ea4406196Ee902C7c076966af with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea4406196Ee902C7c076966af", value: web3.toWei(100,"ether")})' attach http://eth:8545 @@ -49,11 +49,11 @@ geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90E # check if the option is additional-eth # 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 -# unlock the deployer account - echo "funding deployer address 0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC with 100 Ether on ETH2" - geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", value: web3.toWei(100,"ether")})' attach http://eth2:8545 +# 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 # unlock the TSS account - echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH@" + echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH2" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth2:8545 fi diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index f846916b8c..557987eee8 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -1,7 +1,106 @@ package e2etests -import "github.com/zeta-chain/zetacore/e2e/runner" +import ( + "context" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/e2e/runner" + "math/big" +) + +// 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" + +// EVM2ChainID is the chain ID for the additional EVM localnet +// We set Sepolia testnet although the value is not important, only used to differentiate +var EVM2ChainID = common.SepoliaChain().ChainId func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { - r.Logger.Print("🏃 starting migrate chain support test") + // deposit most of the ZETA supply on ZetaChain + zetaAmount := big.NewInt(1e18) + zetaAmount = zetaAmount.Mul(zetaAmount, big.NewInt(20_000_000_000)) // 20B Zeta + r.DepositZetaWithAmount(r.DeployerAddress, zetaAmount) + + // do an ethers withdraw on the previous chain (0.01eth) for some interaction + TestEtherWithdraw(r, []string{"10000000000000000"}) + + // create runner for the new EVM and set it up + newRunner, err := configureEVM2(r) + if err != nil { + panic(err) + } + newRunner.SetupEVM(false) + newRunner.MintERC20OnEvm(10000) + + // update the chain params to set up the chain + + // deposit Ethers and ERC20 on ZetaChain + txEtherDeposit := newRunner.DepositEther(false) + txERC20Deposit := newRunner.DepositERC20() + newRunner.WaitForMinedCCTX(txEtherDeposit) + newRunner.WaitForMinedCCTX(txERC20Deposit) + + // withdraw Zeta, Ethers and ERC20 to the new chain + TestZetaWithdraw(r, []string{"1000000000000000000"}) + TestEtherWithdraw(r, []string{"10000000000000000"}) + TestERC20Withdraw(r, []string{"1000000000000000000"}) +} + +// 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) + if err != nil { + return nil, err + } + + // 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 { + return nil, err + } + newRunner.EVMClient = client + newRunner.EVMAuth = auth + + // reset evm contracts to ensure they are re-initialized + newRunner.ZetaEthAddr = ethcommon.Address{} + newRunner.ZetaEth = nil + newRunner.ConnectorEthAddr = ethcommon.Address{} + newRunner.ConnectorEth = nil + newRunner.ERC20CustodyAddr = ethcommon.Address{} + newRunner.ERC20Custody = nil + newRunner.ERC20Addr = ethcommon.Address{} + newRunner.ERC20 = nil + + return &newRunner, nil +} + +// getEVMClient get evm client +// TODO: put this logic in common with the one in cmd/zetae2e/config/clients.go +func getEVMClient(ctx context.Context, rpc, privKey string) (*ethclient.Client, *bind.TransactOpts, error) { + evmClient, err := ethclient.Dial(rpc) + if err != nil { + return nil, nil, err + } + + chainid, err := evmClient.ChainID(ctx) + if err != nil { + return nil, nil, err + } + deployerPrivkey, err := crypto.HexToECDSA(privKey) + if err != nil { + return nil, nil, err + } + evmAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) + if err != nil { + return nil, nil, err + } + + return evmClient, evmAuth, nil } diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 79f95e9709..07dd526225 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( From a356637afa31688e10bbbed2398a5c0703997eb3 Mon Sep 17 00:00:00 2001 From: lumtis Date: Fri, 15 Mar 2024 11:27:29 +0100 Subject: [PATCH 03/35] go import --- e2e/e2etests/test_migrate_chain_support.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 557987eee8..6b6976624c 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -2,13 +2,14 @@ package e2etests import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/e2e/runner" - "math/big" ) // EVM2RPCURL is the RPC URL for the additional EVM localnet From 0f5198086792b2000a939df323a2824fb80b4b0b Mon Sep 17 00:00:00 2001 From: lumtis Date: Fri, 15 Mar 2024 21:05:47 +0100 Subject: [PATCH 04/35] test logic v1 --- Dockerfile-localnet | 9 --- cmd/zetae2e/local/admin.go | 5 +- contrib/localnet/docker-compose-admin.yml | 12 ++- .../localnet/orchestrator/start-zetae2e.sh | 4 +- contrib/localnet/scripts/start-zetaclientd.sh | 24 +++++- e2e/e2etests/test_migrate_chain_support.go | 76 ++++++++++++++++--- e2e/runner/runner.go | 2 +- e2e/runner/setup_zeta.go | 18 ++--- e2e/txserver/zeta_tx_server.go | 14 ++++ zetaclient/config/config_chain.go | 4 + 10 files changed, 130 insertions(+), 38 deletions(-) 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: "", From 22bc8fc670d11e9d4ff8dc61e5c01c8a3103f059 Mon Sep 17 00:00:00 2001 From: lumtis Date: Tue, 19 Mar 2024 17:41:39 +0100 Subject: [PATCH 05/35] temporary utility to reset nonces --- .../keeper/msg_server_reset_chain_nonce.go | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 x/observer/keeper/msg_server_reset_chain_nonce.go diff --git a/x/observer/keeper/msg_server_reset_chain_nonce.go b/x/observer/keeper/msg_server_reset_chain_nonce.go new file mode 100644 index 0000000000..215a87df3f --- /dev/null +++ b/x/observer/keeper/msg_server_reset_chain_nonce.go @@ -0,0 +1,49 @@ +package keeper + +import ( + "context" + "errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +type MsgResetChainNonces struct { + Creator string + ChainID int64 + //ChainNonces types.ChainNonces + //PendingNonces types.PendingNonces +} + +func (k msgServer) ResetChainNonces(goCtx context.Context, msg *MsgResetChainNonces) (*types.MsgAddBlameVoteResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + tss, found := k.GetTSS(ctx) + if !found { + return nil, errors.New("no tss found") + } + + chain := common.GetChainFromChainID(msg.ChainID) + if chain == nil { + return nil, errors.New("chain not found") + } + + // set chain nonce and pending nonce + chainNonce := types.ChainNonces{ + Index: chain.ChainName.String(), + ChainId: chain.ChainId, + Nonce: 0, + // #nosec G701 always positive + FinalizedHeight: uint64(ctx.BlockHeight()), + } + k.SetChainNonces(ctx, chainNonce) + p := types.PendingNonces{ + NonceLow: 0, + NonceHigh: 0, + ChainId: chain.ChainId, + Tss: tss.TssPubkey, + } + k.SetPendingNonces(ctx, p) + + return &types.MsgAddBlameVoteResponse{}, nil +} From 302ffe5777dedfd95ef35372ce0f757ff4dc6d59 Mon Sep 17 00:00:00 2001 From: lumtis Date: Tue, 19 Mar 2024 17:42:29 +0100 Subject: [PATCH 06/35] complete test with restart --- contrib/localnet/orchestrator/Dockerfile | 1 + .../orchestrator/Dockerfile.fastbuild | 1 + .../restart-zetaclientd-migrate.sh | 9 +++ contrib/localnet/scripts/start-zetaclientd.sh | 4 +- e2e/e2etests/test_eth_withdraw.go | 4 + e2e/e2etests/test_migrate_chain_support.go | 74 +++++++++++++++++-- 6 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh diff --git a/contrib/localnet/orchestrator/Dockerfile b/contrib/localnet/orchestrator/Dockerfile index e159d8ba84..3faed73278 100644 --- a/contrib/localnet/orchestrator/Dockerfile +++ b/contrib/localnet/orchestrator/Dockerfile @@ -13,6 +13,7 @@ COPY --from=zeta /root/.ssh/localtest.pem /root/.ssh/localtest.pem COPY contrib/localnet/orchestrator/start-zetae2e.sh /work/ COPY contrib/localnet/orchestrator/restart-zetaclientd.sh /work/ +COPY contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh /work/ RUN chmod +x /work/*.sh ENV GOPATH /go diff --git a/contrib/localnet/orchestrator/Dockerfile.fastbuild b/contrib/localnet/orchestrator/Dockerfile.fastbuild index 64d9e9c87e..e23223dab4 100644 --- a/contrib/localnet/orchestrator/Dockerfile.fastbuild +++ b/contrib/localnet/orchestrator/Dockerfile.fastbuild @@ -13,6 +13,7 @@ COPY --from=zeta /root/.ssh/localtest.pem /root/.ssh/localtest.pem COPY contrib/localnet/orchestrator/start-zetae2e.sh /work/ COPY contrib/localnet/orchestrator/restart-zetaclientd.sh /work/ +COPY contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh /work/ RUN chmod +x /work/*.sh COPY --from=zeta /usr/local/bin/zetae2e /usr/local/bin/ diff --git a/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh b/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh new file mode 100644 index 0000000000..7b3f3e0799 --- /dev/null +++ b/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +echo restarting zetaclients + +ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem killall zetaclientd +ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem killall zetaclientd +ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" +ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" + diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index a43e8e120f..270ec57339 100755 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -68,7 +68,7 @@ fi # check if the option is background # in this case, we tail the zetaclientd log file -if [ "$OPTION" == "background" ]; then +#if [ "$OPTION" == "background" ]; then sleep 3 tail -f $HOME/zetaclient.log -fi +#fi diff --git a/e2e/e2etests/test_eth_withdraw.go b/e2e/e2etests/test_eth_withdraw.go index 66e0385642..e9a4211461 100644 --- a/e2e/e2etests/test_eth_withdraw.go +++ b/e2e/e2etests/test_eth_withdraw.go @@ -12,6 +12,8 @@ import ( // TestEtherWithdraw tests the withdraw of ether func TestEtherWithdraw(r *runner.E2ERunner, args []string) { + r.Logger.Info("TestEtherWithdraw") + approvedAmount := big.NewInt(1e18) if len(args) != 1 { panic("TestEtherWithdraw requires exactly one argument for the withdrawal amount.") @@ -59,6 +61,8 @@ func TestEtherWithdraw(r *runner.E2ERunner, args []string) { if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { panic("cctx status is not outbound mined") } + + r.Logger.Info("TestEtherWithdraw completed") } // TestEtherWithdrawRestricted tests the withdrawal to a restricted receiver address diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 71a65b0f82..064163a30b 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -2,15 +2,18 @@ package e2etests import ( "context" - - "github.com/fatih/color" - + "fmt" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" "math/big" + "os/exec" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/fatih/color" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -57,16 +60,58 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { panic(err) } + // setup the gas token + if err != nil { + panic(err) + } + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( + adminAddr, + "", + chainParams.ChainId, + 18, + "Sepolia ETH", + "sETH", + common.CoinType_Gas, + 100000, + )) + if err != nil { + panic(err) + } + + // set the gas token in the runner + ethZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chainParams.ChainId)) + if err != nil { + panic(err) + } + if (ethZRC20Addr == ethcommon.Address{}) { + panic("eth zrc20 not found") + } + newRunner.ETHZRC20Addr = ethZRC20Addr + ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, newRunner.ZEVMClient) + if err != nil { + panic(err) + } + newRunner.ETHZRC20 = ethZRC20 + + // restart ZetaClient to pick up the new chain + r.Logger.Print("🔄 restarting ZetaClient to pick up the new chain") + if err := restartZetaClient(); err != nil { + panic(err) + } + + // wait 10 set for the chain to start + time.Sleep(10 * time.Second) + // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) - txERC20Deposit := newRunner.DepositERC20() + //txERC20Deposit := newRunner.DepositERC20() newRunner.WaitForMinedCCTX(txEtherDeposit) - newRunner.WaitForMinedCCTX(txERC20Deposit) + //newRunner.WaitForMinedCCTX(txERC20Deposit) // withdraw Zeta, Ethers and ERC20 to the new chain - TestZetaWithdraw(r, []string{"1000000000000000000"}) - TestEtherWithdraw(r, []string{"10000000000000000"}) - TestERC20Withdraw(r, []string{"1000000000000000000"}) + //TestZetaWithdraw(r, []string{"1000000000000000000"}) + TestEtherWithdraw(newRunner, []string{"10000000000000000"}) + //TestERC20Withdraw(r, []string{"1000000000000000000"}) } // configureEVM2 takes a runner and configures it to use the additional EVM localnet @@ -161,3 +206,16 @@ func getNewEVMChainParams(r *runner.E2ERunner) *observertypes.ChainParams { return chainParams } + +// restartZetaClient restarts the Zeta client +func restartZetaClient() error { + sshCommandFilePath := "/work/restart-zetaclientd-migrate.sh" + cmd := exec.Command("/bin/sh", sshCommandFilePath) + + // Execute the command + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("error restarting ZetaClient: %s - %s", err.Error(), output) + } + return nil +} From ddb78451aeba30d3b7f86cbce69189cf8c5674f9 Mon Sep 17 00:00:00 2001 From: lumtis Date: Tue, 19 Mar 2024 17:42:51 +0100 Subject: [PATCH 07/35] hack for setting nonces --- x/observer/keeper/msg_server_update_chain_params.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/x/observer/keeper/msg_server_update_chain_params.go b/x/observer/keeper/msg_server_update_chain_params.go index 3a2f0dea14..0810d388d3 100644 --- a/x/observer/keeper/msg_server_update_chain_params.go +++ b/x/observer/keeper/msg_server_update_chain_params.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "github.com/zeta-chain/zetacore/common" sdk "github.com/cosmos/cosmos-sdk/types" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" @@ -26,6 +27,17 @@ func (k msgServer) UpdateChainParams(goCtx context.Context, msg *types.MsgUpdate chainParamsList = types.ChainParamsList{} } + if msg.ChainParams.ChainId == common.SepoliaChain().ChainId { + _, err := k.ResetChainNonces(ctx, &MsgResetChainNonces{ + Creator: msg.Creator, + ChainID: msg.ChainParams.ChainId, + }) + if err != nil { + return nil, err + } + ctx.Logger().Info("ResetChainNonces", "ChainID", msg.ChainParams.ChainId) + } + // find chain params for the chain for i, cp := range chainParamsList.ChainParams { if cp.ChainId == msg.ChainParams.ChainId { From 0388a3050c3020e9dbf337622adad4cf5d6d1b37 Mon Sep 17 00:00:00 2001 From: lumtis Date: Tue, 19 Mar 2024 20:18:02 +0100 Subject: [PATCH 08/35] use ganache --- contrib/localnet/docker-compose-admin.yml | 13 ++++++++++-- .../localnet/orchestrator/start-zetae2e.sh | 20 +++++++++---------- e2e/runner/evm.go | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 09cdadd6c9..d84c93d5a5 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -9,7 +9,7 @@ services: entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-evm"] eth2: - image: ethereum/client-go:v1.10.26 + image: trufflesuite/ganache-cli # Replace with your custom image tag if you built your own container_name: eth2 hostname: eth2 ports: @@ -17,7 +17,16 @@ 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"] + command: [ "--blockTime", "3", "--host", "0.0.0.0", "--chainId", "11155111", "--port", "8545", "--account", "0x95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083,100000000000000000000"] +# image: custom-geth:latest +# container_name: eth2 +# hostname: eth2 +# ports: +# - "8546:8545" +# 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"] zetaclient0: entrypoint: [ "/root/start-zetaclientd.sh", "additional-evm" ] diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 12f91ee63c..6ea77d3fcd 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -46,16 +46,16 @@ 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-evm -# in this case an additional eth network is spun up and the deployer and TSS accounts are funded with Ether -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 -# unlock the TSS account - echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH2" - geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth2:8545 -fi +## 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-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 +## unlock the TSS account +# echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH2" +# geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth2:8545 +#fi ### Run zetae2e command depending on the option passed diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index 119b93d79a..dc4fb5b183 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -168,7 +168,7 @@ func (runner *E2ERunner) SendEther(_ ethcommon.Address, value *big.Int, data []b } tx := ethtypes.NewTransaction(nonce, runner.TSSAddress, value, gasLimit, gasPrice, data) - chainID, err := evmClient.NetworkID(runner.Ctx) + chainID, err := evmClient.ChainID(runner.Ctx) if err != nil { return nil, err } From 537ae68c03454c78f613f844e4078c36a6907e0d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 20 Mar 2024 01:48:55 -0400 Subject: [PATCH 09/35] manually produce blocks for e2e test --- contrib/localnet/docker-compose-admin.yml | 2 +- e2e/e2etests/test_erc20_withdraw.go | 1 + e2e/e2etests/test_eth_withdraw.go | 1 + e2e/e2etests/test_migrate_chain_support.go | 9 +++++---- e2e/e2etests/test_zeta_withdraw.go | 1 + e2e/runner/zeta.go | 15 +++++++++++++++ 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index d84c93d5a5..88d380d7ef 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -17,7 +17,7 @@ services: networks: mynetwork: ipv4_address: 172.20.0.102 - command: [ "--blockTime", "3", "--host", "0.0.0.0", "--chainId", "11155111", "--port", "8545", "--account", "0x95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083,100000000000000000000"] + command: ["--host", "0.0.0.0", "--chainId", "11155111", "--port", "8545", "--account", "0x95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083,100000000000000000000"] # image: custom-geth:latest # container_name: eth2 # hostname: eth2 diff --git a/e2e/e2etests/test_erc20_withdraw.go b/e2e/e2etests/test_erc20_withdraw.go index 26959c0eac..ef26ff73c0 100644 --- a/e2e/e2etests/test_erc20_withdraw.go +++ b/e2e/e2etests/test_erc20_withdraw.go @@ -57,6 +57,7 @@ func TestERC20Withdraw(r *runner.E2ERunner, args []string) { } // verify the withdraw value + r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) verifyTransferAmountFromCCTX(r, cctx, withdrawalAmount.Int64()) } diff --git a/e2e/e2etests/test_eth_withdraw.go b/e2e/e2etests/test_eth_withdraw.go index e9a4211461..f15de81ece 100644 --- a/e2e/e2etests/test_eth_withdraw.go +++ b/e2e/e2etests/test_eth_withdraw.go @@ -56,6 +56,7 @@ func TestEtherWithdraw(r *runner.E2ERunner, args []string) { r.Logger.ZRC20Withdrawal(r.ETHZRC20, *receipt, "withdraw") // verify the withdraw value + r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "withdraw") if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 064163a30b..620db45e33 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -3,12 +3,13 @@ package e2etests import ( "context" "fmt" - "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" "math/big" "os/exec" "time" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -105,10 +106,10 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) //txERC20Deposit := newRunner.DepositERC20() + newRunner.ProduceBlocks(34) newRunner.WaitForMinedCCTX(txEtherDeposit) - //newRunner.WaitForMinedCCTX(txERC20Deposit) - // withdraw Zeta, Ethers and ERC20 to the new chain + //TestZetaWithdraw(r, []string{"1000000000000000000"}) TestEtherWithdraw(newRunner, []string{"10000000000000000"}) //TestERC20Withdraw(r, []string{"1000000000000000000"}) diff --git a/e2e/e2etests/test_zeta_withdraw.go b/e2e/e2etests/test_zeta_withdraw.go index fd5d91cd14..f750b9ad14 100644 --- a/e2e/e2etests/test_zeta_withdraw.go +++ b/e2e/e2etests/test_zeta_withdraw.go @@ -85,6 +85,7 @@ func TestZetaWithdraw(r *runner.E2ERunner, args []string) { } r.Logger.Info("waiting for cctx status to change to final...") + r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "zeta withdraw") if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 046e14d706..1da5d43070 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -3,11 +3,13 @@ package runner import ( "fmt" "math/big" + "time" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" "github.com/zeta-chain/zetacore/e2e/utils" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -40,6 +42,19 @@ func (runner *E2ERunner) WaitForMinedCCTX(txHash ethcommon.Hash) { } } +func (runner *E2ERunner) ProduceBlocks(n int) { + smallAmount := big.NewInt(1e12) + randomAddress := sample.EthAddress() + for i := 0; i < n; i++ { + _, err := runner.SendEther(randomAddress, smallAmount, nil) + if err != nil { + runner.Logger.Print("Error sending ether: %s", err.Error()) + } + waitTime := time.Duration(1) * time.Second + time.Sleep(waitTime) + } +} + // SendZetaOnEvm sends ZETA to an address on EVM // this allows the ZETA contract deployer to funds other accounts on EVM func (runner *E2ERunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount int64) *ethtypes.Transaction { From 3bd7ac6f700d8e945a7d36053b57269081fd492d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 20 Mar 2024 02:05:27 -0400 Subject: [PATCH 10/35] add erc20 withdraw with lower amount of 0.01 --- e2e/e2etests/test_migrate_chain_support.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 620db45e33..94956b5ab5 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -112,7 +112,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { //TestZetaWithdraw(r, []string{"1000000000000000000"}) TestEtherWithdraw(newRunner, []string{"10000000000000000"}) - //TestERC20Withdraw(r, []string{"1000000000000000000"}) + TestERC20Withdraw(r, []string{"10000000000000000"}) } // configureEVM2 takes a runner and configures it to use the additional EVM localnet From 5ae0a4b88b51ad72f33dcd19f1c60072685c9566 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 20 Mar 2024 02:41:15 -0400 Subject: [PATCH 11/35] comment failing erc20 withdraw --- e2e/e2etests/test_migrate_chain_support.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 94956b5ab5..8a7e4ba615 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -110,9 +110,9 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { newRunner.WaitForMinedCCTX(txEtherDeposit) // withdraw Zeta, Ethers and ERC20 to the new chain - //TestZetaWithdraw(r, []string{"1000000000000000000"}) + //TestZetaWithdraw(newRunner, []string{"10000000000000000"}) TestEtherWithdraw(newRunner, []string{"10000000000000000"}) - TestERC20Withdraw(r, []string{"10000000000000000"}) + //TestERC20Withdraw(newRunner, []string{"10000000000000000"}) } // configureEVM2 takes a runner and configures it to use the additional EVM localnet From 0edb592e539fb2245d7db087f99aef2960d17de2 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 13:31:48 +0100 Subject: [PATCH 12/35] use new tx format --- zetaclient/evm/evm_signer.go | 42 +++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 3692dd666e..4890d64284 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -107,7 +107,18 @@ func (signer *Signer) Sign( height uint64, ) (*ethtypes.Transaction, []byte, []byte, error) { log.Debug().Msgf("TSS SIGNER: %s", signer.tssSigner.Pubkey()) - tx := ethtypes.NewTransaction(nonce, to, big.NewInt(0), gasLimit, gasPrice, data) + + tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + ChainID: big.NewInt(signer.chain.ChainId), + Nonce: nonce, + To: &to, + Value: big.NewInt(0), + Gas: gasLimit, + GasTipCap: gasPrice, + GasFeeCap: gasPrice, + Data: data, + }) + hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") @@ -215,7 +226,18 @@ func (signer *Signer) SignRevertTx(txData *OutBoundTransactionData) (*ethtypes.T // SignCancelTx signs a transaction from TSS address to itself with a zero amount in order to increment the nonce func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint64) (*ethtypes.Transaction, error) { - tx := ethtypes.NewTransaction(nonce, signer.tssSigner.EVMAddress(), big.NewInt(0), 21000, gasPrice, nil) + to := signer.tssSigner.EVMAddress() + tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + ChainID: big.NewInt(signer.chain.ChainId), + Nonce: nonce, + To: &to, + Value: big.NewInt(0), + Gas: 21000, + GasTipCap: gasPrice, + GasFeeCap: gasPrice, + Data: nil, + }) + hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") if err != nil { @@ -237,7 +259,17 @@ func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint6 // SignWithdrawTx signs a withdrawal transaction sent from the TSS address to the destination func (signer *Signer) SignWithdrawTx(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { - tx := ethtypes.NewTransaction(txData.nonce, txData.to, txData.amount, 21000, txData.gasPrice, nil) + tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + ChainID: big.NewInt(signer.chain.ChainId), + Nonce: txData.nonce, + To: &txData.to, + Value: txData.amount, + Gas: 21000, + GasTipCap: txData.gasPrice, + GasFeeCap: txData.gasPrice, + Data: nil, + }) + hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, txData.height, txData.nonce, signer.chain, "") if err != nil { @@ -476,6 +508,10 @@ func (signer *Signer) reportToOutTxTracker(zetaBridge interfaces.ZetaCoreBridger for { // give up after 10 minutes of monitoring time.Sleep(10 * time.Second) + + report = true + break + if time.Since(tStart) > OutTxInclusionTimeout { // if tx is still pending after timeout, report to outTxTracker anyway as we cannot monitor forever if isPending { From 7d436133aa0c340bde124dbfabb09cef0406e1ad Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:10:53 +0100 Subject: [PATCH 13/35] conflict --- cmd/zetae2e/local/accounts.go | 5 +++-- contrib/localnet/docker-compose-admin.yml | 12 +----------- contrib/localnet/orchestrator/start-zetae2e.sh | 4 ++-- e2e/e2etests/test_migrate_chain_support.go | 8 ++++---- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/cmd/zetae2e/local/accounts.go b/cmd/zetae2e/local/accounts.go index f179e02859..bcdd741e7f 100644 --- a/cmd/zetae2e/local/accounts.go +++ b/cmd/zetae2e/local/accounts.go @@ -30,8 +30,9 @@ var ( UserMiscPrivateKey = "853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4" // #nosec G101 - used for testing // UserAdminAddress is the address of the account for testing admin function features - UserAdminAddress = ethcommon.HexToAddress("0xcC8487562AAc220ea4406196Ee902C7c076966af") - UserAdminPrivateKey = "95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083" // #nosec G101 - used for testing + // NOTE: this is the default account using Anvil + UserAdminAddress = ethcommon.HexToAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266") + UserAdminPrivateKey = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" // #nosec G101 - used for testing FungibleAdminMnemonic = "snow grace federal cupboard arrive fancy gym lady uniform rotate exercise either leave alien grass" // #nosec G101 - used for testing ) diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 88d380d7ef..35ab2b0c44 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -9,7 +9,7 @@ services: entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-evm"] eth2: - image: trufflesuite/ganache-cli # Replace with your custom image tag if you built your own + image: anvil:latest container_name: eth2 hostname: eth2 ports: @@ -17,16 +17,6 @@ services: networks: mynetwork: ipv4_address: 172.20.0.102 - command: ["--host", "0.0.0.0", "--chainId", "11155111", "--port", "8545", "--account", "0x95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083,100000000000000000000"] -# image: custom-geth:latest -# container_name: eth2 -# hostname: eth2 -# ports: -# - "8546:8545" -# 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"] zetaclient0: entrypoint: [ "/root/start-zetaclientd.sh", "additional-evm" ] diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 6ea77d3fcd..5e7f1a83fd 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -38,8 +38,8 @@ echo "funding deployer address 0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf with 1 geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf", value: web3.toWei(100,"ether")})' attach http://eth:8545 # unlock admin erc20 tests accounts -echo "funding deployer address 0xcC8487562AAc220ea4406196Ee902C7c076966af with 100 Ether" -geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea4406196Ee902C7c076966af", value: web3.toWei(100,"ether")})' attach http://eth:8545 +echo "funding deployer address 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", value: web3.toWei(100,"ether")})' attach http://eth:8545 # unlock the TSS account echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether" diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 8a7e4ba615..54cc9f960b 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -110,9 +110,9 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { newRunner.WaitForMinedCCTX(txEtherDeposit) // withdraw Zeta, Ethers and ERC20 to the new chain - //TestZetaWithdraw(newRunner, []string{"10000000000000000"}) - TestEtherWithdraw(newRunner, []string{"10000000000000000"}) - //TestERC20Withdraw(newRunner, []string{"10000000000000000"}) + //TestZetaWithdraw(r, []string{"1000000000000000000"}) + TestEtherWithdraw(newRunner, []string{"50000000000000000"}) + //TestERC20Withdraw(r, []string{"1000000000000000000"}) } // configureEVM2 takes a runner and configures it to use the additional EVM localnet @@ -136,7 +136,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { r.EVMAuth, r.ZEVMAuth, r.BtcRPCClient, - runner.NewLogger(false, color.FgHiYellow, "admin-evm2"), + runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), ) // All existing fields of the runner are the same except for the RPC URL and client for EVM From b58d432a3c7e76b0f35876afdff70f15e1fba9b6 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:13:30 +0100 Subject: [PATCH 14/35] remove produce block --- e2e/e2etests/test_erc20_withdraw.go | 1 - e2e/e2etests/test_eth_withdraw.go | 1 - e2e/e2etests/test_migrate_chain_support.go | 1 - e2e/e2etests/test_zeta_withdraw.go | 1 - e2e/runner/zeta.go | 18 +----------------- 5 files changed, 1 insertion(+), 21 deletions(-) diff --git a/e2e/e2etests/test_erc20_withdraw.go b/e2e/e2etests/test_erc20_withdraw.go index ef26ff73c0..26959c0eac 100644 --- a/e2e/e2etests/test_erc20_withdraw.go +++ b/e2e/e2etests/test_erc20_withdraw.go @@ -57,7 +57,6 @@ func TestERC20Withdraw(r *runner.E2ERunner, args []string) { } // verify the withdraw value - r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) verifyTransferAmountFromCCTX(r, cctx, withdrawalAmount.Int64()) } diff --git a/e2e/e2etests/test_eth_withdraw.go b/e2e/e2etests/test_eth_withdraw.go index f15de81ece..e9a4211461 100644 --- a/e2e/e2etests/test_eth_withdraw.go +++ b/e2e/e2etests/test_eth_withdraw.go @@ -56,7 +56,6 @@ func TestEtherWithdraw(r *runner.E2ERunner, args []string) { r.Logger.ZRC20Withdrawal(r.ETHZRC20, *receipt, "withdraw") // verify the withdraw value - r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "withdraw") if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 54cc9f960b..dfedf04b4f 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -106,7 +106,6 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) //txERC20Deposit := newRunner.DepositERC20() - newRunner.ProduceBlocks(34) newRunner.WaitForMinedCCTX(txEtherDeposit) // withdraw Zeta, Ethers and ERC20 to the new chain diff --git a/e2e/e2etests/test_zeta_withdraw.go b/e2e/e2etests/test_zeta_withdraw.go index f750b9ad14..fd5d91cd14 100644 --- a/e2e/e2etests/test_zeta_withdraw.go +++ b/e2e/e2etests/test_zeta_withdraw.go @@ -85,7 +85,6 @@ func TestZetaWithdraw(r *runner.E2ERunner, args []string) { } r.Logger.Info("waiting for cctx status to change to final...") - r.ProduceBlocks(34) cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "zeta withdraw") if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 1da5d43070..0a963a08ba 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -2,15 +2,12 @@ package runner import ( "fmt" - "math/big" - "time" - ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" "github.com/zeta-chain/zetacore/e2e/utils" - "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/crosschain/types" + "math/big" ) // WaitForTxReceiptOnZEVM waits for a tx receipt on ZEVM @@ -42,19 +39,6 @@ func (runner *E2ERunner) WaitForMinedCCTX(txHash ethcommon.Hash) { } } -func (runner *E2ERunner) ProduceBlocks(n int) { - smallAmount := big.NewInt(1e12) - randomAddress := sample.EthAddress() - for i := 0; i < n; i++ { - _, err := runner.SendEther(randomAddress, smallAmount, nil) - if err != nil { - runner.Logger.Print("Error sending ether: %s", err.Error()) - } - waitTime := time.Duration(1) * time.Second - time.Sleep(waitTime) - } -} - // SendZetaOnEvm sends ZETA to an address on EVM // this allows the ZETA contract deployer to funds other accounts on EVM func (runner *E2ERunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount int64) *ethtypes.Transaction { From 91f19c436b77d12dddc1d803bd39307f79f8e69c Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:08:02 +0100 Subject: [PATCH 15/35] automatic block mining anvil --- e2e/e2etests/test_migrate_chain_support.go | 10 ++++++- e2e/runner/evm.go | 35 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index dfedf04b4f..668bdff957 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -103,6 +103,11 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // wait 10 set for the chain to start time.Sleep(10 * time.Second) + // test cross-chain functionalities on the new network + // we use a Go routine to manually mine blocks because Anvil network only mine blocks on tx by default + // we need automatic block mining to get the necessary confirmations for the cross-chain functionalities + stopMining, err := newRunner.AnvilMineBlocks(EVM2RPCURL, 3) + // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) //txERC20Deposit := newRunner.DepositERC20() @@ -112,6 +117,9 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { //TestZetaWithdraw(r, []string{"1000000000000000000"}) TestEtherWithdraw(newRunner, []string{"50000000000000000"}) //TestERC20Withdraw(r, []string{"1000000000000000000"}) + + // stop mining + stopMining() } // configureEVM2 takes a runner and configures it to use the additional EVM localnet @@ -135,7 +143,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { r.EVMAuth, r.ZEVMAuth, r.BtcRPCClient, - runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), + 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 diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index dc4fb5b183..fa3291b6c4 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -1,6 +1,8 @@ package runner import ( + "github.com/ethereum/go-ethereum/rpc" + "log" "math/big" "time" @@ -255,3 +257,36 @@ func (runner *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { } runner.Logger.Info("OK: txProof verified") } + +// AnvilMineBlocks mines blocks on Anvil localnet +// the block time is provided in seconds +// the method returns a function to stop the mining +func (runner *E2ERunner) AnvilMineBlocks(url string, blockTime int) (func(), error) { + stop := make(chan struct{}) + + client, err := rpc.Dial(url) + if err != nil { + return nil, err + } + defer client.Close() + + go func() { + for { + select { + case <-stop: + return + default: + time.Sleep(time.Duration(blockTime) * time.Second) + + var result interface{} + err = client.CallContext(runner.Ctx, &result, "evm_mine") + if err != nil { + log.Fatalf("Failed to mine a new block: %v", err) + } + } + } + }() + return func() { + close(stop) + }, nil +} From 828939a0d4a2eb8e0197a0d9efe487a37c881748 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:08:29 +0100 Subject: [PATCH 16/35] add Dockerfile for anvil localnet --- contrib/localnet/anvil/Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 contrib/localnet/anvil/Dockerfile diff --git a/contrib/localnet/anvil/Dockerfile b/contrib/localnet/anvil/Dockerfile new file mode 100644 index 0000000000..6cb652251d --- /dev/null +++ b/contrib/localnet/anvil/Dockerfile @@ -0,0 +1,8 @@ +# Start from the latest Rust image as Anvil is built with Rust +FROM ghcr.io/foundry-rs/foundry:latest + +# Expose the default Anvil port +EXPOSE 8545 + +# Run Anvil with specified chain ID and a prefunded account when the container starts +ENTRYPOINT ["anvil", "--host", "0.0.0.0", "--chain-id", "11155111"] \ No newline at end of file From fb2ad231fdef222cfdd4687e5fdfb1f70a654dd1 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:14:53 +0100 Subject: [PATCH 17/35] remove chain nonce hack --- .../keeper/msg_server_reset_chain_nonce.go | 49 ------------------- .../keeper/msg_server_update_chain_params.go | 13 ----- 2 files changed, 62 deletions(-) delete mode 100644 x/observer/keeper/msg_server_reset_chain_nonce.go diff --git a/x/observer/keeper/msg_server_reset_chain_nonce.go b/x/observer/keeper/msg_server_reset_chain_nonce.go deleted file mode 100644 index 215a87df3f..0000000000 --- a/x/observer/keeper/msg_server_reset_chain_nonce.go +++ /dev/null @@ -1,49 +0,0 @@ -package keeper - -import ( - "context" - "errors" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -type MsgResetChainNonces struct { - Creator string - ChainID int64 - //ChainNonces types.ChainNonces - //PendingNonces types.PendingNonces -} - -func (k msgServer) ResetChainNonces(goCtx context.Context, msg *MsgResetChainNonces) (*types.MsgAddBlameVoteResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - tss, found := k.GetTSS(ctx) - if !found { - return nil, errors.New("no tss found") - } - - chain := common.GetChainFromChainID(msg.ChainID) - if chain == nil { - return nil, errors.New("chain not found") - } - - // set chain nonce and pending nonce - chainNonce := types.ChainNonces{ - Index: chain.ChainName.String(), - ChainId: chain.ChainId, - Nonce: 0, - // #nosec G701 always positive - FinalizedHeight: uint64(ctx.BlockHeight()), - } - k.SetChainNonces(ctx, chainNonce) - p := types.PendingNonces{ - NonceLow: 0, - NonceHigh: 0, - ChainId: chain.ChainId, - Tss: tss.TssPubkey, - } - k.SetPendingNonces(ctx, p) - - return &types.MsgAddBlameVoteResponse{}, nil -} diff --git a/x/observer/keeper/msg_server_update_chain_params.go b/x/observer/keeper/msg_server_update_chain_params.go index 0810d388d3..63b0b3b2d5 100644 --- a/x/observer/keeper/msg_server_update_chain_params.go +++ b/x/observer/keeper/msg_server_update_chain_params.go @@ -2,8 +2,6 @@ package keeper import ( "context" - "github.com/zeta-chain/zetacore/common" - sdk "github.com/cosmos/cosmos-sdk/types" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/observer/types" @@ -27,17 +25,6 @@ func (k msgServer) UpdateChainParams(goCtx context.Context, msg *types.MsgUpdate chainParamsList = types.ChainParamsList{} } - if msg.ChainParams.ChainId == common.SepoliaChain().ChainId { - _, err := k.ResetChainNonces(ctx, &MsgResetChainNonces{ - Creator: msg.Creator, - ChainID: msg.ChainParams.ChainId, - }) - if err != nil { - return nil, err - } - ctx.Logger().Info("ResetChainNonces", "ChainID", msg.ChainParams.ChainId) - } - // find chain params for the chain for i, cp := range chainParamsList.ChainParams { if cp.ChainId == msg.ChainParams.ChainId { From 78867791f44d20763503eefc898997d3f71e9cd9 Mon Sep 17 00:00:00 2001 From: skosito Date: Tue, 19 Mar 2024 16:30:18 +0100 Subject: [PATCH 18/35] Reset chain nonces --- proto/observer/tx.proto | 10 + x/observer/client/cli/tx.go | 1 + .../client/cli/tx_reset_chain_nonces.go | 58 ++ .../keeper/msg_server_reset_chain_nonces.go | 49 ++ .../msg_server_reset_chain_nonces_test.go | 143 +++++ x/observer/types/codec.go | 2 + .../types/message_reset_chain_nonces.go | 58 ++ .../types/message_reset_chain_nonces_test.go | 73 +++ x/observer/types/tx.pb.go | 555 ++++++++++++++++-- 9 files changed, 889 insertions(+), 60 deletions(-) create mode 100644 x/observer/client/cli/tx_reset_chain_nonces.go create mode 100644 x/observer/keeper/msg_server_reset_chain_nonces.go create mode 100644 x/observer/keeper/msg_server_reset_chain_nonces_test.go create mode 100644 x/observer/types/message_reset_chain_nonces.go create mode 100644 x/observer/types/message_reset_chain_nonces_test.go diff --git a/proto/observer/tx.proto b/proto/observer/tx.proto index b67e8e0741..c1e3b49d9e 100644 --- a/proto/observer/tx.proto +++ b/proto/observer/tx.proto @@ -22,6 +22,7 @@ service Msg { rpc UpdateCrosschainFlags(MsgUpdateCrosschainFlags) returns (MsgUpdateCrosschainFlagsResponse); rpc UpdateKeygen(MsgUpdateKeygen) returns (MsgUpdateKeygenResponse); rpc AddBlockHeader(MsgAddBlockHeader) returns (MsgAddBlockHeaderResponse); + rpc ResetChainNonces(MsgResetChainNonces) returns (MsgResetChainNoncesResponse); } message MsgUpdateObserver { @@ -88,3 +89,12 @@ message MsgUpdateKeygen { } message MsgUpdateKeygenResponse {} + +message MsgResetChainNonces { + string creator = 1; + int64 chain_id = 2; + uint64 chain_nonce_low = 3; + uint64 chain_nonce_high = 4; +} + +message MsgResetChainNoncesResponse {} diff --git a/x/observer/client/cli/tx.go b/x/observer/client/cli/tx.go index 7f60f10be8..f581f878b9 100644 --- a/x/observer/client/cli/tx.go +++ b/x/observer/client/cli/tx.go @@ -29,6 +29,7 @@ func GetTxCmd() *cobra.Command { CmdAddBlameVote(), CmdUpdateObserver(), CmdEncode(), + CmdResetChainNonces(), ) return cmd diff --git a/x/observer/client/cli/tx_reset_chain_nonces.go b/x/observer/client/cli/tx_reset_chain_nonces.go new file mode 100644 index 0000000000..9f1c81eccb --- /dev/null +++ b/x/observer/client/cli/tx_reset_chain_nonces.go @@ -0,0 +1,58 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func CmdResetChainNonces() *cobra.Command { + cmd := &cobra.Command{ + Use: "reset-chain-nonces [chain-id] [chain-nonce-low] [chain-nonce-high]", + Short: "Broadcast message to reset chain nonces", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + // get chainID as int64 + chainID, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + + // get chainNonceLow as uint64 + chainNonceLow, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + + // get chainNonceHigh as uint64 + chainNonceHigh, err := strconv.ParseUint(args[2], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgResetChainNonces( + clientCtx.GetFromAddress().String(), + chainID, + chainNonceLow, + chainNonceHigh, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/observer/keeper/msg_server_reset_chain_nonces.go b/x/observer/keeper/msg_server_reset_chain_nonces.go new file mode 100644 index 0000000000..64645ad4e3 --- /dev/null +++ b/x/observer/keeper/msg_server_reset_chain_nonces.go @@ -0,0 +1,49 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// ResetChainNonces handles resetting chain nonces +// Authorized: admin policy group 2 (admin update) +func (k msgServer) ResetChainNonces(goCtx context.Context, msg *types.MsgResetChainNonces) (*types.MsgResetChainNoncesResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(types.Policy_Type_group2) { + return &types.MsgResetChainNoncesResponse{}, types.ErrNotAuthorizedPolicy + } + + tss, found := k.GetTSS(ctx) + if !found { + return nil, types.ErrTssNotFound + } + + chain := common.GetChainFromChainID(msg.ChainId) + if chain == nil { + return nil, types.ErrSupportedChains + } + + // reset chain nonces + chainNonce := types.ChainNonces{ + Index: chain.ChainName.String(), + ChainId: chain.ChainId, + Nonce: msg.ChainNonceHigh, + // #nosec G701 always positive + FinalizedHeight: uint64(ctx.BlockHeight()), + } + k.SetChainNonces(ctx, chainNonce) + + // reset pending nonces + p := types.PendingNonces{ + NonceLow: int64(msg.ChainNonceLow), + NonceHigh: int64(msg.ChainNonceHigh), + ChainId: chain.ChainId, + Tss: tss.TssPubkey, + } + k.SetPendingNonces(ctx, p) + + return &types.MsgResetChainNoncesResponse{}, nil +} diff --git a/x/observer/keeper/msg_server_reset_chain_nonces_test.go b/x/observer/keeper/msg_server_reset_chain_nonces_test.go new file mode 100644 index 0000000000..fb12c70a1f --- /dev/null +++ b/x/observer/keeper/msg_server_reset_chain_nonces_test.go @@ -0,0 +1,143 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_ResetChainNonces(t *testing.T) { + t.Run("cannot reset chain nonces if not authorized", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chainId := common.GoerliLocalnetChain().ChainId + _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: sample.AccAddress(), + ChainId: chainId, + ChainNonceLow: 1, + ChainNonceHigh: 5, + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + + // group 1 should not be able to reset chain nonces + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) + + _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: sample.AccAddress(), + ChainId: chainId, + ChainNonceLow: 1, + ChainNonceHigh: 5, + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + }) + + t.Run("cannot reset chain nonces if tss not found", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + chainId := common.GoerliLocalnetChain().ChainId + _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: admin, + ChainId: chainId, + ChainNonceLow: 1, + ChainNonceHigh: 5, + }) + require.ErrorIs(t, err, types.ErrTssNotFound) + }) + + t.Run("cannot reset chain nonces if chain not supported", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + tss := sample.Tss() + k.SetTSS(ctx, tss) + + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: admin, + ChainId: 999, + ChainNonceLow: 1, + ChainNonceHigh: 5, + }) + require.ErrorIs(t, err, types.ErrSupportedChains) + }) + + t.Run("can reset chain nonces", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + tss := sample.Tss() + k.SetTSS(ctx, tss) + + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + chainId := common.GoerliLocalnetChain().ChainId + index := common.GoerliLocalnetChain().ChainName.String() + + // check existing chain nonces + _, found := k.GetChainNonces(ctx, index) + require.False(t, found) + _, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) + require.False(t, found) + + // reset chain nonces + nonceLow := 1 + nonceHigh := 5 + _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: admin, + ChainId: chainId, + ChainNonceLow: uint64(nonceLow), + ChainNonceHigh: uint64(nonceHigh), + }) + require.NoError(t, err) + + // check updated chain nonces + chainNonces, found := k.GetChainNonces(ctx, index) + require.True(t, found) + require.Equal(t, chainId, chainNonces.ChainId) + require.Equal(t, index, chainNonces.Index) + require.Equal(t, uint64(nonceHigh), chainNonces.Nonce) + + pendingNonces, found := k.GetPendingNonces(ctx, tss.TssPubkey, chainId) + require.True(t, found) + require.Equal(t, chainId, pendingNonces.ChainId) + require.Equal(t, tss.TssPubkey, pendingNonces.Tss) + require.Equal(t, int64(nonceLow), pendingNonces.NonceLow) + require.Equal(t, int64(nonceHigh), pendingNonces.NonceHigh) + + // reset nonces back to 0 + _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ + Creator: admin, + ChainId: chainId, + ChainNonceLow: uint64(0), + ChainNonceHigh: uint64(0), + }) + require.NoError(t, err) + + // check updated chain nonces + chainNonces, found = k.GetChainNonces(ctx, index) + require.True(t, found) + require.Equal(t, chainId, chainNonces.ChainId) + require.Equal(t, index, chainNonces.Index) + require.Equal(t, uint64(0), chainNonces.Nonce) + + pendingNonces, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) + require.True(t, found) + require.Equal(t, chainId, pendingNonces.ChainId) + require.Equal(t, tss.TssPubkey, pendingNonces.Tss) + require.Equal(t, int64(0), pendingNonces.NonceLow) + require.Equal(t, int64(0), pendingNonces.NonceHigh) + }) +} diff --git a/x/observer/types/codec.go b/x/observer/types/codec.go index b28c4d0041..af6e7d87a5 100644 --- a/x/observer/types/codec.go +++ b/x/observer/types/codec.go @@ -16,6 +16,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgUpdateKeygen{}, "crosschain/UpdateKeygen", nil) cdc.RegisterConcrete(&MsgAddBlockHeader{}, "crosschain/AddBlockHeader", nil) cdc.RegisterConcrete(&MsgUpdateObserver{}, "observer/UpdateObserver", nil) + cdc.RegisterConcrete(&MsgResetChainNonces{}, "observer/ResetChainNonces", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -28,6 +29,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgUpdateKeygen{}, &MsgAddBlockHeader{}, &MsgUpdateObserver{}, + &MsgResetChainNonces{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/observer/types/message_reset_chain_nonces.go b/x/observer/types/message_reset_chain_nonces.go new file mode 100644 index 0000000000..89bf5698e5 --- /dev/null +++ b/x/observer/types/message_reset_chain_nonces.go @@ -0,0 +1,58 @@ +package types + +import ( + cosmoserrors "cosmossdk.io/errors" + "github.com/zeta-chain/zetacore/common" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgResetChainNonces = "reset_chain_nonces" + +var _ sdk.Msg = &MsgResetChainNonces{} + +func NewMsgResetChainNonces(creator string, chainID int64, chainNonceLow uint64, chainNonceHigh uint64) *MsgResetChainNonces { + return &MsgResetChainNonces{ + Creator: creator, + ChainId: chainID, + ChainNonceLow: chainNonceLow, + ChainNonceHigh: chainNonceHigh, + } +} + +func (msg *MsgResetChainNonces) Route() string { + return RouterKey +} + +func (msg *MsgResetChainNonces) Type() string { + return TypeMsgResetChainNonces +} + +func (msg *MsgResetChainNonces) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgResetChainNonces) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgResetChainNonces) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + // Check if chain exists + chain := common.GetChainFromChainID(msg.ChainId) + if chain == nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidChainID, "invalid chain id (%d)", msg.ChainId) + } + + return nil +} diff --git a/x/observer/types/message_reset_chain_nonces_test.go b/x/observer/types/message_reset_chain_nonces_test.go new file mode 100644 index 0000000000..21545dc52d --- /dev/null +++ b/x/observer/types/message_reset_chain_nonces_test.go @@ -0,0 +1,73 @@ +package types_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgResetChainNonces_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg types.MsgResetChainNonces + err error + }{ + { + name: "valid message", + msg: types.MsgResetChainNonces{ + Creator: sample.AccAddress(), + ChainId: common.ExternalChainList()[0].ChainId, + ChainNonceLow: 1, + ChainNonceHigh: 5, + }, + }, + { + name: "invalid address", + msg: types.MsgResetChainNonces{ + Creator: "invalid_address", + ChainId: common.ExternalChainList()[0].ChainId, + }, + err: sdkerrors.ErrInvalidAddress, + }, + + { + name: "invalid chain ID", + msg: types.MsgResetChainNonces{ + Creator: sample.AccAddress(), + ChainId: 999, + }, + err: sdkerrors.ErrInvalidChainID, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + }) + } +} + +func TestMsgResetChainNonces_Type(t *testing.T) { + msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) + require.Equal(t, types.TypeMsgResetChainNonces, msg.Type()) +} + +func TestMsgResetChainNonces_Route(t *testing.T) { + msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) + require.Equal(t, types.RouterKey, msg.Route()) +} + +func TestMsgResetChainNonces_GetSignBytes(t *testing.T) { + msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) + require.NotPanics(t, func() { + msg.GetSignBytes() + }) +} diff --git a/x/observer/types/tx.pb.go b/x/observer/types/tx.pb.go index bd9bceaf1e..6c73455ae6 100644 --- a/x/observer/types/tx.pb.go +++ b/x/observer/types/tx.pb.go @@ -822,6 +822,110 @@ func (m *MsgUpdateKeygenResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateKeygenResponse proto.InternalMessageInfo +type MsgResetChainNonces struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ChainNonceLow uint64 `protobuf:"varint,3,opt,name=chain_nonce_low,json=chainNonceLow,proto3" json:"chain_nonce_low,omitempty"` + ChainNonceHigh uint64 `protobuf:"varint,4,opt,name=chain_nonce_high,json=chainNonceHigh,proto3" json:"chain_nonce_high,omitempty"` +} + +func (m *MsgResetChainNonces) Reset() { *m = MsgResetChainNonces{} } +func (m *MsgResetChainNonces) String() string { return proto.CompactTextString(m) } +func (*MsgResetChainNonces) ProtoMessage() {} +func (*MsgResetChainNonces) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{16} +} +func (m *MsgResetChainNonces) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgResetChainNonces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgResetChainNonces.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgResetChainNonces) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgResetChainNonces.Merge(m, src) +} +func (m *MsgResetChainNonces) XXX_Size() int { + return m.Size() +} +func (m *MsgResetChainNonces) XXX_DiscardUnknown() { + xxx_messageInfo_MsgResetChainNonces.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgResetChainNonces proto.InternalMessageInfo + +func (m *MsgResetChainNonces) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgResetChainNonces) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *MsgResetChainNonces) GetChainNonceLow() uint64 { + if m != nil { + return m.ChainNonceLow + } + return 0 +} + +func (m *MsgResetChainNonces) GetChainNonceHigh() uint64 { + if m != nil { + return m.ChainNonceHigh + } + return 0 +} + +type MsgResetChainNoncesResponse struct { +} + +func (m *MsgResetChainNoncesResponse) Reset() { *m = MsgResetChainNoncesResponse{} } +func (m *MsgResetChainNoncesResponse) String() string { return proto.CompactTextString(m) } +func (*MsgResetChainNoncesResponse) ProtoMessage() {} +func (*MsgResetChainNoncesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{17} +} +func (m *MsgResetChainNoncesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgResetChainNoncesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgResetChainNoncesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgResetChainNoncesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgResetChainNoncesResponse.Merge(m, src) +} +func (m *MsgResetChainNoncesResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgResetChainNoncesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgResetChainNoncesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgResetChainNoncesResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgUpdateObserver)(nil), "zetachain.zetacore.observer.MsgUpdateObserver") proto.RegisterType((*MsgUpdateObserverResponse)(nil), "zetachain.zetacore.observer.MsgUpdateObserverResponse") @@ -839,71 +943,78 @@ func init() { proto.RegisterType((*MsgUpdateCrosschainFlagsResponse)(nil), "zetachain.zetacore.observer.MsgUpdateCrosschainFlagsResponse") proto.RegisterType((*MsgUpdateKeygen)(nil), "zetachain.zetacore.observer.MsgUpdateKeygen") proto.RegisterType((*MsgUpdateKeygenResponse)(nil), "zetachain.zetacore.observer.MsgUpdateKeygenResponse") + proto.RegisterType((*MsgResetChainNonces)(nil), "zetachain.zetacore.observer.MsgResetChainNonces") + proto.RegisterType((*MsgResetChainNoncesResponse)(nil), "zetachain.zetacore.observer.MsgResetChainNoncesResponse") } func init() { proto.RegisterFile("observer/tx.proto", fileDescriptor_1bcd40fa296a2b1d) } var fileDescriptor_1bcd40fa296a2b1d = []byte{ - // 939 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0x36, 0xe3, 0xc4, 0x3f, 0x23, 0xd7, 0x89, 0xb7, 0x76, 0x2c, 0x2b, 0x89, 0x62, 0xf0, 0xe4, - 0xb6, 0xae, 0x14, 0x2b, 0x6d, 0x81, 0x14, 0xe8, 0xc1, 0xee, 0x8f, 0xa3, 0x06, 0xa9, 0x0d, 0x02, - 0xf5, 0xa1, 0x17, 0x62, 0xc9, 0x1d, 0x53, 0x44, 0xa8, 0x5d, 0x81, 0x4b, 0x25, 0x56, 0xd1, 0x1e, - 0xfa, 0x00, 0x45, 0xfb, 0x2a, 0x7d, 0x87, 0x1e, 0x72, 0xcc, 0xb1, 0xa7, 0xa2, 0xb0, 0x4f, 0xed, - 0x0b, 0xf4, 0x1a, 0x70, 0x49, 0xae, 0x44, 0x51, 0xa2, 0xe4, 0x9c, 0xc4, 0xdd, 0xfd, 0xe6, 0x9b, - 0xf9, 0x66, 0xbf, 0x5d, 0x2d, 0x6c, 0x08, 0x47, 0x62, 0xf8, 0x12, 0xc3, 0x66, 0x74, 0xd1, 0xe8, - 0x85, 0x22, 0x12, 0xe4, 0xde, 0x8f, 0x18, 0x51, 0xb7, 0x43, 0x7d, 0xde, 0x50, 0x5f, 0x22, 0xc4, - 0x46, 0x86, 0xaa, 0xbd, 0xef, 0x8a, 0x6e, 0x57, 0xf0, 0x66, 0xf2, 0x93, 0x44, 0xd4, 0x36, 0x3d, - 0xe1, 0x09, 0xf5, 0xd9, 0x8c, 0xbf, 0xb2, 0x59, 0x4d, 0xed, 0x04, 0xb4, 0x8b, 0xe9, 0xec, 0x43, - 0x3d, 0xeb, 0x86, 0x42, 0x4a, 0x95, 0xc7, 0x3e, 0x0f, 0xa8, 0x27, 0x53, 0xc0, 0xb6, 0x06, 0x64, - 0x1f, 0xe9, 0xc2, 0x96, 0x5e, 0xe8, 0xd1, 0x90, 0x76, 0x33, 0xfc, 0x83, 0xe1, 0x34, 0x72, 0xe6, - 0x73, 0xcf, 0xe6, 0x82, 0xbb, 0x98, 0x2d, 0x93, 0xa1, 0x40, 0x99, 0xce, 0x99, 0xff, 0x1a, 0xb0, - 0xf1, 0x5c, 0x7a, 0xdf, 0xf7, 0x18, 0x8d, 0xf0, 0x24, 0x5d, 0x27, 0x55, 0x58, 0x76, 0x43, 0xa4, - 0x91, 0x08, 0xab, 0xc6, 0xae, 0xb1, 0xb7, 0x6a, 0x65, 0x43, 0xf2, 0x08, 0x36, 0x45, 0xc0, 0xec, - 0x8c, 0xc9, 0xa6, 0x8c, 0x85, 0x28, 0x65, 0xf5, 0x86, 0x82, 0x11, 0x11, 0xb0, 0x8c, 0xe4, 0x30, - 0x59, 0x89, 0x23, 0x38, 0xbe, 0x2a, 0x46, 0x2c, 0x26, 0x11, 0x1c, 0x5f, 0x8d, 0x47, 0x9c, 0xc1, - 0x7b, 0x7d, 0x55, 0x8f, 0x1d, 0x22, 0x95, 0x82, 0x57, 0x6f, 0xee, 0x1a, 0x7b, 0xeb, 0xad, 0x83, - 0x46, 0xc9, 0x6e, 0x34, 0x32, 0x92, 0x44, 0x89, 0xa5, 0x02, 0xad, 0xb5, 0xfe, 0xc8, 0xc8, 0xbc, - 0x07, 0x3b, 0x05, 0xa9, 0x16, 0xca, 0x9e, 0xe0, 0x12, 0xcd, 0x3f, 0x92, 0x46, 0x1c, 0x32, 0x76, - 0x14, 0x08, 0xf7, 0xc5, 0x53, 0xa4, 0xac, 0xb4, 0x11, 0x3b, 0xb0, 0x92, 0x6c, 0x98, 0xcf, 0x94, - 0xf8, 0x45, 0x6b, 0x59, 0x8d, 0xdb, 0x8c, 0x3c, 0x00, 0x70, 0x62, 0x0e, 0xbb, 0x43, 0x65, 0x47, - 0xe9, 0x5c, 0xb3, 0x56, 0xd5, 0xcc, 0x53, 0x2a, 0x3b, 0xe4, 0x2e, 0x2c, 0x75, 0xd0, 0xf7, 0x3a, - 0x91, 0xd2, 0xb5, 0x68, 0xa5, 0x23, 0xf2, 0x28, 0x9e, 0x8f, 0xb3, 0x56, 0x6f, 0xed, 0x1a, 0x7b, - 0x95, 0x16, 0x69, 0xa4, 0xce, 0x4a, 0x6a, 0xf9, 0x8a, 0x46, 0xf4, 0xe8, 0xe6, 0xeb, 0xbf, 0x1f, - 0x2e, 0x58, 0x29, 0x2e, 0x15, 0x94, 0x2f, 0x59, 0x0b, 0xfa, 0x09, 0x36, 0xb5, 0xda, 0x2f, 0xe3, - 0xca, 0x4e, 0x95, 0x55, 0x4a, 0x24, 0x7d, 0x0b, 0x15, 0x77, 0x08, 0x54, 0xaa, 0x2a, 0xad, 0xbd, - 0xd2, 0xae, 0x8f, 0x10, 0x5b, 0xa3, 0xc1, 0x66, 0x1d, 0xee, 0x4f, 0xca, 0xae, 0xab, 0x7b, 0xa6, - 0xaa, 0xb3, 0xb0, 0x2b, 0x5e, 0xce, 0x59, 0xdd, 0xf4, 0x86, 0xa7, 0xc9, 0x0a, 0x64, 0x3a, 0xd9, - 0x9f, 0x06, 0xac, 0x27, 0x8d, 0x9a, 0xc3, 0xe1, 0x1f, 0xc0, 0x9d, 0x29, 0xee, 0xbe, 0x2d, 0xc6, - 0x8c, 0xfa, 0x39, 0xec, 0xa8, 0x96, 0x04, 0x3e, 0xf2, 0xc8, 0xf6, 0x42, 0xca, 0x23, 0x44, 0xbb, - 0xd7, 0x77, 0x5e, 0xe0, 0x20, 0xf5, 0xf7, 0xf6, 0x10, 0x70, 0x9c, 0xac, 0x9f, 0xaa, 0x65, 0x72, - 0x00, 0x5b, 0x94, 0x31, 0x9b, 0x0b, 0x86, 0x36, 0x75, 0x5d, 0xd1, 0xe7, 0x91, 0x2d, 0x78, 0x30, - 0x50, 0xa6, 0x58, 0xb1, 0x08, 0x65, 0xec, 0x3b, 0xc1, 0xf0, 0x30, 0x59, 0x3a, 0xe1, 0xc1, 0xc0, - 0xac, 0xc2, 0xdd, 0xbc, 0x0a, 0x2d, 0xf0, 0x37, 0x03, 0x6e, 0x67, 0x4e, 0xa0, 0x5d, 0x3c, 0x13, - 0x11, 0xbe, 0x9b, 0x75, 0x8f, 0x63, 0xeb, 0xd2, 0x2e, 0xda, 0x3e, 0x3f, 0x17, 0x4a, 0x42, 0xa5, - 0x65, 0x96, 0x3a, 0x40, 0x25, 0x4c, 0x7d, 0xb9, 0xaa, 0x62, 0xdb, 0xfc, 0x5c, 0x98, 0x3b, 0xb0, - 0x3d, 0x56, 0x90, 0x2e, 0xf6, 0xff, 0x1b, 0x50, 0x1d, 0x7a, 0x43, 0xdf, 0x7c, 0xdf, 0xc4, 0x17, - 0x5f, 0x49, 0xd5, 0x1f, 0xc2, 0x1d, 0x5f, 0xb6, 0xb9, 0x23, 0xfa, 0x9c, 0x7d, 0xcd, 0xa9, 0x13, - 0x20, 0x53, 0x05, 0xae, 0x58, 0x85, 0x79, 0xb2, 0x0f, 0x1b, 0xbe, 0x3c, 0xe9, 0x47, 0x39, 0x70, - 0xd2, 0xd8, 0xe2, 0x02, 0xe9, 0xc0, 0x96, 0x47, 0xe5, 0x69, 0xe8, 0xbb, 0xd8, 0xe6, 0x71, 0x3a, - 0x89, 0xaa, 0x98, 0xf4, 0x1c, 0xb6, 0x4a, 0xf5, 0x1f, 0x4f, 0x8a, 0xb4, 0x26, 0x13, 0x92, 0x9f, - 0xe1, 0xbe, 0x33, 0x3c, 0xaa, 0x67, 0x18, 0xfa, 0xe7, 0xbe, 0x4b, 0x23, 0x5f, 0x24, 0xea, 0xab, - 0x4b, 0x2a, 0xe1, 0x93, 0x19, 0x0d, 0x9f, 0x4e, 0x60, 0x95, 0xd2, 0x9b, 0x26, 0xec, 0x4e, 0x6b, - 0xbc, 0xde, 0x9d, 0x43, 0xe5, 0xa4, 0x04, 0xf3, 0x0c, 0x07, 0x1e, 0xf2, 0x92, 0x3d, 0xd9, 0x84, - 0x5b, 0x2a, 0x61, 0x6a, 0xa3, 0x64, 0x90, 0xee, 0xfd, 0x28, 0x45, 0xc6, 0xde, 0xfa, 0x6f, 0x19, - 0x16, 0x9f, 0x4b, 0x8f, 0x08, 0xa8, 0x8c, 0x9e, 0xc6, 0x8f, 0x4a, 0x15, 0xe7, 0x4d, 0x5f, 0x7b, - 0x7c, 0x0d, 0x70, 0x96, 0x98, 0x5c, 0xc0, 0xfa, 0xd8, 0x7f, 0x5c, 0x63, 0x16, 0x4d, 0x1e, 0x5f, - 0xfb, 0xec, 0x7a, 0x78, 0x9d, 0xf9, 0x17, 0x03, 0x36, 0x8a, 0xb7, 0xf0, 0xc1, 0x7c, 0x6c, 0x23, - 0x21, 0xb5, 0x27, 0xd7, 0x0e, 0xc9, 0xd5, 0x50, 0xbc, 0x6b, 0x67, 0xd6, 0x50, 0x08, 0x99, 0x5d, - 0xc3, 0xd4, 0x4b, 0x98, 0x84, 0xb0, 0x96, 0xbb, 0x9f, 0xf6, 0xe7, 0xd8, 0x46, 0x8d, 0xae, 0x7d, - 0x72, 0x1d, 0xb4, 0xce, 0xf9, 0xab, 0x01, 0x5b, 0x93, 0xef, 0x99, 0x4f, 0xe7, 0x6c, 0x66, 0x3e, - 0xac, 0xf6, 0xc5, 0x3b, 0x85, 0x8d, 0xf6, 0x20, 0x77, 0xb2, 0xf6, 0xe7, 0xa3, 0x4b, 0xd0, 0xb3, - 0x7b, 0x30, 0xe9, 0xc8, 0xc5, 0xce, 0x1f, 0x7b, 0xd4, 0x34, 0xe6, 0xea, 0xa5, 0xc6, 0xcf, 0x76, - 0xfe, 0xe4, 0x17, 0xc8, 0x51, 0xfb, 0xf5, 0x65, 0xdd, 0x78, 0x73, 0x59, 0x37, 0xfe, 0xb9, 0xac, - 0x1b, 0xbf, 0x5f, 0xd5, 0x17, 0xde, 0x5c, 0xd5, 0x17, 0xfe, 0xba, 0xaa, 0x2f, 0xfc, 0xd0, 0xf4, - 0xfc, 0xa8, 0xd3, 0x77, 0xe2, 0x07, 0x4e, 0x33, 0x66, 0xfc, 0x58, 0x91, 0x37, 0x33, 0xf2, 0xe6, - 0x45, 0x73, 0xf8, 0x54, 0x1d, 0xf4, 0x50, 0x3a, 0x4b, 0xea, 0xb5, 0xfa, 0xf8, 0x6d, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x9f, 0xe7, 0x2f, 0x7d, 0xa4, 0x0b, 0x00, 0x00, + // 1022 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcb, 0x6e, 0xdb, 0x46, + 0x14, 0x35, 0x63, 0xc7, 0xb1, 0xaf, 0x1c, 0x3f, 0x26, 0x76, 0x2c, 0xcb, 0xb1, 0x62, 0x70, 0x51, + 0xa8, 0xad, 0x2b, 0xd9, 0x4a, 0x5b, 0x34, 0x05, 0xba, 0xb0, 0xfb, 0xb0, 0xd5, 0x34, 0xb1, 0x41, + 0xa0, 0x5e, 0x74, 0x43, 0x8c, 0x38, 0x63, 0x92, 0x08, 0x35, 0x23, 0x70, 0xa8, 0xd8, 0x2a, 0xda, + 0x02, 0xfd, 0x80, 0xa2, 0xfd, 0x80, 0xfe, 0x44, 0xff, 0xa1, 0x8b, 0x2c, 0xb3, 0xec, 0xaa, 0x28, + 0xec, 0x55, 0xfb, 0x03, 0xdd, 0x06, 0x1c, 0x92, 0x23, 0x51, 0x94, 0x28, 0xc9, 0x2b, 0x72, 0xe6, + 0x9e, 0x7b, 0xee, 0x63, 0xce, 0x3c, 0x60, 0x8d, 0x37, 0x05, 0xf5, 0x5f, 0x51, 0xbf, 0x16, 0x5c, + 0x55, 0xdb, 0x3e, 0x0f, 0x38, 0xda, 0xfe, 0x9e, 0x06, 0xd8, 0x72, 0xb0, 0xcb, 0xaa, 0xf2, 0x8f, + 0xfb, 0xb4, 0x9a, 0xa0, 0x4a, 0x0f, 0x2c, 0xde, 0x6a, 0x71, 0x56, 0x8b, 0x3e, 0x91, 0x47, 0x69, + 0xdd, 0xe6, 0x36, 0x97, 0xbf, 0xb5, 0xf0, 0x2f, 0x99, 0x55, 0xd4, 0x4d, 0x0f, 0xb7, 0x68, 0x3c, + 0xfb, 0x58, 0xcd, 0x5a, 0x3e, 0x17, 0x42, 0xc6, 0x31, 0x2f, 0x3c, 0x6c, 0x8b, 0x18, 0xb0, 0xa9, + 0x00, 0xc9, 0x4f, 0x6c, 0xd8, 0x50, 0x86, 0x36, 0xf6, 0x71, 0x2b, 0xc1, 0xef, 0xf4, 0xa6, 0x29, + 0x23, 0x2e, 0xb3, 0x4d, 0xc6, 0x99, 0x45, 0x13, 0x33, 0xea, 0x15, 0x28, 0xe2, 0x39, 0xfd, 0x5f, + 0x0d, 0xd6, 0x9e, 0x0b, 0xfb, 0xdb, 0x36, 0xc1, 0x01, 0x3d, 0x8d, 0xed, 0xa8, 0x08, 0xf7, 0x2c, + 0x9f, 0xe2, 0x80, 0xfb, 0x45, 0x6d, 0x57, 0xab, 0x2c, 0x1a, 0xc9, 0x10, 0xed, 0xc3, 0x3a, 0xf7, + 0x88, 0x99, 0x30, 0x99, 0x98, 0x10, 0x9f, 0x0a, 0x51, 0xbc, 0x23, 0x61, 0x88, 0x7b, 0x24, 0x21, + 0x39, 0x8c, 0x2c, 0xa1, 0x07, 0xa3, 0x97, 0x59, 0x8f, 0xd9, 0xc8, 0x83, 0xd1, 0xcb, 0x41, 0x8f, + 0x73, 0xb8, 0xdf, 0x91, 0xf9, 0x98, 0x3e, 0xc5, 0x82, 0xb3, 0xe2, 0xdc, 0xae, 0x56, 0x59, 0xae, + 0x1f, 0x54, 0x73, 0x56, 0xa3, 0x9a, 0x90, 0x44, 0x95, 0x18, 0xd2, 0xd1, 0x58, 0xea, 0xf4, 0x8d, + 0xf4, 0x6d, 0xd8, 0xca, 0x94, 0x6a, 0x50, 0xd1, 0xe6, 0x4c, 0x50, 0xfd, 0x8f, 0xa8, 0x11, 0x87, + 0x84, 0x1c, 0x79, 0xdc, 0x7a, 0x79, 0x42, 0x31, 0xc9, 0x6d, 0xc4, 0x16, 0x2c, 0x44, 0x0b, 0xe6, + 0x12, 0x59, 0xfc, 0xac, 0x71, 0x4f, 0x8e, 0x1b, 0x04, 0xed, 0x00, 0x34, 0x43, 0x0e, 0xd3, 0xc1, + 0xc2, 0x91, 0x75, 0x2e, 0x19, 0x8b, 0x72, 0xe6, 0x04, 0x0b, 0x07, 0x3d, 0x84, 0x79, 0x87, 0xba, + 0xb6, 0x13, 0xc8, 0xba, 0x66, 0x8d, 0x78, 0x84, 0xf6, 0xc3, 0xf9, 0x30, 0x6a, 0xf1, 0xee, 0xae, + 0x56, 0x29, 0xd4, 0x51, 0x35, 0x56, 0x56, 0x94, 0xcb, 0x17, 0x38, 0xc0, 0x47, 0x73, 0xaf, 0xff, + 0x7e, 0x3c, 0x63, 0xc4, 0xb8, 0xb8, 0xa0, 0x74, 0xca, 0xaa, 0xa0, 0x1f, 0x60, 0x5d, 0x55, 0xfb, + 0x79, 0x98, 0xd9, 0x99, 0x94, 0x4a, 0x4e, 0x49, 0x5f, 0x43, 0xc1, 0xea, 0x01, 0x65, 0x55, 0x85, + 0x7a, 0x25, 0xb7, 0xeb, 0x7d, 0xc4, 0x46, 0xbf, 0xb3, 0x5e, 0x86, 0x47, 0xc3, 0xa2, 0xab, 0xec, + 0x9e, 0xc9, 0xec, 0x0c, 0xda, 0xe2, 0xaf, 0x26, 0xcc, 0x6e, 0x74, 0xc3, 0xe3, 0x60, 0x19, 0x32, + 0x15, 0xec, 0x4f, 0x0d, 0x96, 0xa3, 0x46, 0x4d, 0xa0, 0xf0, 0x77, 0x61, 0x75, 0x84, 0xba, 0x57, + 0xf8, 0x80, 0x50, 0x3f, 0x85, 0x2d, 0xd9, 0x12, 0xcf, 0xa5, 0x2c, 0x30, 0x6d, 0x1f, 0xb3, 0x80, + 0x52, 0xb3, 0xdd, 0x69, 0xbe, 0xa4, 0xdd, 0x58, 0xdf, 0x9b, 0x3d, 0xc0, 0x71, 0x64, 0x3f, 0x93, + 0x66, 0x74, 0x00, 0x1b, 0x98, 0x10, 0x93, 0x71, 0x42, 0x4d, 0x6c, 0x59, 0xbc, 0xc3, 0x02, 0x93, + 0x33, 0xaf, 0x2b, 0x45, 0xb1, 0x60, 0x20, 0x4c, 0xc8, 0x0b, 0x4e, 0xe8, 0x61, 0x64, 0x3a, 0x65, + 0x5e, 0x57, 0x2f, 0xc2, 0xc3, 0x74, 0x15, 0xaa, 0xc0, 0x5f, 0x35, 0x58, 0x49, 0x94, 0x80, 0x5b, + 0xf4, 0x9c, 0x07, 0xf4, 0x76, 0xd2, 0x3d, 0x0e, 0xa5, 0x8b, 0x5b, 0xd4, 0x74, 0xd9, 0x05, 0x97, + 0x25, 0x14, 0xea, 0x7a, 0xae, 0x02, 0x64, 0xc0, 0x58, 0x97, 0x8b, 0xd2, 0xb7, 0xc1, 0x2e, 0xb8, + 0xbe, 0x05, 0x9b, 0x03, 0x09, 0xa9, 0x64, 0xff, 0xbf, 0x03, 0xc5, 0x9e, 0x36, 0xd4, 0xc9, 0xf7, + 0x55, 0x78, 0xf0, 0xe5, 0x64, 0xfd, 0x1e, 0xac, 0xba, 0xa2, 0xc1, 0x9a, 0xbc, 0xc3, 0xc8, 0x97, + 0x0c, 0x37, 0x3d, 0x4a, 0x64, 0x82, 0x0b, 0x46, 0x66, 0x1e, 0xed, 0xc1, 0x9a, 0x2b, 0x4e, 0x3b, + 0x41, 0x0a, 0x1c, 0x35, 0x36, 0x6b, 0x40, 0x0e, 0x6c, 0xd8, 0x58, 0x9c, 0xf9, 0xae, 0x45, 0x1b, + 0x2c, 0x0c, 0x27, 0xa8, 0x4c, 0x26, 0xde, 0x87, 0xf5, 0xdc, 0xfa, 0x8f, 0x87, 0x79, 0x1a, 0xc3, + 0x09, 0xd1, 0x8f, 0xf0, 0xa8, 0xd9, 0xdb, 0xaa, 0xe7, 0xd4, 0x77, 0x2f, 0x5c, 0x0b, 0x07, 0x2e, + 0x8f, 0xaa, 0x2f, 0xce, 0xcb, 0x80, 0x4f, 0xc7, 0x34, 0x7c, 0x34, 0x81, 0x91, 0x4b, 0xaf, 0xeb, + 0xb0, 0x3b, 0xaa, 0xf1, 0x6a, 0x75, 0x0e, 0xa5, 0x92, 0x22, 0xcc, 0x33, 0xda, 0xb5, 0x29, 0xcb, + 0x59, 0x93, 0x75, 0xb8, 0x2b, 0x03, 0xc6, 0x32, 0x8a, 0x06, 0xf1, 0xda, 0xf7, 0x53, 0x28, 0xf6, + 0xdf, 0x35, 0x78, 0x20, 0xb7, 0xaa, 0xa0, 0x81, 0xdc, 0xa9, 0x2f, 0xe4, 0x05, 0x75, 0x3b, 0xb1, + 0xbe, 0x03, 0x2b, 0x91, 0x49, 0xde, 0x72, 0xa6, 0xc7, 0x2f, 0xa5, 0x20, 0xe6, 0x8c, 0xfb, 0x96, + 0xa2, 0xfe, 0x86, 0x5f, 0xa2, 0x0a, 0xac, 0xf6, 0xe3, 0x1c, 0xd7, 0x76, 0xa4, 0x18, 0xe6, 0x8c, + 0xe5, 0x1e, 0xf0, 0xc4, 0xb5, 0x1d, 0x7d, 0x07, 0xb6, 0x87, 0x64, 0x97, 0x64, 0x5f, 0xff, 0x6f, + 0x01, 0x66, 0x9f, 0x0b, 0x1b, 0x71, 0x28, 0xf4, 0x9f, 0x25, 0xef, 0xe7, 0xae, 0x57, 0x7a, 0xcb, + 0x96, 0x9e, 0x4c, 0x01, 0x4e, 0x02, 0xa3, 0x2b, 0x58, 0x1e, 0xb8, 0xa1, 0xab, 0xe3, 0x68, 0xd2, + 0xf8, 0xd2, 0xc7, 0xd3, 0xe1, 0x55, 0xe4, 0x9f, 0x35, 0x58, 0xcb, 0xde, 0x21, 0x07, 0x93, 0xb1, + 0xf5, 0xb9, 0x94, 0x9e, 0x4e, 0xed, 0x92, 0xca, 0x21, 0x7b, 0x53, 0x8c, 0xcd, 0x21, 0xe3, 0x32, + 0x3e, 0x87, 0x91, 0x57, 0x08, 0xf2, 0x61, 0x29, 0x75, 0xba, 0xee, 0x4d, 0xb0, 0x8c, 0x0a, 0x5d, + 0xfa, 0x70, 0x1a, 0xb4, 0x8a, 0xf9, 0x8b, 0x06, 0x1b, 0xc3, 0x4f, 0xc9, 0x8f, 0x26, 0x6c, 0x66, + 0xda, 0xad, 0xf4, 0xd9, 0xad, 0xdc, 0xfa, 0x7b, 0x90, 0x3a, 0x17, 0xf6, 0x26, 0xa3, 0x8b, 0xd0, + 0xe3, 0x7b, 0x30, 0xec, 0xc0, 0x08, 0x95, 0x3f, 0xf0, 0x24, 0xab, 0x4e, 0xd4, 0x4b, 0x85, 0x1f, + 0xaf, 0xfc, 0xe1, 0xef, 0x27, 0xf4, 0x13, 0xac, 0x66, 0x8e, 0xa9, 0xfd, 0xf1, 0x02, 0x4a, 0x7b, + 0x94, 0x3e, 0x99, 0xd6, 0x23, 0x89, 0x7f, 0xd4, 0x78, 0x7d, 0x5d, 0xd6, 0xde, 0x5c, 0x97, 0xb5, + 0x7f, 0xae, 0xcb, 0xda, 0x6f, 0x37, 0xe5, 0x99, 0x37, 0x37, 0xe5, 0x99, 0xbf, 0x6e, 0xca, 0x33, + 0xdf, 0xd5, 0x6c, 0x37, 0x70, 0x3a, 0xcd, 0xf0, 0x79, 0x58, 0x0b, 0x39, 0x3f, 0x90, 0xf4, 0xb5, + 0x84, 0xbe, 0x76, 0x55, 0xeb, 0x3d, 0xf4, 0xbb, 0x6d, 0x2a, 0x9a, 0xf3, 0xf2, 0xad, 0xff, 0xe4, + 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x00, 0x12, 0xf4, 0xe2, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -926,6 +1037,7 @@ type MsgClient interface { UpdateCrosschainFlags(ctx context.Context, in *MsgUpdateCrosschainFlags, opts ...grpc.CallOption) (*MsgUpdateCrosschainFlagsResponse, error) UpdateKeygen(ctx context.Context, in *MsgUpdateKeygen, opts ...grpc.CallOption) (*MsgUpdateKeygenResponse, error) AddBlockHeader(ctx context.Context, in *MsgAddBlockHeader, opts ...grpc.CallOption) (*MsgAddBlockHeaderResponse, error) + ResetChainNonces(ctx context.Context, in *MsgResetChainNonces, opts ...grpc.CallOption) (*MsgResetChainNoncesResponse, error) } type msgClient struct { @@ -1008,6 +1120,15 @@ func (c *msgClient) AddBlockHeader(ctx context.Context, in *MsgAddBlockHeader, o return out, nil } +func (c *msgClient) ResetChainNonces(ctx context.Context, in *MsgResetChainNonces, opts ...grpc.CallOption) (*MsgResetChainNoncesResponse, error) { + out := new(MsgResetChainNoncesResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Msg/ResetChainNonces", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AddObserver(context.Context, *MsgAddObserver) (*MsgAddObserverResponse, error) @@ -1018,6 +1139,7 @@ type MsgServer interface { UpdateCrosschainFlags(context.Context, *MsgUpdateCrosschainFlags) (*MsgUpdateCrosschainFlagsResponse, error) UpdateKeygen(context.Context, *MsgUpdateKeygen) (*MsgUpdateKeygenResponse, error) AddBlockHeader(context.Context, *MsgAddBlockHeader) (*MsgAddBlockHeaderResponse, error) + ResetChainNonces(context.Context, *MsgResetChainNonces) (*MsgResetChainNoncesResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1048,6 +1170,9 @@ func (*UnimplementedMsgServer) UpdateKeygen(ctx context.Context, req *MsgUpdateK func (*UnimplementedMsgServer) AddBlockHeader(ctx context.Context, req *MsgAddBlockHeader) (*MsgAddBlockHeaderResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddBlockHeader not implemented") } +func (*UnimplementedMsgServer) ResetChainNonces(ctx context.Context, req *MsgResetChainNonces) (*MsgResetChainNoncesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetChainNonces not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -1197,6 +1322,24 @@ func _Msg_AddBlockHeader_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Msg_ResetChainNonces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgResetChainNonces) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ResetChainNonces(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Msg/ResetChainNonces", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ResetChainNonces(ctx, req.(*MsgResetChainNonces)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.observer.Msg", HandlerType: (*MsgServer)(nil), @@ -1233,6 +1376,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "AddBlockHeader", Handler: _Msg_AddBlockHeader_Handler, }, + { + MethodName: "ResetChainNonces", + Handler: _Msg_ResetChainNonces_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "observer/tx.proto", @@ -1813,6 +1960,74 @@ func (m *MsgUpdateKeygenResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgResetChainNonces) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgResetChainNonces) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgResetChainNonces) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ChainNonceHigh != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ChainNonceHigh)) + i-- + dAtA[i] = 0x20 + } + if m.ChainNonceLow != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ChainNonceLow)) + i-- + dAtA[i] = 0x18 + } + if m.ChainId != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x10 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgResetChainNoncesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgResetChainNoncesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgResetChainNoncesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -2063,6 +2278,37 @@ func (m *MsgUpdateKeygenResponse) Size() (n int) { return n } +func (m *MsgResetChainNonces) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.ChainId != 0 { + n += 1 + sovTx(uint64(m.ChainId)) + } + if m.ChainNonceLow != 0 { + n += 1 + sovTx(uint64(m.ChainNonceLow)) + } + if m.ChainNonceHigh != 0 { + n += 1 + sovTx(uint64(m.ChainNonceHigh)) + } + return n +} + +func (m *MsgResetChainNoncesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3635,6 +3881,195 @@ func (m *MsgUpdateKeygenResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgResetChainNonces) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgResetChainNonces: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgResetChainNonces: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainNonceLow", wireType) + } + m.ChainNonceLow = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainNonceLow |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainNonceHigh", wireType) + } + m.ChainNonceHigh = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainNonceHigh |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgResetChainNoncesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgResetChainNoncesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgResetChainNoncesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From ffb532c5a9bbf8c4e17a13857b56b182c2bd1b8e Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 14:25:40 +0100 Subject: [PATCH 19/35] add the reset chain nonce message --- e2e/e2etests/test_migrate_chain_support.go | 20 +- .../keeper/msg_server_reset_chain_nonces.go | 7 +- .../msg_server_reset_chain_nonces_test.go | 271 +++++++++--------- 3 files changed, 152 insertions(+), 146 deletions(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 668bdff957..e3cc96053d 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -94,6 +94,17 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } newRunner.ETHZRC20 = ethZRC20 + // set the chain nonces for the new chain + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgResetChainNonces( + adminAddr, + chainParams.ChainId, + 0, + 0, + )) + if err != nil { + panic(err) + } + // restart ZetaClient to pick up the new chain r.Logger.Print("🔄 restarting ZetaClient to pick up the new chain") if err := restartZetaClient(); err != nil { @@ -112,12 +123,15 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { txEtherDeposit := newRunner.DepositEther(false) //txERC20Deposit := newRunner.DepositERC20() newRunner.WaitForMinedCCTX(txEtherDeposit) - // withdraw Zeta, Ethers and ERC20 to the new chain - //TestZetaWithdraw(r, []string{"1000000000000000000"}) + // perform withdrawals on the new chain + TestZetaWithdraw(r, []string{"1000000000000000000"}) TestEtherWithdraw(newRunner, []string{"50000000000000000"}) //TestERC20Withdraw(r, []string{"1000000000000000000"}) + // finally try to deposit Zeta back + TestZetaDeposit(newRunner, []string{"100000000000000000"}) + // stop mining stopMining() } @@ -143,7 +157,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { r.EVMAuth, r.ZEVMAuth, r.BtcRPCClient, - runner.NewLogger(false, color.FgHiYellow, "admin-evm2"), + runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), ) // All existing fields of the runner are the same except for the RPC URL and client for EVM diff --git a/x/observer/keeper/msg_server_reset_chain_nonces.go b/x/observer/keeper/msg_server_reset_chain_nonces.go index 64645ad4e3..4f2591472a 100644 --- a/x/observer/keeper/msg_server_reset_chain_nonces.go +++ b/x/observer/keeper/msg_server_reset_chain_nonces.go @@ -2,6 +2,7 @@ package keeper import ( "context" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/common" @@ -9,10 +10,12 @@ import ( ) // ResetChainNonces handles resetting chain nonces -// Authorized: admin policy group 2 (admin update) +// Authorized: policy group admin func (k msgServer) ResetChainNonces(goCtx context.Context, msg *types.MsgResetChainNonces) (*types.MsgResetChainNoncesResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(types.Policy_Type_group2) { + + // check permission + if !k.GetAuthorityKeeper().IsAuthorized(ctx, msg.Creator, authoritytypes.PolicyType_groupAdmin) { return &types.MsgResetChainNoncesResponse{}, types.ErrNotAuthorizedPolicy } diff --git a/x/observer/keeper/msg_server_reset_chain_nonces_test.go b/x/observer/keeper/msg_server_reset_chain_nonces_test.go index fb12c70a1f..1702e05615 100644 --- a/x/observer/keeper/msg_server_reset_chain_nonces_test.go +++ b/x/observer/keeper/msg_server_reset_chain_nonces_test.go @@ -1,143 +1,132 @@ package keeper_test -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/common" - keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/testutil/sample" - "github.com/zeta-chain/zetacore/x/observer/keeper" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func TestMsgServer_ResetChainNonces(t *testing.T) { - t.Run("cannot reset chain nonces if not authorized", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - srv := keeper.NewMsgServerImpl(*k) - - chainId := common.GoerliLocalnetChain().ChainId - _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: sample.AccAddress(), - ChainId: chainId, - ChainNonceLow: 1, - ChainNonceHigh: 5, - }) - require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) - - // group 1 should not be able to reset chain nonces - admin := sample.AccAddress() - setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) - - _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: sample.AccAddress(), - ChainId: chainId, - ChainNonceLow: 1, - ChainNonceHigh: 5, - }) - require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) - }) - - t.Run("cannot reset chain nonces if tss not found", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - srv := keeper.NewMsgServerImpl(*k) - - admin := sample.AccAddress() - setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) - - chainId := common.GoerliLocalnetChain().ChainId - _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: admin, - ChainId: chainId, - ChainNonceLow: 1, - ChainNonceHigh: 5, - }) - require.ErrorIs(t, err, types.ErrTssNotFound) - }) - - t.Run("cannot reset chain nonces if chain not supported", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - srv := keeper.NewMsgServerImpl(*k) - tss := sample.Tss() - k.SetTSS(ctx, tss) - - admin := sample.AccAddress() - setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) - - _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: admin, - ChainId: 999, - ChainNonceLow: 1, - ChainNonceHigh: 5, - }) - require.ErrorIs(t, err, types.ErrSupportedChains) - }) - - t.Run("can reset chain nonces", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - srv := keeper.NewMsgServerImpl(*k) - tss := sample.Tss() - k.SetTSS(ctx, tss) - - admin := sample.AccAddress() - setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) - - chainId := common.GoerliLocalnetChain().ChainId - index := common.GoerliLocalnetChain().ChainName.String() - - // check existing chain nonces - _, found := k.GetChainNonces(ctx, index) - require.False(t, found) - _, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) - require.False(t, found) - - // reset chain nonces - nonceLow := 1 - nonceHigh := 5 - _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: admin, - ChainId: chainId, - ChainNonceLow: uint64(nonceLow), - ChainNonceHigh: uint64(nonceHigh), - }) - require.NoError(t, err) - - // check updated chain nonces - chainNonces, found := k.GetChainNonces(ctx, index) - require.True(t, found) - require.Equal(t, chainId, chainNonces.ChainId) - require.Equal(t, index, chainNonces.Index) - require.Equal(t, uint64(nonceHigh), chainNonces.Nonce) - - pendingNonces, found := k.GetPendingNonces(ctx, tss.TssPubkey, chainId) - require.True(t, found) - require.Equal(t, chainId, pendingNonces.ChainId) - require.Equal(t, tss.TssPubkey, pendingNonces.Tss) - require.Equal(t, int64(nonceLow), pendingNonces.NonceLow) - require.Equal(t, int64(nonceHigh), pendingNonces.NonceHigh) - - // reset nonces back to 0 - _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ - Creator: admin, - ChainId: chainId, - ChainNonceLow: uint64(0), - ChainNonceHigh: uint64(0), - }) - require.NoError(t, err) - - // check updated chain nonces - chainNonces, found = k.GetChainNonces(ctx, index) - require.True(t, found) - require.Equal(t, chainId, chainNonces.ChainId) - require.Equal(t, index, chainNonces.Index) - require.Equal(t, uint64(0), chainNonces.Nonce) - - pendingNonces, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) - require.True(t, found) - require.Equal(t, chainId, pendingNonces.ChainId) - require.Equal(t, tss.TssPubkey, pendingNonces.Tss) - require.Equal(t, int64(0), pendingNonces.NonceLow) - require.Equal(t, int64(0), pendingNonces.NonceHigh) - }) -} +// TODO: Adapt the test with the admin module refactoring +//func TestMsgServer_ResetChainNonces(t *testing.T) { +// t.Run("cannot reset chain nonces if not authorized", func(t *testing.T) { +// k, ctx := keepertest.ObserverKeeper(t) +// srv := keeper.NewMsgServerImpl(*k) +// +// chainId := common.GoerliLocalnetChain().ChainId +// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: sample.AccAddress(), +// ChainId: chainId, +// ChainNonceLow: 1, +// ChainNonceHigh: 5, +// }) +// require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) +// +// // group 1 should not be able to reset chain nonces +// admin := sample.AccAddress() +// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) +// +// _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: sample.AccAddress(), +// ChainId: chainId, +// ChainNonceLow: 1, +// ChainNonceHigh: 5, +// }) +// require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) +// }) +// +// t.Run("cannot reset chain nonces if tss not found", func(t *testing.T) { +// k, ctx := keepertest.ObserverKeeper(t) +// srv := keeper.NewMsgServerImpl(*k) +// +// admin := sample.AccAddress() +// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) +// +// chainId := common.GoerliLocalnetChain().ChainId +// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: admin, +// ChainId: chainId, +// ChainNonceLow: 1, +// ChainNonceHigh: 5, +// }) +// require.ErrorIs(t, err, types.ErrTssNotFound) +// }) +// +// t.Run("cannot reset chain nonces if chain not supported", func(t *testing.T) { +// k, ctx := keepertest.ObserverKeeper(t) +// srv := keeper.NewMsgServerImpl(*k) +// tss := sample.Tss() +// k.SetTSS(ctx, tss) +// +// admin := sample.AccAddress() +// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) +// +// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: admin, +// ChainId: 999, +// ChainNonceLow: 1, +// ChainNonceHigh: 5, +// }) +// require.ErrorIs(t, err, types.ErrSupportedChains) +// }) +// +// t.Run("can reset chain nonces", func(t *testing.T) { +// k, ctx := keepertest.ObserverKeeper(t) +// srv := keeper.NewMsgServerImpl(*k) +// tss := sample.Tss() +// k.SetTSS(ctx, tss) +// +// admin := sample.AccAddress() +// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) +// +// chainId := common.GoerliLocalnetChain().ChainId +// index := common.GoerliLocalnetChain().ChainName.String() +// +// // check existing chain nonces +// _, found := k.GetChainNonces(ctx, index) +// require.False(t, found) +// _, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) +// require.False(t, found) +// +// // reset chain nonces +// nonceLow := 1 +// nonceHigh := 5 +// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: admin, +// ChainId: chainId, +// ChainNonceLow: uint64(nonceLow), +// ChainNonceHigh: uint64(nonceHigh), +// }) +// require.NoError(t, err) +// +// // check updated chain nonces +// chainNonces, found := k.GetChainNonces(ctx, index) +// require.True(t, found) +// require.Equal(t, chainId, chainNonces.ChainId) +// require.Equal(t, index, chainNonces.Index) +// require.Equal(t, uint64(nonceHigh), chainNonces.Nonce) +// +// pendingNonces, found := k.GetPendingNonces(ctx, tss.TssPubkey, chainId) +// require.True(t, found) +// require.Equal(t, chainId, pendingNonces.ChainId) +// require.Equal(t, tss.TssPubkey, pendingNonces.Tss) +// require.Equal(t, int64(nonceLow), pendingNonces.NonceLow) +// require.Equal(t, int64(nonceHigh), pendingNonces.NonceHigh) +// +// // reset nonces back to 0 +// _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ +// Creator: admin, +// ChainId: chainId, +// ChainNonceLow: uint64(0), +// ChainNonceHigh: uint64(0), +// }) +// require.NoError(t, err) +// +// // check updated chain nonces +// chainNonces, found = k.GetChainNonces(ctx, index) +// require.True(t, found) +// require.Equal(t, chainId, chainNonces.ChainId) +// require.Equal(t, index, chainNonces.Index) +// require.Equal(t, uint64(0), chainNonces.Nonce) +// +// pendingNonces, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) +// require.True(t, found) +// require.Equal(t, chainId, pendingNonces.ChainId) +// require.Equal(t, tss.TssPubkey, pendingNonces.Tss) +// require.Equal(t, int64(0), pendingNonces.NonceLow) +// require.Equal(t, int64(0), pendingNonces.NonceHigh) +// }) +//} From b08692fa2fd78cd67875abba23f9adc71fd9a032 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 16:21:31 +0100 Subject: [PATCH 20/35] various fixes for Zeta --- e2e/e2etests/test_migrate_chain_support.go | 105 +++++++++++++++++++-- zetaclient/evm/evm_signer.go | 3 - 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index e3cc96053d..51e040284b 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -2,9 +2,12 @@ package e2etests import ( "context" + "encoding/json" "fmt" + sdktypes "github.com/cosmos/cosmos-sdk/types" "math/big" "os/exec" + "strings" "time" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" @@ -45,15 +48,21 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { panic(err) } newRunner.SetupEVM(false) + + // mint some ERC20 newRunner.MintERC20OnEvm(10000) + // we deploy connectorETH in this test to simulate a new "canonical" chain emitting ZETA + // to represent the ZETA already existing on ZetaChain we manually send the minted ZETA to the connector + newRunner.SendZetaOnEvm(newRunner.ConnectorEthAddr, 20_000_000_000) + // update the chain params to set up the chain - chainParams := getNewEVMChainParams(r) - adminAddr, err := r.ZetaTxServer.GetAccountAddressFromName(utils.FungibleAdminName) + chainParams := getNewEVMChainParams(newRunner) + adminAddr, err := newRunner.ZetaTxServer.GetAccountAddressFromName(utils.FungibleAdminName) if err != nil { panic(err) } - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgUpdateChainParams( + _, err = newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgUpdateChainParams( adminAddr, chainParams, )) @@ -65,7 +74,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { if err != nil { panic(err) } - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( + _, err = newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( adminAddr, "", chainParams.ChainId, @@ -80,7 +89,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } // set the gas token in the runner - ethZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chainParams.ChainId)) + ethZRC20Addr, err := newRunner.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chainParams.ChainId)) if err != nil { panic(err) } @@ -94,6 +103,36 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } newRunner.ETHZRC20 = ethZRC20 + // deploy erc20 zrc20 + res, err := newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( + adminAddr, + newRunner.ERC20Addr.Hex(), + common.SepoliaChain().ChainId, + 18, + "USDT", + "USDT", + common.CoinType_ERC20, + 100000, + )) + if err != nil { + panic(err) + } + + // fetch the erc20 zrc20 contract address and remove the quotes + erc20zrc20Addr, err := fetchAttribute(res, "Contract") + if err != nil { + panic(err) + } + if !ethcommon.IsHexAddress(erc20zrc20Addr) { + panic(fmt.Errorf("invalid contract address: %s", erc20zrc20Addr)) + } + + erc20ZRC20, err := zrc20.NewZRC20(ethcommon.HexToAddress(erc20zrc20Addr), newRunner.ZEVMClient) + if err != nil { + panic(err) + } + newRunner.ERC20ZRC20 = erc20ZRC20 + // set the chain nonces for the new chain _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgResetChainNonces( adminAddr, @@ -121,13 +160,14 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) - //txERC20Deposit := newRunner.DepositERC20() newRunner.WaitForMinedCCTX(txEtherDeposit) + txERC20Deposit := newRunner.DepositERC20() + newRunner.WaitForMinedCCTX(txERC20Deposit) // perform withdrawals on the new chain - TestZetaWithdraw(r, []string{"1000000000000000000"}) + TestZetaWithdraw(newRunner, []string{"10000000000000000000"}) TestEtherWithdraw(newRunner, []string{"50000000000000000"}) - //TestERC20Withdraw(r, []string{"1000000000000000000"}) + TestERC20Withdraw(r, []string{"100000"}) // finally try to deposit Zeta back TestZetaDeposit(newRunner, []string{"100000000000000000"}) @@ -157,7 +197,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { r.EVMAuth, r.ZEVMAuth, r.BtcRPCClient, - runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), + 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 @@ -241,3 +281,50 @@ func restartZetaClient() error { } return nil } + +// fetchAttribute fetches the attribute from the tx response +// TODO: use tx server +func fetchAttribute(res *sdktypes.TxResponse, key string) (string, error) { + var logs []messageLog + err := json.Unmarshal([]byte(res.RawLog), &logs) + if err != nil { + return "", err + } + + var attributes []string + for _, log := range logs { + for _, event := range log.Events { + for _, attr := range event.Attributes { + attributes = append(attributes, attr.Key) + if strings.EqualFold(attr.Key, key) { + address := attr.Value + + if len(address) < 2 { + return "", fmt.Errorf("invalid address: %s", address) + } + + // trim the quotes + address = address[1 : len(address)-1] + + return address, nil + } + } + } + } + + return "", fmt.Errorf("attribute %s not found, attributes: %+v", key, attributes) +} + +type messageLog struct { + Events []event `json:"events"` +} + +type event struct { + Type string `json:"type"` + Attributes []attribute `json:"attributes"` +} + +type attribute struct { + Key string `json:"key"` + Value string `json:"value"` +} diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 4890d64284..6c7e182bf9 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -509,9 +509,6 @@ func (signer *Signer) reportToOutTxTracker(zetaBridge interfaces.ZetaCoreBridger // give up after 10 minutes of monitoring time.Sleep(10 * time.Second) - report = true - break - if time.Since(tStart) > OutTxInclusionTimeout { // if tx is still pending after timeout, report to outTxTracker anyway as we cannot monitor forever if isPending { From 28533b631c5415be95c90cda87690d2c78dda1dd Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 20 Mar 2024 16:24:00 +0100 Subject: [PATCH 21/35] make generage --- docs/cli/zetacored/zetacored_tx_observer.md | 1 + ...etacored_tx_observer_reset-chain-nonces.md | 52 +++++++++++++++++ docs/openapi/openapi.swagger.yaml | 2 + docs/spec/observer/messages.md | 14 +++++ e2e/e2etests/test_migrate_chain_support.go | 3 +- e2e/runner/evm.go | 3 +- e2e/runner/zeta.go | 3 +- typescript/observer/tx_pb.d.ts | 58 +++++++++++++++++++ .../keeper/msg_server_reset_chain_nonces.go | 1 + .../keeper/msg_server_update_chain_params.go | 1 + 10 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 docs/cli/zetacored/zetacored_tx_observer_reset-chain-nonces.md diff --git a/docs/cli/zetacored/zetacored_tx_observer.md b/docs/cli/zetacored/zetacored_tx_observer.md index 5340a1041a..de1145c512 100644 --- a/docs/cli/zetacored/zetacored_tx_observer.md +++ b/docs/cli/zetacored/zetacored_tx_observer.md @@ -29,6 +29,7 @@ zetacored tx observer [flags] * [zetacored tx observer add-observer](zetacored_tx_observer_add-observer.md) - Broadcast message add-observer * [zetacored tx observer encode](zetacored_tx_observer_encode.md) - Encode a json string into hex * [zetacored tx observer remove-chain-params](zetacored_tx_observer_remove-chain-params.md) - Broadcast message to remove chain params +* [zetacored tx observer reset-chain-nonces](zetacored_tx_observer_reset-chain-nonces.md) - Broadcast message to reset chain nonces * [zetacored tx observer update-chain-params](zetacored_tx_observer_update-chain-params.md) - Broadcast message updateChainParams * [zetacored tx observer update-crosschain-flags](zetacored_tx_observer_update-crosschain-flags.md) - Update crosschain flags * [zetacored tx observer update-keygen](zetacored_tx_observer_update-keygen.md) - command to update the keygen block via a group proposal diff --git a/docs/cli/zetacored/zetacored_tx_observer_reset-chain-nonces.md b/docs/cli/zetacored/zetacored_tx_observer_reset-chain-nonces.md new file mode 100644 index 0000000000..6a858d99b2 --- /dev/null +++ b/docs/cli/zetacored/zetacored_tx_observer_reset-chain-nonces.md @@ -0,0 +1,52 @@ +# tx observer reset-chain-nonces + +Broadcast message to reset chain nonces + +``` +zetacored tx observer reset-chain-nonces [chain-id] [chain-nonce-low] [chain-nonce-high] [flags] +``` + +### Options + +``` + -a, --account-number uint The account number of the signing account (offline mode only) + --aux Generate aux signer data instead of sending a tx + -b, --broadcast-mode string Transaction broadcasting mode (sync|async|block) + --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) + --fee-granter string Fee granter grants fees for the transaction + --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer + --fees string Fees to pay along with transaction; eg: 10uatom + --from string Name or address of private key with which to sign + --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) + --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) + --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) + --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) + -h, --help help for reset-chain-nonces + --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) + --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used + --ledger Use a connected Ledger device + --node string [host]:[port] to tendermint rpc interface for this chain + --note string Note to add a description to the transaction (previously --memo) + --offline Offline mode (does not allow any online functionality) + -o, --output string Output format (text|json) + -s, --sequence uint The sequence number of the signing account (offline mode only) + --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature + --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height + --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator + -y, --yes Skip tx broadcasting prompt confirmation +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored tx observer](zetacored_tx_observer.md) - observer transactions subcommands + diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 8e2cb02f21..dc7759c5a2 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -54364,6 +54364,8 @@ definitions: type: object observerMsgRemoveChainParamsResponse: type: object + observerMsgResetChainNoncesResponse: + type: object observerMsgUpdateChainParamsResponse: type: object observerMsgUpdateCrosschainFlagsResponse: diff --git a/docs/spec/observer/messages.md b/docs/spec/observer/messages.md index ebf63c3781..508225f6af 100644 --- a/docs/spec/observer/messages.md +++ b/docs/spec/observer/messages.md @@ -108,3 +108,17 @@ message MsgAddBlockHeader { } ``` +## MsgResetChainNonces + +ResetChainNonces handles resetting chain nonces +Authorized: policy group admin + +```proto +message MsgResetChainNonces { + string creator = 1; + int64 chain_id = 2; + uint64 chain_nonce_low = 3; + uint64 chain_nonce_high = 4; +} +``` + diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 51e040284b..bfccb35b1f 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -4,12 +4,13 @@ import ( "context" "encoding/json" "fmt" - sdktypes "github.com/cosmos/cosmos-sdk/types" "math/big" "os/exec" "strings" "time" + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index fa3291b6c4..ac816b07c6 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -1,11 +1,12 @@ package runner import ( - "github.com/ethereum/go-ethereum/rpc" "log" "math/big" "time" + "github.com/ethereum/go-ethereum/rpc" + ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 0a963a08ba..046e14d706 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -2,12 +2,13 @@ package runner import ( "fmt" + "math/big" + ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/x/crosschain/types" - "math/big" ) // WaitForTxReceiptOnZEVM waits for a tx receipt on ZEVM diff --git a/typescript/observer/tx_pb.d.ts b/typescript/observer/tx_pb.d.ts index 3684b24d01..3543427ae3 100644 --- a/typescript/observer/tx_pb.d.ts +++ b/typescript/observer/tx_pb.d.ts @@ -450,3 +450,61 @@ export declare class MsgUpdateKeygenResponse extends Message | undefined, b: MsgUpdateKeygenResponse | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.observer.MsgResetChainNonces + */ +export declare class MsgResetChainNonces extends Message { + /** + * @generated from field: string creator = 1; + */ + creator: string; + + /** + * @generated from field: int64 chain_id = 2; + */ + chainId: bigint; + + /** + * @generated from field: uint64 chain_nonce_low = 3; + */ + chainNonceLow: bigint; + + /** + * @generated from field: uint64 chain_nonce_high = 4; + */ + chainNonceHigh: bigint; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.MsgResetChainNonces"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgResetChainNonces; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgResetChainNonces; + + static fromJsonString(jsonString: string, options?: Partial): MsgResetChainNonces; + + static equals(a: MsgResetChainNonces | PlainMessage | undefined, b: MsgResetChainNonces | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.MsgResetChainNoncesResponse + */ +export declare class MsgResetChainNoncesResponse extends Message { + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.MsgResetChainNoncesResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgResetChainNoncesResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgResetChainNoncesResponse; + + static fromJsonString(jsonString: string, options?: Partial): MsgResetChainNoncesResponse; + + static equals(a: MsgResetChainNoncesResponse | PlainMessage | undefined, b: MsgResetChainNoncesResponse | PlainMessage | undefined): boolean; +} + diff --git a/x/observer/keeper/msg_server_reset_chain_nonces.go b/x/observer/keeper/msg_server_reset_chain_nonces.go index 4f2591472a..84a5aac743 100644 --- a/x/observer/keeper/msg_server_reset_chain_nonces.go +++ b/x/observer/keeper/msg_server_reset_chain_nonces.go @@ -2,6 +2,7 @@ package keeper import ( "context" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/observer/keeper/msg_server_update_chain_params.go b/x/observer/keeper/msg_server_update_chain_params.go index 63b0b3b2d5..3a2f0dea14 100644 --- a/x/observer/keeper/msg_server_update_chain_params.go +++ b/x/observer/keeper/msg_server_update_chain_params.go @@ -2,6 +2,7 @@ package keeper import ( "context" + sdk "github.com/cosmos/cosmos-sdk/types" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/observer/types" From f34ad216590def19308deffc84bb07b03993c653 Mon Sep 17 00:00:00 2001 From: lumtis Date: Fri, 22 Mar 2024 15:31:13 +0100 Subject: [PATCH 22/35] remove reset message --- .../client/cli/tx_reset_chain_nonces.go | 58 -------- .../msg_server_reset_chain_nonces_test.go | 132 ------------------ .../types/message_reset_chain_nonces.go | 58 -------- .../types/message_reset_chain_nonces_test.go | 73 ---------- 4 files changed, 321 deletions(-) delete mode 100644 x/observer/client/cli/tx_reset_chain_nonces.go delete mode 100644 x/observer/keeper/msg_server_reset_chain_nonces_test.go delete mode 100644 x/observer/types/message_reset_chain_nonces.go delete mode 100644 x/observer/types/message_reset_chain_nonces_test.go diff --git a/x/observer/client/cli/tx_reset_chain_nonces.go b/x/observer/client/cli/tx_reset_chain_nonces.go deleted file mode 100644 index 9f1c81eccb..0000000000 --- a/x/observer/client/cli/tx_reset_chain_nonces.go +++ /dev/null @@ -1,58 +0,0 @@ -package cli - -import ( - "strconv" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func CmdResetChainNonces() *cobra.Command { - cmd := &cobra.Command{ - Use: "reset-chain-nonces [chain-id] [chain-nonce-low] [chain-nonce-high]", - Short: "Broadcast message to reset chain nonces", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - // get chainID as int64 - chainID, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - return err - } - - // get chainNonceLow as uint64 - chainNonceLow, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return err - } - - // get chainNonceHigh as uint64 - chainNonceHigh, err := strconv.ParseUint(args[2], 10, 64) - if err != nil { - return err - } - - msg := types.NewMsgResetChainNonces( - clientCtx.GetFromAddress().String(), - chainID, - chainNonceLow, - chainNonceHigh, - ) - if err := msg.ValidateBasic(); err != nil { - return err - } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} diff --git a/x/observer/keeper/msg_server_reset_chain_nonces_test.go b/x/observer/keeper/msg_server_reset_chain_nonces_test.go deleted file mode 100644 index 1702e05615..0000000000 --- a/x/observer/keeper/msg_server_reset_chain_nonces_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package keeper_test - -// TODO: Adapt the test with the admin module refactoring -//func TestMsgServer_ResetChainNonces(t *testing.T) { -// t.Run("cannot reset chain nonces if not authorized", func(t *testing.T) { -// k, ctx := keepertest.ObserverKeeper(t) -// srv := keeper.NewMsgServerImpl(*k) -// -// chainId := common.GoerliLocalnetChain().ChainId -// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: sample.AccAddress(), -// ChainId: chainId, -// ChainNonceLow: 1, -// ChainNonceHigh: 5, -// }) -// require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) -// -// // group 1 should not be able to reset chain nonces -// admin := sample.AccAddress() -// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) -// -// _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: sample.AccAddress(), -// ChainId: chainId, -// ChainNonceLow: 1, -// ChainNonceHigh: 5, -// }) -// require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) -// }) -// -// t.Run("cannot reset chain nonces if tss not found", func(t *testing.T) { -// k, ctx := keepertest.ObserverKeeper(t) -// srv := keeper.NewMsgServerImpl(*k) -// -// admin := sample.AccAddress() -// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) -// -// chainId := common.GoerliLocalnetChain().ChainId -// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: admin, -// ChainId: chainId, -// ChainNonceLow: 1, -// ChainNonceHigh: 5, -// }) -// require.ErrorIs(t, err, types.ErrTssNotFound) -// }) -// -// t.Run("cannot reset chain nonces if chain not supported", func(t *testing.T) { -// k, ctx := keepertest.ObserverKeeper(t) -// srv := keeper.NewMsgServerImpl(*k) -// tss := sample.Tss() -// k.SetTSS(ctx, tss) -// -// admin := sample.AccAddress() -// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) -// -// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: admin, -// ChainId: 999, -// ChainNonceLow: 1, -// ChainNonceHigh: 5, -// }) -// require.ErrorIs(t, err, types.ErrSupportedChains) -// }) -// -// t.Run("can reset chain nonces", func(t *testing.T) { -// k, ctx := keepertest.ObserverKeeper(t) -// srv := keeper.NewMsgServerImpl(*k) -// tss := sample.Tss() -// k.SetTSS(ctx, tss) -// -// admin := sample.AccAddress() -// setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) -// -// chainId := common.GoerliLocalnetChain().ChainId -// index := common.GoerliLocalnetChain().ChainName.String() -// -// // check existing chain nonces -// _, found := k.GetChainNonces(ctx, index) -// require.False(t, found) -// _, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) -// require.False(t, found) -// -// // reset chain nonces -// nonceLow := 1 -// nonceHigh := 5 -// _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: admin, -// ChainId: chainId, -// ChainNonceLow: uint64(nonceLow), -// ChainNonceHigh: uint64(nonceHigh), -// }) -// require.NoError(t, err) -// -// // check updated chain nonces -// chainNonces, found := k.GetChainNonces(ctx, index) -// require.True(t, found) -// require.Equal(t, chainId, chainNonces.ChainId) -// require.Equal(t, index, chainNonces.Index) -// require.Equal(t, uint64(nonceHigh), chainNonces.Nonce) -// -// pendingNonces, found := k.GetPendingNonces(ctx, tss.TssPubkey, chainId) -// require.True(t, found) -// require.Equal(t, chainId, pendingNonces.ChainId) -// require.Equal(t, tss.TssPubkey, pendingNonces.Tss) -// require.Equal(t, int64(nonceLow), pendingNonces.NonceLow) -// require.Equal(t, int64(nonceHigh), pendingNonces.NonceHigh) -// -// // reset nonces back to 0 -// _, err = srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ -// Creator: admin, -// ChainId: chainId, -// ChainNonceLow: uint64(0), -// ChainNonceHigh: uint64(0), -// }) -// require.NoError(t, err) -// -// // check updated chain nonces -// chainNonces, found = k.GetChainNonces(ctx, index) -// require.True(t, found) -// require.Equal(t, chainId, chainNonces.ChainId) -// require.Equal(t, index, chainNonces.Index) -// require.Equal(t, uint64(0), chainNonces.Nonce) -// -// pendingNonces, found = k.GetPendingNonces(ctx, tss.TssPubkey, chainId) -// require.True(t, found) -// require.Equal(t, chainId, pendingNonces.ChainId) -// require.Equal(t, tss.TssPubkey, pendingNonces.Tss) -// require.Equal(t, int64(0), pendingNonces.NonceLow) -// require.Equal(t, int64(0), pendingNonces.NonceHigh) -// }) -//} diff --git a/x/observer/types/message_reset_chain_nonces.go b/x/observer/types/message_reset_chain_nonces.go deleted file mode 100644 index 89bf5698e5..0000000000 --- a/x/observer/types/message_reset_chain_nonces.go +++ /dev/null @@ -1,58 +0,0 @@ -package types - -import ( - cosmoserrors "cosmossdk.io/errors" - "github.com/zeta-chain/zetacore/common" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -const TypeMsgResetChainNonces = "reset_chain_nonces" - -var _ sdk.Msg = &MsgResetChainNonces{} - -func NewMsgResetChainNonces(creator string, chainID int64, chainNonceLow uint64, chainNonceHigh uint64) *MsgResetChainNonces { - return &MsgResetChainNonces{ - Creator: creator, - ChainId: chainID, - ChainNonceLow: chainNonceLow, - ChainNonceHigh: chainNonceHigh, - } -} - -func (msg *MsgResetChainNonces) Route() string { - return RouterKey -} - -func (msg *MsgResetChainNonces) Type() string { - return TypeMsgResetChainNonces -} - -func (msg *MsgResetChainNonces) GetSigners() []sdk.AccAddress { - creator, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - panic(err) - } - return []sdk.AccAddress{creator} -} - -func (msg *MsgResetChainNonces) GetSignBytes() []byte { - bz := ModuleCdc.MustMarshalJSON(msg) - return sdk.MustSortJSON(bz) -} - -func (msg *MsgResetChainNonces) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) - } - - // Check if chain exists - chain := common.GetChainFromChainID(msg.ChainId) - if chain == nil { - return cosmoserrors.Wrapf(sdkerrors.ErrInvalidChainID, "invalid chain id (%d)", msg.ChainId) - } - - return nil -} diff --git a/x/observer/types/message_reset_chain_nonces_test.go b/x/observer/types/message_reset_chain_nonces_test.go deleted file mode 100644 index 21545dc52d..0000000000 --- a/x/observer/types/message_reset_chain_nonces_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package types_test - -import ( - "testing" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/testutil/sample" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func TestMsgResetChainNonces_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg types.MsgResetChainNonces - err error - }{ - { - name: "valid message", - msg: types.MsgResetChainNonces{ - Creator: sample.AccAddress(), - ChainId: common.ExternalChainList()[0].ChainId, - ChainNonceLow: 1, - ChainNonceHigh: 5, - }, - }, - { - name: "invalid address", - msg: types.MsgResetChainNonces{ - Creator: "invalid_address", - ChainId: common.ExternalChainList()[0].ChainId, - }, - err: sdkerrors.ErrInvalidAddress, - }, - - { - name: "invalid chain ID", - msg: types.MsgResetChainNonces{ - Creator: sample.AccAddress(), - ChainId: 999, - }, - err: sdkerrors.ErrInvalidChainID, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.msg.ValidateBasic() - if tt.err != nil { - require.ErrorIs(t, err, tt.err) - return - } - require.NoError(t, err) - }) - } -} - -func TestMsgResetChainNonces_Type(t *testing.T) { - msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) - require.Equal(t, types.TypeMsgResetChainNonces, msg.Type()) -} - -func TestMsgResetChainNonces_Route(t *testing.T) { - msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) - require.Equal(t, types.RouterKey, msg.Route()) -} - -func TestMsgResetChainNonces_GetSignBytes(t *testing.T) { - msg := types.NewMsgResetChainNonces(sample.AccAddress(), 5, 1, 5) - require.NotPanics(t, func() { - msg.GetSignBytes() - }) -} From 42e87476378d1a4054ea4dd5d6e4843c04b9ca58 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 10:25:38 +0100 Subject: [PATCH 23/35] rename restart script files --- contrib/localnet/docker-compose-admin.yml | 2 +- contrib/localnet/orchestrator/Dockerfile | 2 +- .../orchestrator/Dockerfile.fastbuild | 2 +- .../restart-zetaclientd-at-upgrade.sh | 50 ++++++++++++++++++ .../restart-zetaclientd-migrate.sh | 9 ---- .../orchestrator/restart-zetaclientd.sh | 51 +++---------------- .../localnet/orchestrator/start-zetae2e.sh | 14 +---- e2e/e2etests/test_migrate_chain_support.go | 5 +- 8 files changed, 64 insertions(+), 71 deletions(-) create mode 100644 contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh delete mode 100644 contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index 35ab2b0c44..a417bb4fa8 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -6,7 +6,7 @@ version: "3" services: orchestrator: - entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin", "additional-evm"] + entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin"] eth2: image: anvil:latest diff --git a/contrib/localnet/orchestrator/Dockerfile b/contrib/localnet/orchestrator/Dockerfile index 3faed73278..e268738ef2 100644 --- a/contrib/localnet/orchestrator/Dockerfile +++ b/contrib/localnet/orchestrator/Dockerfile @@ -13,7 +13,7 @@ COPY --from=zeta /root/.ssh/localtest.pem /root/.ssh/localtest.pem COPY contrib/localnet/orchestrator/start-zetae2e.sh /work/ COPY contrib/localnet/orchestrator/restart-zetaclientd.sh /work/ -COPY contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh /work/ +COPY contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh /work/ RUN chmod +x /work/*.sh ENV GOPATH /go diff --git a/contrib/localnet/orchestrator/Dockerfile.fastbuild b/contrib/localnet/orchestrator/Dockerfile.fastbuild index e23223dab4..36cf07b8cc 100644 --- a/contrib/localnet/orchestrator/Dockerfile.fastbuild +++ b/contrib/localnet/orchestrator/Dockerfile.fastbuild @@ -13,7 +13,7 @@ COPY --from=zeta /root/.ssh/localtest.pem /root/.ssh/localtest.pem COPY contrib/localnet/orchestrator/start-zetae2e.sh /work/ COPY contrib/localnet/orchestrator/restart-zetaclientd.sh /work/ -COPY contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh /work/ +COPY contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh /work/ RUN chmod +x /work/*.sh COPY --from=zeta /usr/local/bin/zetae2e /usr/local/bin/ diff --git a/contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh b/contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh new file mode 100644 index 0000000000..7911deca01 --- /dev/null +++ b/contrib/localnet/orchestrator/restart-zetaclientd-at-upgrade.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# This script is used to restart zetaclientd after an upgrade +# It waits for the upgrade height to be reached and then restarts the zetaclientd on all nodes in the network +# It interacts with the network using the zetaclientd binary + +clibuilder() +{ + echo "" + echo "Usage: $0 -u UPGRADE_HEIGHT" + echo -e "\t-u Height of upgrade, should match governance proposal" + echo -e "\t-n Number of clients in the network" + exit 1 # Exit script after printing help +} + +while getopts "u:n:" opt +do + case "$opt" in + u ) UPGRADE_HEIGHT="$OPTARG" ;; + n ) NUM_OF_NODES="$OPTARG" ;; + ? ) clibuilder ;; # Print cliBuilder in case parameter is non-existent + esac +done + +# generate client list +START=0 +END=$((NUM_OF_NODES-1)) +CLIENT_LIST=() +for i in $(eval echo "{$START..$END}") +do + CLIENT_LIST+=("zetaclient$i") +done + +echo "$UPGRADE_HEIGHT" + +CURRENT_HEIGHT=0 + +while [[ $CURRENT_HEIGHT -lt $UPGRADE_HEIGHT ]] +do + CURRENT_HEIGHT=$(curl -s zetacore0:26657/status | jq '.result.sync_info.latest_block_height' | tr -d '"') + echo current height is "$CURRENT_HEIGHT", waiting for "$UPGRADE_HEIGHT" + sleep 5 +done + +echo upgrade height reached, restarting zetaclients + +for NODE in "${CLIENT_LIST[@]}"; do + ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem killall zetaclientd + ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem "$GOPATH/bin/new/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" +done diff --git a/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh b/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh deleted file mode 100644 index 7b3f3e0799..0000000000 --- a/contrib/localnet/orchestrator/restart-zetaclientd-migrate.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -echo restarting zetaclients - -ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem killall zetaclientd -ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem killall zetaclientd -ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" -ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" - diff --git a/contrib/localnet/orchestrator/restart-zetaclientd.sh b/contrib/localnet/orchestrator/restart-zetaclientd.sh index 7911deca01..6071b07570 100644 --- a/contrib/localnet/orchestrator/restart-zetaclientd.sh +++ b/contrib/localnet/orchestrator/restart-zetaclientd.sh @@ -1,50 +1,11 @@ #!/bin/bash -# This script is used to restart zetaclientd after an upgrade -# It waits for the upgrade height to be reached and then restarts the zetaclientd on all nodes in the network -# It interacts with the network using the zetaclientd binary +# This script immediately restarts the zetaclientd on zetaclient0 and zetaclient1 containers in the network -clibuilder() -{ - echo "" - echo "Usage: $0 -u UPGRADE_HEIGHT" - echo -e "\t-u Height of upgrade, should match governance proposal" - echo -e "\t-n Number of clients in the network" - exit 1 # Exit script after printing help -} +echo restarting zetaclients -while getopts "u:n:" opt -do - case "$opt" in - u ) UPGRADE_HEIGHT="$OPTARG" ;; - n ) NUM_OF_NODES="$OPTARG" ;; - ? ) clibuilder ;; # Print cliBuilder in case parameter is non-existent - esac -done +ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem killall zetaclientd +ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem killall zetaclientd +ssh -o "StrictHostKeyChecking no" "zetaclient0" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" +ssh -o "StrictHostKeyChecking no" "zetaclient1" -i ~/.ssh/localtest.pem "/usr/local/bin/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" -# generate client list -START=0 -END=$((NUM_OF_NODES-1)) -CLIENT_LIST=() -for i in $(eval echo "{$START..$END}") -do - CLIENT_LIST+=("zetaclient$i") -done - -echo "$UPGRADE_HEIGHT" - -CURRENT_HEIGHT=0 - -while [[ $CURRENT_HEIGHT -lt $UPGRADE_HEIGHT ]] -do - CURRENT_HEIGHT=$(curl -s zetacore0:26657/status | jq '.result.sync_info.latest_block_height' | tr -d '"') - echo current height is "$CURRENT_HEIGHT", waiting for "$UPGRADE_HEIGHT" - sleep 5 -done - -echo upgrade height reached, restarting zetaclients - -for NODE in "${CLIENT_LIST[@]}"; do - ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem killall zetaclientd - ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem "$GOPATH/bin/new/zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 &" -done diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 5e7f1a83fd..b474885be9 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -45,18 +45,6 @@ geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xf39Fd6e51aad88F6F4c echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth:8545 - -## 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-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 -## unlock the TSS account -# echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether on ETH2" -# geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth2:8545 -#fi - ### Run zetae2e command depending on the option passed if [ "$OPTION" == "upgrade" ]; then @@ -86,7 +74,7 @@ if [ "$OPTION" == "upgrade" ]; then echo "E2E setup passed, waiting for upgrade height..." # Restart zetaclients at upgrade height - /work/restart-zetaclientd.sh -u "$UPGRADE_HEIGHT" -n 2 + /work/restart-zetaclientd-at-upgrade.sh -u "$UPGRADE_HEIGHT" -n 2 echo "waiting 10 seconds for node to restart..." diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index bfccb35b1f..c691b0816f 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -158,6 +158,9 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // we use a Go routine to manually mine blocks because Anvil network only mine blocks on tx by default // we need automatic block mining to get the necessary confirmations for the cross-chain functionalities stopMining, err := newRunner.AnvilMineBlocks(EVM2RPCURL, 3) + if err != nil { + panic(err) + } // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) @@ -272,7 +275,7 @@ func getNewEVMChainParams(r *runner.E2ERunner) *observertypes.ChainParams { // restartZetaClient restarts the Zeta client func restartZetaClient() error { - sshCommandFilePath := "/work/restart-zetaclientd-migrate.sh" + sshCommandFilePath := "/work/restart-zetaclientd.sh" cmd := exec.Command("/bin/sh", sshCommandFilePath) // Execute the command From e07628862c2487ead927b39245075e4c18ea3788 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 13:42:36 +0100 Subject: [PATCH 24/35] add anvil docker image --- contrib/localnet/anvil/Dockerfile | 3 +++ contrib/localnet/docker-compose-admin.yml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/localnet/anvil/Dockerfile b/contrib/localnet/anvil/Dockerfile index 6cb652251d..5426174fdf 100644 --- a/contrib/localnet/anvil/Dockerfile +++ b/contrib/localnet/anvil/Dockerfile @@ -1,3 +1,6 @@ +# This Dockerfile is used to build a Docker image for Anvil, a localnet for testing purposes. +# Currently we directly set the chain ID to 11155111 and expose the default Anvil port specifically for the chain migration test. + # Start from the latest Rust image as Anvil is built with Rust FROM ghcr.io/foundry-rs/foundry:latest diff --git a/contrib/localnet/docker-compose-admin.yml b/contrib/localnet/docker-compose-admin.yml index a417bb4fa8..23503cf305 100644 --- a/contrib/localnet/docker-compose-admin.yml +++ b/contrib/localnet/docker-compose-admin.yml @@ -9,7 +9,8 @@ services: entrypoint: ["/work/start-zetae2e.sh", "local --skip-regular --test-admin"] eth2: - image: anvil:latest + build: + context: ./anvil container_name: eth2 hostname: eth2 ports: From 75a89ac9cb0bf6255136104cba9fc5c1df5ded37 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 13:43:16 +0100 Subject: [PATCH 25/35] add test erc20 whitelist --- cmd/zetae2e/local/local.go | 2 +- cmd/zetae2e/stress.go | 2 +- e2e/e2etests/test_migrate_chain_support.go | 163 +++++---- e2e/runner/setup_evm.go | 16 +- e2e/runner/zeta.go | 16 + e2e/txserver/zeta_tx_server.go | 16 +- e2e/utils/zetacore.go | 53 +++ proto/crosschain/events.proto | 5 + .../keeper/msg_server_whitelist_erc20.go | 15 +- x/crosschain/types/events.pb.go | 309 +++++++++++++++--- 10 files changed, 448 insertions(+), 149 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index c700285ae6..7a4208c3a9 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -188,7 +188,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if !skipSetup { logger.Print("⚙️ setting up networks") startTime := time.Now() - deployerRunner.SetupEVM(contractsDeployed) + deployerRunner.SetupEVM(contractsDeployed, true) deployerRunner.SetZEVMContracts() // NOTE: this method return an error so we handle it and panic if it occurs unlike other method that panics directly diff --git a/cmd/zetae2e/stress.go b/cmd/zetae2e/stress.go index b85d0e78d7..793b9ec3c4 100644 --- a/cmd/zetae2e/stress.go +++ b/cmd/zetae2e/stress.go @@ -155,7 +155,7 @@ func StressTest(cmd *cobra.Command, _ []string) { panic(err) } - e2eTest.SetupEVM(stressTestArgs.contractsDeployed) + e2eTest.SetupEVM(stressTestArgs.contractsDeployed, true) // If stress test is running on local docker environment if stressTestArgs.network == "LOCAL" { diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index c691b0816f..cb4790fe85 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -2,14 +2,13 @@ package e2etests import ( "context" - "encoding/json" "fmt" "math/big" "os/exec" - "strings" "time" - sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/e2e/txserver" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" @@ -48,7 +47,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { if err != nil { panic(err) } - newRunner.SetupEVM(false) + newRunner.SetupEVM(false, false) // mint some ERC20 newRunner.MintERC20OnEvm(10000) @@ -104,42 +103,23 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } newRunner.ETHZRC20 = ethZRC20 - // deploy erc20 zrc20 - res, err := newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( + // set the chain nonces for the new chain + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgResetChainNonces( adminAddr, - newRunner.ERC20Addr.Hex(), - common.SepoliaChain().ChainId, - 18, - "USDT", - "USDT", - common.CoinType_ERC20, - 100000, + chainParams.ChainId, + 0, + 0, )) if err != nil { panic(err) } - // fetch the erc20 zrc20 contract address and remove the quotes - erc20zrc20Addr, err := fetchAttribute(res, "Contract") - if err != nil { - panic(err) - } - if !ethcommon.IsHexAddress(erc20zrc20Addr) { - panic(fmt.Errorf("invalid contract address: %s", erc20zrc20Addr)) - } - - erc20ZRC20, err := zrc20.NewZRC20(ethcommon.HexToAddress(erc20zrc20Addr), newRunner.ZEVMClient) - if err != nil { - panic(err) - } - newRunner.ERC20ZRC20 = erc20ZRC20 - - // set the chain nonces for the new chain - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgResetChainNonces( + // deactivate the previous chain + chainParams = observertypes.GetDefaultGoerliLocalnetChainParams() + chainParams.IsSupported = false + _, err = newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgUpdateChainParams( adminAddr, - chainParams.ChainId, - 0, - 0, + chainParams, )) if err != nil { panic(err) @@ -154,6 +134,19 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // wait 10 set for the chain to start time.Sleep(10 * time.Second) + // emitting a withdraw with the previous chain should fail + txWithdraw, err := r.ETHZRC20.Withdraw(r.ZEVMAuth, r.DeployerAddress.Bytes(), big.NewInt(10000000000000000)) + if err == nil { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txWithdraw, r.Logger, r.ReceiptTimeout) + if receipt.Status == 1 { + panic("withdraw should have failed on the previous chain") + } else { + r.Logger.Info("withdraw failed on the previous chain as expected with receipt") + } + } else { + r.Logger.Info("withdraw failed on the previous chain as expected") + } + // test cross-chain functionalities on the new network // we use a Go routine to manually mine blocks because Anvil network only mine blocks on tx by default // we need automatic block mining to get the necessary confirmations for the cross-chain functionalities @@ -165,17 +158,63 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit Ethers and ERC20 on ZetaChain txEtherDeposit := newRunner.DepositEther(false) newRunner.WaitForMinedCCTX(txEtherDeposit) - txERC20Deposit := newRunner.DepositERC20() - newRunner.WaitForMinedCCTX(txERC20Deposit) // perform withdrawals on the new chain TestZetaWithdraw(newRunner, []string{"10000000000000000000"}) TestEtherWithdraw(newRunner, []string{"50000000000000000"}) - TestERC20Withdraw(r, []string{"100000"}) // finally try to deposit Zeta back TestZetaDeposit(newRunner, []string{"100000000000000000"}) + // ERC20 test + + // whitelist erc20 zrc20 + newRunner.Logger.Info("whitelisting ERC20 on new network") + res, err := newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, crosschaintypes.NewMsgWhitelistERC20( + adminAddr, + newRunner.ERC20Addr.Hex(), + common.SepoliaChain().ChainId, + "USDT", + "USDT", + 18, + 100000, + )) + if err != nil { + panic(err) + } + + // retrieve zrc20 and cctx from event + whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index") + if err != nil { + panic(err) + } + + erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") + if err != nil { + panic(err) + } + + // wait for the whitelist cctx to be mined + newRunner.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) + + //set erc20 zrc20 contract address + if !ethcommon.IsHexAddress(erc20zrc20Addr) { + panic(fmt.Errorf("invalid contract address: %s", erc20zrc20Addr)) + } + erc20ZRC20, err := zrc20.NewZRC20(ethcommon.HexToAddress(erc20zrc20Addr), newRunner.ZEVMClient) + if err != nil { + panic(err) + } + newRunner.ERC20ZRC20 = erc20ZRC20 + + // deposit + txERC20Deposit := newRunner.DepositERC20() + newRunner.WaitForMinedCCTX(txERC20Deposit) + + // withdraw + newRunner.Logger.Info("trying withdrawing ERC20 on new network") + TestERC20Withdraw(r, []string{"100000"}) + // stop mining stopMining() } @@ -201,7 +240,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { r.EVMAuth, r.ZEVMAuth, r.BtcRPCClient, - runner.NewLogger(false, color.FgHiYellow, "admin-evm2"), + runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), ) // All existing fields of the runner are the same except for the RPC URL and client for EVM @@ -230,8 +269,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { return newRunner, nil } -// getEVMClient get evm client -// TODO: put this logic in common with the one in cmd/zetae2e/config/clients.go +// getEVMClient get evm client from rpc and private key func getEVMClient(ctx context.Context, rpc, privKey string) (*ethclient.Client, *bind.TransactOpts, error) { evmClient, err := ethclient.Dial(rpc) if err != nil { @@ -285,50 +323,3 @@ func restartZetaClient() error { } return nil } - -// fetchAttribute fetches the attribute from the tx response -// TODO: use tx server -func fetchAttribute(res *sdktypes.TxResponse, key string) (string, error) { - var logs []messageLog - err := json.Unmarshal([]byte(res.RawLog), &logs) - if err != nil { - return "", err - } - - var attributes []string - for _, log := range logs { - for _, event := range log.Events { - for _, attr := range event.Attributes { - attributes = append(attributes, attr.Key) - if strings.EqualFold(attr.Key, key) { - address := attr.Value - - if len(address) < 2 { - return "", fmt.Errorf("invalid address: %s", address) - } - - // trim the quotes - address = address[1 : len(address)-1] - - return address, nil - } - } - } - } - - return "", fmt.Errorf("attribute %s not found, attributes: %+v", key, attributes) -} - -type messageLog struct { - Events []event `json:"events"` -} - -type event struct { - Type string `json:"type"` - Attributes []attribute `json:"attributes"` -} - -type attribute struct { - Key string `json:"key"` - Value string `json:"value"` -} diff --git a/e2e/runner/setup_evm.go b/e2e/runner/setup_evm.go index 5b95095344..3e69a71296 100644 --- a/e2e/runner/setup_evm.go +++ b/e2e/runner/setup_evm.go @@ -42,7 +42,7 @@ func (runner *E2ERunner) SetEVMContractsFromConfig() { } // SetupEVM setup contracts on EVM for e2e test -func (runner *E2ERunner) SetupEVM(contractsDeployed bool) { +func (runner *E2ERunner) SetupEVM(contractsDeployed bool, whitelistERC20 bool) { runner.Logger.Print("⚙️ setting up EVM network") startTime := time.Now() defer func() { @@ -157,12 +157,14 @@ func (runner *E2ERunner) SetupEVM(contractsDeployed bool) { // initialize custody contract runner.Logger.Info("Whitelist ERC20") - txWhitelist, err := ERC20Custody.Whitelist(runner.EVMAuth, erc20Addr) - if err != nil { - panic(err) - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txWhitelist, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ERC20 whitelist failed") + if whitelistERC20 { + txWhitelist, err := ERC20Custody.Whitelist(runner.EVMAuth, erc20Addr) + if err != nil { + panic(err) + } + if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txWhitelist, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { + panic("ERC20 whitelist failed") + } } runner.Logger.Info("Set TSS address") diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 046e14d706..d7fdbdcdf4 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -40,6 +40,22 @@ func (runner *E2ERunner) WaitForMinedCCTX(txHash ethcommon.Hash) { } } +// WaitForMinedCCTXFromIndex waits for a cctx to be mined from its index +func (runner *E2ERunner) WaitForMinedCCTXFromIndex(index string) { + defer func() { + runner.Unlock() + }() + runner.Lock() + + cctx := utils.WaitCCTXMinedByIndex(runner.Ctx, index, runner.CctxClient, runner.Logger, runner.CctxTimeout) + if cctx.CctxStatus.Status != types.CctxStatus_OutboundMined { + panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage), + ) + } +} + // SendZetaOnEvm sends ZETA to an address on EVM // this allows the ZETA contract deployer to funds other accounts on EVM func (runner *E2ERunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount int64) *ethtypes.Transaction { diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index 88aa7add33..6f38829316 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -210,7 +210,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) return "", "", "", "", "", fmt.Errorf("failed to deploy system contracts: %s", err.Error()) } - systemContractAddress, err := fetchAttribute(res, "system_contract") + systemContractAddress, err := FetchAttributeFromTxResponse(res, "system_contract") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch system contract address: %s; rawlog %s", err.Error(), res.RawLog) } @@ -222,23 +222,23 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) } // get uniswap contract addresses - uniswapV2FactoryAddr, err := fetchAttribute(res, "uniswap_v2_factory") + uniswapV2FactoryAddr, err := FetchAttributeFromTxResponse(res, "uniswap_v2_factory") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch uniswap v2 factory address: %s", err.Error()) } - uniswapV2RouterAddr, err := fetchAttribute(res, "uniswap_v2_router") + uniswapV2RouterAddr, err := FetchAttributeFromTxResponse(res, "uniswap_v2_router") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch uniswap v2 router address: %s", err.Error()) } // get zevm connector address - zevmConnectorAddr, err := fetchAttribute(res, "connector_zevm") + zevmConnectorAddr, err := FetchAttributeFromTxResponse(res, "connector_zevm") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch zevm connector address: %s, txResponse: %s", err.Error(), res.String()) } // get wzeta address - wzetaAddr, err := fetchAttribute(res, "wzeta") + wzetaAddr, err := FetchAttributeFromTxResponse(res, "wzeta") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch wzeta address: %s, txResponse: %s", err.Error(), res.String()) } @@ -289,7 +289,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) } // fetch the erc20 zrc20 contract address and remove the quotes - erc20zrc20Addr, err := fetchAttribute(res, "Contract") + erc20zrc20Addr, err := FetchAttributeFromTxResponse(res, "Contract") if err != nil { return "", "", "", "", "", fmt.Errorf("failed to fetch erc20 zrc20 contract address: %s", err.Error()) } @@ -408,8 +408,8 @@ type attribute struct { Value string `json:"value"` } -// fetchAttribute fetches the attribute from the tx response -func fetchAttribute(res *sdktypes.TxResponse, key string) (string, error) { +// FetchAttributeFromTxResponse fetches the attribute from the tx response +func FetchAttributeFromTxResponse(res *sdktypes.TxResponse, key string) (string, error) { var logs []messageLog err := json.Unmarshal([]byte(res.RawLog), &logs) if err != nil { diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 6a491d1ebd..30fa0bcf08 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -106,6 +106,59 @@ func WaitCctxsMinedByInTxHash( } } +// WaitCCTXMinedByIndex waits until cctx is mined; returns the cctxIndex +func WaitCCTXMinedByIndex( + ctx context.Context, + cctxIndex string, + cctxClient crosschaintypes.QueryClient, + logger infoLogger, + cctxTimeout time.Duration, +) *crosschaintypes.CrossChainTx { + startTime := time.Now() + + timeout := DefaultCctxTimeout + if cctxTimeout != 0 { + timeout = cctxTimeout + } + + for i := 0; ; i++ { + if time.Since(startTime) > timeout { + panic(fmt.Sprintf( + "waiting cctx timeout, cctx not mined, cctx: %s", + cctxIndex, + )) + } + time.Sleep(1 * time.Second) + + // fetch cctx by index + res, err := cctxClient.Cctx(ctx, &crosschaintypes.QueryGetCctxRequest{ + Index: cctxIndex, + }) + if err != nil { + // prevent spamming logs + if i%10 == 0 { + logger.Info("Error getting cctx by inTxHash: %s", err.Error()) + } + continue + } + cctx := res.CrossChainTx + if !IsTerminalStatus(cctx.CctxStatus.Status) { + // prevent spamming logs + if i%10 == 0 { + logger.Info( + "waiting for cctx to be mined from index: %s, cctx status: %s, message: %s", + cctxIndex, + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage, + ) + } + continue + } + + return cctx + } +} + func IsTerminalStatus(status crosschaintypes.CctxStatus) bool { return status == crosschaintypes.CctxStatus_OutboundMined || status == crosschaintypes.CctxStatus_Aborted || diff --git a/proto/crosschain/events.proto b/proto/crosschain/events.proto index 6497fd147e..34033f52bc 100644 --- a/proto/crosschain/events.proto +++ b/proto/crosschain/events.proto @@ -64,3 +64,8 @@ message EventCCTXGasPriceIncreased { string gas_price_increase = 2; string additional_fees = 3; } + +message EventERC20Whitelist { + string whitelist_cctx_index = 1; + string zrc20_address = 2; +} diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20.go b/x/crosschain/keeper/msg_server_whitelist_erc20.go index e269f2312a..ce72be26fd 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20.go @@ -5,17 +5,14 @@ import ( "fmt" "math/big" - authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/zeta-chain/zetacore/common" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" ) @@ -171,6 +168,16 @@ func (k msgServer) WhitelistERC20(goCtx context.Context, msg *types.MsgWhitelist commit() + err = ctx.EventManager().EmitTypedEvent( + &types.EventERC20Whitelist{ + Zrc20Address: zrc20Addr.Hex(), + WhitelistCctxIndex: index, + }, + ) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed to emit event") + } + return &types.MsgWhitelistERC20Response{ Zrc20Address: zrc20Addr.Hex(), CctxIndex: index, diff --git a/x/crosschain/types/events.pb.go b/x/crosschain/types/events.pb.go index 68c05a18f0..e674807f46 100644 --- a/x/crosschain/types/events.pb.go +++ b/x/crosschain/types/events.pb.go @@ -569,6 +569,58 @@ func (m *EventCCTXGasPriceIncreased) GetAdditionalFees() string { return "" } +type EventERC20Whitelist struct { + WhitelistCctxIndex string `protobuf:"bytes,1,opt,name=whitelist_cctx_index,json=whitelistCctxIndex,proto3" json:"whitelist_cctx_index,omitempty"` + Zrc20Address string `protobuf:"bytes,2,opt,name=zrc20_address,json=zrc20Address,proto3" json:"zrc20_address,omitempty"` +} + +func (m *EventERC20Whitelist) Reset() { *m = EventERC20Whitelist{} } +func (m *EventERC20Whitelist) String() string { return proto.CompactTextString(m) } +func (*EventERC20Whitelist) ProtoMessage() {} +func (*EventERC20Whitelist) Descriptor() ([]byte, []int) { + return fileDescriptor_7398db8b12b87b9e, []int{6} +} +func (m *EventERC20Whitelist) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventERC20Whitelist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventERC20Whitelist.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventERC20Whitelist) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventERC20Whitelist.Merge(m, src) +} +func (m *EventERC20Whitelist) XXX_Size() int { + return m.Size() +} +func (m *EventERC20Whitelist) XXX_DiscardUnknown() { + xxx_messageInfo_EventERC20Whitelist.DiscardUnknown(m) +} + +var xxx_messageInfo_EventERC20Whitelist proto.InternalMessageInfo + +func (m *EventERC20Whitelist) GetWhitelistCctxIndex() string { + if m != nil { + return m.WhitelistCctxIndex + } + return "" +} + +func (m *EventERC20Whitelist) GetZrc20Address() string { + if m != nil { + return m.Zrc20Address + } + return "" +} + func init() { proto.RegisterType((*EventInboundFinalized)(nil), "zetachain.zetacore.crosschain.EventInboundFinalized") proto.RegisterType((*EventZrcWithdrawCreated)(nil), "zetachain.zetacore.crosschain.EventZrcWithdrawCreated") @@ -576,53 +628,58 @@ func init() { proto.RegisterType((*EventOutboundFailure)(nil), "zetachain.zetacore.crosschain.EventOutboundFailure") proto.RegisterType((*EventOutboundSuccess)(nil), "zetachain.zetacore.crosschain.EventOutboundSuccess") proto.RegisterType((*EventCCTXGasPriceIncreased)(nil), "zetachain.zetacore.crosschain.EventCCTXGasPriceIncreased") + proto.RegisterType((*EventERC20Whitelist)(nil), "zetachain.zetacore.crosschain.EventERC20Whitelist") } func init() { proto.RegisterFile("crosschain/events.proto", fileDescriptor_7398db8b12b87b9e) } var fileDescriptor_7398db8b12b87b9e = []byte{ - // 654 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x95, 0xcf, 0x6e, 0x13, 0x3b, - 0x14, 0xc6, 0x3b, 0x6d, 0x92, 0x26, 0x6e, 0x9b, 0x5e, 0xcd, 0xed, 0xbd, 0xf5, 0x8d, 0x6e, 0xa3, - 0x52, 0x89, 0x3f, 0x0b, 0x48, 0x84, 0x78, 0x83, 0x46, 0x94, 0x56, 0x08, 0x15, 0xb5, 0x45, 0xa0, - 0x6e, 0x2c, 0xc7, 0x73, 0x98, 0xb1, 0x98, 0xb1, 0x23, 0xdb, 0xd3, 0x4e, 0xfb, 0x14, 0x88, 0xf7, - 0x40, 0xe2, 0x01, 0x78, 0x00, 0x96, 0x5d, 0xb0, 0x60, 0x89, 0xda, 0x17, 0x41, 0xb6, 0x67, 0x68, - 0x33, 0x45, 0xb0, 0x40, 0x20, 0xb1, 0x8a, 0xcf, 0x77, 0xec, 0x93, 0x9f, 0xbf, 0xe3, 0xe4, 0xa0, - 0x55, 0xa6, 0xa4, 0xd6, 0x2c, 0xa1, 0x5c, 0x0c, 0xe1, 0x08, 0x84, 0xd1, 0x83, 0x89, 0x92, 0x46, - 0x86, 0x6b, 0xa7, 0x60, 0xa8, 0xd3, 0x07, 0x6e, 0x25, 0x15, 0x0c, 0x2e, 0xf7, 0xf6, 0xfe, 0x66, - 0x32, 0xcb, 0xa4, 0x18, 0xfa, 0x0f, 0x7f, 0xa6, 0xb7, 0x12, 0xcb, 0x58, 0xba, 0xe5, 0xd0, 0xae, - 0xbc, 0xba, 0xf1, 0x71, 0x0e, 0xfd, 0xf3, 0xd0, 0x96, 0xde, 0x11, 0x63, 0x99, 0x8b, 0x68, 0x8b, - 0x0b, 0x9a, 0xf2, 0x53, 0x88, 0xc2, 0x75, 0xb4, 0x98, 0xe9, 0x98, 0x98, 0x93, 0x09, 0x90, 0x5c, - 0xa5, 0x38, 0x58, 0x0f, 0xee, 0x74, 0xf6, 0x50, 0xa6, 0xe3, 0x83, 0x93, 0x09, 0x3c, 0x53, 0x69, - 0xb8, 0x86, 0x10, 0x63, 0xa6, 0x20, 0x5c, 0x44, 0x50, 0xe0, 0x59, 0x97, 0xef, 0x58, 0x65, 0xc7, - 0x0a, 0xe1, 0xbf, 0xa8, 0xa5, 0x41, 0x44, 0xa0, 0xf0, 0x9c, 0x4b, 0x95, 0x51, 0xf8, 0x1f, 0x6a, - 0x9b, 0x82, 0x48, 0x15, 0x73, 0x81, 0x1b, 0x2e, 0x33, 0x6f, 0x8a, 0x5d, 0x1b, 0x86, 0x2b, 0xa8, - 0x49, 0xb5, 0x06, 0x83, 0x9b, 0x4e, 0xf7, 0x41, 0xf8, 0x3f, 0x42, 0x5c, 0x10, 0x53, 0x90, 0x84, - 0xea, 0x04, 0xb7, 0x5c, 0xaa, 0xcd, 0xc5, 0x41, 0xb1, 0x4d, 0x75, 0x12, 0xde, 0x42, 0xcb, 0x5c, - 0x90, 0x71, 0x2a, 0xd9, 0x2b, 0x92, 0x00, 0x8f, 0x13, 0x83, 0xe7, 0xdd, 0x96, 0x25, 0x2e, 0x36, - 0xad, 0xba, 0xed, 0xc4, 0xb0, 0x87, 0xda, 0x0a, 0x18, 0xf0, 0x23, 0x50, 0xb8, 0xed, 0x6b, 0x54, - 0x71, 0x78, 0x13, 0x75, 0xab, 0x35, 0x71, 0x16, 0xe2, 0x8e, 0x2f, 0x51, 0xa9, 0x23, 0x2b, 0xda, - 0x1b, 0xd1, 0x4c, 0xe6, 0xc2, 0x60, 0xe4, 0x6f, 0xe4, 0xa3, 0xf0, 0x36, 0x5a, 0x56, 0x90, 0xd2, - 0x13, 0x88, 0x48, 0x06, 0x5a, 0xd3, 0x18, 0xf0, 0x82, 0xdb, 0xd0, 0x2d, 0xe5, 0x27, 0x5e, 0xb5, - 0x8e, 0x09, 0x38, 0x26, 0xda, 0x50, 0x93, 0x6b, 0xbc, 0xe8, 0x1d, 0x13, 0x70, 0xbc, 0xef, 0x04, - 0x8b, 0xe1, 0x53, 0x5f, 0xcb, 0x2c, 0x79, 0x0c, 0xaf, 0x56, 0x55, 0x6e, 0xa0, 0x45, 0x6f, 0x65, - 0xc9, 0xda, 0x75, 0x9b, 0x16, 0xbc, 0xe6, 0x48, 0x37, 0xde, 0xce, 0xa2, 0x55, 0xd7, 0xd6, 0x43, - 0xc5, 0x9e, 0x73, 0x93, 0x44, 0x8a, 0x1e, 0x8f, 0x14, 0x50, 0xf3, 0x2b, 0x1b, 0x5b, 0xe7, 0x6a, - 0x5c, 0xe3, 0xaa, 0xb5, 0xb2, 0x59, 0x6b, 0xe5, 0xd5, 0x16, 0xb5, 0x7e, 0xd8, 0xa2, 0xf9, 0xef, - 0xb7, 0xa8, 0x3d, 0xd5, 0xa2, 0x69, 0xe7, 0x3b, 0x35, 0xe7, 0x37, 0xde, 0x05, 0x08, 0x7b, 0xbf, - 0xc0, 0xd0, 0xdf, 0x66, 0xd8, 0xb4, 0x1b, 0x8d, 0x9a, 0x1b, 0xd3, 0xc8, 0xcd, 0x3a, 0xf2, 0xfb, - 0x00, 0xad, 0x38, 0xe4, 0xdd, 0xdc, 0xf8, 0x9f, 0x2e, 0xe5, 0x69, 0xae, 0xe0, 0xe7, 0x71, 0xd7, - 0x10, 0x92, 0x69, 0x54, 0x7d, 0xb1, 0x47, 0xee, 0xc8, 0x34, 0x2a, 0x5f, 0xe9, 0x34, 0x57, 0xe3, - 0x1b, 0x8f, 0xf8, 0x88, 0xa6, 0x39, 0x90, 0xb2, 0x31, 0x51, 0x89, 0xbe, 0xe4, 0xd4, 0xbd, 0x52, - 0xbc, 0x8e, 0xbf, 0x9f, 0x33, 0x06, 0x5a, 0xff, 0x21, 0xf8, 0x6f, 0x02, 0xd4, 0x73, 0xf8, 0xa3, - 0xd1, 0xc1, 0x8b, 0x47, 0x54, 0x3f, 0x55, 0x9c, 0xc1, 0x8e, 0x60, 0x0a, 0xa8, 0x86, 0xa8, 0x86, - 0x18, 0xd4, 0x11, 0xef, 0xa2, 0x30, 0xa6, 0x9a, 0x4c, 0xec, 0x21, 0xc2, 0xcb, 0x53, 0xe5, 0x4d, - 0xfe, 0x8a, 0x6b, 0xd5, 0xec, 0xdf, 0x0b, 0x8d, 0x22, 0x6e, 0xb8, 0x14, 0x34, 0x25, 0x2f, 0x01, - 0xaa, 0x5b, 0x75, 0x2f, 0xe5, 0x2d, 0x00, 0xbd, 0xf9, 0xf8, 0xc3, 0x79, 0x3f, 0x38, 0x3b, 0xef, - 0x07, 0x9f, 0xcf, 0xfb, 0xc1, 0xeb, 0x8b, 0xfe, 0xcc, 0xd9, 0x45, 0x7f, 0xe6, 0xd3, 0x45, 0x7f, - 0xe6, 0xf0, 0x7e, 0xcc, 0x4d, 0x92, 0x8f, 0x07, 0x4c, 0x66, 0x43, 0x3b, 0x31, 0xee, 0xf9, 0xa1, - 0x52, 0x0d, 0x8f, 0x61, 0x31, 0xbc, 0x32, 0x6a, 0xac, 0xf5, 0x7a, 0xdc, 0x72, 0x03, 0xe2, 0xc1, - 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0x66, 0xf0, 0x4d, 0x85, 0x06, 0x00, 0x00, + // 705 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x95, 0xcf, 0x4e, 0x1b, 0x3b, + 0x14, 0xc6, 0x19, 0x48, 0x42, 0x62, 0x92, 0x70, 0x35, 0xe4, 0x5e, 0xe6, 0x46, 0x97, 0x88, 0x9b, + 0xaa, 0x7f, 0x16, 0x6d, 0x42, 0xe9, 0x13, 0x94, 0x08, 0x0a, 0xaa, 0x2a, 0x2a, 0xa0, 0xa2, 0x62, + 0x63, 0x39, 0x33, 0xa7, 0x33, 0x56, 0x27, 0x76, 0x64, 0x7b, 0xc8, 0xc0, 0x53, 0x54, 0x7d, 0x8f, + 0x4a, 0x7d, 0x80, 0x3e, 0x40, 0x97, 0x2c, 0xba, 0xe8, 0xb2, 0x82, 0x17, 0xa9, 0x6c, 0xcf, 0x00, + 0x19, 0xaa, 0x76, 0x51, 0xb5, 0x52, 0x57, 0xf1, 0xf9, 0x8e, 0xe7, 0xe4, 0xe7, 0xef, 0x9b, 0xc4, + 0x68, 0xd9, 0x17, 0x5c, 0x4a, 0x3f, 0x22, 0x94, 0xf5, 0xe1, 0x18, 0x98, 0x92, 0xbd, 0xb1, 0xe0, + 0x8a, 0xbb, 0x2b, 0xa7, 0xa0, 0x88, 0xd1, 0x7b, 0x66, 0xc5, 0x05, 0xf4, 0xae, 0xf6, 0xb6, 0x97, + 0x7c, 0x3e, 0x1a, 0x71, 0xd6, 0xb7, 0x1f, 0xf6, 0x99, 0x76, 0x2b, 0xe4, 0x21, 0x37, 0xcb, 0xbe, + 0x5e, 0x59, 0xb5, 0xfb, 0x69, 0x0e, 0xfd, 0xbd, 0xa9, 0x47, 0xef, 0xb0, 0x21, 0x4f, 0x58, 0xb0, + 0x45, 0x19, 0x89, 0xe9, 0x29, 0x04, 0xee, 0x2a, 0xaa, 0x8f, 0x64, 0x88, 0xd5, 0xc9, 0x18, 0x70, + 0x22, 0x62, 0xcf, 0x59, 0x75, 0xee, 0xd5, 0xf6, 0xd0, 0x48, 0x86, 0x07, 0x27, 0x63, 0x78, 0x21, + 0x62, 0x77, 0x05, 0x21, 0xdf, 0x57, 0x29, 0xa6, 0x2c, 0x80, 0xd4, 0x9b, 0x35, 0xfd, 0x9a, 0x56, + 0x76, 0xb4, 0xe0, 0xfe, 0x83, 0x2a, 0x12, 0x58, 0x00, 0xc2, 0x9b, 0x33, 0xad, 0xac, 0x72, 0xff, + 0x45, 0x55, 0x95, 0x62, 0x2e, 0x42, 0xca, 0xbc, 0x92, 0xe9, 0xcc, 0xab, 0x74, 0x57, 0x97, 0x6e, + 0x0b, 0x95, 0x89, 0x94, 0xa0, 0xbc, 0xb2, 0xd1, 0x6d, 0xe1, 0xfe, 0x87, 0x10, 0x65, 0x58, 0xa5, + 0x38, 0x22, 0x32, 0xf2, 0x2a, 0xa6, 0x55, 0xa5, 0xec, 0x20, 0xdd, 0x26, 0x32, 0x72, 0xef, 0xa0, + 0x45, 0xca, 0xf0, 0x30, 0xe6, 0xfe, 0x6b, 0x1c, 0x01, 0x0d, 0x23, 0xe5, 0xcd, 0x9b, 0x2d, 0x0d, + 0xca, 0x36, 0xb4, 0xba, 0x6d, 0x44, 0xb7, 0x8d, 0xaa, 0x02, 0x7c, 0xa0, 0xc7, 0x20, 0xbc, 0xaa, + 0x9d, 0x91, 0xd7, 0xee, 0x6d, 0xd4, 0xcc, 0xd7, 0xd8, 0x58, 0xe8, 0xd5, 0xec, 0x88, 0x5c, 0x1d, + 0x68, 0x51, 0x9f, 0x88, 0x8c, 0x78, 0xc2, 0x94, 0x87, 0xec, 0x89, 0x6c, 0xe5, 0xde, 0x45, 0x8b, + 0x02, 0x62, 0x72, 0x02, 0x01, 0x1e, 0x81, 0x94, 0x24, 0x04, 0x6f, 0xc1, 0x6c, 0x68, 0x66, 0xf2, + 0x33, 0xab, 0x6a, 0xc7, 0x18, 0x4c, 0xb0, 0x54, 0x44, 0x25, 0xd2, 0xab, 0x5b, 0xc7, 0x18, 0x4c, + 0xf6, 0x8d, 0xa0, 0x31, 0x6c, 0xeb, 0x72, 0x4c, 0xc3, 0x62, 0x58, 0x35, 0x9f, 0xf2, 0x3f, 0xaa, + 0x5b, 0x2b, 0x33, 0xd6, 0xa6, 0xd9, 0xb4, 0x60, 0x35, 0x43, 0xda, 0x7d, 0x37, 0x8b, 0x96, 0x4d, + 0xac, 0x47, 0xc2, 0x3f, 0xa4, 0x2a, 0x0a, 0x04, 0x99, 0x0c, 0x04, 0x10, 0xf5, 0x2b, 0x83, 0x2d, + 0x72, 0x95, 0x6e, 0x70, 0x15, 0xa2, 0x2c, 0x17, 0xa2, 0xbc, 0x1e, 0x51, 0xe5, 0x87, 0x11, 0xcd, + 0x7f, 0x3f, 0xa2, 0xea, 0x54, 0x44, 0xd3, 0xce, 0xd7, 0x0a, 0xce, 0x77, 0xdf, 0x3b, 0xc8, 0xb3, + 0x7e, 0x81, 0x22, 0xbf, 0xcd, 0xb0, 0x69, 0x37, 0x4a, 0x05, 0x37, 0xa6, 0x91, 0xcb, 0x45, 0xe4, + 0x0f, 0x0e, 0x6a, 0x19, 0xe4, 0xdd, 0x44, 0xd9, 0x9f, 0x2e, 0xa1, 0x71, 0x22, 0xe0, 0xe7, 0x71, + 0x57, 0x10, 0xe2, 0x71, 0x90, 0x7f, 0xb1, 0x45, 0xae, 0xf1, 0x38, 0xc8, 0xde, 0xd2, 0x69, 0xae, + 0xd2, 0x37, 0x5e, 0xe2, 0x63, 0x12, 0x27, 0x80, 0xb3, 0x60, 0x82, 0x0c, 0xbd, 0x61, 0xd4, 0xbd, + 0x4c, 0xbc, 0x89, 0xbf, 0x9f, 0xf8, 0x3e, 0x48, 0xf9, 0x87, 0xe0, 0xbf, 0x75, 0x50, 0xdb, 0xe0, + 0x0f, 0x06, 0x07, 0x2f, 0x9f, 0x10, 0xf9, 0x5c, 0x50, 0x1f, 0x76, 0x98, 0x2f, 0x80, 0x48, 0x08, + 0x0a, 0x88, 0x4e, 0x11, 0xf1, 0x3e, 0x72, 0x43, 0x22, 0xf1, 0x58, 0x3f, 0x84, 0x69, 0xf6, 0x54, + 0x76, 0x92, 0xbf, 0xc2, 0xc2, 0x34, 0xfd, 0xf7, 0x42, 0x82, 0x80, 0x2a, 0xca, 0x19, 0x89, 0xf1, + 0x2b, 0x80, 0xfc, 0x54, 0xcd, 0x2b, 0x79, 0x0b, 0x40, 0x76, 0x63, 0xb4, 0x64, 0x98, 0x36, 0xf7, + 0x06, 0xeb, 0x6b, 0x87, 0x11, 0x55, 0x10, 0x53, 0xa9, 0xdc, 0x35, 0xd4, 0x9a, 0xe4, 0x05, 0xbe, + 0x81, 0xe5, 0x5e, 0xf6, 0x06, 0x97, 0x7c, 0xb7, 0x50, 0xe3, 0x54, 0xf8, 0xeb, 0x6b, 0x98, 0x04, + 0x81, 0x00, 0x29, 0x33, 0xb4, 0xba, 0x11, 0x1f, 0x5b, 0x6d, 0xe3, 0xe9, 0xc7, 0xf3, 0x8e, 0x73, + 0x76, 0xde, 0x71, 0xbe, 0x9c, 0x77, 0x9c, 0x37, 0x17, 0x9d, 0x99, 0xb3, 0x8b, 0xce, 0xcc, 0xe7, + 0x8b, 0xce, 0xcc, 0xd1, 0xc3, 0x90, 0xaa, 0x28, 0x19, 0xf6, 0x7c, 0x3e, 0xea, 0xeb, 0xfb, 0xe9, + 0x81, 0xbd, 0xc2, 0xf2, 0xab, 0xaa, 0x9f, 0xf6, 0xaf, 0x5d, 0x6c, 0x3a, 0x68, 0x39, 0xac, 0x98, + 0xeb, 0xe8, 0xd1, 0xd7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xdd, 0x61, 0x9f, 0xf3, 0x06, 0x00, + 0x00, } func (m *EventInboundFinalized) Marshal() (dAtA []byte, err error) { @@ -1050,6 +1107,43 @@ func (m *EventCCTXGasPriceIncreased) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *EventERC20Whitelist) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventERC20Whitelist) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventERC20Whitelist) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Zrc20Address) > 0 { + i -= len(m.Zrc20Address) + copy(dAtA[i:], m.Zrc20Address) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Zrc20Address))) + i-- + dAtA[i] = 0x12 + } + if len(m.WhitelistCctxIndex) > 0 { + i -= len(m.WhitelistCctxIndex) + copy(dAtA[i:], m.WhitelistCctxIndex) + i = encodeVarintEvents(dAtA, i, uint64(len(m.WhitelistCctxIndex))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -1279,6 +1373,23 @@ func (m *EventCCTXGasPriceIncreased) Size() (n int) { return n } +func (m *EventERC20Whitelist) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.WhitelistCctxIndex) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + l = len(m.Zrc20Address) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2897,6 +3008,120 @@ func (m *EventCCTXGasPriceIncreased) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventERC20Whitelist) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventERC20Whitelist: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventERC20Whitelist: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WhitelistCctxIndex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WhitelistCctxIndex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Zrc20Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Zrc20Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipEvents(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From cbfa5f759752db32450517089e0051d6d83d4df2 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 13:46:15 +0100 Subject: [PATCH 26/35] make lint --- e2e/e2etests/test_migrate_chain_support.go | 4 --- typescript/crosschain/events_pb.d.ts | 29 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index cb4790fe85..a51a6d4c31 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -140,11 +140,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txWithdraw, r.Logger, r.ReceiptTimeout) if receipt.Status == 1 { panic("withdraw should have failed on the previous chain") - } else { - r.Logger.Info("withdraw failed on the previous chain as expected with receipt") } - } else { - r.Logger.Info("withdraw failed on the previous chain as expected") } // test cross-chain functionalities on the new network diff --git a/typescript/crosschain/events_pb.d.ts b/typescript/crosschain/events_pb.d.ts index 285f476b30..37a8e7cf2a 100644 --- a/typescript/crosschain/events_pb.d.ts +++ b/typescript/crosschain/events_pb.d.ts @@ -325,3 +325,32 @@ export declare class EventCCTXGasPriceIncreased extends Message | undefined, b: EventCCTXGasPriceIncreased | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.crosschain.EventERC20Whitelist + */ +export declare class EventERC20Whitelist extends Message { + /** + * @generated from field: string whitelist_cctx_index = 1; + */ + whitelistCctxIndex: string; + + /** + * @generated from field: string zrc20_address = 2; + */ + zrc20Address: string; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.EventERC20Whitelist"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): EventERC20Whitelist; + + static fromJson(jsonValue: JsonValue, options?: Partial): EventERC20Whitelist; + + static fromJsonString(jsonString: string, options?: Partial): EventERC20Whitelist; + + static equals(a: EventERC20Whitelist | PlainMessage | undefined, b: EventERC20Whitelist | PlainMessage | undefined): boolean; +} + From 0f10ccb7c2b8176e16047a832fe451c2bb90719b Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 16:25:45 +0100 Subject: [PATCH 27/35] fix comment --- e2e/runner/evm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index ac816b07c6..c438f7df1d 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -79,7 +79,7 @@ func (runner *E2ERunner) DepositERC20() ethcommon.Hash { } func (runner *E2ERunner) DepositERC20WithAmountAndMessage(to ethcommon.Address, amount *big.Int, msg []byte) ethcommon.Hash { - // reset allowance, necessary for ERC20 + // reset allowance, necessary for USDT tx, err := runner.ERC20.Approve(runner.EVMAuth, runner.ERC20CustodyAddr, big.NewInt(0)) if err != nil { panic(err) From 25ec0bc54c8e453597a7bfbd527723df4abdb4b3 Mon Sep 17 00:00:00 2001 From: kevinssgh Date: Mon, 25 Mar 2024 11:59:25 -0400 Subject: [PATCH 28/35] fix some unit tests --- zetaclient/evm/evm_signer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 97a1a7bee5..8c0ff4367d 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -676,7 +676,7 @@ func (signer *Signer) EvmSigner() ethtypes.Signer { func getEVMRPC(endpoint string) (interfaces.EVMRPCClient, ethtypes.Signer, error) { if endpoint == stub.EVMRPCEnabled { chainID := big.NewInt(common.BscMainnetChain().ChainId) - ethSigner := ethtypes.NewEIP155Signer(chainID) + ethSigner := ethtypes.NewLondonSigner(chainID) client := &stub.MockEvmClient{} return client, ethSigner, nil } From 911b99f0288cef9b31fcc31081d17c0b9c1b1388 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 22:38:54 +0100 Subject: [PATCH 29/35] add tests back --- cmd/zetae2e/local/local.go | 6 +++--- e2e/e2etests/test_migrate_chain_support.go | 12 +++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 7a4208c3a9..eb4fd7dc34 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -282,9 +282,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, - //e2etests.TestPauseZRC20Name, - //e2etests.TestUpdateBytecodeName, - //e2etests.TestDepositEtherLiquidityCapName, + e2etests.TestPauseZRC20Name, + e2etests.TestUpdateBytecodeName, + e2etests.TestDepositEtherLiquidityCapName, e2etests.TestMigrateChainSupportName, )) } diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index a51a6d4c31..57c78901d0 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -152,7 +152,9 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } // deposit Ethers and ERC20 on ZetaChain - txEtherDeposit := newRunner.DepositEther(false) + etherAmount := big.NewInt(1e18) + etherAmount = etherAmount.Mul(etherAmount, big.NewInt(10)) + txEtherDeposit := newRunner.DepositEtherWithAmount(false, etherAmount) newRunner.WaitForMinedCCTX(txEtherDeposit) // perform withdrawals on the new chain @@ -193,7 +195,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // wait for the whitelist cctx to be mined newRunner.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) - //set erc20 zrc20 contract address + // set erc20 zrc20 contract address if !ethcommon.IsHexAddress(erc20zrc20Addr) { panic(fmt.Errorf("invalid contract address: %s", erc20zrc20Addr)) } @@ -203,14 +205,10 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { } newRunner.ERC20ZRC20 = erc20ZRC20 - // deposit + // deposit ERC20 on ZetaChain txERC20Deposit := newRunner.DepositERC20() newRunner.WaitForMinedCCTX(txERC20Deposit) - // withdraw - newRunner.Logger.Info("trying withdrawing ERC20 on new network") - TestERC20Withdraw(r, []string{"100000"}) - // stop mining stopMining() } From d3beb31e9231f994d4637238f1a9faafe6bd2e64 Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 25 Mar 2024 22:39:47 +0100 Subject: [PATCH 30/35] update changeog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 6efe4a3c45..7887382f48 100644 --- a/changelog.md +++ b/changelog.md @@ -41,6 +41,7 @@ * [1805](https://github.com/zeta-chain/node/pull/1805) - add admin and performance test and fix upgrade test * [1879](https://github.com/zeta-chain/node/pull/1879) - full coverage for messages in types packages * [1899](https://github.com/zeta-chain/node/pull/1899) - add empty test files so packages are included in coverage +* [1900](https://github.com/zeta-chain/node/pull/1900) - add testing for external chain migration ### Fixes From 11dbf72d763c2f10969966ef4181813c02a5d335 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 27 Mar 2024 11:02:15 +0100 Subject: [PATCH 31/35] remove bg --- contrib/localnet/scripts/start-zetaclientd.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index 270ec57339..a43e8e120f 100755 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -68,7 +68,7 @@ fi # check if the option is background # in this case, we tail the zetaclientd log file -#if [ "$OPTION" == "background" ]; then +if [ "$OPTION" == "background" ]; then sleep 3 tail -f $HOME/zetaclient.log -#fi +fi From 41f138663bc97e11bad50d44a1ff01d052e70cd0 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 3 Apr 2024 14:53:09 +0200 Subject: [PATCH 32/35] revert back legacy tx --- zetaclient/evm/evm_signer.go | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 77a097f4d3..4f38ca3634 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -142,16 +142,7 @@ func (signer *Signer) Sign( ) (*ethtypes.Transaction, []byte, []byte, error) { log.Debug().Msgf("TSS SIGNER: %s", signer.tssSigner.Pubkey()) - tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ - ChainID: big.NewInt(signer.chain.ChainId), - Nonce: nonce, - To: &to, - Value: big.NewInt(0), - Gas: gasLimit, - GasTipCap: gasPrice, - GasFeeCap: gasPrice, - Data: data, - }) + tx := ethtypes.NewTransaction(nonce, to, big.NewInt(0), gasLimit, gasPrice, data) hashBytes := signer.ethSigner.Hash(tx).Bytes() @@ -260,17 +251,7 @@ func (signer *Signer) SignRevertTx(txData *OutBoundTransactionData) (*ethtypes.T // SignCancelTx signs a transaction from TSS address to itself with a zero amount in order to increment the nonce func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint64) (*ethtypes.Transaction, error) { - to := signer.tssSigner.EVMAddress() - tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ - ChainID: big.NewInt(signer.chain.ChainId), - Nonce: nonce, - To: &to, - Value: big.NewInt(0), - Gas: 21000, - GasTipCap: gasPrice, - GasFeeCap: gasPrice, - Data: nil, - }) + tx := ethtypes.NewTransaction(nonce, signer.tssSigner.EVMAddress(), big.NewInt(0), 21000, gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") @@ -293,16 +274,7 @@ func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint6 // SignWithdrawTx signs a withdrawal transaction sent from the TSS address to the destination func (signer *Signer) SignWithdrawTx(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { - tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ - ChainID: big.NewInt(signer.chain.ChainId), - Nonce: txData.nonce, - To: &txData.to, - Value: txData.amount, - Gas: 21000, - GasTipCap: txData.gasPrice, - GasFeeCap: txData.gasPrice, - Data: nil, - }) + tx := ethtypes.NewTransaction(txData.nonce, txData.to, txData.amount, 21000, txData.gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, txData.height, txData.nonce, signer.chain, "") From 5d93e26fa7ad75847dbf9e8f2a28169d819fc3a7 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 3 Apr 2024 15:11:54 +0200 Subject: [PATCH 33/35] disable chain migration test --- cmd/zetae2e/local/local.go | 7 ++++++- zetaclient/evm/evm_signer.go | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index eb4fd7dc34..7c202deb93 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -285,7 +285,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestPauseZRC20Name, e2etests.TestUpdateBytecodeName, e2etests.TestDepositEtherLiquidityCapName, - e2etests.TestMigrateChainSupportName, + + // TestMigrateChainSupportName tests EVM chain migration. Currently this test doesn't work with Anvil because pre-EIP1559 txs are not supported + // See issue below for details + // TODO: renenable this test as per the issue below + // https://github.com/zeta-chain/node/issues/1980 + // e2etests.TestMigrateChainSupportName, )) } if testPerformance { diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 4f38ca3634..e077d19fe2 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -142,6 +142,8 @@ func (signer *Signer) Sign( ) (*ethtypes.Transaction, []byte, []byte, error) { log.Debug().Msgf("TSS SIGNER: %s", signer.tssSigner.Pubkey()) + // TODO: use EIP-1559 transaction type + // https://github.com/zeta-chain/node/issues/1952 tx := ethtypes.NewTransaction(nonce, to, big.NewInt(0), gasLimit, gasPrice, data) hashBytes := signer.ethSigner.Hash(tx).Bytes() @@ -251,6 +253,8 @@ func (signer *Signer) SignRevertTx(txData *OutBoundTransactionData) (*ethtypes.T // SignCancelTx signs a transaction from TSS address to itself with a zero amount in order to increment the nonce func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint64) (*ethtypes.Transaction, error) { + // TODO: use EIP-1559 transaction type + // https://github.com/zeta-chain/node/issues/1952 tx := ethtypes.NewTransaction(nonce, signer.tssSigner.EVMAddress(), big.NewInt(0), 21000, gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() @@ -274,6 +278,8 @@ func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint6 // SignWithdrawTx signs a withdrawal transaction sent from the TSS address to the destination func (signer *Signer) SignWithdrawTx(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { + // TODO: use EIP-1559 transaction type + // https://github.com/zeta-chain/node/issues/1952 tx := ethtypes.NewTransaction(txData.nonce, txData.to, txData.amount, 21000, txData.gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() From 1af1b4f2a93d120097cc71562968a2b998fe8420 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 3 Apr 2024 15:51:26 +0200 Subject: [PATCH 34/35] fix test file --- e2e/e2etests/test_migrate_chain_support.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 57c78901d0..ae1acdde93 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -7,20 +7,19 @@ import ( "os/exec" "time" - "github.com/zeta-chain/zetacore/e2e/txserver" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - - "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/fatih/color" - "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/zetacore/e2e/runner" + "github.com/zeta-chain/zetacore/e2e/txserver" "github.com/zeta-chain/zetacore/e2e/utils" + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/coin" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -31,7 +30,7 @@ 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 -var EVM2ChainID = common.SepoliaChain().ChainId +var EVM2ChainID = chains.SepoliaChain().ChainId func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit most of the ZETA supply on ZetaChain @@ -81,7 +80,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { 18, "Sepolia ETH", "sETH", - common.CoinType_Gas, + coin.CoinType_Gas, 100000, )) if err != nil { @@ -171,7 +170,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { res, err := newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, crosschaintypes.NewMsgWhitelistERC20( adminAddr, newRunner.ERC20Addr.Hex(), - common.SepoliaChain().ChainId, + chains.SepoliaChain().ChainId, "USDT", "USDT", 18, From 00ed796594f0fa2ff3e0fa2d28441990ae198ae6 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 3 Apr 2024 16:44:59 +0200 Subject: [PATCH 35/35] move timeout check location --- e2e/utils/zetacore.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 30fa0bcf08..4aeac71ba3 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -49,7 +49,11 @@ func WaitCctxsMinedByInTxHash( // fetch cctxs by inTxHash for i := 0; ; i++ { + if time.Since(startTime) > timeout { + panic(fmt.Sprintf("waiting cctx timeout, cctx not mined, inTxHash: %s", inTxHash)) + } time.Sleep(1 * time.Second) + res, err := cctxClient.InTxHashToCctxData(ctx, &crosschaintypes.QueryInTxHashToCctxDataRequest{ InTxHash: inTxHash, }) @@ -93,13 +97,6 @@ func WaitCctxsMinedByInTxHash( cctxs = append(cctxs, &cctx) } if !allFound { - if time.Since(startTime) > timeout { - panic(fmt.Sprintf( - "waiting cctx timeout, cctx not mined, inTxHash: %s, current cctxs: %v", - inTxHash, - cctxs, - )) - } continue } return cctxs