From e37a0798e70de0a47618dbd790d7bfe1824ab62e Mon Sep 17 00:00:00 2001 From: Grant Zukel Date: Tue, 26 Sep 2023 13:56:14 -0600 Subject: [PATCH] updates. --- .../actions/upgrade-testing/create_genesis.py | 54 + .../upgrade-testing/scripts/create_genesis.py | 49 + .../scripts/get_proposal_id.py | 23 + .../scripts/raise_gov_proposal.py | 63 + .github/labeler.yml | 3 + .github/workflows/build.yml | 1 - .github/workflows/sast-linters.yml | 52 +- .github/workflows/upgrade_path_testing.yaml | 432 +++ Makefile | 24 +- app/app.go | 2 +- app/setup_handlers.go | 17 +- cmd/config_mainnet.go | 9 +- cmd/config_mock_mainnet.go | 16 + cmd/zetaclientd/init.go | 11 - cmd/zetaclientd/start.go | 4 + cmd/zetacored/observer_accounts.go | 4 + common/chain.go | 6 + common/common.pb.go | 990 ++++++- common/default_chains_mainnet.go | 20 +- common/default_chains_mock_mainnet.go | 66 + common/default_chains_privnet.go | 12 + common/default_chains_testnet.go | 14 + common/ethereum/ethereum.pb.go | 374 +++ common/ethereum/proof.go | 168 ++ common/ethereum/proof_test.go | 125 + common/headers.go | 68 + common/proof.go | 61 + common/proof_test.go | 15 + .../contracts/testzrc20/TestZRC20.abi | 670 +++++ .../contracts/testzrc20/TestZRC20.bin | 1 + .../contracts/testzrc20/TestZRC20.go | 1925 ++++++++++++ .../contracts/testzrc20/TestZRC20.json | 673 +++++ .../contracts/testzrc20/TestZRC20.sol | 363 +++ .../smoketest/contracts/testzrc20/bindings.go | 6 + .../localnet/orchestrator/smoketest/main.go | 14 +- .../smoketest/test_crosschain_swap.go | 4 +- .../smoketest/test_deposit_eth.go | 152 +- .../smoketest/test_erc20_refund.go | 200 ++ .../smoketest/test_update_bytecode.go | 189 ++ .../localnet/orchestrator/smoketest/utils.go | 4 +- docs/openapi/openapi.swagger.yaml | 229 ++ docs/spec/crosschain/messages.md | 20 +- docs/spec/fungible/messages.md | 15 + docs/spec/observer/messages.md | 14 + go.mod | 5 +- go.sum | 123 +- proto/common/common.proto | 23 +- proto/common/ethereum/ethereum.proto | 9 + proto/crosschain/events.proto | 4 +- proto/crosschain/out_tx_tracker.proto | 1 + proto/crosschain/query.proto | 12 + proto/crosschain/tx.proto | 9 +- proto/fungible/tx.proto | 15 +- proto/observer/query.proto | 42 + proto/observer/tx.proto | 11 + rpc/apis.go | 129 +- rpc/namespaces/ethereum/debug/api.go | 10 +- rpc/namespaces/ethereum/eth/api.go | 60 +- rpc/namespaces/ethereum/eth/filters/api.go | 14 +- .../ethereum/eth/filters/filter_system.go | 16 +- .../ethereum/eth/filters/filters.go | 12 +- rpc/namespaces/ethereum/miner/api.go | 3 - rpc/namespaces/ethereum/personal/api.go | 13 +- rpc/namespaces/ethereum/txpool/api.go | 4 +- rpc/namespaces/ethereum/web3/api.go | 3 +- rpc/websockets.go | 17 +- scripts/mocks-generate.sh | 11 + standalone-network/run-zetaclient.sh | 2 +- testutil/keeper/crosschain.go | 36 +- testutil/keeper/fungible.go | 30 +- testutil/keeper/mocks/crosschain/account.go | 3 +- testutil/keeper/mocks/crosschain/bank.go | 5 +- testutil/keeper/mocks/crosschain/fungible.go | 230 +- testutil/keeper/mocks/crosschain/observer.go | 29 +- testutil/keeper/mocks/crosschain/staking.go | 5 +- testutil/keeper/mocks/fungible/account.go | 3 +- testutil/keeper/mocks/fungible/bank.go | 3 +- testutil/keeper/mocks/fungible/evm.go | 36 +- testutil/keeper/mocks/fungible/observer.go | 5 +- testutil/keeper/{ => mocks}/mocks.go | 20 +- testutil/network/network_config.go | 1 + testutil/sample/sample.go | 7 + x/crosschain/client/cli/cli_cctx.go | 22 +- x/crosschain/client/cli/cli_out_tx_tracker.go | 3 + .../client/integrationtests/cli_helpers.go | 25 +- .../integrationtests/inbound_voter_test.go | 16 +- .../integrationtests/outbound_voter_test.go | 44 +- x/crosschain/genesis_test.go | 2 +- x/crosschain/keeper/abci_test.go | 2 +- x/crosschain/keeper/cctx_utils.go | 87 + x/crosschain/keeper/cctx_utils_test.go | 140 + x/crosschain/keeper/events.go | 20 +- x/crosschain/keeper/evm_hooks.go | 40 +- x/crosschain/keeper/gas_payment.go | 352 +++ x/crosschain/keeper/gas_payment_test.go | 802 +++++ .../grpc_query_in_tx_hash_to_cctx_test.go | 6 +- .../keeper/in_tx_hash_to_cctx_test.go | 6 +- .../keeper_cross_chain_tx_vote_inbound_tx.go | 85 +- .../keeper_cross_chain_tx_vote_outbound_tx.go | 30 +- x/crosschain/keeper/keeper_out_tx_tracker.go | 104 +- .../keeper/keeper_out_tx_tracker_test.go | 6 +- x/crosschain/keeper/keeper_pending_nonces.go | 20 + x/crosschain/keeper/keeper_tss_voter.go | 9 + x/crosschain/keeper/keeper_utils.go | 143 - x/crosschain/keeper/zeta_conversion_rate.go | 2 +- x/crosschain/module.go | 9 +- x/crosschain/types/cctx_utils.go | 19 +- x/crosschain/types/cctx_utils_test.go | 52 + x/crosschain/types/errors.go | 52 +- x/crosschain/types/events.pb.go | 130 +- x/crosschain/types/expected_keepers.go | 34 +- .../types/message_add_to_out_tx_tracker.go | 22 +- .../message_vote_on_observed_outbound_tx.go | 4 +- ...ssage_vote_on_observed_outbound_tx_test.go | 12 +- x/crosschain/types/out_tx_tracker.pb.go | 80 +- x/crosschain/types/query.pb.go | 786 +++-- x/crosschain/types/query.pb.gw.go | 101 + x/crosschain/types/tx.pb.go | 335 ++- .../begin_blocker_deploy_system_contracts.go | 4 +- ...er_deploy_system_contracts_mock_mainnet.go | 18 + ...blocker_deploy_system_contracts_privnet.go | 9 +- x/fungible/keeper/deposits.go | 26 +- x/fungible/keeper/evm.go | 215 +- x/fungible/keeper/foreign_coins.go | 12 + x/fungible/keeper/foreign_coins_test.go | 113 + x/fungible/keeper/gas_price.go | 6 +- x/fungible/keeper/gas_price_test.go | 75 + .../msg_server_deploy_fungible_coin_zrc20.go | 47 +- ..._server_deploy_fungible_coin_zrc20_test.go | 147 + .../msg_server_remove_foreign_coin_test.go | 60 + x/fungible/keeper/msg_server_test.go | 16 - .../msg_server_update_contract_bytecode.go | 83 + ...sg_server_update_contract_bytecode_test.go | 374 +++ .../msg_server_update_system_contract_test.go | 108 + ..._server_update_zrc20_paused_status_test.go | 13 - .../msg_server_update_zrc20_withdraw_fee.go | 73 +- ...g_server_update_zrc20_withdraw_fee_test.go | 159 + x/fungible/keeper/system_contract.go | 447 ++- x/fungible/keeper/system_contract_test.go | 120 +- x/fungible/types/errors.go | 6 +- x/fungible/types/expected_keepers.go | 4 + .../types/message_update_contract_bytecode.go | 62 + .../message_update_contract_bytecode_test.go | 65 + .../types/message_update_system_contract.go | 2 +- .../message_update_zrc20_withdraw_fee.go | 2 +- x/fungible/types/tx.pb.go | 637 +++- x/observer/keeper/block_header.go | 78 + x/observer/keeper/grpc_query_prove.go | 47 + .../keeper/msg_server_add_block_header.go | 65 + x/observer/types/core_params_mainnet.go | 67 +- x/observer/types/core_params_mock_mainnet.go | 72 + x/observer/types/core_params_privnet.go | 11 +- x/observer/types/core_params_testnet.go | 20 +- x/observer/types/errors.go | 40 +- x/observer/types/keys.go | 1 + x/observer/types/messages_add_block_header.go | 79 + x/observer/types/params.go | 2 +- x/observer/types/query.pb.go | 2612 +++++++++++++---- x/observer/types/query.pb.gw.go | 267 ++ x/observer/types/tx.pb.go | 611 +++- zetaclient/bitcoin_client.go | 22 +- zetaclient/broadcast.go | 10 +- zetaclient/btc_signer.go | 4 +- zetaclient/config/config_mainnet.go | 27 +- zetaclient/config/config_mock_mainnet.go | 63 + zetaclient/config/config_privnet.go | 3 - zetaclient/config/config_testnet.go | 3 - zetaclient/evm_client.go | 99 +- zetaclient/evm_signer.go | 4 +- zetaclient/query.go | 26 +- zetaclient/tss_signer.go | 1 + zetaclient/tx.go | 24 +- zetaclient/zetabridge.go | 24 +- 173 files changed, 16729 insertions(+), 2181 deletions(-) create mode 100644 .github/actions/upgrade-testing/create_genesis.py create mode 100644 .github/actions/upgrade-testing/scripts/create_genesis.py create mode 100644 .github/actions/upgrade-testing/scripts/get_proposal_id.py create mode 100644 .github/actions/upgrade-testing/scripts/raise_gov_proposal.py create mode 100644 .github/workflows/upgrade_path_testing.yaml create mode 100644 cmd/config_mock_mainnet.go create mode 100644 common/default_chains_mock_mainnet.go create mode 100644 common/ethereum/ethereum.pb.go create mode 100644 common/ethereum/proof.go create mode 100644 common/ethereum/proof_test.go create mode 100644 common/headers.go create mode 100644 common/proof.go create mode 100644 common/proof_test.go create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go create mode 100644 contrib/localnet/orchestrator/smoketest/test_erc20_refund.go create mode 100644 contrib/localnet/orchestrator/smoketest/test_update_bytecode.go create mode 100644 proto/common/ethereum/ethereum.proto create mode 100644 scripts/mocks-generate.sh rename testutil/keeper/{ => mocks}/mocks.go (74%) create mode 100644 x/crosschain/keeper/cctx_utils.go create mode 100644 x/crosschain/keeper/cctx_utils_test.go create mode 100644 x/crosschain/keeper/gas_payment.go create mode 100644 x/crosschain/keeper/gas_payment_test.go delete mode 100644 x/crosschain/keeper/keeper_utils.go create mode 100644 x/crosschain/types/cctx_utils_test.go create mode 100644 x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go create mode 100644 x/fungible/keeper/gas_price_test.go create mode 100644 x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go create mode 100644 x/fungible/keeper/msg_server_remove_foreign_coin_test.go delete mode 100644 x/fungible/keeper/msg_server_test.go create mode 100644 x/fungible/keeper/msg_server_update_contract_bytecode.go create mode 100644 x/fungible/keeper/msg_server_update_contract_bytecode_test.go create mode 100644 x/fungible/keeper/msg_server_update_system_contract_test.go create mode 100644 x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go create mode 100644 x/fungible/types/message_update_contract_bytecode.go create mode 100644 x/fungible/types/message_update_contract_bytecode_test.go create mode 100644 x/observer/keeper/block_header.go create mode 100644 x/observer/keeper/grpc_query_prove.go create mode 100644 x/observer/keeper/msg_server_add_block_header.go create mode 100644 x/observer/types/core_params_mock_mainnet.go create mode 100644 x/observer/types/messages_add_block_header.go create mode 100644 zetaclient/config/config_mock_mainnet.go diff --git a/.github/actions/upgrade-testing/create_genesis.py b/.github/actions/upgrade-testing/create_genesis.py new file mode 100644 index 0000000000..75ef7f9f66 --- /dev/null +++ b/.github/actions/upgrade-testing/create_genesis.py @@ -0,0 +1,54 @@ +import json +import os + +genesis = open(os.environ["NEW_GENESIS"], "r").read() +genesis_json_object = json.loads(genesis) + +#cut this out for now because it fails to start when done in python with the exact same keys being replaced with same value. Will fix later. +# genesis_json_object["staking"]["params"]["bond_denom"] = "azeta" +# genesis_json_object["crisis"]["constant_fee"]["denom"] = "azeta" +# genesis_json_object["gov"]["deposit_params"]["min_deposit"][0]["denom"] = "azeta" +# genesis_json_object["mint"]["params"]["mint_denom"] = "azeta" +# genesis_json_object["evm"]["params"]["evm_denom"] = "azeta" +# genesis_json_object["block"]["max_gas"] = "10000000" +# genesis_json_object["gov"]["voting_params"]["voting_period"] = '60s' + +exported_genesis = open(os.environ["OLD_GENESIS"], "r").read() +exported_genesis_json_object = json.loads(exported_genesis) + +crosschain = exported_genesis_json_object["app_state"]["crosschain"] +observer = exported_genesis_json_object["app_state"]["observer"] +emissions = exported_genesis_json_object["app_state"]["emissions"] +fungible = exported_genesis_json_object["app_state"]["fungible"] +evm = exported_genesis_json_object["app_state"]["evm"] +auth_accounts = exported_genesis_json_object["app_state"]["auth"]["accounts"] + +genesis_json_object["app_state"]["auth"]["accounts"] = genesis_json_object["app_state"]["auth"]["accounts"] + auth_accounts +genesis_json_object["app_state"]["crosschain"] = crosschain +genesis_json_object["app_state"]["observer"] = observer +genesis_json_object["app_state"]["emissions"] = emissions +genesis_json_object["app_state"]["fungible"] = fungible + +evm_accounts = [] +for index, account in enumerate(evm["accounts"]): + if account["address"] == "0x0000000000000000000000000000000000000001": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000006": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000002": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000002": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000008": + print("pop account", account["address"]) + else: + evm_accounts.append(account) + +evm["accounts"] = evm_accounts +genesis_json_object["app_state"]["evm"] = evm + +genesis = open("genesis-edited.json", "w") +genesis_string = json.dumps(genesis_json_object, indent=2) +dumped_genesis_object = genesis_string.replace("0x0000000000000000000000000000000000000001","0x387A12B28fe02DcAa467c6a1070D19B82F718Bb5") +genesis.write(genesis_string) +genesis.close() diff --git a/.github/actions/upgrade-testing/scripts/create_genesis.py b/.github/actions/upgrade-testing/scripts/create_genesis.py new file mode 100644 index 0000000000..ce5e3627dd --- /dev/null +++ b/.github/actions/upgrade-testing/scripts/create_genesis.py @@ -0,0 +1,49 @@ +import json +import os + +print("OPEN NEW GENESIS") +genesis = open(os.environ["NEW_GENESIS"], "r").read() +genesis_json_object = json.loads(genesis) + +print("OPEN OLD GENESIS") +exported_genesis = open(os.environ["OLD_GENESIS"], "r").read() +exported_genesis_json_object = json.loads(exported_genesis) + +print("PULL STATE OUT OF OLD GENESIS") +crosschain = exported_genesis_json_object["app_state"]["crosschain"] +observer = exported_genesis_json_object["app_state"]["observer"] +emissions = exported_genesis_json_object["app_state"]["emissions"] +fungible = exported_genesis_json_object["app_state"]["fungible"] +evm = exported_genesis_json_object["app_state"]["evm"] +auth_accounts = exported_genesis_json_object["app_state"]["auth"]["accounts"] + +print("MANIPULATE NEW GENESIS") +genesis_json_object["app_state"]["auth"]["accounts"] = genesis_json_object["app_state"]["auth"]["accounts"] + auth_accounts +genesis_json_object["app_state"]["crosschain"] = crosschain +genesis_json_object["app_state"]["observer"] = observer +genesis_json_object["app_state"]["emissions"] = emissions +genesis_json_object["app_state"]["fungible"] = fungible + +evm_accounts = [] +for index, account in enumerate(evm["accounts"]): + if account["address"] == "0x0000000000000000000000000000000000000001": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000006": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000002": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000002": + print("pop account", account["address"]) + elif account["address"] == "0x0000000000000000000000000000000000000008": + print("pop account", account["address"]) + else: + evm_accounts.append(account) +evm["accounts"] = evm_accounts +genesis_json_object["app_state"]["evm"] = evm + +print("WRITE GENESIS-EDITED") +genesis = open("genesis-edited.json", "w") +genesis_string = json.dumps(genesis_json_object, indent=2) +dumped_genesis_object = genesis_string.replace("0x0000000000000000000000000000000000000001","0x387A12B28fe02DcAa467c6a1070D19B82F718Bb5") +genesis.write(genesis_string) +genesis.close() diff --git a/.github/actions/upgrade-testing/scripts/get_proposal_id.py b/.github/actions/upgrade-testing/scripts/get_proposal_id.py new file mode 100644 index 0000000000..39105228de --- /dev/null +++ b/.github/actions/upgrade-testing/scripts/get_proposal_id.py @@ -0,0 +1,23 @@ +import json +import subprocess +import os + +os.environ['NODE'] = "http://127.0.0.1:26657" +def run_command(self, cmd): + COMMAND_PREFIX = "export PATH=" + self.go_path + ":${PATH} && " + cmd = COMMAND_PREFIX + cmd + result = subprocess.run(cmd, stdout=subprocess.PIPE, shell=True) + result_output = result.stdout.decode('utf-8') + return result_output + +try: + QUERY_GOV_PROPOSAL = f"""zetacored query gov proposals --output json --node {os.environ['NODE']}""" + GOV_PROPOSALS = json.loads(run_command(QUERY_GOV_PROPOSAL)) + for proposal in GOV_PROPOSALS["proposals"]: + try: + PROPOSAL_ID = proposal["id"] + except Exception as e: + print(1) + print(PROPOSAL_ID) +except Exception as e: + print(1) \ No newline at end of file diff --git a/.github/actions/upgrade-testing/scripts/raise_gov_proposal.py b/.github/actions/upgrade-testing/scripts/raise_gov_proposal.py new file mode 100644 index 0000000000..cd33a1a116 --- /dev/null +++ b/.github/actions/upgrade-testing/scripts/raise_gov_proposal.py @@ -0,0 +1,63 @@ +import os +import requests +import json + +os.environ['NODE'] = "http://127.0.0.1:26657" +CURRENT_HEIGHT = requests.get(f"{os.environ['NODE']}/status").json()["result"]["sync_info"]["latest_block_height"] +UPGRADE_HEIGHT = int(CURRENT_HEIGHT) + ( + int(os.environ['PROPOSAL_TIME_SECONDS']) / int(os.environ['BLOCK_TIME_SECONDS'])) + 20 +github_file = open(os.environ["GITHUB_ENV"], "a+") +github_file.write(f"UPGRADE_HEIGHT={UPGRADE_HEIGHT}") +github_file.close() + +proposal_json = { + "messages": [ + { + "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", + "authority": os.environ["GOV_ADDRESS"], + "plan": { + "name": os.environ['UPGRADE_NAME'], + "time": "0001-01-01T00:00:00Z", + "height": str(UPGRADE_HEIGHT).split('.')[0], + "info": os.environ["UPGRADE_INFO"], + "upgraded_client_state": None + } + } + ], + "metadata": os.environ["METADATA"], + "deposit": os.environ["DEPOSIT"] +} + +proposal_json = json.dumps(proposal_json) +write_gov_json = open("gov.json", "w") +write_gov_json.write(proposal_json) +write_gov_json.close() + +# GOV_PROPOSAL = f"""zetacored tx gov submit-proposal gov.json \ +# --from {os.environ['MONIKER']} \ +# --chain-id "{os.environ['CHAINID']}" \ +# --keyring-backend test \ +# --node "{os.environ['NODE']}" \ +# --gas=auto \ +# --gas-adjustment=2 \ +# --gas-prices={os.environ['GAS_PRICES']} \ +# -y +# """ + +GOV_PROPOSAL = f"""zetacored tx gov submit-legacy-proposal software-upgrade "{os.environ['UPGRADE_NAME']}" \ + --from "{os.environ['MONIKER']}" \ + --deposit {os.environ["DEPOSIT"]} \ + --upgrade-height "{str(UPGRADE_HEIGHT).split('.')[0]}" \ + --upgrade-info '{os.environ["UPGRADE_INFO"]}' \ + --title "{os.environ['VERSION']}" \ + --description "Zeta Release {os.environ['UPGRADE_NAME']}" \ + --chain-id "{os.environ['CHAINID']}" \ + --node "{os.environ['NODE']}" \ + --keyring-backend test \ + --gas=auto \ + --gas-adjustment=2 \ + --gas-prices={os.environ['GAS_PRICES']} \ + -y \ + --no-validate""" + +print(GOV_PROPOSAL) diff --git a/.github/labeler.yml b/.github/labeler.yml index aebf63e968..293796511c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -4,3 +4,6 @@ breaking:proto: breaking:cli: - "x/*/client/cli/*.go" - "cmd/**/*.go" + +ci: + - ".github/**" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce4ba4a4dc..f6012ce610 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -245,7 +245,6 @@ jobs: shell: alpine.sh --root {0} run: | git config --global --add safe.directory '*' - go mod tidy make install-testnet cp "$HOME"/go/bin/* ./ diff --git a/.github/workflows/sast-linters.yml b/.github/workflows/sast-linters.yml index 8b86ea3c6c..79efac1562 100644 --- a/.github/workflows/sast-linters.yml +++ b/.github/workflows/sast-linters.yml @@ -33,10 +33,33 @@ jobs: # uses: ./.github/actions/install-dependencies - name: Run Gosec Security Scanner - run: | - export PATH=$PATH:$(go env GOPATH)/bin - go install github.com/securego/gosec/v2/cmd/gosec@latest - gosec ./... + uses: securego/gosec@master + with: + args: ./... + + gosec-cosmos: + runs-on: ubuntu-latest + env: + GO111MODULE: on + steps: + - name: Checkout Source + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '1.20' + + # - name: Install Pipeline Dependencies + # uses: ./.github/actions/install-dependencies + + - name: Run Cosmos Gosec Security Scanner + uses: cosmos/gosec@master + with: + args: './... -include=G701,G703,G704' # Disabled G702 as it doesn't seem to be relevant 2023-09-14 + git-guardian: runs-on: ubuntu-latest @@ -68,18 +91,18 @@ jobs: with: fetch-depth: 0 - - name: Install Pipeline Dependencies - uses: ./.github/actions/install-dependencies + # - name: Install Pipeline Dependencies + # uses: ./.github/actions/install-dependencies - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: '1.20' - name: Run golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.50 + version: v1.54 skip-cache: true args: --timeout=15m @@ -137,8 +160,11 @@ jobs: Be very careful about using `#nosec` in code. It can be a quick way to suppress security warnings and move forward with development, it should be employed with caution. Suppressing warnings with #nosec can hide potentially serious vulnerabilities. Only use #nosec when you're absolutely certain that the security issue is either a false positive or has been mitigated in another way. + Only suppress a single rule (or a specific set of rules) within a section of code, while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within the #nosec annotation, e.g: /* #nosec G401 */ or //#nosec G201 G202 G203 + Broad `#nosec` annotations should be avoided, as they can hide other vulnerabilities. **The CI will block you from merging this PR until you remove `#nosec` annotations that do not target specific rules**. + Pay extra attention to the way `#nosec` is being used in the files listed above. - + - name: Add Label uses: actions/github-script@v6 if: env.nosec_detected == 1 @@ -150,3 +176,11 @@ jobs: repo: context.repo.repo, labels: ["nosec"] }) + + - name: Check for '#nosec' without a specific rule + run: | + DIFF=$(git diff ${{ github.event.pull_request.base.sha }}) + echo "$DIFF" | grep -P '#nosec(?!(\sG\d{3}))(?![^\s\t])([\s\t]*|$)' && echo "nosec without specified rule found!" && exit 1 || exit 0 + + + \ No newline at end of file diff --git a/.github/workflows/upgrade_path_testing.yaml b/.github/workflows/upgrade_path_testing.yaml new file mode 100644 index 0000000000..fffc7fcbda --- /dev/null +++ b/.github/workflows/upgrade_path_testing.yaml @@ -0,0 +1,432 @@ +name: "UPGRADE_PATH_TESTING" + +on: + workflow_dispatch: + inputs: + version: + description: 'The new version of tag you are going to download the binary from..' + required: true + default: 'v10.0.0-rc2' + upgrade_name: + description: 'The version that is set in setup_handlers.go' + required: true + default: 'v10.0.0' + +jobs: + upgrade_path_test_state_export: + name: "UPGRADE_PATH_TEST_STATE_EXPORT" + runs-on: ["buildjet-8vcpu-ubuntu-2204"] + env: + latest_state_export: "https://zetachain-external-files.s3.amazonaws.com/state-export/athens3/latest.json" + github_binary_version_link: "https://github.com/zeta-chain/node/releases/download/${{ github.event.inputs.version }}/zetacored-ubuntu-22-amd64" + downloaded_binary_name: "zetacored-ubuntu-22-amd64" + VERSION: "${{ github.event.inputs.version }}" + aws_region: "us-east-1" + GAS_PRICES: "1.0azeta" + DEPOSIT: "10000000000000000000azeta" + METADATA: "ipfs://QmeABfwZ2nAxDzYyqZ1LEypPgQFMjEyrx8FfnoPLkF8R3f" + LOG_LEVEL: "INFO" + CHAINID: "localnet_101-1" + DAEMON_HOME: "/home/runner/.zetacored" + UPGRADE_NAME: "${{ github.event.inputs.upgrade_name }}" + DAEMON_NAME: "zetacored" + DENOM: "azeta" + DAEMON_ALLOW_DOWNLOAD_BINARIES: "true" + DAEMON_RESTART_AFTER_UPGRADE: "true" + MONIKER: "zeta" + BLOCK_TIME_SECONDS: "6" + PROPOSAL_TIME_SECONDS: "60" + UNSAFE_SKIP_BACKUP: "true" + CLIENT_DAEMON_NAME: "zetaclientd" + CLIENT_DAEMON_ARGS: "-enable-chains,GOERLI,-val,zeta" + CLIENT_SKIP_UPGRADE: "true" + CLIENT_START_PROCESS: "false" + BINARY_NAME_SUFFIX: "ubuntu-22-amd64" + UPGRADES_SLEEP_TIME: "300" + KEYRING: "test" + STATUS_ENDPOINT: "http://127.0.0.1:26657/status" + ABCI_ENDPOINT: "http://127.0.0.1:26657/abci_info" + ENDPOINT: "http://127.0.0.1:26657" + SLEEP_DURATION: "5" + GOV_ADDRESS: "zeta10d07y265gmmuvt4z0w9aw880jnsr700jvxasvr" + previous_height: "-1" + stalled_count: "0" + first: "true" + MAX_TRIES: "100" + count: "0" + steps: + - uses: actions/checkout@v1 + + - id: install-aws-cli + uses: unfor19/install-aws-cli-action@v1 + with: + version: 2 + + - uses: actions/setup-go@v4 + with: + check-latest: false + go-version: '^1.20' + + - name: "CLONE:ZETAVISOR:REPOSITORY" + uses: actions/checkout@v2 + with: + repository: zeta-chain/cosmos-sdk + path: zetavisor/ + ref: zetavisor-v0.1.5 + + - name: "INSTALL_APT_PACKAGES" + working-directory: "zetavisor/cosmovisor" + run: | + echo "*********INSTALL SOME APT PACKAGES*********" + sudo apt update + sudo apt install unzip psmisc -y + + - name: "INSTALL_ZETAVISOR" + working-directory: "zetavisor/cosmovisor" + run: | + echo "*********INSTALL ZETAVISOR*********" + go get github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/zetavisor + go install github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/zetavisor + zetavisor version || echo "zetavisor failed to install." + + echo "*********SETUP ZETAVISOR DIRECTORIES*********" + rm -rf /home/runner/.zetacored + mkdir -p /home/runner/.zetacored/zetavisor + mkdir -p /home/runner/.zetacored/zetavisor/genesis/bin + mkdir -p /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin + mkdir -p /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.upgrade_name }}/bin + + - name: "DOWNLOAD_STATE_EXPORT_AND_BINARIES" + run: | + echo "*********DOWNLOAD STATE EXPORT*********" + wget -q ${latest_state_export} + + echo "*********DOWNLOAD UPGRADE BINARY AND PUT IN ZETAVISOR UPGRADES FOLDER*********" + wget -q ${github_binary_version_link} -O /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored + ZETACORED_CHECKSUM=$(shasum -b -a 256 /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored | cut -d ' ' -f 1) + sudo chmod a+x /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored + + echo "UPGRADE_INFO=${UPGRADE_INFO}" >> ${GITHUB_ENV} + ls -lah /home/runner/.zetacored/zetavisor/upgrades/ + ls -lah /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored + + wget -q ${github_binary_version_link} -O /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.upgrade_name }}/bin/zetacored + ZETACORED_CHECKSUM=$(shasum -b -a 256 /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.upgrade_name }}/bin/zetacored | cut -d ' ' -f 1) + sudo chmod a+x /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.upgrade_name }}/bin/zetacored + + echo "UPGRADE_INFO=${UPGRADE_INFO}" >> ${GITHUB_ENV} + ls -lah /home/runner/.zetacored/zetavisor/upgrades/ + ls -lah /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.upgrade_name }}/bin/zetacored + + echo "ZETACORED_CHECKSUM=${ZETACORED_CHECKSUM}" >> ${GITHUB_ENV} + UPGRADE_INFO='{"binaries": {"zetacored-linux/amd64": "https://github.com/zeta-chain/node/releases/download/${{ github.event.inputs.version }}/zetacored-ubuntu-22-amd64?checksum=sha256:'${ZETACORED_CHECKSUM}'"}}' + echo ${UPGRADE_INFO} + + + + echo "*********DOWNLOAD CURRENT BINARY AND PUT IN ZETAVISOR GENESIS & CURRENT FOLDER*********" + current_version=$(curl https://rpc-archive.athens.zetachain.com:26657/abci_info -s | jq .result.response.version -r | tr -d '\n') + echo "STARTING_VERSION=${current_version}" >> ${GITHUB_ENV} + echo "STARTING_VERSION=${current_version}" + wget -q https://github.com/zeta-chain/node/releases/download/${current_version}/zetacored-ubuntu-22-amd64 -O /home/runner/.zetacored/zetavisor/genesis/bin/zetacored + sudo chmod a+x /home/runner/.zetacored/zetavisor/genesis/bin/zetacored + echo "PATH=/home/runner/.zetacored/zetavisor/genesis/bin:$PATH" >> ${GITHUB_ENV} + + - name: "START_TESTING_NETWORK" + run: | + zetacored config keyring-backend $KEYRING --home ${DAEMON_HOME} + + zetacored config chain-id $CHAINID --home ${DAEMON_HOME} + + zetacored keys delete zetaa --keyring-backend $KEYRING -y > /dev/null 2>&1 || echo "doesn't exist" + zetacored keys delete executer_zeta --keyring-backend $KEYRING -y > /dev/null 2>&1 || echo "doesn't exist" + zetacored keys delete mario --keyring-backend $KEYRING -y > /dev/null 2>&1 || echo "doesn't exist" + zetacored keys delete executer_mario --keyring-backend $KEYRING -y > /dev/null 2>&1 || echo "doesn't exist" + + echo "race draft rival universe maid cheese steel logic crowd fork comic easy truth drift tomorrow eye buddy head time cash swing swift midnight borrow" | zetacored keys add zeta --algo=secp256k1 --recover --keyring-backend=$KEYRING + echo "hand inmate canvas head lunar naive increase recycle dog ecology inhale december wide bubble hockey dice worth gravity ketchup feed balance parent secret orchard" | zetacored keys add mario --algo secp256k1 --recover --keyring-backend=$KEYRING + echo "lounge supply patch festival retire duck foster decline theme horror decline poverty behind clever harsh layer primary syrup depart fantasy session fossil dismiss east" | zetacored keys add executer_zeta --recover --keyring-backend=$KEYRING --algo secp256k1 + echo "debris dumb among crew celery derive judge spoon road oyster dad panic adult song attack net pole merge mystery pig actual penalty neither peasant"| zetacored keys add executer_mario --algo=secp256k1 --recover --keyring-backend=$KEYRING + + echo ' + [ + { + "IsObserver": "y", + "ObserverAddress": "zeta13c7p3xrhd6q2rx3h235jpt8pjdwvacyw6twpax", + "ZetaClientGranteeAddress": "zeta10up34mvwjhjd9xkq56fwsf0k75vtg287uav69n", + "ZetaClientGranteePubKey": "zetapub1addwnpepqtlu7fykuh875xjckz4mn4x0mzc25rrqk5qne7mrwxqmatgllv3nx6lrkdp" + }, + { + "IsObserver": "y", + "ObserverAddress": "zeta1f203dypqg5jh9hqfx0gfkmmnkdfuat3jr45ep2", + "ZetaClientGranteeAddress": "zeta1unzpyll3tmutf0r8sqpxpnj46vtdr59mw8qepx", + "ZetaClientGranteePubKey": "zetapub1addwnpepqwy5pmg39regpq0gkggxehmfm8hwmxxw94sch7qzh4smava0szs07kk5045" + } + ] + ' > observers.json + + zetacored init Zetanode-Localnet --chain-id=$CHAINID + + #Set config to use azeta + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="azeta"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="azeta"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="azeta"' > ~/.zetacored/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="azeta"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["evm"]["params"]["evm_denom"]="azeta"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="10000000"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + cat $DAEMON_HOME/config/genesis.json | jq '.app_state["gov"]["voting_params"]["voting_period"]="60s"' > $DAEMON_HOME/config/tmp_genesis.json && mv $DAEMON_HOME/config/tmp_genesis.json $DAEMON_HOME/config/genesis.json + + sed -i '/\[api\]/,+3 s/enable = false/enable = true/' $DAEMON_HOME/config/app.toml + + zetacored add-observer-list observers.json --keygen-block=5 + + zetacored gentx zeta 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING + + echo "Collecting genesis txs..." + zetacored collect-gentxs + + echo "Validating genesis file..." + zetacored validate-genesis + + cp $DAEMON_HOME/config/genesis.json ./genesis.json + + echo "Do Genesis Manipulation" + export OLD_GENESIS=./latest.json + export NEW_GENESIS=./genesis.json + + python .github/actions/upgrade-testing/scripts/create_genesis.py + + echo "Move Manipulated Genesis" + cp ./genesis-edited.json $DAEMON_HOME/config/genesis.json + + echo "Start Network" + nohup zetavisor start --rpc.laddr tcp://0.0.0.0:26657 --minimum-gas-prices ${GAS_PRICES} "--grpc.enable=true" > cosmovisor.log 2>&1 & + + sleep ${UPGRADES_SLEEP_TIME} + cat cosmovisor.log + + - name: "DETERMINE_UPGRADE_TYPE" + shell: python + run: | + import os + + first_version=os.environ["STARTING_VERSION"] + first_major_version = first_version.split(".")[0] + first_minor_version = first_version.split(".")[1] + first_sub_version = first_version.split(".")[2] + + version="${{ github.event.inputs.version }}" + major_version = version.split(".")[0] + minor_version = version.split(".")[1] + sub_version = version.split(".")[2] + + git_env_file = open(os.environ["GITHUB_ENV"], "a+") + if major_version == first_major_version and minor_version != first_minor_version: + git_env_file.write("UPGRADE_TYPE=NONCON") + elif major_version == first_major_version and minor_version == first_minor_version and sub_version != first_sub_version: + git_env_file.write("UPGRADE_TYPE=NONCON") + else: + git_env_file.write("UPGRADE_TYPE=GOV") + git_env_file.close() + + - name: "NON_CONSENSUS_BREAKING_UPGRADE" + if: env.UPGRADE_TYPE == 'NONCON' + run: | + echo ${UPGRADE_TYPE} + echo "*********CHECK VERSION BEFORE BINARY SWITCH*********" + zetavisor version + + echo "*********KILLALL ZETAVISOR*********" + killall zetavisor + + echo "*********COPY UPGRADE BINARY TO NEW LOCATION*********" + rm -rf /home/runner/.zetacored/zetavisor/genesis/bin/zetacored + rm -rf /home/runner/.zetacored/zetavisor/current/bin/zetacored + + cp /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored /home/runner/.zetacored/zetavisor/genesis/bin/zetacored + cp /home/runner/.zetacored/zetavisor/upgrades/${{ github.event.inputs.version }}/bin/zetacored /home/runner/.zetacored/zetavisor/current/bin/zetacored + nohup zetavisor start --rpc.laddr tcp://0.0.0.0:26657 --minimum-gas-prices ${GAS_PRICES} "--grpc.enable=true" > cosmovisor.log 2>&1 & + + sleep ${UPGRADES_SLEEP_TIME} + cat cosmovisor.log + echo "*********CHECK VERSION AFTER BINARY SWITCH*********" + check_version=$(zetavisor version | tr -d '\n') + http_version=$(curl http://127.0.0.1:26657/abci_info | jq .result.response.version -r | tr -d '\n') + + echo "END_VERSION=${{ github.event.inputs.version }}" + echo "CURRENT_VERSION_BINARY=${check_version}" + echo "CURRENT_VERSION_HTTP=${http_version}" + + if [ "${{ github.event.inputs.version }}" == "${check_version}" ]; then + if [ "${{ github.event.inputs.version }}" == "${http_version}" ]; then + echo "*********VERSION MATCHES UPGRADE SUCCESS*********" + exit 0 + else + echo "*********VERSION DOESN'T MATCH UPGRADE FAILED*********" + exit 2 + fi + else + echo "*********VERSION DOESN'T MATCH UPGRADE FAILED*********" + exit 2 + fi + + - name: "CONSENSUS_BREAKING_UPGRADE" + if: env.UPGRADE_TYPE == 'GOV' #GOV + run: | + echo "*****UPGRADE TYPE*****" + echo ${UPGRADE_TYPE} + + echo "*****BUILD GOV PROPOSAL*****" + GOV_PROPOSAL=$(python .github/actions/upgrade-testing/scripts/raise_gov_proposal.py) + + echo "${GOV_PROPOSAL}" + cat gov.json + + GOV_PROPOSAL_OUTPUT=$(eval ${GOV_PROPOSAL}) + + echo "*****GOV PROPOSAL OUTPUT*****" + echo ${GOV_PROPOSAL_OUTPUT} + + echo "*****GET TX HASH*****" + TX_HASH=$(echo ${GOV_PROPOSAL_OUTPUT} | awk -F'txhash: ' '{print $2}' | tr -d '\n' | tr -d ' ') + echo "****TXHASH: ${TX_HASH}****" + + echo "*****SLEEP FOR 1 MIN TO ALLOW TX TO MAKE IT ON NETWORK*****" + sleep 15 + + zetacored query tx --type=hash ${TX_HASH} + + proposal_id=$(python .github/actions/upgrade-testing/scripts/get_proposal_id.py) + echo "****PROPOSAL_ID: ${proposal_id}****" + + source ${GITHUB_ENV} + + zetacored tx gov vote "${proposal_id}" yes \ + --from ${MONIKER} \ + --keyring-backend test \ + --chain-id ${CHAINID} \ + --node http://127.0.0.1:26657 \ + --gas=auto \ + --gas-adjustment=2 \ + --gas-prices=${{ env.GAS_PRICES }} \ + -y + + sleep 5 + zetacored query gov proposal ${proposal_id} --node http://127.0.0.1:26657 + + TARGET_HEIGHT=$(echo ${UPGRADE_HEIGHT} | cut -d '.' -f 1) + + echo "**** CHECK FOR HEIGHT ${TARGET_HEIGHT} ****" + while [[ $count -lt $MAX_TRIES ]] + do + echo "CURL FOR CURRENT HEIGHT" + response=$(curl -s "$ENDPOINT/status" || echo "failed curl") + if [ $? -ne 0 ]; then + echo "CURL failed with exit code $?" + else + echo "curl success" + fi + echo "curl success" + echo "${response}" + current_height=$(echo $response | jq '.result.sync_info.latest_block_height' | tr -d '"') + echo "Current Height: $current_height" + echo "Target Height: $TARGET_HEIGHT" + + if [[ $current_height -ge $TARGET_HEIGHT ]]; then + echo "Reached target height: $current_height. Sleep and wait for upgrade to take place." + sleep 120 + break + fi + + echo "attempt number ${count} of ${MAX_TRIES}" + ((count=count+1)) + echo "sleep and ty again." + sleep 10 + done + + if [[ $count -eq $MAX_TRIES ]]; then + cat cosmovisor.log + echo "Max tries reached without achieving target height." + exit 2 + fi + + for (( i=1; i<=MAX_TRIES; i++ )) + do + pgrep zetavisor > /dev/null + if [[ $? -ne 0 ]]; then + cat cosmovisor.log + echo "zetavisor process not found." + exit 2 + fi + + response=$(curl -s "$STATUS_ENDPOINT") + + # If curl fails + if [[ $? -ne 0 ]]; then + cat cosmovisor.log + echo "Failed to get a response from the status endpoint on try $i." + exit 2 + fi + + # Extracting the current height from the response + current_height=$(echo $response | jq '.result.sync_info.latest_block_height' | tr -d '"') + + # If jq fails or height is empty + if [[ $? -ne 0 || -z "$current_height" ]]; then + cat cosmovisor.log + echo "Failed to extract block height from the response on try $i." + exit 2 + fi + + # If the block height has changed since last check + if [[ $current_height -ne $previous_height ]]; then + if [ "${first}" == "true" ]; then + stalled_count=0 + first="false" + else + echo "Network appears to be processing blocks" + stalled_count=0 + + # Query the ABCI endpoint for version info + abci_response=$(curl -s "$ABCI_ENDPOINT") + + # Extracting the version from the response + app_version=$(echo $abci_response | jq '.result.response.version' | tr -d '"') + + # If jq fails or version is empty + if [[ $? -ne 0 || -z "$app_version" ]]; then + cat cosmovisor.log + echo "Failed to extract version from the ABCI response on try $i." + exit 2 + fi + + # Compare the extracted version with the expected version + if [[ "$app_version" == "$VERSION" ]]; then + echo "Version matches the expected version. Exiting..." + echo "ABCI RESPONSE \n ${abci_response}" + echo "Versions: $VERSION, Found: $app_version" + exit 0 + else + cat cosmovisor.log + echo "Version mismatch. Expected: $VERSION, Found: $app_version" + echo "ABCI RESPONSE \n ${abci_response}" + exit 2 + fi + fi + else + ((stalled_count=stalled_count+1)) + fi + + # Update the previous height + previous_height=$current_height + + # If we're on the last iteration and the block height hasn't changed for all tries + if [[ $i -eq $MAX_TRIES && $stalled_count -eq $MAX_TRIES ]]; then + cat cosmovisor.log + echo "Block height hasn't changed for $MAX_TRIES consecutive checks. Network might be stalled." + exit 2 + fi + + # Sleep for the specified duration + sleep $SLEEP_DURATION + done \ No newline at end of file diff --git a/Makefile b/Makefile index 019f5cef68..063540ef86 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,8 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=zetacore \ BUILD_FLAGS := -ldflags '$(ldflags)' -tags PRIVNET,pebbledb,ledger TESTNET_BUILD_FLAGS := -ldflags '$(ldflags)' -tags TESTNET,pebbledb,ledger +MOCK_MAINNET_BUILD_FLAGS := -ldflags '$(ldflags)' -tags MOCK_MAINNET,pebbledb,ledger +MAINNET_BUILD_FLAGS := -ldflags '$(ldflags)' -tags pebbledb,ledger TEST_DIR?="./..." TEST_BUILD_FLAGS := -tags TESTNET,pebbledb,ledger @@ -82,8 +84,19 @@ build-testnet-ubuntu: go.sum install: go.sum @echo "--> Installing zetacored & zetaclientd" - @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored - @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd + @go install -race -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored + @go install -race -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd + +install-mainnet: go.sum + @echo "--> Installing zetacored & zetaclientd" + @go install -mod=readonly $(MAINNET_BUILD_FLAGS) ./cmd/zetacored + @go install -mod=readonly $(MAINNET_BUILD_FLAGS) ./cmd/zetaclientd + +install-mock-mainnet: go.sum + @echo "--> Installing zetacored & zetaclientd" + @go install -mod=readonly $(MOCK_MAINNET_BUILD_FLAGS) ./cmd/zetacored + @go install -mod=readonly $(MOCK_MAINNET_BUILD_FLAGS) ./cmd/zetaclientd + install-zetaclient: go.sum @echo "--> Installing zetaclientd" @@ -129,6 +142,9 @@ chain-stop: chain-init-testnet: clean install-zetacore-testnet init chain-run-testnet: clean install-zetacore-testnet init run +chain-init-mock-mainnet: clean install-mock-mainnet init +chain-run-mock-mainnet: clean install-mock-mainnet init run + lint-pre: @test -z $(gofmt -l .) @GOFLAGS=$(GOFLAGS) go mod verify @@ -157,6 +173,10 @@ specs: @go run ./scripts/gen-spec.go .PHONY: specs +mocks: + @echo "--> Generating mocks" + @bash ./scripts/mocks-generate.sh + generate: proto openapi specs .PHONY: generate diff --git a/app/app.go b/app/app.go index 42c2cc6d20..53bfee51cd 100644 --- a/app/app.go +++ b/app/app.go @@ -464,7 +464,7 @@ func New( groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, interfaceRegistry), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, evmSs), feemarket.NewAppModule(app.FeeMarketKeeper, feeSs), - zetaCoreModule.NewAppModule(appCodec, app.ZetaCoreKeeper, app.StakingKeeper), + zetaCoreModule.NewAppModule(appCodec, app.ZetaCoreKeeper, app.StakingKeeper, app.AccountKeeper), zetaObserverModule.NewAppModule(appCodec, *app.ZetaObserverKeeper, app.AccountKeeper, app.BankKeeper), fungibleModule.NewAppModule(appCodec, app.FungibleKeeper, app.AccountKeeper, app.BankKeeper), emissionsModule.NewAppModule(appCodec, app.EmissionsKeeper, app.AccountKeeper), diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 66e168f7ee..47d63564ad 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -5,23 +5,18 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -const releaseVersion = "v9.0.0" +const releaseVersion = "v10.0.0" func SetupHandlers(app *App) { app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { app.Logger().Info("Running upgrade handler for " + releaseVersion) - // Updated version map to the latest consensus versions from each module for m, mb := range app.mm.Modules { vm[m] = mb.ConsensusVersion() } - vm[observertypes.ModuleName] = vm[observertypes.ModuleName] - 1 - vm[crosschaintypes.ModuleName] = vm[crosschaintypes.ModuleName] - 1 - SetParams(app, ctx) + return app.mm.RunMigrations(ctx, app.configurator, vm) }) @@ -40,11 +35,3 @@ func SetupHandlers(app *App) { app.SetStoreLoader(types.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } } - -// SetParams sets the default params for the observer module -// A new policy has been added for add_observer. -func SetParams(app *App, ctx sdk.Context) { - params := app.ZetaObserverKeeper.GetParamsIsExists(ctx) - params.AdminPolicy = observertypes.DefaultAdminPolicy() - app.ZetaObserverKeeper.SetParams(ctx, params) -} diff --git a/cmd/config_mainnet.go b/cmd/config_mainnet.go index bb50270c19..dcc8c4f9e2 100644 --- a/cmd/config_mainnet.go +++ b/cmd/config_mainnet.go @@ -1,5 +1,5 @@ -//go:build !PRIVNET && !TESTNET -// +build !PRIVNET,!TESTNET +//go:build !PRIVNET && !TESTNET && !MOCK_MAINNET +// +build !PRIVNET,!TESTNET,!MOCK_MAINNET package cmd @@ -13,9 +13,4 @@ const ( DenomRegex = `[a-zA-Z][a-zA-Z0-9:\\/\\\-\\_\\.]{2,127}` ZetaChainCoinType uint32 = 60 ZetaChainHDPath string = `m/44'/60'/0'/0/0` - NET = "TESTNET" -) - -var ( - CHAINID = "zeta_7001-1" ) diff --git a/cmd/config_mock_mainnet.go b/cmd/config_mock_mainnet.go new file mode 100644 index 0000000000..c8f775c61c --- /dev/null +++ b/cmd/config_mock_mainnet.go @@ -0,0 +1,16 @@ +//go:build MOCK_MAINNET +// +build MOCK_MAINNET + +package cmd + +const ( + Bech32PrefixAccAddr = "zeta" + Bech32PrefixAccPub = "zetapub" + Bech32PrefixValAddr = "zetav" + Bech32PrefixValPub = "zetavpub" + Bech32PrefixConsAddr = "zetac" + Bech32PrefixConsPub = "zetacpub" + DenomRegex = `[a-zA-Z][a-zA-Z0-9:\\/\\\-\\_\\.]{2,127}` + ZetaChainCoinType uint32 = 60 + ZetaChainHDPath string = `m/44'/60'/0'/0/0` +) diff --git a/cmd/zetaclientd/init.go b/cmd/zetaclientd/init.go index 303ce02e90..79ef1833cb 100644 --- a/cmd/zetaclientd/init.go +++ b/cmd/zetaclientd/init.go @@ -1,10 +1,8 @@ package main import ( - etherminttypes "github.com/evmos/ethermint/types" "github.com/rs/zerolog" "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/zetaclient/config" ) @@ -86,16 +84,7 @@ func Initialize(_ *cobra.Command, _ []string) error { configData.TssPath = initArgs.TssPath configData.P2PDiagnosticTicker = initArgs.p2pDiagnosticTicker configData.ConfigUpdateTicker = initArgs.configUpdateTicker - initChainID(&configData) //Save config file return config.Save(&configData, rootArgs.zetaCoreHome) } - -func initChainID(configData *config.Config) { - ZEVMChainID, err := etherminttypes.ParseChainID(configData.ChainID) - if err != nil { - panic(err) - } - configData.EVMChainConfigs[common.ZetaChain().ChainId].Chain.ChainId = ZEVMChainID.Int64() -} diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 2cfb8d4a0a..0932f8bff3 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -243,6 +243,10 @@ func start(_ *cobra.Command, _ []string) error { // stop zetacore observer for _, chain := range cfg.GetEnabledChains() { + // zeta chain does not have a chain client + if chain.IsZetaChain() { + continue + } (chainClientMap)[chain].Stop() } zetaBridge.Stop() diff --git a/cmd/zetacored/observer_accounts.go b/cmd/zetacored/observer_accounts.go index 5efc118277..397146a688 100644 --- a/cmd/zetacored/observer_accounts.go +++ b/cmd/zetacored/observer_accounts.go @@ -28,6 +28,10 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) +// Token distribution +// Validators Only = ValidatorTokens sent to their operator address +// Observer = ObserverTokens sent to their operator address + HotkeyTokens sent to their hotkey address +// HotkeyTokens are for operational expenses such as paying for gas fees const ( ValidatorTokens = "100000000000000000000000" ObserverTokens = "4100000000000000000000000" diff --git a/common/chain.go b/common/chain.go index c0286a1f8d..0952a64b49 100644 --- a/common/chain.go +++ b/common/chain.go @@ -102,6 +102,12 @@ func IsEVMChain(chainID int64) bool { chainID == 137 // polygon mainnet } +func IsEthereum(chainID int64) bool { + return chainID == 5 || // Goerli + chainID == 1337 || // eth privnet + chainID == 1 // eth mainnet +} + func (chain Chain) IsKlaytnChain() bool { return chain.ChainId == 1001 } diff --git a/common/common.pb.go b/common/common.pb.go index 683a844041..4277cc8dc6 100644 --- a/common/common.pb.go +++ b/common/common.pb.go @@ -11,6 +11,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/gogo/protobuf/proto" + ethereum "github.com/zeta-chain/zetacore/common/ethereum" ) // Reference imports to suppress errors if they are not otherwise used. @@ -255,48 +256,284 @@ func (m *Chain) GetChainId() int64 { return 0 } +type BlockHeader struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + ParentHash []byte `protobuf:"bytes,3,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` + ChainId int64 `protobuf:"varint,4,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // chain specific header + Header HeaderData `protobuf:"bytes,5,opt,name=header,proto3" json:"header"` +} + +func (m *BlockHeader) Reset() { *m = BlockHeader{} } +func (m *BlockHeader) String() string { return proto.CompactTextString(m) } +func (*BlockHeader) ProtoMessage() {} +func (*BlockHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{2} +} +func (m *BlockHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlockHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlockHeader.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 *BlockHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockHeader.Merge(m, src) +} +func (m *BlockHeader) XXX_Size() int { + return m.Size() +} +func (m *BlockHeader) XXX_DiscardUnknown() { + xxx_messageInfo_BlockHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockHeader proto.InternalMessageInfo + +func (m *BlockHeader) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *BlockHeader) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *BlockHeader) GetParentHash() []byte { + if m != nil { + return m.ParentHash + } + return nil +} + +func (m *BlockHeader) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *BlockHeader) GetHeader() HeaderData { + if m != nil { + return m.Header + } + return HeaderData{} +} + +type HeaderData struct { + // Types that are valid to be assigned to Data: + // + // *HeaderData_EthereumHeader + Data isHeaderData_Data `protobuf_oneof:"data"` +} + +func (m *HeaderData) Reset() { *m = HeaderData{} } +func (m *HeaderData) String() string { return proto.CompactTextString(m) } +func (*HeaderData) ProtoMessage() {} +func (*HeaderData) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{3} +} +func (m *HeaderData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeaderData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeaderData.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 *HeaderData) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeaderData.Merge(m, src) +} +func (m *HeaderData) XXX_Size() int { + return m.Size() +} +func (m *HeaderData) XXX_DiscardUnknown() { + xxx_messageInfo_HeaderData.DiscardUnknown(m) +} + +var xxx_messageInfo_HeaderData proto.InternalMessageInfo + +type isHeaderData_Data interface { + isHeaderData_Data() + MarshalTo([]byte) (int, error) + Size() int +} + +type HeaderData_EthereumHeader struct { + EthereumHeader []byte `protobuf:"bytes,1,opt,name=ethereum_header,json=ethereumHeader,proto3,oneof" json:"ethereum_header,omitempty"` +} + +func (*HeaderData_EthereumHeader) isHeaderData_Data() {} + +func (m *HeaderData) GetData() isHeaderData_Data { + if m != nil { + return m.Data + } + return nil +} + +func (m *HeaderData) GetEthereumHeader() []byte { + if x, ok := m.GetData().(*HeaderData_EthereumHeader); ok { + return x.EthereumHeader + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*HeaderData) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*HeaderData_EthereumHeader)(nil), + } +} + +type Proof struct { + // Types that are valid to be assigned to Proof: + // + // *Proof_EthereumProof + Proof isProof_Proof `protobuf_oneof:"proof"` +} + +func (m *Proof) Reset() { *m = Proof{} } +func (m *Proof) String() string { return proto.CompactTextString(m) } +func (*Proof) ProtoMessage() {} +func (*Proof) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{4} +} +func (m *Proof) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Proof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Proof.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 *Proof) XXX_Merge(src proto.Message) { + xxx_messageInfo_Proof.Merge(m, src) +} +func (m *Proof) XXX_Size() int { + return m.Size() +} +func (m *Proof) XXX_DiscardUnknown() { + xxx_messageInfo_Proof.DiscardUnknown(m) +} + +var xxx_messageInfo_Proof proto.InternalMessageInfo + +type isProof_Proof interface { + isProof_Proof() + MarshalTo([]byte) (int, error) + Size() int +} + +type Proof_EthereumProof struct { + EthereumProof *ethereum.Proof `protobuf:"bytes,1,opt,name=ethereum_proof,json=ethereumProof,proto3,oneof" json:"ethereum_proof,omitempty"` +} + +func (*Proof_EthereumProof) isProof_Proof() {} + +func (m *Proof) GetProof() isProof_Proof { + if m != nil { + return m.Proof + } + return nil +} + +func (m *Proof) GetEthereumProof() *ethereum.Proof { + if x, ok := m.GetProof().(*Proof_EthereumProof); ok { + return x.EthereumProof + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Proof) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Proof_EthereumProof)(nil), + } +} + func init() { proto.RegisterEnum("common.ReceiveStatus", ReceiveStatus_name, ReceiveStatus_value) proto.RegisterEnum("common.CoinType", CoinType_name, CoinType_value) proto.RegisterEnum("common.ChainName", ChainName_name, ChainName_value) proto.RegisterType((*PubKeySet)(nil), "common.PubKeySet") proto.RegisterType((*Chain)(nil), "common.Chain") + proto.RegisterType((*BlockHeader)(nil), "common.BlockHeader") + proto.RegisterType((*HeaderData)(nil), "common.HeaderData") + proto.RegisterType((*Proof)(nil), "common.Proof") } func init() { proto.RegisterFile("common/common.proto", fileDescriptor_8f954d82c0b891f6) } var fileDescriptor_8f954d82c0b891f6 = []byte{ - // 476 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x92, 0x41, 0x8b, 0xd3, 0x40, - 0x14, 0xc7, 0x93, 0x76, 0x9b, 0x34, 0xaf, 0x6b, 0x3b, 0xce, 0x0a, 0xae, 0x7b, 0xc8, 0xca, 0xa2, - 0x20, 0x0b, 0x6e, 0x77, 0x2b, 0x55, 0xc4, 0x83, 0xb0, 0x41, 0x45, 0x04, 0x91, 0x74, 0x4f, 0x7b, - 0x29, 0x93, 0xc9, 0x23, 0x09, 0x26, 0x99, 0x90, 0x4c, 0x84, 0xfa, 0x29, 0xfc, 0x0a, 0x82, 0x07, - 0x3f, 0x8a, 0xc7, 0x3d, 0x7a, 0x5a, 0xa4, 0xfd, 0x16, 0x9e, 0x64, 0x26, 0x4d, 0xea, 0x29, 0x6f, - 0x7e, 0xf3, 0x7b, 0xf3, 0xfe, 0x64, 0x06, 0x0e, 0xb8, 0xc8, 0x32, 0x91, 0x4f, 0x9b, 0xcf, 0x59, - 0x51, 0x0a, 0x29, 0xa8, 0xd5, 0xac, 0x8e, 0xee, 0x45, 0x22, 0x12, 0x1a, 0x4d, 0x55, 0xd5, 0xec, - 0x9e, 0xc4, 0xe0, 0x7c, 0xaa, 0x83, 0x0f, 0xb8, 0x5a, 0xa0, 0xa4, 0x73, 0x70, 0x2a, 0xe4, 0xc5, - 0x6c, 0xfe, 0xfc, 0xf3, 0xc5, 0xa1, 0xf9, 0xd0, 0x7c, 0xe2, 0x5c, 0xde, 0x5f, 0xdf, 0x1e, 0x3b, - 0x8b, 0x16, 0xfe, 0xbd, 0x3d, 0xb6, 0x1a, 0xdd, 0xdf, 0x99, 0xf4, 0x11, 0xd8, 0x18, 0xce, 0xe6, - 0xf3, 0x8b, 0x97, 0x87, 0x3d, 0xdd, 0x04, 0xff, 0x79, 0xed, 0xd6, 0xc9, 0x15, 0x0c, 0xbc, 0x98, - 0x25, 0x39, 0x3d, 0x07, 0xe0, 0xaa, 0x58, 0xe6, 0x2c, 0x43, 0x3d, 0x66, 0x3c, 0xbb, 0x7b, 0xb6, - 0xcd, 0xac, 0x95, 0x8f, 0x2c, 0x43, 0xdf, 0xe1, 0x6d, 0x49, 0x1f, 0xc0, 0xb0, 0xe9, 0x48, 0x42, - 0x3d, 0xa1, 0xef, 0xdb, 0x7a, 0xfd, 0x3e, 0x3c, 0x7d, 0x05, 0x77, 0x7c, 0xe4, 0x98, 0x7c, 0xc1, - 0x85, 0x64, 0xb2, 0xae, 0xe8, 0x08, 0x6c, 0xaf, 0x44, 0x26, 0x31, 0x24, 0x86, 0x5a, 0x2c, 0x6a, - 0xce, 0xb1, 0xaa, 0x88, 0x49, 0x01, 0xac, 0xb7, 0x2c, 0x49, 0x31, 0x24, 0xbd, 0xa3, 0xbd, 0x9f, - 0x3f, 0x5c, 0xf3, 0xf4, 0x05, 0x0c, 0x3d, 0x91, 0xe4, 0x57, 0xab, 0x02, 0xe9, 0x10, 0xf6, 0xae, - 0x51, 0x32, 0x62, 0x50, 0x1b, 0xfa, 0xef, 0x98, 0x6a, 0x70, 0x60, 0xf0, 0xc6, 0xf7, 0x66, 0xe7, - 0xa4, 0xa7, 0x98, 0x97, 0x85, 0xa4, 0xbf, 0x6d, 0xfc, 0xde, 0x03, 0xa7, 0x4b, 0xaa, 0x3c, 0xcc, - 0x0a, 0xb9, 0x22, 0x06, 0x9d, 0xc0, 0x08, 0x65, 0xbc, 0xcc, 0x58, 0x92, 0xe7, 0x28, 0x89, 0x49, - 0x09, 0xec, 0x7f, 0x45, 0xc9, 0x3a, 0xd2, 0x53, 0x4a, 0x20, 0x79, 0x07, 0xfa, 0xf4, 0x00, 0x26, - 0x85, 0x48, 0x57, 0x91, 0xc8, 0x3b, 0xb8, 0xa7, 0xad, 0x6a, 0x67, 0x0d, 0x28, 0x85, 0x71, 0x24, - 0xb0, 0x4c, 0x93, 0xa5, 0xc4, 0x4a, 0x2a, 0x66, 0x29, 0x96, 0xd5, 0x59, 0xc0, 0x76, 0xcc, 0x56, - 0xa7, 0x45, 0x2c, 0x67, 0x3c, 0xc6, 0x0e, 0x0e, 0x95, 0x18, 0x30, 0x11, 0xb0, 0xa0, 0x63, 0x4e, - 0x3b, 0xa1, 0x05, 0xd0, 0x45, 0x6d, 0xc9, 0xa8, 0x8d, 0xda, 0x82, 0x7d, 0x7d, 0x78, 0x13, 0x22, - 0x15, 0x9c, 0xa5, 0x0a, 0x8e, 0x5b, 0xab, 0xc4, 0x48, 0x89, 0x64, 0xd2, 0xfc, 0xa3, 0xcb, 0xd7, - 0xbf, 0xd6, 0xae, 0x79, 0xb3, 0x76, 0xcd, 0x3f, 0x6b, 0xd7, 0xfc, 0xb6, 0x71, 0x8d, 0x9b, 0x8d, - 0x6b, 0xfc, 0xde, 0xb8, 0xc6, 0xf5, 0xe3, 0x28, 0x91, 0x71, 0x1d, 0xa8, 0x2b, 0x9f, 0xaa, 0x89, - 0x4f, 0xf5, 0x65, 0xea, 0x92, 0x8b, 0x12, 0xb7, 0xcf, 0x37, 0xb0, 0xf4, 0x0b, 0x7d, 0xf6, 0x2f, - 0x00, 0x00, 0xff, 0xff, 0xba, 0x90, 0x73, 0x66, 0xd6, 0x02, 0x00, 0x00, + // 639 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x94, 0xcb, 0x6a, 0xdb, 0x4c, + 0x14, 0x80, 0x25, 0x5f, 0x64, 0xeb, 0xc8, 0xb1, 0xf5, 0x4f, 0x7e, 0xfe, 0x3f, 0xcd, 0x42, 0x0e, + 0xa6, 0x85, 0x34, 0xd0, 0x5c, 0x5c, 0xdc, 0x0b, 0x5d, 0x04, 0xec, 0x5e, 0xdc, 0x16, 0x4a, 0x90, + 0xb3, 0xca, 0xc6, 0x8c, 0xa4, 0x53, 0x49, 0xc4, 0xd2, 0x08, 0x69, 0x5c, 0x70, 0x9f, 0xa2, 0xaf, + 0x50, 0x28, 0xb4, 0x8f, 0x92, 0x65, 0x96, 0x5d, 0x85, 0xe2, 0xbc, 0x45, 0x57, 0x65, 0x46, 0x17, + 0xa7, 0x2b, 0x9f, 0xf9, 0xce, 0x77, 0x2e, 0xf2, 0xc8, 0x86, 0x6d, 0x97, 0x45, 0x11, 0x8b, 0x8f, + 0xf2, 0x8f, 0xc3, 0x24, 0x65, 0x9c, 0x11, 0x2d, 0x3f, 0xed, 0x5a, 0x45, 0x12, 0x79, 0x80, 0x29, + 0x2e, 0xa3, 0x2a, 0xc8, 0xbd, 0xdd, 0x7f, 0x7d, 0xe6, 0x33, 0x19, 0x1e, 0x89, 0x28, 0xa7, 0x83, + 0x00, 0xf4, 0xb3, 0xa5, 0xf3, 0x1e, 0x57, 0x33, 0xe4, 0x64, 0x04, 0x7a, 0x86, 0x6e, 0x32, 0x1c, + 0x3d, 0xb9, 0x3c, 0xd9, 0x51, 0xf7, 0xd4, 0x7d, 0x7d, 0xfc, 0xff, 0xfa, 0xa6, 0xaf, 0xcf, 0x4a, + 0xf8, 0xfb, 0xa6, 0xaf, 0xe5, 0xba, 0xbd, 0x31, 0xc9, 0x7d, 0x68, 0xa1, 0x37, 0x1c, 0x8d, 0x4e, + 0x9e, 0xef, 0xd4, 0x64, 0x11, 0xdc, 0xf1, 0xca, 0xd4, 0xe0, 0x1c, 0x9a, 0x93, 0x80, 0x86, 0x31, + 0x39, 0x06, 0x70, 0x45, 0x30, 0x8f, 0x69, 0x84, 0x72, 0x4c, 0x77, 0xf8, 0xcf, 0x61, 0xf1, 0x4c, + 0x52, 0xf9, 0x40, 0x23, 0xb4, 0x75, 0xb7, 0x0c, 0xc9, 0x3d, 0x68, 0xe7, 0x15, 0xa1, 0x27, 0x27, + 0xd4, 0xed, 0x96, 0x3c, 0xbf, 0xf5, 0x06, 0xdf, 0x55, 0x30, 0xc6, 0x0b, 0xe6, 0x5e, 0x4e, 0x91, + 0x7a, 0x98, 0x92, 0xff, 0x40, 0x0b, 0x30, 0xf4, 0x03, 0x2e, 0x1b, 0xd7, 0xed, 0xe2, 0x44, 0x08, + 0x34, 0x02, 0x9a, 0x05, 0xb2, 0xbc, 0x63, 0xcb, 0x98, 0xf4, 0xc1, 0x48, 0x68, 0x8a, 0x31, 0x9f, + 0xcb, 0x54, 0x5d, 0xa6, 0x20, 0x47, 0x53, 0x21, 0xdc, 0x9d, 0xdb, 0xf8, 0x6b, 0x2e, 0x39, 0x16, + 0x73, 0xc4, 0xc4, 0x9d, 0xe6, 0x9e, 0xba, 0x6f, 0x0c, 0x49, 0xf9, 0x00, 0xf9, 0x1e, 0x2f, 0x29, + 0xa7, 0xe3, 0xc6, 0xd5, 0x4d, 0x5f, 0xb1, 0x0b, 0x6f, 0x70, 0x0a, 0xb0, 0xc9, 0x91, 0x87, 0xd0, + 0x2b, 0xef, 0x67, 0x5e, 0x34, 0x12, 0x0b, 0x77, 0xa6, 0x8a, 0xdd, 0x2d, 0x13, 0xb9, 0x3e, 0xd6, + 0xa0, 0xe1, 0x51, 0x4e, 0x07, 0xef, 0xa0, 0x79, 0x96, 0x32, 0xf6, 0x91, 0x3c, 0x83, 0x4a, 0x99, + 0x27, 0x82, 0xc8, 0x52, 0x63, 0xd8, 0x3b, 0xac, 0xae, 0x5c, 0x8a, 0x53, 0xc5, 0xde, 0x2a, 0x89, + 0x04, 0xe3, 0x16, 0x34, 0x65, 0xc1, 0xc1, 0x0b, 0xd8, 0xb2, 0xd1, 0xc5, 0xf0, 0x13, 0xce, 0x38, + 0xe5, 0xcb, 0x8c, 0x18, 0xd0, 0x9a, 0xa4, 0x48, 0x39, 0x7a, 0xa6, 0x22, 0x0e, 0xb3, 0xa5, 0xeb, + 0x62, 0x96, 0x99, 0x2a, 0x01, 0xd0, 0x5e, 0xd3, 0x70, 0x81, 0x9e, 0x59, 0xdb, 0x6d, 0xfc, 0xf8, + 0x66, 0xa9, 0x07, 0x4f, 0xa1, 0x3d, 0x61, 0x61, 0x7c, 0xbe, 0x4a, 0x90, 0xb4, 0xa1, 0x71, 0x81, + 0x9c, 0x9a, 0x0a, 0x69, 0x41, 0xfd, 0x0d, 0x15, 0x05, 0x3a, 0x34, 0x5f, 0xd9, 0x93, 0xe1, 0xb1, + 0x59, 0x13, 0x6c, 0x12, 0x79, 0x66, 0xbd, 0x28, 0xfc, 0x5a, 0x03, 0xbd, 0xba, 0x60, 0xe1, 0x61, + 0x94, 0xf0, 0x95, 0xa9, 0x90, 0x1e, 0x18, 0xc8, 0x83, 0x79, 0x44, 0xc3, 0x38, 0x46, 0x6e, 0xaa, + 0xc4, 0x84, 0xce, 0x67, 0xe4, 0xb4, 0x22, 0x35, 0xa1, 0x38, 0xdc, 0xad, 0x40, 0x9d, 0x6c, 0x43, + 0x2f, 0x61, 0x8b, 0x95, 0xcf, 0xe2, 0x0a, 0x36, 0xa4, 0x95, 0x6d, 0xac, 0x26, 0x21, 0xd0, 0xf5, + 0x19, 0xa6, 0x8b, 0x70, 0xce, 0x31, 0xe3, 0x82, 0x69, 0x82, 0x45, 0xcb, 0xc8, 0xa1, 0x1b, 0xd6, + 0x12, 0xdd, 0x7c, 0x1a, 0x53, 0x37, 0xc0, 0x0a, 0xb6, 0x85, 0xe8, 0x50, 0xe6, 0x50, 0xa7, 0x62, + 0x7a, 0x39, 0xa1, 0x04, 0x50, 0xad, 0x5a, 0x12, 0xa3, 0x5c, 0xb5, 0x04, 0x1d, 0xd9, 0x3c, 0x5f, + 0x62, 0xc1, 0x5c, 0xba, 0x10, 0xb0, 0x5b, 0x5a, 0x29, 0xfa, 0x42, 0x34, 0x7b, 0xf9, 0x77, 0x34, + 0x3e, 0xbd, 0x5a, 0x5b, 0xea, 0xf5, 0xda, 0x52, 0x7f, 0xad, 0x2d, 0xf5, 0xcb, 0xad, 0xa5, 0x5c, + 0xdf, 0x5a, 0xca, 0xcf, 0x5b, 0x4b, 0xb9, 0x78, 0xe0, 0x87, 0x3c, 0x58, 0x3a, 0xe2, 0x45, 0x3b, + 0x12, 0x13, 0x1f, 0xc9, 0x77, 0x51, 0x86, 0x2e, 0x4b, 0xb1, 0xf8, 0x57, 0x70, 0x34, 0xf9, 0xc3, + 0x7e, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x3c, 0x8a, 0x97, 0x2d, 0x04, 0x00, 0x00, } func (m *PubKeySet) Marshal() (dAtA []byte, err error) { @@ -369,6 +606,164 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *BlockHeader) 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 *BlockHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlockHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if m.ChainId != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x20 + } + if len(m.ParentHash) > 0 { + i -= len(m.ParentHash) + copy(dAtA[i:], m.ParentHash) + i = encodeVarintCommon(dAtA, i, uint64(len(m.ParentHash))) + i-- + dAtA[i] = 0x1a + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintCommon(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *HeaderData) 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 *HeaderData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeaderData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + { + size := m.Data.Size() + i -= size + if _, err := m.Data.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *HeaderData_EthereumHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeaderData_EthereumHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EthereumHeader != nil { + i -= len(m.EthereumHeader) + copy(dAtA[i:], m.EthereumHeader) + i = encodeVarintCommon(dAtA, i, uint64(len(m.EthereumHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *Proof) 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 *Proof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Proof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Proof != nil { + { + size := m.Proof.Size() + i -= size + if _, err := m.Proof.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *Proof_EthereumProof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Proof_EthereumProof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EthereumProof != nil { + { + size, err := m.EthereumProof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} func encodeVarintCommon(dAtA []byte, offset int, v uint64) int { offset -= sovCommon(v) base := offset @@ -394,31 +789,307 @@ func (m *PubKeySet) Size() (n int) { if l > 0 { n += 1 + l + sovCommon(uint64(l)) } - return n -} + return n +} + +func (m *Chain) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainName != 0 { + n += 1 + sovCommon(uint64(m.ChainName)) + } + if m.ChainId != 0 { + n += 1 + sovCommon(uint64(m.ChainId)) + } + return n +} + +func (m *BlockHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovCommon(uint64(m.Height)) + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = len(m.ParentHash) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + if m.ChainId != 0 { + n += 1 + sovCommon(uint64(m.ChainId)) + } + l = m.Header.Size() + n += 1 + l + sovCommon(uint64(l)) + return n +} + +func (m *HeaderData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Data != nil { + n += m.Data.Size() + } + return n +} + +func (m *HeaderData_EthereumHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EthereumHeader != nil { + l = len(m.EthereumHeader) + n += 1 + l + sovCommon(uint64(l)) + } + return n +} +func (m *Proof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Proof != nil { + n += m.Proof.Size() + } + return n +} + +func (m *Proof_EthereumProof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EthereumProof != nil { + l = m.EthereumProof.Size() + n += 1 + l + sovCommon(uint64(l)) + } + return n +} + +func sovCommon(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCommon(x uint64) (n int) { + return sovCommon(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PubKeySet) 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 ErrIntOverflowCommon + } + 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: PubKeySet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubKeySet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Secp256k1", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + 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 ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Secp256k1 = PubKey(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + 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 ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ed25519 = PubKey(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Chain) 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 ErrIntOverflowCommon + } + 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: Chain: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainName", wireType) + } + m.ChainName = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainName |= ChainName(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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 ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func (m *Chain) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ChainName != 0 { - n += 1 + sovCommon(uint64(m.ChainName)) - } - if m.ChainId != 0 { - n += 1 + sovCommon(uint64(m.ChainId)) + if iNdEx > l { + return io.ErrUnexpectedEOF } - return n -} - -func sovCommon(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozCommon(x uint64) (n int) { - return sovCommon(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + return nil } -func (m *PubKeySet) Unmarshal(dAtA []byte) error { +func (m *BlockHeader) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -441,17 +1112,36 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PubKeySet: wiretype end group for non-group") + return fmt.Errorf("proto: BlockHeader: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PubKeySet: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockHeader: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Secp256k1", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -461,29 +1151,31 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthCommon } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthCommon } if postIndex > l { return io.ErrUnexpectedEOF } - m.Secp256k1 = PubKey(dAtA[iNdEx:postIndex]) + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ParentHash", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -493,23 +1185,77 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthCommon } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthCommon } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ed25519 = PubKey(dAtA[iNdEx:postIndex]) + m.ParentHash = append(m.ParentHash[:0], dAtA[iNdEx:postIndex]...) + if m.ParentHash == nil { + m.ParentHash = []byte{} + } + iNdEx = postIndex + case 4: + 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 ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -532,7 +1278,7 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } return nil } -func (m *Chain) Unmarshal(dAtA []byte) error { +func (m *HeaderData) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -555,17 +1301,17 @@ func (m *Chain) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Chain: wiretype end group for non-group") + return fmt.Errorf("proto: HeaderData: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HeaderData: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainName", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeader", wireType) } - m.ChainName = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -575,16 +1321,80 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChainName |= ChainName(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + if byteLen < 0 { + return ErrInvalidLengthCommon } - m.ChainId = 0 + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.Data = &HeaderData_EthereumHeader{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Proof) 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 ErrIntOverflowCommon + } + 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: Proof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Proof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EthereumProof", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -594,11 +1404,27 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChainId |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := ðereum.Proof{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Proof = &Proof_EthereumProof{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommon(dAtA[iNdEx:]) diff --git a/common/default_chains_mainnet.go b/common/default_chains_mainnet.go index c57cd2f1be..18868b5a13 100644 --- a/common/default_chains_mainnet.go +++ b/common/default_chains_mainnet.go @@ -1,5 +1,5 @@ -//go:build !PRIVNET && !TESTNET -// +build !PRIVNET,!TESTNET +//go:build !PRIVNET && !TESTNET && !MOCK_MAINNET +// +build !PRIVNET,!TESTNET,!MOCK_MAINNET package common @@ -20,7 +20,7 @@ func BscMainnetChain() Chain { func ZetaChain() Chain { return Chain{ ChainName: ChainName_zeta_mainnet, - ChainId: 101, + ChainId: 7000, } } @@ -41,7 +41,6 @@ func PolygonChain() Chain { func DefaultChainsList() []*Chain { chains := []Chain{ BtcMainnetChain(), - PolygonChain(), BscMainnetChain(), EthChain(), ZetaChain(), @@ -52,3 +51,16 @@ func DefaultChainsList() []*Chain { } return c } + +func ExternalChainList() []*Chain { + chains := []Chain{ + BtcMainnetChain(), + BscMainnetChain(), + EthChain(), + } + var c []*Chain + for i := 0; i < len(chains); i++ { + c = append(c, &chains[i]) + } + return c +} diff --git a/common/default_chains_mock_mainnet.go b/common/default_chains_mock_mainnet.go new file mode 100644 index 0000000000..6498ed087e --- /dev/null +++ b/common/default_chains_mock_mainnet.go @@ -0,0 +1,66 @@ +//go:build MOCK_MAINNET +// +build MOCK_MAINNET + +package common + +func EthChain() Chain { + return Chain{ + ChainName: ChainName_eth_mainnet, + ChainId: 1, + } +} + +func BscMainnetChain() Chain { + return Chain{ + ChainName: ChainName_bsc_mainnet, + ChainId: 56, + } +} + +func ZetaChain() Chain { + return Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 70000, + } +} + +func BtcMainnetChain() Chain { + return Chain{ + ChainName: ChainName_btc_mainnet, + ChainId: 8332, + } +} + +func PolygonChain() Chain { + return Chain{ + ChainName: ChainName_polygon_mainnet, + ChainId: 137, + } +} + +func DefaultChainsList() []*Chain { + chains := []Chain{ + BtcMainnetChain(), + BscMainnetChain(), + EthChain(), + ZetaChain(), + } + var c []*Chain + for i := 0; i < len(chains); i++ { + c = append(c, &chains[i]) + } + return c +} + +func ExternalChainList() []*Chain { + chains := []Chain{ + BtcMainnetChain(), + BscMainnetChain(), + EthChain(), + } + var c []*Chain + for i := 0; i < len(chains); i++ { + c = append(c, &chains[i]) + } + return c +} diff --git a/common/default_chains_privnet.go b/common/default_chains_privnet.go index 328799d7c8..f415cc0af7 100644 --- a/common/default_chains_privnet.go +++ b/common/default_chains_privnet.go @@ -36,3 +36,15 @@ func DefaultChainsList() []*Chain { } return c } + +func ExternalChainList() []*Chain { + chains := []Chain{ + BtcRegtestChain(), + GoerliChain(), + } + var c []*Chain + for i := 0; i < len(chains); i++ { + c = append(c, &chains[i]) + } + return c +} diff --git a/common/default_chains_testnet.go b/common/default_chains_testnet.go index 23942c1e22..74473464ca 100644 --- a/common/default_chains_testnet.go +++ b/common/default_chains_testnet.go @@ -52,3 +52,17 @@ func DefaultChainsList() []*Chain { } return c } + +func ExternalChainList() []*Chain { + chains := []Chain{ + BtcTestNetChain(), + MumbaiChain(), + BscTestnetChain(), + GoerliChain(), + } + var c []*Chain + for i := 0; i < len(chains); i++ { + c = append(c, &chains[i]) + } + return c +} diff --git a/common/ethereum/ethereum.pb.go b/common/ethereum/ethereum.pb.go new file mode 100644 index 0000000000..8dd8096019 --- /dev/null +++ b/common/ethereum/ethereum.pb.go @@ -0,0 +1,374 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: common/ethereum/ethereum.proto + +package ethereum + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Proof struct { + Keys [][]byte `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` + Values [][]byte `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"` +} + +func (m *Proof) Reset() { *m = Proof{} } +func (m *Proof) String() string { return proto.CompactTextString(m) } +func (*Proof) ProtoMessage() {} +func (*Proof) Descriptor() ([]byte, []int) { + return fileDescriptor_93e74b59a4555c70, []int{0} +} +func (m *Proof) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Proof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Proof.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 *Proof) XXX_Merge(src proto.Message) { + xxx_messageInfo_Proof.Merge(m, src) +} +func (m *Proof) XXX_Size() int { + return m.Size() +} +func (m *Proof) XXX_DiscardUnknown() { + xxx_messageInfo_Proof.DiscardUnknown(m) +} + +var xxx_messageInfo_Proof proto.InternalMessageInfo + +func (m *Proof) GetKeys() [][]byte { + if m != nil { + return m.Keys + } + return nil +} + +func (m *Proof) GetValues() [][]byte { + if m != nil { + return m.Values + } + return nil +} + +func init() { + proto.RegisterType((*Proof)(nil), "ethereum.Proof") +} + +func init() { proto.RegisterFile("common/ethereum/ethereum.proto", fileDescriptor_93e74b59a4555c70) } + +var fileDescriptor_93e74b59a4555c70 = []byte{ + // 159 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xce, 0xcf, 0xcd, + 0xcd, 0xcf, 0xd3, 0x4f, 0x2d, 0xc9, 0x48, 0x2d, 0x4a, 0x2d, 0xcd, 0x85, 0x33, 0xf4, 0x0a, 0x8a, + 0xf2, 0x4b, 0xf2, 0x85, 0x38, 0x60, 0x7c, 0x25, 0x63, 0x2e, 0xd6, 0x80, 0xa2, 0xfc, 0xfc, 0x34, + 0x21, 0x21, 0x2e, 0x96, 0xec, 0xd4, 0xca, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x9e, 0x20, 0x30, + 0x5b, 0x48, 0x8c, 0x8b, 0xad, 0x2c, 0x31, 0xa7, 0x34, 0xb5, 0x58, 0x82, 0x09, 0x2c, 0x0a, 0xe5, + 0x39, 0x79, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, + 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x5e, 0x7a, 0x66, + 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x55, 0x6a, 0x49, 0xa2, 0x6e, 0x72, 0x46, + 0x62, 0x66, 0x1e, 0x98, 0x99, 0x9c, 0x5f, 0x94, 0xaa, 0x8f, 0xe6, 0xae, 0x24, 0x36, 0xb0, 0x7b, + 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x31, 0x9b, 0x72, 0x4f, 0xb1, 0x00, 0x00, 0x00, +} + +func (m *Proof) 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 *Proof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Proof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Values) > 0 { + for iNdEx := len(m.Values) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Values[iNdEx]) + copy(dAtA[i:], m.Values[iNdEx]) + i = encodeVarintEthereum(dAtA, i, uint64(len(m.Values[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Keys) > 0 { + for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Keys[iNdEx]) + copy(dAtA[i:], m.Keys[iNdEx]) + i = encodeVarintEthereum(dAtA, i, uint64(len(m.Keys[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintEthereum(dAtA []byte, offset int, v uint64) int { + offset -= sovEthereum(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Proof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Keys) > 0 { + for _, b := range m.Keys { + l = len(b) + n += 1 + l + sovEthereum(uint64(l)) + } + } + if len(m.Values) > 0 { + for _, b := range m.Values { + l = len(b) + n += 1 + l + sovEthereum(uint64(l)) + } + } + return n +} + +func sovEthereum(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEthereum(x uint64) (n int) { + return sovEthereum(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Proof) 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 ErrIntOverflowEthereum + } + 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: Proof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Proof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEthereum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEthereum + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEthereum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx)) + copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEthereum + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEthereum + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEthereum + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Values = append(m.Values, make([]byte, postIndex-iNdEx)) + copy(m.Values[len(m.Values)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEthereum(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEthereum + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEthereum(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEthereum + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEthereum + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEthereum + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEthereum + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEthereum + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEthereum + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEthereum = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEthereum = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEthereum = fmt.Errorf("proto: unexpected end of group") +) diff --git a/common/ethereum/proof.go b/common/ethereum/proof.go new file mode 100644 index 0000000000..1ff6f705b4 --- /dev/null +++ b/common/ethereum/proof.go @@ -0,0 +1,168 @@ +// This file was adapted from go-ethereum. Here's the go-ethereum license reproduced: + +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package trie implements Merkle Patricia Tries. + +package ethereum + +import ( + "bytes" + "errors" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +func NewProof() *Proof { + return &Proof{ + Keys: make([][]byte, 0), + Values: make([][]byte, 0), + } +} + +func (m *Proof) Put(key []byte, value []byte) error { + for i := 0; i < len(m.Keys); i++ { + if bytes.Equal(m.Keys[i], key) { + m.Values[i] = value + return nil + } + } + m.Keys = append(m.Keys, key) + m.Values = append(m.Values, value) + + return nil +} + +func (m *Proof) Delete(key []byte) error { + found := false + index := -1 + for i := 0; i < len(m.Keys); i++ { + if bytes.Equal(m.Keys[i], key) { + found = true + index = i + break + } + } + if !found { + return errors.New("key not found") + } + copy(m.Keys[index:len(m.Keys)-1], m.Keys[index+1:]) + copy(m.Values[index:len(m.Values)-1], m.Values[index+1:]) + m.Keys = m.Keys[:len(m.Keys)-1] + m.Values = m.Values[:len(m.Values)-1] + + return nil +} + +func (m *Proof) Has(key []byte) (bool, error) { + for i := 0; i < len(m.Keys); i++ { + if bytes.Equal(m.Keys[i], key) { + + return true, nil + } + } + return false, nil +} + +func (m *Proof) Get(key []byte) ([]byte, error) { + found := false + index := -1 + for i := 0; i < len(m.Keys); i++ { + if bytes.Equal(m.Keys[i], key) { + found = true + index = i + break + } + } + if !found { + return nil, errors.New("key not found") + } + + return m.Values[index], nil +} + +// Verify verifies the proof against the given root hash and key. +// Typically, the rootHash is from a trusted source (e.g. a trusted block header), +// and the key is the index of the transaction in the block. +func (m *Proof) Verify(rootHash common.Hash, key int) ([]byte, error) { + var indexBuf []byte + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(key)) + return trie.VerifyProof(rootHash, indexBuf, m) +} + +type Trie struct { + *trie.Trie +} + +var encodeBufferPool = sync.Pool{ + New: func() interface{} { return new(bytes.Buffer) }, +} + +func encodeForDerive(list types.DerivableList, i int, buf *bytes.Buffer) []byte { + buf.Reset() + list.EncodeIndex(i, buf) + // It's really unfortunate that we need to do perform this copy. + // StackTrie holds onto the values until Hash is called, so the values + // written to it must not alias. + return common.CopyBytes(buf.Bytes()) +} + +func (t *Trie) GenerateProof(txIndex int) (*Proof, error) { + var indexBuf []byte + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(txIndex)) + proof := NewProof() + err := t.Prove(indexBuf, 0, proof) + if err != nil { + return nil, err + } + return proof, nil +} + +// NewTrie builds a trie from a DerivableList. The DerivableList must be types.Transactions +// or types.Receipts. +func NewTrie(list types.DerivableList) Trie { + hasher := new(trie.Trie) + hasher.Reset() + + valueBuf := encodeBufferPool.Get().(*bytes.Buffer) + defer encodeBufferPool.Put(valueBuf) + + // StackTrie requires values to be inserted in increasing hash order, which is not the + // order that `list` provides hashes in. This insertion sequence ensures that the + // order is correct. + var indexBuf []byte + for i := 1; i < list.Len() && i <= 0x7f; i++ { + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) + value := encodeForDerive(list, i, valueBuf) + hasher.Update(indexBuf, value) + } + if list.Len() > 0 { + indexBuf = rlp.AppendUint64(indexBuf[:0], 0) + value := encodeForDerive(list, 0, valueBuf) + hasher.Update(indexBuf, value) + } + for i := 0x80; i < list.Len(); i++ { + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) + value := encodeForDerive(list, i, valueBuf) + hasher.Update(indexBuf, value) + } + return Trie{hasher} +} diff --git a/common/ethereum/proof_test.go b/common/ethereum/proof_test.go new file mode 100644 index 0000000000..14a153ffc7 --- /dev/null +++ b/common/ethereum/proof_test.go @@ -0,0 +1,125 @@ +package ethereum + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +func TestProofGeneration(t *testing.T) { + RPC_URL := "https://rpc.ankr.com/eth_goerli" + client, err := ethclient.Dial(RPC_URL) + if err != nil { + t.Fatal(err) + } + bn := int64(9509129) + block, err := client.BlockByNumber(context.Background(), big.NewInt(bn)) + if err != nil { + t.Fatal(err) + } + + headerRLP, _ := rlp.EncodeToBytes(block.Header()) + t.Logf("block header size %d\n", len(headerRLP)) + + var header types.Header + rlp.DecodeBytes(headerRLP, &header) + + t.Logf("block %d\n", block.Number()) + t.Logf(" tx root %x\n", header.TxHash) + + //ttt := new(trie.Trie) + tr := NewTrie(block.Transactions()) + t.Logf(" sha2 %x\n", tr.Hash()) + if tr.Hash() != header.TxHash { + t.Fatal("tx root mismatch") + } else { + t.Logf(" tx root hash & block tx root match\n") + } + + var indexBuf []byte + for i := 0; i < len(block.Transactions()); i++ { + + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) + + proof := NewProof() + tr.Prove(indexBuf, 0, proof) + t.Logf("proof len %d\n", len(proof.Keys)) + value, err := proof.Verify(block.Header().TxHash, i) + //value, err := trie.VerifyProof(tr.trie.Hash(), indexBuf, proof) + t.Logf("pass? %v\n", err == nil) + //t.Logf("value %x\n", value) + + var txx types.Transaction + txx.UnmarshalBinary(value) + t.Logf(" tx %+v\n", txx.To().Hex()) + t.Logf(" tx hash %+v\n", txx.Hash().Hex()) + if txx.Hash() != block.Transactions()[i].Hash() { + t.Fatal("tx hash mismatch") + } else { + t.Logf(" tx hash & block tx hash match\n") + } + signer := types.NewLondonSigner(txx.ChainId()) + sender, err := types.Sender(signer, &txx) + t.Logf(" tx from %s\n", sender.Hex()) + } + + //for k, v := range proof.Proof { + // key, _ := base64.StdEncoding.DecodeString(k) + // t.Logf("k: %x, v: %x\n", key, v) + //} + + { + var receipts types.Receipts + for _, tx := range block.Transactions() { + receipt, err := client.TransactionReceipt(context.Background(), tx.Hash()) + if err != nil { + t.Fatal(err) + } + receipts = append(receipts, receipt) + time.Sleep(200 * time.Millisecond) + } + + receiptTree := NewTrie(receipts) + t.Logf(" block receipt root %x\n", block.Header().ReceiptHash) + t.Logf(" receipt tree root %x\n", receiptTree.Hash()) + if receiptTree.Hash() != block.Header().ReceiptHash { + t.Fatal("receipt root mismatch") + } else { + t.Logf(" receipt root hash & block receipt root match\n") + } + + i := 1 + proof := NewProof() + indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) + err = receiptTree.Prove(indexBuf, 0, proof) + if err != nil { + t.Fatal(err) + } + + // NOTE: eth receipts only hashes the following fields + // data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} + value, err := trie.VerifyProof(block.Header().ReceiptHash, indexBuf, proof) + t.Logf("pass? %v\n", err == nil) + t.Logf("value %x\n", value) + value, err = proof.Verify(block.Header().ReceiptHash, i) + if err != nil { + t.Fatal(err) + } + + var receipt types.Receipt + receipt.UnmarshalBinary(value) + + t.Logf(" receipt %+v\n", receipt) + t.Logf(" receipt tx hash %+v\n", receipt.TxHash.Hex()) + + for _, log := range receipt.Logs { + t.Logf(" log %+v\n", log) + } + } +} diff --git a/common/headers.go b/common/headers.go new file mode 100644 index 0000000000..e05a3f0c18 --- /dev/null +++ b/common/headers.go @@ -0,0 +1,68 @@ +package common + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// NewEthereumHeader returns a new HeaderData containing an Ethereum header +func NewEthereumHeader(header []byte) HeaderData { + return HeaderData{ + Data: &HeaderData_EthereumHeader{ + EthereumHeader: header, + }, + } +} + +// ParentHash extracts the parent hash from the header +func (h HeaderData) ParentHash() ([]byte, error) { + switch data := h.Data.(type) { + case *HeaderData_EthereumHeader: + var header ethtypes.Header + if err := rlp.DecodeBytes(data.EthereumHeader, &header); err != nil { + return nil, err + } + return header.ParentHash.Bytes(), nil + default: + return nil, errors.New("unrecognized header type") + } +} + +// Validate performs a basic validation of the HeaderData +func (h HeaderData) Validate(blockHash []byte, height int64) error { + switch data := h.Data.(type) { + case *HeaderData_EthereumHeader: + return validateEthereumHeader(data.EthereumHeader, blockHash, height) + default: + return errors.New("unrecognized header type") + } +} + +// validateEthereumHeader performs a basic validation of the Ethereum header +func validateEthereumHeader(headerBytes []byte, blockHash []byte, height int64) error { + // on ethereum the block header is ~538 bytes in RLP encoding + if len(headerBytes) > 1024 { + return fmt.Errorf("header too long (%d)", len(headerBytes)) + } + + // RLP encoded block header + var header ethtypes.Header + if err := rlp.DecodeBytes(headerBytes, &header); err != nil { + return fmt.Errorf("cannot decode RLP (%s)", err) + } + if err := header.SanityCheck(); err != nil { + return fmt.Errorf("sanity check failed (%s)", err) + } + if bytes.Compare(blockHash, header.Hash().Bytes()) != 0 { + return fmt.Errorf("tx hash mismatch (%s) vs (%s)", hex.EncodeToString(blockHash), header.Hash().Hex()) + } + if height != header.Number.Int64() { + return fmt.Errorf("height mismatch (%d) vs (%d)", height, header.Number.Int64()) + } + return nil +} diff --git a/common/proof.go b/common/proof.go new file mode 100644 index 0000000000..615c39b1f5 --- /dev/null +++ b/common/proof.go @@ -0,0 +1,61 @@ +package common + +import ( + "errors" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/zeta-chain/zetacore/common/ethereum" +) + +// ErrInvalidProof is a error type for invalid proofs embedding the underlying error +type ErrInvalidProof struct { + Err error +} + +func NewErrInvalidProof(err error) ErrInvalidProof { + return ErrInvalidProof{ + Err: err, + } +} + +func (e ErrInvalidProof) Error() string { + return e.Err.Error() +} + +// IsErrorInvalidProof returns true if the error is an ErrInvalidProof +func IsErrorInvalidProof(err error) bool { + return errors.As(err, &ErrInvalidProof{}) +} + +// NewEthereumProof returns a new Proof containing an Ethereum proof +func NewEthereumProof(proof *ethereum.Proof) *Proof { + return &Proof{ + Proof: &Proof_EthereumProof{ + EthereumProof: proof, + }, + } +} + +// Verify verifies the proof against the header +func (p Proof) Verify(headerData HeaderData, txIndex int) ([]byte, error) { + switch proof := p.Proof.(type) { + case *Proof_EthereumProof: + ethHeaderBytes := headerData.GetEthereumHeader() + if ethHeaderBytes == nil { + return nil, errors.New("can't verify ethereum proof against non-ethereum header") + } + var ethHeader ethtypes.Header + err := rlp.DecodeBytes(ethHeaderBytes, ðHeader) + if err != nil { + return nil, err + } + val, err := proof.EthereumProof.Verify(ethHeader.TxHash, txIndex) + if err != nil { + return nil, NewErrInvalidProof(err) + } + return val, nil + default: + return nil, errors.New("unrecognized proof type") + } +} diff --git a/common/proof_test.go b/common/proof_test.go new file mode 100644 index 0000000000..0615407684 --- /dev/null +++ b/common/proof_test.go @@ -0,0 +1,15 @@ +package common_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" +) + +func Test_IsErrorInvalidProof(t *testing.T) { + require.False(t, common.IsErrorInvalidProof(nil)) + require.False(t, common.IsErrorInvalidProof(errors.New("foo"))) + require.True(t, common.IsErrorInvalidProof(common.NewErrInvalidProof(errors.New("foo")))) +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi new file mode 100644 index 0000000000..ec8cc79f66 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi @@ -0,0 +1,670 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainid_", + "type": "uint256" + }, + { + "internalType": "enum CoinType", + "name": "coinType_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerIsNotFungibleModule", + "type": "error" + }, + { + "inputs": [], + "name": "GasFeeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "LowAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "LowBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasCoin", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasPrice", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "UpdatedGasLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "UpdatedProtocolFlatFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "systemContract", + "type": "address" + } + ], + "name": "UpdatedSystemContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasfee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COIN_TYPE", + "outputs": [ + { + "internalType": "enum CoinType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUNGIBLE_MODULE_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAS_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_FLAT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONTRACT_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newField", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newPublicField", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "updateGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newField_", + "type": "uint256" + } + ], + "name": "updateNewField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "updateProtocolFlatFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "updateSystemContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawGasFee", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin new file mode 100644 index 0000000000..9e74c2aaa3 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin @@ -0,0 +1 @@ +60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033 diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go new file mode 100644 index 0000000000..aef95ec0d1 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go @@ -0,0 +1,1925 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testzrc20 + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TestZRC20MetaData contains all meta data concerning the TestZRC20 contract. +var TestZRC20MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid_\",\"type\":\"uint256\"},{\"internalType\":\"enumCoinType\",\"name\":\"coinType_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerIsNotFungibleModule\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasFeeTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasCoin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasPrice\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"UpdatedGasLimit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedProtocolFlatFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"systemContract\",\"type\":\"address\"}],\"name\":\"UpdatedSystemContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasfee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHAIN_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COIN_TYPE\",\"outputs\":[{\"internalType\":\"enumCoinType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FUNGIBLE_MODULE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GAS_LIMIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROTOCOL_FLAT_FEE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONTRACT_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newField\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newPublicField\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"updateGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newField_\",\"type\":\"uint256\"}],\"name\":\"updateNewField\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"updateProtocolFlatFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"updateSystemContractAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawGasFee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033", +} + +// TestZRC20ABI is the input ABI used to generate the binding from. +// Deprecated: Use TestZRC20MetaData.ABI instead. +var TestZRC20ABI = TestZRC20MetaData.ABI + +// TestZRC20Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TestZRC20MetaData.Bin instead. +var TestZRC20Bin = TestZRC20MetaData.Bin + +// DeployTestZRC20 deploys a new Ethereum contract, binding an instance of TestZRC20 to it. +func DeployTestZRC20(auth *bind.TransactOpts, backend bind.ContractBackend, chainid_ *big.Int, coinType_ uint8) (common.Address, *types.Transaction, *TestZRC20, error) { + parsed, err := TestZRC20MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TestZRC20Bin), backend, chainid_, coinType_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TestZRC20{TestZRC20Caller: TestZRC20Caller{contract: contract}, TestZRC20Transactor: TestZRC20Transactor{contract: contract}, TestZRC20Filterer: TestZRC20Filterer{contract: contract}}, nil +} + +// TestZRC20 is an auto generated Go binding around an Ethereum contract. +type TestZRC20 struct { + TestZRC20Caller // Read-only binding to the contract + TestZRC20Transactor // Write-only binding to the contract + TestZRC20Filterer // Log filterer for contract events +} + +// TestZRC20Caller is an auto generated read-only Go binding around an Ethereum contract. +type TestZRC20Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Transactor is an auto generated write-only Go binding around an Ethereum contract. +type TestZRC20Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TestZRC20Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TestZRC20Session struct { + Contract *TestZRC20 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestZRC20CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TestZRC20CallerSession struct { + Contract *TestZRC20Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TestZRC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TestZRC20TransactorSession struct { + Contract *TestZRC20Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestZRC20Raw is an auto generated low-level Go binding around an Ethereum contract. +type TestZRC20Raw struct { + Contract *TestZRC20 // Generic contract binding to access the raw methods on +} + +// TestZRC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TestZRC20CallerRaw struct { + Contract *TestZRC20Caller // Generic read-only contract binding to access the raw methods on +} + +// TestZRC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TestZRC20TransactorRaw struct { + Contract *TestZRC20Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewTestZRC20 creates a new instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20(address common.Address, backend bind.ContractBackend) (*TestZRC20, error) { + contract, err := bindTestZRC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TestZRC20{TestZRC20Caller: TestZRC20Caller{contract: contract}, TestZRC20Transactor: TestZRC20Transactor{contract: contract}, TestZRC20Filterer: TestZRC20Filterer{contract: contract}}, nil +} + +// NewTestZRC20Caller creates a new read-only instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Caller(address common.Address, caller bind.ContractCaller) (*TestZRC20Caller, error) { + contract, err := bindTestZRC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TestZRC20Caller{contract: contract}, nil +} + +// NewTestZRC20Transactor creates a new write-only instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Transactor(address common.Address, transactor bind.ContractTransactor) (*TestZRC20Transactor, error) { + contract, err := bindTestZRC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TestZRC20Transactor{contract: contract}, nil +} + +// NewTestZRC20Filterer creates a new log filterer instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Filterer(address common.Address, filterer bind.ContractFilterer) (*TestZRC20Filterer, error) { + contract, err := bindTestZRC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TestZRC20Filterer{contract: contract}, nil +} + +// bindTestZRC20 binds a generic wrapper to an already deployed contract. +func bindTestZRC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TestZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestZRC20 *TestZRC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestZRC20.Contract.TestZRC20Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestZRC20 *TestZRC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestZRC20.Contract.TestZRC20Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestZRC20 *TestZRC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestZRC20.Contract.TestZRC20Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestZRC20 *TestZRC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestZRC20.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestZRC20 *TestZRC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestZRC20.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestZRC20 *TestZRC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestZRC20.Contract.contract.Transact(opts, method, params...) +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) CHAINID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "CHAIN_ID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) CHAINID() (*big.Int, error) { + return _TestZRC20.Contract.CHAINID(&_TestZRC20.CallOpts) +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) CHAINID() (*big.Int, error) { + return _TestZRC20.Contract.CHAINID(&_TestZRC20.CallOpts) +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20Caller) COINTYPE(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "COIN_TYPE") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20Session) COINTYPE() (uint8, error) { + return _TestZRC20.Contract.COINTYPE(&_TestZRC20.CallOpts) +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20CallerSession) COINTYPE() (uint8, error) { + return _TestZRC20.Contract.COINTYPE(&_TestZRC20.CallOpts) +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Caller) FUNGIBLEMODULEADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "FUNGIBLE_MODULE_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Session) FUNGIBLEMODULEADDRESS() (common.Address, error) { + return _TestZRC20.Contract.FUNGIBLEMODULEADDRESS(&_TestZRC20.CallOpts) +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20CallerSession) FUNGIBLEMODULEADDRESS() (common.Address, error) { + return _TestZRC20.Contract.FUNGIBLEMODULEADDRESS(&_TestZRC20.CallOpts) +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) GASLIMIT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "GAS_LIMIT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) GASLIMIT() (*big.Int, error) { + return _TestZRC20.Contract.GASLIMIT(&_TestZRC20.CallOpts) +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) GASLIMIT() (*big.Int, error) { + return _TestZRC20.Contract.GASLIMIT(&_TestZRC20.CallOpts) +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) PROTOCOLFLATFEE(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "PROTOCOL_FLAT_FEE") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) PROTOCOLFLATFEE() (*big.Int, error) { + return _TestZRC20.Contract.PROTOCOLFLATFEE(&_TestZRC20.CallOpts) +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) PROTOCOLFLATFEE() (*big.Int, error) { + return _TestZRC20.Contract.PROTOCOLFLATFEE(&_TestZRC20.CallOpts) +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Caller) SYSTEMCONTRACTADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "SYSTEM_CONTRACT_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Session) SYSTEMCONTRACTADDRESS() (common.Address, error) { + return _TestZRC20.Contract.SYSTEMCONTRACTADDRESS(&_TestZRC20.CallOpts) +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20CallerSession) SYSTEMCONTRACTADDRESS() (common.Address, error) { + return _TestZRC20.Contract.SYSTEMCONTRACTADDRESS(&_TestZRC20.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TestZRC20.Contract.Allowance(&_TestZRC20.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TestZRC20.Contract.Allowance(&_TestZRC20.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _TestZRC20.Contract.BalanceOf(&_TestZRC20.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _TestZRC20.Contract.BalanceOf(&_TestZRC20.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20Session) Decimals() (uint8, error) { + return _TestZRC20.Contract.Decimals(&_TestZRC20.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20CallerSession) Decimals() (uint8, error) { + return _TestZRC20.Contract.Decimals(&_TestZRC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20Session) Name() (string, error) { + return _TestZRC20.Contract.Name(&_TestZRC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) Name() (string, error) { + return _TestZRC20.Contract.Name(&_TestZRC20.CallOpts) +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) NewField(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "newField") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) NewField() (*big.Int, error) { + return _TestZRC20.Contract.NewField(&_TestZRC20.CallOpts) +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) NewField() (*big.Int, error) { + return _TestZRC20.Contract.NewField(&_TestZRC20.CallOpts) +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20Caller) NewPublicField(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "newPublicField") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20Session) NewPublicField() (string, error) { + return _TestZRC20.Contract.NewPublicField(&_TestZRC20.CallOpts) +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) NewPublicField() (string, error) { + return _TestZRC20.Contract.NewPublicField(&_TestZRC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20Session) Symbol() (string, error) { + return _TestZRC20.Contract.Symbol(&_TestZRC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) Symbol() (string, error) { + return _TestZRC20.Contract.Symbol(&_TestZRC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) TotalSupply() (*big.Int, error) { + return _TestZRC20.Contract.TotalSupply(&_TestZRC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) TotalSupply() (*big.Int, error) { + return _TestZRC20.Contract.TotalSupply(&_TestZRC20.CallOpts) +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20Caller) WithdrawGasFee(opts *bind.CallOpts) (common.Address, *big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "withdrawGasFee") + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20Session) WithdrawGasFee() (common.Address, *big.Int, error) { + return _TestZRC20.Contract.WithdrawGasFee(&_TestZRC20.CallOpts) +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20CallerSession) WithdrawGasFee() (common.Address, *big.Int, error) { + return _TestZRC20.Contract.WithdrawGasFee(&_TestZRC20.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "approve", spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Approve(&_TestZRC20.TransactOpts, spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Approve(&_TestZRC20.TransactOpts, spender, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "burn", amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Burn(amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Burn(&_TestZRC20.TransactOpts, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Burn(amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Burn(&_TestZRC20.TransactOpts, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "decreaseAllowance", spender, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) DecreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.DecreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) DecreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.DecreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Deposit(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "deposit", to, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Deposit(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Deposit(&_TestZRC20.TransactOpts, to, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Deposit(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Deposit(&_TestZRC20.TransactOpts, to, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "increaseAllowance", spender, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) IncreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.IncreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) IncreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.IncreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Transfer(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "transfer", recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Transfer(&_TestZRC20.TransactOpts, recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Transfer(&_TestZRC20.TransactOpts, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) TransferFrom(opts *bind.TransactOpts, sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "transferFrom", sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.TransferFrom(&_TestZRC20.TransactOpts, sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.TransferFrom(&_TestZRC20.TransactOpts, sender, recipient, amount) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateGasLimit(opts *bind.TransactOpts, gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateGasLimit", gasLimit) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20Session) UpdateGasLimit(gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateGasLimit(&_TestZRC20.TransactOpts, gasLimit) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateGasLimit(gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateGasLimit(&_TestZRC20.TransactOpts, gasLimit) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateNewField(opts *bind.TransactOpts, newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateNewField", newField_) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20Session) UpdateNewField(newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateNewField(&_TestZRC20.TransactOpts, newField_) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateNewField(newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateNewField(&_TestZRC20.TransactOpts, newField_) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateProtocolFlatFee(opts *bind.TransactOpts, protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateProtocolFlatFee", protocolFlatFee) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20Session) UpdateProtocolFlatFee(protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateProtocolFlatFee(&_TestZRC20.TransactOpts, protocolFlatFee) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateProtocolFlatFee(protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateProtocolFlatFee(&_TestZRC20.TransactOpts, protocolFlatFee) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateSystemContractAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateSystemContractAddress", addr) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20Session) UpdateSystemContractAddress(addr common.Address) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateSystemContractAddress(&_TestZRC20.TransactOpts, addr) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateSystemContractAddress(addr common.Address) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateSystemContractAddress(&_TestZRC20.TransactOpts, addr) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Withdraw(opts *bind.TransactOpts, to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "withdraw", to, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Withdraw(to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Withdraw(&_TestZRC20.TransactOpts, to, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Withdraw(to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Withdraw(&_TestZRC20.TransactOpts, to, amount) +} + +// TestZRC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the TestZRC20 contract. +type TestZRC20ApprovalIterator struct { + Event *TestZRC20Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Approval represents a Approval event raised by the TestZRC20 contract. +type TestZRC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TestZRC20ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &TestZRC20ApprovalIterator{contract: _TestZRC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TestZRC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Approval) + if err := _TestZRC20.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseApproval(log types.Log) (*TestZRC20Approval, error) { + event := new(TestZRC20Approval) + if err := _TestZRC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20DepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the TestZRC20 contract. +type TestZRC20DepositIterator struct { + Event *TestZRC20Deposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20DepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20DepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20DepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Deposit represents a Deposit event raised by the TestZRC20 contract. +type TestZRC20Deposit struct { + From []byte + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterDeposit(opts *bind.FilterOpts, to []common.Address) (*TestZRC20DepositIterator, error) { + + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Deposit", toRule) + if err != nil { + return nil, err + } + return &TestZRC20DepositIterator{contract: _TestZRC20.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *TestZRC20Deposit, to []common.Address) (event.Subscription, error) { + + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Deposit", toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Deposit) + if err := _TestZRC20.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseDeposit(log types.Log) (*TestZRC20Deposit, error) { + event := new(TestZRC20Deposit) + if err := _TestZRC20.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the TestZRC20 contract. +type TestZRC20TransferIterator struct { + Event *TestZRC20Transfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20TransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20TransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Transfer represents a Transfer event raised by the TestZRC20 contract. +type TestZRC20Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TestZRC20TransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &TestZRC20TransferIterator{contract: _TestZRC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TestZRC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Transfer) + if err := _TestZRC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseTransfer(log types.Log) (*TestZRC20Transfer, error) { + event := new(TestZRC20Transfer) + if err := _TestZRC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedGasLimitIterator is returned from FilterUpdatedGasLimit and is used to iterate over the raw logs and unpacked data for UpdatedGasLimit events raised by the TestZRC20 contract. +type TestZRC20UpdatedGasLimitIterator struct { + Event *TestZRC20UpdatedGasLimit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedGasLimitIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedGasLimit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedGasLimit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedGasLimitIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedGasLimitIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedGasLimit represents a UpdatedGasLimit event raised by the TestZRC20 contract. +type TestZRC20UpdatedGasLimit struct { + GasLimit *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedGasLimit is a free log retrieval operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedGasLimit(opts *bind.FilterOpts) (*TestZRC20UpdatedGasLimitIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedGasLimit") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedGasLimitIterator{contract: _TestZRC20.contract, event: "UpdatedGasLimit", logs: logs, sub: sub}, nil +} + +// WatchUpdatedGasLimit is a free log subscription operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedGasLimit(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedGasLimit) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedGasLimit") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedGasLimit) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedGasLimit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedGasLimit is a log parse operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedGasLimit(log types.Log) (*TestZRC20UpdatedGasLimit, error) { + event := new(TestZRC20UpdatedGasLimit) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedGasLimit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedProtocolFlatFeeIterator is returned from FilterUpdatedProtocolFlatFee and is used to iterate over the raw logs and unpacked data for UpdatedProtocolFlatFee events raised by the TestZRC20 contract. +type TestZRC20UpdatedProtocolFlatFeeIterator struct { + Event *TestZRC20UpdatedProtocolFlatFee // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedProtocolFlatFee) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedProtocolFlatFee) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedProtocolFlatFee represents a UpdatedProtocolFlatFee event raised by the TestZRC20 contract. +type TestZRC20UpdatedProtocolFlatFee struct { + ProtocolFlatFee *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedProtocolFlatFee is a free log retrieval operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedProtocolFlatFee(opts *bind.FilterOpts) (*TestZRC20UpdatedProtocolFlatFeeIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedProtocolFlatFee") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedProtocolFlatFeeIterator{contract: _TestZRC20.contract, event: "UpdatedProtocolFlatFee", logs: logs, sub: sub}, nil +} + +// WatchUpdatedProtocolFlatFee is a free log subscription operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedProtocolFlatFee(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedProtocolFlatFee) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedProtocolFlatFee") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedProtocolFlatFee) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedProtocolFlatFee", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedProtocolFlatFee is a log parse operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedProtocolFlatFee(log types.Log) (*TestZRC20UpdatedProtocolFlatFee, error) { + event := new(TestZRC20UpdatedProtocolFlatFee) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedProtocolFlatFee", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedSystemContractIterator is returned from FilterUpdatedSystemContract and is used to iterate over the raw logs and unpacked data for UpdatedSystemContract events raised by the TestZRC20 contract. +type TestZRC20UpdatedSystemContractIterator struct { + Event *TestZRC20UpdatedSystemContract // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedSystemContractIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedSystemContract) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedSystemContract) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedSystemContractIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedSystemContractIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedSystemContract represents a UpdatedSystemContract event raised by the TestZRC20 contract. +type TestZRC20UpdatedSystemContract struct { + SystemContract common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedSystemContract is a free log retrieval operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedSystemContract(opts *bind.FilterOpts) (*TestZRC20UpdatedSystemContractIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedSystemContract") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedSystemContractIterator{contract: _TestZRC20.contract, event: "UpdatedSystemContract", logs: logs, sub: sub}, nil +} + +// WatchUpdatedSystemContract is a free log subscription operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedSystemContract(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedSystemContract) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedSystemContract") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedSystemContract) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedSystemContract", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedSystemContract is a log parse operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedSystemContract(log types.Log) (*TestZRC20UpdatedSystemContract, error) { + event := new(TestZRC20UpdatedSystemContract) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedSystemContract", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20WithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the TestZRC20 contract. +type TestZRC20WithdrawalIterator struct { + Event *TestZRC20Withdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20WithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20WithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20WithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Withdrawal represents a Withdrawal event raised by the TestZRC20 contract. +type TestZRC20Withdrawal struct { + From common.Address + To []byte + Value *big.Int + Gasfee *big.Int + ProtocolFlatFee *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) FilterWithdrawal(opts *bind.FilterOpts, from []common.Address) (*TestZRC20WithdrawalIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Withdrawal", fromRule) + if err != nil { + return nil, err + } + return &TestZRC20WithdrawalIterator{contract: _TestZRC20.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *TestZRC20Withdrawal, from []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Withdrawal", fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Withdrawal) + if err := _TestZRC20.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) ParseWithdrawal(log types.Log) (*TestZRC20Withdrawal, error) { + event := new(TestZRC20Withdrawal) + if err := _TestZRC20.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json new file mode 100644 index 0000000000..b4d7b68b26 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json @@ -0,0 +1,673 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainid_", + "type": "uint256" + }, + { + "internalType": "enum CoinType", + "name": "coinType_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerIsNotFungibleModule", + "type": "error" + }, + { + "inputs": [], + "name": "GasFeeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "LowAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "LowBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasCoin", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasPrice", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "UpdatedGasLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "UpdatedProtocolFlatFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "systemContract", + "type": "address" + } + ], + "name": "UpdatedSystemContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasfee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COIN_TYPE", + "outputs": [ + { + "internalType": "enum CoinType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUNGIBLE_MODULE_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAS_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_FLAT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONTRACT_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newField", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newPublicField", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "updateGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newField_", + "type": "uint256" + } + ], + "name": "updateNewField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "updateProtocolFlatFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "updateSystemContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawGasFee", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bin": "60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033" +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol new file mode 100644 index 0000000000..c31ccb4686 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +/** + * @dev Custom errors for ZRC20 + */ +interface ZRC20Errors { + error CallerIsNotFungibleModule(); + error InvalidSender(); + error GasFeeTransferFailed(); + error ZeroGasCoin(); + error ZeroGasPrice(); + error LowAllowance(); + error LowBalance(); + error ZeroAddress(); +} + +/** + * @dev Interfaces of SystemContract and ZRC20 to make easier to import. + */ +interface ISystem { + function FUNGIBLE_MODULE_ADDRESS() external view returns (address); + function wZetaContractAddress() external view returns (address); + function uniswapv2FactoryAddress() external view returns (address); + function gasPriceByChainId(uint256 chainID) external view returns (uint256); + function gasCoinZRC20ByChainId(uint256 chainID) external view returns (address); + function gasZetaPoolByChainId(uint256 chainID) external view returns (address); +} + +interface IZRC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function deposit(address to, uint256 amount) external returns (bool); + function withdraw(bytes memory to, uint256 amount) external returns (bool); + function withdrawGasFee() external view returns (address, uint256); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + event Deposit(bytes from, address indexed to, uint256 value); + event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee); + event UpdatedSystemContract(address systemContract); + event UpdatedGasLimit(uint256 gasLimit); + event UpdatedProtocolFlatFee(uint256 protocolFlatFee); +} + +interface IZRC20Metadata is IZRC20 { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); +} + +/// @dev Coin types for ZRC20. Zeta value should not be used. +enum CoinType { + Zeta, + Gas, + ERC20 +} + +/** + * @dev TestZRC20 is a test implementation of ZRC20 that extends the contract with new fields to test contract + bytecode upgrade + */ +contract TestZRC20 is IZRC20, IZRC20Metadata, ZRC20Errors { + /// @notice Fungible address is always the same, maintained at the protocol level + address public constant FUNGIBLE_MODULE_ADDRESS = 0x735b14BB79463307AAcBED86DAf3322B1e6226aB; + /// @notice Chain id.abi + uint256 public immutable CHAIN_ID; + /// @notice Coin type, checkout Interfaces.sol. + CoinType public immutable COIN_TYPE; + /// @notice System contract address. + address public SYSTEM_CONTRACT_ADDRESS; + /// @notice Gas limit. + uint256 public GAS_LIMIT; + /// @notice Protocol flat fee. + uint256 public PROTOCOL_FLAT_FEE; + + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + uint256 private _totalSupply; + string private _name; + string private _symbol; + uint8 private _decimals; + + /// @notice extend the contract with new fields to test contract bytecode upgrade + uint256 public newField; + string public newPublicField; + + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + /** + * @dev Only fungible module modifier. + */ + modifier onlyFungible() { + if (msg.sender != FUNGIBLE_MODULE_ADDRESS) revert CallerIsNotFungibleModule(); + _; + } + + /** + * @dev Constructor + */ + constructor( + uint256 chainid_, + CoinType coinType_ + ) { + CHAIN_ID = chainid_; + COIN_TYPE = coinType_; + } + + /** + * @dev ZRC20 name + * @return name as string + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev ZRC20 symbol. + * @return symbol as string. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev ZRC20 decimals. + * @return returns uint8 decimals. + */ + function decimals() public view virtual override returns (uint8) { + return _decimals; + } + + /** + * @dev ZRC20 total supply. + * @return returns uint256 total supply. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev Returns ZRC20 balance of an account. + * @param account, account address for which balance is requested. + * @return uint256 account balance. + */ + function balanceOf(address account) public view virtual override returns (uint256) { + return _balances[account]; + } + + /** + * @dev Returns ZRC20 balance of an account. + * @param recipient, recipiuent address to which transfer is done. + * @return true/false if transfer succeeded/failed. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + /** + * @dev Returns token allowance from owner to spender. + * @param owner, owner address. + * @return uint256 allowance. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev Approves amount transferFrom for spender. + * @param spender, spender address. + * @param amount, amount to approve. + * @return true/false if succeeded/failed. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * @dev Increases allowance by amount for spender. + * @param spender, spender address. + * @param amount, amount by which to increase allownace. + * @return true/false if succeeded/failed. + */ + function increaseAllowance(address spender, uint256 amount) external virtual returns (bool) { + _allowances[spender][_msgSender()] += amount; + return true; + } + + /** + * @dev Decreases allowance by amount for spender. + * @param spender, spender address. + * @param amount, amount by which to decrease allownace. + * @return true/false if succeeded/failed. + */ + function decreaseAllowance(address spender, uint256 amount) external virtual returns (bool) { + if (_allowances[spender][_msgSender()] < amount) revert LowAllowance(); + _allowances[spender][_msgSender()] -= amount; + return true; + } + + /** + * @dev Transfers tokens from sender to recipient. + * @param sender, sender address. + * @param recipient, recipient address. + * @param amount, amount to transfer. + * @return true/false if succeeded/failed. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + + uint256 currentAllowance = _allowances[sender][_msgSender()]; + if (currentAllowance < amount) revert LowAllowance(); + + _approve(sender, _msgSender(), currentAllowance - amount); + + return true; + } + + /** + * @dev Burns an amount of tokens. + * @param amount, amount to burn. + * @return true/false if succeeded/failed. + */ + function burn(uint256 amount) external returns (bool) { + _burn(msg.sender, amount); + return true; + } + + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + if (sender == address(0)) revert ZeroAddress(); + if (recipient == address(0)) revert ZeroAddress(); + + uint256 senderBalance = _balances[sender]; + if (senderBalance < amount) revert LowBalance(); + + _balances[sender] = senderBalance - amount; + _balances[recipient] += amount; + + emit Transfer(sender, recipient, amount); + } + + function _mint(address account, uint256 amount) internal virtual { + if (account == address(0)) revert ZeroAddress(); + + _totalSupply += amount; + _balances[account] += amount; + emit Transfer(address(0), account, amount); + } + + function _burn(address account, uint256 amount) internal virtual { + if (account == address(0)) revert ZeroAddress(); + + uint256 accountBalance = _balances[account]; + if (accountBalance < amount) revert LowBalance(); + + _balances[account] = accountBalance - amount; + _totalSupply -= amount; + + emit Transfer(account, address(0), amount); + } + + function _approve(address owner, address spender, uint256 amount) internal virtual { + if (owner == address(0)) revert ZeroAddress(); + if (spender == address(0)) revert ZeroAddress(); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Deposits corresponding tokens from external chain, only callable by Fungible module. + * @param to, recipient address. + * @param amount, amount to deposit. + * @return true/false if succeeded/failed. + */ + function deposit(address to, uint256 amount) external override returns (bool) { + if (msg.sender != FUNGIBLE_MODULE_ADDRESS && msg.sender != SYSTEM_CONTRACT_ADDRESS) revert InvalidSender(); + _mint(to, amount); + emit Deposit(abi.encodePacked(FUNGIBLE_MODULE_ADDRESS), to, amount); + return true; + } + + /** + * @dev Withdraws gas fees. + * @return returns the ZRC20 address for gas on the same chain of this ZRC20, and calculates the gas fee for withdraw() + */ + function withdrawGasFee() public view override returns (address, uint256) { + address gasZRC20 = ISystem(SYSTEM_CONTRACT_ADDRESS).gasCoinZRC20ByChainId(CHAIN_ID); + if (gasZRC20 == address(0)) { + revert ZeroGasCoin(); + } + uint256 gasPrice = ISystem(SYSTEM_CONTRACT_ADDRESS).gasPriceByChainId(CHAIN_ID); + if (gasPrice == 0) { + revert ZeroGasPrice(); + } + uint256 gasFee = gasPrice * GAS_LIMIT + PROTOCOL_FLAT_FEE; + return (gasZRC20, gasFee); + } + + /** + * @dev Withraws ZRC20 tokens to external chains, this function causes cctx module to send out outbound tx to the outbound chain + * this contract should be given enough allowance of the gas ZRC20 to pay for outbound tx gas fee. + * @param to, recipient address. + * @param amount, amount to deposit. + * @return true/false if succeeded/failed. + */ + function withdraw(bytes memory to, uint256 amount) external override returns (bool) { + (address gasZRC20, uint256 gasFee) = withdrawGasFee(); + if (!IZRC20(gasZRC20).transferFrom(msg.sender, FUNGIBLE_MODULE_ADDRESS, gasFee)) { + revert GasFeeTransferFailed(); + } + _burn(msg.sender, amount); + emit Withdrawal(msg.sender, to, amount, gasFee, PROTOCOL_FLAT_FEE); + return true; + } + + /** + * @dev Updates system contract address. Can only be updated by the fungible module. + * @param addr, new system contract address. + */ + function updateSystemContractAddress(address addr) external onlyFungible { + SYSTEM_CONTRACT_ADDRESS = addr; + emit UpdatedSystemContract(addr); + } + + /** + * @dev Updates gas limit. Can only be updated by the fungible module. + * @param gasLimit, new gas limit. + */ + function updateGasLimit(uint256 gasLimit) external onlyFungible { + GAS_LIMIT = gasLimit; + emit UpdatedGasLimit(gasLimit); + } + + /** + * @dev Updates protocol flat fee. Can only be updated by the fungible module. + * @param protocolFlatFee, new protocol flat fee. + */ + function updateProtocolFlatFee(uint256 protocolFlatFee) external onlyFungible { + PROTOCOL_FLAT_FEE = protocolFlatFee; + emit UpdatedProtocolFlatFee(protocolFlatFee); + } + + /** + * @dev Updates newField. Can only be updated by the fungible module. + * @param newField_, new newField. + */ + function updateNewField(uint256 newField_) external { + newField = newField_; + } +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go new file mode 100644 index 0000000000..dc615b9770 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go @@ -0,0 +1,6 @@ +//go:generate sh -c "solc --evm-version paris TestZRC20.sol --combined-json abi,bin | jq '.contracts.\"TestZRC20.sol:TestZRC20\"' > TestZRC20.json" +//go:generate sh -c "cat TestZRC20.json | jq .abi > TestZRC20.abi" +//go:generate sh -c "cat TestZRC20.json | jq .bin | tr -d '\"' > TestZRC20.bin" +//go:generate sh -c "abigen --abi TestZRC20.abi --bin TestZRC20.bin --pkg testzrc20 --type TestZRC20 --out TestZRC20.go" + +package testzrc20 diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index 2939ea2181..44607b3c22 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -148,6 +148,9 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { bankClient := banktypes.NewQueryClient(grpcConn) observerClient := observertypes.NewQueryClient(grpcConn) + //Wait for Genesis + time.Sleep(20 * time.Second) + // initialize client to send messages to ZetaChain zetaTxServer, err := NewZetaTxServer( "http://zetacore0:26657", @@ -158,8 +161,7 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { panic(err) } - // Wait for Genesis and keygen to be completed. ~ height 30 - time.Sleep(20 * time.Second) + //Wait for keygen to be completed. ~ height 30 for { time.Sleep(5 * time.Second) response, err := cctxClient.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) @@ -284,7 +286,7 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestBitcoinWithdraw() - smokeTest.CheckZRC20ReserveAndSupply() + //smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestCrosschainSwap() smokeTest.CheckZRC20ReserveAndSupply() @@ -298,6 +300,12 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.TestPauseZRC20() smokeTest.CheckZRC20ReserveAndSupply() + smokeTest.TestERC20DepositAndCallRefund() + smokeTest.CheckZRC20ReserveAndSupply() + + smokeTest.TestUpdateBytecode() + smokeTest.CheckZRC20ReserveAndSupply() + // add your dev test here smokeTest.TestMyTest() diff --git a/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go b/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go index d4e5c5c604..7e40cb8084 100644 --- a/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go +++ b/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go @@ -170,7 +170,8 @@ func (sm *SmokeTest) TestCrosschainSwap() { memo = append(sm.ZEVMSwapAppAddr.Bytes(), memo...) fmt.Printf("memo length %d\n", len(memo)) - txid, err := SendToTSSFromDeployerWithMemo(BTCTSSAddress, 0.001, utxos[0:2], sm.btcRPCClient, memo) + amount := 0.1 + txid, err := SendToTSSFromDeployerWithMemo(BTCTSSAddress, amount, utxos[0:2], sm.btcRPCClient, memo) fmt.Printf("Sent BTC to TSS txid %s; now mining 10 blocks for confirmation\n", txid) _, err = sm.btcRPCClient.GenerateToAddress(10, BTCDeployerAddress, nil) if err != nil { @@ -182,6 +183,7 @@ func (sm *SmokeTest) TestCrosschainSwap() { fmt.Printf(" inboudn tx hash %s\n", cctx.InboundTxParams.InboundTxObservedHash) fmt.Printf(" status %s\n", cctx.CctxStatus.Status.String()) fmt.Printf(" status msg: %s\n", cctx.CctxStatus.StatusMessage) + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { panic(fmt.Sprintf("expected reverted status; got %s", cctx.CctxStatus.Status.String())) } diff --git a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go index b65fdb5691..2a02176ada 100644 --- a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go +++ b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go @@ -9,15 +9,16 @@ import ( "math/big" "time" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/zeta-chain/zetacore/x/crosschain/types" - "github.com/zeta-chain/zetacore/zetaclient" - "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" zrc20 "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/common/ethereum" + "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "github.com/zeta-chain/zetacore/zetaclient" ) // this tests sending ZETA out of ZetaChain to Ethereum @@ -39,6 +40,26 @@ func (sm *SmokeTest) TestDepositEtherIntoZRC20() { } fmt.Printf("GOERLI deployer balance: %s\n", bal.String()) + systemContract := sm.SystemContract + if err != nil { + panic(err) + } + ethZRC20Addr, err := systemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.GoerliChain().ChainId)) + if err != nil { + panic(err) + } + sm.ETHZRC20Addr = ethZRC20Addr + fmt.Printf("eth zrc20 address: %s\n", ethZRC20Addr.String()) + ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, sm.zevmClient) + if err != nil { + panic(err) + } + sm.ETHZRC20 = ethZRC20 + initialBalance, err := ethZRC20.BalanceOf(nil, DeployerAddress) + if err != nil { + panic(err) + } + value := big.NewInt(1000000000000000000) // in wei (1 eth) signedTx, err := sm.SendEther(TSSAddress, value, nil) if err != nil { @@ -53,6 +74,67 @@ func (sm *SmokeTest) TestDepositEtherIntoZRC20() { fmt.Printf(" value: %d\n", signedTx.Value()) fmt.Printf(" block num: %d\n", receipt.BlockNumber) + { + LoudPrintf("Merkle Proof\n") + txHash := receipt.TxHash + blockHash := receipt.BlockHash + txIndex := int(receipt.TransactionIndex) + + block, err := sm.goerliClient.BlockByHash(context.Background(), blockHash) + if err != nil { + panic(err) + } + i := 0 + for { + if i > 20 { + panic("block header not found") + } + _, err := sm.observerClient.GetBlockHeaderByHash(context.Background(), &observertypes.QueryGetBlockHeaderByHashRequest{ + BlockHash: blockHash.Bytes(), + }) + if err != nil { + fmt.Printf("WARN: block header not found; retrying...\n") + time.Sleep(2 * time.Second) + } else { + fmt.Printf("OK: block header found\n") + break + } + i++ + } + + trie := ethereum.NewTrie(block.Transactions()) + if trie.Hash() != block.Header().TxHash { + panic("tx root hash & block tx root mismatch") + } + txProof, err := trie.GenerateProof(txIndex) + if err != nil { + panic("error generating txProof") + } + val, err := txProof.Verify(block.TxHash(), txIndex) + if err != nil { + panic("error verifying txProof") + } + var txx ethtypes.Transaction + err = txx.UnmarshalBinary(val) + if err != nil { + panic("error unmarshalling txProof'd tx") + } + res, err := sm.observerClient.Prove(context.Background(), &observertypes.QueryProveRequest{ + BlockHash: blockHash.Hex(), + TxIndex: int64(txIndex), + TxHash: txHash.Hex(), + Proof: common.NewEthereumProof(txProof), + ChainId: 0, + }) + if err != nil { + panic(err) + } + if !res.Valid { + panic("txProof invalid") // FIXME: don't do this in production + } + fmt.Printf("OK: txProof verified\n") + } + { tx, err := sm.SendEther(TSSAddress, big.NewInt(101000000000000000), []byte(zetaclient.DonationMessage)) if err != nil { @@ -71,26 +153,6 @@ func (sm *SmokeTest) TestDepositEtherIntoZRC20() { }() sm.wg.Add(1) go func() { - systemContract := sm.SystemContract - if err != nil { - panic(err) - } - ethZRC20Addr, err := systemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.GoerliChain().ChainId)) - if err != nil { - panic(err) - } - sm.ETHZRC20Addr = ethZRC20Addr - fmt.Printf("eth zrc20 address: %s\n", ethZRC20Addr.String()) - ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, sm.zevmClient) - if err != nil { - panic(err) - } - sm.ETHZRC20 = ethZRC20 - initialBalance, err := ethZRC20.BalanceOf(nil, DeployerAddress) - if err != nil { - panic(err) - } - defer sm.wg.Done() <-c @@ -132,12 +194,17 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { if err != nil { panic(err) } - value := big.NewInt(100000000000000000) // in wei (1 eth) - gasLimit := uint64(23000) // in units + + // in wei (10 eth) + value := big.NewInt(1e18) + value = value.Mul(value, big.NewInt(10)) + + gasLimit := uint64(23000) // in units gasPrice, err := goerliClient.SuggestGasPrice(context.Background()) if err != nil { panic(err) } + data := append(sm.BTCZRC20Addr.Bytes(), []byte("hello sailors")...) // this data tx := ethtypes.NewTransaction(nonce, TSSAddress, value, gasLimit, gasPrice, data) chainID, err := goerliClient.NetworkID(context.Background()) @@ -170,6 +237,7 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { fmt.Printf("cctx status message: %s", cctx.CctxStatus.StatusMessage) revertTxHash := cctx.GetCurrentOutTxParam().OutboundTxHash fmt.Printf("GOERLI revert tx receipt: status %d\n", receipt.Status) + tx, _, err := sm.goerliClient.TransactionByHash(context.Background(), ethcommon.HexToHash(revertTxHash)) if err != nil { panic(err) @@ -178,13 +246,41 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { if err != nil { panic(err) } - if cctx.CctxStatus.Status != types.CctxStatus_Reverted || receipt.Status == 0 || *tx.To() != DeployerAddress || tx.Value().Cmp(value) != 0 { + + printTxInfo := func() { // debug info when test fails fmt.Printf(" tx: %+v\n", tx) fmt.Printf(" receipt: %+v\n", receipt) fmt.Printf("cctx http://localhost:1317/zeta-chain/crosschain/cctx/%s\n", cctx.Index) - panic(fmt.Sprintf("expected cctx status PendingRevert; got %s", cctx.CctxStatus.Status)) } + + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { + printTxInfo() + panic(fmt.Sprintf("expected cctx status to be PendingRevert; got %s", cctx.CctxStatus.Status)) + } + + if receipt.Status == 0 { + printTxInfo() + panic("expected the revert tx receipt to have status 1; got 0") + } + + if *tx.To() != DeployerAddress { + printTxInfo() + panic(fmt.Sprintf("expected tx to %s; got %s", DeployerAddress.Hex(), tx.To().Hex())) + } + + // the received value must be lower than the original value because of the paid fees for the revert tx + // we check that the value is still greater than 0 + if tx.Value().Cmp(value) != -1 || tx.Value().Cmp(big.NewInt(0)) != 1 { + printTxInfo() + panic(fmt.Sprintf("expected tx value %s; should be non-null and lower than %s", tx.Value().String(), value.String())) + } + + fmt.Printf("REVERT tx receipt: %d\n", receipt.Status) + fmt.Printf(" tx hash: %s\n", receipt.TxHash.String()) + fmt.Printf(" to: %s\n", tx.To().String()) + fmt.Printf(" value: %s\n", tx.Value().String()) + fmt.Printf(" block num: %d\n", receipt.BlockNumber) }() } diff --git a/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go b/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go new file mode 100644 index 0000000000..e8d5686313 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go @@ -0,0 +1,200 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func (sm *SmokeTest) TestERC20DepositAndCallRefund() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + LoudPrintf("Deposit a non-gas ZRC20 into ZEVM and call a contract that reverts; should refund on ZetaChain if no liquidity pool, should refund on origin if liquidity pool\n") + + // Get the initial balance of the deployer + initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + + fmt.Println("Sending a deposit that should revert without a liquidity pool makes the cctx aborted") + + amount := big.NewInt(1e4) + + // send the deposit + inTxHash, err := sm.sendInvalidUSDTDeposit(amount) + if err != nil { + panic(err) + } + + // There is no liquidity pool, therefore the cctx should abort + cctx := WaitCctxMinedByInTxHash(inTxHash, sm.cctxClient) + if cctx.CctxStatus.Status != types.CctxStatus_Aborted { + panic(fmt.Sprintf("expected cctx status to be Aborted; got %s", cctx.CctxStatus.Status)) + } + + // Check that the erc20 in the aborted cctx was refunded on ZetaChain + newBalance, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + expectedBalance := initialBal.Add(initialBal, amount) + if newBalance.Cmp(expectedBalance) != 0 { + panic(fmt.Sprintf("expected balance to be %s after refund; got %s", expectedBalance.String(), newBalance.String())) + } + fmt.Println("CCTX has been aborted and the erc20 has been refunded on ZetaChain") + + amount = big.NewInt(1e7) + goerliBalance, err := sm.USDTERC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + + fmt.Println("Sending a deposit that should revert with a liquidity pool") + + fmt.Println("Creating the liquidity pool USTD/ZETA") + err = sm.createZetaERC20LiquidityPool() + if err != nil { + panic(err) + } + fmt.Println("Liquidity pool created") + + // send the deposit + inTxHash, err = sm.sendInvalidUSDTDeposit(amount) + if err != nil { + panic(err) + } + + // there is a liquidity pool, therefore the cctx should revert + cctx = WaitCctxMinedByInTxHash(inTxHash, sm.cctxClient) + + // the revert tx creation will fail because the sender, used as the recipient, is not defined in the cctx + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { + panic(fmt.Sprintf("expected cctx status to be PendingRevert; got %s", cctx.CctxStatus.Status)) + } + + // get revert tx + revertTxHash := cctx.GetCurrentOutTxParam().OutboundTxHash + _, _, err = sm.goerliClient.TransactionByHash(context.Background(), ethcommon.HexToHash(revertTxHash)) + if err != nil { + panic(err) + } + receipt, err := sm.goerliClient.TransactionReceipt(context.Background(), ethcommon.HexToHash(revertTxHash)) + if err != nil { + panic(err) + } + if receipt.Status == 0 { + panic("expected the revert tx receipt to have status 1; got 0") + } + + // check that the erc20 in the reverted cctx was refunded on Goerli + newGoerliBalance, err := sm.USDTERC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + // the new balance must be higher than the previous one because of the revert refund + if goerliBalance.Cmp(newGoerliBalance) != -1 { + panic(fmt.Sprintf("expected balance to be higher than %s after refund; got %s", goerliBalance.String(), newGoerliBalance.String())) + } + // it must also be lower than the previous balance + the amount because of the gas fee for the revert tx + balancePlusAmount := goerliBalance.Add(goerliBalance, amount) + if newGoerliBalance.Cmp(balancePlusAmount) != -1 { + panic(fmt.Sprintf("expected balance to be lower than %s after refund; got %s", balancePlusAmount.String(), newGoerliBalance.String())) + } + + fmt.Println("ERC20 CCTX successfully reverted") + fmt.Println("\tbalance before refund: ", goerliBalance.String()) + fmt.Println("\tamount: ", amount.String()) + fmt.Println("\tbalance after refund: ", newGoerliBalance.String()) +} + +func (sm *SmokeTest) createZetaERC20LiquidityPool() error { + amount := big.NewInt(1e10) + txHash := sm.DepositERC20(amount, []byte{}) + WaitCctxMinedByInTxHash(txHash.Hex(), sm.cctxClient) + + tx, err := sm.USDTZRC20.Approve(sm.zevmAuth, sm.UniswapV2RouterAddr, big.NewInt(1e10)) + if err != nil { + return err + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + return errors.New("approve failed") + } + + previousValue := sm.zevmAuth.Value + sm.zevmAuth.Value = big.NewInt(1e10) + tx, err = sm.UniswapV2Router.AddLiquidityETH( + sm.zevmAuth, + sm.USDTZRC20Addr, + amount, + BigZero, + BigZero, + DeployerAddress, + big.NewInt(time.Now().Add(10*time.Minute).Unix()), + ) + sm.zevmAuth.Value = previousValue + if err != nil { + return err + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + return errors.New("add liquidity failed") + } + + return nil +} + +func (sm *SmokeTest) sendInvalidUSDTDeposit(amount *big.Int) (string, error) { + // send the tx + USDT := sm.USDTERC20 + tx, err := USDT.Mint(sm.goerliAuth, amount) + if err != nil { + return "", err + } + receipt := MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("Mint receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = USDT.Approve(sm.goerliAuth, sm.ERC20CustodyAddr, amount) + if err != nil { + return "", err + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("USDT Approve receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = sm.ERC20Custody.Deposit( + sm.goerliAuth, + DeployerAddress.Bytes(), + sm.USDTERC20Addr, + amount, + []byte("this is an invalid msg that will cause the contract to revert"), + ) + if err != nil { + return "", err + } + + fmt.Printf("GOERLI tx sent: %s; to %s, nonce %d\n", tx.Hash().String(), tx.To().Hex(), tx.Nonce()) + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + return "", errors.New("expected the tx receipt to have status 1; got 0") + } + fmt.Printf("GOERLI tx receipt: %d\n", receipt.Status) + fmt.Printf(" tx hash: %s\n", receipt.TxHash.String()) + fmt.Printf(" to: %s\n", tx.To().String()) + fmt.Printf(" value: %d\n", tx.Value()) + fmt.Printf(" block num: %d\n", receipt.BlockNumber) + + return tx.Hash().Hex(), nil +} diff --git a/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go b/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go new file mode 100644 index 0000000000..f8350b9a12 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go @@ -0,0 +1,189 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/testzrc20" + "github.com/zeta-chain/zetacore/testutil/sample" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" +) + +// TestUpdateBytecode tests updating the bytecode of a zrc20 and interact with it +func (sm *SmokeTest) TestUpdateBytecode() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + LoudPrintf("Testing updating ZRC20 bytecode swap...\n") + + // Random approval + approved := sample.EthAddress() + tx, err := sm.ETHZRC20.Approve(sm.zevmAuth, approved, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("approval failed") + } + + // Deploy the TestZRC20 contract + fmt.Println("Deploying contract with new bytecode") + newZRC20Address, _, newZRC20Contract, err := testzrc20.DeployTestZRC20(sm.zevmAuth, sm.zevmClient, big.NewInt(5), uint8(common.CoinType_Gas)) + if err != nil { + panic(err) + } + + // Get current info of the ZRC20 + name, err := sm.ETHZRC20.Name(&bind.CallOpts{}) + if err != nil { + panic(err) + } + symbol, err := sm.ETHZRC20.Symbol(&bind.CallOpts{}) + if err != nil { + panic(err) + } + decimals, err := sm.ETHZRC20.Decimals(&bind.CallOpts{}) + if err != nil { + panic(err) + } + totalSupply, err := sm.ETHZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + balance, err := sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + approval, err := sm.ETHZRC20.Allowance(&bind.CallOpts{}, DeployerAddress, approved) + if err != nil { + panic(err) + } + + fmt.Println("Updating the bytecode of the ZRC20") + msg := fungibletypes.NewMsgUpdateContractBytecode( + FungibleAdminAddress, + sm.ETHZRC20Addr, + newZRC20Address, + ) + res, err := sm.zetaTxServer.BroadcastTx(FungibleAdminName, msg) + if err != nil { + panic(err) + } + fmt.Printf("Update zrc20 bytecode tx hash: %s\n", res.TxHash) + + // Get new info of the ZRC20 + fmt.Println("Checking the state of the ZRC20 remains the same") + newName, err := sm.ETHZRC20.Name(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if name != newName { + panic("name shouldn't change upon bytecode update") + } + newSymbol, err := sm.ETHZRC20.Symbol(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if symbol != newSymbol { + panic("symbol shouldn't change upon bytecode update") + } + newDecimals, err := sm.ETHZRC20.Decimals(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if decimals != newDecimals { + panic("decimals shouldn't change upon bytecode update") + } + newTotalSupply, err := sm.ETHZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if totalSupply.Cmp(newTotalSupply) != 0 { + panic("total supply shouldn't change upon bytecode update") + } + newBalance, err := sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + if balance.Cmp(newBalance) != 0 { + panic("balance shouldn't change upon bytecode update") + } + newApproval, err := sm.ETHZRC20.Allowance(&bind.CallOpts{}, DeployerAddress, approved) + if err != nil { + panic(err) + } + if approval.Cmp(newApproval) != 0 { + panic("approval shouldn't change upon bytecode update") + } + + fmt.Println("Can interact with the new code of the contract") + testZRC20Contract, err := testzrc20.NewTestZRC20(sm.ETHZRC20Addr, sm.zevmClient) + if err != nil { + panic(err) + } + tx, err = testZRC20Contract.UpdateNewField(sm.zevmAuth, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("update new field failed") + } + newField, err := testZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e10)) != 0 { + panic("new field value mismatch") + } + + fmt.Println("Interacting with the bytecode contract doesn't disrupt the zrc20 contract") + tx, err = newZRC20Contract.UpdateNewField(sm.zevmAuth, big.NewInt(1e5)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("update new field failed") + } + newField, err = newZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e5)) != 0 { + panic("new field value mismatch on bytecode contract") + } + newField, err = testZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e10)) != 0 { + panic("new field value mismatch on zrc20 contract") + } + + // can continue to operate the ZRC20 + fmt.Println("Checking the ZRC20 can continue to operate after state change") + tx, err = sm.ETHZRC20.Transfer(sm.zevmAuth, approved, big.NewInt(1e14)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("transfer failed") + } + newBalance, err = sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, approved) + if err != nil { + panic(err) + } + if newBalance.Cmp(big.NewInt(1e14)) != 0 { + panic("balance not updated") + } +} diff --git a/contrib/localnet/orchestrator/smoketest/utils.go b/contrib/localnet/orchestrator/smoketest/utils.go index 735d2d305a..7c4345f536 100644 --- a/contrib/localnet/orchestrator/smoketest/utils.go +++ b/contrib/localnet/orchestrator/smoketest/utils.go @@ -15,12 +15,10 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil" - + ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/zeta-chain/zetacore/x/crosschain/types" - - ethcommon "github.com/ethereum/go-ethereum/common" ) // WaitCctxMinedByInTxHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 639510433c..e1cf35b007 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27213,6 +27213,26 @@ paths: $ref: '#/definitions/googlerpcStatus' tags: - Query + /zeta-chain/crosschain/pendingNonces/{chain_id}: + get: + operationId: Query_PendingNoncesByChain + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/crosschainQueryPendingNoncesByChainResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: path + required: true + type: string + format: uint64 + tags: + - Query /zeta-chain/crosschain/protocolFee: get: operationId: Query_ProtocolFee @@ -27310,6 +27330,84 @@ paths: $ref: '#/definitions/googlerpcStatus' tags: - Query + /zeta-chain/observer/get_all_block_headers: + get: + operationId: Query_GetAllBlockHeaders + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryAllBlockHeaderResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: |- + offset is a numeric offset that can be used when key is unavailable. + It is less efficient than using key. Only one of offset or key should + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: |- + limit is the total number of results to be returned in the result page. + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: |- + count_total is set to true to indicate that the result set should include + a count of the total number of items available for pagination in UIs. + count_total is only respected when offset is used. It is ignored when key + is set. + in: query + required: false + type: boolean + - name: pagination.reverse + description: |- + reverse is set to true if results are to be returned in the descending order. + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + tags: + - Query + /zeta-chain/observer/get_block_header_by_hash/{block_hash}: + get: + operationId: Query_GetBlockHeaderByHash + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryGetBlockHeaderByHashResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: block_hash + in: path + required: true + type: string + format: byte + tags: + - Query /zeta-chain/observer/get_client_params_for_chain/{chain_id}: get: summary: Queries a list of GetClientParamsForChain items. @@ -27489,6 +27587,56 @@ paths: $ref: '#/definitions/googlerpcStatus' tags: - Query + /zeta-chain/observer/prove: + get: + summary: merkle proof verification + operationId: Query_Prove + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryProveResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: query + required: false + type: string + format: uint64 + - name: tx_hash + in: query + required: false + type: string + - name: proof.ethereum_proof.keys + in: query + required: false + type: array + items: + type: string + format: byte + collectionFormat: multi + - name: proof.ethereum_proof.values + in: query + required: false + type: array + items: + type: string + format: byte + collectionFormat: multi + - name: block_hash + in: query + required: false + type: string + - name: tx_index + in: query + required: false + type: string + format: int64 + tags: + - Query /zeta-chain/observer/supportedChains: get: operationId: Query_SupportedChains @@ -50054,6 +50202,24 @@ definitions: - VOTE_OPTION_ABSTAIN: VOTE_OPTION_ABSTAIN defines an abstain vote option. - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. - VOTE_OPTION_NO_WITH_VETO: VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. + commonBlockHeader: + type: object + properties: + height: + type: string + format: int64 + hash: + type: string + format: byte + parent_hash: + type: string + format: byte + chain_id: + type: string + format: int64 + header: + $ref: '#/definitions/commonHeaderData' + title: chain specific header commonChain: type: object properties: @@ -50099,6 +50265,18 @@ definitions: - Gas: Ether, BNB, Matic, Klay, BTC, etc - ERC20: ERC20 token - Cmd: not a real coin, rather a command + commonHeaderData: + type: object + properties: + ethereum_header: + type: string + format: byte + title: binary encoded headers; RLP for ethereum + commonProof: + type: object + properties: + ethereum_proof: + $ref: '#/definitions/ethereumProof' commonPubKeySet: type: object properties: @@ -50502,6 +50680,11 @@ definitions: properties: feeInZeta: type: string + crosschainQueryPendingNoncesByChainResponse: + type: object + properties: + pending_nonces: + $ref: '#/definitions/crosschainPendingNonces' crosschainQueryTssHistoryResponse: type: object properties: @@ -50536,6 +50719,8 @@ definitions: type: string tx_signer: type: string + proved: + type: boolean emissionsQueryGetEmmisonsFactorsResponse: type: object properties: @@ -50559,6 +50744,19 @@ definitions: properties: amount: type: string + ethereumProof: + type: object + properties: + keys: + type: array + items: + type: string + format: byte + values: + type: array + items: + type: string + format: byte fungibleForeignCoins: type: object properties: @@ -50587,8 +50785,17 @@ definitions: type: boolean fungibleMsgDeployFungibleCoinZRC20Response: type: object + properties: + address: + type: string fungibleMsgRemoveForeignCoinResponse: type: object + fungibleMsgUpdateContractBytecodeResponse: + type: object + properties: + new_bytecode_hash: + type: string + format: byte fungibleMsgUpdateSystemContractResponse: type: object fungibleMsgUpdateZRC20PausedStatusResponse: @@ -50754,6 +50961,8 @@ definitions: format: int64 observerMsgAddBlameVoteResponse: type: object + observerMsgAddBlockHeaderResponse: + type: object observerMsgAddObserverResponse: type: object observerMsgUpdateCoreParamsResponse: @@ -50851,6 +51060,16 @@ definitions: items: type: object $ref: '#/definitions/observerBlame' + observerQueryAllBlockHeaderResponse: + type: object + properties: + block_headers: + type: array + items: + type: object + $ref: '#/definitions/commonBlockHeader' + pagination: + $ref: '#/definitions/v1beta1PageResponse' observerQueryAllNodeAccountResponse: type: object properties: @@ -50888,6 +51107,11 @@ definitions: properties: blame_info: $ref: '#/definitions/observerBlame' + observerQueryGetBlockHeaderByHashResponse: + type: object + properties: + block_header: + $ref: '#/definitions/commonBlockHeader' observerQueryGetCoreParamsForChainResponse: type: object properties: @@ -50920,6 +51144,11 @@ definitions: type: array items: type: string + observerQueryProveResponse: + type: object + properties: + valid: + type: boolean observerQueryShowObserverCountResponse: type: object properties: diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index 6ef9aed746..ba1161d149 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -2,10 +2,8 @@ ## MsgAddToOutTxTracker -Adds a new record to the outbound transaction tracker. - -Only the admin policy account and the observer validators are authorized to -broadcast this message. +AddToOutTxTracker adds a new record to the outbound transaction tracker. +only the admin policy account and the observer validators are authorized to broadcast this message. ```proto message MsgAddToOutTxTracker { @@ -13,14 +11,16 @@ message MsgAddToOutTxTracker { int64 chain_id = 2; uint64 nonce = 3; string tx_hash = 4; + common.Proof proof = 5; + string block_hash = 6; + int64 tx_index = 7; } ``` ## MsgRemoveFromOutTxTracker -Removes a record from the outbound transaction tracker by chain ID and nonce. - -Only the admin policy account is authorized to broadcast this message. +RemoveFromOutTxTracker removes a record from the outbound transaction tracker by chain ID and nonce. +only the admin policy account is authorized to broadcast this message. ```proto message MsgRemoveFromOutTxTracker { @@ -84,7 +84,7 @@ message MsgNonceVoter { ## MsgVoteOnObservedOutboundTx -Casts a vote on an outbound transaction observed on a connected chain (after +VoteOnObservedOutboundTx casts a vote on an outbound transaction observed on a connected chain (after it has been broadcasted to and finalized on a connected chain). If this is the first vote, a new ballot is created. When a threshold of votes is reached, the ballot is finalized. When a ballot is finalized, the outbound @@ -135,7 +135,7 @@ message MsgVoteOnObservedOutboundTx { uint64 observed_outTx_gas_used = 10; string observed_outTx_effective_gas_price = 11; uint64 observed_outTx_effective_gas_limit = 12; - string zeta_minted = 5; + string value_received = 5; common.ReceiveStatus status = 6; int64 outTx_chain = 7; uint64 outTx_tss_nonce = 8; @@ -145,7 +145,7 @@ message MsgVoteOnObservedOutboundTx { ## MsgVoteOnObservedInboundTx -Casts a vote on an inbound transaction observed on a connected chain. If this +VoteOnObservedInboundTx casts a vote on an inbound transaction observed on a connected chain. If this is the first vote, a new ballot is created. When a threshold of votes is reached, the ballot is finalized. When a ballot is finalized, a new CCTX is created. diff --git a/docs/spec/fungible/messages.md b/docs/spec/fungible/messages.md index 5e67f9131b..9f86674b5b 100644 --- a/docs/spec/fungible/messages.md +++ b/docs/spec/fungible/messages.md @@ -66,6 +66,21 @@ message MsgUpdateZRC20WithdrawFee { } ``` +## MsgUpdateContractBytecode + +UpdateContractBytecode updates the bytecode of a contract from the bytecode of an existing contract +Only a ZRC20 contract or the WZeta connector contract can be updated +IMPORTANT: the new contract bytecode must have the same storage layout as the old contract bytecode +the new contract can add new variable but cannot remove any existing variable + +```proto +message MsgUpdateContractBytecode { + string creator = 1; + string contract_address = 2; + string new_bytecode_address = 3; +} +``` + ## MsgUpdateZRC20PausedStatus UpdateZRC20PausedStatus updates the paused status of a ZRC20 diff --git a/docs/spec/observer/messages.md b/docs/spec/observer/messages.md index 6ae205a88e..2ae574f73a 100644 --- a/docs/spec/observer/messages.md +++ b/docs/spec/observer/messages.md @@ -70,3 +70,17 @@ message MsgUpdateKeygen { } ``` +## MsgAddBlockHeader + +AddBlockHeader handles adding a block header to the store, through majority voting of observers + +```proto +message MsgAddBlockHeader { + string creator = 1; + int64 chain_id = 2; + bytes block_hash = 3; + int64 height = 4; + common.HeaderData header = 5; +} +``` + diff --git a/go.mod b/go.mod index cc29fa1ce0..2ac6cf2de1 100644 --- a/go.mod +++ b/go.mod @@ -187,7 +187,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect @@ -197,8 +197,6 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipns v0.3.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipld/go-ipld-prime v0.20.0 // indirect @@ -217,7 +215,6 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p v0.27.8 github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-core v0.20.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect diff --git a/go.sum b/go.sum index 9a52b53dcc..741d11222e 100644 --- a/go.sum +++ b/go.sum @@ -690,7 +690,6 @@ github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -780,7 +779,6 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= @@ -1033,7 +1031,6 @@ github.com/cosmos/ibc-go/v6 v6.1.0 h1:o7oXws2vKkKfOFzJI+oNylRn44PCNt5wzHd/zKQKbv github.com/cosmos/ibc-go/v6 v6.1.0/go.mod h1:CY3zh2HLfetRiW8LY6kVHMATe90Wj/UOoY8T6cuB0is= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -1070,13 +1067,10 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0/go.mod h1:d0H8xGMWbiIQP7gN3v2rByWUcuZPm9YsgmnfoxgbINc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= @@ -1089,10 +1083,8 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= @@ -1244,7 +1236,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -1317,7 +1308,6 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -1569,8 +1559,6 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -1617,8 +1605,8 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904= @@ -1775,8 +1763,6 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -1817,37 +1803,21 @@ github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6B github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipns v0.2.0 h1:BgmNtQhqOw5XEZ8RAfWEpK4DhqaYiuP6h71MhIp7xXU= -github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= @@ -1867,7 +1837,6 @@ github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5D github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= @@ -1950,7 +1919,6 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiD github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -1972,18 +1940,12 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= @@ -2036,40 +1998,23 @@ github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= -github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.20.0 h1:PGKM74+T+O/FaZNARNW32i90RMBHCcgd/hkum2UQ5eY= -github.com/libp2p/go-libp2p-core v0.20.0/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= -github.com/libp2p/go-libp2p-kad-dht v0.18.0 h1:akqO3gPMwixR7qFSFq70ezRun97g5hrA/lBW9jrjUYM= -github.com/libp2p/go-libp2p-kad-dht v0.18.0/go.mod h1:Gb92MYIPm3K2pJLGn8wl0m8wiKDvHrYpg+rOd0GzzPA= github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= -github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70= -github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.8.0 h1:bzTG693TA1Ju/zKmUCQzDLSqiJnyRFVwPpuloZ/OZtI= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= @@ -2077,10 +2022,6 @@ github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= @@ -2152,8 +2093,6 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -2194,8 +2133,6 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -2215,9 +2152,6 @@ github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLT github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -2288,9 +2222,7 @@ github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinK github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= @@ -2298,47 +2230,28 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= -github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -2411,8 +2324,6 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -2431,7 +2342,6 @@ github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -2553,8 +2463,6 @@ github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUI github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= @@ -2584,7 +2492,6 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= @@ -2646,8 +2553,6 @@ github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraN github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -2774,13 +2679,11 @@ github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvR github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= @@ -2795,7 +2698,6 @@ github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34c github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -2876,7 +2778,6 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -2983,7 +2884,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -3019,12 +2919,10 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= @@ -3170,17 +3068,13 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= -go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= -go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= @@ -3265,8 +3159,6 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3345,7 +3237,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -3488,7 +3379,6 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -3658,7 +3548,6 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3675,8 +3564,6 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -3692,8 +3579,6 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3711,8 +3596,6 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3862,8 +3745,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -4351,8 +4232,6 @@ k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= diff --git a/proto/common/common.proto b/proto/common/common.proto index 936d542bba..161f533034 100644 --- a/proto/common/common.proto +++ b/proto/common/common.proto @@ -1,10 +1,10 @@ syntax = "proto3"; package common; +import "common/ethereum/ethereum.proto"; //option (gogoproto.goproto_stringer_all) = false; //option (gogoproto.stringer_all) = false; //option (gogoproto.goproto_getters_all) = false; - import "gogoproto/gogo.proto"; option go_package = "github.com/zeta-chain/zetacore/common"; @@ -62,3 +62,24 @@ message Chain { ChainName chain_name = 1; int64 chain_id = 2; } + +message BlockHeader { + int64 height = 1; + bytes hash = 2; + bytes parent_hash = 3; + int64 chain_id = 4; + // chain specific header + HeaderData header = 5 [(gogoproto.nullable) = false]; +} + +message HeaderData { + oneof data { + bytes ethereum_header = 1; // binary encoded headers; RLP for ethereum + } +} + +message Proof { + oneof proof { + ethereum.Proof ethereum_proof = 1; + } +} diff --git a/proto/common/ethereum/ethereum.proto b/proto/common/ethereum/ethereum.proto new file mode 100644 index 0000000000..92d3813035 --- /dev/null +++ b/proto/common/ethereum/ethereum.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package ethereum; + +option go_package = "github.com/zeta-chain/zetacore/common/ethereum"; + +message Proof { + repeated bytes keys = 1; + repeated bytes values = 2; +} diff --git a/proto/crosschain/events.proto b/proto/crosschain/events.proto index cc022fb368..90fff428fb 100644 --- a/proto/crosschain/events.proto +++ b/proto/crosschain/events.proto @@ -48,7 +48,7 @@ message EventOutboundFailure { string cctx_index = 2; string old_status = 3; string new_status = 4; - string zeta_minted = 5; + string value_received = 5; } message EventOutboundSuccess { @@ -56,5 +56,5 @@ message EventOutboundSuccess { string cctx_index = 2; string old_status = 3; string new_status = 4; - string zeta_minted = 5; + string value_received = 5; } diff --git a/proto/crosschain/out_tx_tracker.proto b/proto/crosschain/out_tx_tracker.proto index 16fa43d6d3..43d2a05f2c 100644 --- a/proto/crosschain/out_tx_tracker.proto +++ b/proto/crosschain/out_tx_tracker.proto @@ -6,6 +6,7 @@ option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; message TxHashList { string tx_hash = 1; string tx_signer = 2; + bool proved = 3; } message OutTxTracker { string index = 1; // format: "chain-nonce" diff --git a/proto/crosschain/query.proto b/proto/crosschain/query.proto index 600645508e..ca7ccb7f51 100644 --- a/proto/crosschain/query.proto +++ b/proto/crosschain/query.proto @@ -94,6 +94,10 @@ service Query { option (google.api.http).get = "/zeta-chain/crosschain/pendingNonces"; } + rpc PendingNoncesByChain(QueryPendingNoncesByChainRequest) returns (QueryPendingNoncesByChainResponse) { + option (google.api.http).get = "/zeta-chain/crosschain/pendingNonces/{chain_id}"; + } + // Queries a lastBlockHeight by index. rpc LastBlockHeight(QueryGetLastBlockHeightRequest) returns (QueryGetLastBlockHeightResponse) { option (google.api.http).get = "/zeta-chain/crosschain/lastBlockHeight/{index}"; @@ -253,6 +257,14 @@ message QueryAllPendingNoncesResponse { repeated PendingNonces pending_nonces = 1; } +message QueryPendingNoncesByChainRequest { + uint64 chain_id = 1; +} + +message QueryPendingNoncesByChainResponse { + PendingNonces pending_nonces = 1 [(gogoproto.nullable) = false]; +} + message QueryGetLastBlockHeightRequest { string index = 1; } diff --git a/proto/crosschain/tx.proto b/proto/crosschain/tx.proto index da2a21beb6..417b899787 100644 --- a/proto/crosschain/tx.proto +++ b/proto/crosschain/tx.proto @@ -17,6 +17,7 @@ service Msg { rpc VoteOnObservedInboundTx(MsgVoteOnObservedInboundTx) returns (MsgVoteOnObservedInboundTxResponse); rpc WhitelistERC20(MsgWhitelistERC20) returns (MsgWhitelistERC20Response); rpc UpdateTssAddress(MsgUpdateTssAddress) returns (MsgUpdateTssAddressResponse); + // rpc ProveOutboundTx(MsgProveOutboundTx) returns (MsgProveOutboundTxResponse); } message MsgUpdateTssAddress { @@ -25,6 +26,7 @@ message MsgUpdateTssAddress { } message MsgUpdateTssAddressResponse {} + message MsgWhitelistERC20 { string creator = 1; string erc20_address = 2; @@ -42,6 +44,9 @@ message MsgAddToOutTxTracker { int64 chain_id = 2; uint64 nonce = 3; string tx_hash = 4; + common.Proof proof = 5; + string block_hash = 6; + int64 tx_index = 7; } message MsgAddToOutTxTrackerResponse {} @@ -92,10 +97,10 @@ message MsgVoteOnObservedOutboundTx { (gogoproto.nullable) = false ]; uint64 observed_outTx_effective_gas_limit = 12; - string zeta_minted = 5 [ + string value_received = 5 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"zeta_minted\"" + (gogoproto.moretags) = "yaml:\"value_received\"" ]; common.ReceiveStatus status = 6; int64 outTx_chain = 7; diff --git a/proto/fungible/tx.proto b/proto/fungible/tx.proto index c26e0adea2..bd7a67794a 100644 --- a/proto/fungible/tx.proto +++ b/proto/fungible/tx.proto @@ -12,6 +12,7 @@ service Msg { rpc RemoveForeignCoin(MsgRemoveForeignCoin) returns (MsgRemoveForeignCoinResponse); rpc UpdateSystemContract(MsgUpdateSystemContract) returns (MsgUpdateSystemContractResponse); rpc UpdateZRC20WithdrawFee(MsgUpdateZRC20WithdrawFee) returns (MsgUpdateZRC20WithdrawFeeResponse); + rpc UpdateContractBytecode(MsgUpdateContractBytecode) returns (MsgUpdateContractBytecodeResponse); rpc UpdateZRC20PausedStatus(MsgUpdateZRC20PausedStatus) returns (MsgUpdateZRC20PausedStatusResponse); } @@ -44,7 +45,9 @@ message MsgDeployFungibleCoinZRC20 { int64 gas_limit = 8; } -message MsgDeployFungibleCoinZRC20Response {} +message MsgDeployFungibleCoinZRC20Response { + string address = 1; +} message MsgRemoveForeignCoin { string creator = 1; @@ -53,6 +56,16 @@ message MsgRemoveForeignCoin { message MsgRemoveForeignCoinResponse {} +message MsgUpdateContractBytecode { + string creator = 1; + string contract_address = 2; + string new_bytecode_address = 3; +} + +message MsgUpdateContractBytecodeResponse { + bytes new_bytecode_hash = 1; +} + enum UpdatePausedStatusAction { PAUSE = 0; UNPAUSE = 1; diff --git a/proto/observer/query.proto b/proto/observer/query.proto index b5de301651..f210f5e84c 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -79,6 +79,31 @@ service Query { rpc GetAllBlameRecords(QueryAllBlameRecordsRequest) returns (QueryAllBlameRecordsResponse) { option (google.api.http).get = "/zeta-chain/observer/get_all_blame_records"; } + + rpc GetAllBlockHeaders(QueryAllBlockHeaderRequest) returns (QueryAllBlockHeaderResponse) { + option (google.api.http).get = "/zeta-chain/observer/get_all_block_headers"; + } + + rpc GetBlockHeaderByHash(QueryGetBlockHeaderByHashRequest) returns (QueryGetBlockHeaderByHashResponse) { + option (google.api.http).get = "/zeta-chain/observer/get_block_header_by_hash/{block_hash}"; + } + + // merkle proof verification + rpc Prove(QueryProveRequest) returns (QueryProveResponse) { + option (google.api.http).get = "/zeta-chain/observer/prove"; + } +} + +message QueryProveRequest { + uint64 chain_id = 1; + string tx_hash = 2; + common.Proof proof = 3; + string block_hash = 4; + int64 tx_index = 5; +} + +message QueryProveResponse { + bool valid = 1; } message QueryParamsRequest {} @@ -185,3 +210,20 @@ message QueryAllBlameRecordsRequest {} message QueryAllBlameRecordsResponse { repeated Blame blame_info = 1; } + +message QueryAllBlockHeaderRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +message QueryAllBlockHeaderResponse { + repeated common.BlockHeader block_headers = 1; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +message QueryGetBlockHeaderByHashRequest { + bytes block_hash = 1; +} + +message QueryGetBlockHeaderByHashResponse { + common.BlockHeader block_header = 1; +} diff --git a/proto/observer/tx.proto b/proto/observer/tx.proto index 76a414cbae..368af443b5 100644 --- a/proto/observer/tx.proto +++ b/proto/observer/tx.proto @@ -16,8 +16,19 @@ service Msg { rpc AddBlameVote(MsgAddBlameVote) returns (MsgAddBlameVoteResponse); rpc UpdatePermissionFlags(MsgUpdatePermissionFlags) returns (MsgUpdatePermissionFlagsResponse); rpc UpdateKeygen(MsgUpdateKeygen) returns (MsgUpdateKeygenResponse); + rpc AddBlockHeader(MsgAddBlockHeader) returns (MsgAddBlockHeaderResponse); } +message MsgAddBlockHeader { + string creator = 1; + int64 chain_id = 2; + bytes block_hash = 3; + int64 height = 4; + common.HeaderData header = 5 [(gogoproto.nullable) = false]; +} + +message MsgAddBlockHeaderResponse {} + message MsgUpdateCoreParams { string creator = 1; CoreParams coreParams = 2; diff --git a/rpc/apis.go b/rpc/apis.go index 3256f42d77..da130ad0a1 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -20,21 +20,14 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" - "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" + rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" "github.com/zeta-chain/zetacore/rpc/backend" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/debug" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth/filters" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/miner" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/net" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/personal" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/txpool" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/web3" - - rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" ) // RPC namespaces and API version @@ -47,8 +40,8 @@ const ( Web3Namespace = "web3" EthNamespace = "eth" - PersonalNamespace = "personal" NetNamespace = "net" + PersonalNamespace = "personal" TxPoolNamespace = "txpool" DebugNamespace = "debug" MinerNamespace = "miner" @@ -112,64 +105,66 @@ func init() { }, } }, - PersonalNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: PersonalNamespace, - Version: apiVersion, - Service: personal.NewAPI(ctx.Logger, evmBackend), - Public: false, - }, - } - }, - TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { - return []rpc.API{ - { - Namespace: TxPoolNamespace, - Version: apiVersion, - Service: txpool.NewPublicAPI(ctx.Logger), - Public: true, - }, - } - }, - DebugNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: DebugNamespace, - Version: apiVersion, - Service: debug.NewAPI(ctx, evmBackend), - Public: true, - }, - } - }, - MinerNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: MinerNamespace, - Version: apiVersion, - Service: miner.NewPrivateAPI(ctx, evmBackend), - Public: false, - }, - } - }, + // Disabled + // NOTE: Public field of API is deprecated and defined only for compatibility. + //PersonalNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: PersonalNamespace, + // Version: apiVersion, + // Service: personal.NewAPI(ctx.Logger, evmBackend), + // Public: false, + // }, + // } + //}, + //TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + // return []rpc.API{ + // { + // Namespace: TxPoolNamespace, + // Version: apiVersion, + // Service: txpool.NewPublicAPI(ctx.Logger), + // Public: true, + // }, + // } + //}, + //DebugNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: DebugNamespace, + // Version: apiVersion, + // Service: debug.NewAPI(ctx, evmBackend), + // Public: true, + // }, + // } + //}, + //MinerNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: MinerNamespace, + // Version: apiVersion, + // Service: miner.NewPrivateAPI(ctx, evmBackend), + // Public: false, + // }, + // } + //}, } } diff --git a/rpc/namespaces/ethereum/debug/api.go b/rpc/namespaces/ethereum/debug/api.go index 0620b67be0..94f771ab39 100644 --- a/rpc/namespaces/ethereum/debug/api.go +++ b/rpc/namespaces/ethereum/debug/api.go @@ -27,18 +27,14 @@ import ( "sync" "time" - "github.com/davecgh/go-spew/spew" - - evmtypes "github.com/evmos/ethermint/x/evm/types" - - stderrors "github.com/pkg/errors" - "github.com/cosmos/cosmos-sdk/server" - + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/rlp" + evmtypes "github.com/evmos/ethermint/x/evm/types" + stderrors "github.com/pkg/errors" "github.com/tendermint/tendermint/libs/log" "github.com/zeta-chain/zetacore/rpc/backend" rpctypes "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/namespaces/ethereum/eth/api.go b/rpc/namespaces/ethereum/eth/api.go index d62ddbe18c..7d05848b91 100644 --- a/rpc/namespaces/ethereum/eth/api.go +++ b/rpc/namespaces/ethereum/eth/api.go @@ -18,20 +18,14 @@ package eth import ( "context" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - - "github.com/ethereum/go-ethereum/rpc" - - "github.com/tendermint/tendermint/libs/log" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - - "github.com/zeta-chain/zetacore/rpc/backend" - + "github.com/ethereum/go-ethereum/rpc" ethermint "github.com/evmos/ethermint/types" evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + "github.com/zeta-chain/zetacore/rpc/backend" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) @@ -67,7 +61,6 @@ type EthereumAPI interface { // Allows developers to both send ETH from one address to another, write data // on-chain, and interact with smart contracts. SendRawTransaction(data hexutil.Bytes) (common.Hash, error) - SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) // eth_sendPrivateTransaction // eth_cancel PrivateTransaction @@ -111,9 +104,7 @@ type EthereumAPI interface { // Other Syncing() (interface{}, error) Coinbase() (string, error) - Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) - SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) Resend(ctx context.Context, args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) @@ -125,6 +116,11 @@ type EthereumAPI interface { // eth_getWork (on Ethereum.org) // eth_submitWork (on Ethereum.org) // eth_submitHashrate (on Ethereum.org) + + // Disabled APIs for security reasons + //SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) + //Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) + //SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) } var _ EthereumAPI = (*PublicAPI)(nil) @@ -230,12 +226,6 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) return e.backend.SendRawTransaction(data) } -// SendTransaction sends an Ethereum transaction. -func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { - e.logger.Debug("eth_sendTransaction", "args", args.String()) - return e.backend.SendTransaction(args) -} - /////////////////////////////////////////////////////////////////////////////// /// Account Information /// /////////////////////////////////////////////////////////////////////////////// @@ -416,12 +406,6 @@ func (e *PublicAPI) Coinbase() (string, error) { return ethAddr.Hex(), nil } -// Sign signs the provided data using the private key of address via Geth's signature standard. -func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { - e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) - return e.backend.Sign(address, data) -} - // GetTransactionLogs returns the logs given a transaction hash. func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) { e.logger.Debug("eth_getTransactionLogs", "hash", txHash) @@ -448,12 +432,6 @@ func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, err return backend.TxLogsFromEvents(resBlockResult.TxsResults[res.TxIndex].Events, int(res.MsgIndex)) } -// SignTypedData signs EIP-712 conformant typed data -func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { - e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData) - return e.backend.SignTypedData(address, typedData) -} - // FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) // on a given unsigned transaction, and returns it to the caller for further // processing (signing + broadcast). @@ -527,3 +505,25 @@ func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) return result, nil } + +/////////////////////////////////////////////////////////////////////////////// +/// Disabled /// +/////////////////////////////////////////////////////////////////////////////// + +//// SendTransaction sends an Ethereum transaction. +//func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { +// e.logger.Debug("eth_sendTransaction", "args", args.String()) +// return e.backend.SendTransaction(args) +//} +// +//// Sign signs the provided data using the private key of address via Geth's signature standard. +//func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { +// e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) +// return e.backend.Sign(address, data) +//} +// +//// SignTypedData signs EIP-712 conformant typed data +//func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { +// e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData) +// return e.backend.SignTypedData(address, typedData) +//} diff --git a/rpc/namespaces/ethereum/eth/filters/api.go b/rpc/namespaces/ethereum/eth/filters/api.go index f6a9135a16..0268c7217d 100644 --- a/rpc/namespaces/ethereum/eth/filters/api.go +++ b/rpc/namespaces/ethereum/eth/filters/api.go @@ -22,20 +22,16 @@ import ( "time" "github.com/cosmos/cosmos-sdk/client" - "github.com/zeta-chain/zetacore/rpc/types" - - "github.com/tendermint/tendermint/libs/log" - - coretypes "github.com/tendermint/tendermint/rpc/core/types" - rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rpc" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + coretypes "github.com/tendermint/tendermint/rpc/core/types" + rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/zeta-chain/zetacore/rpc/types" ) // FilterAPI gathers diff --git a/rpc/namespaces/ethereum/eth/filters/filter_system.go b/rpc/namespaces/ethereum/eth/filters/filter_system.go index ac69cfc53d..ba203cf685 100644 --- a/rpc/namespaces/ethereum/eth/filters/filter_system.go +++ b/rpc/namespaces/ethereum/eth/filters/filter_system.go @@ -21,23 +21,19 @@ import ( "sync" "time" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/rpc" + evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" - tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" tmquery "github.com/tendermint/tendermint/libs/pubsub/query" coretypes "github.com/tendermint/tendermint/rpc/core/types" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" tmtypes "github.com/tendermint/tendermint/types" - - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" - "github.com/ethereum/go-ethereum/rpc" - - sdk "github.com/cosmos/cosmos-sdk/types" - - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" ) diff --git a/rpc/namespaces/ethereum/eth/filters/filters.go b/rpc/namespaces/ethereum/eth/filters/filters.go index 7bcb08fd75..4355182001 100644 --- a/rpc/namespaces/ethereum/eth/filters/filters.go +++ b/rpc/namespaces/ethereum/eth/filters/filters.go @@ -21,17 +21,15 @@ import ( "fmt" "math/big" - "github.com/zeta-chain/zetacore/rpc/backend" - "github.com/zeta-chain/zetacore/rpc/types" - - "github.com/pkg/errors" - "github.com/tendermint/tendermint/libs/log" - tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/filters" + "github.com/pkg/errors" + "github.com/tendermint/tendermint/libs/log" + tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/zeta-chain/zetacore/rpc/backend" + "github.com/zeta-chain/zetacore/rpc/types" ) // BloomIV represents the bit indexes and value inside the bloom filter that belong diff --git a/rpc/namespaces/ethereum/miner/api.go b/rpc/namespaces/ethereum/miner/api.go index 901c567a46..9d5e8fc556 100644 --- a/rpc/namespaces/ethereum/miner/api.go +++ b/rpc/namespaces/ethereum/miner/api.go @@ -17,12 +17,9 @@ package miner import ( "github.com/cosmos/cosmos-sdk/server" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/tendermint/tendermint/libs/log" - "github.com/zeta-chain/zetacore/rpc/backend" ) diff --git a/rpc/namespaces/ethereum/personal/api.go b/rpc/namespaces/ethereum/personal/api.go index 49b654c8dc..fa182c4759 100644 --- a/rpc/namespaces/ethereum/personal/api.go +++ b/rpc/namespaces/ethereum/personal/api.go @@ -21,22 +21,17 @@ import ( "os" "time" - "github.com/zeta-chain/zetacore/rpc/backend" - - "github.com/evmos/ethermint/crypto/hd" - ethermint "github.com/evmos/ethermint/types" - - "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" - + "github.com/evmos/ethermint/crypto/hd" + ethermint "github.com/evmos/ethermint/types" evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + "github.com/zeta-chain/zetacore/rpc/backend" ) // PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec. diff --git a/rpc/namespaces/ethereum/txpool/api.go b/rpc/namespaces/ethereum/txpool/api.go index e8320b6655..89fb056bde 100644 --- a/rpc/namespaces/ethereum/txpool/api.go +++ b/rpc/namespaces/ethereum/txpool/api.go @@ -16,10 +16,8 @@ package txpool import ( - "github.com/tendermint/tendermint/libs/log" - "github.com/ethereum/go-ethereum/common/hexutil" - + "github.com/tendermint/tendermint/libs/log" "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/namespaces/ethereum/web3/api.go b/rpc/namespaces/ethereum/web3/api.go index 47f522785d..46e09d9637 100644 --- a/rpc/namespaces/ethereum/web3/api.go +++ b/rpc/namespaces/ethereum/web3/api.go @@ -19,10 +19,9 @@ import ( "fmt" "runtime" - "github.com/zeta-chain/zetacore/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/zeta-chain/zetacore/common" ) // PublicAPI is the web3_ prefixed set of APIs in the Web3 JSON-RPC spec. diff --git a/rpc/websockets.go b/rpc/websockets.go index c76a028ea3..ba0419efcc 100644 --- a/rpc/websockets.go +++ b/rpc/websockets.go @@ -27,27 +27,28 @@ import ( "sync" "github.com/cosmos/cosmos-sdk/client" - "github.com/gorilla/mux" - "github.com/gorilla/websocket" - "github.com/pkg/errors" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - + evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/gorilla/mux" + "github.com/gorilla/websocket" + "github.com/pkg/errors" "github.com/tendermint/tendermint/libs/log" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" tmtypes "github.com/tendermint/tendermint/types" - - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" rpcfilters "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth/filters" "github.com/zeta-chain/zetacore/rpc/types" "github.com/zeta-chain/zetacore/server/config" ) +const ( + messageSizeLimit = 32 * 1024 * 1024 // 32MB +) + type WebsocketsServer interface { Start() } @@ -139,6 +140,8 @@ func (s *websocketsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + conn.SetReadLimit(messageSizeLimit) + s.readLoop(&wsConn{ mux: new(sync.Mutex), conn: conn, diff --git a/scripts/mocks-generate.sh b/scripts/mocks-generate.sh new file mode 100644 index 0000000000..8e7dc5222b --- /dev/null +++ b/scripts/mocks-generate.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Install mockery +go install github.com/vektra/mockery/v2@latest + +# Run generate command for mocks +cd ./testutil/keeper/mocks +go generate "mocks.go" + +# Print a message to indicate completion +echo "Mocks generated." \ No newline at end of file diff --git a/standalone-network/run-zetaclient.sh b/standalone-network/run-zetaclient.sh index 8c8a27b71e..5ad3375ea9 100644 --- a/standalone-network/run-zetaclient.sh +++ b/standalone-network/run-zetaclient.sh @@ -1,2 +1,2 @@ -zetaclientd init --chain-id localnet_101-1 --operator zeta1syavy2npfyt9tcncdtsdzf7kny9lh777heefxk --hotkey=zeta --public-ip=0.0.0.0 +zetaclientd init --chain-id localnet_101-1 --operator zeta13c7p3xrhd6q2rx3h235jpt8pjdwvacyw6twpax --hotkey=zeta --public-ip=0.0.0.0 zetaclientd start \ No newline at end of file diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index c8bb95e435..f96dc7e87c 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -8,11 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" tmdb "github.com/tendermint/tm-db" - crosschainmocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/crosschain" "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" - fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" ) type CrosschainMockOptions struct { @@ -35,7 +33,10 @@ var ( ) // CrosschainKeeper initializes a crosschain keeper for testing purposes with option to mock specific keepers -func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) (*keeper.Keeper, sdk.Context) { +func CrosschainKeeperWithMocks( + t testing.TB, + mockOptions CrosschainMockOptions, +) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) @@ -47,14 +48,30 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) - // Create observer keeper - var observerKeeper types.ZetaObserverKeeper = initObserverKeeper( + // Create zeta keepers + observerKeeperTmp := initObserverKeeper( cdc, db, stateStore, sdkKeepers.StakingKeeper, sdkKeepers.ParamsKeeper, ) + fungiblekeeperTmp := initFungibleKeeper( + cdc, + db, + stateStore, + sdkKeepers.ParamsKeeper, + sdkKeepers.AuthKeeper, + sdkKeepers.BankKeeper, + sdkKeepers.EvmKeeper, + observerKeeperTmp, + ) + zetaKeepers := ZetaKeepers{ + ObserverKeeper: observerKeeperTmp, + FungibleKeeper: fungiblekeeperTmp, + } + var observerKeeper types.ZetaObserverKeeper = observerKeeperTmp + var fungibleKeeper types.FungibleKeeper = fungiblekeeperTmp // Create the fungible keeper stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) @@ -65,6 +82,7 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) // Initialize modules genesis sdkKeepers.InitGenesis(ctx) + zetaKeepers.InitGenesis(ctx) // Add a proposer to the context ctx = sdkKeepers.InitBlockProposer(t, ctx) @@ -73,7 +91,6 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) var authKeeper types.AccountKeeper = sdkKeepers.AuthKeeper var bankKeeper types.BankKeeper = sdkKeepers.BankKeeper var stakingKeeper types.StakingKeeper = sdkKeepers.StakingKeeper - var fungibleKeeper types.FungibleKeeper = &fungiblekeeper.Keeper{} if mockOptions.UseAccountMock { authKeeper = crosschainmocks.NewCrosschainAccountKeeper(t) } @@ -102,16 +119,17 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) fungibleKeeper, ) - return k, ctx + return k, ctx, sdkKeepers, zetaKeepers } // CrosschainKeeperAllMocks initializes a crosschain keeper for testing purposes with all mocks func CrosschainKeeperAllMocks(t testing.TB) (*keeper.Keeper, sdk.Context) { - return CrosschainKeeperWithMocks(t, CrosschainMocksAll) + k, ctx, _, _ := CrosschainKeeperWithMocks(t, CrosschainMocksAll) + return k, ctx } // CrosschainKeeper initializes a crosschain keeper for testing purposes -func CrosschainKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { +func CrosschainKeeper(t testing.TB) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { return CrosschainKeeperWithMocks(t, CrosschainNoMocks) } diff --git a/testutil/keeper/fungible.go b/testutil/keeper/fungible.go index fe9df11be8..6f26a2733e 100644 --- a/testutil/keeper/fungible.go +++ b/testutil/keeper/fungible.go @@ -3,13 +3,14 @@ package keeper import ( "testing" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tmdb "github.com/tendermint/tm-db" - fungiblemocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/fungible" fungiblemodule "github.com/zeta-chain/zetacore/x/fungible" "github.com/zeta-chain/zetacore/x/fungible/keeper" @@ -33,6 +34,33 @@ var ( FungibleNoMocks = FungibleMockOptions{} ) +func initFungibleKeeper( + cdc codec.Codec, + db *tmdb.MemDB, + ss store.CommitMultiStore, + paramKeeper paramskeeper.Keeper, + authKeeper types.AccountKeeper, + bankKeepr types.BankKeeper, + evmKeeper types.EVMKeeper, + observerKeeper types.ObserverKeeper, +) *keeper.Keeper { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + + return keeper.NewKeeper( + cdc, + storeKey, + memKey, + paramKeeper.Subspace(types.ModuleName), + authKeeper, + evmKeeper, + bankKeepr, + observerKeeper, + ) +} + // FungibleKeeperWithMocks initializes a fungible keeper for testing purposes with option to mock specific keepers func FungibleKeeperWithMocks(t testing.TB, mockOptions FungibleMockOptions) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { storeKey := sdk.NewKVStoreKey(types.StoreKey) diff --git a/testutil/keeper/mocks/crosschain/account.go b/testutil/keeper/mocks/crosschain/account.go index 7e8c1ae7da..626900da83 100644 --- a/testutil/keeper/mocks/crosschain/account.go +++ b/testutil/keeper/mocks/crosschain/account.go @@ -1,10 +1,9 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - mock "github.com/stretchr/testify/mock" types "github.com/cosmos/cosmos-sdk/types" diff --git a/testutil/keeper/mocks/crosschain/bank.go b/testutil/keeper/mocks/crosschain/bank.go index 39acac1f3a..cdf1e371ef 100644 --- a/testutil/keeper/mocks/crosschain/bank.go +++ b/testutil/keeper/mocks/crosschain/bank.go @@ -1,10 +1,11 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( - types "github.com/cosmos/cosmos-sdk/types" mock "github.com/stretchr/testify/mock" + + types "github.com/cosmos/cosmos-sdk/types" ) // CrosschainBankKeeper is an autogenerated mock type for the CrosschainBankKeeper type diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index 8daca22327..a6b763b8a3 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -22,8 +22,8 @@ type CrosschainFungibleKeeper struct { mock.Mock } -// CallUniswapv2RouterSwapExactETHForToken provides a mock function with given fields: ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent -func (_m *CrosschainFungibleKeeper) CallUniswapv2RouterSwapExactETHForToken(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { +// CallUniswapV2RouterSwapExactETHForToken provides a mock function with given fields: ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallUniswapV2RouterSwapExactETHForToken(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { ret := _m.Called(ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent) var r0 []*big.Int @@ -48,6 +48,46 @@ func (_m *CrosschainFungibleKeeper) CallUniswapv2RouterSwapExactETHForToken(ctx return r0, r1 } +// CallUniswapV2RouterSwapExactTokensForTokens provides a mock function with given fields: ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallUniswapV2RouterSwapExactTokensForTokens(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, inZRC4 common.Address, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { + ret := _m.Called(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + + var r0 []*big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) ([]*big.Int, error)); ok { + return rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) []*big.Int); ok { + r0 = rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) error); ok { + r1 = rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CallZRC20Approve provides a mock function with given fields: ctx, owner, zrc20address, spender, amount, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallZRC20Approve(ctx types.Context, owner common.Address, zrc20address common.Address, spender common.Address, amount *big.Int, noEthereumTxEvent bool) error { + ret := _m.Called(ctx, owner, zrc20address, spender, amount, noEthereumTxEvent) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, common.Address, *big.Int, bool) error); ok { + r0 = rf(ctx, owner, zrc20address, spender, amount, noEthereumTxEvent) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // CallZRC20Burn provides a mock function with given fields: ctx, sender, zrc20address, amount, noEthereumTxEvent func (_m *CrosschainFungibleKeeper) CallZRC20Burn(ctx types.Context, sender common.Address, zrc20address common.Address, amount *big.Int, noEthereumTxEvent bool) error { ret := _m.Called(ctx, sender, zrc20address, amount, noEthereumTxEvent) @@ -102,6 +142,32 @@ func (_m *CrosschainFungibleKeeper) DepositCoinZeta(ctx types.Context, to common return r0 } +// DepositZRC20 provides a mock function with given fields: ctx, contract, to, amount +func (_m *CrosschainFungibleKeeper) DepositZRC20(ctx types.Context, contract common.Address, to common.Address, amount *big.Int) (*evmtypes.MsgEthereumTxResponse, error) { + ret := _m.Called(ctx, contract, to, amount) + + var r0 *evmtypes.MsgEthereumTxResponse + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int) (*evmtypes.MsgEthereumTxResponse, error)); ok { + return rf(ctx, contract, to, amount) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int) *evmtypes.MsgEthereumTxResponse); ok { + r0 = rf(ctx, contract, to, amount) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evmtypes.MsgEthereumTxResponse) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address, common.Address, *big.Int) error); ok { + r1 = rf(ctx, contract, to, amount) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FundGasStabilityPool provides a mock function with given fields: ctx, chainID, amount func (_m *CrosschainFungibleKeeper) FundGasStabilityPool(ctx types.Context, chainID int64, amount *big.Int) error { ret := _m.Called(ctx, chainID, amount) @@ -148,6 +214,30 @@ func (_m *CrosschainFungibleKeeper) GetAllForeignCoinsForChain(ctx types.Context return r0 } +// GetForeignCoinFromAsset provides a mock function with given fields: ctx, asset, chainID +func (_m *CrosschainFungibleKeeper) GetForeignCoinFromAsset(ctx types.Context, asset string, chainID int64) (fungibletypes.ForeignCoins, bool) { + ret := _m.Called(ctx, asset, chainID) + + var r0 fungibletypes.ForeignCoins + var r1 bool + if rf, ok := ret.Get(0).(func(types.Context, string, int64) (fungibletypes.ForeignCoins, bool)); ok { + return rf(ctx, asset, chainID) + } + if rf, ok := ret.Get(0).(func(types.Context, string, int64) fungibletypes.ForeignCoins); ok { + r0 = rf(ctx, asset, chainID) + } else { + r0 = ret.Get(0).(fungibletypes.ForeignCoins) + } + + if rf, ok := ret.Get(1).(func(types.Context, string, int64) bool); ok { + r1 = rf(ctx, asset, chainID) + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + // GetForeignCoins provides a mock function with given fields: ctx, zrc20Addr func (_m *CrosschainFungibleKeeper) GetForeignCoins(ctx types.Context, zrc20Addr string) (fungibletypes.ForeignCoins, bool) { ret := _m.Called(ctx, zrc20Addr) @@ -196,6 +286,84 @@ func (_m *CrosschainFungibleKeeper) GetSystemContract(ctx types.Context) (fungib return r0, r1 } +// GetUniswapV2Router02Address provides a mock function with given fields: ctx +func (_m *CrosschainFungibleKeeper) GetUniswapV2Router02Address(ctx types.Context) (common.Address, error) { + ret := _m.Called(ctx) + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(types.Context) (common.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(types.Context) common.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(types.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryGasLimit provides a mock function with given fields: ctx, contract +func (_m *CrosschainFungibleKeeper) QueryGasLimit(ctx types.Context, contract common.Address) (*big.Int, error) { + ret := _m.Called(ctx, contract) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address) (*big.Int, error)); ok { + return rf(ctx, contract) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *big.Int); ok { + r0 = rf(ctx, contract) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address) error); ok { + r1 = rf(ctx, contract) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryProtocolFlatFee provides a mock function with given fields: ctx, contract +func (_m *CrosschainFungibleKeeper) QueryProtocolFlatFee(ctx types.Context, contract common.Address) (*big.Int, error) { + ret := _m.Called(ctx, contract) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address) (*big.Int, error)); ok { + return rf(ctx, contract) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *big.Int); ok { + r0 = rf(ctx, contract) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address) error); ok { + r1 = rf(ctx, contract) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // QuerySystemContractGasCoinZRC20 provides a mock function with given fields: ctx, chainID func (_m *CrosschainFungibleKeeper) QuerySystemContractGasCoinZRC20(ctx types.Context, chainID *big.Int) (common.Address, error) { ret := _m.Called(ctx, chainID) @@ -222,8 +390,60 @@ func (_m *CrosschainFungibleKeeper) QuerySystemContractGasCoinZRC20(ctx types.Co return r0, r1 } -// QueryUniswapv2RouterGetAmountsIn provides a mock function with given fields: ctx, amountOut, outZRC4 -func (_m *CrosschainFungibleKeeper) QueryUniswapv2RouterGetAmountsIn(ctx types.Context, amountOut *big.Int, outZRC4 common.Address) (*big.Int, error) { +// QueryUniswapV2RouterGetZRC4AmountsIn provides a mock function with given fields: ctx, amountOut, inZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZRC4AmountsIn(ctx types.Context, amountOut *big.Int, inZRC4 common.Address) (*big.Int, error) { + ret := _m.Called(ctx, amountOut, inZRC4) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address) (*big.Int, error)); ok { + return rf(ctx, amountOut, inZRC4) + } + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address) *big.Int); ok { + r0 = rf(ctx, amountOut, inZRC4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, *big.Int, common.Address) error); ok { + r1 = rf(ctx, amountOut, inZRC4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn provides a mock function with given fields: ctx, amountOut, inZRC4, outZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx types.Context, amountOut *big.Int, inZRC4 common.Address, outZRC4 common.Address) (*big.Int, error) { + ret := _m.Called(ctx, amountOut, inZRC4, outZRC4) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address, common.Address) (*big.Int, error)); ok { + return rf(ctx, amountOut, inZRC4, outZRC4) + } + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address, common.Address) *big.Int); ok { + r0 = rf(ctx, amountOut, inZRC4, outZRC4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, *big.Int, common.Address, common.Address) error); ok { + r1 = rf(ctx, amountOut, inZRC4, outZRC4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryUniswapV2RouterGetZetaAmountsIn provides a mock function with given fields: ctx, amountOut, outZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZetaAmountsIn(ctx types.Context, amountOut *big.Int, outZRC4 common.Address) (*big.Int, error) { ret := _m.Called(ctx, amountOut, outZRC4) var r0 *big.Int diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index 08735e93dd..5811d9ba4d 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -1,11 +1,10 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( - common "github.com/zeta-chain/zetacore/common" - mock "github.com/stretchr/testify/mock" + common "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" @@ -173,6 +172,30 @@ func (_m *CrosschainObserverKeeper) GetBallot(ctx types.Context, index string) ( return r0, r1 } +// GetBlockHeader provides a mock function with given fields: ctx, hash +func (_m *CrosschainObserverKeeper) GetBlockHeader(ctx types.Context, hash []byte) (common.BlockHeader, bool) { + ret := _m.Called(ctx, hash) + + var r0 common.BlockHeader + var r1 bool + if rf, ok := ret.Get(0).(func(types.Context, []byte) (common.BlockHeader, bool)); ok { + return rf(ctx, hash) + } + if rf, ok := ret.Get(0).(func(types.Context, []byte) common.BlockHeader); ok { + r0 = rf(ctx, hash) + } else { + r0 = ret.Get(0).(common.BlockHeader) + } + + if rf, ok := ret.Get(1).(func(types.Context, []byte) bool); ok { + r1 = rf(ctx, hash) + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + // GetCoreParamsByChainID provides a mock function with given fields: ctx, chainID func (_m *CrosschainObserverKeeper) GetCoreParamsByChainID(ctx types.Context, chainID int64) (*observertypes.CoreParams, bool) { ret := _m.Called(ctx, chainID) diff --git a/testutil/keeper/mocks/crosschain/staking.go b/testutil/keeper/mocks/crosschain/staking.go index a6c02e638d..3027f516b1 100644 --- a/testutil/keeper/mocks/crosschain/staking.go +++ b/testutil/keeper/mocks/crosschain/staking.go @@ -1,11 +1,12 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" mock "github.com/stretchr/testify/mock" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + types "github.com/cosmos/cosmos-sdk/types" ) diff --git a/testutil/keeper/mocks/fungible/account.go b/testutil/keeper/mocks/fungible/account.go index 301f6d882a..8ca9535cad 100644 --- a/testutil/keeper/mocks/fungible/account.go +++ b/testutil/keeper/mocks/fungible/account.go @@ -1,10 +1,9 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - mock "github.com/stretchr/testify/mock" types "github.com/cosmos/cosmos-sdk/types" diff --git a/testutil/keeper/mocks/fungible/bank.go b/testutil/keeper/mocks/fungible/bank.go index dbbb384d3e..a061b091f4 100644 --- a/testutil/keeper/mocks/fungible/bank.go +++ b/testutil/keeper/mocks/fungible/bank.go @@ -1,10 +1,9 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - mock "github.com/stretchr/testify/mock" types "github.com/cosmos/cosmos-sdk/types" diff --git a/testutil/keeper/mocks/fungible/evm.go b/testutil/keeper/mocks/fungible/evm.go index e05034a958..81653bd4a4 100644 --- a/testutil/keeper/mocks/fungible/evm.go +++ b/testutil/keeper/mocks/fungible/evm.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -6,12 +6,16 @@ import ( context "context" big "math/big" + common "github.com/ethereum/go-ethereum/common" + core "github.com/ethereum/go-ethereum/core" evmtypes "github.com/evmos/ethermint/x/evm/types" mock "github.com/stretchr/testify/mock" + statedb "github.com/evmos/ethermint/x/evm/statedb" + types "github.com/cosmos/cosmos-sdk/types" vm "github.com/ethereum/go-ethereum/core/vm" @@ -90,6 +94,22 @@ func (_m *FungibleEVMKeeper) EstimateGas(c context.Context, req *evmtypes.EthCal return r0, r1 } +// GetAccount provides a mock function with given fields: ctx, addr +func (_m *FungibleEVMKeeper) GetAccount(ctx types.Context, addr common.Address) *statedb.Account { + ret := _m.Called(ctx, addr) + + var r0 *statedb.Account + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *statedb.Account); ok { + r0 = rf(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*statedb.Account) + } + } + + return r0 +} + // GetBlockBloomTransient provides a mock function with given fields: ctx func (_m *FungibleEVMKeeper) GetBlockBloomTransient(ctx types.Context) *big.Int { ret := _m.Called(ctx) @@ -120,6 +140,20 @@ func (_m *FungibleEVMKeeper) GetLogSizeTransient(ctx types.Context) uint64 { return r0 } +// SetAccount provides a mock function with given fields: ctx, addr, account +func (_m *FungibleEVMKeeper) SetAccount(ctx types.Context, addr common.Address, account statedb.Account) error { + ret := _m.Called(ctx, addr, account) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, statedb.Account) error); ok { + r0 = rf(ctx, addr, account) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // SetBlockBloomTransient provides a mock function with given fields: ctx, bloom func (_m *FungibleEVMKeeper) SetBlockBloomTransient(ctx types.Context, bloom *big.Int) { _m.Called(ctx, bloom) diff --git a/testutil/keeper/mocks/fungible/observer.go b/testutil/keeper/mocks/fungible/observer.go index 7d8248a6ae..13f419d80a 100644 --- a/testutil/keeper/mocks/fungible/observer.go +++ b/testutil/keeper/mocks/fungible/observer.go @@ -1,11 +1,10 @@ -// Code generated by mockery v2.32.3. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( - common "github.com/zeta-chain/zetacore/common" - mock "github.com/stretchr/testify/mock" + common "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks/mocks.go similarity index 74% rename from testutil/keeper/mocks.go rename to testutil/keeper/mocks/mocks.go index 90d3835197..53e5842e65 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks/mocks.go @@ -1,4 +1,4 @@ -package keeper +package mocks import ( crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -9,27 +9,27 @@ import ( * Crosschain Mocks */ -//go:generate mockery --name CrosschainAccountKeeper --filename account.go --case underscore --output ./mocks/crosschain +//go:generate mockery --name CrosschainAccountKeeper --filename account.go --case underscore --output ./crosschain type CrosschainAccountKeeper interface { crosschaintypes.AccountKeeper } -//go:generate mockery --name CrosschainBankKeeper --filename bank.go --case underscore --output ./mocks/crosschain +//go:generate mockery --name CrosschainBankKeeper --filename bank.go --case underscore --output ./crosschain type CrosschainBankKeeper interface { crosschaintypes.BankKeeper } -//go:generate mockery --name CrosschainStakingKeeper --filename staking.go --case underscore --output ./mocks/crosschain +//go:generate mockery --name CrosschainStakingKeeper --filename staking.go --case underscore --output ./crosschain type CrosschainStakingKeeper interface { crosschaintypes.StakingKeeper } -//go:generate mockery --name CrosschainObserverKeeper --filename observer.go --case underscore --output ./mocks/crosschain +//go:generate mockery --name CrosschainObserverKeeper --filename observer.go --case underscore --output ./crosschain type CrosschainObserverKeeper interface { crosschaintypes.ZetaObserverKeeper } -//go:generate mockery --name CrosschainFungibleKeeper --filename fungible.go --case underscore --output ./mocks/crosschain +//go:generate mockery --name CrosschainFungibleKeeper --filename fungible.go --case underscore --output ./crosschain type CrosschainFungibleKeeper interface { crosschaintypes.FungibleKeeper } @@ -38,22 +38,22 @@ type CrosschainFungibleKeeper interface { * Fungible Mocks */ -//go:generate mockery --name FungibleAccountKeeper --filename account.go --case underscore --output ./mocks/fungible +//go:generate mockery --name FungibleAccountKeeper --filename account.go --case underscore --output ./fungible type FungibleAccountKeeper interface { fungibletypes.AccountKeeper } -//go:generate mockery --name FungibleBankKeeper --filename bank.go --case underscore --output ./mocks/fungible +//go:generate mockery --name FungibleBankKeeper --filename bank.go --case underscore --output ./fungible type FungibleBankKeeper interface { fungibletypes.BankKeeper } -//go:generate mockery --name FungibleObserverKeeper --filename observer.go --case underscore --output ./mocks/fungible +//go:generate mockery --name FungibleObserverKeeper --filename observer.go --case underscore --output ./fungible type FungibleObserverKeeper interface { fungibletypes.ObserverKeeper } -//go:generate mockery --name FungibleEVMKeeper --filename evm.go --case underscore --output ./mocks/fungible +//go:generate mockery --name FungibleEVMKeeper --filename evm.go --case underscore --output ./fungible type FungibleEVMKeeper interface { fungibletypes.EVMKeeper } diff --git a/testutil/network/network_config.go b/testutil/network/network_config.go index 29391739af..2aabd219e1 100644 --- a/testutil/network/network_config.go +++ b/testutil/network/network_config.go @@ -24,6 +24,7 @@ import ( // genesis and single validator. All other parameters are inherited from cosmos-sdk/testutil/network.DefaultConfig func DefaultConfig() Config { encoding := app.MakeEncodingConfig() + return Config{ Codec: encoding.Codec, TxConfig: encoding.TxConfig, diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 22b57c6cde..2eef2b61b0 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -7,6 +7,8 @@ import ( "strconv" "testing" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -113,3 +115,8 @@ func StringRandom(r *rand.Rand, length int) string { } return string(result) } + +// Coins returns a sample sdk.Coins +func Coins() sdk.Coins { + return sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewInt(42))) +} diff --git a/x/crosschain/client/cli/cli_cctx.go b/x/crosschain/client/cli/cli_cctx.go index 11e4e814a5..058233bb77 100644 --- a/x/crosschain/client/cli/cli_cctx.go +++ b/x/crosschain/client/cli/cli_cctx.go @@ -99,14 +99,23 @@ func CmdCCTXInboundVoter() *cobra.Command { } amount := math.NewUintFromString(args[5]) + argsMessage := args[6] argsInTxHash := args[7] + argsInBlockHeight, err := strconv.ParseUint(args[8], 10, 64) - argsCoinType := common.CoinType(common.CoinType_value[args[9]]) - argsAsset := args[10] if err != nil { return err } + + coinType, ok := common.CoinType_value[args[9]] + if !ok { + return fmt.Errorf("wrong coin type %s", args[9]) + } + argsCoinType := common.CoinType(coinType) + + argsAsset := args[10] + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err @@ -141,7 +150,7 @@ func CmdCCTXInboundVoter() *cobra.Command { func CmdCCTXOutboundVoter() *cobra.Command { cmd := &cobra.Command{ - Use: "outbound-voter [sendHash] [outTxHash] [outBlockHeight] [outGasUsed] [outEffectiveGasPrice] [outEffectiveGasLimit] [ZetaMinted] [Status] [chain] [outTXNonce] [coinType]", + Use: "outbound-voter [sendHash] [outTxHash] [outBlockHeight] [outGasUsed] [outEffectiveGasPrice] [outEffectiveGasLimit] [valueReceived] [Status] [chain] [outTXNonce] [coinType]", Short: "Broadcast message receiveConfirmation", Args: cobra.ExactArgs(11), RunE: func(cmd *cobra.Command, args []string) error { @@ -189,7 +198,12 @@ func CmdCCTXOutboundVoter() *cobra.Command { return err } - argsCoinType := common.CoinType(common.CoinType_value[args[10]]) + coinType, ok := common.CoinType_value[args[10]] + if !ok { + return fmt.Errorf("wrong coin type %s", args[10]) + } + argsCoinType := common.CoinType(coinType) + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err diff --git a/x/crosschain/client/cli/cli_out_tx_tracker.go b/x/crosschain/client/cli/cli_out_tx_tracker.go index 87535ea0be..95432badad 100644 --- a/x/crosschain/client/cli/cli_out_tx_tracker.go +++ b/x/crosschain/client/cli/cli_out_tx_tracker.go @@ -110,6 +110,9 @@ func CmdAddToWatchList() *cobra.Command { argChain, uint64(argNonce), argTxHash, + nil, // TODO: add option to provide a proof from CLI arguments https://github.com/zeta-chain/node/issues/1134 + "", + -1, ) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 16922f18da..06a3198b1d 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -27,12 +27,6 @@ import ( "github.com/zeta-chain/zetacore/x/crosschain/client/cli" ) -func MsgVoteOnObservedInboundTxExec(clientCtx client.Context, chain, obsType fmt.Stringer, extraArgs ...string) (testutil.BufferWriter, error) { - args := []string{chain.String(), obsType.String()} - args = append(args, extraArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, cli.CmdCCTXInboundVoter(), args) -} - func TxSignExec(clientCtx client.Context, from fmt.Stringer, filename string, extraArgs ...string) (testutil.BufferWriter, error) { args := []string{ fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), @@ -128,7 +122,8 @@ func BuildSignedTssVote(t testing.TB, val *network.Validator, denom string, acco return WriteToNewTempFile(t, res.String()) } -func BuildSignedOutboundVote(t testing.TB, val *network.Validator, denom string, account authtypes.AccountI, cctxIndex, outTxHash, zetaminted, status string) *os.File { +func BuildSignedOutboundVote(t testing.TB, val *network.Validator, denom string, account authtypes.AccountI, + cctxIndex, outTxHash, valueReceived, status string) *os.File { cmd := cli.CmdCCTXOutboundVoter() outboundVoterArgs := []string{ cctxIndex, @@ -137,11 +132,11 @@ func BuildSignedOutboundVote(t testing.TB, val *network.Validator, denom string, "0", "0", "0", - zetaminted, + valueReceived, status, strconv.FormatInt(common.GoerliChain().ChainId, 10), "1", - "Gas", + "Zeta", } txArgs := []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), @@ -172,7 +167,7 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, message, "0x19398991572a825894b34b904ac1e3692720895351466b5c9e6bb7ae1e21d680", "100", - "Gas", + "Zeta", "", } txArgs := []string{ @@ -204,15 +199,13 @@ func GetBallotIdentifier(message string) string { "0x19398991572a825894b34b904ac1e3692720895351466b5c9e6bb7ae1e21d680", 100, 250_000, - common.CoinType_Gas, + common.CoinType_Zeta, "", ) return msg.Digest() } -func GetBallotIdentifierOutBound(cctxindex, outtxHash, zetaminted string) string { - math.NewUintFromString(zetaminted) - +func GetBallotIdentifierOutBound(cctxindex, outtxHash, valueReceived string) string { msg := types.NewMsgVoteOnObservedOutboundTx( "", cctxindex, @@ -221,11 +214,11 @@ func GetBallotIdentifierOutBound(cctxindex, outtxHash, zetaminted string) string 0, math.ZeroInt(), 0, - math.NewUintFromString(zetaminted), + math.NewUintFromString(valueReceived), 0, common.GoerliChain().ChainId, 1, - common.CoinType_Gas, + common.CoinType_Zeta, ) return msg.Digest() } diff --git a/x/crosschain/client/integrationtests/inbound_voter_test.go b/x/crosschain/client/integrationtests/inbound_voter_test.go index c78b990199..6305295b2a 100644 --- a/x/crosschain/client/integrationtests/inbound_voter_test.go +++ b/x/crosschain/client/integrationtests/inbound_voter_test.go @@ -129,8 +129,12 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { test := test s.Run(test.name, func() { broadcaster := s.network.Validators[0] + + // Vote the gas price for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) + s.Require().NoError(err) + var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) signedTx := BuildSignedGasPriceVote(s.T(), val, s.cfg.BondDenom, account) @@ -138,8 +142,12 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the tss for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) + s.Require().NoError(err) + var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) signedTx := BuildSignedTssVote(s.T(), val, s.cfg.BondDenom, account) @@ -147,6 +155,8 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the inbound tx for _, val := range s.network.Validators { vote := test.votes[val.Address.String()] if vote == observerTypes.VoteType_NotYetVoted { @@ -164,14 +174,16 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } - s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the ballot ballotIdentifier := GetBallotIdentifier(test.name) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observerCli.CmdBallotByIdentifier(), []string{ballotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ballot)) + // Check the vote in the ballot s.Assert().Equal(len(test.votes), len(ballot.Voters)) for _, vote := range ballot.Voters { if test.votes[vote.VoterAddress] == observerTypes.VoteType_FailureObservation { @@ -182,6 +194,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { } s.Assert().Equal(test.ballotResult, ballot.BallotStatus) + // Get the cctx and check its status cctxIdentifier := ballotIdentifier if test.falseBallotIdentifier != "" { cctxIdentifier = test.falseBallotIdentifier @@ -189,7 +202,6 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} if test.cctxStatus == crosschaintypes.CctxStatus_PendingRevert { - s.Require().Error(err) s.Require().Contains(out.String(), "not found") } else { s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) diff --git a/x/crosschain/client/integrationtests/outbound_voter_test.go b/x/crosschain/client/integrationtests/outbound_voter_test.go index dee7ea514e..7671708295 100644 --- a/x/crosschain/client/integrationtests/outbound_voter_test.go +++ b/x/crosschain/client/integrationtests/outbound_voter_test.go @@ -22,7 +22,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { tt := []struct { name string votes []Vote - zetaMinted string // TODO : calculate this value + valueReceived string // TODO : calculate this value correctBallotResult observerTypes.BallotStatus cctxStatus crosschaintypes.CctxStatus falseBallotIdentifier string @@ -43,7 +43,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { }, correctBallotResult: observerTypes.BallotStatus_BallotFinalized_SuccessObservation, cctxStatus: crosschaintypes.CctxStatus_OutboundMined, - zetaMinted: "7991636132140714751", + valueReceived: "7991636132140714751", }, { name: "1 fake vote but ballot still success", @@ -61,7 +61,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { }, correctBallotResult: observerTypes.BallotStatus_BallotFinalized_SuccessObservation, cctxStatus: crosschaintypes.CctxStatus_OutboundMined, - zetaMinted: "7990439496224753106", + valueReceived: "7990439496224753106", }, { name: "Half success and half false", @@ -79,7 +79,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { }, correctBallotResult: observerTypes.BallotStatus_BallotInProgress, cctxStatus: crosschaintypes.CctxStatus_PendingOutbound, - zetaMinted: "7993442360774956232", + valueReceived: "7993442360774956232", }, { name: "Fake ballot has more votes outbound gets finalized", @@ -97,7 +97,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { }, correctBallotResult: observerTypes.BallotStatus_BallotInProgress, cctxStatus: crosschaintypes.CctxStatus_OutboundMined, - zetaMinted: "7987124742653889020", + valueReceived: "7987124742653889020", }, { name: "5 success 5 Failed votes ", @@ -115,13 +115,15 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { }, correctBallotResult: observerTypes.BallotStatus_BallotInProgress, cctxStatus: crosschaintypes.CctxStatus_PendingOutbound, - zetaMinted: "7991636132140714751", + valueReceived: "7991636132140714751", }, } for _, test := range tt { test := test s.Run(test.name, func() { broadcaster := s.network.Validators[0] + + // Vote the gas price for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -131,6 +133,8 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the tss for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -140,6 +144,8 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the inbound tx for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -149,14 +155,16 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } - s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the ballot cctxIdentifier := GetBallotIdentifier(test.name) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) s.Assert().Equal(crosschaintypes.CctxStatus_PendingOutbound, cctx.CrossChainTx.CctxStatus.Status) + // Check the vote in the ballot and vote the outbound tx fakeVotes := []string{} for _, val := range s.network.Validators { valVote := Vote{} @@ -171,6 +179,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) + outTxhash := test.name if valVote.isFakeVote { outTxhash = outTxhash + "falseVote" @@ -184,21 +193,27 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { votestring = "1" } - signedTx := BuildSignedOutboundVote(s.T(), val, s.cfg.BondDenom, account, cctxIdentifier, outTxhash, test.zetaMinted, votestring) + // Vote the outbound tx + signedTx := BuildSignedOutboundVote(s.T(), val, s.cfg.BondDenom, account, cctxIdentifier, outTxhash, test.valueReceived, votestring) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the cctx out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx = crosschaintypes.QueryGetCctxResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) s.Assert().Equal(test.cctxStatus, cctx.CrossChainTx.CctxStatus.Status) - outboundBallotIdentifier := GetBallotIdentifierOutBound(cctxIdentifier, test.name, test.zetaMinted) + + outboundBallotIdentifier := GetBallotIdentifierOutBound(cctxIdentifier, test.name, test.valueReceived) + out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observerCli.CmdBallotByIdentifier(), []string{outboundBallotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ballot)) + // Check the votes s.Require().Equal(test.correctBallotResult, ballot.BallotStatus) for _, vote := range test.votes { for _, ballotvote := range ballot.Voters { @@ -213,25 +228,22 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { } } if len(fakeVotes) > 0 { - outboundFakeBallotIdentifier := GetBallotIdentifierOutBound(cctxIdentifier, test.name+"falseVote", test.zetaMinted) + outboundFakeBallotIdentifier := GetBallotIdentifierOutBound(cctxIdentifier, test.name+"falseVote", test.valueReceived) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observerCli.CmdBallotByIdentifier(), []string{outboundFakeBallotIdentifier, "--output", "json"}) s.Require().NoError(err) fakeBallot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &fakeBallot)) for _, vote := range test.votes { if vote.isFakeVote { - for _, ballotvote := range fakeBallot.Voters { - if vote.voterAddress == ballotvote.VoterAddress { - s.Assert().Equal(vote.voteType, ballotvote.VoteType) + for _, ballotVote := range fakeBallot.Voters { + if vote.voterAddress == ballotVote.VoterAddress { + s.Assert().Equal(vote.voteType, ballotVote.VoteType) break } } } } - } - }) - } } diff --git a/x/crosschain/genesis_test.go b/x/crosschain/genesis_test.go index af745a938d..994c83f67a 100644 --- a/x/crosschain/genesis_test.go +++ b/x/crosschain/genesis_test.go @@ -48,7 +48,7 @@ func TestGenesis(t *testing.T) { } // Init and export - k, ctx := keepertest.CrosschainKeeper(t) + k, ctx, _, _ := keepertest.CrosschainKeeper(t) crosschain.InitGenesis(ctx, *k, genesisState) got := crosschain.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/crosschain/keeper/abci_test.go b/x/crosschain/keeper/abci_test.go index 374f307f73..1a8e484a1d 100644 --- a/x/crosschain/keeper/abci_test.go +++ b/x/crosschain/keeper/abci_test.go @@ -205,7 +205,7 @@ func TestKeeper_CheckAndUpdateCctxGasPrice(t *testing.T) { } func TestKeeper_IncreaseCctxGasPrice(t *testing.T) { - k, ctx := testkeeper.CrosschainKeeper(t) + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) t.Run("can increase gas", func(t *testing.T) { // sample cctx diff --git a/x/crosschain/keeper/cctx_utils.go b/x/crosschain/keeper/cctx_utils.go new file mode 100644 index 0000000000..2333cf7add --- /dev/null +++ b/x/crosschain/keeper/cctx_utils.go @@ -0,0 +1,87 @@ +package keeper + +import ( + "errors" + "fmt" + + "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/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/crosschain/types" + zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. +// It also updates the PendingNonces that is used to track the unfulfilled outbound txs. +func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { + chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiveChainID) + if chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + nonce, found := k.GetChainNonces(ctx, chain.ChainName.String()) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindReceiverNonce, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) + } + + // SET nonce + cctx.GetCurrentOutTxParam().OutboundTxTssNonce = nonce.Nonce + tss, found := k.GetTSS(ctx) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindTSSKeys, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) + } + + p, found := k.GetPendingNonces(ctx, tss.TssPubkey, uint64(receiveChainID)) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindPendingNonces, fmt.Sprintf("chain_id %d, nonce %d", receiveChainID, nonce.Nonce)) + } + + if p.NonceHigh != int64(nonce.Nonce) { + return sdkerrors.Wrap(types.ErrNonceMismatch, fmt.Sprintf("chain_id %d, high nonce %d, current nonce %d", receiveChainID, p.NonceHigh, nonce.Nonce)) + } + + nonce.Nonce++ + p.NonceHigh++ + k.SetChainNonces(ctx, nonce) + k.SetPendingNonces(ctx, p) + return nil +} + +// RefundAmountOnZetaChain refunds the amount of the cctx on ZetaChain in case of aborted cctx +// NOTE: GetCurrentOutTxParam should contain the last up to date cctx amount +func (k Keeper) RefundAmountOnZetaChain(ctx sdk.Context, cctx types.CrossChainTx, inputAmount math.Uint) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_ERC20 { + return errors.New("unsupported coin type for refund on ZetaChain") + } + if !common.IsEVMChain(cctx.InboundTxParams.SenderChainId) { + return errors.New("only EVM chains are supported for refund on ZetaChain") + } + sender := ethcommon.HexToAddress(cctx.InboundTxParams.Sender) + if sender == (ethcommon.Address{}) { + return errors.New("invalid sender address") + } + if inputAmount.IsNil() || inputAmount.IsZero() { + return errors.New("no amount to refund") + } + + // get address of the zrc20 + fc, found := k.fungibleKeeper.GetForeignCoinFromAsset(ctx, cctx.InboundTxParams.Asset, cctx.InboundTxParams.SenderChainId) + if !found { + return fmt.Errorf("asset %s zrc not found", cctx.InboundTxParams.Asset) + } + zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return fmt.Errorf("asset %s invalid zrc address", cctx.InboundTxParams.Asset) + } + + // deposit the amount to the sender + if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, sender, inputAmount.BigInt()); err != nil { + return errors.New("failed to deposit zrc20 on ZetaChain" + err.Error()) + } + + return nil +} diff --git a/x/crosschain/keeper/cctx_utils_test.go b/x/crosschain/keeper/cctx_utils_test.go new file mode 100644 index 0000000000..bdeb9eff4d --- /dev/null +++ b/x/crosschain/keeper/cctx_utils_test.go @@ -0,0 +1,140 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + + "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/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_RefundAmountOnZetaChain(t *testing.T) { + t.Run("should refund amount on zeta chain", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + asset := sample.EthAddress().String() + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + // deploy zrc20 + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + asset, + "bar", + ) + + err := k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + }}, + math.NewUint(42), + ) + require.NoError(t, err) + + // check amount deposited in balance + balance, err := zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender) + require.NoError(t, err) + require.Equal(t, uint64(42), balance.Uint64()) + + // can refund again + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + }}, + math.NewUint(42), + ) + require.NoError(t, err) + balance, err = zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender) + require.NoError(t, err) + require.Equal(t, uint64(84), balance.Uint64()) + }) + + t.Run("should fail with invalid cctx", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + + err := k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_Zeta, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "unsupported coin type") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_Gas, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "unsupported coin type") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: 999999, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "only EVM chains are supported") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: "invalid", + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "invalid sender address") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + }, + }, + math.Uint{}, + ) + require.ErrorContains(t, err, "no amount to refund") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + }}, + math.ZeroUint(), + ) + require.ErrorContains(t, err, "no amount to refund") + + // the foreign coin has not been set + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "zrc not found") + }) +} diff --git a/x/crosschain/keeper/events.go b/x/crosschain/keeper/events.go index 3306b7d1f8..2f6a88908c 100644 --- a/x/crosschain/keeper/events.go +++ b/x/crosschain/keeper/events.go @@ -61,11 +61,11 @@ func EmitZetaWithdrawCreated(ctx sdk.Context, cctx types.CrossChainTx) { func EmitOutboundSuccess(ctx sdk.Context, msg *types.MsgVoteOnObservedOutboundTx, oldStatus string, newStatus string, cctx types.CrossChainTx) { err := ctx.EventManager().EmitTypedEvents(&types.EventOutboundSuccess{ - MsgTypeUrl: sdk.MsgTypeURL(&types.MsgVoteOnObservedOutboundTx{}), - CctxIndex: cctx.Index, - ZetaMinted: msg.ZetaMinted.String(), - OldStatus: oldStatus, - NewStatus: newStatus, + MsgTypeUrl: sdk.MsgTypeURL(&types.MsgVoteOnObservedOutboundTx{}), + CctxIndex: cctx.Index, + ValueReceived: msg.ValueReceived.String(), + OldStatus: oldStatus, + NewStatus: newStatus, }) if err != nil { ctx.Logger().Error("Error emitting MsgVoteOnObservedOutboundTx :", err) @@ -75,11 +75,11 @@ func EmitOutboundSuccess(ctx sdk.Context, msg *types.MsgVoteOnObservedOutboundTx func EmitOutboundFailure(ctx sdk.Context, msg *types.MsgVoteOnObservedOutboundTx, oldStatus string, newStatus string, cctx types.CrossChainTx) { err := ctx.EventManager().EmitTypedEvents(&types.EventOutboundFailure{ - MsgTypeUrl: sdk.MsgTypeURL(&types.MsgVoteOnObservedOutboundTx{}), - CctxIndex: cctx.Index, - ZetaMinted: msg.ZetaMinted.String(), - OldStatus: oldStatus, - NewStatus: newStatus, + MsgTypeUrl: sdk.MsgTypeURL(&types.MsgVoteOnObservedOutboundTx{}), + CctxIndex: cctx.Index, + ValueReceived: msg.ValueReceived.String(), + OldStatus: oldStatus, + NewStatus: newStatus, }) if err != nil { ctx.Logger().Error("Error emitting MsgVoteOnObservedOutboundTx :", err) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 260df6dc3a..a9779766d8 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -4,10 +4,12 @@ import ( "bytes" "encoding/hex" "fmt" + "math/big" "strings" errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" + "github.com/btcsuite/btcutil" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -79,9 +81,6 @@ func (k Keeper) PostTxProcessing( // from registered ZRC20 contract, new CCTX will be created to trigger and track outbound // transaction. func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContract ethcommon.Address, txOrigin string) error { - if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { - return types.ErrNotEnoughPermissions - } system, found := k.fungibleKeeper.GetSystemContract(ctx) if !found { return fmt.Errorf("cannot find system contract") @@ -111,6 +110,9 @@ func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContr // ProcessZRC20WithdrawalEvent creates a new CCTX to process the withdrawal event // error indicates system error and non-recoverable; should abort func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20Withdrawal, emittingContract ethcommon.Address, txOrigin string) error { + if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { + return types.ErrNotEnoughPermissions + } ctx.Logger().Info("ZRC20 withdrawal to %s amount %d\n", hex.EncodeToString(event.To), event.Value) tss, found := k.GetTSS(ctx) if !found { @@ -162,6 +164,9 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W } func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaConnectorZEVMZetaSent, emittingContract ethcommon.Address, txOrigin string) error { + if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { + return types.ErrNotEnoughPermissions + } ctx.Logger().Info(fmt.Sprintf( "Zeta withdrawal to %s amount %d to chain with chainId %d", hex.EncodeToString(event.DestinationAddress), @@ -219,8 +224,13 @@ func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaC // Create the CCTX cctx := k.CreateNewCCTX(ctx, msg, sendHash, tss.TssPubkey, types.CctxStatus_PendingOutbound, &senderChain, receiverChain) - // Pay gas in Zeta and update the amount for the cctx - if err := k.PayGasInZetaAndUpdateCctx(ctx, receiverChain.ChainId, &cctx, true); err != nil { + if err := k.PayGasAndUpdateCctx( + ctx, + receiverChain.ChainId, + &cctx, + amount, + true, + ); err != nil { return fmt.Errorf("ProcessWithdrawalEvent: pay gas failed: %s", err.Error()) } @@ -256,10 +266,28 @@ func (k Keeper) ParseZRC20WithdrawalEvent(ctx sdk.Context, log ethtypes.Log) (*z return nil, err } - _, found := k.fungibleKeeper.GetForeignCoins(ctx, event.Raw.Address.Hex()) + coin, found := k.fungibleKeeper.GetForeignCoins(ctx, event.Raw.Address.Hex()) if !found { return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: cannot find foreign coin with contract address %s", event.Raw.Address.Hex()) } + chainID := coin.ForeignChainId + if common.IsBitcoinChain(chainID) { + if event.Value.Cmp(big.NewInt(0)) <= 0 { + return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String()) + } + btcChainParams, err := common.GetBTCChainParams(chainID) + if err != nil { + return nil, err + } + addr, err := btcutil.DecodeAddress(string(event.To), btcChainParams) + if err != nil { + return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid address %s: %s", event.To, err) + } + _, ok := addr.(*btcutil.AddressWitnessPubKeyHash) + if !ok { + return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid address %s (not P2WPKH address)", event.To) + } + } return event, nil } diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go new file mode 100644 index 0000000000..9cd5e0f916 --- /dev/null +++ b/x/crosschain/keeper/gas_payment.go @@ -0,0 +1,352 @@ +package keeper + +import ( + "errors" + "fmt" + "math/big" + + cosmoserrors "cosmossdk.io/errors" + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// PayGasAndUpdateCctx updates the outbound tx with the new amount after paying the gas fee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, + noEthereumTxEvent bool, +) error { + // Dispatch to the correct function based on the coin type + switch cctx.InboundTxParams.CoinType { + case common.CoinType_Zeta: + return k.PayGasInZetaAndUpdateCctx(ctx, chainID, cctx, inputAmount, noEthereumTxEvent) + case common.CoinType_Gas: + return k.PayGasNativeAndUpdateCctx(ctx, chainID, cctx, inputAmount) + case common.CoinType_ERC20: + return k.PayGasInERC20AndUpdateCctx(ctx, chainID, cctx, inputAmount, noEthereumTxEvent) + default: + // can't pay gas with coin type + return fmt.Errorf("can't pay gas with coin type %s", cctx.InboundTxParams.CoinType.String()) + } +} + +// ChainGasParams returns the params to calculates the fees for gas for a chain +// tha gas address, the gas limit, gas price and protocol flat fee are returned +func (k Keeper) ChainGasParams( + ctx sdk.Context, + chainID int64, +) (gasZRC20 ethcommon.Address, gasLimit, gasPrice, protocolFee math.Uint, err error) { + gasZRC20, err = k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + + // get the gas limit + gasLimitQueried, err := k.fungibleKeeper.QueryGasLimit(ctx, gasZRC20) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + if gasLimitQueried == nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, errors.New("gas limit is nil") + } + gasLimit = math.NewUintFromBigInt(gasLimitQueried) + + // get the protocol flat fee + protocolFlatFeeQueried, err := k.fungibleKeeper.QueryProtocolFlatFee(ctx, gasZRC20) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + if protocolFlatFeeQueried == nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, errors.New("protocol flat fee is nil") + } + protocolFee = math.NewUintFromBigInt(protocolFlatFeeQueried) + + // get the gas price + gasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chainID) + if !isFound { + return gasZRC20, gasLimit, gasPrice, protocolFee, types.ErrUnableToGetGasPrice + } + + return +} + +// PayGasNativeAndUpdateCctx updates the outbound tx with the new amount subtracting the gas fee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasNativeAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_Gas { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in native gas with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + // get gas params + _, gasLimit, gasPrice, protocolFlatFee, err := k.ChainGasParams(ctx, chainID) + if err != nil { + return cosmoserrors.Wrap(types.ErrCannotFindGasParams, err.Error()) + } + + // calculate the final gas fee + outTxGasFee := gasLimit.Mul(gasPrice).Add(protocolFlatFee) + + // subtract the withdraw fee from the input amount + if outTxGasFee.GT(inputAmount) { + return cosmoserrors.Wrap(types.ErrNotEnoughGas, fmt.Sprintf("outTxGasFee(%s) more than available gas for tx (%s) | Identifiers : %s ", + outTxGasFee, + inputAmount, + cctx.LogIdentifierForCCTX()), + ) + } + ctx.Logger().Info("Subtracting amount from inbound tx", "amount", inputAmount.String(), "fee", outTxGasFee.String()) + newAmount := inputAmount.Sub(outTxGasFee) + + // update cctx + cctx.GetCurrentOutTxParam().Amount = newAmount + cctx.GetCurrentOutTxParam().OutboundTxGasLimit = gasLimit.Uint64() + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + + return nil +} + +// PayGasInERC20AndUpdateCctx updates parameter cctx amount subtracting the gas fee +// the gas fee in ERC20 is calculated by swapping ERC20 -> Zeta -> Gas +// if the route is not available, the gas payment will fail +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasInERC20AndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, + noEthereumTxEvent bool, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_ERC20 { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in erc20 with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + // get gas params + gasZRC20, gasLimit, gasPrice, protocolFlatFee, err := k.ChainGasParams(ctx, chainID) + if err != nil { + return cosmoserrors.Wrap(types.ErrCannotFindGasParams, err.Error()) + } + outTxGasFee := gasLimit.Mul(gasPrice).Add(protocolFlatFee) + + // get address of the zrc20 + fc, found := k.fungibleKeeper.GetForeignCoinFromAsset(ctx, cctx.InboundTxParams.Asset, chainID) + if !found { + return cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "zrc20 from asset %s not found", cctx.InboundTxParams.Asset) + } + zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "zrc20 from asset %s invalid address", cctx.InboundTxParams.Asset) + } + + // get the necessary ERC20 amount for gas + feeInZRC20, err := k.fungibleKeeper.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, outTxGasFee.BigInt(), zrc20, gasZRC20) + if err != nil { + // NOTE: this is the first method that fails when a liquidity pool is not set for the gas ZRC20, so we return a specific error + return cosmoserrors.Wrap(types.ErrNoLiquidityPool, err.Error()) + } + + // subtract the withdraw fee from the input amount + if math.NewUintFromBigInt(feeInZRC20).GT(inputAmount) { + return cosmoserrors.Wrap(types.ErrNotEnoughGas, fmt.Sprintf("feeInZRC20(%s) more than available gas for tx (%s) | Identifiers : %s ", + feeInZRC20, + inputAmount, + cctx.LogIdentifierForCCTX()), + ) + } + newAmount := inputAmount.Sub(math.NewUintFromBigInt(feeInZRC20)) + + // mint the amount of ERC20 to be burnt as gas fee + _, err = k.fungibleKeeper.DepositZRC20(ctx, zrc20, types.ModuleAddressEVM, feeInZRC20) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("Minted ERC20 for gas fee", + "zrc20", zrc20.Hex(), + "amount", feeInZRC20, + ) + + // approve the uniswapv2 router to spend the ERC20 + routerAddress, err := k.fungibleKeeper.GetUniswapV2Router02Address(ctx) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + err = k.fungibleKeeper.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20, + routerAddress, + feeInZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + + // swap the fee in ERC20 into gas passing through Zeta and burn the gas ZRC20 + amounts, err := k.fungibleKeeper.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + feeInZRC20, + zrc20, + gasZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("CallUniswapV2RouterSwapExactTokensForTokens", + "zrc20AmountIn", amounts[0], + "gasAmountOut", amounts[2], + ) + gasObtained := amounts[2] + + // check if the final gas received after swap matches the gas fee defined + // if not there might be issues with the pool liquidity and it is safer from an accounting perspective to return an error + if gasObtained.Cmp(outTxGasFee.BigInt()) != 0 { + return cosmoserrors.Wrapf(types.ErrInvalidGasAmount, "gas obtained for burn (%s) not equal to gas fee(%s)", gasObtained, outTxGasFee) + } + + // burn the gas ZRC20 + err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, gasObtained, noEthereumTxEvent) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("Burning gas ZRC20", + "zrc20", gasZRC20.Hex(), + "amount", gasObtained, + ) + + // update cctx + cctx.GetCurrentOutTxParam().Amount = newAmount + cctx.GetCurrentOutTxParam().OutboundTxGasLimit = gasLimit.Uint64() + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + + return nil +} + +// PayGasInZetaAndUpdateCctx updates parameter cctx with the gas price and gas fee for the outbound tx; +// it also makes a trade to fulfill the outbound tx gas fee in ZETA by swapping ZETA for some gas ZRC20 balances +// The gas ZRC20 balance is subsequently burned to account for the expense of TSS address gas fee payment in the outbound tx. +// zetaBurnt represents the amount of Zeta that has been burnt for the tx, the final amount for the tx is zetaBurnt - gasFee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasInZetaAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + zetaBurnt math.Uint, + noEthereumTxEvent bool, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_Zeta { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in zeta with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + gasZRC20, err := k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to get system contract gas coin") + } + + // get the gas price + gasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chainID) + if !isFound { + return cosmoserrors.Wrap(types.ErrUnableToGetGasPrice, fmt.Sprintf(" chain %d | Identifiers : %s ", + chainID, + cctx.LogIdentifierForCCTX()), + ) + } + gasPrice = gasPrice.MulUint64(2) // overpays gas price by 2x + + // get the gas fee in gas token + gasLimit := sdk.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + outTxGasFee := gasLimit.Mul(gasPrice) + + // get the gas fee in Zeta using system uniswapv2 pool wzeta/gasZRC20 and adding the protocol fee + outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, outTxGasFee.BigInt(), gasZRC20) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to QueryUniswapv2RouterGetAmountsIn") + } + feeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(outTxGasFeeInZeta)) + + // reduce the amount of the outbound tx + if feeInZeta.GT(zetaBurnt) { + return cosmoserrors.Wrap(types.ErrNotEnoughZetaBurnt, fmt.Sprintf("feeInZeta(%s) more than zetaBurnt (%s) | Identifiers : %s ", + feeInZeta, + zetaBurnt, + cctx.LogIdentifierForCCTX()), + ) + } + ctx.Logger().Info("Subtracting amount from inbound tx", + "amount", zetaBurnt.String(), + "feeInZeta", feeInZeta.String(), + ) + newAmount := zetaBurnt.Sub(feeInZeta) + + // ** The following logic converts the outTxGasFeeInZeta into gasZRC20 and burns it ** + // swap the outTxGasFeeInZeta portion of zeta to the real gas ZRC20 and burn it, in a temporary context. + { + coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(feeInZeta.BigInt()))) + err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to mint coins") + } + + amounts, err := k.fungibleKeeper.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + outTxGasFeeInZeta, + gasZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallUniswapv2RouterSwapExactETHForToken") + } + + ctx.Logger().Info("gas fee", "outTxGasFee", outTxGasFee, "outTxGasFeeInZeta", outTxGasFeeInZeta) + ctx.Logger().Info("CallUniswapv2RouterSwapExactETHForToken", + "zetaAmountIn", amounts[0], + "zrc20AmountOut", amounts[1], + ) + err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, amounts[1], noEthereumTxEvent) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallZRC20Burn") + } + } + + // Update the cctx + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + cctx.GetCurrentOutTxParam().Amount = newAmount + if cctx.ZetaFees.IsNil() { + cctx.ZetaFees = feeInZeta + } else { + cctx.ZetaFees = cctx.ZetaFees.Add(feeInZeta) + } + + return nil +} diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go new file mode 100644 index 0000000000..a9c385c7d8 --- /dev/null +++ b/x/crosschain/keeper/gas_payment_test.go @@ -0,0 +1,802 @@ +package keeper_test + +import ( + "math/big" + "testing" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/common" + evmkeeper "github.com/evmos/ethermint/x/evm/keeper" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + zetacommon "github.com/zeta-chain/zetacore/common" + testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// get a valid chain id independently of the build flag +func getValidEthChainID(t *testing.T) int64 { + list := zetacommon.DefaultChainsList() + require.True(t, len(list) > 1) + require.NotNil(t, list[1]) + require.False(t, zetacommon.IsBitcoinChain(list[1].ChainId)) + + return list[1].ChainId +} + +// assert that a contract has been deployed by checking stored code is non-empty. +func assertContractDeployment(t *testing.T, k *evmkeeper.Keeper, ctx sdk.Context, contractAddress common.Address) { + acc := k.GetAccount(ctx, contractAddress) + require.NotNil(t, acc) + + code := k.GetCode(ctx, common.BytesToHash(acc.CodeHash)) + require.NotEmpty(t, code) +} + +// deploySystemContracts deploys the system contracts and returns their addresses. +func deploySystemContracts( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, +) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { + var err error + + wzeta, err = k.DeployWZETA(ctx) + require.NoError(t, err) + require.NotEmpty(t, wzeta) + assertContractDeployment(t, evmk, ctx, wzeta) + + uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Factory) + assertContractDeployment(t, evmk, ctx, uniswapV2Factory) + + uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Router) + assertContractDeployment(t, evmk, ctx, uniswapV2Router) + + connector, err = k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, connector) + assertContractDeployment(t, evmk, ctx, connector) + + systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) + require.NoError(t, err) + require.NotEmpty(t, systemContract) + assertContractDeployment(t, evmk, ctx, systemContract) + + return +} + +// setupGasCoin is a helper function to setup the gas coin for testing +func setupGasCoin( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.SetupChainGasCoinAndPool( + ctx, + chainID, + assetName, + symbol, + 8, + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// deployZRC20 deploys a ZRC20 contract and returns its address +func deployZRC20( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + assetAddress string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.DeployZRC20Contract( + ctx, + assetName, + symbol, + 8, + chainID, + 0, + assetAddress, + big.NewInt(21_000), + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// setupZRC20Pool setup a Uniswap pool with liquidity for the pair zeta/asset +func setupZRC20Pool( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + bankKeeper bankkeeper.Keeper, + zrc20Addr common.Address, +) { + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + require.NoError(t, err) + + // enough for the small numbers used in test + liquidityAmount := big.NewInt(1e17) + + // mint some zrc20 and zeta + _, err = k.DepositZRC20(ctx, zrc20Addr, types.ModuleAddressEVM, liquidityAmount) + require.NoError(t, err) + err = bankKeeper.MintCoins( + ctx, + types.ModuleName, + sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(liquidityAmount))), + ) + require.NoError(t, err) + + // approve the router to spend the zeta + err = k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20Addr, + routerAddress, + liquidityAmount, + false, + ) + require.NoError(t, err) + + // add the liquidity + //function addLiquidityETH( + // address token, + // uint amountTokenDesired, + // uint amountTokenMin, + // uint amountETHMin, + // address to, + // uint deadline + //) + _, err = k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + liquidityAmount, + big.NewInt(5_000_000), + true, + false, + "addLiquidityETH", + zrc20Addr, + liquidityAmount, + fungiblekeeper.BigIntZero, + fungiblekeeper.BigIntZero, + types.ModuleAddressEVM, + liquidityAmount, + ) + require.NoError(t, err) +} + +func setAdminDeployFungibleCoin(ctx sdk.Context, zk testkeeper.ZetaKeepers, admin string) { + params := zk.ObserverKeeper.GetParams(ctx) + params.AdminPolicy = []*observertypes.Admin_Policy{ + { + PolicyType: observertypes.Policy_Type_deploy_fungible_coin, + Address: admin, + }, + } + zk.ObserverKeeper.SetParams(ctx, params) +} + +var ( + // gasLimit = big.NewInt(21_000) - value used in SetupChainGasCoinAndPool for gas limit initialization + withdrawFee uint64 = 1000 + gasPrice uint64 = 2 + inputAmount uint64 = 100000 +) + +func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { + t.Run("can pay gas in native gas", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, zrc20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees must be 21000*2+1000=43000 + // if the input amount of the cctx is 100000, the output amount must be 100000-43000=57000 + err = k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.NoError(t, err) + require.Equal(t, uint64(57000), cctx.GetCurrentOutTxParam().Amount.Uint64()) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + require.Equal(t, "2", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + }) + + t.Run("should fail if not coin type gas", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + } + err := k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasNativeAndUpdateCctx(ctx, 999999, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err := k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, types.ErrCannotFindGasParams) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, zrc20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // 42999 < 43000 + err = k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(42999)) + require.ErrorIs(t, err, types.ErrNotEnoughGas) + }) +} + +func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { + t.Run("can pay gas in erc20", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + setupZRC20Pool( + t, + ctx, + zk.FungibleKeeper, + sdkk.BankKeeper, + zrc20Addr, + ) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees in gas must be 21000*2+1000=43000 + // we calculate what it represents in erc20 + expectedInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(43000), gasZRC20) + require.NoError(t, err) + expectedInZRC20, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, expectedInZeta, zrc20Addr) + require.NoError(t, err) + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.NoError(t, err) + require.Equal(t, inputAmount-expectedInZRC20.Uint64(), cctx.GetCurrentOutTxParam().Amount.Uint64()) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + require.Equal(t, "2", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + }) + + t.Run("should fail if not coin type erc20", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + }, + } + err := k.PayGasInERC20AndUpdateCctx(ctx, 999999, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err := k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrCannotFindGasParams) + }) + + t.Run("should fail if can't find the ZRC20", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // zrc20 not deployed + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrForeignCoinNotFound) + }) + + t.Run("should fail if liquidity pool not setup", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // liquidity pool not set + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrNoLiquidityPool) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + setupZRC20Pool( + t, + ctx, + zk.FungibleKeeper, + sdkk.BankKeeper, + zrc20Addr, + ) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees in gas must be 21000*2+1000=43000 + // we calculate what it represents in erc20 + expectedInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(43000), gasZRC20) + require.NoError(t, err) + expectedInZRC20, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, expectedInZeta, zrc20Addr) + require.NoError(t, err) + + // Provide expected value minus 1 + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUintFromBigInt(expectedInZRC20).SubUint64(1), false) + require.ErrorIs(t, err, types.ErrNotEnoughGas) + }) +} + +func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { + t.Run("can pay gas in zeta", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + ZetaFees: math.NewUint(100), + } + // gasLimit * gasPrice * 2 = 1000 * 2 * 2 = 4000 + expectedOutTxGasFeeInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + + // the output amount must be input amount - (out tx fee in zeta + protocol flat fee) + expectedFeeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + inputAmount := expectedFeeInZeta.Add(math.NewUint(100000)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.NoError(t, err) + require.Equal(t, "100000", cctx.GetCurrentOutTxParam().Amount.String()) + require.Equal(t, "4", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) // gas price is doubled + require.True(t, cctx.ZetaFees.Equal(expectedFeeInZeta.Add(math.NewUint(100))), "expected %s, got %s", expectedFeeInZeta.String(), cctx.ZetaFees.String()) + + // can call with undefined zeta fees + cctx = types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + } + expectedOutTxGasFeeInZeta, err = zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + expectedFeeInZeta = types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + inputAmount = expectedFeeInZeta.Add(math.NewUint(100000)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.NoError(t, err) + require.Equal(t, "100000", cctx.GetCurrentOutTxParam().Amount.String()) + require.Equal(t, "4", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) // gas price is doubled + require.True(t, cctx.ZetaFees.Equal(expectedFeeInZeta), "expected %s, got %s", expectedFeeInZeta.String(), cctx.ZetaFees.String()) + }) + + t.Run("should fail if pay gas in zeta with coin type other than zeta", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + } + err := k.PayGasInZetaAndUpdateCctx(ctx, 999999, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // gas price not set + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + } + + err := k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, types.ErrUnableToGetGasPrice) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + ZetaFees: math.NewUint(100), + } + expectedOutTxGasFeeInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + expectedFeeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + + // set input amount lower than total zeta fee + inputAmount := expectedFeeInZeta.Sub(math.NewUint(1)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.ErrorIs(t, err, types.ErrNotEnoughZetaBurnt) + }) +} diff --git a/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go b/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go index 0bcce1517b..5704fdc54a 100644 --- a/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go @@ -20,7 +20,7 @@ import ( ) func TestInTxHashToCctxQuerySingle(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) msgs := createNInTxHashToCctx(keeper, ctx, 2) for _, tc := range []struct { @@ -71,7 +71,7 @@ func TestInTxHashToCctxQuerySingle(t *testing.T) { } func TestInTxHashToCctxQueryPaginated(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) msgs := createNInTxHashToCctx(keeper, ctx, 5) @@ -148,7 +148,7 @@ func createInTxHashToCctxWithCctxs(keeper *crosschainkeeper.Keeper, ctx sdk.Cont } func TestKeeper_InTxHashToCctxDataQuery(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) t.Run("can query all cctxs data with in tx hash", func(t *testing.T) { diff --git a/x/crosschain/keeper/in_tx_hash_to_cctx_test.go b/x/crosschain/keeper/in_tx_hash_to_cctx_test.go index 550b3395e1..6eb0118cf9 100644 --- a/x/crosschain/keeper/in_tx_hash_to_cctx_test.go +++ b/x/crosschain/keeper/in_tx_hash_to_cctx_test.go @@ -24,7 +24,7 @@ func createNInTxHashToCctx(keeper *keeper.Keeper, ctx sdk.Context, n int) []type } func TestInTxHashToCctxGet(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) for _, item := range items { rst, found := keeper.GetInTxHashToCctx(ctx, @@ -38,7 +38,7 @@ func TestInTxHashToCctxGet(t *testing.T) { } } func TestInTxHashToCctxRemove(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) for _, item := range items { keeper.RemoveInTxHashToCctx(ctx, @@ -52,7 +52,7 @@ func TestInTxHashToCctxRemove(t *testing.T) { } func TestInTxHashToCctxGetAll(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) require.ElementsMatch(t, nullify.Fill(items), diff --git a/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go b/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go index fac94ec7f4..01c8e5d822 100644 --- a/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go +++ b/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go @@ -14,7 +14,7 @@ import ( // FIXME: use more specific error types & codes -// Casts a vote on an inbound transaction observed on a connected chain. If this +// VoteOnObservedInboundTx casts a vote on an inbound transaction observed on a connected chain. If this // is the first vote, a new ballot is created. When a threshold of votes is // reached, the ballot is finalized. When a ballot is finalized, a new CCTX is // created. @@ -57,6 +57,7 @@ import ( // Only observer validators are authorized to broadcast this message. func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.MsgVoteOnObservedInboundTx) (*types.MsgVoteOnObservedInboundTxResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + observationType := observerTypes.ObservationType_InBoundTx if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { return nil, types.ErrNotEnoughPermissions @@ -104,12 +105,14 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg } // Validation if we want to send ZETA to external chain, but there is no ZETA token. - coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, receiverChain.ChainId) - if !found { - return nil, types.ErrNotFoundCoreParams - } - if receiverChain.IsExternalChain() && coreParams.ZetaTokenContractAddress == "" && msg.CoinType == common.CoinType_Zeta { - return nil, types.ErrUnableToSendCoinType + if receiverChain.IsExternalChain() { + coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, receiverChain.ChainId) + if !found { + return nil, types.ErrNotFoundCoreParams + } + if coreParams.ZetaTokenContractAddress == "" && msg.CoinType == common.CoinType_Zeta { + return nil, types.ErrUnableToSendCoinType + } } // ****************************************************************************** @@ -128,6 +131,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg if receiverChain.IsZetaChain() { tmpCtx, commit := ctx.CacheContext() isContractReverted, err := k.HandleEVMDeposit(tmpCtx, &cctx, *msg, observationChain) + if err != nil && !isContractReverted { // exceptional case; internal error; should abort CCTX cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()) return &types.MsgVoteOnObservedInboundTxResponse{}, nil @@ -138,27 +142,60 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, "invalid sender chain") return &types.MsgVoteOnObservedInboundTxResponse{}, nil } - medianGasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chain.ChainId) - if !isFound { - cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, "cannot find gas price") - return &types.MsgVoteOnObservedInboundTxResponse{}, nil - } // create new OutboundTxParams for the revert cctx.OutboundTxParams = append(cctx.OutboundTxParams, &types.OutboundTxParams{ - Receiver: cctx.InboundTxParams.Sender, - ReceiverChainId: cctx.InboundTxParams.SenderChainId, - Amount: cctx.InboundTxParams.Amount, - CoinType: cctx.InboundTxParams.CoinType, - OutboundTxGasLimit: 0, // for fungible refund, use default gasLimit - OutboundTxGasPrice: medianGasPrice.MulUint64(2).String(), + Receiver: cctx.InboundTxParams.Sender, + ReceiverChainId: cctx.InboundTxParams.SenderChainId, + Amount: cctx.InboundTxParams.Amount, + CoinType: cctx.InboundTxParams.CoinType, + // use same gas limit as outbound + //TODO: determine a specific revert gas limit https://github.com/zeta-chain/node/issues/1065 + OutboundTxGasLimit: msg.GasLimit, }) - if err = k.UpdateNonce(ctx, chain.ChainId, &cctx); err != nil { + + // we create a new cached context, and we don't commit the previous one with EVM deposit + tmpCtx, commit := ctx.CacheContext() + err = func() error { + err := k.PayGasAndUpdateCctx( + tmpCtx, + chain.ChainId, + &cctx, + cctx.InboundTxParams.Amount, + false, + ) + if err != nil { + return err + } + err = k.UpdateNonce(tmpCtx, chain.ChainId, &cctx) + if err != nil { + return err + } + return nil + }() + if err != nil { + // do not commit anything here as the CCTX should be aborted + + // gas payment for erc20 type might fail because no liquidity pool is defined to swap the zrc20 token into the gas token + // in this gas we should refund the sender on ZetaChain + if cctx.InboundTxParams.CoinType == common.CoinType_ERC20 { + + if err := k.RefundAmountOnZetaChain(ctx, cctx, cctx.InboundTxParams.Amount); err != nil { + // log the error + k.Logger(ctx).Error("failed to refund amount of aborted cctx on ZetaChain", + "error", err, + "sender", cctx.InboundTxParams.Sender, + "amount", cctx.InboundTxParams.Amount.String(), + ) + } + } + cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()) return &types.MsgVoteOnObservedInboundTxResponse{}, nil } - // do not commit() here; + commit() cctx.CctxStatus.ChangeStatus(types.CctxStatus_PendingRevert, revertMessage) return &types.MsgVoteOnObservedInboundTxResponse{}, nil + } else { // successful HandleEVMDeposit; commit() cctx.CctxStatus.ChangeStatus(types.CctxStatus_OutboundMined, "Remote omnichain contract call completed") @@ -167,7 +204,13 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg } else { // Cross Chain SWAP tmpCtx, commit := ctx.CacheContext() err = func() error { - err := k.PayGasInZetaAndUpdateCctx(tmpCtx, receiverChain.ChainId, &cctx, false) + err := k.PayGasAndUpdateCctx( + tmpCtx, + receiverChain.ChainId, + &cctx, + cctx.InboundTxParams.Amount, + false, + ) if err != nil { return err } diff --git a/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go b/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go index 42d01988dd..6b8f0b02a9 100644 --- a/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go +++ b/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go @@ -16,7 +16,7 @@ import ( observerTypes "github.com/zeta-chain/zetacore/x/observer/types" ) -// Casts a vote on an outbound transaction observed on a connected chain (after +// VoteOnObservedOutboundTx casts a vote on an outbound transaction observed on a connected chain (after // it has been broadcasted to and finalized on a connected chain). If this is // the first vote, a new ballot is created. When a threshold of votes is // reached, the ballot is finalized. When a ballot is finalized, the outbound @@ -109,11 +109,11 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms return &types.MsgVoteOnObservedOutboundTxResponse{}, nil } if ballot.BallotStatus != observerTypes.BallotStatus_BallotFinalized_FailureObservation { - if !msg.ZetaMinted.Equal(cctx.GetCurrentOutTxParam().Amount) { - log.Error().Msgf("VoteOnObservedOutboundTx: Mint mismatch: %s zeta minted vs %s cctx amount", - msg.ZetaMinted, + if !msg.ValueReceived.Equal(cctx.GetCurrentOutTxParam().Amount) { + log.Error().Msgf("VoteOnObservedOutboundTx: Mint mismatch: %s value received vs %s cctx amount", + msg.ValueReceived, cctx.GetCurrentOutTxParam().Amount) - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("ZetaMinted %s does not match send ZetaMint %s", msg.ZetaMinted, cctx.GetCurrentOutTxParam().Amount)) + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("ValueReceived %s does not match sent value %s", msg.ValueReceived, cctx.GetCurrentOutTxParam().Amount)) } } @@ -159,13 +159,21 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms case types.CctxStatus_PendingOutbound: // create new OutboundTxParams for the revert cctx.OutboundTxParams = append(cctx.OutboundTxParams, &types.OutboundTxParams{ - Receiver: cctx.InboundTxParams.Sender, - ReceiverChainId: cctx.InboundTxParams.SenderChainId, - Amount: cctx.InboundTxParams.Amount, - CoinType: cctx.InboundTxParams.CoinType, - OutboundTxGasLimit: cctx.OutboundTxParams[0].OutboundTxGasLimit, // NOTE(pwu): revert gas limit = initial outbound gas limit set by user; + Receiver: cctx.InboundTxParams.Sender, + ReceiverChainId: cctx.InboundTxParams.SenderChainId, + Amount: cctx.InboundTxParams.Amount, + CoinType: cctx.InboundTxParams.CoinType, + // NOTE(pwu): revert gas limit = initial outbound gas limit set by user + //TODO: determine a specific revert gas limit https://github.com/zeta-chain/node/issues/1065 + OutboundTxGasLimit: cctx.OutboundTxParams[0].OutboundTxGasLimit, }) - err := k.PayGasInZetaAndUpdateCctx(tmpCtx, cctx.InboundTxParams.SenderChainId, &cctx, false) + err := k.PayGasAndUpdateCctx( + tmpCtx, + cctx.InboundTxParams.SenderChainId, + &cctx, + cctx.OutboundTxParams[0].Amount, + false, + ) if err != nil { return err } diff --git a/x/crosschain/keeper/keeper_out_tx_tracker.go b/x/crosschain/keeper/keeper_out_tx_tracker.go index 030d12eadb..f0ed81f469 100644 --- a/x/crosschain/keeper/keeper_out_tx_tracker.go +++ b/x/crosschain/keeper/keeper_out_tx_tracker.go @@ -5,12 +5,16 @@ import ( "fmt" "strings" + cosmoserrors "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" + eth "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" - zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -156,27 +160,74 @@ func (k Keeper) OutTxTracker(c context.Context, req *types.QueryGetOutTxTrackerR // Messages -// Adds a new record to the outbound transaction tracker. -// -// Only the admin policy account and the observer validators are authorized to -// broadcast this message. +// AddToOutTxTracker adds a new record to the outbound transaction tracker. +// only the admin policy account and the observer validators are authorized to broadcast this message. func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToOutTxTracker) (*types.MsgAddToOutTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) if chain == nil { - return nil, zetaObserverTypes.ErrSupportedChains + return nil, observertypes.ErrSupportedChains } - adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_out_tx_tracker) - isAdmin := msg.Creator == adminPolicyAccount + if msg.Proof == nil { // without proof, only certain accounts can send this message + adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_out_tx_tracker) + isAdmin := msg.Creator == adminPolicyAccount - isObserver, err := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain) - if err != nil { - ctx.Logger().Error("Error while checking if the account is an observer", err) + isObserver, err := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain) + if err != nil { + ctx.Logger().Error("Error while checking if the account is an observer", err) + return nil, cosmoserrors.Wrap(observertypes.ErrNotAuthorized, fmt.Sprintf("error IsAuthorized %s", msg.Creator)) + } + // Sender needs to be either the admin policy account or an observer + if !(isAdmin || isObserver) { + return nil, cosmoserrors.Wrap(observertypes.ErrNotAuthorized, fmt.Sprintf("Creator %s", msg.Creator)) + } } - // Sender needs to be either the admin policy account or an observer - if !(isAdmin || isObserver) { - return nil, sdkerrors.Wrap(zetaObserverTypes.ErrNotAuthorized, fmt.Sprintf("Creator %s", msg.Creator)) + + proven := false + if msg.Proof != nil { + blockHash := eth.HexToHash(msg.BlockHash) + res, found := k.zetaObserverKeeper.GetBlockHeader(ctx, blockHash.Bytes()) + if !found { + return nil, cosmoserrors.Wrap(observertypes.ErrBlockHeaderNotFound, fmt.Sprintf("block header not found %s", msg.BlockHash)) + } + + // verify and process the proof + val, err := msg.Proof.Verify(res.Header, int(msg.TxIndex)) + if err != nil && !common.IsErrorInvalidProof(err) { + return nil, err + } + if err == nil { + var txx ethtypes.Transaction + err = txx.UnmarshalBinary(val) + if err != nil { + return nil, err + } + signer := ethtypes.NewLondonSigner(txx.ChainId()) + sender, err := ethtypes.Sender(signer, &txx) + if err != nil { + return nil, err + } + res, err := k.GetTssAddress(ctx, &types.QueryGetTssAddressRequest{}) + if err != nil { + return nil, err + } + tssAddr := eth.HexToAddress(res.Eth) + if tssAddr == (eth.Address{}) { + return nil, fmt.Errorf("tss address not found") + } + if sender != tssAddr { + return nil, fmt.Errorf("sender is not tss address") + } + if txx.Nonce() != msg.Nonce { + return nil, fmt.Errorf("nonce mismatch") + } + proven = true + } + + if !proven { + return nil, fmt.Errorf("proof failed") + } } tracker, found := k.GetOutTxTracker(ctx, msg.ChainId, msg.Nonce) @@ -198,23 +249,34 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO for _, hash := range tracker.HashList { if strings.EqualFold(hash.TxHash, msg.TxHash) { isDup = true + if proven { + hash.Proved = true + k.SetOutTxTracker(ctx, tracker) + k.Logger(ctx).Info("Proof'd outbound transaction") + return &types.MsgAddToOutTxTrackerResponse{}, nil + } break } } if !isDup { - tracker.HashList = append(tracker.HashList, &hash) + if proven { + hash.Proved = true + tracker.HashList = append([]*types.TxHashList{&hash}, tracker.HashList...) + k.Logger(ctx).Info("Proof'd outbound transaction") + } else { + tracker.HashList = append(tracker.HashList, &hash) + } k.SetOutTxTracker(ctx, tracker) } return &types.MsgAddToOutTxTrackerResponse{}, nil } -// Removes a record from the outbound transaction tracker by chain ID and nonce. -// -// Only the admin policy account is authorized to broadcast this message. +// RemoveFromOutTxTracker removes a record from the outbound transaction tracker by chain ID and nonce. +// only the admin policy account is authorized to broadcast this message. func (k msgServer) RemoveFromOutTxTracker(goCtx context.Context, msg *types.MsgRemoveFromOutTxTracker) (*types.MsgRemoveFromOutTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_out_tx_tracker) { - return &types.MsgRemoveFromOutTxTrackerResponse{}, zetaObserverTypes.ErrNotAuthorizedPolicy + if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_out_tx_tracker) { + return &types.MsgRemoveFromOutTxTrackerResponse{}, observertypes.ErrNotAuthorizedPolicy } k.RemoveOutTxTracker(ctx, msg.ChainId, msg.Nonce) diff --git a/x/crosschain/keeper/keeper_out_tx_tracker_test.go b/x/crosschain/keeper/keeper_out_tx_tracker_test.go index 16570daad4..d6835b1623 100644 --- a/x/crosschain/keeper/keeper_out_tx_tracker_test.go +++ b/x/crosschain/keeper/keeper_out_tx_tracker_test.go @@ -31,7 +31,7 @@ func createNOutTxTracker(keeper *keeper.Keeper, ctx sdk.Context, n int) []types. } func TestOutTxTrackerGet(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(keeper, ctx, 10) for _, item := range items { rst, found := keeper.GetOutTxTracker(ctx, @@ -46,7 +46,7 @@ func TestOutTxTrackerGet(t *testing.T) { } } func TestOutTxTrackerRemove(t *testing.T) { - k, ctx := keepertest.CrosschainKeeper(t) + k, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(k, ctx, 10) for _, item := range items { k.RemoveOutTxTracker(ctx, @@ -62,7 +62,7 @@ func TestOutTxTrackerRemove(t *testing.T) { } func TestOutTxTrackerGetAll(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(keeper, ctx, 10) require.ElementsMatch(t, nullify.Fill(items), diff --git a/x/crosschain/keeper/keeper_pending_nonces.go b/x/crosschain/keeper/keeper_pending_nonces.go index da1648b104..8808b6ec4b 100644 --- a/x/crosschain/keeper/keeper_pending_nonces.go +++ b/x/crosschain/keeper/keeper_pending_nonces.go @@ -93,3 +93,23 @@ func (k Keeper) PendingNoncesAll(c context.Context, req *types.QueryAllPendingNo PendingNonces: list, }, nil } + +func (k Keeper) PendingNoncesByChain(c context.Context, req *types.QueryPendingNoncesByChainRequest) (*types.QueryPendingNoncesByChainResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + tss, found := k.GetTSS(ctx) + if !found { + return nil, status.Error(codes.NotFound, "tss not found") + } + list, found := k.GetPendingNonces(ctx, tss.TssPubkey, req.ChainId) + if !found { + return nil, status.Error(codes.NotFound, fmt.Sprintf("pending nonces not found for chain id : %d", req.ChainId)) + } + + return &types.QueryPendingNoncesByChainResponse{ + PendingNonces: list, + }, nil +} diff --git a/x/crosschain/keeper/keeper_tss_voter.go b/x/crosschain/keeper/keeper_tss_voter.go index f28904ba66..0dc818d48f 100644 --- a/x/crosschain/keeper/keeper_tss_voter.go +++ b/x/crosschain/keeper/keeper_tss_voter.go @@ -128,3 +128,12 @@ func (k msgServer) UpdateTssAddress(goCtx context.Context, msg *types.MsgUpdateT return &types.MsgUpdateTssAddressResponse{}, nil } + +// IsAuthorizedNodeAccount checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type +func (k Keeper) IsAuthorizedNodeAccount(ctx sdk.Context, address string) bool { + _, found := k.zetaObserverKeeper.GetNodeAccount(ctx, address) + if found { + return true + } + return false +} diff --git a/x/crosschain/keeper/keeper_utils.go b/x/crosschain/keeper/keeper_utils.go deleted file mode 100644 index 77882f6a2b..0000000000 --- a/x/crosschain/keeper/keeper_utils.go +++ /dev/null @@ -1,143 +0,0 @@ -package keeper - -import ( - "fmt" - "math/big" - - "github.com/zeta-chain/zetacore/cmd/zetacored/config" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/zeta-chain/zetacore/x/crosschain/types" - zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" -) - -// IsAuthorizedNodeAccount checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type -func (k Keeper) IsAuthorizedNodeAccount(ctx sdk.Context, address string) bool { - _, found := k.zetaObserverKeeper.GetNodeAccount(ctx, address) - if found { - return true - } - return false -} - -// PayGasInZetaAndUpdateCctx updates parameter cctx with the gas price and gas fee for the outbound tx; -// it also makes a trade to fulfill the outbound tx gas fee in ZETA by swapping ZETA for some gas ZRC20 balances -// The gas ZRC20 balance is subsequently burned to account for the expense of TSS address gas fee payment in the outbound tx. -// **Caller should feed temporary ctx into this function** -func (k Keeper) PayGasInZetaAndUpdateCctx(ctx sdk.Context, chainID int64, cctx *types.CrossChainTx, noEthereumTxEvent bool) error { - // TODO: this check currently break the integration tests, enable it when integration tests are fixed - // https://github.com/zeta-chain/node/issues/1022 - //if cctx.InboundTxParams.CoinType != common.CoinType_Zeta { - // return sdkerrors.Wrapf(zetaObserverTypes.ErrInvalidCoinType, "can't pay gas in zeta with %s", cctx.InboundTxParams.CoinType.String()) - //} - - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID) - if chain == nil { - return zetaObserverTypes.ErrSupportedChains - } - medianGasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chain.ChainId) - if !isFound { - return sdkerrors.Wrap(types.ErrUnableToGetGasPrice, fmt.Sprintf(" chain %d | Identifiers : %s ", - cctx.GetCurrentOutTxParam().ReceiverChainId, - cctx.LogIdentifierForCCTX()), - ) - } - medianGasPrice = medianGasPrice.MulUint64(2) // overpays gas price by 2x - cctx.GetCurrentOutTxParam().OutboundTxGasPrice = medianGasPrice.String() - gasLimit := sdk.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit) - outTxGasFee := gasLimit.Mul(medianGasPrice) - - // the following logic computes outbound tx gas fee, and convert into ZETA using system uniswapv2 pool wzeta/gasZRC20 - gasZRC20, err := k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chain.ChainId)) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to get system contract gas coin") - } - - outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapv2RouterGetAmountsIn(ctx, outTxGasFee.BigInt(), gasZRC20) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to QueryUniswapv2RouterGetAmountsIn") - } - feeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(outTxGasFeeInZeta)) - - cctx.ZetaFees = cctx.ZetaFees.Add(feeInZeta) - - if cctx.ZetaFees.GT(cctx.InboundTxParams.Amount) { - return sdkerrors.Wrap(types.ErrNotEnoughZetaBurnt, fmt.Sprintf("feeInZeta(%s) more than zetaBurnt (%s) | Identifiers : %s ", - cctx.ZetaFees, - cctx.InboundTxParams.Amount, - cctx.LogIdentifierForCCTX()), - ) - } - - ctx.Logger().Info("Subtracting amount from inbound tx", "amount", cctx.InboundTxParams.Amount.String(), "feeInZeta", - cctx.ZetaFees.String()) - cctx.GetCurrentOutTxParam().Amount = cctx.InboundTxParams.Amount.Sub(cctx.ZetaFees) - - // ** The following logic converts the outTxGasFeeInZeta into gasZRC20 and burns it ** - // swap the outTxGasFeeInZeta portion of zeta to the real gas ZRC20 and burn it, in a temporary context. - { - coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(feeInZeta.BigInt()))) - err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to mint coins") - } - - amounts, err := k.fungibleKeeper.CallUniswapv2RouterSwapExactETHForToken( - ctx, - types.ModuleAddressEVM, - types.ModuleAddressEVM, - outTxGasFeeInZeta, - gasZRC20, - noEthereumTxEvent, - ) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallUniswapv2RouterSwapExactETHForToken") - } - ctx.Logger().Info("gas fee", "outTxGasFee", outTxGasFee, "outTxGasFeeInZeta", outTxGasFeeInZeta) - ctx.Logger().Info("CallUniswapv2RouterSwapExactETHForToken", "zetaAmountIn", amounts[0], "zrc20AmountOut", amounts[1]) - err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, amounts[1], noEthereumTxEvent) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallZRC20Burn") - } - } - - return nil -} - -// UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. -// It also updates the PendingNonces that is used to track the unfulfilled outbound txs. -func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiveChainID) - if chain == nil { - return zetaObserverTypes.ErrSupportedChains - } - - nonce, found := k.GetChainNonces(ctx, chain.ChainName.String()) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindReceiverNonce, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) - } - - // SET nonce - cctx.GetCurrentOutTxParam().OutboundTxTssNonce = nonce.Nonce - tss, found := k.GetTSS(ctx) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindTSSKeys, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) - } - - p, found := k.GetPendingNonces(ctx, tss.TssPubkey, uint64(receiveChainID)) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindPendingNonces, fmt.Sprintf("chain_id %d, nonce %d", receiveChainID, nonce.Nonce)) - } - - if p.NonceHigh != int64(nonce.Nonce) { - return sdkerrors.Wrap(types.ErrNonceMismatch, fmt.Sprintf("chain_id %d, high nonce %d, current nonce %d", receiveChainID, p.NonceHigh, nonce.Nonce)) - } - - nonce.Nonce++ - p.NonceHigh++ - k.SetChainNonces(ctx, nonce) - k.SetPendingNonces(ctx, p) - return nil -} diff --git a/x/crosschain/keeper/zeta_conversion_rate.go b/x/crosschain/keeper/zeta_conversion_rate.go index b1c0e4df61..abb43e02ec 100644 --- a/x/crosschain/keeper/zeta_conversion_rate.go +++ b/x/crosschain/keeper/zeta_conversion_rate.go @@ -30,7 +30,7 @@ func (k Keeper) ConvertGasToZeta(context context.Context, request *types.QueryCo if err != nil { return nil, status.Error(codes.NotFound, "zrc20 not found") } - outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapv2RouterGetAmountsIn(ctx, outTxGasFee.BigInt(), zrc20) + outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, outTxGasFee.BigInt(), zrc20) if err != nil { return nil, status.Error(codes.Internal, "zQueryUniswapv2RouterGetAmountsIn failed") } diff --git a/x/crosschain/module.go b/x/crosschain/module.go index 314af4cc07..4be40efde9 100644 --- a/x/crosschain/module.go +++ b/x/crosschain/module.go @@ -107,16 +107,20 @@ type AppModule struct { keeper keeper.Keeper stakingKeeper types.StakingKeeper + authKeeper types.AccountKeeper } func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - stakingKeeper types.StakingKeeper) AppModule { + stakingKeeper types.StakingKeeper, + authKeeper types.AccountKeeper, +) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), keeper: keeper, stakingKeeper: stakingKeeper, + authKeeper: authKeeper, } } @@ -164,6 +168,9 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.Ra InitGenesis(ctx, am.keeper, genState) + // ensure account is created + am.authKeeper.GetModuleAccount(ctx, types.ModuleName) + return []abci.ValidatorUpdate{} } diff --git a/x/crosschain/types/cctx_utils.go b/x/crosschain/types/cctx_utils.go index ba2afd7918..d6807b63b1 100644 --- a/x/crosschain/types/cctx_utils.go +++ b/x/crosschain/types/cctx_utils.go @@ -5,16 +5,32 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) +// GetCurrentOutTxParam returns the current outbound tx params. // There can only be one active outtx. // OutboundTxParams[0] is the original outtx, if it reverts, then // OutboundTxParams[1] is the new outtx. -func (m *CrossChainTx) GetCurrentOutTxParam() *OutboundTxParams { +func (m CrossChainTx) GetCurrentOutTxParam() *OutboundTxParams { if len(m.OutboundTxParams) == 0 { return &OutboundTxParams{} } return m.OutboundTxParams[len(m.OutboundTxParams)-1] } +// IsCurrentOutTxRevert returns true if the current outbound tx is the revert tx. +func (m CrossChainTx) IsCurrentOutTxRevert() bool { + return len(m.OutboundTxParams) == 2 +} + +// OriginalDestinationChainID returns the original destination of the outbound tx, reverted or not +// If there is no outbound tx, return -1 +func (m CrossChainTx) OriginalDestinationChainID() int64 { + if len(m.OutboundTxParams) == 0 { + return -1 + } + return m.OutboundTxParams[0].ReceiverChainId +} + +// GetAllAuthzZetaclientTxTypes returns all the authz types for zetaclient func GetAllAuthzZetaclientTxTypes() []string { return []string{ sdk.MsgTypeURL(&MsgNonceVoter{}), @@ -26,5 +42,6 @@ func GetAllAuthzZetaclientTxTypes() []string { sdk.MsgTypeURL(&MsgAddToOutTxTracker{}), sdk.MsgTypeURL(&MsgSetNodeKeys{}), sdk.MsgTypeURL(&types.MsgAddBlameVote{}), + sdk.MsgTypeURL(&types.MsgAddBlockHeader{}), } } diff --git a/x/crosschain/types/cctx_utils_test.go b/x/crosschain/types/cctx_utils_test.go new file mode 100644 index 0000000000..4fec09f3b6 --- /dev/null +++ b/x/crosschain/types/cctx_utils_test.go @@ -0,0 +1,52 @@ +package types_test + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestCrossChainTx_GetCurrentOutTxParam(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.Equal(t, &types.OutboundTxParams{}, cctx.GetCurrentOutTxParam()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0], cctx.GetCurrentOutTxParam()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[1], cctx.GetCurrentOutTxParam()) +} + +func TestCrossChainTx_IsCurrentOutTxRevert(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.False(t, cctx.IsCurrentOutTxRevert()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.False(t, cctx.IsCurrentOutTxRevert()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.True(t, cctx.IsCurrentOutTxRevert()) +} + +func TestCrossChainTx_OriginalDestinationChainID(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.Equal(t, int64(-1), cctx.OriginalDestinationChainID()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0].ReceiverChainId, cctx.OriginalDestinationChainID()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0].ReceiverChainId, cctx.OriginalDestinationChainID()) +} diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index aa78a52a87..b8191ef9fa 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -5,29 +5,37 @@ import ( ) var ( - ErrUnsupportedChain = errorsmod.Register(ModuleName, 1102, "chain parse error") - ErrInvalidChainID = errorsmod.Register(ModuleName, 1101, "chain id cannot be negative") - ErrInvalidPubKeySet = errorsmod.Register(ModuleName, 1106, "invalid pubkeyset") - ErrUnableToGetGasPrice = errorsmod.Register(ModuleName, 1107, "unable to get gas price") - ErrNotEnoughZetaBurnt = errorsmod.Register(ModuleName, 1109, "not enough zeta burnt") - ErrCannotFindReceiverNonce = errorsmod.Register(ModuleName, 1110, "cannot find receiver chain nonce") - ErrCannotFindPendingTxQueue = errorsmod.Register(ModuleName, 1111, "cannot find pending tx queue") + ErrUnsupportedChain = errorsmod.Register(ModuleName, 1102, "chain parse error") + ErrInvalidChainID = errorsmod.Register(ModuleName, 1101, "chain id cannot be negative") + ErrInvalidPubKeySet = errorsmod.Register(ModuleName, 1106, "invalid pubkeyset") + ErrUnableToGetGasPrice = errorsmod.Register(ModuleName, 1107, "unable to get gas price") + ErrNotEnoughZetaBurnt = errorsmod.Register(ModuleName, 1109, "not enough zeta burnt") + ErrCannotFindReceiverNonce = errorsmod.Register(ModuleName, 1110, "cannot find receiver chain nonce") - ErrGasCoinNotFound = errorsmod.Register(ModuleName, 1113, "Err gas coin not found for SenderChain") - ErrUnableToDepositZRC20 = errorsmod.Register(ModuleName, 1114, "Unable to deposit ZRC20 ") - ErrUnableToParseContract = errorsmod.Register(ModuleName, 1115, "Cannot parse contract and data") - ErrCannotProcessWithdrawal = errorsmod.Register(ModuleName, 1116, "Cannot process withdrawal event") - ErrForeignCoinNotFound = errorsmod.Register(ModuleName, 1118, "Err gas coin not found for SenderChain") - ErrNotEnoughPermissions = errorsmod.Register(ModuleName, 1119, "Not enough permissions for current actions") + ErrGasCoinNotFound = errorsmod.Register(ModuleName, 1113, "gas coin not found for SenderChain") + ErrUnableToParseContract = errorsmod.Register(ModuleName, 1115, "cannot parse contract and data") + ErrCannotProcessWithdrawal = errorsmod.Register(ModuleName, 1116, "cannot process withdrawal event") + ErrForeignCoinNotFound = errorsmod.Register(ModuleName, 1118, "gas coin not found for SenderChain") + ErrNotEnoughPermissions = errorsmod.Register(ModuleName, 1119, "not enough permissions for current actions") - ErrCannotFindPendingNonces = errorsmod.Register(ModuleName, 1121, "Err Cannot find pending nonces") - ErrCannotFindTSSKeys = errorsmod.Register(ModuleName, 1122, "Err Cannot find TSS keys") - ErrNonceMismatch = errorsmod.Register(ModuleName, 1123, "Err Nonce mismatch") - ErrNotFoundCoreParams = errorsmod.Register(ModuleName, 1126, "Not found chain core params") - ErrUnableToSendCoinType = errorsmod.Register(ModuleName, 1127, "Unable to send this coin type to a receiver chain") + ErrCannotFindPendingNonces = errorsmod.Register(ModuleName, 1121, "cannot find pending nonces") + ErrCannotFindTSSKeys = errorsmod.Register(ModuleName, 1122, "cannot find TSS keys") + ErrNonceMismatch = errorsmod.Register(ModuleName, 1123, "nonce mismatch") + ErrNotFoundCoreParams = errorsmod.Register(ModuleName, 1126, "not found chain core params") + ErrUnableToSendCoinType = errorsmod.Register(ModuleName, 1127, "unable to send this coin type to a receiver chain") - ErrInvalidAddress = errorsmod.Register(ModuleName, 1128, "Invalid address") - ErrDeployContract = errorsmod.Register(ModuleName, 1129, "Unable to deploy contract") - ErrUnableToUpdateTss = errorsmod.Register(ModuleName, 1130, "Unable to update TSS address") - ErrNotEnoughFunds = errorsmod.Register(ModuleName, 1131, "Not enough funds") + ErrInvalidAddress = errorsmod.Register(ModuleName, 1128, "invalid address") + ErrDeployContract = errorsmod.Register(ModuleName, 1129, "unable to deploy contract") + ErrUnableToUpdateTss = errorsmod.Register(ModuleName, 1130, "unable to update TSS address") + ErrNotEnoughGas = errorsmod.Register(ModuleName, 1131, "not enough gas") + ErrNotEnoughFunds = errorsmod.Register(ModuleName, 1132, "not enough funds") + + ErrProofVerificationFail = errorsmod.Register(ModuleName, 1133, "Proof verification fail") + ErrCannotFindCctx = errorsmod.Register(ModuleName, 1134, "Cannot find cctx") + ErrStatusNotPending = errorsmod.Register(ModuleName, 1135, "Status not pending") + + ErrCannotFindGasParams = errorsmod.Register(ModuleName, 1136, "cannot find gas params") + ErrInvalidGasAmount = errorsmod.Register(ModuleName, 1137, "invalid gas amount") + ErrNoLiquidityPool = errorsmod.Register(ModuleName, 1138, "no liquidity pool") + ErrInvalidCoinType = errorsmod.Register(ModuleName, 1139, "invalid coin type") ) diff --git a/x/crosschain/types/events.pb.go b/x/crosschain/types/events.pb.go index 0c60abeaaa..3fbc7f3fa3 100644 --- a/x/crosschain/types/events.pb.go +++ b/x/crosschain/types/events.pb.go @@ -358,11 +358,11 @@ func (m *EventZetaWithdrawCreated) GetNewStatus() string { } type EventOutboundFailure struct { - MsgTypeUrl string `protobuf:"bytes,1,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"` - CctxIndex string `protobuf:"bytes,2,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` - OldStatus string `protobuf:"bytes,3,opt,name=old_status,json=oldStatus,proto3" json:"old_status,omitempty"` - NewStatus string `protobuf:"bytes,4,opt,name=new_status,json=newStatus,proto3" json:"new_status,omitempty"` - ZetaMinted string `protobuf:"bytes,5,opt,name=zeta_minted,json=zetaMinted,proto3" json:"zeta_minted,omitempty"` + MsgTypeUrl string `protobuf:"bytes,1,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"` + CctxIndex string `protobuf:"bytes,2,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` + OldStatus string `protobuf:"bytes,3,opt,name=old_status,json=oldStatus,proto3" json:"old_status,omitempty"` + NewStatus string `protobuf:"bytes,4,opt,name=new_status,json=newStatus,proto3" json:"new_status,omitempty"` + ValueReceived string `protobuf:"bytes,5,opt,name=value_received,json=valueReceived,proto3" json:"value_received,omitempty"` } func (m *EventOutboundFailure) Reset() { *m = EventOutboundFailure{} } @@ -426,19 +426,19 @@ func (m *EventOutboundFailure) GetNewStatus() string { return "" } -func (m *EventOutboundFailure) GetZetaMinted() string { +func (m *EventOutboundFailure) GetValueReceived() string { if m != nil { - return m.ZetaMinted + return m.ValueReceived } return "" } type EventOutboundSuccess struct { - MsgTypeUrl string `protobuf:"bytes,1,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"` - CctxIndex string `protobuf:"bytes,2,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` - OldStatus string `protobuf:"bytes,3,opt,name=old_status,json=oldStatus,proto3" json:"old_status,omitempty"` - NewStatus string `protobuf:"bytes,4,opt,name=new_status,json=newStatus,proto3" json:"new_status,omitempty"` - ZetaMinted string `protobuf:"bytes,5,opt,name=zeta_minted,json=zetaMinted,proto3" json:"zeta_minted,omitempty"` + MsgTypeUrl string `protobuf:"bytes,1,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"` + CctxIndex string `protobuf:"bytes,2,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` + OldStatus string `protobuf:"bytes,3,opt,name=old_status,json=oldStatus,proto3" json:"old_status,omitempty"` + NewStatus string `protobuf:"bytes,4,opt,name=new_status,json=newStatus,proto3" json:"new_status,omitempty"` + ValueReceived string `protobuf:"bytes,5,opt,name=value_received,json=valueReceived,proto3" json:"value_received,omitempty"` } func (m *EventOutboundSuccess) Reset() { *m = EventOutboundSuccess{} } @@ -502,9 +502,9 @@ func (m *EventOutboundSuccess) GetNewStatus() string { return "" } -func (m *EventOutboundSuccess) GetZetaMinted() string { +func (m *EventOutboundSuccess) GetValueReceived() string { if m != nil { - return m.ZetaMinted + return m.ValueReceived } return "" } @@ -521,43 +521,43 @@ func init() { proto.RegisterFile("crosschain/events.proto", fileDescriptor_7398d var fileDescriptor_7398db8b12b87b9e = []byte{ // 586 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0xcd, 0x6e, 0xd4, 0x30, - 0x10, 0xc7, 0x9b, 0x76, 0x77, 0xbb, 0x3b, 0xfd, 0x92, 0x42, 0xa1, 0xa6, 0xa2, 0xa1, 0x54, 0xe2, - 0xe3, 0xc2, 0x46, 0x88, 0x37, 0x68, 0x05, 0x6a, 0x85, 0xaa, 0x4a, 0xb4, 0x08, 0xa9, 0x17, 0xcb, - 0x9b, 0x8c, 0x12, 0x8b, 0xc4, 0xae, 0x6c, 0xa7, 0x4d, 0xfb, 0x14, 0xbc, 0x08, 0x12, 0x27, 0x9e, - 0x81, 0x63, 0x0f, 0x1c, 0x38, 0xa2, 0xee, 0x8b, 0x20, 0xdb, 0x1b, 0xe8, 0xa6, 0x12, 0x1c, 0x10, - 0x88, 0xd3, 0x7a, 0x7e, 0x33, 0x99, 0xfd, 0xfb, 0x3f, 0xc9, 0xc0, 0x5a, 0xa2, 0xa4, 0xd6, 0x49, - 0xce, 0xb8, 0x88, 0xf1, 0x14, 0x85, 0xd1, 0xc3, 0x13, 0x25, 0x8d, 0x0c, 0x37, 0x2e, 0xd0, 0x30, - 0xc7, 0x87, 0xee, 0x24, 0x15, 0x0e, 0x7f, 0xd6, 0xae, 0xdf, 0x4a, 0x64, 0x59, 0x4a, 0x11, 0xfb, - 0x1f, 0xff, 0xcc, 0xfa, 0x6a, 0x26, 0x33, 0xe9, 0x8e, 0xb1, 0x3d, 0x79, 0xba, 0xf5, 0x65, 0x0e, - 0x6e, 0xbf, 0xb0, 0xad, 0xf7, 0xc4, 0x48, 0x56, 0x22, 0x7d, 0xc9, 0x05, 0x2b, 0xf8, 0x05, 0xa6, - 0xe1, 0x26, 0x2c, 0x96, 0x3a, 0xa3, 0xe6, 0xfc, 0x04, 0x69, 0xa5, 0x0a, 0x12, 0x6c, 0x06, 0x4f, - 0x06, 0xaf, 0xa1, 0xd4, 0xd9, 0xd1, 0xf9, 0x09, 0xbe, 0x51, 0x45, 0xb8, 0x01, 0x90, 0x24, 0xa6, - 0xa6, 0x5c, 0xa4, 0x58, 0x93, 0x59, 0x97, 0x1f, 0x58, 0xb2, 0x67, 0x41, 0x78, 0x07, 0x7a, 0x1a, - 0x45, 0x8a, 0x8a, 0xcc, 0xb9, 0xd4, 0x24, 0x0a, 0xef, 0x42, 0xdf, 0xd4, 0x54, 0xaa, 0x8c, 0x0b, - 0xd2, 0x71, 0x99, 0x79, 0x53, 0x1f, 0xd8, 0x30, 0x5c, 0x85, 0x2e, 0xd3, 0x1a, 0x0d, 0xe9, 0x3a, - 0xee, 0x83, 0xf0, 0x1e, 0x00, 0x17, 0xd4, 0xd4, 0x34, 0x67, 0x3a, 0x27, 0x3d, 0x97, 0xea, 0x73, - 0x71, 0x54, 0xef, 0x32, 0x9d, 0x87, 0x8f, 0x60, 0x85, 0x0b, 0x3a, 0x2a, 0x64, 0xf2, 0x8e, 0xe6, - 0xc8, 0xb3, 0xdc, 0x90, 0x79, 0x57, 0xb2, 0xc4, 0xc5, 0xb6, 0xa5, 0xbb, 0x0e, 0x86, 0xeb, 0xd0, - 0x57, 0x98, 0x20, 0x3f, 0x45, 0x45, 0xfa, 0xbe, 0x47, 0x13, 0x87, 0x0f, 0x61, 0xb9, 0x39, 0x53, - 0x67, 0x21, 0x19, 0xf8, 0x16, 0x0d, 0xdd, 0xb1, 0xd0, 0xde, 0x88, 0x95, 0xb2, 0x12, 0x86, 0x80, - 0xbf, 0x91, 0x8f, 0xc2, 0xc7, 0xb0, 0xa2, 0xb0, 0x60, 0xe7, 0x98, 0xd2, 0x12, 0xb5, 0x66, 0x19, - 0x92, 0x05, 0x57, 0xb0, 0x3c, 0xc1, 0xfb, 0x9e, 0x5a, 0xc7, 0x04, 0x9e, 0x51, 0x6d, 0x98, 0xa9, - 0x34, 0x59, 0xf4, 0x8e, 0x09, 0x3c, 0x3b, 0x74, 0xc0, 0xca, 0xf0, 0xa9, 0x1f, 0x6d, 0x96, 0xbc, - 0x0c, 0x4f, 0x9b, 0x2e, 0x0f, 0x60, 0xd1, 0x5b, 0x39, 0xd1, 0xba, 0xec, 0x8a, 0x16, 0x3c, 0x73, - 0x4a, 0xb7, 0x3e, 0xcc, 0xc2, 0x9a, 0x1b, 0xeb, 0xb1, 0x4a, 0xde, 0x72, 0x93, 0xa7, 0x8a, 0x9d, - 0xed, 0x28, 0x64, 0xe6, 0x6f, 0x0e, 0xb6, 0xad, 0xab, 0x73, 0x43, 0x57, 0x6b, 0x94, 0xdd, 0xd6, - 0x28, 0xaf, 0x8f, 0xa8, 0xf7, 0xdb, 0x11, 0xcd, 0xff, 0x7a, 0x44, 0xfd, 0xa9, 0x11, 0x4d, 0x3b, - 0x3f, 0x68, 0x39, 0xbf, 0xf5, 0x31, 0x00, 0xe2, 0xfd, 0x42, 0xc3, 0xfe, 0x99, 0x61, 0xd3, 0x6e, - 0x74, 0x5a, 0x6e, 0x4c, 0x4b, 0xee, 0xb6, 0x25, 0x7f, 0x0a, 0x60, 0xd5, 0x49, 0x3e, 0xa8, 0x8c, - 0xff, 0x74, 0x19, 0x2f, 0x2a, 0x85, 0x7f, 0x2e, 0x77, 0x03, 0x40, 0x16, 0x69, 0xf3, 0xc7, 0x5e, - 0xf2, 0x40, 0x16, 0xe9, 0xe4, 0x2d, 0x9d, 0xd6, 0xd5, 0x69, 0xbf, 0xc4, 0xf7, 0x61, 0xc1, 0xee, - 0x24, 0x5a, 0x72, 0x61, 0x30, 0x9d, 0xe8, 0x06, 0x8b, 0xf6, 0x1d, 0xb9, 0x29, 0xfc, 0xb0, 0x4a, - 0x12, 0xd4, 0xfa, 0x7f, 0x17, 0xbe, 0xfd, 0xea, 0xf3, 0x55, 0x14, 0x5c, 0x5e, 0x45, 0xc1, 0xb7, - 0xab, 0x28, 0x78, 0x3f, 0x8e, 0x66, 0x2e, 0xc7, 0xd1, 0xcc, 0xd7, 0x71, 0x34, 0x73, 0xfc, 0x2c, - 0xe3, 0x26, 0xaf, 0x46, 0xc3, 0x44, 0x96, 0xb1, 0x7d, 0xe0, 0xa9, 0xdf, 0xd9, 0xcd, 0x6e, 0x8e, - 0xeb, 0xf8, 0xda, 0x26, 0xb7, 0xf7, 0xd3, 0xa3, 0x9e, 0xdb, 0xbf, 0xcf, 0xbf, 0x07, 0x00, 0x00, - 0xff, 0xff, 0xd2, 0x22, 0x77, 0xcb, 0xe4, 0x05, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xdd, 0x6a, 0xd4, 0x40, + 0x14, 0x6e, 0xda, 0xdd, 0xed, 0xee, 0xf4, 0x0f, 0x62, 0xb5, 0x63, 0xb1, 0xa1, 0x2e, 0xf8, 0x73, + 0xe3, 0x06, 0xf1, 0x0d, 0x5a, 0x94, 0x16, 0x91, 0x42, 0x5b, 0x11, 0x7a, 0x33, 0xcc, 0x26, 0x87, + 0x64, 0x30, 0x99, 0x59, 0x66, 0x26, 0xbb, 0xd9, 0x3e, 0x85, 0x2f, 0x22, 0xf8, 0x00, 0x3e, 0x80, + 0x97, 0xbd, 0xf0, 0xc2, 0x4b, 0xd9, 0x7d, 0x11, 0x99, 0x99, 0x44, 0xbb, 0xa9, 0xe8, 0x85, 0x28, + 0x78, 0x95, 0x73, 0xbe, 0x73, 0x72, 0xf2, 0xcd, 0xf7, 0x4d, 0x0e, 0xda, 0x89, 0xa4, 0x50, 0x2a, + 0x4a, 0x29, 0xe3, 0x21, 0x8c, 0x81, 0x6b, 0x35, 0x18, 0x49, 0xa1, 0x85, 0xbf, 0x77, 0x09, 0x9a, + 0x5a, 0x7c, 0x60, 0x23, 0x21, 0x61, 0xf0, 0xa3, 0x77, 0xf7, 0x56, 0x24, 0xf2, 0x5c, 0xf0, 0xd0, + 0x3d, 0xdc, 0x3b, 0xbb, 0xdb, 0x89, 0x48, 0x84, 0x0d, 0x43, 0x13, 0x39, 0xb4, 0xff, 0x79, 0x05, + 0xdd, 0x7e, 0x6e, 0x46, 0x1f, 0xf3, 0xa1, 0x28, 0x78, 0xfc, 0x82, 0x71, 0x9a, 0xb1, 0x4b, 0x88, + 0xfd, 0x7d, 0xb4, 0x9e, 0xab, 0x84, 0xe8, 0xe9, 0x08, 0x48, 0x21, 0x33, 0xec, 0xed, 0x7b, 0x8f, + 0x7b, 0xa7, 0x28, 0x57, 0xc9, 0xf9, 0x74, 0x04, 0xaf, 0x65, 0xe6, 0xef, 0x21, 0x14, 0x45, 0xba, + 0x24, 0x8c, 0xc7, 0x50, 0xe2, 0x65, 0x5b, 0xef, 0x19, 0xe4, 0xd8, 0x00, 0xfe, 0x1d, 0xd4, 0x51, + 0xc0, 0x63, 0x90, 0x78, 0xc5, 0x96, 0xaa, 0xcc, 0xbf, 0x8b, 0xba, 0xba, 0x24, 0x42, 0x26, 0x8c, + 0xe3, 0x96, 0xad, 0xac, 0xea, 0xf2, 0xc4, 0xa4, 0xfe, 0x36, 0x6a, 0x53, 0xa5, 0x40, 0xe3, 0xb6, + 0xc5, 0x5d, 0xe2, 0xdf, 0x43, 0x88, 0x71, 0xa2, 0x4b, 0x92, 0x52, 0x95, 0xe2, 0x8e, 0x2d, 0x75, + 0x19, 0x3f, 0x2f, 0x8f, 0xa8, 0x4a, 0xfd, 0x87, 0x68, 0x8b, 0x71, 0x32, 0xcc, 0x44, 0xf4, 0x96, + 0xa4, 0xc0, 0x92, 0x54, 0xe3, 0x55, 0xdb, 0xb2, 0xc1, 0xf8, 0x81, 0x41, 0x8f, 0x2c, 0xe8, 0xef, + 0xa2, 0xae, 0x84, 0x08, 0xd8, 0x18, 0x24, 0xee, 0xba, 0x19, 0x75, 0xee, 0x3f, 0x40, 0x9b, 0x75, + 0x4c, 0xac, 0x84, 0xb8, 0xe7, 0x46, 0xd4, 0xe8, 0xa1, 0x01, 0xcd, 0x89, 0x68, 0x2e, 0x0a, 0xae, + 0x31, 0x72, 0x27, 0x72, 0x99, 0xff, 0x08, 0x6d, 0x49, 0xc8, 0xe8, 0x14, 0x62, 0x92, 0x83, 0x52, + 0x34, 0x01, 0xbc, 0x66, 0x1b, 0x36, 0x2b, 0xf8, 0x95, 0x43, 0x8d, 0x62, 0x1c, 0x26, 0x44, 0x69, + 0xaa, 0x0b, 0x85, 0xd7, 0x9d, 0x62, 0x1c, 0x26, 0x67, 0x16, 0x30, 0x34, 0x5c, 0xe9, 0xfb, 0x98, + 0x0d, 0x47, 0xc3, 0xa1, 0xf5, 0x94, 0xfb, 0x68, 0xdd, 0x49, 0x59, 0x71, 0xdd, 0xb4, 0x4d, 0x6b, + 0x0e, 0xb3, 0x4c, 0xfb, 0xef, 0x97, 0xd1, 0x8e, 0xb5, 0xf5, 0x42, 0x46, 0x6f, 0x98, 0x4e, 0x63, + 0x49, 0x27, 0x87, 0x12, 0xa8, 0xfe, 0x9b, 0xc6, 0x36, 0x79, 0xb5, 0x6e, 0xf0, 0x6a, 0x58, 0xd9, + 0x6e, 0x58, 0x79, 0xdd, 0xa2, 0xce, 0x6f, 0x2d, 0x5a, 0xfd, 0xb5, 0x45, 0xdd, 0x05, 0x8b, 0x16, + 0x95, 0xef, 0x35, 0x94, 0xef, 0x7f, 0xf0, 0x10, 0x76, 0x7a, 0x81, 0xa6, 0xff, 0x4c, 0xb0, 0x45, + 0x35, 0x5a, 0x0d, 0x35, 0x16, 0x29, 0xb7, 0x9b, 0x94, 0x3f, 0x7a, 0x68, 0xdb, 0x52, 0x3e, 0x29, + 0xb4, 0xfb, 0x75, 0x29, 0xcb, 0x0a, 0x09, 0x7f, 0x4e, 0x77, 0x0f, 0x21, 0x91, 0xc5, 0xf5, 0x87, + 0x1d, 0xe5, 0x9e, 0xc8, 0xe2, 0xea, 0x96, 0x2e, 0xf2, 0x6a, 0xfd, 0xe4, 0x12, 0x8f, 0x69, 0x56, + 0x00, 0xa9, 0x8c, 0x89, 0x2b, 0xea, 0x1b, 0x16, 0x3d, 0xad, 0xc0, 0x9b, 0xf4, 0xcf, 0x8a, 0x28, + 0x02, 0xa5, 0xfe, 0x0f, 0xfa, 0x07, 0x2f, 0x3f, 0xcd, 0x02, 0xef, 0x6a, 0x16, 0x78, 0x5f, 0x67, + 0x81, 0xf7, 0x6e, 0x1e, 0x2c, 0x5d, 0xcd, 0x83, 0xa5, 0x2f, 0xf3, 0x60, 0xe9, 0xe2, 0x69, 0xc2, + 0x74, 0x5a, 0x0c, 0x07, 0x91, 0xc8, 0x43, 0xb3, 0x9c, 0x9f, 0xb8, 0xfd, 0x5d, 0xef, 0xe9, 0xb0, + 0x0c, 0xaf, 0x6d, 0x75, 0x73, 0x4a, 0x35, 0xec, 0xd8, 0x5d, 0xfc, 0xec, 0x5b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xee, 0x0c, 0x96, 0x59, 0xf0, 0x05, 0x00, 0x00, } func (m *EventInboundFinalized) Marshal() (dAtA []byte, err error) { @@ -845,10 +845,10 @@ func (m *EventOutboundFailure) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ZetaMinted) > 0 { - i -= len(m.ZetaMinted) - copy(dAtA[i:], m.ZetaMinted) - i = encodeVarintEvents(dAtA, i, uint64(len(m.ZetaMinted))) + if len(m.ValueReceived) > 0 { + i -= len(m.ValueReceived) + copy(dAtA[i:], m.ValueReceived) + i = encodeVarintEvents(dAtA, i, uint64(len(m.ValueReceived))) i-- dAtA[i] = 0x2a } @@ -903,10 +903,10 @@ func (m *EventOutboundSuccess) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ZetaMinted) > 0 { - i -= len(m.ZetaMinted) - copy(dAtA[i:], m.ZetaMinted) - i = encodeVarintEvents(dAtA, i, uint64(len(m.ZetaMinted))) + if len(m.ValueReceived) > 0 { + i -= len(m.ValueReceived) + copy(dAtA[i:], m.ValueReceived) + i = encodeVarintEvents(dAtA, i, uint64(len(m.ValueReceived))) i-- dAtA[i] = 0x2a } @@ -1113,7 +1113,7 @@ func (m *EventOutboundFailure) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } - l = len(m.ZetaMinted) + l = len(m.ValueReceived) if l > 0 { n += 1 + l + sovEvents(uint64(l)) } @@ -1142,7 +1142,7 @@ func (m *EventOutboundSuccess) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } - l = len(m.ZetaMinted) + l = len(m.ValueReceived) if l > 0 { n += 1 + l + sovEvents(uint64(l)) } @@ -2360,7 +2360,7 @@ func (m *EventOutboundFailure) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ZetaMinted", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValueReceived", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2388,7 +2388,7 @@ func (m *EventOutboundFailure) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ZetaMinted = string(dAtA[iNdEx:postIndex]) + m.ValueReceived = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2570,7 +2570,7 @@ func (m *EventOutboundSuccess) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ZetaMinted", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValueReceived", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2598,7 +2598,7 @@ func (m *EventOutboundSuccess) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ZetaMinted = string(dAtA[iNdEx:postIndex]) + m.ValueReceived = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index fe35310c01..eaaf36b966 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -66,6 +66,7 @@ type ZetaObserverKeeper interface { IsAuthorized(ctx sdk.Context, address string, chain *common.Chain) (bool, error) FindBallot(ctx sdk.Context, index string, chain *common.Chain, observationType zetaObserverTypes.ObservationType) (ballot zetaObserverTypes.Ballot, isNew bool, err error) AddBallotToList(ctx sdk.Context, ballot zetaObserverTypes.Ballot) + GetBlockHeader(ctx sdk.Context, hash []byte) (val common.BlockHeader, found bool) } type FungibleKeeper interface { @@ -73,11 +74,23 @@ type FungibleKeeper interface { GetAllForeignCoins(ctx sdk.Context) (list []fungibletypes.ForeignCoins) SetForeignCoins(ctx sdk.Context, foreignCoins fungibletypes.ForeignCoins) GetAllForeignCoinsForChain(ctx sdk.Context, foreignChainID int64) (list []fungibletypes.ForeignCoins) + GetForeignCoinFromAsset(ctx sdk.Context, asset string, chainID int64) (fungibletypes.ForeignCoins, bool) GetSystemContract(ctx sdk.Context) (val fungibletypes.SystemContract, found bool) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainID *big.Int) (eth.Address, error) - QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 eth.Address) (*big.Int, error) + GetUniswapV2Router02Address(ctx sdk.Context) (eth.Address, error) + QueryUniswapV2RouterGetZetaAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 eth.Address) (*big.Int, error) + QueryUniswapV2RouterGetZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4 eth.Address) (*big.Int, error) + QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4, outZRC4 eth.Address) (*big.Int, error) + QueryGasLimit(ctx sdk.Context, contract eth.Address) (*big.Int, error) + QueryProtocolFlatFee(ctx sdk.Context, contract eth.Address) (*big.Int, error) SetGasPrice(ctx sdk.Context, chainID *big.Int, gasPrice *big.Int) (uint64, error) DepositCoinZeta(ctx sdk.Context, to eth.Address, amount *big.Int) error + DepositZRC20( + ctx sdk.Context, + contract eth.Address, + to eth.Address, + amount *big.Int, + ) (*evmtypes.MsgEthereumTxResponse, error) ZRC20DepositAndCallContract( ctx sdk.Context, from []byte, @@ -90,7 +103,16 @@ type FungibleKeeper interface { coinType common.CoinType, asset string, ) (*evmtypes.MsgEthereumTxResponse, error) - CallUniswapv2RouterSwapExactETHForToken( + CallUniswapV2RouterSwapExactTokensForTokens( + ctx sdk.Context, + sender eth.Address, + to eth.Address, + amountIn *big.Int, + inZRC4, + outZRC4 eth.Address, + noEthereumTxEvent bool, + ) (ret []*big.Int, err error) + CallUniswapV2RouterSwapExactETHForToken( ctx sdk.Context, sender eth.Address, to eth.Address, @@ -99,6 +121,14 @@ type FungibleKeeper interface { noEthereumTxEvent bool, ) ([]*big.Int, error) CallZRC20Burn(ctx sdk.Context, sender eth.Address, zrc20address eth.Address, amount *big.Int, noEthereumTxEvent bool) error + CallZRC20Approve( + ctx sdk.Context, + owner eth.Address, + zrc20address eth.Address, + spender eth.Address, + amount *big.Int, + noEthereumTxEvent bool, + ) error DeployZRC20Contract( ctx sdk.Context, name, symbol string, diff --git a/x/crosschain/types/message_add_to_out_tx_tracker.go b/x/crosschain/types/message_add_to_out_tx_tracker.go index cdb878dd93..06716762a1 100644 --- a/x/crosschain/types/message_add_to_out_tx_tracker.go +++ b/x/crosschain/types/message_add_to_out_tx_tracker.go @@ -3,18 +3,30 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/zeta-chain/zetacore/common" ) const TypeMsgAddToOutTxTracker = "AddToTracker" var _ sdk.Msg = &MsgAddToOutTxTracker{} -func NewMsgAddToOutTxTracker(creator string, chain int64, nonce uint64, txHash string) *MsgAddToOutTxTracker { +func NewMsgAddToOutTxTracker( + creator string, + chain int64, + nonce uint64, + txHash string, + proof *common.Proof, + blockHash string, + txIndex int64, +) *MsgAddToOutTxTracker { return &MsgAddToOutTxTracker{ - Creator: creator, - ChainId: chain, - Nonce: nonce, - TxHash: txHash, + Creator: creator, + ChainId: chain, + Nonce: nonce, + TxHash: txHash, + Proof: proof, + BlockHash: blockHash, + TxIndex: txIndex, } } diff --git a/x/crosschain/types/message_vote_on_observed_outbound_tx.go b/x/crosschain/types/message_vote_on_observed_outbound_tx.go index 9bccf434c6..bf940f6984 100644 --- a/x/crosschain/types/message_vote_on_observed_outbound_tx.go +++ b/x/crosschain/types/message_vote_on_observed_outbound_tx.go @@ -18,7 +18,7 @@ func NewMsgVoteOnObservedOutboundTx( outTxGasUsed uint64, outTxEffectiveGasPrice math.Int, outTxEffectiveGasLimit uint64, - mMint math.Uint, + valueReceived math.Uint, status common.ReceiveStatus, chain int64, nonce uint64, @@ -32,7 +32,7 @@ func NewMsgVoteOnObservedOutboundTx( ObservedOutTxGasUsed: outTxGasUsed, ObservedOutTxEffectiveGasPrice: outTxEffectiveGasPrice, ObservedOutTxEffectiveGasLimit: outTxEffectiveGasLimit, - ZetaMinted: mMint, + ValueReceived: valueReceived, Status: status, OutTxChain: chain, OutTxTssNonce: nonce, diff --git a/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go b/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go index 7df78fd94d..cce6a29c3c 100644 --- a/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go +++ b/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go @@ -28,7 +28,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { ObservedOutTxGasUsed: 42, ObservedOutTxEffectiveGasPrice: math.NewInt(42), ObservedOutTxEffectiveGasLimit: 42, - ZetaMinted: math.NewUint(42), + ValueReceived: math.NewUint(42), Status: common.ReceiveStatus_Created, OutTxChain: 42, OutTxTssNonce: 42, @@ -43,7 +43,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { ObservedOutTxHash: sample.String(), ObservedOutTxBlockHeight: 42, ObservedOutTxGasUsed: 42, - ZetaMinted: math.NewUint(42), + ValueReceived: math.NewUint(42), Status: common.ReceiveStatus_Created, OutTxChain: 42, OutTxTssNonce: 42, @@ -60,7 +60,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { ObservedOutTxGasUsed: 42, ObservedOutTxEffectiveGasPrice: math.NewInt(42), ObservedOutTxEffectiveGasLimit: 42, - ZetaMinted: math.NewUint(42), + ValueReceived: math.NewUint(42), Status: common.ReceiveStatus_Created, OutTxChain: 42, OutTxTssNonce: 42, @@ -78,7 +78,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { ObservedOutTxGasUsed: 42, ObservedOutTxEffectiveGasPrice: math.NewInt(42), ObservedOutTxEffectiveGasLimit: 42, - ZetaMinted: math.NewUint(42), + ValueReceived: math.NewUint(42), Status: common.ReceiveStatus_Created, OutTxChain: -1, OutTxTssNonce: 42, @@ -110,7 +110,7 @@ func TestMsgVoteOnObservedOutboundTx_Digest(t *testing.T) { ObservedOutTxGasUsed: 42, ObservedOutTxEffectiveGasPrice: math.NewInt(42), ObservedOutTxEffectiveGasLimit: 42, - ZetaMinted: math.NewUint(42), + ValueReceived: math.NewUint(42), Status: common.ReceiveStatus_Created, OutTxChain: 42, OutTxTssNonce: 42, @@ -169,7 +169,7 @@ func TestMsgVoteOnObservedOutboundTx_Digest(t *testing.T) { // zeta minted used msg2 = msg - msg2.ZetaMinted = math.NewUint(43) + msg2.ValueReceived = math.NewUint(43) hash2 = msg2.Digest() require.NotEqual(t, hash, hash2, "zeta minted should change hash") diff --git a/x/crosschain/types/out_tx_tracker.pb.go b/x/crosschain/types/out_tx_tracker.pb.go index 86eba158a2..d9d021851a 100644 --- a/x/crosschain/types/out_tx_tracker.pb.go +++ b/x/crosschain/types/out_tx_tracker.pb.go @@ -26,6 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type TxHashList struct { TxHash string `protobuf:"bytes,1,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` TxSigner string `protobuf:"bytes,2,opt,name=tx_signer,json=txSigner,proto3" json:"tx_signer,omitempty"` + Proved bool `protobuf:"varint,3,opt,name=proved,proto3" json:"proved,omitempty"` } func (m *TxHashList) Reset() { *m = TxHashList{} } @@ -75,6 +76,13 @@ func (m *TxHashList) GetTxSigner() string { return "" } +func (m *TxHashList) GetProved() bool { + if m != nil { + return m.Proved + } + return false +} + type OutTxTracker struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -151,25 +159,26 @@ func init() { func init() { proto.RegisterFile("crosschain/out_tx_tracker.proto", fileDescriptor_5638c11005e4d36d) } var fileDescriptor_5638c11005e4d36d = []byte{ - // 287 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xb1, 0x4e, 0xf3, 0x30, - 0x14, 0x85, 0xeb, 0xbf, 0xfd, 0xdb, 0xc6, 0x30, 0x59, 0x48, 0x04, 0x21, 0x4c, 0xd4, 0x29, 0x0c, - 0x38, 0x02, 0xde, 0xa0, 0x03, 0x02, 0x81, 0x84, 0x14, 0x32, 0xb1, 0x58, 0x69, 0x62, 0xd5, 0x16, - 0x10, 0x57, 0xf6, 0x8d, 0x64, 0x78, 0x0a, 0x5e, 0x80, 0xf7, 0x61, 0xec, 0xc8, 0x88, 0x92, 0x17, - 0x41, 0x71, 0x8a, 0xca, 0xc4, 0x76, 0x8f, 0x8e, 0xee, 0x77, 0xef, 0x39, 0xf8, 0xb8, 0x30, 0xda, - 0xda, 0x42, 0xe6, 0xaa, 0x4a, 0x74, 0x0d, 0x1c, 0x1c, 0x07, 0x93, 0x17, 0x8f, 0xc2, 0xb0, 0x95, - 0xd1, 0xa0, 0xc9, 0xd1, 0xab, 0x80, 0xdc, 0xfb, 0xcc, 0x4f, 0xda, 0x08, 0xb6, 0xdd, 0x99, 0xcd, - 0x31, 0xce, 0xdc, 0x55, 0x6e, 0xe5, 0xad, 0xb2, 0x40, 0xf6, 0xf1, 0x04, 0x1c, 0x97, 0xb9, 0x95, - 0x21, 0x8a, 0x50, 0x1c, 0xa4, 0x63, 0xf0, 0x26, 0x39, 0xc4, 0x01, 0x38, 0x6e, 0xd5, 0xb2, 0x12, - 0x26, 0xfc, 0xe7, 0xad, 0x29, 0xb8, 0x7b, 0xaf, 0x67, 0xef, 0x08, 0xef, 0xde, 0xd5, 0x90, 0xb9, - 0xac, 0xbf, 0x4c, 0xf6, 0xf0, 0x7f, 0x55, 0x95, 0xc2, 0x6d, 0x20, 0xbd, 0x20, 0x07, 0x78, 0xea, - 0x6f, 0x72, 0x55, 0x7a, 0xc4, 0x30, 0x9d, 0x78, 0x7d, 0x5d, 0x76, 0x0b, 0x95, 0xae, 0x0a, 0x11, - 0x0e, 0x23, 0x14, 0x8f, 0xd2, 0x5e, 0x90, 0x4b, 0x1c, 0x74, 0xaf, 0xf0, 0x27, 0x65, 0x21, 0x1c, - 0x45, 0xc3, 0x78, 0xe7, 0xfc, 0x84, 0xfd, 0x19, 0x87, 0x6d, 0xb3, 0xa4, 0x53, 0xb9, 0x99, 0xe6, - 0x37, 0x1f, 0x0d, 0x45, 0xeb, 0x86, 0xa2, 0xaf, 0x86, 0xa2, 0xb7, 0x96, 0x0e, 0xd6, 0x2d, 0x1d, - 0x7c, 0xb6, 0x74, 0xf0, 0x70, 0xb6, 0x54, 0x20, 0xeb, 0x05, 0x2b, 0xf4, 0x73, 0xd2, 0xe1, 0x4e, - 0xfb, 0x22, 0x7f, 0xc8, 0x89, 0x4b, 0x7e, 0xd5, 0x0b, 0x2f, 0x2b, 0x61, 0x17, 0x63, 0x5f, 0xeb, - 0xc5, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x97, 0x57, 0xaa, 0x79, 0x01, 0x00, 0x00, + // 299 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xb1, 0x4e, 0xeb, 0x30, + 0x14, 0x86, 0xeb, 0xdb, 0xde, 0x36, 0x35, 0x4c, 0x16, 0x82, 0x20, 0x84, 0xa9, 0x3a, 0x95, 0x01, + 0x47, 0xc0, 0x1b, 0x30, 0x20, 0x10, 0x48, 0x48, 0xa1, 0x53, 0x17, 0x2b, 0x4d, 0xac, 0xda, 0x02, + 0xe2, 0xc8, 0x3e, 0x41, 0x86, 0xa7, 0xe0, 0x05, 0x78, 0x1f, 0xc6, 0x8e, 0x8c, 0x28, 0x79, 0x11, + 0x14, 0x27, 0xa8, 0x4c, 0x6c, 0xe7, 0xd3, 0xd1, 0xf9, 0xf4, 0x9f, 0x1f, 0x1f, 0xa5, 0x46, 0x5b, + 0x9b, 0xca, 0x44, 0xe5, 0x91, 0x2e, 0x81, 0x83, 0xe3, 0x60, 0x92, 0xf4, 0x41, 0x18, 0x56, 0x18, + 0x0d, 0x9a, 0x1c, 0xbe, 0x0a, 0x48, 0xfc, 0x9e, 0xf9, 0x49, 0x1b, 0xc1, 0x36, 0x37, 0xd3, 0x05, + 0xc6, 0x73, 0x77, 0x95, 0x58, 0x79, 0xab, 0x2c, 0x90, 0x3d, 0x3c, 0x02, 0xc7, 0x65, 0x62, 0x65, + 0x88, 0x26, 0x68, 0x36, 0x8e, 0x87, 0xe0, 0x97, 0xe4, 0x00, 0x8f, 0xc1, 0x71, 0xab, 0x56, 0xb9, + 0x30, 0xe1, 0x3f, 0xbf, 0x0a, 0xc0, 0xdd, 0x7b, 0x26, 0xbb, 0x78, 0x58, 0x18, 0xfd, 0x2c, 0xb2, + 0xb0, 0x3f, 0x41, 0xb3, 0x20, 0xee, 0x68, 0xfa, 0x8e, 0xf0, 0xf6, 0x5d, 0x09, 0x73, 0x37, 0x6f, + 0x13, 0x91, 0x1d, 0xfc, 0x5f, 0xe5, 0x99, 0x70, 0x9d, 0xbc, 0x05, 0xb2, 0x8f, 0x03, 0x9f, 0x85, + 0xab, 0xcc, 0xab, 0xfb, 0xf1, 0xc8, 0xf3, 0x75, 0xd6, 0x1c, 0xe4, 0x3a, 0x4f, 0x85, 0x17, 0x0f, + 0xe2, 0x16, 0xc8, 0x25, 0x1e, 0x37, 0x11, 0xf9, 0xa3, 0xb2, 0x10, 0x0e, 0x26, 0xfd, 0xd9, 0xd6, + 0xd9, 0x31, 0xfb, 0xf3, 0x4d, 0xb6, 0xf9, 0x31, 0x0e, 0x64, 0x37, 0x5d, 0xdc, 0x7c, 0x54, 0x14, + 0xad, 0x2b, 0x8a, 0xbe, 0x2a, 0x8a, 0xde, 0x6a, 0xda, 0x5b, 0xd7, 0xb4, 0xf7, 0x59, 0xd3, 0xde, + 0xe2, 0x74, 0xa5, 0x40, 0x96, 0x4b, 0x96, 0xea, 0xa7, 0xa8, 0xd1, 0x9d, 0xb4, 0x05, 0xff, 0x98, + 0x23, 0x17, 0xfd, 0xaa, 0x1d, 0x5e, 0x0a, 0x61, 0x97, 0x43, 0x5f, 0xf7, 0xf9, 0x77, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x0c, 0x73, 0x3d, 0x85, 0x91, 0x01, 0x00, 0x00, } func (m *TxHashList) Marshal() (dAtA []byte, err error) { @@ -192,6 +201,16 @@ func (m *TxHashList) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Proved { + i-- + if m.Proved { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if len(m.TxSigner) > 0 { i -= len(m.TxSigner) copy(dAtA[i:], m.TxSigner) @@ -288,6 +307,9 @@ func (m *TxHashList) Size() (n int) { if l > 0 { n += 1 + l + sovOutTxTracker(uint64(l)) } + if m.Proved { + n += 2 + } return n } @@ -415,6 +437,26 @@ func (m *TxHashList) Unmarshal(dAtA []byte) error { } m.TxSigner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proved", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOutTxTracker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Proved = bool(v != 0) default: iNdEx = preIndex skippy, err := skipOutTxTracker(dAtA[iNdEx:]) diff --git a/x/crosschain/types/query.pb.go b/x/crosschain/types/query.pb.go index ab9aef612d..4a808fb004 100644 --- a/x/crosschain/types/query.pb.go +++ b/x/crosschain/types/query.pb.go @@ -1378,6 +1378,94 @@ func (m *QueryAllPendingNoncesResponse) GetPendingNonces() []*PendingNonces { return nil } +type QueryPendingNoncesByChainRequest struct { + ChainId uint64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *QueryPendingNoncesByChainRequest) Reset() { *m = QueryPendingNoncesByChainRequest{} } +func (m *QueryPendingNoncesByChainRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPendingNoncesByChainRequest) ProtoMessage() {} +func (*QueryPendingNoncesByChainRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{30} +} +func (m *QueryPendingNoncesByChainRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingNoncesByChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingNoncesByChainRequest.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 *QueryPendingNoncesByChainRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingNoncesByChainRequest.Merge(m, src) +} +func (m *QueryPendingNoncesByChainRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingNoncesByChainRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingNoncesByChainRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingNoncesByChainRequest proto.InternalMessageInfo + +func (m *QueryPendingNoncesByChainRequest) GetChainId() uint64 { + if m != nil { + return m.ChainId + } + return 0 +} + +type QueryPendingNoncesByChainResponse struct { + PendingNonces PendingNonces `protobuf:"bytes,1,opt,name=pending_nonces,json=pendingNonces,proto3" json:"pending_nonces"` +} + +func (m *QueryPendingNoncesByChainResponse) Reset() { *m = QueryPendingNoncesByChainResponse{} } +func (m *QueryPendingNoncesByChainResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPendingNoncesByChainResponse) ProtoMessage() {} +func (*QueryPendingNoncesByChainResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{31} +} +func (m *QueryPendingNoncesByChainResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingNoncesByChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingNoncesByChainResponse.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 *QueryPendingNoncesByChainResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingNoncesByChainResponse.Merge(m, src) +} +func (m *QueryPendingNoncesByChainResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingNoncesByChainResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingNoncesByChainResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingNoncesByChainResponse proto.InternalMessageInfo + +func (m *QueryPendingNoncesByChainResponse) GetPendingNonces() PendingNonces { + if m != nil { + return m.PendingNonces + } + return PendingNonces{} +} + type QueryGetLastBlockHeightRequest struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` } @@ -1386,7 +1474,7 @@ func (m *QueryGetLastBlockHeightRequest) Reset() { *m = QueryGetLastBloc func (m *QueryGetLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightRequest) ProtoMessage() {} func (*QueryGetLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{30} + return fileDescriptor_65a992045e92a606, []int{32} } func (m *QueryGetLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1430,7 +1518,7 @@ func (m *QueryGetLastBlockHeightResponse) Reset() { *m = QueryGetLastBlo func (m *QueryGetLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightResponse) ProtoMessage() {} func (*QueryGetLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{31} + return fileDescriptor_65a992045e92a606, []int{33} } func (m *QueryGetLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1474,7 +1562,7 @@ func (m *QueryAllLastBlockHeightRequest) Reset() { *m = QueryAllLastBloc func (m *QueryAllLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightRequest) ProtoMessage() {} func (*QueryAllLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{32} + return fileDescriptor_65a992045e92a606, []int{34} } func (m *QueryAllLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1519,7 +1607,7 @@ func (m *QueryAllLastBlockHeightResponse) Reset() { *m = QueryAllLastBlo func (m *QueryAllLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightResponse) ProtoMessage() {} func (*QueryAllLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{33} + return fileDescriptor_65a992045e92a606, []int{35} } func (m *QueryAllLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1570,7 +1658,7 @@ func (m *QueryGetCctxRequest) Reset() { *m = QueryGetCctxRequest{} } func (m *QueryGetCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxRequest) ProtoMessage() {} func (*QueryGetCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{34} + return fileDescriptor_65a992045e92a606, []int{36} } func (m *QueryGetCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1615,7 +1703,7 @@ func (m *QueryGetCctxByNonceRequest) Reset() { *m = QueryGetCctxByNonceR func (m *QueryGetCctxByNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxByNonceRequest) ProtoMessage() {} func (*QueryGetCctxByNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{35} + return fileDescriptor_65a992045e92a606, []int{37} } func (m *QueryGetCctxByNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1666,7 +1754,7 @@ func (m *QueryGetCctxResponse) Reset() { *m = QueryGetCctxResponse{} } func (m *QueryGetCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxResponse) ProtoMessage() {} func (*QueryGetCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{36} + return fileDescriptor_65a992045e92a606, []int{38} } func (m *QueryGetCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1710,7 +1798,7 @@ func (m *QueryAllCctxRequest) Reset() { *m = QueryAllCctxRequest{} } func (m *QueryAllCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxRequest) ProtoMessage() {} func (*QueryAllCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{37} + return fileDescriptor_65a992045e92a606, []int{39} } func (m *QueryAllCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1755,7 +1843,7 @@ func (m *QueryAllCctxResponse) Reset() { *m = QueryAllCctxResponse{} } func (m *QueryAllCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxResponse) ProtoMessage() {} func (*QueryAllCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{38} + return fileDescriptor_65a992045e92a606, []int{40} } func (m *QueryAllCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1807,7 +1895,7 @@ func (m *QueryAllCctxPendingRequest) Reset() { *m = QueryAllCctxPendingR func (m *QueryAllCctxPendingRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxPendingRequest) ProtoMessage() {} func (*QueryAllCctxPendingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{39} + return fileDescriptor_65a992045e92a606, []int{41} } func (m *QueryAllCctxPendingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1859,7 +1947,7 @@ func (m *QueryAllCctxPendingResponse) Reset() { *m = QueryAllCctxPending func (m *QueryAllCctxPendingResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxPendingResponse) ProtoMessage() {} func (*QueryAllCctxPendingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{40} + return fileDescriptor_65a992045e92a606, []int{42} } func (m *QueryAllCctxPendingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1909,7 +1997,7 @@ func (m *QueryLastZetaHeightRequest) Reset() { *m = QueryLastZetaHeightR func (m *QueryLastZetaHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightRequest) ProtoMessage() {} func (*QueryLastZetaHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{41} + return fileDescriptor_65a992045e92a606, []int{43} } func (m *QueryLastZetaHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1946,7 +2034,7 @@ func (m *QueryLastZetaHeightResponse) Reset() { *m = QueryLastZetaHeight func (m *QueryLastZetaHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightResponse) ProtoMessage() {} func (*QueryLastZetaHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{42} + return fileDescriptor_65a992045e92a606, []int{44} } func (m *QueryLastZetaHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1991,7 +2079,7 @@ func (m *QueryConvertGasToZetaRequest) Reset() { *m = QueryConvertGasToZ func (m *QueryConvertGasToZetaRequest) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaRequest) ProtoMessage() {} func (*QueryConvertGasToZetaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{43} + return fileDescriptor_65a992045e92a606, []int{45} } func (m *QueryConvertGasToZetaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2044,7 +2132,7 @@ func (m *QueryConvertGasToZetaResponse) Reset() { *m = QueryConvertGasTo func (m *QueryConvertGasToZetaResponse) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaResponse) ProtoMessage() {} func (*QueryConvertGasToZetaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{44} + return fileDescriptor_65a992045e92a606, []int{46} } func (m *QueryConvertGasToZetaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2101,7 +2189,7 @@ func (m *QueryMessagePassingProtocolFeeRequest) Reset() { *m = QueryMess func (m *QueryMessagePassingProtocolFeeRequest) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeRequest) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{45} + return fileDescriptor_65a992045e92a606, []int{47} } func (m *QueryMessagePassingProtocolFeeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2140,7 +2228,7 @@ func (m *QueryMessagePassingProtocolFeeResponse) Reset() { func (m *QueryMessagePassingProtocolFeeResponse) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeResponse) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{46} + return fileDescriptor_65a992045e92a606, []int{48} } func (m *QueryMessagePassingProtocolFeeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2184,7 +2272,7 @@ func (m *QueryZEVMGetTransactionReceiptRequest) Reset() { *m = QueryZEVM func (m *QueryZEVMGetTransactionReceiptRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionReceiptRequest) ProtoMessage() {} func (*QueryZEVMGetTransactionReceiptRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{47} + return fileDescriptor_65a992045e92a606, []int{49} } func (m *QueryZEVMGetTransactionReceiptRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2241,7 +2329,7 @@ func (m *QueryZEVMGetTransactionReceiptResponse) Reset() { func (m *QueryZEVMGetTransactionReceiptResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionReceiptResponse) ProtoMessage() {} func (*QueryZEVMGetTransactionReceiptResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{48} + return fileDescriptor_65a992045e92a606, []int{50} } func (m *QueryZEVMGetTransactionReceiptResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2371,7 +2459,7 @@ func (m *Log) Reset() { *m = Log{} } func (m *Log) String() string { return proto.CompactTextString(m) } func (*Log) ProtoMessage() {} func (*Log) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{49} + return fileDescriptor_65a992045e92a606, []int{51} } func (m *Log) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2471,7 +2559,7 @@ func (m *QueryZEVMGetTransactionRequest) Reset() { *m = QueryZEVMGetTran func (m *QueryZEVMGetTransactionRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionRequest) ProtoMessage() {} func (*QueryZEVMGetTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{50} + return fileDescriptor_65a992045e92a606, []int{52} } func (m *QueryZEVMGetTransactionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2531,7 +2619,7 @@ func (m *QueryZEVMGetTransactionResponse) Reset() { *m = QueryZEVMGetTra func (m *QueryZEVMGetTransactionResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionResponse) ProtoMessage() {} func (*QueryZEVMGetTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{51} + return fileDescriptor_65a992045e92a606, []int{53} } func (m *QueryZEVMGetTransactionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2687,7 +2775,7 @@ func (m *QueryZEVMGetBlockByNumberRequest) Reset() { *m = QueryZEVMGetBl func (m *QueryZEVMGetBlockByNumberRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetBlockByNumberRequest) ProtoMessage() {} func (*QueryZEVMGetBlockByNumberRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{52} + return fileDescriptor_65a992045e92a606, []int{54} } func (m *QueryZEVMGetBlockByNumberRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2751,7 +2839,7 @@ func (m *QueryZEVMGetBlockByNumberResponse) Reset() { *m = QueryZEVMGetB func (m *QueryZEVMGetBlockByNumberResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetBlockByNumberResponse) ProtoMessage() {} func (*QueryZEVMGetBlockByNumberResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{53} + return fileDescriptor_65a992045e92a606, []int{55} } func (m *QueryZEVMGetBlockByNumberResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2958,6 +3046,8 @@ func init() { proto.RegisterType((*QueryAllChainNoncesResponse)(nil), "zetachain.zetacore.crosschain.QueryAllChainNoncesResponse") proto.RegisterType((*QueryAllPendingNoncesRequest)(nil), "zetachain.zetacore.crosschain.QueryAllPendingNoncesRequest") proto.RegisterType((*QueryAllPendingNoncesResponse)(nil), "zetachain.zetacore.crosschain.QueryAllPendingNoncesResponse") + proto.RegisterType((*QueryPendingNoncesByChainRequest)(nil), "zetachain.zetacore.crosschain.QueryPendingNoncesByChainRequest") + proto.RegisterType((*QueryPendingNoncesByChainResponse)(nil), "zetachain.zetacore.crosschain.QueryPendingNoncesByChainResponse") proto.RegisterType((*QueryGetLastBlockHeightRequest)(nil), "zetachain.zetacore.crosschain.QueryGetLastBlockHeightRequest") proto.RegisterType((*QueryGetLastBlockHeightResponse)(nil), "zetachain.zetacore.crosschain.QueryGetLastBlockHeightResponse") proto.RegisterType((*QueryAllLastBlockHeightRequest)(nil), "zetachain.zetacore.crosschain.QueryAllLastBlockHeightRequest") @@ -2987,192 +3077,196 @@ func init() { func init() { proto.RegisterFile("crosschain/query.proto", fileDescriptor_65a992045e92a606) } var fileDescriptor_65a992045e92a606 = []byte{ - // 2949 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0x5b, 0x6f, 0x1b, 0xc7, - 0xf5, 0xf7, 0x8a, 0x14, 0x25, 0x8d, 0xae, 0x1e, 0x2b, 0x0e, 0xc3, 0xd8, 0xa2, 0xb3, 0x8e, 0x2f, - 0xf1, 0x85, 0x8c, 0x15, 0xdb, 0x49, 0x6c, 0x27, 0xf8, 0x4b, 0x76, 0xac, 0x18, 0x51, 0x12, 0xfd, - 0x57, 0x4a, 0x5b, 0xb8, 0x68, 0x89, 0xd5, 0x72, 0x4c, 0x2d, 0xb2, 0xe4, 0x32, 0x3b, 0x43, 0x41, - 0x8a, 0xe1, 0x3e, 0xe4, 0x13, 0x04, 0x28, 0xd0, 0xbe, 0xf4, 0xb5, 0x97, 0x87, 0x3e, 0x14, 0x68, - 0xd0, 0x14, 0x28, 0x90, 0x3e, 0xb4, 0x4d, 0xf3, 0x18, 0xa0, 0x40, 0xd1, 0x22, 0x00, 0x51, 0xc4, - 0x7d, 0xe2, 0x37, 0x28, 0xd0, 0x87, 0x62, 0xce, 0x9e, 0xe5, 0xce, 0x92, 0xbb, 0xe2, 0x9a, 0x62, - 0x8b, 0xf6, 0x85, 0x3b, 0x73, 0x66, 0xce, 0x99, 0xdf, 0xb9, 0xcc, 0xcc, 0xd9, 0x3d, 0x24, 0xc7, - 0x2d, 0xcf, 0xe5, 0xdc, 0xda, 0x31, 0xed, 0x46, 0xf9, 0x83, 0x16, 0xf3, 0xf6, 0x4b, 0x4d, 0xcf, - 0x15, 0x2e, 0x3d, 0xf9, 0x21, 0x13, 0x26, 0x90, 0x4b, 0xd0, 0x72, 0x3d, 0x56, 0x0a, 0xa7, 0x16, - 0x2e, 0x58, 0x2e, 0xaf, 0xbb, 0xbc, 0xbc, 0x6d, 0x72, 0xe6, 0xf3, 0x95, 0x77, 0xaf, 0x6c, 0x33, - 0x61, 0x5e, 0x29, 0x37, 0xcd, 0x9a, 0xdd, 0x30, 0x85, 0xed, 0x36, 0x7c, 0x51, 0x85, 0x93, 0xca, - 0x12, 0xf0, 0x5b, 0x69, 0xb8, 0x0d, 0x8b, 0x71, 0x1c, 0x2e, 0xaa, 0xc3, 0xb2, 0x59, 0xf1, 0x27, - 0x89, 0x3d, 0x9c, 0x50, 0x50, 0x26, 0xd4, 0x4c, 0x5e, 0x69, 0x7a, 0xb6, 0xc5, 0x70, 0xec, 0xb4, - 0x32, 0x06, 0x3c, 0x95, 0x1d, 0x93, 0xef, 0x54, 0x84, 0x5b, 0xb1, 0xac, 0xae, 0x00, 0x5d, 0x99, - 0xe4, 0x98, 0x5c, 0x54, 0xb6, 0x1d, 0xd7, 0x7a, 0xbf, 0xb2, 0xc3, 0xec, 0xda, 0x8e, 0xc0, 0x39, - 0x4b, 0xca, 0x1c, 0x80, 0xd7, 0x23, 0x43, 0x45, 0xe9, 0xb6, 0x84, 0x5c, 0x49, 0x78, 0xa6, 0xf5, - 0x3e, 0xf3, 0x70, 0xc2, 0xd3, 0xca, 0x84, 0xa6, 0xe9, 0x99, 0xf5, 0x40, 0xbf, 0x45, 0x65, 0x40, - 0xf0, 0x2e, 0xb5, 0xe6, 0xd6, 0x5c, 0x68, 0x96, 0x65, 0x0b, 0xa9, 0x27, 0x6a, 0xae, 0x5b, 0x73, - 0x58, 0xd9, 0x6c, 0xda, 0x65, 0xb3, 0xd1, 0x70, 0x05, 0xd8, 0x11, 0x79, 0xf4, 0x3c, 0x39, 0xfe, - 0xff, 0xd2, 0xd4, 0x5b, 0x9c, 0xbf, 0x69, 0x73, 0xe1, 0x7a, 0xfb, 0x06, 0xfb, 0xa0, 0xc5, 0xb8, - 0xd0, 0xbf, 0x4b, 0x9e, 0xee, 0x1b, 0xe1, 0x4d, 0xb7, 0xc1, 0x19, 0xbd, 0x4d, 0x26, 0x05, 0xe7, - 0x15, 0xc7, 0xe6, 0x22, 0xaf, 0x9d, 0xca, 0x9c, 0x9f, 0x5e, 0xd6, 0x4b, 0x07, 0xfa, 0xb6, 0xb4, - 0xb5, 0xb9, 0xb9, 0x9a, 0xfd, 0xa2, 0x5d, 0x3c, 0x62, 0x4c, 0x08, 0xce, 0xd7, 0x6d, 0x2e, 0xf4, - 0x45, 0x42, 0x41, 0xfe, 0x06, 0x28, 0x16, 0xac, 0x7a, 0x9f, 0x1c, 0x8b, 0x50, 0xbb, 0x2b, 0xe6, - 0x7c, 0x03, 0xe4, 0xb5, 0x53, 0xda, 0xf9, 0xe9, 0xe5, 0x33, 0x03, 0xd6, 0xf3, 0xd9, 0x71, 0x49, - 0x64, 0xd5, 0xdf, 0x26, 0xcf, 0x82, 0xec, 0x35, 0x26, 0xde, 0x6d, 0x89, 0xad, 0xbd, 0x2d, 0xdf, - 0xd8, 0xb8, 0x34, 0xcd, 0x93, 0x09, 0x60, 0xbe, 0x77, 0x07, 0x16, 0xc9, 0x18, 0x41, 0x97, 0x2e, - 0x92, 0x71, 0xf0, 0x5f, 0x7e, 0xec, 0x94, 0x76, 0x3e, 0x6b, 0xf8, 0x1d, 0xbd, 0x45, 0x4e, 0xc4, - 0x8b, 0x43, 0xcc, 0xef, 0x91, 0x19, 0x57, 0xa1, 0x23, 0xf2, 0x8b, 0x03, 0x90, 0xab, 0xa2, 0x10, - 0x7f, 0x44, 0x8c, 0xce, 0x50, 0x8b, 0x15, 0xc7, 0x89, 0xd3, 0xe2, 0x2e, 0x21, 0xe1, 0x6e, 0xc1, - 0x35, 0xcf, 0x96, 0xfc, 0xad, 0x55, 0x92, 0x5b, 0xab, 0xe4, 0x6f, 0x49, 0xdc, 0x5a, 0xa5, 0x0d, - 0xb3, 0xc6, 0x90, 0xd7, 0x50, 0x38, 0xf5, 0xcf, 0x34, 0x54, 0xaf, 0x6f, 0x9d, 0x44, 0xf5, 0x32, - 0x23, 0x50, 0x8f, 0xae, 0x45, 0xf0, 0x8f, 0x01, 0xfe, 0x73, 0x03, 0xf1, 0xfb, 0x98, 0x22, 0x0a, - 0x7c, 0xa4, 0x11, 0x3d, 0x4e, 0x81, 0xd5, 0xfd, 0xdb, 0x12, 0x49, 0x60, 0xaf, 0x45, 0x32, 0x0e, - 0xc8, 0xd0, 0xe7, 0x7e, 0xa7, 0xc7, 0x8a, 0x63, 0x43, 0x5b, 0xf1, 0x0f, 0x1a, 0x39, 0x7d, 0x20, - 0x88, 0xff, 0x11, 0x63, 0xde, 0x24, 0x27, 0x83, 0x58, 0xbf, 0xd7, 0xd8, 0xda, 0x7b, 0xd3, 0xe4, - 0x3b, 0x5b, 0xee, 0x6d, 0x4b, 0xec, 0x05, 0x66, 0x2c, 0x90, 0x49, 0x1b, 0x07, 0xc0, 0x92, 0x53, - 0x46, 0xb7, 0xaf, 0x3f, 0x22, 0x4b, 0x49, 0xcc, 0xa8, 0xfe, 0xb7, 0xc9, 0x9c, 0x1d, 0x19, 0xc1, - 0xc0, 0xbd, 0x3c, 0xc0, 0x00, 0x51, 0x71, 0x68, 0x82, 0x1e, 0x51, 0xfa, 0x2d, 0x5c, 0x3e, 0x3a, - 0xf9, 0x8e, 0x29, 0xcc, 0x34, 0xe0, 0x3f, 0x24, 0xc5, 0x44, 0x6e, 0x44, 0xff, 0x4d, 0x32, 0x7b, - 0x5b, 0x62, 0x02, 0x97, 0x6e, 0xed, 0xf1, 0x94, 0xde, 0x53, 0x79, 0x10, 0x7a, 0x54, 0x8e, 0x5e, - 0x43, 0xab, 0xaf, 0x38, 0x4e, 0xbc, 0xd5, 0x47, 0xb5, 0xd9, 0x3f, 0xd7, 0xd0, 0x46, 0x31, 0x2b, - 0x1d, 0xe0, 0xa2, 0xcc, 0x88, 0x5c, 0x34, 0xba, 0x38, 0x7d, 0x96, 0x3c, 0x13, 0x84, 0xda, 0x16, - 0xe7, 0x2b, 0xd5, 0xaa, 0xc7, 0x78, 0xf7, 0x6e, 0xf9, 0x3f, 0x52, 0x88, 0x1b, 0x44, 0x05, 0x17, - 0x48, 0x86, 0x89, 0xc0, 0xff, 0xb2, 0x29, 0x29, 0xdb, 0xc2, 0x02, 0x38, 0x53, 0x86, 0x6c, 0x76, - 0xef, 0x2c, 0x29, 0x61, 0x73, 0x33, 0x90, 0xfb, 0x16, 0xde, 0x59, 0x01, 0x15, 0x05, 0x5e, 0x25, - 0x99, 0xad, 0xcd, 0x4d, 0xf4, 0x4a, 0x8a, 0x0b, 0xd2, 0x90, 0xd3, 0xf5, 0x32, 0x5e, 0xbb, 0x6b, - 0x4c, 0xac, 0x99, 0x7c, 0x43, 0xe6, 0x25, 0xca, 0x51, 0x65, 0x37, 0xaa, 0x6c, 0x0f, 0x31, 0xfa, - 0x1d, 0xbd, 0x42, 0xf2, 0xfd, 0x0c, 0xe1, 0x45, 0x1d, 0xd0, 0x10, 0xc7, 0xb9, 0x01, 0x38, 0xba, - 0x22, 0xba, 0x8c, 0xba, 0x89, 0x88, 0x56, 0x1c, 0xa7, 0x17, 0xd1, 0xa8, 0xe2, 0xef, 0x67, 0x1a, - 0x2a, 0x11, 0x59, 0x23, 0x56, 0x89, 0xcc, 0x50, 0x4a, 0x8c, 0x2e, 0xc2, 0x96, 0xc3, 0x20, 0x82, - 0x7d, 0xfa, 0x0e, 0xe4, 0x9d, 0x07, 0xbb, 0xe8, 0xfd, 0x30, 0xf1, 0x88, 0xf0, 0xa0, 0x82, 0xeb, - 0x64, 0x5a, 0x21, 0xa3, 0x19, 0x2f, 0x0c, 0x3a, 0x3d, 0x14, 0x41, 0x2a, 0xbb, 0x5e, 0x45, 0x80, - 0x2b, 0x8e, 0x13, 0x03, 0x70, 0x54, 0x1e, 0xfb, 0x44, 0x0b, 0xd3, 0x90, 0x54, 0x3a, 0x65, 0x0e, - 0xa1, 0xd3, 0xe8, 0xbc, 0xb7, 0x14, 0x26, 0x35, 0x1b, 0xac, 0x51, 0xb5, 0x1b, 0xb5, 0x88, 0x79, - 0x74, 0x11, 0x9e, 0xb8, 0x3d, 0xe3, 0xa8, 0xd7, 0x26, 0x99, 0x6b, 0xfa, 0x03, 0xf8, 0xc6, 0x81, - 0xaa, 0x5d, 0x1a, 0x94, 0x90, 0x46, 0xa4, 0xcd, 0x36, 0xd5, 0xae, 0x7e, 0x3d, 0xbc, 0x20, 0xd7, - 0x4d, 0x2e, 0x56, 0xe5, 0xab, 0xc4, 0x9b, 0xf0, 0x26, 0x71, 0x70, 0x5c, 0x3d, 0xc4, 0xbb, 0x29, - 0x8e, 0x0f, 0xf1, 0x7e, 0x8b, 0xcc, 0xf7, 0x0c, 0xa1, 0xd3, 0x4b, 0x03, 0x00, 0xf7, 0x0a, 0xec, - 0x15, 0xa3, 0xef, 0x84, 0x57, 0x46, 0x02, 0xe8, 0x51, 0xc5, 0xda, 0xef, 0x35, 0xd4, 0x33, 0x6e, - 0xa9, 0x83, 0xf4, 0xcc, 0x8c, 0x40, 0xcf, 0xd1, 0xc5, 0xde, 0xc5, 0xf0, 0x9a, 0x50, 0xef, 0xf0, - 0x78, 0xd7, 0xae, 0x2b, 0xc7, 0x8c, 0xbc, 0x37, 0xf7, 0x21, 0x54, 0x86, 0x7d, 0x55, 0xa9, 0x91, - 0xc5, 0xe8, 0xd2, 0x68, 0xb5, 0x77, 0xc9, 0x8c, 0x9a, 0x71, 0xa4, 0x7c, 0x45, 0x51, 0x59, 0x8c, - 0x88, 0x00, 0xfd, 0x3b, 0xa8, 0xa3, 0x3c, 0x15, 0xfe, 0x0d, 0x79, 0xca, 0x2f, 0x34, 0x54, 0xa4, - 0x2b, 0x3f, 0x51, 0x91, 0xcc, 0xa1, 0x14, 0x19, 0x9d, 0xd7, 0xbf, 0xa7, 0x1c, 0xc7, 0x96, 0xd8, - 0xc3, 0x73, 0xa0, 0xcf, 0x91, 0x55, 0xb0, 0x4a, 0x36, 0x70, 0x64, 0x75, 0x64, 0x6f, 0x20, 0x9f, - 0xaa, 0x07, 0xb5, 0x0a, 0xe0, 0xbf, 0xde, 0x72, 0x27, 0xd0, 0x72, 0x72, 0x43, 0xde, 0x67, 0xc2, - 0x8c, 0x1c, 0x2e, 0xfa, 0x35, 0x54, 0xab, 0x77, 0x14, 0xd5, 0x3a, 0x4e, 0x72, 0xca, 0x71, 0x97, - 0x31, 0xb0, 0xa7, 0x6f, 0xe1, 0x05, 0x70, 0xdb, 0x6d, 0xec, 0x32, 0x4f, 0x66, 0x4c, 0x5b, 0xae, - 0x64, 0x4f, 0x70, 0x48, 0x26, 0x74, 0x48, 0x81, 0x4c, 0xd6, 0x4c, 0xbe, 0x6e, 0xd7, 0x6d, 0x81, - 0x29, 0x61, 0xb7, 0xaf, 0xff, 0x58, 0xc3, 0x7b, 0xa3, 0x5f, 0x2c, 0xe2, 0xb9, 0x44, 0x8e, 0xba, - 0x2d, 0xb1, 0xed, 0xb6, 0x1a, 0xd5, 0x35, 0x93, 0xdf, 0x6b, 0xc8, 0x41, 0xdc, 0xf1, 0xfd, 0x03, - 0x72, 0x36, 0x7c, 0x9e, 0xb1, 0x5c, 0xe7, 0x2e, 0x63, 0x38, 0xdb, 0x5f, 0xb4, 0x7f, 0x80, 0x9e, - 0x27, 0xf3, 0xf2, 0xa9, 0x9e, 0x7d, 0x19, 0x08, 0xa6, 0x5e, 0xb2, 0x7e, 0x8e, 0x9c, 0x01, 0x98, - 0x6f, 0x33, 0xce, 0xcd, 0x1a, 0xdb, 0x30, 0x39, 0xb7, 0x1b, 0xb5, 0x8d, 0x50, 0x62, 0x60, 0xdd, - 0xbb, 0xe4, 0xec, 0xa0, 0x89, 0xa8, 0xd8, 0x09, 0x32, 0xf5, 0xa0, 0x0b, 0xd1, 0x57, 0x28, 0x24, - 0xe8, 0x37, 0x71, 0xc1, 0xfb, 0x6f, 0x7c, 0xe3, 0x6d, 0x99, 0x1e, 0x7b, 0x66, 0x83, 0x9b, 0x96, - 0x74, 0xaf, 0xc1, 0x2c, 0x66, 0x37, 0xbb, 0x77, 0x05, 0x25, 0xd9, 0x9d, 0xf0, 0xf5, 0x0b, 0xda, - 0xfa, 0x3f, 0xb3, 0x88, 0xe2, 0x00, 0xee, 0xae, 0x79, 0x09, 0x7e, 0x80, 0xeb, 0x0a, 0x59, 0x9d, - 0xed, 0xb4, 0x8b, 0x53, 0x40, 0x95, 0x6f, 0x1a, 0x46, 0xd8, 0xa4, 0xcb, 0x64, 0xc6, 0x9f, 0xdd, - 0x68, 0xd5, 0xb7, 0x99, 0xe7, 0x5b, 0x76, 0x75, 0xbe, 0xd3, 0x2e, 0x4e, 0x03, 0xfd, 0x1d, 0x20, - 0x1b, 0x6a, 0x87, 0xbe, 0x4e, 0x16, 0x2c, 0xb7, 0x21, 0x3c, 0xd3, 0x12, 0x15, 0xd3, 0x7f, 0x75, - 0x00, 0x2b, 0x4f, 0xad, 0x1e, 0xeb, 0xb4, 0x8b, 0xf3, 0xc1, 0x58, 0xf0, 0x56, 0xd1, 0x4b, 0xa0, - 0x6f, 0x90, 0x63, 0x56, 0xab, 0xde, 0x72, 0x4c, 0x61, 0xef, 0xb2, 0x4a, 0xcd, 0xe4, 0x95, 0x16, - 0x67, 0xd5, 0x7c, 0x16, 0x44, 0x3c, 0xd5, 0x69, 0x17, 0x8f, 0x86, 0xc3, 0x6b, 0x26, 0x7f, 0x8f, - 0xb3, 0xaa, 0xd1, 0x4f, 0xa2, 0x27, 0x48, 0xf6, 0x81, 0xe7, 0xd6, 0xf3, 0xe3, 0xc0, 0x37, 0xd9, - 0x69, 0x17, 0xa1, 0x6f, 0xc0, 0x2f, 0x3d, 0x0b, 0x31, 0xea, 0x4b, 0xce, 0xc1, 0x8c, 0xe9, 0x4e, - 0xbb, 0x38, 0x51, 0x43, 0x79, 0x41, 0x43, 0x9a, 0xcb, 0x71, 0x6b, 0xbc, 0xb2, 0xed, 0xb8, 0x6e, - 0x3d, 0x3f, 0x11, 0x9a, 0x4b, 0x52, 0x57, 0x25, 0xd1, 0x08, 0x9b, 0x54, 0x27, 0x39, 0x2e, 0x4c, - 0xd1, 0xe2, 0xf9, 0x49, 0x98, 0x49, 0x3a, 0xed, 0x22, 0x52, 0x0c, 0x7c, 0xd2, 0xe3, 0x64, 0x4c, - 0xb8, 0xf9, 0x29, 0x18, 0xcf, 0x75, 0xda, 0xc5, 0x31, 0xe1, 0x1a, 0x63, 0xc2, 0x95, 0x66, 0x13, - 0xa1, 0xdb, 0x7c, 0xf7, 0x90, 0xd0, 0x6c, 0xca, 0x18, 0x38, 0xa9, 0x97, 0x40, 0x57, 0xc8, 0x51, - 0x95, 0xdf, 0xbf, 0x29, 0xa7, 0x41, 0xc0, 0x62, 0xa7, 0x5d, 0x54, 0x85, 0xdf, 0x93, 0x63, 0x46, - 0x1f, 0x85, 0x5e, 0x27, 0x59, 0xa9, 0x4b, 0x7e, 0x26, 0xd5, 0x97, 0xca, 0x75, 0xb7, 0x66, 0xc0, - 0x7c, 0xfd, 0xa3, 0x0c, 0xc9, 0xac, 0xbb, 0x35, 0x79, 0x24, 0x04, 0x0e, 0xf7, 0xa3, 0x33, 0xe8, - 0xca, 0x43, 0x46, 0xb8, 0x4d, 0xdb, 0xe2, 0xf9, 0xb1, 0x53, 0x99, 0xf3, 0x53, 0x06, 0xf6, 0x64, - 0x30, 0x57, 0x4d, 0x61, 0xfa, 0xf1, 0x61, 0x40, 0xbb, 0x2f, 0xe6, 0xa4, 0xe3, 0xb3, 0x83, 0x63, - 0xae, 0xcf, 0x78, 0xe3, 0x87, 0x35, 0x5e, 0x0e, 0x16, 0x4e, 0x6b, 0xbc, 0xe8, 0xc6, 0x9a, 0x18, - 0xb0, 0xb1, 0x5e, 0x20, 0x32, 0x6c, 0x70, 0xa1, 0x49, 0x58, 0x68, 0xa6, 0xd3, 0x2e, 0x4e, 0x3a, - 0x6e, 0xcd, 0x5f, 0xa0, 0xdb, 0xa2, 0x67, 0xc8, 0x84, 0xc7, 0xea, 0xee, 0x2e, 0xab, 0x42, 0xd4, - 0x4c, 0xfa, 0x91, 0x8a, 0x24, 0x23, 0x68, 0xe8, 0x57, 0x31, 0xcb, 0x8c, 0x3b, 0x02, 0x92, 0x4f, - 0x8e, 0x7f, 0x64, 0x31, 0x63, 0x8c, 0x63, 0xfb, 0x8f, 0x1d, 0x19, 0xc1, 0x5e, 0xcd, 0xc4, 0xee, - 0xd5, 0x67, 0x48, 0xa6, 0x66, 0x72, 0x3c, 0x00, 0x26, 0x3a, 0xed, 0xa2, 0xec, 0x1a, 0xf2, 0x47, - 0x9a, 0xb1, 0x5b, 0x94, 0x40, 0x87, 0x83, 0x19, 0x6b, 0xdd, 0xf7, 0xda, 0xa0, 0x25, 0xd7, 0x00, - 0xfc, 0xb9, 0x70, 0x0d, 0xd9, 0xf7, 0xed, 0x40, 0x8b, 0x32, 0xb7, 0x6c, 0xb6, 0x04, 0x3a, 0x6e, - 0xaa, 0xd3, 0x2e, 0xfa, 0x04, 0xc3, 0x7f, 0xc8, 0x09, 0x7e, 0xba, 0x38, 0x19, 0x4e, 0x00, 0x02, - 0x66, 0x8e, 0x89, 0xfb, 0x3a, 0x36, 0xb4, 0xc8, 0x13, 0xed, 0xcb, 0x22, 0x19, 0xdf, 0x35, 0x9d, - 0x16, 0xc3, 0xed, 0x0c, 0x6b, 0x03, 0xc1, 0xf0, 0x1f, 0x52, 0x37, 0xb1, 0xdf, 0x64, 0xf9, 0x99, - 0x50, 0x37, 0xd9, 0x37, 0xe0, 0x97, 0x96, 0xc9, 0xb4, 0x69, 0x59, 0x2c, 0xa8, 0x43, 0xcc, 0xca, - 0x1d, 0xb8, 0x3a, 0xd7, 0x69, 0x17, 0x89, 0x4f, 0x5e, 0xb7, 0x65, 0x26, 0x14, 0xb6, 0xe5, 0xe1, - 0xe8, 0x57, 0x81, 0xec, 0x6a, 0x7e, 0x2e, 0x3c, 0x1c, 0xf1, 0x7e, 0x0f, 0x2f, 0xfa, 0x63, 0x44, - 0xdb, 0xcd, 0xcf, 0xc3, 0x84, 0xf1, 0x4e, 0xbb, 0xa8, 0xed, 0x1a, 0xda, 0xae, 0x24, 0x7a, 0xf9, - 0x85, 0x90, 0xe8, 0x19, 0x9a, 0x27, 0x89, 0x3c, 0x7f, 0x34, 0x24, 0x72, 0x43, 0xe3, 0xfa, 0x0d, - 0x72, 0x4a, 0x0d, 0x3d, 0xb8, 0x7e, 0x57, 0xf7, 0x31, 0x3e, 0x30, 0x66, 0x8f, 0x93, 0xdc, 0x4e, - 0x98, 0x9d, 0x64, 0x0d, 0xec, 0xe9, 0x7f, 0x9d, 0x20, 0xcf, 0x1d, 0xc0, 0x8c, 0x91, 0xab, 0x93, - 0x1c, 0x46, 0xa1, 0x16, 0x9e, 0xc7, 0x3e, 0xc5, 0xc0, 0x67, 0x37, 0x2e, 0xc6, 0x62, 0xe3, 0xa2, - 0x4c, 0xa6, 0x9b, 0xa6, 0xc7, 0x1a, 0xc2, 0x0f, 0x7e, 0x3f, 0x40, 0xc1, 0x76, 0x3e, 0x19, 0xa2, - 0x5f, 0x69, 0x87, 0x71, 0x92, 0x4d, 0x88, 0x93, 0x32, 0x99, 0xe6, 0x3b, 0xe6, 0x4b, 0x95, 0x56, - 0xc3, 0x72, 0x18, 0xc7, 0xa0, 0x05, 0x89, 0x92, 0xfc, 0x1e, 0x50, 0x0d, 0xa5, 0xdd, 0x73, 0x05, - 0xe5, 0x06, 0x5c, 0x41, 0xd1, 0x70, 0xe3, 0x15, 0xcf, 0x75, 0x83, 0xa0, 0xee, 0x0d, 0x37, 0x6e, - 0xb8, 0xae, 0x30, 0xfa, 0x28, 0x72, 0x41, 0x79, 0x57, 0x31, 0x9f, 0x77, 0x32, 0x5c, 0x10, 0xa8, - 0xc0, 0x14, 0x36, 0xe9, 0x35, 0x32, 0xeb, 0xf9, 0x39, 0x06, 0x2e, 0xe6, 0x6f, 0x81, 0x85, 0x4e, - 0xbb, 0x38, 0x13, 0x0c, 0x00, 0x4f, 0xa4, 0x27, 0xed, 0x54, 0xb7, 0x1b, 0xcc, 0xc3, 0xad, 0x00, - 0x76, 0x02, 0x82, 0xe1, 0x3f, 0x68, 0x89, 0x90, 0xaa, 0xfd, 0xe0, 0x81, 0x6d, 0xb5, 0x1c, 0xb1, - 0x8f, 0x91, 0x0f, 0x66, 0x0a, 0xa9, 0x86, 0xd2, 0x86, 0x2b, 0xc0, 0x15, 0xa6, 0x53, 0x51, 0xb8, - 0x66, 0x94, 0x2b, 0x40, 0x8e, 0xdd, 0x09, 0x59, 0x7b, 0x09, 0x52, 0x6b, 0xb6, 0x27, 0x3c, 0xb3, - 0x02, 0x17, 0xd2, 0x6c, 0xa8, 0x35, 0x50, 0xe1, 0x33, 0x76, 0xd8, 0x94, 0x51, 0xc3, 0xed, 0x0f, - 0x19, 0x6e, 0x0f, 0x88, 0x1a, 0xd9, 0x37, 0xe0, 0x37, 0x38, 0x96, 0x1c, 0x48, 0x81, 0xe7, 0x23, - 0xc7, 0x12, 0xa4, 0xc1, 0x61, 0x42, 0x1c, 0x49, 0x44, 0x16, 0x0e, 0x48, 0x44, 0x2e, 0x92, 0x29, - 0x61, 0xd7, 0x19, 0x17, 0x66, 0xbd, 0x89, 0x3b, 0x09, 0xd0, 0x75, 0x89, 0x46, 0xd8, 0xa4, 0x57, - 0xc9, 0x8c, 0xea, 0xd5, 0x3c, 0x85, 0x2d, 0x0f, 0x2e, 0x89, 0x78, 0x3b, 0xd2, 0x93, 0xbb, 0x05, - 0x83, 0xf2, 0x18, 0xcc, 0x87, 0xdd, 0xe2, 0x53, 0x0c, 0x7c, 0xd2, 0x1b, 0x64, 0x41, 0xbe, 0x99, - 0x54, 0x1e, 0x30, 0x56, 0x69, 0x32, 0x4f, 0xa6, 0x67, 0xf9, 0x45, 0x40, 0x73, 0xb4, 0xd3, 0x2e, - 0xce, 0xca, 0xb1, 0xbb, 0x8c, 0x6d, 0x30, 0x6f, 0xcd, 0xe4, 0x46, 0xb4, 0x2b, 0x55, 0xad, 0xdb, - 0x7e, 0x8d, 0x38, 0xff, 0x54, 0xa8, 0x6a, 0xdd, 0x86, 0x0f, 0xdc, 0x46, 0xd0, 0x58, 0xfe, 0x4a, - 0x27, 0xe3, 0xb0, 0xb7, 0xe9, 0x0f, 0x34, 0x92, 0xf3, 0x0b, 0x94, 0xf4, 0xca, 0x80, 0x6c, 0xa4, - 0xbf, 0x42, 0x5a, 0x58, 0x7e, 0x12, 0x16, 0xff, 0xc4, 0xd0, 0xcf, 0x7c, 0xf4, 0xa7, 0xbf, 0x7f, - 0x7f, 0xac, 0x48, 0x4f, 0x96, 0x25, 0xc7, 0x65, 0xa5, 0x30, 0xae, 0x16, 0x97, 0xe9, 0xe7, 0x1a, - 0x99, 0x51, 0x6b, 0x4a, 0xf4, 0x46, 0x9a, 0xb5, 0xe2, 0xcb, 0xa9, 0x85, 0x9b, 0x43, 0xf1, 0x22, - 0xe0, 0xd7, 0x00, 0xf0, 0xcb, 0xf4, 0x5a, 0x02, 0x60, 0xb5, 0xca, 0x55, 0x7e, 0x88, 0x1f, 0x3f, - 0x1e, 0x95, 0x1f, 0xc2, 0x61, 0xf4, 0x88, 0x7e, 0xaa, 0x91, 0x79, 0x55, 0xee, 0x8a, 0xe3, 0xa4, - 0xd3, 0x25, 0xbe, 0xa8, 0x9a, 0x4e, 0x97, 0x84, 0x42, 0xa9, 0x7e, 0x11, 0x74, 0x39, 0x43, 0x4f, - 0xa7, 0xd0, 0x85, 0x7e, 0xa5, 0x91, 0xe3, 0x3d, 0xc8, 0xb1, 0x56, 0x48, 0x57, 0x86, 0x00, 0x11, - 0x2d, 0x76, 0x16, 0x56, 0x0f, 0x23, 0x02, 0xd5, 0xb9, 0x01, 0xea, 0x5c, 0xa5, 0xcb, 0x29, 0xd4, - 0x41, 0x5e, 0xf4, 0xd0, 0x23, 0xfa, 0x47, 0x8d, 0xcc, 0x45, 0x0b, 0x42, 0xf4, 0x56, 0xca, 0x30, - 0x89, 0x2d, 0x80, 0x15, 0x5e, 0x1b, 0x92, 0x1b, 0x75, 0x79, 0x05, 0x74, 0x59, 0xa6, 0x2f, 0x26, - 0xe8, 0x12, 0x2d, 0x53, 0x95, 0x1f, 0x06, 0xfd, 0x47, 0xf4, 0xcf, 0x1a, 0xa1, 0xfd, 0x25, 0x41, - 0x9a, 0x0a, 0x4f, 0x62, 0x21, 0xb2, 0xf0, 0xfa, 0xb0, 0xec, 0xa8, 0xcf, 0x0a, 0xe8, 0x73, 0x93, - 0xbe, 0x9a, 0xa8, 0x4f, 0xef, 0xdf, 0x59, 0xe0, 0x5e, 0x50, 0x15, 0xfb, 0xad, 0x46, 0x8e, 0x46, - 0x57, 0x90, 0x9b, 0xe7, 0x56, 0xca, 0xc0, 0x39, 0x84, 0x97, 0x12, 0x4b, 0x8f, 0xfa, 0x65, 0xd0, - 0xea, 0x1c, 0x3d, 0x93, 0xca, 0x4b, 0xf4, 0x13, 0x8d, 0xcc, 0x46, 0x4a, 0x7c, 0xf4, 0x95, 0x94, - 0x51, 0xd2, 0x57, 0x32, 0x2c, 0xbc, 0x3a, 0x04, 0x27, 0xa2, 0x2e, 0x01, 0xea, 0xf3, 0xf4, 0x6c, - 0x02, 0xea, 0x1a, 0x13, 0x15, 0xc1, 0x79, 0xf0, 0x31, 0x81, 0x7e, 0xac, 0x41, 0xbd, 0x30, 0xdd, - 0x95, 0x10, 0x29, 0x40, 0xa6, 0xbb, 0x12, 0xa2, 0xd5, 0x49, 0x5d, 0x07, 0x78, 0x27, 0x68, 0x21, - 0x01, 0x9e, 0x84, 0xf2, 0x73, 0x2d, 0x2c, 0xbd, 0xd1, 0xeb, 0x29, 0x17, 0xe9, 0xa9, 0x11, 0x16, - 0x5e, 0x7e, 0x62, 0x3e, 0x44, 0x58, 0x06, 0x84, 0x2f, 0xd0, 0x73, 0x49, 0x06, 0x44, 0x06, 0x19, - 0xbd, 0x55, 0xb6, 0xf7, 0x88, 0xfe, 0x54, 0x23, 0xd3, 0x81, 0x14, 0x19, 0xb4, 0xd7, 0x53, 0x86, - 0xdd, 0x50, 0x88, 0x63, 0x2a, 0x95, 0xfa, 0x39, 0x40, 0xfc, 0x1c, 0x2d, 0x0e, 0x40, 0x4c, 0x3f, - 0xd3, 0xc8, 0x42, 0xef, 0xa7, 0x42, 0x9a, 0xea, 0x92, 0x49, 0xf8, 0x6e, 0x59, 0xb8, 0x35, 0x1c, - 0x73, 0x4a, 0x53, 0x5b, 0xbd, 0x58, 0x3f, 0xd7, 0xc8, 0xb4, 0xf2, 0x35, 0x90, 0xde, 0x49, 0xb3, - 0xfc, 0xa0, 0xaf, 0x8e, 0x85, 0x37, 0x0e, 0x29, 0x05, 0xb5, 0xb9, 0x00, 0xda, 0x3c, 0x4f, 0xf5, - 0xa4, 0x6c, 0x47, 0x01, 0xfe, 0x6b, 0x2d, 0x52, 0xa8, 0xa4, 0x69, 0x37, 0x7c, 0x7f, 0x69, 0xb5, - 0x70, 0x63, 0x18, 0x56, 0x84, 0xbc, 0x0c, 0x90, 0x2f, 0xd1, 0x0b, 0x49, 0x0e, 0x08, 0x79, 0xba, - 0xe1, 0xfe, 0x4b, 0x8d, 0xcc, 0x29, 0xb2, 0x64, 0xc4, 0xbf, 0x9a, 0x32, 0x72, 0x87, 0x45, 0x1f, - 0x5f, 0xec, 0x1d, 0x68, 0x70, 0x05, 0x3d, 0xfd, 0x8d, 0x46, 0x16, 0x22, 0xc5, 0x50, 0x89, 0x3b, - 0x6d, 0x7e, 0x15, 0x57, 0xb3, 0x2d, 0xdc, 0x1a, 0x8e, 0x19, 0xb1, 0x5f, 0x02, 0xec, 0x67, 0xe9, - 0xf3, 0x49, 0xc1, 0xa2, 0x72, 0xd1, 0x2f, 0xb4, 0xbe, 0x3a, 0x23, 0x4d, 0x9b, 0x83, 0xc4, 0x57, - 0x49, 0xd3, 0xdd, 0xf9, 0xc9, 0x15, 0x5e, 0xfd, 0x3a, 0x28, 0xf0, 0x22, 0x2d, 0x25, 0x28, 0xe0, - 0x44, 0xf9, 0xba, 0xe1, 0xf3, 0x3b, 0x8d, 0xd0, 0x1e, 0x99, 0xd2, 0x15, 0x69, 0xef, 0xea, 0xc3, - 0x68, 0x93, 0x5c, 0xc7, 0x1d, 0x78, 0x6b, 0xf6, 0x68, 0x43, 0x7f, 0xa4, 0x91, 0x2c, 0xdc, 0xfa, - 0x69, 0xef, 0x40, 0x35, 0x2f, 0x79, 0xe9, 0x89, 0x78, 0x52, 0xa6, 0xf3, 0x16, 0x66, 0x8a, 0x60, - 0xe4, 0x4f, 0xe4, 0xf1, 0x12, 0xd6, 0x6f, 0xd3, 0x1f, 0x2f, 0x7d, 0x35, 0xdf, 0xe1, 0xc0, 0x5e, - 0x03, 0xb0, 0x65, 0x7a, 0xf9, 0x40, 0xb0, 0x7d, 0xef, 0x4f, 0x3f, 0xd4, 0xc8, 0x44, 0x90, 0xfa, - 0x2d, 0xa7, 0x3d, 0x18, 0x9e, 0xd4, 0xb0, 0x3d, 0x35, 0x5c, 0xfd, 0x34, 0x60, 0x3d, 0x49, 0x9f, - 0x3d, 0x00, 0xab, 0x7f, 0xe8, 0xf9, 0xc8, 0x70, 0x3f, 0xa7, 0x3f, 0xf4, 0xfa, 0xca, 0xaf, 0xe9, - 0x0f, 0xbd, 0xfe, 0xc2, 0xe9, 0xe0, 0x43, 0x2f, 0xe4, 0xa1, 0xbf, 0xd2, 0xc8, 0x5c, 0xb4, 0x50, - 0x99, 0x0e, 0x75, 0x6c, 0xe9, 0x33, 0x1d, 0xea, 0xf8, 0xba, 0xe8, 0xc0, 0x5c, 0xda, 0x89, 0xa2, - 0xfc, 0x89, 0x46, 0x48, 0xf8, 0x07, 0x70, 0x7a, 0x2d, 0xcd, 0xca, 0x7d, 0x7f, 0x25, 0x2f, 0x5c, - 0x7f, 0x52, 0x36, 0x04, 0xfb, 0x02, 0x80, 0x3d, 0x4d, 0x9f, 0x4b, 0x00, 0x2b, 0xba, 0x2c, 0xab, - 0x6f, 0x7d, 0xf1, 0xf5, 0x92, 0xf6, 0xe5, 0xd7, 0x4b, 0xda, 0xdf, 0xbe, 0x5e, 0xd2, 0x3e, 0x7e, - 0xbc, 0x74, 0xe4, 0xcb, 0xc7, 0x4b, 0x47, 0xfe, 0xf2, 0x78, 0xe9, 0xc8, 0xfd, 0x2b, 0x35, 0x5b, - 0xec, 0xb4, 0xb6, 0x4b, 0x96, 0x5b, 0x57, 0xc5, 0x04, 0x38, 0xca, 0x7b, 0x11, 0x89, 0xfb, 0x4d, - 0xc6, 0xb7, 0x73, 0x90, 0x21, 0xbc, 0xf4, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0xbe, 0xfc, - 0x57, 0xc9, 0x30, 0x00, 0x00, + // 3021 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xf7, 0x8a, 0xb4, 0x3e, 0x46, 0x9f, 0x1e, 0x2b, 0x0e, 0xc3, 0xd8, 0xa2, 0xb3, 0x8e, 0x3f, + 0xe2, 0x0f, 0x32, 0x56, 0x6c, 0x27, 0xb1, 0x9d, 0x34, 0x92, 0x1d, 0x2b, 0x46, 0x94, 0x44, 0x5d, + 0x29, 0xfd, 0x70, 0xd1, 0x12, 0xab, 0xe5, 0x98, 0x5a, 0x64, 0xc9, 0x65, 0x76, 0x86, 0x82, 0x14, + 0x43, 0x39, 0xe4, 0x2f, 0x08, 0x50, 0xa0, 0xbd, 0xf4, 0xda, 0x8f, 0x43, 0x0f, 0x01, 0x1a, 0x34, + 0x05, 0x0a, 0xa4, 0x87, 0xb6, 0x69, 0x8e, 0x41, 0x0b, 0x14, 0x2d, 0x0a, 0x10, 0x45, 0xd2, 0x13, + 0xff, 0x83, 0x02, 0x3d, 0x14, 0xf3, 0xf6, 0x2d, 0x77, 0x96, 0xdc, 0x15, 0x57, 0x14, 0x5b, 0xb4, + 0x17, 0x71, 0xe6, 0xcd, 0xbc, 0x37, 0xbf, 0xf7, 0x31, 0x33, 0x6f, 0xf6, 0x89, 0x9c, 0xb0, 0x3c, + 0x97, 0x73, 0x6b, 0xcb, 0xb4, 0xeb, 0xa5, 0x77, 0x9b, 0xcc, 0xdb, 0x2d, 0x36, 0x3c, 0x57, 0xb8, + 0xf4, 0xd4, 0x7b, 0x4c, 0x98, 0x40, 0x2e, 0x42, 0xcb, 0xf5, 0x58, 0x31, 0x9c, 0x9a, 0xbf, 0x68, + 0xb9, 0xbc, 0xe6, 0xf2, 0xd2, 0xa6, 0xc9, 0x99, 0xcf, 0x57, 0xda, 0xbe, 0xba, 0xc9, 0x84, 0x79, + 0xb5, 0xd4, 0x30, 0xab, 0x76, 0xdd, 0x14, 0xb6, 0x5b, 0xf7, 0x45, 0xe5, 0x4f, 0x29, 0x4b, 0xc0, + 0xdf, 0x72, 0xdd, 0xad, 0x5b, 0x8c, 0xe3, 0x70, 0x41, 0x1d, 0x96, 0xcd, 0xb2, 0x3f, 0x49, 0xec, + 0xe0, 0x84, 0xbc, 0x32, 0xa1, 0x6a, 0xf2, 0x72, 0xc3, 0xb3, 0x2d, 0x86, 0x63, 0x67, 0x94, 0x31, + 0xe0, 0x29, 0x6f, 0x99, 0x7c, 0xab, 0x2c, 0xdc, 0xb2, 0x65, 0x75, 0x04, 0xe8, 0xca, 0x24, 0xc7, + 0xe4, 0xa2, 0xbc, 0xe9, 0xb8, 0xd6, 0x3b, 0xe5, 0x2d, 0x66, 0x57, 0xb7, 0x04, 0xce, 0x59, 0x50, + 0xe6, 0x00, 0xbc, 0x2e, 0x19, 0x2a, 0x4a, 0xb7, 0x29, 0xe4, 0x4a, 0xc2, 0x33, 0xad, 0x77, 0x98, + 0x87, 0x13, 0x1e, 0x57, 0x26, 0x34, 0x4c, 0xcf, 0xac, 0x05, 0xfa, 0xcd, 0x2b, 0x03, 0x82, 0x77, + 0xa8, 0x55, 0xb7, 0xea, 0x42, 0xb3, 0x24, 0x5b, 0x48, 0x3d, 0x59, 0x75, 0xdd, 0xaa, 0xc3, 0x4a, + 0x66, 0xc3, 0x2e, 0x99, 0xf5, 0xba, 0x2b, 0xc0, 0x8e, 0xc8, 0xa3, 0xe7, 0xc8, 0x89, 0xaf, 0x4b, + 0x53, 0x6f, 0x70, 0xfe, 0x9a, 0xcd, 0x85, 0xeb, 0xed, 0x1a, 0xec, 0xdd, 0x26, 0xe3, 0x42, 0xff, + 0x1e, 0x79, 0xbc, 0x67, 0x84, 0x37, 0xdc, 0x3a, 0x67, 0xf4, 0x0e, 0x19, 0x17, 0x9c, 0x97, 0x1d, + 0x9b, 0x8b, 0x9c, 0x76, 0x3a, 0x73, 0x61, 0x72, 0x51, 0x2f, 0xee, 0xeb, 0xdb, 0xe2, 0xc6, 0xfa, + 0xfa, 0x72, 0xf6, 0xf3, 0x56, 0xe1, 0x88, 0x31, 0x26, 0x38, 0x5f, 0xb5, 0xb9, 0xd0, 0xe7, 0x09, + 0x05, 0xf9, 0x6b, 0xa0, 0x58, 0xb0, 0xea, 0x03, 0x72, 0x3c, 0x42, 0xed, 0xac, 0x38, 0xea, 0x1b, + 0x20, 0xa7, 0x9d, 0xd6, 0x2e, 0x4c, 0x2e, 0x9e, 0xed, 0xb3, 0x9e, 0xcf, 0x8e, 0x4b, 0x22, 0xab, + 0xfe, 0x06, 0x79, 0x12, 0x64, 0xaf, 0x30, 0xf1, 0x56, 0x53, 0x6c, 0xec, 0x6c, 0xf8, 0xc6, 0xc6, + 0xa5, 0x69, 0x8e, 0x8c, 0x01, 0xf3, 0xfd, 0xbb, 0xb0, 0x48, 0xc6, 0x08, 0xba, 0x74, 0x9e, 0x1c, + 0x05, 0xff, 0xe5, 0x46, 0x4e, 0x6b, 0x17, 0xb2, 0x86, 0xdf, 0xd1, 0x9b, 0xe4, 0x64, 0xbc, 0x38, + 0xc4, 0xfc, 0x36, 0x99, 0x72, 0x15, 0x3a, 0x22, 0xbf, 0xd4, 0x07, 0xb9, 0x2a, 0x0a, 0xf1, 0x47, + 0xc4, 0xe8, 0x0c, 0xb5, 0x58, 0x72, 0x9c, 0x38, 0x2d, 0xee, 0x11, 0x12, 0xee, 0x16, 0x5c, 0xf3, + 0x5c, 0xd1, 0xdf, 0x5a, 0x45, 0xb9, 0xb5, 0x8a, 0xfe, 0x96, 0xc4, 0xad, 0x55, 0x5c, 0x33, 0xab, + 0x0c, 0x79, 0x0d, 0x85, 0x53, 0xff, 0x54, 0x43, 0xf5, 0x7a, 0xd6, 0x49, 0x54, 0x2f, 0x33, 0x04, + 0xf5, 0xe8, 0x4a, 0x04, 0xff, 0x08, 0xe0, 0x3f, 0xdf, 0x17, 0xbf, 0x8f, 0x29, 0xa2, 0xc0, 0x07, + 0x1a, 0xd1, 0xe3, 0x14, 0x58, 0xde, 0xbd, 0x23, 0x91, 0x04, 0xf6, 0x9a, 0x27, 0x47, 0x01, 0x19, + 0xfa, 0xdc, 0xef, 0x74, 0x59, 0x71, 0x64, 0x60, 0x2b, 0xfe, 0x5e, 0x23, 0x67, 0xf6, 0x05, 0xf1, + 0x7f, 0x62, 0xcc, 0x5b, 0xe4, 0x54, 0x10, 0xeb, 0xf7, 0xeb, 0x1b, 0x3b, 0xaf, 0x99, 0x7c, 0x6b, + 0xc3, 0xbd, 0x63, 0x89, 0x9d, 0xc0, 0x8c, 0x79, 0x32, 0x6e, 0xe3, 0x00, 0x58, 0x72, 0xc2, 0xe8, + 0xf4, 0xf5, 0x3d, 0xb2, 0x90, 0xc4, 0x8c, 0xea, 0x7f, 0x87, 0xcc, 0xd8, 0x91, 0x11, 0x0c, 0xdc, + 0x2b, 0x7d, 0x0c, 0x10, 0x15, 0x87, 0x26, 0xe8, 0x12, 0xa5, 0xdf, 0xc6, 0xe5, 0xa3, 0x93, 0xef, + 0x9a, 0xc2, 0x4c, 0x03, 0xfe, 0x3d, 0x52, 0x48, 0xe4, 0x46, 0xf4, 0xdf, 0x24, 0xd3, 0x77, 0x24, + 0x26, 0x70, 0xe9, 0xc6, 0x0e, 0x4f, 0xe9, 0x3d, 0x95, 0x07, 0xa1, 0x47, 0xe5, 0xe8, 0x55, 0xb4, + 0xfa, 0x92, 0xe3, 0xc4, 0x5b, 0x7d, 0x58, 0x9b, 0xfd, 0x33, 0x0d, 0x6d, 0x14, 0xb3, 0xd2, 0x3e, + 0x2e, 0xca, 0x0c, 0xc9, 0x45, 0xc3, 0x8b, 0xd3, 0x27, 0xc9, 0x13, 0x41, 0xa8, 0x6d, 0x70, 0xbe, + 0x54, 0xa9, 0x78, 0x8c, 0x77, 0xee, 0x96, 0x57, 0x48, 0x3e, 0x6e, 0x10, 0x15, 0x9c, 0x23, 0x19, + 0x26, 0x02, 0xff, 0xcb, 0xa6, 0xa4, 0x6c, 0x0a, 0x0b, 0xe0, 0x4c, 0x18, 0xb2, 0xd9, 0xb9, 0xb3, + 0xa4, 0x84, 0xf5, 0xf5, 0x40, 0xee, 0xeb, 0x78, 0x67, 0x05, 0x54, 0x14, 0x78, 0x8d, 0x64, 0x36, + 0xd6, 0xd7, 0xd1, 0x2b, 0x29, 0x2e, 0x48, 0x43, 0x4e, 0xd7, 0x4b, 0x78, 0xed, 0xae, 0x30, 0xb1, + 0x62, 0xf2, 0x35, 0x99, 0x97, 0x28, 0x47, 0x95, 0x5d, 0xaf, 0xb0, 0x1d, 0xc4, 0xe8, 0x77, 0xf4, + 0x32, 0xc9, 0xf5, 0x32, 0x84, 0x17, 0x75, 0x40, 0x43, 0x1c, 0xe7, 0xfb, 0xe0, 0xe8, 0x88, 0xe8, + 0x30, 0xea, 0x26, 0x22, 0x5a, 0x72, 0x9c, 0x6e, 0x44, 0xc3, 0x8a, 0xbf, 0x9f, 0x69, 0xa8, 0x44, + 0x64, 0x8d, 0x58, 0x25, 0x32, 0x03, 0x29, 0x31, 0xbc, 0x08, 0x5b, 0x0c, 0x83, 0x08, 0xf6, 0xe9, + 0x9b, 0x90, 0x77, 0xee, 0xef, 0xa2, 0x77, 0xc2, 0xc4, 0x23, 0xc2, 0x83, 0x0a, 0xae, 0x92, 0x49, + 0x85, 0x8c, 0x66, 0xbc, 0xd8, 0xef, 0xf4, 0x50, 0x04, 0xa9, 0xec, 0x7a, 0x05, 0x01, 0x2e, 0x39, + 0x4e, 0x0c, 0xc0, 0x61, 0x79, 0xec, 0x63, 0x2d, 0x4c, 0x43, 0x52, 0xe9, 0x94, 0x39, 0x84, 0x4e, + 0xc3, 0xf3, 0xde, 0x42, 0x98, 0xd4, 0xac, 0xb1, 0x7a, 0xc5, 0xae, 0x57, 0x23, 0xe6, 0xd1, 0x45, + 0x78, 0xe2, 0x76, 0x8d, 0xa3, 0x5e, 0xeb, 0x64, 0xa6, 0xe1, 0x0f, 0xe0, 0x8b, 0x03, 0x55, 0xbb, + 0xdc, 0x2f, 0x21, 0x8d, 0x48, 0x9b, 0x6e, 0xa8, 0x5d, 0xfd, 0x25, 0x72, 0xda, 0x4f, 0x7a, 0x55, + 0x6a, 0x57, 0x9e, 0xf2, 0x04, 0x19, 0xf7, 0xdf, 0x30, 0x76, 0x05, 0xdc, 0x96, 0x0d, 0xd2, 0xd3, + 0x8a, 0xfe, 0x3e, 0x79, 0x6a, 0x1f, 0x76, 0x04, 0xfe, 0xed, 0x18, 0xe0, 0xda, 0x41, 0x81, 0x07, + 0xd7, 0x54, 0x14, 0xfe, 0x8d, 0xf0, 0x7e, 0x5f, 0x35, 0xb9, 0x58, 0x96, 0x2f, 0xa1, 0xd7, 0xe0, + 0x21, 0xb4, 0xff, 0xb6, 0x78, 0x84, 0x57, 0x6b, 0x1c, 0x1f, 0xa2, 0xfe, 0x16, 0x99, 0xed, 0x1a, + 0x42, 0xd8, 0xc5, 0x3e, 0xb0, 0xbb, 0x05, 0x76, 0x8b, 0xd1, 0xb7, 0xc2, 0x1b, 0x2f, 0x01, 0xf4, + 0xb0, 0xb6, 0xca, 0xef, 0x34, 0xd4, 0x33, 0x6e, 0xa9, 0xfd, 0xf4, 0xcc, 0x0c, 0x41, 0xcf, 0xe1, + 0x6d, 0x9d, 0x4b, 0xe1, 0x2d, 0xa7, 0xa6, 0x20, 0xf1, 0xae, 0x5d, 0x55, 0x4e, 0x49, 0x79, 0xed, + 0xef, 0x42, 0xa8, 0x0c, 0xfa, 0xd2, 0xaa, 0x92, 0xf9, 0xe8, 0xd2, 0x68, 0xb5, 0xb7, 0xc8, 0x94, + 0x9a, 0x30, 0xa5, 0x7c, 0x61, 0xa9, 0x2c, 0x46, 0x44, 0x80, 0xfe, 0x5d, 0xd4, 0x51, 0x1e, 0x6a, + 0xff, 0x81, 0x34, 0xeb, 0x23, 0x0d, 0x15, 0xe9, 0xc8, 0x4f, 0x54, 0x24, 0x73, 0x28, 0x45, 0x86, + 0xe7, 0xf5, 0xf7, 0x95, 0xdb, 0xc4, 0x12, 0x3b, 0x78, 0x1a, 0xf4, 0x38, 0xb2, 0xfb, 0x4c, 0x1a, + 0xda, 0x03, 0xea, 0x13, 0xf5, 0x9e, 0x51, 0x01, 0xfc, 0xcf, 0x5b, 0xee, 0x24, 0x5a, 0x4e, 0x6e, + 0xc8, 0x07, 0x4c, 0x98, 0x91, 0xc3, 0x45, 0xbf, 0x8e, 0x6a, 0x75, 0x8f, 0xa2, 0x5a, 0x27, 0xc8, + 0xa8, 0x72, 0xdc, 0x65, 0x0c, 0xec, 0xe9, 0x1b, 0x78, 0x7f, 0xdd, 0x71, 0xeb, 0xdb, 0xcc, 0x93, + 0x09, 0xdf, 0x86, 0x2b, 0xd9, 0x13, 0x1c, 0x92, 0x09, 0x1d, 0x92, 0x27, 0xe3, 0x55, 0x93, 0xaf, + 0xda, 0x35, 0x5b, 0x60, 0x46, 0xdb, 0xe9, 0xeb, 0x3f, 0xd6, 0xf0, 0xda, 0xeb, 0x15, 0x8b, 0x78, + 0x2e, 0x93, 0x63, 0x6e, 0x53, 0x6c, 0xba, 0xcd, 0x7a, 0x65, 0xc5, 0xe4, 0xf7, 0xeb, 0x72, 0x10, + 0x77, 0x7c, 0xef, 0x80, 0x9c, 0x0d, 0x5f, 0x97, 0x2c, 0xd7, 0xb9, 0xc7, 0x18, 0xce, 0xf6, 0x17, + 0xed, 0x1d, 0xa0, 0x17, 0xc8, 0xac, 0xfc, 0x55, 0xcf, 0xbe, 0x0c, 0x04, 0x53, 0x37, 0x59, 0x3f, + 0x4f, 0xce, 0x02, 0xcc, 0x37, 0x18, 0xe7, 0x66, 0x95, 0xad, 0x99, 0x9c, 0xdb, 0xf5, 0xea, 0x5a, + 0x28, 0x31, 0xb0, 0xee, 0x3d, 0x72, 0xae, 0xdf, 0x44, 0x54, 0xec, 0x24, 0x99, 0x78, 0xd8, 0x81, + 0xe8, 0x2b, 0x14, 0x12, 0xf4, 0x5b, 0xb8, 0xe0, 0x83, 0x57, 0xbf, 0xf1, 0x86, 0xcc, 0xee, 0x3d, + 0xb3, 0xce, 0x4d, 0x4b, 0xba, 0xd7, 0x60, 0x16, 0xb3, 0x1b, 0x9d, 0xbb, 0x82, 0x92, 0xec, 0x56, + 0xf8, 0x7a, 0x84, 0xb6, 0xfe, 0xaf, 0x2c, 0xa2, 0xd8, 0x87, 0xbb, 0x63, 0x5e, 0x82, 0xdf, 0x0f, + 0x3b, 0x42, 0x96, 0xa7, 0xdb, 0xad, 0xc2, 0x04, 0x50, 0xe5, 0x43, 0xc9, 0x08, 0x9b, 0x74, 0x91, + 0x4c, 0xf9, 0xb3, 0xeb, 0xcd, 0xda, 0x26, 0xf3, 0x7c, 0xcb, 0x2e, 0xcf, 0xb6, 0x5b, 0x85, 0x49, + 0xa0, 0xbf, 0x09, 0x64, 0x43, 0xed, 0xd0, 0x97, 0xc9, 0x9c, 0xe5, 0xd6, 0x85, 0x67, 0x5a, 0xa2, + 0x6c, 0xfa, 0x2f, 0x1f, 0xb0, 0xf2, 0xc4, 0xf2, 0xf1, 0x76, 0xab, 0x30, 0x1b, 0x8c, 0x05, 0x8f, + 0xa2, 0x6e, 0x02, 0x7d, 0x95, 0x1c, 0xb7, 0x9a, 0xb5, 0xa6, 0x63, 0x0a, 0x7b, 0x9b, 0x95, 0xab, + 0x26, 0x2f, 0x37, 0x39, 0xab, 0xe4, 0xb2, 0x20, 0xe2, 0xb1, 0x76, 0xab, 0x70, 0x2c, 0x1c, 0x5e, + 0x31, 0xf9, 0xdb, 0x9c, 0x55, 0x8c, 0x5e, 0x12, 0x3d, 0x49, 0xb2, 0x0f, 0x3d, 0xb7, 0x96, 0x3b, + 0x0a, 0x7c, 0xe3, 0xed, 0x56, 0x01, 0xfa, 0x06, 0xfc, 0xa5, 0xe7, 0x20, 0x46, 0x7d, 0xc9, 0xa3, + 0x30, 0x63, 0xb2, 0xdd, 0x2a, 0x8c, 0x55, 0x51, 0x5e, 0xd0, 0x90, 0xe6, 0x72, 0xdc, 0x2a, 0x2f, + 0x6f, 0x3a, 0xae, 0x5b, 0xcb, 0x8d, 0x85, 0xe6, 0x92, 0xd4, 0x65, 0x49, 0x34, 0xc2, 0x26, 0xd5, + 0xc9, 0x28, 0x17, 0xa6, 0x68, 0xf2, 0xdc, 0x38, 0xcc, 0x24, 0xed, 0x56, 0x01, 0x29, 0x06, 0xfe, + 0xd2, 0x13, 0x64, 0x44, 0xb8, 0xb9, 0x09, 0x18, 0x1f, 0x6d, 0xb7, 0x0a, 0x23, 0xc2, 0x35, 0x46, + 0x84, 0x2b, 0xcd, 0x26, 0x42, 0xb7, 0xf9, 0xee, 0x21, 0xa1, 0xd9, 0x94, 0x31, 0x70, 0x52, 0x37, + 0x81, 0x2e, 0x91, 0x63, 0x2a, 0xbf, 0x7f, 0x53, 0x4e, 0x82, 0x80, 0xf9, 0x76, 0xab, 0xa0, 0x0a, + 0xbf, 0x2f, 0xc7, 0x8c, 0x1e, 0x0a, 0xbd, 0x41, 0xb2, 0x52, 0x97, 0xdc, 0x54, 0xaa, 0x0f, 0xad, + 0xab, 0x6e, 0xd5, 0x80, 0xf9, 0xfa, 0x07, 0x19, 0x92, 0x59, 0x75, 0xab, 0xf2, 0x48, 0x08, 0x1c, + 0xee, 0x47, 0x67, 0xd0, 0x95, 0x87, 0x8c, 0x70, 0x1b, 0xb6, 0xc5, 0x73, 0x23, 0xa7, 0x33, 0x17, + 0x26, 0x0c, 0xec, 0xc9, 0x60, 0xae, 0x98, 0xc2, 0xf4, 0xe3, 0xc3, 0x80, 0x76, 0x4f, 0xcc, 0x49, + 0xc7, 0x67, 0xfb, 0xc7, 0x5c, 0x8f, 0xf1, 0x8e, 0x1e, 0xd6, 0x78, 0xa3, 0xb0, 0x70, 0x5a, 0xe3, + 0x45, 0x37, 0xd6, 0x58, 0x9f, 0x8d, 0xf5, 0x0c, 0x91, 0x61, 0x83, 0x0b, 0x8d, 0xc3, 0x42, 0x53, + 0xed, 0x56, 0x61, 0xdc, 0x71, 0xab, 0xfe, 0x02, 0x9d, 0x16, 0x3d, 0x4b, 0xc6, 0x3c, 0x56, 0x73, + 0xb7, 0x59, 0x05, 0xa2, 0x66, 0xdc, 0x8f, 0x54, 0x24, 0x19, 0x41, 0x43, 0xbf, 0x86, 0x59, 0x66, + 0xdc, 0x11, 0x90, 0x7c, 0x72, 0xfc, 0x33, 0x8b, 0x19, 0x63, 0x1c, 0xdb, 0x7f, 0xed, 0xc8, 0x08, + 0xf6, 0x6a, 0x26, 0x76, 0xaf, 0x3e, 0x41, 0x32, 0x55, 0x93, 0xe3, 0x01, 0x30, 0xd6, 0x6e, 0x15, + 0x64, 0xd7, 0x90, 0x7f, 0xa4, 0x19, 0x3b, 0x35, 0x15, 0x74, 0x38, 0x98, 0xb1, 0xda, 0x79, 0x96, + 0x07, 0x2d, 0xb9, 0x06, 0xe0, 0x1f, 0x0d, 0xd7, 0x90, 0x7d, 0xdf, 0x0e, 0xb4, 0x20, 0x73, 0xcb, + 0x46, 0x53, 0xa0, 0xe3, 0x26, 0xda, 0xad, 0x82, 0x4f, 0x30, 0xfc, 0x1f, 0x39, 0xc1, 0x4f, 0x17, + 0xc7, 0xc3, 0x09, 0x40, 0xc0, 0xcc, 0x31, 0x71, 0x5f, 0xc7, 0x86, 0x16, 0x39, 0xd0, 0xbe, 0x2c, + 0x90, 0xa3, 0xdb, 0xa6, 0xd3, 0x64, 0xb8, 0x9d, 0x61, 0x6d, 0x20, 0x18, 0xfe, 0x8f, 0xd4, 0x4d, + 0xec, 0x36, 0x58, 0x6e, 0x2a, 0xd4, 0x4d, 0xf6, 0x0d, 0xf8, 0x4b, 0x4b, 0x64, 0xd2, 0xb4, 0x2c, + 0x16, 0x94, 0x51, 0xa6, 0xe5, 0x0e, 0x5c, 0x9e, 0x69, 0xb7, 0x0a, 0xc4, 0x27, 0xaf, 0xda, 0x32, + 0x13, 0x0a, 0xdb, 0xf2, 0x70, 0xec, 0x3c, 0x00, 0x67, 0xc2, 0xc3, 0x11, 0xef, 0xf7, 0xf0, 0xa2, + 0x3f, 0x4e, 0xb4, 0xed, 0xdc, 0x2c, 0x4c, 0x38, 0xda, 0x6e, 0x15, 0xb4, 0x6d, 0x43, 0xdb, 0x96, + 0x44, 0x2f, 0x37, 0x17, 0x12, 0x3d, 0x43, 0xf3, 0x24, 0x91, 0xe7, 0x8e, 0x85, 0x44, 0x6e, 0x68, + 0x5c, 0xbf, 0x89, 0x6f, 0x51, 0x0c, 0x3d, 0xb8, 0x7e, 0x97, 0x77, 0x31, 0x3e, 0x30, 0x66, 0x4f, + 0x90, 0xd1, 0xad, 0x30, 0x3b, 0xc9, 0x1a, 0xd8, 0xd3, 0xff, 0x3a, 0x86, 0x2f, 0xd1, 0x78, 0x66, + 0x8c, 0x5c, 0x9d, 0x8c, 0x62, 0x14, 0x6a, 0xe1, 0x79, 0xec, 0x53, 0x0c, 0xfc, 0xed, 0xc4, 0xc5, + 0x48, 0x6c, 0x5c, 0x94, 0xc8, 0x64, 0xc3, 0xf4, 0x58, 0x5d, 0xf8, 0xc1, 0xef, 0x07, 0x28, 0xd8, + 0xce, 0x27, 0x43, 0xf4, 0x2b, 0xed, 0x30, 0x4e, 0xb2, 0x09, 0x71, 0x52, 0x22, 0x93, 0x7c, 0xcb, + 0x7c, 0xae, 0xdc, 0xac, 0x5b, 0x0e, 0xe3, 0x18, 0xb4, 0x20, 0x51, 0x92, 0xdf, 0x06, 0xaa, 0xa1, + 0xb4, 0xbb, 0xae, 0xa0, 0xd1, 0x3e, 0x57, 0x50, 0x34, 0xdc, 0x78, 0xd9, 0x73, 0xdd, 0x20, 0xa8, + 0xbb, 0xc3, 0x8d, 0x1b, 0xae, 0x2b, 0x8c, 0x1e, 0x8a, 0x5c, 0x50, 0xde, 0x55, 0xcc, 0xe7, 0x1d, + 0x0f, 0x17, 0x04, 0x2a, 0x30, 0x85, 0x4d, 0x7a, 0x9d, 0x4c, 0x7b, 0x7e, 0x8e, 0x81, 0x8b, 0xf9, + 0x5b, 0x60, 0xae, 0xdd, 0x2a, 0x4c, 0x05, 0x03, 0xc0, 0x13, 0xe9, 0x49, 0x3b, 0xd5, 0xec, 0x3a, + 0xf3, 0x70, 0x2b, 0x80, 0x9d, 0x80, 0x60, 0xf8, 0x3f, 0xb4, 0x48, 0x48, 0xc5, 0x7e, 0xf8, 0xd0, + 0xb6, 0x9a, 0x8e, 0xd8, 0xc5, 0xc8, 0x07, 0x33, 0x85, 0x54, 0x43, 0x69, 0xc3, 0x15, 0xe0, 0x0a, + 0xd3, 0x29, 0x2b, 0x5c, 0x53, 0xca, 0x15, 0x20, 0xc7, 0xee, 0x86, 0xac, 0xdd, 0x04, 0xa9, 0x35, + 0xdb, 0x11, 0x9e, 0x59, 0x86, 0x0b, 0x69, 0x3a, 0xd4, 0x1a, 0xa8, 0xf0, 0x15, 0x3e, 0x6c, 0xca, + 0xa8, 0xe1, 0xf6, 0x7b, 0x0c, 0xb7, 0x07, 0x44, 0x8d, 0xec, 0x1b, 0xf0, 0x37, 0x38, 0x96, 0x1c, + 0x48, 0x81, 0x67, 0x23, 0xc7, 0x12, 0xa4, 0xc1, 0x61, 0x42, 0x1c, 0x49, 0x44, 0xe6, 0xf6, 0x49, + 0x44, 0x2e, 0x91, 0x09, 0x61, 0xd7, 0x18, 0x17, 0x66, 0xad, 0x81, 0x3b, 0x09, 0xd0, 0x75, 0x88, + 0x46, 0xd8, 0xa4, 0xd7, 0xc8, 0x94, 0xea, 0xd5, 0x1c, 0x85, 0x2d, 0x0f, 0x2e, 0x89, 0x78, 0x3b, + 0xd2, 0x93, 0xbb, 0x05, 0x83, 0xf2, 0x38, 0xcc, 0x87, 0xdd, 0xe2, 0x53, 0x0c, 0xfc, 0xa5, 0x37, + 0xc9, 0x9c, 0x7c, 0x99, 0x94, 0x1f, 0x32, 0x56, 0x6e, 0x30, 0x4f, 0xa6, 0x67, 0xb9, 0x79, 0x40, + 0x73, 0xac, 0xdd, 0x2a, 0x4c, 0xcb, 0xb1, 0x7b, 0x8c, 0xad, 0x31, 0x6f, 0xc5, 0xe4, 0x46, 0xb4, + 0x2b, 0x55, 0xad, 0xd9, 0x7e, 0x89, 0x3b, 0xf7, 0x58, 0xa8, 0x6a, 0xcd, 0x86, 0xef, 0xf3, 0x46, + 0xd0, 0x58, 0xfc, 0xe8, 0x69, 0x72, 0x14, 0xf6, 0x36, 0xfd, 0x81, 0x46, 0x46, 0xfd, 0xfa, 0x2a, + 0xbd, 0xda, 0x27, 0x1b, 0xe9, 0x2d, 0xf0, 0xe6, 0x17, 0x0f, 0xc2, 0xe2, 0x9f, 0x18, 0xfa, 0xd9, + 0x0f, 0xfe, 0xf4, 0x8f, 0xef, 0x8f, 0x14, 0xe8, 0xa9, 0x92, 0xe4, 0xb8, 0xa2, 0xd4, 0xf5, 0xd5, + 0xda, 0x38, 0xfd, 0x4c, 0x23, 0x53, 0x6a, 0x49, 0x8c, 0xde, 0x4c, 0xb3, 0x56, 0x7c, 0x35, 0x38, + 0x7f, 0x6b, 0x20, 0x5e, 0x04, 0xfc, 0x12, 0x00, 0x7e, 0x9e, 0x5e, 0x4f, 0x00, 0xac, 0x16, 0xe9, + 0x4a, 0x8f, 0xf0, 0xe3, 0xc7, 0x5e, 0xe9, 0x11, 0x1c, 0x46, 0x7b, 0xf4, 0x13, 0x8d, 0xcc, 0xaa, + 0x72, 0x97, 0x1c, 0x27, 0x9d, 0x2e, 0xf1, 0x35, 0xe1, 0x74, 0xba, 0x24, 0xd4, 0x79, 0xf5, 0x4b, + 0xa0, 0xcb, 0x59, 0x7a, 0x26, 0x85, 0x2e, 0xf4, 0x6f, 0x1a, 0x39, 0xd1, 0x85, 0x1c, 0x3f, 0x44, + 0xd2, 0xa5, 0x01, 0x40, 0x44, 0xbf, 0x81, 0xe6, 0x97, 0x0f, 0x23, 0x02, 0xd5, 0xb9, 0x09, 0xea, + 0x5c, 0xa3, 0x8b, 0x29, 0xd4, 0x41, 0x5e, 0xf4, 0xd0, 0x1e, 0xfd, 0x83, 0x46, 0x66, 0xa2, 0xf5, + 0x2c, 0x7a, 0x3b, 0x65, 0x98, 0xc4, 0xd6, 0xef, 0xf2, 0x2f, 0x0d, 0xc8, 0x8d, 0xba, 0xbc, 0x00, + 0xba, 0x2c, 0xd2, 0x67, 0x13, 0x74, 0x89, 0x56, 0xd9, 0x4a, 0x8f, 0x82, 0xfe, 0x1e, 0xfd, 0xb3, + 0x46, 0x68, 0x6f, 0x45, 0x93, 0xa6, 0xc2, 0x93, 0x58, 0x47, 0xcd, 0xbf, 0x3c, 0x28, 0x3b, 0xea, + 0xb3, 0x04, 0xfa, 0xdc, 0xa2, 0x2f, 0x26, 0xea, 0xd3, 0xfd, 0xdf, 0x38, 0x70, 0x2f, 0xa8, 0x8a, + 0xfd, 0x46, 0x23, 0xc7, 0xa2, 0x2b, 0xc8, 0xcd, 0x73, 0x3b, 0x65, 0xe0, 0x1c, 0xc2, 0x4b, 0x89, + 0x95, 0x53, 0xfd, 0x0a, 0x68, 0x75, 0x9e, 0x9e, 0x4d, 0xe5, 0x25, 0xfa, 0xb1, 0x46, 0xa6, 0x23, + 0x15, 0x4a, 0xfa, 0x42, 0xca, 0x28, 0xe9, 0xa9, 0x78, 0xe6, 0x5f, 0x1c, 0x80, 0x13, 0x51, 0x17, + 0x01, 0xf5, 0x05, 0x7a, 0x2e, 0x01, 0x75, 0x95, 0x89, 0xb2, 0xe0, 0x3c, 0xf8, 0x98, 0x40, 0x3f, + 0xd4, 0xa0, 0xdc, 0x99, 0xee, 0x4a, 0x88, 0xd4, 0x4f, 0xd3, 0x5d, 0x09, 0xd1, 0xe2, 0xaa, 0xae, + 0x03, 0xbc, 0x93, 0x34, 0x9f, 0x00, 0x4f, 0x42, 0xf9, 0xb9, 0x16, 0x56, 0x0e, 0xe9, 0x8d, 0x94, + 0x8b, 0x74, 0x95, 0x38, 0xf3, 0xcf, 0x1f, 0x98, 0x0f, 0x11, 0x96, 0x00, 0xe1, 0x33, 0xf4, 0x7c, + 0x92, 0x01, 0x91, 0x41, 0x46, 0x6f, 0x85, 0xed, 0xec, 0xd1, 0x9f, 0x6a, 0x64, 0x32, 0x90, 0x22, + 0x83, 0xf6, 0x46, 0xca, 0xb0, 0x1b, 0x08, 0x71, 0x4c, 0xa1, 0x55, 0x3f, 0x0f, 0x88, 0x9f, 0xa2, + 0x85, 0x3e, 0x88, 0xe9, 0xa7, 0x1a, 0x99, 0xeb, 0xfe, 0x54, 0x48, 0x53, 0x5d, 0x32, 0x09, 0xdf, + 0x2d, 0xf3, 0xb7, 0x07, 0x63, 0x4e, 0x69, 0x6a, 0xab, 0x1b, 0xeb, 0x67, 0x1a, 0x99, 0x54, 0xbe, + 0x06, 0xd2, 0xbb, 0x69, 0x96, 0xef, 0xf7, 0xd5, 0x31, 0xff, 0xea, 0x21, 0xa5, 0xa0, 0x36, 0x17, + 0x41, 0x9b, 0xa7, 0xa9, 0x9e, 0x94, 0xed, 0x28, 0xc0, 0x7f, 0xa5, 0x45, 0xea, 0xac, 0x34, 0xed, + 0x86, 0xef, 0xad, 0x0c, 0xe7, 0x6f, 0x0e, 0xc2, 0x8a, 0x90, 0x17, 0x01, 0xf2, 0x65, 0x7a, 0x31, + 0xc9, 0x01, 0x21, 0x4f, 0x27, 0xdc, 0x7f, 0xa1, 0x91, 0x19, 0x45, 0x96, 0x8c, 0xf8, 0x17, 0x53, + 0x46, 0xee, 0xa0, 0xe8, 0xe3, 0x6b, 0xd5, 0x7d, 0x0d, 0xae, 0xa0, 0xa7, 0xbf, 0xd6, 0xc8, 0x5c, + 0xa4, 0x24, 0x2a, 0x71, 0xa7, 0xcd, 0xaf, 0xe2, 0x4a, 0xce, 0xf9, 0xdb, 0x83, 0x31, 0x23, 0xf6, + 0xcb, 0x80, 0xfd, 0x1c, 0x7d, 0x3a, 0x29, 0x58, 0x54, 0x2e, 0xfa, 0x47, 0x8d, 0xcc, 0xc7, 0x55, + 0x89, 0xe9, 0xd7, 0x52, 0x65, 0xe5, 0xc9, 0xe5, 0xe9, 0xfc, 0x2b, 0x83, 0x0b, 0x40, 0x4d, 0x9e, + 0x07, 0x4d, 0xae, 0xd2, 0x52, 0x1a, 0x4d, 0x30, 0x25, 0x2b, 0xdb, 0x95, 0x3d, 0xfa, 0xb9, 0xd6, + 0x53, 0x3c, 0xa5, 0x69, 0x13, 0xab, 0xf8, 0xd2, 0x6f, 0xba, 0x44, 0x26, 0xb9, 0x6c, 0xad, 0xdf, + 0x00, 0x5d, 0x9e, 0xa5, 0xc5, 0x04, 0x5d, 0x9c, 0x28, 0x5f, 0x67, 0x4f, 0xfc, 0x56, 0x23, 0xb4, + 0x4b, 0xa6, 0x8c, 0xaf, 0xb4, 0x09, 0xc8, 0x61, 0xb4, 0x49, 0x2e, 0x4e, 0xf7, 0x4d, 0x05, 0xba, + 0xb4, 0xa1, 0x3f, 0xd2, 0x48, 0x16, 0x52, 0x99, 0xb4, 0x17, 0xbb, 0x9a, 0x6c, 0x3d, 0x77, 0x20, + 0x9e, 0x94, 0x6f, 0x14, 0x0b, 0xd3, 0x5f, 0x30, 0xf2, 0xc7, 0xf2, 0xcc, 0x0c, 0x8b, 0xd2, 0xe9, + 0xcf, 0xcc, 0x9e, 0x42, 0xf6, 0x60, 0x60, 0xaf, 0x03, 0xd8, 0x12, 0xbd, 0xb2, 0x2f, 0xd8, 0x9e, + 0x47, 0xe1, 0x0f, 0x35, 0x32, 0x16, 0xe4, 0xb3, 0x8b, 0x69, 0x4f, 0xbb, 0x83, 0x1a, 0xb6, 0xab, + 0x30, 0xad, 0x9f, 0x01, 0xac, 0xa7, 0xe8, 0x93, 0xfb, 0x60, 0xf5, 0x4f, 0x72, 0x1f, 0x19, 0xee, + 0xf0, 0xf4, 0x27, 0x79, 0x4f, 0x4d, 0x39, 0xfd, 0x49, 0xde, 0x5b, 0x0d, 0xee, 0x7f, 0x92, 0x87, + 0x3c, 0xf4, 0x97, 0x1a, 0x99, 0x89, 0x56, 0x5f, 0xd3, 0xa1, 0x8e, 0xad, 0xe7, 0xa6, 0x43, 0x1d, + 0x5f, 0xec, 0xed, 0xfb, 0x40, 0x70, 0xa2, 0x28, 0x7f, 0xa2, 0x11, 0x12, 0xfe, 0x53, 0x3e, 0xbd, + 0x9e, 0x66, 0xe5, 0x9e, 0x7f, 0xef, 0xcf, 0xdf, 0x38, 0x28, 0x1b, 0x82, 0x7d, 0x06, 0xc0, 0x9e, + 0xa1, 0x4f, 0x25, 0x80, 0x15, 0x1d, 0x96, 0xe5, 0xd7, 0x3f, 0xff, 0x72, 0x41, 0xfb, 0xe2, 0xcb, + 0x05, 0xed, 0xef, 0x5f, 0x2e, 0x68, 0x1f, 0x7e, 0xb5, 0x70, 0xe4, 0x8b, 0xaf, 0x16, 0x8e, 0xfc, + 0xe5, 0xab, 0x85, 0x23, 0x0f, 0xae, 0x56, 0x6d, 0xb1, 0xd5, 0xdc, 0x2c, 0x5a, 0x6e, 0x4d, 0x15, + 0x13, 0xe0, 0x28, 0xed, 0x44, 0x24, 0xee, 0x36, 0x18, 0xdf, 0x1c, 0x85, 0xb4, 0xe7, 0xb9, 0x7f, + 0x07, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xf5, 0xed, 0x4b, 0x5d, 0x32, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3215,6 +3309,7 @@ type QueryClient interface { // Queries a list of chainNonces items. ChainNoncesAll(ctx context.Context, in *QueryAllChainNoncesRequest, opts ...grpc.CallOption) (*QueryAllChainNoncesResponse, error) PendingNoncesAll(ctx context.Context, in *QueryAllPendingNoncesRequest, opts ...grpc.CallOption) (*QueryAllPendingNoncesResponse, error) + PendingNoncesByChain(ctx context.Context, in *QueryPendingNoncesByChainRequest, opts ...grpc.CallOption) (*QueryPendingNoncesByChainResponse, error) // Queries a lastBlockHeight by index. LastBlockHeight(ctx context.Context, in *QueryGetLastBlockHeightRequest, opts ...grpc.CallOption) (*QueryGetLastBlockHeightResponse, error) // Queries a list of lastBlockHeight items. @@ -3384,6 +3479,15 @@ func (c *queryClient) PendingNoncesAll(ctx context.Context, in *QueryAllPendingN return out, nil } +func (c *queryClient) PendingNoncesByChain(ctx context.Context, in *QueryPendingNoncesByChainRequest, opts ...grpc.CallOption) (*QueryPendingNoncesByChainResponse, error) { + out := new(QueryPendingNoncesByChainResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/PendingNoncesByChain", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) LastBlockHeight(ctx context.Context, in *QueryGetLastBlockHeightRequest, opts ...grpc.CallOption) (*QueryGetLastBlockHeightResponse, error) { out := new(QueryGetLastBlockHeightResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/LastBlockHeight", in, out, opts...) @@ -3486,6 +3590,7 @@ type QueryServer interface { // Queries a list of chainNonces items. ChainNoncesAll(context.Context, *QueryAllChainNoncesRequest) (*QueryAllChainNoncesResponse, error) PendingNoncesAll(context.Context, *QueryAllPendingNoncesRequest) (*QueryAllPendingNoncesResponse, error) + PendingNoncesByChain(context.Context, *QueryPendingNoncesByChainRequest) (*QueryPendingNoncesByChainResponse, error) // Queries a lastBlockHeight by index. LastBlockHeight(context.Context, *QueryGetLastBlockHeightRequest) (*QueryGetLastBlockHeightResponse, error) // Queries a list of lastBlockHeight items. @@ -3555,6 +3660,9 @@ func (*UnimplementedQueryServer) ChainNoncesAll(ctx context.Context, req *QueryA func (*UnimplementedQueryServer) PendingNoncesAll(ctx context.Context, req *QueryAllPendingNoncesRequest) (*QueryAllPendingNoncesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PendingNoncesAll not implemented") } +func (*UnimplementedQueryServer) PendingNoncesByChain(ctx context.Context, req *QueryPendingNoncesByChainRequest) (*QueryPendingNoncesByChainResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingNoncesByChain not implemented") +} func (*UnimplementedQueryServer) LastBlockHeight(ctx context.Context, req *QueryGetLastBlockHeightRequest) (*QueryGetLastBlockHeightResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LastBlockHeight not implemented") } @@ -3872,6 +3980,24 @@ func _Query_PendingNoncesAll_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Query_PendingNoncesByChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingNoncesByChainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingNoncesByChain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.crosschain.Query/PendingNoncesByChain", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingNoncesByChain(ctx, req.(*QueryPendingNoncesByChainRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_LastBlockHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryGetLastBlockHeightRequest) if err := dec(in); err != nil { @@ -4084,6 +4210,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "PendingNoncesAll", Handler: _Query_PendingNoncesAll_Handler, }, + { + MethodName: "PendingNoncesByChain", + Handler: _Query_PendingNoncesByChain_Handler, + }, { MethodName: "LastBlockHeight", Handler: _Query_LastBlockHeight_Handler, @@ -5166,6 +5296,67 @@ func (m *QueryAllPendingNoncesResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *QueryPendingNoncesByChainRequest) 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 *QueryPendingNoncesByChainRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingNoncesByChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ChainId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryPendingNoncesByChainResponse) 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 *QueryPendingNoncesByChainResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingNoncesByChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.PendingNonces.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *QueryGetLastBlockHeightRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6808,6 +6999,29 @@ func (m *QueryAllPendingNoncesResponse) Size() (n int) { return n } +func (m *QueryPendingNoncesByChainRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainId != 0 { + n += 1 + sovQuery(uint64(m.ChainId)) + } + return n +} + +func (m *QueryPendingNoncesByChainResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.PendingNonces.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func (m *QueryGetLastBlockHeightRequest) Size() (n int) { if m == nil { return 0 @@ -9963,6 +10177,158 @@ func (m *QueryAllPendingNoncesResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryPendingNoncesByChainRequest) 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 ErrIntOverflowQuery + } + 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: QueryPendingNoncesByChainRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingNoncesByChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPendingNoncesByChainResponse) 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 ErrIntOverflowQuery + } + 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: QueryPendingNoncesByChainResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingNoncesByChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PendingNonces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PendingNonces.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryGetLastBlockHeightRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/crosschain/types/query.pb.gw.go b/x/crosschain/types/query.pb.gw.go index 2b64d0ef9a..f8ea4ecbae 100644 --- a/x/crosschain/types/query.pb.gw.go +++ b/x/crosschain/types/query.pb.gw.go @@ -667,6 +667,60 @@ func local_request_Query_PendingNoncesAll_0(ctx context.Context, marshaler runti } +func request_Query_PendingNoncesByChain_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingNoncesByChainRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := client.PendingNoncesByChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_PendingNoncesByChain_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingNoncesByChainRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := server.PendingNoncesByChain(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_LastBlockHeight_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryGetLastBlockHeightRequest var metadata runtime.ServerMetadata @@ -1369,6 +1423,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_PendingNoncesByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_PendingNoncesByChain_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PendingNoncesByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_LastBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1914,6 +1991,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_PendingNoncesByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_PendingNoncesByChain_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PendingNoncesByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_LastBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2110,6 +2207,8 @@ var ( pattern_Query_PendingNoncesAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "pendingNonces"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_PendingNoncesByChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "crosschain", "pendingNonces", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_LastBlockHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "crosschain", "lastBlockHeight", "index"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_LastBlockHeightAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "lastBlockHeight"}, "", runtime.AssumeColonVerbOpt(false))) @@ -2160,6 +2259,8 @@ var ( forward_Query_PendingNoncesAll_0 = runtime.ForwardResponseMessage + forward_Query_PendingNoncesByChain_0 = runtime.ForwardResponseMessage + forward_Query_LastBlockHeight_0 = runtime.ForwardResponseMessage forward_Query_LastBlockHeightAll_0 = runtime.ForwardResponseMessage diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index 303a06633a..f255d88bc9 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -248,10 +248,13 @@ func (m *MsgWhitelistERC20Response) XXX_DiscardUnknown() { var xxx_messageInfo_MsgWhitelistERC20Response proto.InternalMessageInfo type MsgAddToOutTxTracker 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"` - Nonce uint64 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"` - TxHash string `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` + 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"` + Nonce uint64 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"` + TxHash string `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` + Proof *common.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` + BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + TxIndex int64 `protobuf:"varint,7,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` } func (m *MsgAddToOutTxTracker) Reset() { *m = MsgAddToOutTxTracker{} } @@ -315,6 +318,27 @@ func (m *MsgAddToOutTxTracker) GetTxHash() string { return "" } +func (m *MsgAddToOutTxTracker) GetProof() *common.Proof { + if m != nil { + return m.Proof + } + return nil +} + +func (m *MsgAddToOutTxTracker) GetBlockHash() string { + if m != nil { + return m.BlockHash + } + return "" +} + +func (m *MsgAddToOutTxTracker) GetTxIndex() int64 { + if m != nil { + return m.TxIndex + } + return 0 +} + type MsgAddToOutTxTrackerResponse struct { } @@ -767,7 +791,7 @@ type MsgVoteOnObservedOutboundTx struct { ObservedOutTxGasUsed uint64 `protobuf:"varint,10,opt,name=observed_outTx_gas_used,json=observedOutTxGasUsed,proto3" json:"observed_outTx_gas_used,omitempty"` ObservedOutTxEffectiveGasPrice github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,11,opt,name=observed_outTx_effective_gas_price,json=observedOutTxEffectiveGasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"observed_outTx_effective_gas_price"` ObservedOutTxEffectiveGasLimit uint64 `protobuf:"varint,12,opt,name=observed_outTx_effective_gas_limit,json=observedOutTxEffectiveGasLimit,proto3" json:"observed_outTx_effective_gas_limit,omitempty"` - ZetaMinted github_com_cosmos_cosmos_sdk_types.Uint `protobuf:"bytes,5,opt,name=zeta_minted,json=zetaMinted,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Uint" json:"zeta_minted" yaml:"zeta_minted"` + ValueReceived github_com_cosmos_cosmos_sdk_types.Uint `protobuf:"bytes,5,opt,name=value_received,json=valueReceived,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Uint" json:"value_received" yaml:"value_received"` Status common.ReceiveStatus `protobuf:"varint,6,opt,name=status,proto3,enum=common.ReceiveStatus" json:"status,omitempty"` OutTxChain int64 `protobuf:"varint,7,opt,name=outTx_chain,json=outTxChain,proto3" json:"outTx_chain,omitempty"` OutTxTssNonce uint64 `protobuf:"varint,8,opt,name=outTx_tss_nonce,json=outTxTssNonce,proto3" json:"outTx_tss_nonce,omitempty"` @@ -1206,89 +1230,92 @@ func init() { func init() { proto.RegisterFile("crosschain/tx.proto", fileDescriptor_81d6d611190b7635) } var fileDescriptor_81d6d611190b7635 = []byte{ - // 1313 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0x36, 0x89, 0x63, 0xbf, 0xc4, 0x69, 0x32, 0x49, 0x9b, 0xed, 0xa6, 0x75, 0xda, 0x2d, - 0x2d, 0x15, 0x6a, 0xec, 0x92, 0x82, 0x28, 0x85, 0x03, 0x4d, 0x54, 0xd2, 0x52, 0x9c, 0x54, 0x1b, - 0x17, 0xa4, 0x5e, 0x56, 0xeb, 0xdd, 0xc9, 0x7a, 0x15, 0xef, 0x8e, 0xb5, 0x33, 0x8e, 0xec, 0x8a, - 0x13, 0x12, 0x07, 0x6e, 0x1c, 0x90, 0x40, 0x7c, 0x01, 0xbe, 0x4a, 0xb9, 0x55, 0x9c, 0x10, 0x87, - 0x0a, 0xda, 0x6f, 0xc0, 0x27, 0x40, 0xf3, 0x67, 0x37, 0x5e, 0x27, 0xb6, 0xe3, 0x20, 0x4e, 0x3b, - 0xef, 0xed, 0xfb, 0xf3, 0x7b, 0x33, 0xbf, 0x37, 0x7f, 0x60, 0xc9, 0x8d, 0x09, 0xa5, 0x6e, 0xc3, - 0x09, 0xa2, 0x0a, 0xeb, 0x94, 0x5b, 0x31, 0x61, 0x04, 0x5d, 0x79, 0x81, 0x99, 0x23, 0x74, 0x65, - 0x31, 0x22, 0x31, 0x2e, 0x1f, 0xd9, 0x19, 0x4b, 0x2e, 0x09, 0x43, 0x12, 0x55, 0xe4, 0x47, 0xfa, - 0x18, 0xcb, 0x3e, 0xf1, 0x89, 0x18, 0x56, 0xf8, 0x48, 0x6a, 0xcd, 0x1d, 0x58, 0xaa, 0x52, 0xff, - 0x59, 0xcb, 0x73, 0x18, 0xae, 0x51, 0xfa, 0xc0, 0xf3, 0x62, 0x4c, 0x29, 0xd2, 0x61, 0xc6, 0x8d, - 0xb1, 0xc3, 0x48, 0xac, 0x6b, 0x57, 0xb5, 0x5b, 0x05, 0x2b, 0x11, 0xd1, 0x15, 0x00, 0x46, 0xa9, - 0xdd, 0x6a, 0xd7, 0x0f, 0x70, 0x57, 0x3f, 0x27, 0x7e, 0x16, 0x18, 0xa5, 0x4f, 0x85, 0xc2, 0xbc, - 0x02, 0xab, 0x27, 0xc4, 0xb3, 0x30, 0x6d, 0x91, 0x88, 0x62, 0xf3, 0x77, 0x0d, 0x16, 0xab, 0xd4, - 0xff, 0xba, 0x11, 0x30, 0xdc, 0x0c, 0x28, 0x7b, 0x68, 0x6d, 0x6d, 0xdc, 0x19, 0x92, 0xed, 0x3a, - 0x14, 0x71, 0xec, 0x6e, 0xdc, 0xb1, 0x1d, 0x19, 0x48, 0x25, 0x9c, 0x13, 0xca, 0x04, 0xec, 0x25, - 0xc8, 0x8b, 0xba, 0xed, 0xc0, 0xd3, 0x27, 0xaf, 0x6a, 0xb7, 0x26, 0xad, 0x19, 0x21, 0x3f, 0xf6, - 0x10, 0x82, 0xa9, 0xc8, 0x09, 0xb1, 0x3e, 0x25, 0xdc, 0xc4, 0x18, 0x5d, 0x84, 0x1c, 0xed, 0x86, - 0x75, 0xd2, 0xd4, 0xa7, 0x85, 0x56, 0x49, 0xc8, 0x80, 0xbc, 0x87, 0xdd, 0x20, 0x74, 0x9a, 0x54, - 0xcf, 0x5d, 0xd5, 0x6e, 0x15, 0xad, 0x54, 0x46, 0xab, 0x50, 0xf0, 0x1d, 0x6a, 0x37, 0x83, 0x30, - 0x60, 0xfa, 0x8c, 0xc8, 0x91, 0xf7, 0x1d, 0xfa, 0x25, 0x97, 0xcd, 0x55, 0xb8, 0x74, 0xac, 0xa6, - 0xb4, 0xe2, 0x17, 0xb0, 0x5c, 0xa5, 0xfe, 0x03, 0xcf, 0xab, 0x91, 0xdd, 0x36, 0xab, 0x75, 0x6a, - 0xb1, 0xe3, 0x1e, 0xe0, 0x78, 0x48, 0xcd, 0xbd, 0xe5, 0x9c, 0xcb, 0x96, 0xb3, 0x0c, 0xd3, 0x11, - 0x89, 0x5c, 0x2c, 0xca, 0x9c, 0xb2, 0xa4, 0x80, 0x56, 0x60, 0x86, 0x75, 0xec, 0x86, 0x43, 0x1b, - 0xaa, 0xce, 0x1c, 0xeb, 0x3c, 0x72, 0x68, 0xc3, 0x2c, 0xc1, 0xe5, 0x93, 0x72, 0xa7, 0xd8, 0xf6, - 0x05, 0x70, 0x0b, 0x87, 0xe4, 0x10, 0x7f, 0x1e, 0x93, 0xf0, 0x7f, 0x02, 0x68, 0x5e, 0x87, 0x6b, - 0x03, 0xf3, 0xa4, 0x60, 0x7e, 0x95, 0xd4, 0xd8, 0xe2, 0x49, 0x70, 0x6d, 0x6f, 0xef, 0x2b, 0xc2, - 0x86, 0xa2, 0x18, 0x4e, 0x44, 0xf4, 0x1e, 0x2c, 0x1c, 0xe0, 0xee, 0x36, 0x8e, 0x9e, 0x63, 0xe6, - 0x3c, 0xc2, 0x81, 0xdf, 0x60, 0x8a, 0x1c, 0xc7, 0xf4, 0x68, 0x1d, 0x72, 0x94, 0x39, 0xac, 0x4d, - 0xc5, 0xfc, 0xcd, 0x6f, 0x5c, 0x28, 0xab, 0xce, 0xb1, 0xb0, 0x8b, 0x83, 0x43, 0xbc, 0x27, 0x7e, - 0x5a, 0xca, 0x48, 0xad, 0x77, 0x16, 0x68, 0x5a, 0xc6, 0xcf, 0x1a, 0x2c, 0x54, 0xa9, 0xbf, 0xed, - 0xd0, 0xa7, 0x71, 0xe0, 0xe2, 0x51, 0x55, 0x0c, 0x9f, 0xcb, 0x16, 0x0f, 0x91, 0xcc, 0xa5, 0x10, - 0xd0, 0x35, 0x98, 0xab, 0x37, 0x89, 0x7b, 0x60, 0x47, 0xed, 0xb0, 0x8e, 0x63, 0x81, 0x78, 0xca, - 0x9a, 0x15, 0xba, 0x1d, 0xa1, 0x12, 0x04, 0x6f, 0xb7, 0x5a, 0xcd, 0x6e, 0x4a, 0x70, 0x21, 0x99, - 0x06, 0xe8, 0xfd, 0xc8, 0x52, 0xd8, 0xcf, 0xa1, 0x58, 0xa5, 0xfe, 0x0e, 0x5f, 0xae, 0xff, 0x06, - 0xf9, 0x84, 0xe5, 0x5f, 0x81, 0x0b, 0x99, 0xd8, 0x69, 0xd2, 0x57, 0xd3, 0x62, 0xb7, 0xe0, 0xca, - 0xdd, 0x68, 0xb7, 0x4e, 0x71, 0x7c, 0x88, 0xbd, 0xdd, 0x36, 0xab, 0x93, 0x76, 0xe4, 0xd5, 0x3a, - 0x43, 0x30, 0xac, 0x42, 0xc1, 0x75, 0x13, 0xd2, 0xcb, 0xb5, 0xcf, 0x73, 0x05, 0xa7, 0x3d, 0x2a, - 0xc3, 0x12, 0x51, 0xc1, 0x6c, 0xc2, 0xa9, 0x26, 0xcd, 0x26, 0x85, 0xd9, 0x22, 0x39, 0xca, 0x53, - 0x93, 0xf6, 0x9f, 0x82, 0xd1, 0x67, 0x2f, 0x66, 0x53, 0x91, 0x46, 0x4e, 0xb0, 0x9e, 0x71, 0xdb, - 0x3c, 0xfa, 0x8f, 0x3e, 0x84, 0x95, 0x3e, 0x6f, 0xbe, 0x53, 0xb4, 0x29, 0xf6, 0x74, 0x10, 0xae, - 0xcb, 0x19, 0xd7, 0x6d, 0x87, 0x3e, 0xa3, 0xd8, 0x43, 0x2f, 0xc0, 0xec, 0x73, 0xc3, 0xfb, 0xfb, - 0xd8, 0x65, 0xc1, 0x21, 0x16, 0x01, 0xe4, 0xd2, 0xcf, 0x72, 0xcc, 0x9b, 0xe5, 0x97, 0xaf, 0xd7, - 0x26, 0xfe, 0x7c, 0xbd, 0x76, 0xd3, 0x0f, 0x58, 0xa3, 0x5d, 0xe7, 0xec, 0xac, 0xb8, 0x84, 0x86, - 0x84, 0xaa, 0xcf, 0x3a, 0xf5, 0x0e, 0x2a, 0xac, 0xdb, 0xc2, 0xb4, 0xfc, 0x38, 0x62, 0x56, 0x29, - 0x93, 0xf1, 0x61, 0x12, 0x37, 0x59, 0x79, 0xf4, 0xc5, 0x88, 0xdc, 0x72, 0x9b, 0x9b, 0x13, 0xe8, - 0x07, 0xc7, 0x12, 0x9b, 0x1f, 0xda, 0x87, 0x59, 0x7e, 0x04, 0xd9, 0x61, 0x10, 0x31, 0xec, 0x49, - 0xc6, 0x6d, 0x3e, 0x54, 0x80, 0xdf, 0x3d, 0x05, 0xe0, 0x67, 0x41, 0xc4, 0xfe, 0x79, 0xbd, 0x86, - 0xba, 0x4e, 0xd8, 0xbc, 0x6f, 0xf6, 0xc4, 0x32, 0x2d, 0xe0, 0x52, 0x55, 0x08, 0x3d, 0x3d, 0x9a, - 0x3b, 0x45, 0x8f, 0xa2, 0x35, 0x98, 0x95, 0x95, 0x09, 0x6a, 0xaa, 0x2d, 0x1b, 0x84, 0x6a, 0x8b, - 0x6b, 0xd0, 0x4d, 0x38, 0x2f, 0x0d, 0xf8, 0x26, 0x22, 0x49, 0x9b, 0x17, 0x05, 0x17, 0x85, 0xba, - 0x46, 0xa9, 0x20, 0x2c, 0x5a, 0x87, 0x82, 0x4b, 0x82, 0xc8, 0xe6, 0x60, 0xf5, 0x82, 0x48, 0xbd, - 0x90, 0xa4, 0xde, 0x22, 0x41, 0x54, 0xeb, 0xb6, 0xb0, 0x95, 0x77, 0xd5, 0xc8, 0xbc, 0x01, 0xd7, - 0x87, 0x30, 0x3a, 0x65, 0xfe, 0xdf, 0x93, 0x60, 0x1c, 0xb3, 0x7b, 0x1c, 0x8d, 0x26, 0x3e, 0xef, - 0x6d, 0x1c, 0x79, 0x38, 0x56, 0xac, 0x57, 0x12, 0x2f, 0x47, 0x8e, 0xec, 0xbe, 0xa3, 0xb0, 0x28, - 0xd5, 0x5b, 0xaa, 0x43, 0x0d, 0xc8, 0xc7, 0x72, 0xc2, 0x62, 0x75, 0x58, 0xa4, 0x32, 0xba, 0x01, - 0xf3, 0xc9, 0x58, 0x4d, 0xdb, 0xb4, 0x0c, 0x91, 0x68, 0xe5, 0xcc, 0x6d, 0x43, 0xce, 0x09, 0x49, - 0x3b, 0x62, 0x62, 0x25, 0x0a, 0x9b, 0x95, 0x31, 0x17, 0xdb, 0x52, 0xee, 0xbc, 0xca, 0x10, 0x53, - 0xea, 0xf8, 0x72, 0xea, 0x0b, 0x56, 0x22, 0xa2, 0xcb, 0x00, 0x7c, 0xca, 0x55, 0xe3, 0x16, 0x24, - 0xce, 0x20, 0x52, 0xfd, 0x7a, 0x13, 0xce, 0x07, 0x91, 0xec, 0x51, 0xbb, 0x21, 0x9b, 0x54, 0x76, - 0x5a, 0x31, 0x88, 0x7a, 0x3b, 0x33, 0x73, 0x68, 0xcf, 0x0a, 0x8b, 0xf4, 0xd0, 0xce, 0xae, 0xeb, - 0xdc, 0xa8, 0x75, 0xe5, 0xb1, 0x58, 0xc7, 0x26, 0x71, 0xe0, 0x07, 0x91, 0x5e, 0x94, 0x80, 0x58, - 0x67, 0x57, 0xc8, 0x7c, 0xdb, 0x73, 0x28, 0xc5, 0x4c, 0x9f, 0x17, 0x3f, 0xa4, 0x60, 0xbe, 0x03, - 0xe6, 0xe0, 0x25, 0x4e, 0x99, 0xf0, 0xbd, 0x06, 0xf3, 0x55, 0xea, 0xef, 0x61, 0xb6, 0x43, 0x3c, - 0xfc, 0x04, 0x77, 0x87, 0x5d, 0xbe, 0x2a, 0x50, 0x90, 0xe7, 0xdd, 0x1e, 0x66, 0x82, 0x00, 0xb3, - 0x1b, 0x8b, 0x09, 0xe8, 0xa7, 0xed, 0xfa, 0x13, 0xf1, 0xc3, 0x3a, 0xb2, 0x41, 0xb7, 0x01, 0x71, - 0x7e, 0xd3, 0xc0, 0x8f, 0x70, 0x6c, 0xab, 0x0b, 0x93, 0xda, 0x09, 0x17, 0x18, 0xa5, 0x7b, 0xe2, - 0x87, 0xd2, 0x9b, 0x3a, 0x5c, 0xcc, 0x42, 0x49, 0x50, 0x6e, 0xfc, 0x56, 0x80, 0xc9, 0x2a, 0xf5, - 0xd1, 0x77, 0x1a, 0x2c, 0x1e, 0xbf, 0xcb, 0xdc, 0x2d, 0x0f, 0xbd, 0x8f, 0x96, 0x4f, 0xba, 0x84, - 0x18, 0x9f, 0x9c, 0xc1, 0x29, 0xc1, 0x83, 0x7e, 0xd4, 0xe0, 0xe2, 0x80, 0x7b, 0xcb, 0xbd, 0xd1, - 0x71, 0x4f, 0xf6, 0x34, 0x3e, 0x3b, 0xab, 0x67, 0x0a, 0xeb, 0x1b, 0x98, 0xef, 0xbb, 0xbf, 0xdc, - 0x19, 0x1d, 0x33, 0xeb, 0x61, 0xdc, 0x1b, 0xd7, 0x23, 0xcd, 0xde, 0x85, 0x62, 0xf6, 0xda, 0x51, - 0x19, 0x1d, 0x2a, 0xe3, 0x60, 0x7c, 0x34, 0xa6, 0x43, 0x9a, 0xba, 0x05, 0xd0, 0x73, 0x77, 0xb8, - 0x3d, 0x3a, 0xcc, 0x91, 0xb5, 0xf1, 0xc1, 0x38, 0xd6, 0x69, 0xc6, 0x5f, 0x34, 0xd0, 0x07, 0x5e, - 0x1c, 0xee, 0x8f, 0x0e, 0x39, 0xc8, 0xd7, 0xd8, 0x3c, 0xbb, 0x6f, 0x0a, 0xee, 0x27, 0x0d, 0x56, - 0x06, 0xed, 0xed, 0x1f, 0x8f, 0x1b, 0x3f, 0x75, 0x35, 0x1e, 0x9c, 0xd9, 0xb5, 0x97, 0xa1, 0x7d, - 0x8f, 0xaf, 0x53, 0x30, 0x34, 0xeb, 0x71, 0x1a, 0x86, 0x9e, 0xfc, 0x18, 0x42, 0xdf, 0x6a, 0xb0, - 0x70, 0xec, 0xad, 0xb9, 0x31, 0x3a, 0x5c, 0xbf, 0x8f, 0x71, 0x7f, 0x7c, 0x9f, 0x04, 0xc4, 0xe6, - 0x93, 0x97, 0x6f, 0x4a, 0xda, 0xab, 0x37, 0x25, 0xed, 0xaf, 0x37, 0x25, 0xed, 0x87, 0xb7, 0xa5, - 0x89, 0x57, 0x6f, 0x4b, 0x13, 0x7f, 0xbc, 0x2d, 0x4d, 0x3c, 0x7f, 0xbf, 0xe7, 0x04, 0xe3, 0x51, - 0xd7, 0xe5, 0xb3, 0x3b, 0x49, 0x50, 0xe9, 0x54, 0x7a, 0x1f, 0xe3, 0xfc, 0x40, 0xab, 0xe7, 0xc4, - 0x33, 0xfa, 0xee, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7d, 0xa2, 0x25, 0x9b, 0xa7, 0x0f, 0x00, + // 1361 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6e, 0xdb, 0xc6, + 0x13, 0x37, 0x63, 0x5b, 0x96, 0xc6, 0x96, 0x63, 0xaf, 0x9d, 0x98, 0xa1, 0x13, 0x39, 0xa1, 0xff, + 0xc9, 0x3f, 0x28, 0x62, 0x29, 0x75, 0x5a, 0x34, 0x4d, 0x7b, 0x68, 0x6c, 0xa4, 0x8e, 0x9b, 0xca, + 0x0e, 0x68, 0xa5, 0x05, 0x72, 0x21, 0x28, 0x72, 0x4d, 0x11, 0x16, 0xb9, 0x02, 0x77, 0x65, 0x48, + 0x41, 0x4f, 0x05, 0x7a, 0xe8, 0xad, 0x87, 0x02, 0x2d, 0xfa, 0x02, 0x7d, 0x95, 0xf4, 0x16, 0xf4, + 0xd4, 0xf6, 0x10, 0xb4, 0xc9, 0x1b, 0xf4, 0x09, 0x8a, 0xfd, 0x20, 0x2d, 0xca, 0x96, 0x64, 0xbb, + 0xe8, 0x89, 0x3b, 0xb3, 0xf3, 0xf1, 0x9b, 0x9d, 0x99, 0xdd, 0x21, 0x2c, 0xb8, 0x31, 0xa1, 0xd4, + 0x6d, 0x38, 0x41, 0x54, 0x61, 0x9d, 0x72, 0x2b, 0x26, 0x8c, 0xa0, 0x6b, 0x2f, 0x30, 0x73, 0x04, + 0xaf, 0x2c, 0x56, 0x24, 0xc6, 0xe5, 0x23, 0x39, 0x63, 0xc1, 0x25, 0x61, 0x48, 0xa2, 0x8a, 0xfc, + 0x48, 0x1d, 0x63, 0xd1, 0x27, 0x3e, 0x11, 0xcb, 0x0a, 0x5f, 0x49, 0xae, 0xb9, 0x03, 0x0b, 0x55, + 0xea, 0x3f, 0x6b, 0x79, 0x0e, 0xc3, 0x35, 0x4a, 0x1f, 0x7a, 0x5e, 0x8c, 0x29, 0x45, 0x3a, 0x4c, + 0xb9, 0x31, 0x76, 0x18, 0x89, 0x75, 0xed, 0xba, 0x76, 0xbb, 0x60, 0x25, 0x24, 0xba, 0x06, 0xc0, + 0x28, 0xb5, 0x5b, 0xed, 0xfa, 0x01, 0xee, 0xea, 0x17, 0xc4, 0x66, 0x81, 0x51, 0xfa, 0x54, 0x30, + 0xcc, 0x6b, 0xb0, 0x7c, 0x82, 0x3d, 0x0b, 0xd3, 0x16, 0x89, 0x28, 0x36, 0x7f, 0xd5, 0x60, 0xbe, + 0x4a, 0xfd, 0x2f, 0x1b, 0x01, 0xc3, 0xcd, 0x80, 0xb2, 0x47, 0xd6, 0xe6, 0xfa, 0xdd, 0x21, 0xde, + 0x56, 0xa1, 0x88, 0x63, 0x77, 0xfd, 0xae, 0xed, 0x48, 0x43, 0xca, 0xe1, 0x8c, 0x60, 0x26, 0x60, + 0xaf, 0x40, 0x5e, 0xc4, 0x6d, 0x07, 0x9e, 0x3e, 0x7e, 0x5d, 0xbb, 0x3d, 0x6e, 0x4d, 0x09, 0x7a, + 0xdb, 0x43, 0x08, 0x26, 0x22, 0x27, 0xc4, 0xfa, 0x84, 0x50, 0x13, 0x6b, 0x74, 0x19, 0x72, 0xb4, + 0x1b, 0xd6, 0x49, 0x53, 0x9f, 0x14, 0x5c, 0x45, 0x21, 0x03, 0xf2, 0x1e, 0x76, 0x83, 0xd0, 0x69, + 0x52, 0x3d, 0x77, 0x5d, 0xbb, 0x5d, 0xb4, 0x52, 0x1a, 0x2d, 0x43, 0xc1, 0x77, 0xa8, 0xdd, 0x0c, + 0xc2, 0x80, 0xe9, 0x53, 0xc2, 0x47, 0xde, 0x77, 0xe8, 0xe7, 0x9c, 0x36, 0x97, 0xe1, 0xca, 0xb1, + 0x98, 0xd2, 0x88, 0x7f, 0xd7, 0x60, 0xb1, 0x4a, 0xfd, 0x87, 0x9e, 0x57, 0x23, 0xbb, 0x6d, 0x56, + 0xeb, 0xd4, 0x62, 0xc7, 0x3d, 0xc0, 0xf1, 0x90, 0xa0, 0x7b, 0xe3, 0xb9, 0x90, 0x8d, 0x67, 0x11, + 0x26, 0x23, 0x12, 0xb9, 0x58, 0xc4, 0x39, 0x61, 0x49, 0x02, 0x2d, 0xc1, 0x14, 0xeb, 0xd8, 0x0d, + 0x87, 0x36, 0x54, 0xa0, 0x39, 0xd6, 0x79, 0xec, 0xd0, 0x06, 0x5a, 0x85, 0xc9, 0x56, 0x4c, 0xc8, + 0xbe, 0x88, 0x74, 0x7a, 0xbd, 0x58, 0x56, 0x15, 0xf1, 0x94, 0x33, 0x2d, 0xb9, 0xc7, 0x33, 0x5a, + 0x6f, 0x12, 0xf7, 0x40, 0x1a, 0xc8, 0xc9, 0x8c, 0x0a, 0x8e, 0xb0, 0x71, 0x05, 0xf2, 0xac, 0x63, + 0x07, 0x91, 0x87, 0x3b, 0x2a, 0xf2, 0x29, 0xd6, 0xd9, 0xe6, 0xa4, 0x59, 0x82, 0xab, 0x27, 0x85, + 0x96, 0xc6, 0xbe, 0x2f, 0x0e, 0xc6, 0xc2, 0x21, 0x39, 0xc4, 0x9f, 0xc6, 0x24, 0xfc, 0x8f, 0xe2, + 0x37, 0x57, 0xe1, 0xc6, 0x40, 0x3f, 0x29, 0x98, 0x9f, 0x65, 0xe9, 0x6d, 0x72, 0x27, 0xb8, 0xb6, + 0xb7, 0xf7, 0x05, 0x61, 0x43, 0x51, 0x0c, 0x2f, 0x74, 0xf4, 0x0e, 0xcc, 0x1d, 0xe0, 0xee, 0x16, + 0x8e, 0x9e, 0x63, 0xe6, 0x3c, 0xc6, 0x81, 0xdf, 0x60, 0xaa, 0xf8, 0x8e, 0xf1, 0xd1, 0x1a, 0xe4, + 0x28, 0x73, 0x58, 0x9b, 0x8a, 0xf4, 0xcc, 0xae, 0x5f, 0x4a, 0xf2, 0x60, 0x61, 0x17, 0x07, 0x87, + 0x78, 0x4f, 0x6c, 0x5a, 0x4a, 0x48, 0xd5, 0x53, 0x16, 0x68, 0x1a, 0xc6, 0x8f, 0x1a, 0xcc, 0x55, + 0xa9, 0xbf, 0xe5, 0xd0, 0xa7, 0x71, 0xe0, 0xe2, 0x51, 0x51, 0x0c, 0x3f, 0xcb, 0x16, 0x37, 0x91, + 0x9c, 0xa5, 0x20, 0xd0, 0x0d, 0x98, 0x91, 0xd5, 0x10, 0xb5, 0xc3, 0x3a, 0x8e, 0x05, 0xe2, 0x09, + 0x6b, 0x5a, 0xf0, 0x76, 0x04, 0x4b, 0x34, 0x50, 0xbb, 0xd5, 0x6a, 0x76, 0xd3, 0x06, 0x12, 0x94, + 0x69, 0x80, 0xde, 0x8f, 0x2c, 0x85, 0xfd, 0x1c, 0x8a, 0x55, 0xea, 0xef, 0xf0, 0x74, 0xfd, 0x3b, + 0xc8, 0x27, 0xa4, 0x7f, 0x09, 0x2e, 0x65, 0x6c, 0x1f, 0xf5, 0xde, 0xa4, 0xb8, 0x8d, 0x38, 0x73, + 0x37, 0xda, 0xad, 0x53, 0x1c, 0x1f, 0x62, 0x6f, 0xb7, 0xcd, 0xea, 0xa4, 0x1d, 0x79, 0xb5, 0xce, + 0x10, 0x0c, 0xcb, 0x50, 0x70, 0xdd, 0xa4, 0xa7, 0x64, 0xee, 0xf3, 0x9c, 0x21, 0x3a, 0xa2, 0x0c, + 0x0b, 0x44, 0x19, 0xb3, 0x09, 0x2f, 0x35, 0x29, 0x36, 0x2e, 0xc4, 0xe6, 0xc9, 0x91, 0x9f, 0x9a, + 0x94, 0xff, 0x18, 0x8c, 0x3e, 0x79, 0xd9, 0x5d, 0xb2, 0x68, 0xe4, 0x01, 0xeb, 0x19, 0xb5, 0x8d, + 0xa3, 0x7d, 0xf4, 0x3e, 0x2c, 0xf5, 0x69, 0xf3, 0x9b, 0xa8, 0x4d, 0xb1, 0xa7, 0x83, 0x50, 0x5d, + 0xcc, 0xa8, 0x6e, 0x39, 0xf4, 0x19, 0xc5, 0x1e, 0x7a, 0x01, 0x66, 0x9f, 0x1a, 0xde, 0xdf, 0xc7, + 0x2e, 0x0b, 0x0e, 0xb1, 0x30, 0x20, 0x53, 0x3f, 0xcd, 0x31, 0x6f, 0x94, 0x5f, 0xbe, 0x5e, 0x19, + 0xfb, 0xe3, 0xf5, 0xca, 0x2d, 0x3f, 0x60, 0x8d, 0x76, 0x9d, 0x57, 0x67, 0xc5, 0x25, 0x34, 0x24, + 0x54, 0x7d, 0xd6, 0xa8, 0x77, 0x50, 0x61, 0xdd, 0x16, 0xa6, 0xe5, 0xed, 0x88, 0x59, 0xa5, 0x8c, + 0xc7, 0x47, 0x89, 0xdd, 0x24, 0xf3, 0xe8, 0xb3, 0x11, 0xbe, 0xe5, 0x35, 0x3a, 0x23, 0xd0, 0x0f, + 0xb6, 0x25, 0x2e, 0x57, 0x44, 0x60, 0xf6, 0xd0, 0x69, 0xb6, 0xb1, 0x1d, 0xcb, 0x5e, 0xf1, 0x64, + 0xd1, 0x6d, 0x3c, 0x56, 0x98, 0xff, 0x7f, 0x0a, 0xcc, 0xcf, 0x82, 0x88, 0xfd, 0xfd, 0x7a, 0xe5, + 0x52, 0xd7, 0x09, 0x9b, 0x0f, 0xcc, 0xac, 0x39, 0xd3, 0x2a, 0x0a, 0x86, 0x6a, 0x45, 0xaf, 0xa7, + 0x59, 0x73, 0xa7, 0x68, 0x56, 0xb4, 0x02, 0xd3, 0x32, 0x44, 0x51, 0xa3, 0xea, 0x86, 0x04, 0xc1, + 0xda, 0xe4, 0x1c, 0x74, 0x0b, 0x2e, 0x4a, 0x01, 0x7e, 0x9b, 0xc8, 0xea, 0xcd, 0x8b, 0xc8, 0x8b, + 0x82, 0x5d, 0xa3, 0x54, 0x54, 0x2e, 0x5a, 0x83, 0x82, 0x4b, 0x82, 0xc8, 0xe6, 0x90, 0xf5, 0x82, + 0x70, 0x3d, 0x97, 0xb8, 0xde, 0x24, 0x41, 0x54, 0xeb, 0xb6, 0xb0, 0x95, 0x77, 0xd5, 0xca, 0xbc, + 0x09, 0xab, 0x43, 0x4a, 0x3b, 0x6d, 0x81, 0xbf, 0xc6, 0xc1, 0x38, 0x26, 0xb7, 0x1d, 0x8d, 0xee, + 0x00, 0xde, 0xe4, 0x38, 0xf2, 0x70, 0xac, 0xca, 0x5f, 0x51, 0x3c, 0x1c, 0xb9, 0xb2, 0xfb, 0xde, + 0xdc, 0xa2, 0x64, 0x6f, 0xaa, 0x56, 0x35, 0x20, 0xaf, 0x8e, 0x38, 0x56, 0x8f, 0x52, 0x4a, 0xa3, + 0x9b, 0x30, 0x9b, 0xac, 0xd5, 0xb1, 0x4d, 0x4a, 0x13, 0x09, 0x57, 0x9e, 0xdc, 0x16, 0xe4, 0x9c, + 0x90, 0xb4, 0x23, 0x26, 0x1f, 0xa5, 0x8d, 0xca, 0x19, 0x53, 0x6e, 0x29, 0x75, 0x1e, 0x65, 0x88, + 0x29, 0x75, 0x7c, 0x79, 0xf4, 0x05, 0x2b, 0x21, 0xd1, 0x55, 0x00, 0x7e, 0xe4, 0xaa, 0x83, 0x0b, + 0x12, 0x67, 0x10, 0xa9, 0xc6, 0xbd, 0x05, 0x17, 0x83, 0xc8, 0x56, 0x8f, 0xa3, 0xec, 0x56, 0xd9, + 0x72, 0xc5, 0x20, 0xea, 0x6d, 0xd1, 0xcc, 0x74, 0x30, 0x2d, 0x24, 0xd2, 0xe9, 0x20, 0x9b, 0xd7, + 0x99, 0x51, 0x79, 0xe5, 0xb6, 0x58, 0xc7, 0x26, 0x71, 0xe0, 0x07, 0x91, 0x5e, 0x94, 0x80, 0x58, + 0x67, 0x57, 0xd0, 0xfc, 0xfe, 0x73, 0x28, 0xc5, 0x4c, 0x9f, 0x15, 0x1b, 0x92, 0x30, 0xff, 0x07, + 0xe6, 0xe0, 0x14, 0xa7, 0x95, 0xf0, 0xad, 0x06, 0xb3, 0x55, 0xea, 0xef, 0x61, 0xb6, 0x43, 0x3c, + 0xfc, 0x04, 0x77, 0x87, 0x4d, 0x79, 0x15, 0x28, 0xc8, 0x87, 0x6f, 0x0f, 0x33, 0x51, 0x00, 0xd3, + 0xeb, 0xf3, 0xe9, 0xf0, 0xd0, 0xae, 0x3f, 0x11, 0x1b, 0xd6, 0x91, 0x0c, 0xba, 0x03, 0x88, 0xd7, + 0x37, 0x0d, 0xfc, 0x08, 0xc7, 0xb6, 0x9a, 0xcc, 0xd4, 0x95, 0x38, 0xc7, 0x28, 0xdd, 0x13, 0x1b, + 0x8a, 0x6f, 0xea, 0x70, 0x39, 0x0b, 0x25, 0x41, 0xb9, 0xfe, 0x4b, 0x01, 0xc6, 0xab, 0xd4, 0x47, + 0xdf, 0x68, 0x30, 0x7f, 0x7c, 0x66, 0xba, 0x57, 0x1e, 0x3a, 0xf8, 0x96, 0x4f, 0x9a, 0x46, 0x8c, + 0x8f, 0xce, 0xa1, 0x94, 0xe0, 0x41, 0xdf, 0x6b, 0x70, 0x79, 0xc0, 0x00, 0x73, 0x7f, 0xb4, 0xdd, + 0x93, 0x35, 0x8d, 0x4f, 0xce, 0xab, 0x99, 0xc2, 0xfa, 0x0a, 0x66, 0xfb, 0x06, 0x99, 0xbb, 0xa3, + 0x6d, 0x66, 0x35, 0x8c, 0xfb, 0x67, 0xd5, 0x48, 0xbd, 0x77, 0xa1, 0x98, 0x9d, 0x3f, 0x2a, 0xa3, + 0x4d, 0x65, 0x14, 0x8c, 0x0f, 0xce, 0xa8, 0x90, 0xba, 0x6e, 0x01, 0xf4, 0x0c, 0x11, 0x77, 0x46, + 0x9b, 0x39, 0x92, 0x36, 0xde, 0x3b, 0x8b, 0x74, 0xea, 0xf1, 0x27, 0x0d, 0xf4, 0x81, 0x13, 0xc4, + 0x83, 0xd1, 0x26, 0x07, 0xe9, 0x1a, 0x1b, 0xe7, 0xd7, 0x4d, 0xc1, 0xfd, 0xa0, 0xc1, 0xd2, 0xa0, + 0xbb, 0xfd, 0xc3, 0xb3, 0xda, 0x4f, 0x55, 0x8d, 0x87, 0xe7, 0x56, 0xed, 0xad, 0xd0, 0xbe, 0xbf, + 0xbc, 0x53, 0x54, 0x68, 0x56, 0xe3, 0x34, 0x15, 0x7a, 0xf2, 0x5f, 0x17, 0xfa, 0x5a, 0x83, 0xb9, + 0x63, 0x3f, 0xb5, 0xeb, 0xa3, 0xcd, 0xf5, 0xeb, 0x18, 0x0f, 0xce, 0xae, 0x93, 0x80, 0xd8, 0x78, + 0xf2, 0xf2, 0x4d, 0x49, 0x7b, 0xf5, 0xa6, 0xa4, 0xfd, 0xf9, 0xa6, 0xa4, 0x7d, 0xf7, 0xb6, 0x34, + 0xf6, 0xea, 0x6d, 0x69, 0xec, 0xb7, 0xb7, 0xa5, 0xb1, 0xe7, 0xef, 0xf6, 0xbc, 0x60, 0xdc, 0xea, + 0x9a, 0xfc, 0xbf, 0x4f, 0x1c, 0x54, 0x3a, 0x95, 0xde, 0xbf, 0x7e, 0xfe, 0xa0, 0xd5, 0x73, 0xe2, + 0x7f, 0xfd, 0xde, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x41, 0x25, 0x03, 0x10, 0x10, 0x00, 0x00, } @@ -1829,6 +1856,30 @@ func (m *MsgAddToOutTxTracker) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TxIndex != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TxIndex)) + i-- + dAtA[i] = 0x38 + } + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0x32 + } + if m.Proof != nil { + { + size, err := m.Proof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } if len(m.TxHash) > 0 { i -= len(m.TxHash) copy(dAtA[i:], m.TxHash) @@ -2211,9 +2262,9 @@ func (m *MsgVoteOnObservedOutboundTx) MarshalToSizedBuffer(dAtA []byte) (int, er dAtA[i] = 0x30 } { - size := m.ZetaMinted.Size() + size := m.ValueReceived.Size() i -= size - if _, err := m.ZetaMinted.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.ValueReceived.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintTx(dAtA, i, uint64(size)) @@ -2574,6 +2625,17 @@ func (m *MsgAddToOutTxTracker) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.Proof != nil { + l = m.Proof.Size() + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.TxIndex != 0 { + n += 1 + sovTx(uint64(m.TxIndex)) + } return n } @@ -2730,7 +2792,7 @@ func (m *MsgVoteOnObservedOutboundTx) Size() (n int) { if m.ObservedOutTxBlockHeight != 0 { n += 1 + sovTx(uint64(m.ObservedOutTxBlockHeight)) } - l = m.ZetaMinted.Size() + l = m.ValueReceived.Size() n += 1 + l + sovTx(uint64(l)) if m.Status != 0 { n += 1 + sovTx(uint64(m.Status)) @@ -3443,6 +3505,93 @@ func (m *MsgAddToOutTxTracker) Unmarshal(dAtA []byte) error { } m.TxHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Proof == nil { + m.Proof = &common.Proof{} + } + if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", 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.BlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxIndex", wireType) + } + m.TxIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxIndex |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4423,7 +4572,7 @@ func (m *MsgVoteOnObservedOutboundTx) Unmarshal(dAtA []byte) error { } case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ZetaMinted", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValueReceived", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4451,7 +4600,7 @@ func (m *MsgVoteOnObservedOutboundTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ZetaMinted.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ValueReceived.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts.go index 495a51563d..8425f4e9a0 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts.go @@ -1,5 +1,5 @@ -//go:build !PRIVNET && !TESTNET -// +build !PRIVNET,!TESTNET +//go:build !PRIVNET && !TESTNET && !MOCK_MAINNET +// +build !PRIVNET,!TESTNET,!MOCK_MAINNET package keeper diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go new file mode 100644 index 0000000000..44a45dacc9 --- /dev/null +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go @@ -0,0 +1,18 @@ +//go:build MOCK_MAINNET +// +build MOCK_MAINNET + +package keeper + +import ( + "context" +) + +func (k Keeper) BlockOneDeploySystemContracts(_ context.Context) error { + return nil +} +func (k Keeper) TestUpdateSystemContractAddress(_ context.Context) error { + return nil +} +func (k Keeper) TestUpdateZRC20WithdrawFee(_ context.Context) error { + return nil +} diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go index 21a04c7f64..579767fe35 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go @@ -81,15 +81,17 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error { return err } - _, err = k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) + ETHZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } + ctx.Logger().Info("Deployed ETH ZRC20 at " + ETHZRC20Addr.String()) - _, err = k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8) + BTCZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } + ctx.Logger().Info("Deployed BTC ZRC20 at " + BTCZRC20Addr.String()) //FIXME: clean up and config the above based on localnet/testnet/mainnet @@ -131,8 +133,9 @@ func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error { return sdkerrors.Wrapf(err, "failed to DeploySystemContract") } creator := k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin) - msg := types.NewMessageUpdateSystemContract(creator, SystemContractAddress.Hex()) + msg := types.NewMsgUpdateSystemContract(creator, SystemContractAddress.Hex()) _, err = k.UpdateSystemContract(ctx, msg) + k.Logger(ctx).Info("System contract updated", "new address", SystemContractAddress.String()) return err } diff --git a/x/fungible/keeper/deposits.go b/x/fungible/keeper/deposits.go index c95f6ed48f..8206f744bc 100644 --- a/x/fungible/keeper/deposits.go +++ b/x/fungible/keeper/deposits.go @@ -17,26 +17,28 @@ func (k Keeper) DepositCoinZeta(ctx sdk.Context, to eth.Address, amount *big.Int return k.MintZetaToEVMAccount(ctx, zetaToAddress, amount) } -func (k Keeper) ZRC20DepositAndCallContract(ctx sdk.Context, from []byte, to eth.Address, amount *big.Int, senderChain *common.Chain, - message string, contract eth.Address, data []byte, coinType common.CoinType, asset string) (*evmtypes.MsgEthereumTxResponse, error) { +func (k Keeper) ZRC20DepositAndCallContract( + ctx sdk.Context, + from []byte, + to eth.Address, + amount *big.Int, + senderChain *common.Chain, + message string, + contract eth.Address, + data []byte, + coinType common.CoinType, + asset string, +) (*evmtypes.MsgEthereumTxResponse, error) { var Zrc20Contract eth.Address var coin fungibletypes.ForeignCoins + var found bool if coinType == common.CoinType_Gas { - var found bool coin, found = k.GetGasCoinForForeignCoin(ctx, senderChain.ChainId) if !found { return nil, types.ErrGasCoinNotFound } } else { - foreignCoinList := k.GetAllForeignCoinsForChain(ctx, senderChain.ChainId) - found := false - for _, foreignCoin := range foreignCoinList { - if foreignCoin.Asset == asset && foreignCoin.ForeignChainId == senderChain.ChainId { - coin = foreignCoin - found = true - break - } - } + coin, found = k.GetForeignCoinFromAsset(ctx, asset, senderChain.ChainId) if !found { return nil, types.ErrForeignCoinNotFound } diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 731b57cad6..df739a5157 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -3,6 +3,7 @@ package keeper import ( "encoding/hex" "encoding/json" + "errors" "fmt" "math/big" "strconv" @@ -37,12 +38,13 @@ var ( ZEVMGasLimitDepositAndCall = big.NewInt(1_000_000) ) -func (k Keeper) deployContract(ctx sdk.Context, metadata *bind.MetaData, ctorArguments ...interface{}) (common.Address, error) { - abi, err := metadata.GetAbi() +// DeployContract deploys a new contract in the ZEVM +func (k Keeper) DeployContract(ctx sdk.Context, metadata *bind.MetaData, ctorArguments ...interface{}) (common.Address, error) { + contractABI, err := metadata.GetAbi() if err != nil { return common.Address{}, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get ABI: %s", err.Error()) } - ctorArgs, err := abi.Pack( + ctorArgs, err := contractABI.Pack( "", // function--empty string for constructor ctorArguments..., // feeToSetter ) @@ -103,7 +105,7 @@ func (k Keeper) DeployZRC20Contract( if !found { return common.Address{}, cosmoserrors.Wrapf(types.ErrSystemContractNotFound, "system contract not found") } - contractAddr, err := k.deployContract(ctx, zrc20.ZRC20MetaData, + contractAddr, err := k.DeployContract(ctx, zrc20.ZRC20MetaData, name, // name symbol, // symbol decimals, // decimals @@ -133,7 +135,7 @@ func (k Keeper) DeployZRC20Contract( func (k Keeper) DeploySystemContract(ctx sdk.Context, wzeta common.Address, v2factory common.Address, router02 common.Address) (common.Address, error) { system, _ := k.GetSystemContract(ctx) - contractAddr, err := k.deployContract(ctx, systemcontract.SystemContractMetaData, wzeta, v2factory, router02) + contractAddr, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, v2factory, router02) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "failed to deploy SystemContract") } @@ -149,7 +151,7 @@ func (k Keeper) DeployUniswapV2Factory(ctx sdk.Context) (common.Address, error) // https://etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f#code refFactoryBytecode := "0x608060405234801561001057600080fd5b506040516136863803806136868339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055613623806100636000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a2e74af61161005b578063a2e74af6146100fd578063c9c6539614610132578063e6a439051461016d578063f46901ed146101a857610088565b8063017e7e581461008d578063094b7415146100be5780631e3dd18b146100c6578063574f2ba3146100e3575b600080fd5b6100956101db565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100956101f7565b610095600480360360208110156100dc57600080fd5b5035610213565b6100eb610247565b60408051918252519081900360200190f35b6101306004803603602081101561011357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661024d565b005b6100956004803603604081101561014857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661031a565b6100956004803603604081101561018357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661076d565b610130600480360360208110156101be57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a0565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6003818154811061022057fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035490565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102d357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056323a204944454e544943414c5f4144445245535345530000604482015290519081900360640190fd5b6000808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106103f45783856103f7565b84845b909250905073ffffffffffffffffffffffffffffffffffffffff821661047e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f556e697377617056323a205a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526002602090815260408083208585168452909152902054161561051f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f556e697377617056323a20504149525f45584953545300000000000000000000604482015290519081900360640190fd5b6060604051806020016105319061086d565b6020820181038252601f19601f82011660405250905060008383604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f5604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152868116602483015291519297509087169163485cc9559160448082019260009290919082900301818387803b15801561065e57600080fd5b505af1158015610672573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff84811660008181526002602081815260408084208987168086529083528185208054978d167fffffffffffffffffffffffff000000000000000000000000000000000000000098891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a35050505092915050565b600260209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b612d748061087b8339019056fe60806040526001600c5534801561001557600080fd5b506040514690806052612d228239604080519182900360520182208282018252600a8352692ab734b9bbb0b8102b1960b11b6020938401528151808301835260018152603160f81b908401528151808401919091527fbfcc8ef98ffbf7b6c3fec7bf5185b566b9863e35a9d83acd49ad6824b5969738818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060035550600580546001600160a01b03191633179055612c1d806101056000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a7146105da578063d505accf146105e2578063dd62ed3e14610640578063fff6cae91461067b576101b9565b8063ba9a7a5614610597578063bc25cf771461059f578063c45a0155146105d2576101b9565b80637ecebe00116100d35780637ecebe00146104d757806389afcb441461050a57806395d89b4114610556578063a9059cbb1461055e576101b9565b80636a6278421461046957806370a082311461049c5780637464fc3d146104cf576101b9565b806323b872dd116101665780633644e515116101405780633644e51514610416578063485cc9551461041e5780635909c0d5146104595780635a3d549314610461576101b9565b806323b872dd146103ad57806330adf81f146103f0578063313ce567146103f8576101b9565b8063095ea7b311610197578063095ea7b3146103155780630dfe16811461036257806318160ddd14610393576101b9565b8063022c0d9f146101be57806306fdde03146102595780630902f1ac146102d6575b600080fd5b610257600480360360808110156101d457600080fd5b81359160208101359173ffffffffffffffffffffffffffffffffffffffff604083013516919081019060808101606082013564010000000081111561021857600080fd5b82018360208201111561022a57600080fd5b8035906020019184600183028401116401000000008311171561024c57600080fd5b509092509050610683565b005b610261610d57565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029b578181015183820152602001610283565b50505050905090810190601f1680156102c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102de610d90565b604080516dffffffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b61034e6004803603604081101561032b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610de5565b604080519115158252519081900360200190f35b61036a610dfc565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61039b610e18565b60408051918252519081900360200190f35b61034e600480360360608110156103c357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e1e565b61039b610efd565b610400610f21565b6040805160ff9092168252519081900360200190f35b61039b610f26565b6102576004803603604081101561043457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610f2c565b61039b611005565b61039b61100b565b61039b6004803603602081101561047f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611011565b61039b600480360360208110156104b257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113cb565b61039b6113dd565b61039b600480360360208110156104ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113e3565b61053d6004803603602081101561052057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113f5565b6040805192835260208301919091528051918290030190f35b610261611892565b61034e6004803603604081101561057457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356118cb565b61039b6118d8565b610257600480360360208110156105b557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118de565b61036a611ad4565b61036a611af0565b610257600480360360e08110156105f857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611b0c565b61039b6004803603604081101561065657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611dd8565b610257611df5565b600c546001146106f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55841515806107075750600084115b61075c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612b2f6025913960400191505060405180910390fd5b600080610767610d90565b5091509150816dffffffffffffffffffffffffffff168710801561079a5750806dffffffffffffffffffffffffffff1686105b6107ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b786021913960400191505060405180910390fd5b600654600754600091829173ffffffffffffffffffffffffffffffffffffffff91821691908116908916821480159061085457508073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b6108bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f556e697377617056323a20494e56414c49445f544f0000000000000000000000604482015290519081900360640190fd5b8a156108d0576108d0828a8d611fdb565b89156108e1576108e1818a8c611fdb565b86156109c3578873ffffffffffffffffffffffffffffffffffffffff166310d1e85c338d8d8c8c6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050505b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d6020811015610a5957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191955073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d6020811015610af557600080fd5b5051925060009150506dffffffffffffffffffffffffffff85168a90038311610b1f576000610b35565b89856dffffffffffffffffffffffffffff160383035b9050600089856dffffffffffffffffffffffffffff16038311610b59576000610b6f565b89856dffffffffffffffffffffffffffff160383035b90506000821180610b805750600081115b610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612b546024913960400191505060405180910390fd5b6000610c09610beb84600363ffffffff6121e816565b610bfd876103e863ffffffff6121e816565b9063ffffffff61226e16565b90506000610c21610beb84600363ffffffff6121e816565b9050610c59620f4240610c4d6dffffffffffffffffffffffffffff8b8116908b1663ffffffff6121e816565b9063ffffffff6121e816565b610c69838363ffffffff6121e816565b1015610cd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f556e697377617056323a204b0000000000000000000000000000000000000000604482015290519081900360640190fd5b5050610ce4848488886122e0565b60408051838152602081018390528082018d9052606081018c9052905173ffffffffffffffffffffffffffffffffffffffff8b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600a81526020017f556e69737761702056320000000000000000000000000000000000000000000081525081565b6008546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000008304909116917c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690565b6000610df233848461259c565b5060015b92915050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610ee85773ffffffffffffffffffffffffffffffffffffffff84166000908152600260209081526040808320338452909152902054610eb6908363ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b610ef384848461260b565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b60055473ffffffffffffffffffffffffffffffffffffffff163314610fb257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c5460011461108457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611094610d90565b50600654604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905193955091935060009273ffffffffffffffffffffffffffffffffffffffff909116916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905192935060009273ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b505190506000611201836dffffffffffffffffffffffffffff871663ffffffff61226e16565b90506000611225836dffffffffffffffffffffffffffff871663ffffffff61226e16565b9050600061123387876126ec565b600054909150806112705761125c6103e8610bfd611257878763ffffffff6121e816565b612878565b985061126b60006103e86128ca565b6112cd565b6112ca6dffffffffffffffffffffffffffff8916611294868463ffffffff6121e816565b8161129b57fe5b046dffffffffffffffffffffffffffff89166112bd868563ffffffff6121e816565b816112c457fe5b0461297a565b98505b60008911611326576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612bc16028913960400191505060405180910390fd5b6113308a8a6128ca565b61133c86868a8a6122e0565b811561137e5760085461137a906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c5460011461146957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611479610d90565b50600654600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905194965092945073ffffffffffffffffffffffffffffffffffffffff9182169391169160009184916370a08231916024808301926020929190829003018186803b1580156114fb57600080fd5b505afa15801561150f573d6000803e3d6000fd5b505050506040513d602081101561152557600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561159957600080fd5b505afa1580156115ad573d6000803e3d6000fd5b505050506040513d60208110156115c357600080fd5b5051306000908152600160205260408120549192506115e288886126ec565b600054909150806115f9848763ffffffff6121e816565b8161160057fe5b049a5080611614848663ffffffff6121e816565b8161161b57fe5b04995060008b11801561162e575060008a115b611683576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612b996028913960400191505060405180910390fd5b61168d3084612992565b611698878d8d611fdb565b6116a3868d8c611fdb565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8916916370a08231916024808301926020929190829003018186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191965073ffffffffffffffffffffffffffffffffffffffff8816916370a0823191602480820192602092909190829003018186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d60208110156117d557600080fd5b505193506117e585858b8b6122e0565b811561182757600854611823906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b604080518c8152602081018c9052815173ffffffffffffffffffffffffffffffffffffffff8f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b6040518060400160405280600681526020017f554e492d5632000000000000000000000000000000000000000000000000000081525081565b6000610df233848461260b565b6103e881565b600c5460011461194f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654600754600854604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9485169490931692611a2b9285928792611a26926dffffffffffffffffffffffffffff169185916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b505afa158015611a02573d6000803e3d6000fd5b505050506040513d6020811015611a1857600080fd5b50519063ffffffff61226e16565b611fdb565b600854604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611aca9284928792611a26926e01000000000000000000000000000090046dffffffffffffffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b50506001600c5550565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b42841015611b7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f556e697377617056323a20455850495245440000000000000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff80891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611cdc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611d5757508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611dc257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f556e697377617056323a20494e56414c49445f5349474e415455524500000000604482015290519081900360640190fd5b611dcd89898961259c565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c54600114611e6657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611fd49273ffffffffffffffffffffffffffffffffffffffff16916370a08231916024808301926020929190829003018186803b158015611edd57600080fd5b505afa158015611ef1573d6000803e3d6000fd5b505050506040513d6020811015611f0757600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b158015611f7a57600080fd5b505afa158015611f8e573d6000803e3d6000fd5b505050506040513d6020811015611fa457600080fd5b50516008546dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004166122e0565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602091820152815173ffffffffffffffffffffffffffffffffffffffff85811660248301526044808301869052845180840390910181526064909201845291810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251815160009460609489169392918291908083835b602083106120e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120a4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612143576040519150601f19603f3d011682016040523d82523d6000602084013e612148565b606091505b5091509150818015612176575080511580612176575080806020019051602081101561217357600080fd5b50515b6121e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e697377617056323a205452414e534645525f4641494c4544000000000000604482015290519081900360640190fd5b5050505050565b60008115806122035750508082028282828161220057fe5b04145b610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff841180159061230c57506dffffffffffffffffffffffffffff8311155b61237757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e697377617056323a204f564552464c4f5700000000000000000000000000604482015290519081900360640190fd5b60085463ffffffff428116917c0100000000000000000000000000000000000000000000000000000000900481168203908116158015906123c757506dffffffffffffffffffffffffffff841615155b80156123e257506dffffffffffffffffffffffffffff831615155b15612492578063ffffffff16612425856123fb86612a57565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169063ffffffff612a7b16565b600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092169290920201905563ffffffff8116612465846123fb87612a57565b600a80547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190555b600880547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff888116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e0100000000000000000000000000008883168102919091177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020526040902054612641908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160205260408082209390935590841681522054612683908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561275757600080fd5b505afa15801561276b573d6000803e3d6000fd5b505050506040513d602081101561278157600080fd5b5051600b5473ffffffffffffffffffffffffffffffffffffffff821615801594509192509061286457801561285f5760006127d86112576dffffffffffffffffffffffffffff88811690881663ffffffff6121e816565b905060006127e583612878565b90508082111561285c576000612813612804848463ffffffff61226e16565b6000549063ffffffff6121e816565b905060006128388361282c86600563ffffffff6121e816565b9063ffffffff612abc16565b9050600081838161284557fe5b04905080156128585761285887826128ca565b5050505b50505b612870565b8015612870576000600b555b505092915050565b600060038211156128bb575080600160028204015b818110156128b5578091506002818285816128a457fe5b0401816128ad57fe5b04905061288d565b506128c5565b81156128c5575060015b919050565b6000546128dd908263ffffffff612abc16565b600090815573ffffffffffffffffffffffffffffffffffffffff8316815260016020526040902054612915908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612989578161298b565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020546129c8908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081209190915554612a02908263ffffffff61226e16565b600090815560408051838152905173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6dffffffffffffffffffffffffffff166e0100000000000000000000000000000290565b60006dffffffffffffffffffffffffffff82167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841681612ab457fe5b049392505050565b80820182811015610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fdfe556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f4c4951554944495459556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4255524e4544556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a723158207dca18479e58487606bf70c79e44d8dee62353c9ee6d01f9a9d70885b8765f2264736f6c63430005100032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a723158202760f92d7fa1db6f5aa16307bad65df4ebcc8550c4b1f03755ab8dfd830c178f64736f6c63430005100032" uniswapv2factory.UniswapV2FactoryMetaData.Bin = refFactoryBytecode - contractAddr, err := k.deployContract(ctx, uniswapv2factory.UniswapV2FactoryMetaData, types.ModuleAddressEVM) + contractAddr, err := k.DeployContract(ctx, uniswapv2factory.UniswapV2FactoryMetaData, types.ModuleAddressEVM) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "UniswapV2FactoryContract") } @@ -158,7 +160,7 @@ func (k Keeper) DeployUniswapV2Factory(ctx sdk.Context) (common.Address, error) } func (k Keeper) DeployUniswapV2Router02(ctx sdk.Context, factory common.Address, wzeta common.Address) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, uniswapv2router02.UniswapV2Router02MetaData, factory, wzeta) + contractAddr, err := k.DeployContract(ctx, uniswapv2router02.UniswapV2Router02MetaData, factory, wzeta) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "UniswapV2Router02") } @@ -166,7 +168,7 @@ func (k Keeper) DeployUniswapV2Router02(ctx sdk.Context, factory common.Address, } func (k Keeper) DeployWZETA(ctx sdk.Context) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, wzeta.WETH9MetaData) + contractAddr, err := k.DeployContract(ctx, wzeta.WETH9MetaData) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "WZETA") } @@ -174,7 +176,7 @@ func (k Keeper) DeployWZETA(ctx sdk.Context) (common.Address, error) { } func (k Keeper) DeployConnectorZEVM(ctx sdk.Context, wzeta common.Address) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, connectorzevm.ZetaConnectorZEVMMetaData, wzeta) + contractAddr, err := k.DeployContract(ctx, connectorzevm.ZetaConnectorZEVMMetaData, wzeta) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "ZetaConnectorZEVM") } @@ -194,12 +196,11 @@ func (k Keeper) DepositZRC20( to common.Address, amount *big.Int, ) (*evmtypes.MsgEthereumTxResponse, error) { - //abi, err := zrc20.ZRC4MetaData.GetAbi() - abi, err := zrc20.ZRC20MetaData.GetAbi() + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return nil, err } - return k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, true, false, "deposit", to, amount) + return k.CallEVM(ctx, *zrc20ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, true, false, "deposit", to, amount) } // DepositZRC20AndCallContract deposits into ZRC4 and call contract function in a single tx @@ -226,6 +227,117 @@ func (k Keeper) DepositZRC20AndCallContract(ctx sdk.Context, "depositAndCall", context, zrc20Addr, amount, targetContract, message) } +// QueryWithdrawGasFee returns the gas fee for a withdrawal transaction associated with a given zrc20 +func (k Keeper) QueryWithdrawGasFee(ctx sdk.Context, contract common.Address) (*big.Int, error) { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + res, err := k.CallEVM( + ctx, + *zrc20ABI, + types.ModuleAddressEVM, + contract, + BigIntZero, + nil, + false, + false, + "withdrawGasFee", + ) + if err != nil { + return nil, err + } + + unpacked, err := zrc20ABI.Unpack("withdrawGasFee", res.Ret) + if err != nil { + return nil, err + } + if len(unpacked) < 2 { + return nil, fmt.Errorf("expect 2 returned values, got %d", len(unpacked)) + } + + GasFee, ok := unpacked[1].(*big.Int) + if !ok { + return nil, errors.New("can't read returned value as big.Int") + } + + return GasFee, nil +} + +// QueryProtocolFlatFee returns the protocol flat fee associated with a given zrc20 +func (k Keeper) QueryProtocolFlatFee(ctx sdk.Context, contract common.Address) (*big.Int, error) { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + res, err := k.CallEVM( + ctx, + *zrc20ABI, + types.ModuleAddressEVM, + contract, + BigIntZero, + nil, + false, + false, + "PROTOCOL_FLAT_FEE", + ) + if err != nil { + return nil, err + } + + unpacked, err := zrc20ABI.Unpack("PROTOCOL_FLAT_FEE", res.Ret) + if err != nil { + return nil, err + } + if len(unpacked) == 0 { + return nil, fmt.Errorf("expect 1 returned values, got %d", len(unpacked)) + } + + protocolGasFee, ok := unpacked[0].(*big.Int) + if !ok { + return nil, errors.New("can't read returned value as big.Int") + } + + return protocolGasFee, nil +} + +// QueryGasLimit returns the gas limit for a withdrawal transaction associated with a given zrc20 +func (k Keeper) QueryGasLimit(ctx sdk.Context, contract common.Address) (*big.Int, error) { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + res, err := k.CallEVM( + ctx, + *zrc20ABI, + types.ModuleAddressEVM, + contract, + BigIntZero, + nil, + false, + false, + "GAS_LIMIT", + ) + if err != nil { + return nil, err + } + + unpacked, err := zrc20ABI.Unpack("GAS_LIMIT", res.Ret) + if err != nil { + return nil, err + } + if len(unpacked) == 0 { + return nil, fmt.Errorf("expect 1 returned values, got %d", len(unpacked)) + } + + gasLimit, ok := unpacked[0].(*big.Int) + if !ok { + return nil, errors.New("can't read returned value as big.Int") + } + + return gasLimit, nil +} + // QueryZRC20Data returns the data of a deployed ZRC20 contract func (k Keeper) QueryZRC20Data( ctx sdk.Context, @@ -237,35 +349,40 @@ func (k Keeper) QueryZRC20Data( decimalRes types.ZRC20Uint8Response ) - zrc4, _ := zrc20.ZRC20MetaData.GetAbi() + zrc4ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return types.ZRC20Data{}, sdkerrors.Wrapf( + types.ErrABIUnpack, "failed to get ABI: %s", err.Error(), + ) + } // Name - res, err := k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "name") + res, err := k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "name") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&nameRes, "name", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&nameRes, "name", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack name: %s", err.Error()) } // Symbol - res, err = k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "symbol") + res, err = k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "symbol") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&symbolRes, "symbol", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&symbolRes, "symbol", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack symbol: %s", err.Error()) } // Decimals - res, err = k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "decimals") + res, err = k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "decimals") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&decimalRes, "decimals", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&decimalRes, "decimals", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack decimals: %s", err.Error()) } @@ -277,17 +394,17 @@ func (k Keeper) BalanceOfZRC4( ctx sdk.Context, contract, account common.Address, ) (*big.Int, error) { - abi, err := zrc20.ZRC20MetaData.GetAbi() + zrc4ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) } - res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "balanceOf", + res, err := k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "balanceOf", account) if err != nil { return nil, err } - unpacked, err := abi.Unpack("balanceOf", res.Ret) + unpacked, err := zrc4ABI.Unpack("balanceOf", res.Ret) if err != nil || len(unpacked) == 0 { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) } @@ -300,6 +417,60 @@ func (k Keeper) BalanceOfZRC4( return balance, nil } +// TotalSupplyZRC4 queries the total supply of a given ZRC4 contract +func (k Keeper) TotalSupplyZRC4( + ctx sdk.Context, + contract common.Address, +) (*big.Int, error) { + abi, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "totalSupply") + if err != nil { + return nil, err + } + + unpacked, err := abi.Unpack("totalSupply", res.Ret) + if err != nil || len(unpacked) == 0 { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + + totalSupply, ok := unpacked[0].(*big.Int) + if !ok { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack total supply") + } + + return totalSupply, nil +} + +// QueryChainIDFromContract returns the chain id of the chain +func (k Keeper) QueryChainIDFromContract( + ctx sdk.Context, + contract common.Address, +) (*big.Int, error) { + abi, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "CHAIN_ID") + if err != nil { + return nil, err + } + + unpacked, err := abi.Unpack("CHAIN_ID", res.Ret) + if err != nil || len(unpacked) == 0 { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + + chainID, ok := unpacked[0].(*big.Int) + if !ok { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack chain ID") + } + + return chainID, nil +} + // CallEVM performs a smart contract method call using given args // returns (msg,err) the EVM execution result if there is any, even if error is non-nil due to contract reverts // Furthermore, err!=nil && msg!=nil && msg.Failed() means the contract call reverted. diff --git a/x/fungible/keeper/foreign_coins.go b/x/fungible/keeper/foreign_coins.go index 7e51a90be6..7450b66cd8 100644 --- a/x/fungible/keeper/foreign_coins.go +++ b/x/fungible/keeper/foreign_coins.go @@ -80,6 +80,7 @@ func (k Keeper) GetAllForeignCoins(ctx sdk.Context) (list []types.ForeignCoins) return } +// GetGasCoinForForeignCoin returns the gas coin for a given chain func (k Keeper) GetGasCoinForForeignCoin(ctx sdk.Context, chainID int64) (types.ForeignCoins, bool) { foreignCoinList := k.GetAllForeignCoinsForChain(ctx, chainID) for _, coin := range foreignCoinList { @@ -89,3 +90,14 @@ func (k Keeper) GetGasCoinForForeignCoin(ctx sdk.Context, chainID int64) (types. } return types.ForeignCoins{}, false } + +// GetForeignCoinFromAsset returns the foreign coin for a given asset for a given chain +func (k Keeper) GetForeignCoinFromAsset(ctx sdk.Context, asset string, chainID int64) (types.ForeignCoins, bool) { + foreignCoinList := k.GetAllForeignCoinsForChain(ctx, chainID) + for _, coin := range foreignCoinList { + if coin.Asset == asset && coin.ForeignChainId == chainID { + return coin, true + } + } + return types.ForeignCoins{}, false +} diff --git a/x/fungible/keeper/foreign_coins_test.go b/x/fungible/keeper/foreign_coins_test.go index 56248eb016..347630002d 100644 --- a/x/fungible/keeper/foreign_coins_test.go +++ b/x/fungible/keeper/foreign_coins_test.go @@ -2,6 +2,12 @@ package keeper_test import ( "strconv" + "testing" + + "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" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/fungible/keeper" @@ -17,3 +23,110 @@ func createNForeignCoins(keeper *keeper.Keeper, ctx sdk.Context, n int) []types. } return items } + +func setForeignCoins(ctx sdk.Context, k *keeper.Keeper, fc ...types.ForeignCoins) { + for _, item := range fc { + k.SetForeignCoins(ctx, item) + } +} + +func TestKeeper_GetGasCoinForForeignCoin(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + // populate + setForeignCoins(ctx, k, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_Gas, + Name: "bar", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + ) + + fc, found := k.GetGasCoinForForeignCoin(ctx, 1) + require.True(t, found) + require.Equal(t, "bar", fc.Name) + fc, found = k.GetGasCoinForForeignCoin(ctx, 2) + require.False(t, found) + fc, found = k.GetGasCoinForForeignCoin(ctx, 3) + require.False(t, found) +} + +func TestKeeperGetForeignCoinFromAsset(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + gasAsset := sample.EthAddress().String() + + // populate + setForeignCoins(ctx, k, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: gasAsset, + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "bar", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_Gas, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + ) + + fc, found := k.GetForeignCoinFromAsset(ctx, gasAsset, 1) + require.True(t, found) + require.Equal(t, "bar", fc.Name) + fc, found = k.GetForeignCoinFromAsset(ctx, sample.EthAddress().String(), 1) + require.False(t, found) + fc, found = k.GetForeignCoinFromAsset(ctx, gasAsset, 2) + require.False(t, found) + fc, found = k.GetForeignCoinFromAsset(ctx, gasAsset, 3) + require.False(t, found) +} diff --git a/x/fungible/keeper/gas_price.go b/x/fungible/keeper/gas_price.go index cca8c03597..f492ddb2ec 100644 --- a/x/fungible/keeper/gas_price.go +++ b/x/fungible/keeper/gas_price.go @@ -10,7 +10,7 @@ import ( "github.com/zeta-chain/zetacore/x/fungible/types" ) -// sets gas price on the system contract in zEVM; return the gasUsed and error code +// SetGasPrice sets gas price on the system contract in zEVM; return the gasUsed and error code func (k Keeper) SetGasPrice(ctx sdk.Context, chainid *big.Int, gasPrice *big.Int) (uint64, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -66,9 +66,9 @@ func (k Keeper) SetGasZetaPool(ctx sdk.Context, chainid *big.Int, pool common.Ad if err != nil { return sdkerrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") } - res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "SetGasZetaPool", chainid, pool) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "setGasZetaPool", chainid, pool) if err != nil || res.Failed() { - return sdkerrors.Wrapf(types.ErrContractCall, "SetGasZetaPool") + return sdkerrors.Wrapf(types.ErrContractCall, "setGasZetaPool") } return nil diff --git a/x/fungible/keeper/gas_price_test.go b/x/fungible/keeper/gas_price_test.go new file mode 100644 index 0000000000..ec1bf267d8 --- /dev/null +++ b/x/fungible/keeper/gas_price_test.go @@ -0,0 +1,75 @@ +package keeper_test + +import ( + "math/big" + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_SetGasPrice(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, _, _, _, system := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + queryGasPrice := func(chainID *big.Int) *big.Int { + abi, err := systemcontract.SystemContractMetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, system, keeper.BigIntZero, nil, false, false, "gasPriceByChainId", chainID) + require.NoError(t, err) + unpacked, err := abi.Unpack("gasPriceByChainId", res.Ret) + require.NoError(t, err) + gasPrice, ok := unpacked[0].(*big.Int) + require.True(t, ok) + return gasPrice + } + + _, err := k.SetGasPrice(ctx, big.NewInt(1), big.NewInt(42)) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), queryGasPrice(big.NewInt(1))) +} + +func TestKeeper_SetGasCoin(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + gas := sample.EthAddress() + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + err := k.SetGasCoin(ctx, big.NewInt(1), gas) + require.NoError(t, err) + + found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(1)) + require.NoError(t, err) + require.Equal(t, gas.Hex(), found.Hex()) +} + +func TestKeeper_SetGasZetaPool(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + zrc20 := sample.EthAddress() + + _, _, _, _, system := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + queryZetaPool := func(chainID *big.Int) ethcommon.Address { + abi, err := systemcontract.SystemContractMetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, system, keeper.BigIntZero, nil, false, false, "gasZetaPoolByChainId", chainID) + require.NoError(t, err) + unpacked, err := abi.Unpack("gasZetaPoolByChainId", res.Ret) + require.NoError(t, err) + pool, ok := unpacked[0].(ethcommon.Address) + require.True(t, ok) + return pool + } + + err := k.SetGasZetaPool(ctx, big.NewInt(1), zrc20) + require.NoError(t, err) + require.NotEqual(t, ethcommon.Address{}, queryZetaPool(big.NewInt(1))) +} diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go index 41b678e349..db782a6491 100644 --- a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go @@ -4,6 +4,8 @@ import ( "context" "math/big" + "github.com/ethereum/go-ethereum/common" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" zetacommon "github.com/zeta-chain/zetacore/common" @@ -31,6 +33,10 @@ import ( // Only the admin policy account is authorized to broadcast this message. func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.MsgDeployFungibleCoinZRC20) (*types.MsgDeployFungibleCoinZRC20Response, error) { ctx := sdk.UnwrapSDKContext(goCtx) + + var address common.Address + var err error + if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_deploy_fungible_coin) { return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") } @@ -38,34 +44,35 @@ func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.Msg return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 256") } if msg.CoinType == zetacommon.CoinType_Gas { - _, err := k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals)) + address, err = k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals)) if err != nil { return nil, sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } } else { - addr, err := k.DeployZRC20Contract(ctx, msg.Name, msg.Symbol, uint8(msg.Decimals), msg.ForeignChainId, msg.CoinType, msg.ERC20, big.NewInt(msg.GasLimit)) + address, err = k.DeployZRC20Contract(ctx, msg.Name, msg.Symbol, uint8(msg.Decimals), msg.ForeignChainId, msg.CoinType, msg.ERC20, big.NewInt(msg.GasLimit)) if err != nil { return nil, err } + } - err = ctx.EventManager().EmitTypedEvent( - &types.EventZRC20Deployed{ - MsgTypeUrl: sdk.MsgTypeURL(&types.MsgDeployFungibleCoinZRC20{}), - ChainId: msg.ForeignChainId, - Contract: addr.String(), - Name: msg.Name, - Symbol: msg.Symbol, - Decimals: int64(msg.Decimals), - CoinType: msg.CoinType, - Erc20: msg.ERC20, - GasLimit: msg.GasLimit, - }, - ) - if err != nil { - return nil, sdkerrors.Wrapf(err, "failed to emit event") - } - + err = ctx.EventManager().EmitTypedEvent( + &types.EventZRC20Deployed{ + MsgTypeUrl: sdk.MsgTypeURL(&types.MsgDeployFungibleCoinZRC20{}), + ChainId: msg.ForeignChainId, + Contract: address.String(), + Name: msg.Name, + Symbol: msg.Symbol, + Decimals: int64(msg.Decimals), + CoinType: msg.CoinType, + Erc20: msg.ERC20, + GasLimit: msg.GasLimit, + }, + ) + if err != nil { + return nil, sdkerrors.Wrapf(err, "failed to emit event") } - return &types.MsgDeployFungibleCoinZRC20Response{}, nil + return &types.MsgDeployFungibleCoinZRC20Response{ + Address: address.Hex(), + }, nil } diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go new file mode 100644 index 0000000000..5eef132e3f --- /dev/null +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go @@ -0,0 +1,147 @@ +package keeper_test + +import ( + "math/big" + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "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/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_DeployFungibleCoinZRC20(t *testing.T) { + t.Run("can deploy a new zrc20", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + res, err := msgServer.DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.NoError(t, err) + gasAddress := res.Address + assertContractDeployment(t, sdkk.EvmKeeper, ctx, ethcommon.HexToAddress(gasAddress)) + + // can retrieve the gas coin + foreignCoin, found := k.GetForeignCoins(ctx, gasAddress) + require.True(t, found) + require.Equal(t, foreignCoin.CoinType, common.CoinType_Gas) + require.Contains(t, foreignCoin.Name, "foo") + + gas, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.Equal(t, gasAddress, gas.Hex()) + + // can deploy non-gas zrc20 + res, err = msgServer.DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 8, + "bar", + "bar", + common.CoinType_ERC20, + 1000000, + )) + require.NoError(t, err) + assertContractDeployment(t, sdkk.EvmKeeper, ctx, ethcommon.HexToAddress(res.Address)) + + foreignCoin, found = k.GetForeignCoins(ctx, res.Address) + require.True(t, found) + require.Equal(t, foreignCoin.CoinType, common.CoinType_ERC20) + require.Contains(t, foreignCoin.Name, "bar") + + // gas should remain the same + gas, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.NotEqual(t, res.Address, gas.Hex()) + require.Equal(t, gasAddress, gas.Hex()) + }) + + t.Run("should not deploy a new zrc20 if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + sample.AccAddress(), + sample.EthAddress().Hex(), + chainID, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should not deploy a new zrc20 with wrong decimal", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 256, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) + }) + + t.Run("should not deploy a new zrc20 with invalid chain ID", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + 9999999, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) +} diff --git a/x/fungible/keeper/msg_server_remove_foreign_coin_test.go b/x/fungible/keeper/msg_server_remove_foreign_coin_test.go new file mode 100644 index 0000000000..c866d81f21 --- /dev/null +++ b/x/fungible/keeper/msg_server_remove_foreign_coin_test.go @@ -0,0 +1,60 @@ +package keeper_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestMsgServer_RemoveForeignCoin(t *testing.T) { + t.Run("can remove a foreign coin", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", "foo") + + _, found := k.GetForeignCoins(ctx, zrc20.Hex()) + require.True(t, found) + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(admin, zrc20.Hex())) + require.NoError(t, err) + _, found = k.GetForeignCoins(ctx, zrc20.Hex()) + require.False(t, found) + }) + + t.Run("should fail if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", "foo") + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(sample.AccAddress(), zrc20.Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should fail if not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(admin, sample.EthAddress().Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) + }) +} diff --git a/x/fungible/keeper/msg_server_test.go b/x/fungible/keeper/msg_server_test.go deleted file mode 100644 index b4b4427f8e..0000000000 --- a/x/fungible/keeper/msg_server_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package keeper_test - -import ( - "context" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/x/fungible/keeper" - "github.com/zeta-chain/zetacore/x/fungible/types" -) - -func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) { - k, ctx, _, _ := keepertest.FungibleKeeper(t) - return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx) -} diff --git a/x/fungible/keeper/msg_server_update_contract_bytecode.go b/x/fungible/keeper/msg_server_update_contract_bytecode.go new file mode 100644 index 0000000000..ed66882fe4 --- /dev/null +++ b/x/fungible/keeper/msg_server_update_contract_bytecode.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "context" + + cosmoserror "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// UpdateContractBytecode updates the bytecode of a contract from the bytecode of an existing contract +// Only a ZRC20 contract or the WZeta connector contract can be updated +// IMPORTANT: the new contract bytecode must have the same storage layout as the old contract bytecode +// the new contract can add new variable but cannot remove any existing variable +func (k Keeper) UpdateContractBytecode(goCtx context.Context, msg *types.MsgUpdateContractBytecode) (*types.MsgUpdateContractBytecodeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // check authorization + if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin) { + return nil, cosmoserror.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") + } + + // fetch account to update + if !ethcommon.IsHexAddress(msg.ContractAddress) { + return nil, cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + contractAddress := ethcommon.HexToAddress(msg.ContractAddress) + acct := k.evmKeeper.GetAccount(ctx, contractAddress) + if acct == nil { + return nil, cosmoserror.Wrapf(types.ErrContractNotFound, "contract (%s) not found", contractAddress.Hex()) + } + + // check the contract is a zrc20 + _, found := k.GetForeignCoins(ctx, msg.ContractAddress) + if !found { + // check contract is wzeta connector contract + systemContract, found := k.GetSystemContract(ctx) + if !found { + return nil, types.ErrSystemContractNotFound + } + if msg.ContractAddress != systemContract.ConnectorZevm { + // not a zrc20 or wzeta connector contract, can't be updated + return nil, cosmoserror.Wrapf(types.ErrInvalidContract, "contract (%s) is neither a zrc20 nor wzeta connector", msg.ContractAddress) + } + } + + // fetch the account of the new bytecode + if !ethcommon.IsHexAddress(msg.NewBytecodeAddress) { + return nil, cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.NewBytecodeAddress) + } + newBytecodeAddress := ethcommon.HexToAddress(msg.NewBytecodeAddress) + newBytecodeAcct := k.evmKeeper.GetAccount(ctx, newBytecodeAddress) + if newBytecodeAcct == nil { + return nil, cosmoserror.Wrapf(types.ErrContractNotFound, "contract (%s) not found", newBytecodeAddress.Hex()) + } + + // set the new CodeHash to the account + previousCodeHash := acct.CodeHash + acct.CodeHash = newBytecodeAcct.CodeHash + err := k.evmKeeper.SetAccount(ctx, contractAddress, *acct) + if err != nil { + return nil, cosmoserror.Wrapf( + types.ErrSetBytecode, + "failed to update contract (%s) bytecode (%s)", + contractAddress.Hex(), + err.Error(), + ) + } + k.Logger(ctx).Info( + "updated contract bytecode", + "contract", contractAddress.Hex(), + "oldCodeHash", string(previousCodeHash), + "newCodeHash", string(acct.CodeHash), + ) + + return &types.MsgUpdateContractBytecodeResponse{ + NewBytecodeHash: acct.CodeHash, + }, nil +} diff --git a/x/fungible/keeper/msg_server_update_contract_bytecode_test.go b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go new file mode 100644 index 0000000000..8db3f53bdf --- /dev/null +++ b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go @@ -0,0 +1,374 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/evmos/ethermint/x/evm/statedb" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + zetacommon "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/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func setAdminDeployFungibleCoin(ctx sdk.Context, zk keepertest.ZetaKeepers, admin string) { + zk.ObserverKeeper.SetParams(ctx, observertypes.Params{ + AdminPolicy: []*observertypes.Admin_Policy{ + { + PolicyType: observertypes.Policy_Type_deploy_fungible_coin, + Address: admin, + }, + }, + }) +} + +func TestKeeper_UpdateContractBytecode(t *testing.T) { + t.Run("can update the bytecode from another contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + // set admin policy + setAdminDeployFungibleCoin(ctx, zk, admin) + + // sample chainIDs and addresses + chainList := zetacommon.DefaultChainsList() + require.True(t, len(chainList) > 1) + require.NotNil(t, chainList[0]) + require.NotNil(t, chainList[1]) + require.NotEqual(t, chainList[0].ChainId, chainList[1].ChainId) + chainID1 := chainList[0].ChainId + chainID2 := chainList[1].ChainId + + addr1 := sample.EthAddress() + addr2 := sample.EthAddress() + + // deploy the system contract and a ZRC20 contract + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID1, "alpha", "alpha") + + // do some operation to populate the state + _, err := k.DepositZRC20(ctx, zrc20, addr1, big.NewInt(100)) + require.NoError(t, err) + _, err = k.DepositZRC20(ctx, zrc20, addr2, big.NewInt(200)) + require.NoError(t, err) + + // check the state + checkState := func() { + // state that should not change + balance, err := k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(100), balance.Int64()) + balance, err = k.BalanceOfZRC4(ctx, zrc20, addr2) + require.NoError(t, err) + require.Equal(t, int64(200), balance.Int64()) + totalSupply, err := k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10000300), totalSupply.Int64()) // 10000000 minted on deploy + } + + checkState() + chainID, err := k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID1, chainID.Int64()) + + // deploy new zrc20 + newCodeAddress, err := k.DeployZRC20Contract( + ctx, + "beta", + "BETA", + 18, + chainID2, + zetacommon.CoinType_ERC20, + "beta", + big.NewInt(90_000), + ) + require.NoError(t, err) + + // update the bytecode + res, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + zrc20, + newCodeAddress, + )) + require.NoError(t, err) + + // check the returned new bytecode hash matches the one in the account + acct := sdkk.EvmKeeper.GetAccount(ctx, zrc20) + require.Equal(t, acct.CodeHash, res.NewBytecodeHash) + + // check the state + // balances and total supply should remain + // BYTECODE value is immutable and therefore part of the code, this value should change + checkState() + chainID, err = k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID2, chainID.Int64()) + + // can continue to interact with the contract + _, err = k.DepositZRC20(ctx, zrc20, addr1, big.NewInt(1000)) + require.NoError(t, err) + balance, err := k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(1100), balance.Int64()) + totalSupply, err := k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10001300), totalSupply.Int64()) + + // can change again bytecode + newCodeAddress, err = k.DeployZRC20Contract( + ctx, + "gamma", + "GAMMA", + 18, + chainID1, + zetacommon.CoinType_ERC20, + "gamma", + big.NewInt(90_000), + ) + require.NoError(t, err) + _, err = k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + zrc20, + newCodeAddress, + )) + require.NoError(t, err) + balance, err = k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(1100), balance.Int64()) + totalSupply, err = k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10001300), totalSupply.Int64()) + chainID, err = k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID1, chainID.Int64()) + }) + + t.Run("can update the bytecode of the wzeta connector contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + // deploy a connector + setAdminDeployFungibleCoin(ctx, zk, admin) + wzeta, _, _, oldConnector, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // deploy a new connector that will become official connector + newConnector, err := k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, newConnector) + assertContractDeployment(t, sdkk.EvmKeeper, ctx, newConnector) + + // can update the bytecode of the new connector with the old connector contract + _, err = k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + newConnector, + oldConnector, + )) + require.NoError(t, err) + }) + + t.Run("should fail if unauthorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + sample.AccAddress(), + sample.EthAddress(), + sample.EthAddress(), + )) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should fail invalid contract address", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := k.UpdateContractBytecode(ctx, &types.MsgUpdateContractBytecode{ + Creator: admin, + ContractAddress: "invalid", + NewBytecodeAddress: sample.EthAddress().Hex(), + }) + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + }) + + t.Run("should fail if can't get contract account", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(nil) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrContractNotFound) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail neither a zrc20 nor wzeta connector", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + setAdminDeployFungibleCoin(ctx, zk, admin) + wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // can't update the bytecode of the wzeta contract + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + wzeta, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrInvalidContract) + }) + + t.Run("should fail if system contract not found", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + setAdminDeployFungibleCoin(ctx, zk, admin) + _, _, _, connector, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // remove system contract + k.RemoveSystemContract(ctx) + + // can't update the bytecode of the wzeta contract + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + connector, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrSystemContractNotFound) + }) + + t.Run("should fail if invalid bytecode address", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // set the contract as the connector + contract := sample.EthAddress() + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contract.Hex(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + mock.Anything, + ).Return(&statedb.Account{}) + + _, err := k.UpdateContractBytecode(ctx, &types.MsgUpdateContractBytecode{ + Creator: admin, + ContractAddress: contract.Hex(), + NewBytecodeAddress: "invalid", + }) + + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail if can't get new bytecode account", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + newBytecodeAddr := sample.EthAddress() + + // set the contract as the connector + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contractAddr.String(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + newBytecodeAddr, + ).Return(nil) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + newBytecodeAddr, + )) + require.ErrorIs(t, err, types.ErrContractNotFound) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail if can't set account with new bytecode", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + newBytecodeAddr := sample.EthAddress() + + // set the contract as the connector + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contractAddr.String(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + newBytecodeAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "SetAccount", + mock.Anything, + mock.Anything, + mock.Anything, + ).Return(errors.New("can't set account")) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + newBytecodeAddr, + )) + require.ErrorIs(t, err, types.ErrSetBytecode) + + mockEVMKeeper.AssertExpectations(t) + }) +} diff --git a/x/fungible/keeper/msg_server_update_system_contract_test.go b/x/fungible/keeper/msg_server_update_system_contract_test.go new file mode 100644 index 0000000000..1d38265022 --- /dev/null +++ b/x/fungible/keeper/msg_server_update_system_contract_test.go @@ -0,0 +1,108 @@ +package keeper_test + +import ( + "math/big" + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + zetacommon "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/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_UpdateSystemContract(t *testing.T) { + t.Run("can update the system contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + queryZRC20SystemContract := func(contract common.Address) string { + abi, err := zrc20.ZRC20MetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, keeper.BigIntZero, nil, false, false, "SYSTEM_CONTRACT_ADDRESS") + require.NoError(t, err) + unpacked, err := abi.Unpack("SYSTEM_CONTRACT_ADDRESS", res.Ret) + require.NoError(t, err) + address, ok := unpacked[0].(common.Address) + require.True(t, ok) + return address.Hex() + } + + chains := zetacommon.DefaultChainsList() + require.True(t, len(chains) > 1) + require.NotNil(t, chains[0]) + require.NotNil(t, chains[1]) + chainID1 := chains[0].ChainId + chainID2 := chains[1].ChainId + + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + gas1 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID1, "foo", "foo") + gas2 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID2, "bar", "bar") + + // deploy a new system contracts + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // can update the system contract + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(admin, newSystemContract.Hex())) + require.NoError(t, err) + + // can retrieve the system contract + sc, found := k.GetSystemContract(ctx) + require.True(t, found) + require.Equal(t, newSystemContract.Hex(), sc.SystemContract) + + // check gas updated + foundGas1, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID1)) + require.NoError(t, err) + require.Equal(t, gas1, foundGas1) + foundGas2, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID2)) + require.NoError(t, err) + require.Equal(t, gas2, foundGas2) + + require.Equal(t, newSystemContract.Hex(), queryZRC20SystemContract(gas1)) + require.Equal(t, newSystemContract.Hex(), queryZRC20SystemContract(gas2)) + }) + + t.Run("should not update the system contract if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // deploy a new system contracts + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // should not update the system contract if not admin + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(sample.AccAddress(), newSystemContract.Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should not update the system contract if invalid address", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy a new system contracts + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // should not update the system contract if invalid address + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(admin, "invalid")) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + }) +} diff --git a/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go b/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go index a6b452747c..cdf27ed943 100644 --- a/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go +++ b/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go @@ -3,26 +3,13 @@ package keeper_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/fungible/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func setAdminDeployFungibleCoin(ctx sdk.Context, zk keepertest.ZetaKeepers, admin string) { - zk.ObserverKeeper.SetParams(ctx, observertypes.Params{ - AdminPolicy: []*observertypes.Admin_Policy{ - { - PolicyType: observertypes.Policy_Type_deploy_fungible_coin, - Address: admin, - }, - }, - }) -} - func TestKeeper_UpdateZRC20PausedStatus(t *testing.T) { t.Run("can update the paused status of zrc20", func(t *testing.T) { k, ctx, _, zk := keepertest.FungibleKeeper(t) diff --git a/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee.go b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee.go index dc6d18864a..56e75381e6 100644 --- a/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee.go +++ b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee.go @@ -2,7 +2,8 @@ package keeper import ( "context" - "math/big" + + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -14,55 +15,50 @@ import ( func (k Keeper) UpdateZRC20WithdrawFee(goCtx context.Context, msg *types.MsgUpdateZRC20WithdrawFee) (*types.MsgUpdateZRC20WithdrawFeeResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + + // check signer permission if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_deploy_fungible_coin) { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") + return nil, cosmoserrors.Wrap(sdkerrors.ErrUnauthorized, "deploy can only be executed by the correct policy account") } + + // check the zrc20 exists zrc20Addr := ethcommon.HexToAddress(msg.Zrc20Address) if zrc20Addr == (ethcommon.Address{}) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid zrc20 contract address (%s)", msg.Zrc20Address) - } - - // update contracts - zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() - if err != nil { - return nil, sdkerrors.Wrapf(types.ErrABIGet, "failed to get zrc20 abi") - } - - foreignCoins := k.GetAllForeignCoins(ctx) - found := false - var coin types.ForeignCoins - for _, fcoin := range foreignCoins { - coinZRC20Addr := ethcommon.HexToAddress(fcoin.Zrc20ContractAddress) - if coinZRC20Addr == (ethcommon.Address{}) { - k.Logger(ctx).Error("invalid zrc20 contract address", "address", fcoin.Zrc20ContractAddress) - continue - } - if coinZRC20Addr == zrc20Addr { - coin = fcoin - found = true - break - } + return nil, cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid zrc20 contract address (%s)", msg.Zrc20Address) } - + coin, found := k.GetForeignCoins(ctx, msg.Zrc20Address) if !found { - return nil, sdkerrors.Wrapf(types.ErrInvalidAddress, "no foreign coin match requested zrc20 address (%s)", msg.Zrc20Address) + return nil, cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "no foreign coin match requested zrc20 address (%s)", msg.Zrc20Address) } - res, err := k.CallEVM(ctx, *zrc20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, false, false, "PROTOCOL_FLAT_FEE") + // get the previous fee + oldWithdrawFee, err := k.QueryProtocolFlatFee(ctx, zrc20Addr) if err != nil { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to call zrc20 contract PROTOCOL_FLAT_FEE method (%s)", err.Error()) - } - unpacked, err := zrc20ABI.Unpack("PROTOCOL_FLAT_FEE", res.Ret) - if err != nil || len(unpacked) == 0 { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to unpack zrc20 contract PROTOCOL_FLAT_FEE method (%s)", err.Error()) + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to query protocol flat fee (%s)", err.Error()) } - oldWithdrawFee, ok := unpacked[0].(*big.Int) - if !ok { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to interpret the returned unpacked zrc20 contract PROTOCOL_FLAT_FEE method; ret %x", res.Ret) + + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get zrc20 abi") } + // call the contract method to update the fee tmpCtx, commit := ctx.CacheContext() - _, err = k.CallEVM(tmpCtx, *zrc20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, true, false, "updateProtocolFlatFee", msg.NewWithdrawFee.BigInt()) + _, err = k.CallEVM( + tmpCtx, + *zrc20ABI, + types.ModuleAddressEVM, + zrc20Addr, + BigIntZero, + nil, + true, + false, + "updateProtocolFlatFee", + msg.NewWithdrawFee.BigInt(), + ) + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to call zrc20 contract updateProtocolFlatFee method (%s)", err.Error()) + } err = ctx.EventManager().EmitTypedEvent( &types.EventZRC20WithdrawFeeUpdated{ @@ -77,8 +73,9 @@ func (k Keeper) UpdateZRC20WithdrawFee(goCtx context.Context, msg *types.MsgUpda ) if err != nil { k.Logger(ctx).Error("failed to emit event", "error", err.Error()) - return nil, sdkerrors.Wrapf(types.ErrEmitEvent, "failed to emit event (%s)", err.Error()) + return nil, cosmoserrors.Wrapf(types.ErrEmitEvent, "failed to emit event (%s)", err.Error()) } commit() + return &types.MsgUpdateZRC20WithdrawFeeResponse{}, nil } diff --git a/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go new file mode 100644 index 0000000000..28a967b248 --- /dev/null +++ b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go @@ -0,0 +1,159 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + "cosmossdk.io/math" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_UpdateZRC20WithdrawFee(t *testing.T) { + t.Run("can update the withdraw fee", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + chainID := getValidChainID(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // set coin admin + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy the system contract and a ZRC20 contract + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20Addr := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "alpha", "alpha") + + // initial protocol fee is zero + fee, err := k.QueryProtocolFlatFee(ctx, zrc20Addr) + require.NoError(t, err) + require.Zero(t, fee.Uint64()) + + // can update the fee + _, err = k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + admin, + zrc20Addr.String(), + math.NewUint(42), + )) + require.NoError(t, err) + + // can query the updated fee + fee, err = k.QueryProtocolFlatFee(ctx, zrc20Addr) + require.NoError(t, err) + require.Equal(t, uint64(42), fee.Uint64()) + }) + + t.Run("should fail if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + _, err := k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + sample.AccAddress(), + sample.EthAddress().String(), + math.NewUint(42)), + ) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should fail if invalid zrc20 address", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + admin, + "invalid_address", + math.NewUint(42)), + ) + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + }) + + t.Run("should fail if can't retrieve the foreign coin", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + admin, + sample.EthAddress().String(), + math.NewUint(42)), + ) + require.ErrorIs(t, err, types.ErrForeignCoinNotFound) + }) + + t.Run("should fail if can't query old fee", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // setup + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + zrc20 := sample.EthAddress() + k.SetForeignCoins(ctx, sample.ForeignCoins(t, zrc20.String())) + + // the method shall fail since we only set the foreign coin manually in the store but didn't deploy the contract + _, err := k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + admin, + zrc20.String(), + math.NewUint(42)), + ) + require.ErrorIs(t, err, types.ErrContractCall) + }) + + t.Run("should fail if contract call for setting new fee fails", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{UseEVMMock: true}) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + + // setup + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + zrc20Addr := sample.EthAddress() + k.SetForeignCoins(ctx, sample.ForeignCoins(t, zrc20Addr.String())) + + // evm mocks + mockEVMKeeper.On("EstimateGas", mock.Anything, mock.Anything).Maybe().Return( + &evmtypes.EstimateGasResponse{Gas: 1000}, + nil, + ) + mockEVMKeeper.On("WithChainID", mock.Anything).Maybe().Return(ctx) + mockEVMKeeper.On("ChainID").Maybe().Return(big.NewInt(1)) + + // this is the query (commit == false) + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + require.NoError(t, err) + protocolFlatFee, err := zrc20ABI.Methods["PROTOCOL_FLAT_FEE"].Outputs.Pack(big.NewInt(42)) + require.NoError(t, err) + mockEVMKeeper.On( + "ApplyMessage", + mock.Anything, + mock.Anything, + mock.Anything, + false, + ).Return(&evmtypes.MsgEthereumTxResponse{Ret: protocolFlatFee}, nil) + + // this is the update call (commit == true) + mockEVMKeeper.On( + "ApplyMessage", + mock.Anything, + mock.Anything, + mock.Anything, + true, + ).Return(&evmtypes.MsgEthereumTxResponse{}, errors.New("transaction failed")) + + _, err = k.UpdateZRC20WithdrawFee(ctx, types.NewMsgUpdateZRC20WithdrawFee( + admin, + zrc20Addr.String(), + math.NewUint(42)), + ) + require.ErrorIs(t, err, types.ErrContractCall) + + mockEVMKeeper.AssertExpectations(t) + }) +} diff --git a/x/fungible/keeper/system_contract.go b/x/fungible/keeper/system_contract.go index 5c2c888b74..b49141b031 100644 --- a/x/fungible/keeper/system_contract.go +++ b/x/fungible/keeper/system_contract.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" 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" @@ -54,6 +53,7 @@ func (k *Keeper) GetSystemContractAddress(ctx sdk.Context) (ethcommon.Address, e return systemAddress, nil } +// GetWZetaContractAddress returns the wzeta contract address on ZetaChain func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -62,7 +62,17 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "wZetaContractAddress") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "wZetaContractAddress", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call wZetaContractAddress") } @@ -76,6 +86,7 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er return wzetaResponse.Value, nil } +// GetUniswapV2FactoryAddress returns the uniswapv2 factory contract address on ZetaChain func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -84,7 +95,17 @@ func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "uniswapv2FactoryAddress") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "uniswapv2FactoryAddress", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call uniswapv2FactoryAddress") } @@ -98,6 +119,7 @@ func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, return wzetaResponse.Value, nil } +// GetUniswapV2Router02Address returns the uniswapv2 router02 address on ZetaChain func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -106,7 +128,17 @@ func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "uniswapv2Router02Address") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "uniswapv2Router02Address", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call uniswapv2Router02Address") } @@ -120,6 +152,7 @@ func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address return routerResponse.Value, nil } +// CallWZetaDeposit calls the deposit method of the wzeta contract func (k *Keeper) CallWZetaDeposit(ctx sdk.Context, sender ethcommon.Address, amount *big.Int) error { wzetaAddress, err := k.GetWZetaContractAddress(ctx) if err != nil { @@ -130,23 +163,52 @@ func (k *Keeper) CallWZetaDeposit(ctx sdk.Context, sender ethcommon.Address, amo return err } gasLimit := big.NewInt(70_000) // for some reason, GasEstimate for this contract call is always insufficient - _, err = k.CallEVM(ctx, *abi, sender, wzetaAddress, amount, gasLimit, true, false, "deposit") + + _, err = k.CallEVM( + ctx, + *abi, + sender, + wzetaAddress, + amount, + gasLimit, + true, + false, + "deposit", + ) if err != nil { return cosmoserrors.Wrapf(err, "failed to call wzeta deposit") } return nil } +// QueryWZetaBalanceOf returns the balance of the given address in the wzeta contract func (k *Keeper) QueryWZetaBalanceOf(ctx sdk.Context, addr ethcommon.Address) (*big.Int, error) { wzetaAddress, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get wzeta contract address") } - wzetaABI, _ := connectorzevm.WZETAMetaData.GetAbi() - res, err := k.CallEVM(ctx, *wzetaABI, addr, wzetaAddress, big.NewInt(0), nil, false, false, "balanceOf", addr) + + wzetaABI, err := wzeta.WETH9MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get ABI") + } + + res, err := k.CallEVM( + ctx, + *wzetaABI, + addr, + wzetaAddress, + big.NewInt(0), + nil, + false, + false, + "balanceOf", + addr, + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to call balanceOf") } + type BigIntResponse struct { Value *big.Int } @@ -154,21 +216,38 @@ func (k *Keeper) QueryWZetaBalanceOf(ctx sdk.Context, addr ethcommon.Address) (* if err := wzetaABI.UnpackIntoInterface(&balanceResponse, "balanceOf", res.Ret); err != nil { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack balanceOf: %s", err.Error()) } + return balanceResponse.Value, nil } +// QuerySystemContractGasCoinZRC20 returns the gas coin zrc20 address for the given chain id func (k *Keeper) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainid *big.Int) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrStateVariableNotFound, "failed to get system contract variable") } systemAddress := ethcommon.HexToAddress(system.SystemContract) - sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() + sysABI, err := systemcontract.SystemContractMetaData.GetAbi() + if err != nil { + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to get system contract abi") + } - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "gasCoinZRC20ByChainId", chainid) + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "gasCoinZRC20ByChainId", + chainid, + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call gasCoinZRC20ByChainId") } + type AddressResponse struct { Value ethcommon.Address } @@ -179,14 +258,138 @@ func (k *Keeper) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainid *big.I return zrc20Res.Value, nil } -// returns the amount [in, out] -func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender ethcommon.Address, - to ethcommon.Address, amountIn *big.Int, outZRC4 ethcommon.Address, noEthereumTxEvent bool) ([]*big.Int, error) { +// CallUniswapV2RouterSwapExactTokensForTokens calls the swapExactTokensForETH method of the uniswapv2 router contract +// to swap tokens to another tokens using wZeta as intermediary +func (k *Keeper) CallUniswapV2RouterSwapExactTokensForTokens( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + inZRC4, + outZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) (ret []*big.Int, err error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function swapExactTokensForTokens( + // uint amountIn, + // uint amountOutMin, + // address[] calldata path, + // address to, + // uint deadline + //) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + BigIntZero, + big.NewInt(1000_000), + true, + noEthereumTxEvent, + "swapExactTokensForTokens", + amountIn, + BigIntZero, + []ethcommon.Address{inZRC4, wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForTokens") + } + + amounts := new([3]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "swapExactTokensForTokens", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to UnpackIntoInterface swapExactTokensForTokens") + } + return (*amounts)[:], nil +} + +// CallUniswapV2RouterSwapExactTokensForETH calls the swapExactTokensForETH method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapExactTokensForETH( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + inZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) (ret []*big.Int, err error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function swapExactTokensForETH( + // uint amountIn, + // uint amountOutMin, + // address[] calldata path, + // address to, + // uint deadline + //) + ctx.Logger().Error("Calling swapExactTokensForETH") + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + BigIntZero, + big.NewInt(300_000), + true, + noEthereumTxEvent, + "swapExactTokensForETH", + amountIn, + BigIntZero, + []ethcommon.Address{inZRC4, wzetaAddr}, + to, + big.NewInt(1e17), + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForETH") + } + + amounts := new([2]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "swapExactTokensForETH", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to UnpackIntoInterface swapExactTokensForETH") + } + return (*amounts)[:], nil +} + +// CallUniswapV2RouterSwapExactETHForToken calls the swapExactETHForTokens method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapExactETHForToken( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + outZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) ([]*big.Int, error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } @@ -194,10 +397,24 @@ func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + //function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable //returns (uint[] memory amounts); - res, err := k.CallEVM(ctx, *routerABI, sender, routerAddress, amountIn, big.NewInt(300_000), true, noEthereumTxEvent, - "swapExactETHForTokens", BigIntZero, []ethcommon.Address{wzeta, outZRC4}, to, big.NewInt(1e17)) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + amountIn, + big.NewInt(300_000), + true, + noEthereumTxEvent, + "swapExactETHForTokens", + BigIntZero, + []ethcommon.Address{wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactETHForTokens") } @@ -210,13 +427,20 @@ func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender return (*amounts)[:], nil } -func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender ethcommon.Address, to ethcommon.Address, maxAmountIn *big.Int, amountOut *big.Int, outZRC4 ethcommon.Address) ([]*big.Int, error) { - +// CallUniswapV2RouterSwapEthForExactToken calls the swapETHForExactTokens method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapEthForExactToken( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + maxAmountIn *big.Int, + amountOut *big.Int, + outZRC4 ethcommon.Address, +) ([]*big.Int, error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } @@ -224,10 +448,24 @@ func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + //function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) //returns (uint[] memory amounts); - res, err := k.CallEVM(ctx, *routerABI, sender, routerAddress, maxAmountIn, big.NewInt(300_000), true, false, - "swapETHForExactTokens", amountOut, []ethcommon.Address{wzeta, outZRC4}, to, big.NewInt(1e17)) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + maxAmountIn, + big.NewInt(300_000), + true, + false, + "swapETHForExactTokens", + amountOut, + []ethcommon.Address{wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapETHForExactTokens") } @@ -240,24 +478,77 @@ func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender return (*amounts)[:], nil } -func (k *Keeper) QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 ethcommon.Address) (*big.Int, error) { +// QueryUniswapV2RouterGetZetaAmountsIn returns the amount of zeta needed to buy the given amount of ZRC4 tokens +func (k *Keeper) QueryUniswapV2RouterGetZetaAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 ethcommon.Address) (*big.Int, error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); + k.Logger(ctx).Info("getAmountsIn", "outZRC20", outZRC4.Hex(), "amountOut", amountOut, "wzeta", wzetaAddr.Hex()) + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{wzetaAddr, outZRC4}, + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + } + + amounts := new([2]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "getAmountsIn", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to unpack getAmountsIn") + } + return (*amounts)[0], nil +} +// QueryUniswapV2RouterGetZRC4AmountsIn returns the amount of ZRC4 tokens needed to buy the given amount of zeta +func (k *Keeper) QueryUniswapV2RouterGetZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4 ethcommon.Address) (*big.Int, error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } routerAddress, err := k.GetUniswapV2Router02Address(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); - k.Logger(ctx).Info("getAmountsIn", "outZRC20", outZRC4.Hex(), "amountOut", amountOut, "wzeta", wzeta.Hex()) - res, err := k.CallEVM(ctx, *routerABI, types.ModuleAddressEVM, routerAddress, BigIntZero, nil, false, false, - "getAmountsIn", amountOut, []ethcommon.Address{wzeta, outZRC4}) + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{inZRC4, wzetaAddr}, + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") } @@ -270,30 +561,92 @@ func (k *Keeper) QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *bi return (*amounts)[0], nil } -func (k *Keeper) CallZRC20Burn(ctx sdk.Context, sender ethcommon.Address, zrc20address ethcommon.Address, - amount *big.Int, noEthereumTxEvent bool) error { +// QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn returns the amount of ZRC4 tokens needed to buy another ZRC4 token, it uses the WZeta contract as a bridge +func (k *Keeper) QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4, outZRC4 ethcommon.Address) (*big.Int, error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{inZRC4, wzetaAddr, outZRC4}, + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + } + + amounts := new([3]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "getAmountsIn", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to unpack getAmountsIn") + } + return (*amounts)[0], nil +} + +// CallZRC20Burn calls the burn method of the zrc20 contract +func (k *Keeper) CallZRC20Burn( + ctx sdk.Context, + sender ethcommon.Address, + zrc20address ethcommon.Address, + amount *big.Int, + noEthereumTxEvent bool, +) error { zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") } - _, err = k.CallEVM(ctx, *zrc20ABI, sender, zrc20address, big.NewInt(0), big.NewInt(100_000), true, noEthereumTxEvent, - "burn", amount) + + _, err = k.CallEVM( + ctx, + *zrc20ABI, + sender, + zrc20address, + big.NewInt(0), + big.NewInt(100_000), + true, + noEthereumTxEvent, + "burn", + amount, + ) if err != nil { return cosmoserrors.Wrapf(err, "failed to CallEVM method burn") } + return nil } +// CallZRC20Deposit calls the deposit method of the zrc20 contract func (k *Keeper) CallZRC20Deposit( ctx sdk.Context, sender ethcommon.Address, zrc20address ethcommon.Address, to ethcommon.Address, - amount *big.Int) error { + amount *big.Int, +) error { zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") } + _, err = k.CallEVM( ctx, *zrc20ABI, @@ -312,3 +665,37 @@ func (k *Keeper) CallZRC20Deposit( } return nil } + +// CallZRC20Approve calls the approve method of the zrc20 contract +func (k *Keeper) CallZRC20Approve( + ctx sdk.Context, + owner ethcommon.Address, + zrc20address ethcommon.Address, + spender ethcommon.Address, + amount *big.Int, + noEthereumTxEvent bool, +) error { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") + } + + _, err = k.CallEVM( + ctx, + *zrc20ABI, + owner, + zrc20address, + BigIntZero, + nil, + true, + noEthereumTxEvent, + "approve", + spender, + amount, + ) + if err != nil { + return cosmoserrors.Wrapf(err, "failed to CallEVM method approve") + } + + return nil +} diff --git a/x/fungible/keeper/system_contract_test.go b/x/fungible/keeper/system_contract_test.go index ff60389a13..3874f52435 100644 --- a/x/fungible/keeper/system_contract_test.go +++ b/x/fungible/keeper/system_contract_test.go @@ -1,16 +1,126 @@ package keeper_test import ( - "fmt" + "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/fungible/types" ) func TestKeeper_GetSystemContract(t *testing.T) { - keeper, ctx, _, _ := keepertest.FungibleKeeper(t) - keeper.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) - val, b := keeper.GetSystemContract(ctx) - fmt.Println(val, b) + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) + val, found := k.GetSystemContract(ctx) + require.True(t, found) + require.Equal(t, types.SystemContract{SystemContract: "test"}, val) + + // can remove contract + k.RemoveSystemContract(ctx) + _, found = k.GetSystemContract(ctx) + require.False(t, found) +} + +func TestKeeper_GetSystemContractAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetSystemContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, _, _, _, systemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetSystemContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, systemContract, found) +} + +func TestKeeper_GetWZetaContractAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetWZetaContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetWZetaContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, wzeta, found) +} + +func TestKeeper_GetUniswapV2FactoryAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, factory, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2FactoryAddress(ctx) + require.NoError(t, err) + require.Equal(t, factory, found) +} + +func TestKeeper_GetUniswapV2Router02Address(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetUniswapV2Router02Address(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + require.Equal(t, router, found) +} + +func TestKeeper_CallWZetaDeposit(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // mint tokens + addr := sample.Bech32AccAddress() + ethAddr := common.BytesToAddress(addr.Bytes()) + coins := sample.Coins() + err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err) + + // fail if no system contract + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.Error(t, err) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // deposit + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.NoError(t, err) + + balance, err := k.QueryWZetaBalanceOf(ctx, ethAddr) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), balance) +} + +func TestKeeper_QuerySystemContractGasCoinZRC20(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.Equal(t, zrc20, found) } diff --git a/x/fungible/types/errors.go b/x/fungible/types/errors.go index 64e770b547..5b63632114 100644 --- a/x/fungible/types/errors.go +++ b/x/fungible/types/errors.go @@ -27,6 +27,8 @@ var ( ErrGasPriceNotFound = sdkerrors.Register(ModuleName, 1116, "gas price not found") ErrUpdateNonce = sdkerrors.Register(ModuleName, 1117, "update nonce error") ErrInvalidGasLimit = sdkerrors.Register(ModuleName, 1118, "invalid gas limit") - ErrPausedZRC20 = sdkerrors.Register(ModuleName, 1120, "ZRC20 is paused") - ErrForeignCoinNotFound = sdkerrors.Register(ModuleName, 1121, "foreign coin not found") + ErrSetBytecode = sdkerrors.Register(ModuleName, 1119, "set bytecode error") + ErrInvalidContract = sdkerrors.Register(ModuleName, 1120, "invalid contract") + ErrPausedZRC20 = sdkerrors.Register(ModuleName, 1121, "ZRC20 is paused") + ErrForeignCoinNotFound = sdkerrors.Register(ModuleName, 1122, "foreign coin not found") ) diff --git a/x/fungible/types/expected_keepers.go b/x/fungible/types/expected_keepers.go index fd3b5505f5..46450aab09 100644 --- a/x/fungible/types/expected_keepers.go +++ b/x/fungible/types/expected_keepers.go @@ -7,8 +7,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" + "github.com/evmos/ethermint/x/evm/statedb" evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/common" @@ -63,4 +65,6 @@ type EVMKeeper interface { tracer vm.EVMLogger, commit bool, ) (*evmtypes.MsgEthereumTxResponse, error) + GetAccount(ctx sdk.Context, addr ethcommon.Address) *statedb.Account + SetAccount(ctx sdk.Context, addr ethcommon.Address, account statedb.Account) error } diff --git a/x/fungible/types/message_update_contract_bytecode.go b/x/fungible/types/message_update_contract_bytecode.go new file mode 100644 index 0000000000..a8a10cb5bd --- /dev/null +++ b/x/fungible/types/message_update_contract_bytecode.go @@ -0,0 +1,62 @@ +package types + +import ( + cosmoserror "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" +) + +const TypeMsgUpdateContractBytecode = "update_contract_bytecode" + +var _ sdk.Msg = &MsgUpdateContractBytecode{} + +func NewMsgUpdateContractBytecode( + creator string, contractAddress ethcommon.Address, newBytecodeAddress ethcommon.Address, +) *MsgUpdateContractBytecode { + return &MsgUpdateContractBytecode{ + Creator: creator, + ContractAddress: contractAddress.Hex(), + NewBytecodeAddress: newBytecodeAddress.Hex(), + } +} + +func (msg *MsgUpdateContractBytecode) Route() string { + return RouterKey +} + +func (msg *MsgUpdateContractBytecode) Type() string { + return TypeMsgUpdateContractBytecode +} + +func (msg *MsgUpdateContractBytecode) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUpdateContractBytecode) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUpdateContractBytecode) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Creator); err != nil { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + // check if the contract address is valid + if !ethcommon.IsHexAddress(msg.ContractAddress) { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + + // check if the bytecode contract address is valid + if !ethcommon.IsHexAddress(msg.NewBytecodeAddress) { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + + return nil +} diff --git a/x/fungible/types/message_update_contract_bytecode_test.go b/x/fungible/types/message_update_contract_bytecode_test.go new file mode 100644 index 0000000000..23a1ee2d97 --- /dev/null +++ b/x/fungible/types/message_update_contract_bytecode_test.go @@ -0,0 +1,65 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestMsgUpdateContractBytecode_ValidateBasic(t *testing.T) { + tt := []struct { + name string + msg types.MsgUpdateContractBytecode + wantError bool + }{ + { + name: "valid", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: false, + }, + { + name: "invalid creator", + msg: types.MsgUpdateContractBytecode{ + Creator: "invalid", + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: true, + }, + { + name: "invalid contract address", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: "invalid", + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: true, + }, + { + name: "invalid bytecode address", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: "invalid", + }, + wantError: true, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/fungible/types/message_update_system_contract.go b/x/fungible/types/message_update_system_contract.go index 201aad573f..b6879f2ff6 100644 --- a/x/fungible/types/message_update_system_contract.go +++ b/x/fungible/types/message_update_system_contract.go @@ -10,7 +10,7 @@ const TypeMsgUpdateSystemContract = "update_system_contract" var _ sdk.Msg = &MsgUpdateSystemContract{} -func NewMessageUpdateSystemContract(creator string, systemContractAddr string) *MsgUpdateSystemContract { +func NewMsgUpdateSystemContract(creator string, systemContractAddr string) *MsgUpdateSystemContract { return &MsgUpdateSystemContract{ Creator: creator, NewSystemContractAddress: systemContractAddr, diff --git a/x/fungible/types/message_update_zrc20_withdraw_fee.go b/x/fungible/types/message_update_zrc20_withdraw_fee.go index ba1c61183f..1b1d6de1ec 100644 --- a/x/fungible/types/message_update_zrc20_withdraw_fee.go +++ b/x/fungible/types/message_update_zrc20_withdraw_fee.go @@ -45,7 +45,7 @@ func (msg *MsgUpdateZRC20WithdrawFee) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } // check if the system contract address is valid - if ethcommon.HexToAddress(msg.Zrc20Address) == (ethcommon.Address{}) { + if !ethcommon.IsHexAddress(msg.Zrc20Address) { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid system contract address (%s)", msg.Zrc20Address) } if msg.NewWithdrawFee.IsNil() { diff --git a/x/fungible/types/tx.pb.go b/x/fungible/types/tx.pb.go index c1df08fe31..62cb8d4ac8 100644 --- a/x/fungible/types/tx.pb.go +++ b/x/fungible/types/tx.pb.go @@ -334,6 +334,7 @@ func (m *MsgDeployFungibleCoinZRC20) GetGasLimit() int64 { } type MsgDeployFungibleCoinZRC20Response struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } func (m *MsgDeployFungibleCoinZRC20Response) Reset() { *m = MsgDeployFungibleCoinZRC20Response{} } @@ -369,6 +370,13 @@ func (m *MsgDeployFungibleCoinZRC20Response) XXX_DiscardUnknown() { var xxx_messageInfo_MsgDeployFungibleCoinZRC20Response proto.InternalMessageInfo +func (m *MsgDeployFungibleCoinZRC20Response) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + type MsgRemoveForeignCoin struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -457,6 +465,110 @@ func (m *MsgRemoveForeignCoinResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRemoveForeignCoinResponse proto.InternalMessageInfo +type MsgUpdateContractBytecode struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + NewBytecodeAddress string `protobuf:"bytes,3,opt,name=new_bytecode_address,json=newBytecodeAddress,proto3" json:"new_bytecode_address,omitempty"` +} + +func (m *MsgUpdateContractBytecode) Reset() { *m = MsgUpdateContractBytecode{} } +func (m *MsgUpdateContractBytecode) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateContractBytecode) ProtoMessage() {} +func (*MsgUpdateContractBytecode) Descriptor() ([]byte, []int) { + return fileDescriptor_197fdedece277fa0, []int{8} +} +func (m *MsgUpdateContractBytecode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateContractBytecode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateContractBytecode.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 *MsgUpdateContractBytecode) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateContractBytecode.Merge(m, src) +} +func (m *MsgUpdateContractBytecode) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateContractBytecode) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateContractBytecode.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateContractBytecode proto.InternalMessageInfo + +func (m *MsgUpdateContractBytecode) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUpdateContractBytecode) GetContractAddress() string { + if m != nil { + return m.ContractAddress + } + return "" +} + +func (m *MsgUpdateContractBytecode) GetNewBytecodeAddress() string { + if m != nil { + return m.NewBytecodeAddress + } + return "" +} + +type MsgUpdateContractBytecodeResponse struct { + NewBytecodeHash []byte `protobuf:"bytes,1,opt,name=new_bytecode_hash,json=newBytecodeHash,proto3" json:"new_bytecode_hash,omitempty"` +} + +func (m *MsgUpdateContractBytecodeResponse) Reset() { *m = MsgUpdateContractBytecodeResponse{} } +func (m *MsgUpdateContractBytecodeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateContractBytecodeResponse) ProtoMessage() {} +func (*MsgUpdateContractBytecodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_197fdedece277fa0, []int{9} +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateContractBytecodeResponse.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 *MsgUpdateContractBytecodeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateContractBytecodeResponse.Merge(m, src) +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateContractBytecodeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateContractBytecodeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateContractBytecodeResponse proto.InternalMessageInfo + +func (m *MsgUpdateContractBytecodeResponse) GetNewBytecodeHash() []byte { + if m != nil { + return m.NewBytecodeHash + } + return nil +} + type MsgUpdateZRC20PausedStatus struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` Zrc20Addresses []string `protobuf:"bytes,2,rep,name=zrc20_addresses,json=zrc20Addresses,proto3" json:"zrc20_addresses,omitempty"` @@ -467,7 +579,7 @@ func (m *MsgUpdateZRC20PausedStatus) Reset() { *m = MsgUpdateZRC20Paused func (m *MsgUpdateZRC20PausedStatus) String() string { return proto.CompactTextString(m) } func (*MsgUpdateZRC20PausedStatus) ProtoMessage() {} func (*MsgUpdateZRC20PausedStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_197fdedece277fa0, []int{8} + return fileDescriptor_197fdedece277fa0, []int{10} } func (m *MsgUpdateZRC20PausedStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +636,7 @@ func (m *MsgUpdateZRC20PausedStatusResponse) Reset() { *m = MsgUpdateZRC func (m *MsgUpdateZRC20PausedStatusResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateZRC20PausedStatusResponse) ProtoMessage() {} func (*MsgUpdateZRC20PausedStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_197fdedece277fa0, []int{9} + return fileDescriptor_197fdedece277fa0, []int{11} } func (m *MsgUpdateZRC20PausedStatusResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -563,6 +675,8 @@ func init() { proto.RegisterType((*MsgDeployFungibleCoinZRC20Response)(nil), "zetachain.zetacore.fungible.MsgDeployFungibleCoinZRC20Response") proto.RegisterType((*MsgRemoveForeignCoin)(nil), "zetachain.zetacore.fungible.MsgRemoveForeignCoin") proto.RegisterType((*MsgRemoveForeignCoinResponse)(nil), "zetachain.zetacore.fungible.MsgRemoveForeignCoinResponse") + proto.RegisterType((*MsgUpdateContractBytecode)(nil), "zetachain.zetacore.fungible.MsgUpdateContractBytecode") + proto.RegisterType((*MsgUpdateContractBytecodeResponse)(nil), "zetachain.zetacore.fungible.MsgUpdateContractBytecodeResponse") proto.RegisterType((*MsgUpdateZRC20PausedStatus)(nil), "zetachain.zetacore.fungible.MsgUpdateZRC20PausedStatus") proto.RegisterType((*MsgUpdateZRC20PausedStatusResponse)(nil), "zetachain.zetacore.fungible.MsgUpdateZRC20PausedStatusResponse") } @@ -570,54 +684,60 @@ func init() { func init() { proto.RegisterFile("fungible/tx.proto", fileDescriptor_197fdedece277fa0) } var fileDescriptor_197fdedece277fa0 = []byte{ - // 744 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x4d, 0x4f, 0xdb, 0x4a, - 0x14, 0x8d, 0x09, 0x09, 0xc9, 0x7d, 0x8f, 0xbc, 0x30, 0x2f, 0x02, 0x3f, 0xf3, 0x14, 0x42, 0xa8, - 0x44, 0x54, 0x09, 0x9b, 0xa6, 0x1f, 0xa8, 0x52, 0x3f, 0x04, 0x01, 0x24, 0xa4, 0xa6, 0x42, 0xa6, - 0x51, 0x55, 0x36, 0x96, 0x63, 0x0f, 0xc6, 0x6a, 0xec, 0x89, 0x3c, 0x93, 0x86, 0xb0, 0xeb, 0x96, - 0x15, 0x52, 0xff, 0x47, 0x77, 0xfd, 0x0f, 0x2c, 0xd9, 0x54, 0xaa, 0xba, 0x40, 0x15, 0xfc, 0x91, - 0xca, 0x63, 0xc7, 0x84, 0x0f, 0x27, 0x85, 0x55, 0xe6, 0x4e, 0xe6, 0x9c, 0x7b, 0xce, 0xdc, 0x7b, - 0x3d, 0x30, 0xb5, 0xd7, 0x71, 0x2d, 0xbb, 0xd9, 0xc2, 0x0a, 0x3b, 0x90, 0xdb, 0x1e, 0x61, 0x04, - 0xcd, 0x1e, 0x62, 0xa6, 0x1b, 0xfb, 0xba, 0xed, 0xca, 0x7c, 0x45, 0x3c, 0x2c, 0xf7, 0x4f, 0x49, - 0xff, 0x1a, 0xc4, 0x71, 0x88, 0xab, 0x04, 0x3f, 0x01, 0x42, 0x2a, 0x58, 0xc4, 0x22, 0x7c, 0xa9, - 0xf8, 0xab, 0x60, 0xb7, 0xfc, 0x4d, 0x80, 0xff, 0xea, 0xd4, 0x6a, 0xb4, 0x4d, 0x9d, 0xe1, 0x5d, - 0xb5, 0x56, 0x5d, 0x7e, 0x6f, 0xb3, 0x7d, 0xd3, 0xd3, 0xbb, 0x9b, 0x18, 0x23, 0x11, 0x26, 0x0c, - 0x0f, 0xeb, 0x8c, 0x78, 0xa2, 0x50, 0x12, 0x2a, 0x59, 0xb5, 0x1f, 0xa2, 0x05, 0x98, 0x3c, 0xf4, - 0x8c, 0xea, 0xb2, 0xa6, 0x9b, 0xa6, 0x87, 0x29, 0x15, 0xc7, 0xf8, 0xff, 0x7f, 0xf3, 0xcd, 0xd5, - 0x60, 0x0f, 0x7d, 0x80, 0xbc, 0x8b, 0xbb, 0x5a, 0x37, 0x64, 0xd4, 0xf6, 0x30, 0x16, 0xd3, 0xfe, - 0xb9, 0x35, 0xe5, 0xe4, 0x6c, 0x2e, 0xf1, 0xf3, 0x6c, 0x6e, 0xd1, 0xb2, 0xd9, 0x7e, 0xa7, 0x29, - 0x1b, 0xc4, 0x51, 0x0c, 0x42, 0x1d, 0x42, 0xc3, 0x9f, 0x25, 0x6a, 0x7e, 0x54, 0x58, 0xaf, 0x8d, - 0xa9, 0xdc, 0xb0, 0x5d, 0xa6, 0xe6, 0x5c, 0xdc, 0x1d, 0x50, 0x56, 0x5e, 0x80, 0xf9, 0x58, 0xd9, - 0x2a, 0xa6, 0x6d, 0xe2, 0x52, 0x5c, 0xf6, 0x60, 0x26, 0x3a, 0xb4, 0xd3, 0xa3, 0x0c, 0x3b, 0x35, - 0xe2, 0x32, 0x4f, 0x37, 0xd8, 0x10, 0x67, 0x2f, 0x61, 0xd6, 0x17, 0x4d, 0xf9, 0x79, 0xcd, 0x08, - 0x01, 0xd7, 0x7c, 0x8a, 0x2e, 0xee, 0x5e, 0x65, 0x0c, 0x3d, 0x97, 0xe7, 0x61, 0x2e, 0x26, 0x67, - 0x24, 0xeb, 0x68, 0x0c, 0xa4, 0x3a, 0xb5, 0xd6, 0x71, 0xbb, 0x45, 0x7a, 0x9b, 0x61, 0xd1, 0x6a, - 0xc4, 0x76, 0xb9, 0x91, 0x21, 0xd2, 0x0a, 0x90, 0xda, 0xf0, 0x8f, 0x84, 0x22, 0x82, 0x00, 0x55, - 0x20, 0xbf, 0x47, 0x3c, 0x6c, 0x5b, 0xae, 0xc6, 0x1b, 0x42, 0xb3, 0x4d, 0x31, 0x59, 0x12, 0x2a, - 0x49, 0x35, 0x17, 0xee, 0xd7, 0xfc, 0xed, 0x2d, 0x13, 0x49, 0x90, 0x31, 0xb1, 0x61, 0x3b, 0x7a, - 0x8b, 0x8a, 0xe3, 0x25, 0xa1, 0x32, 0xa9, 0x46, 0x31, 0x42, 0x30, 0xee, 0xea, 0x0e, 0x16, 0x53, - 0x9c, 0x9a, 0xaf, 0xd1, 0x34, 0xa4, 0x69, 0xcf, 0x69, 0x92, 0x56, 0x50, 0x35, 0x35, 0x8c, 0xd0, - 0x12, 0x64, 0x0d, 0x62, 0xbb, 0x9a, 0x5f, 0x1f, 0x71, 0xa2, 0x24, 0x54, 0x72, 0xd5, 0xbc, 0x1c, - 0x36, 0x9b, 0xef, 0xe3, 0x5d, 0xaf, 0x8d, 0xd5, 0x8c, 0x11, 0xae, 0xd0, 0x2c, 0x64, 0x2d, 0x9d, - 0x6a, 0x2d, 0xdb, 0xb1, 0x99, 0x98, 0xe1, 0xca, 0x32, 0x96, 0x4e, 0xdf, 0xf8, 0x71, 0xf9, 0x01, - 0x94, 0xe3, 0xef, 0x22, 0xba, 0xb2, 0x75, 0x28, 0xd4, 0xa9, 0xa5, 0x62, 0x87, 0x7c, 0xc2, 0x9b, - 0xa1, 0x29, 0x62, 0xbb, 0x43, 0xee, 0xaa, 0xef, 0x67, 0xec, 0xd2, 0x4f, 0xb9, 0x08, 0xff, 0xdf, - 0xc6, 0x12, 0x65, 0xf9, 0x2a, 0xf0, 0xc2, 0x0c, 0x74, 0xd5, 0xb6, 0xde, 0xa1, 0xd8, 0xdc, 0x61, - 0x3a, 0xeb, 0xd0, 0x21, 0xc9, 0x16, 0xe1, 0x9f, 0x2b, 0xd3, 0x80, 0xfd, 0x3e, 0x49, 0x56, 0xb2, - 0x6a, 0x6e, 0x70, 0x1e, 0x30, 0x45, 0x75, 0x48, 0xeb, 0x06, 0xb3, 0x89, 0xcb, 0x2b, 0x94, 0xab, - 0x3e, 0x95, 0x87, 0xcc, 0xb1, 0x1c, 0x08, 0x19, 0xd4, 0xb0, 0xca, 0xc1, 0x6a, 0x48, 0x12, 0x5e, - 0x5e, 0x8c, 0xde, 0xbe, 0xad, 0x87, 0x55, 0x10, 0xe3, 0x98, 0x50, 0x16, 0x52, 0xdb, 0xab, 0x8d, - 0x9d, 0x8d, 0x7c, 0x02, 0xfd, 0x05, 0x13, 0x8d, 0xb7, 0x41, 0x20, 0x54, 0xbf, 0xa7, 0x20, 0x59, - 0xa7, 0x16, 0xfa, 0x22, 0xc0, 0x4c, 0x5c, 0xa3, 0xae, 0x0c, 0x15, 0x1f, 0x5f, 0x55, 0xe9, 0xf5, - 0x3d, 0x81, 0x7d, 0x47, 0xe8, 0xb3, 0x00, 0x53, 0x37, 0x9b, 0xe1, 0xd1, 0x28, 0xda, 0x1b, 0x10, - 0xe9, 0xf9, 0x9d, 0x21, 0x91, 0x86, 0x23, 0x01, 0x0a, 0xb7, 0x7e, 0x5a, 0x9e, 0x8c, 0xe2, 0xbc, - 0x0d, 0x25, 0xbd, 0xb8, 0x0f, 0x2a, 0x12, 0x73, 0x2c, 0xc0, 0x74, 0xcc, 0x37, 0xfc, 0xd9, 0x9f, - 0x11, 0x5f, 0xc7, 0x49, 0xaf, 0xee, 0x87, 0x8b, 0x24, 0xf9, 0x9d, 0x13, 0x37, 0x49, 0x2b, 0x77, - 0xe0, 0x1e, 0x04, 0x8e, 0xee, 0x9c, 0x11, 0xb3, 0xb0, 0xb6, 0x75, 0x72, 0x5e, 0x14, 0x4e, 0xcf, - 0x8b, 0xc2, 0xaf, 0xf3, 0xa2, 0x70, 0x7c, 0x51, 0x4c, 0x9c, 0x5e, 0x14, 0x13, 0x3f, 0x2e, 0x8a, - 0x89, 0x5d, 0x65, 0xe0, 0x29, 0xf2, 0xa9, 0x97, 0x78, 0x16, 0xa5, 0x9f, 0x45, 0x39, 0x50, 0x2e, - 0x5f, 0x61, 0xff, 0x5d, 0x6a, 0xa6, 0xf9, 0x0b, 0xfa, 0xf8, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xc4, 0xe2, 0x45, 0x29, 0x9e, 0x07, 0x00, 0x00, + // 843 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x16, 0xad, 0x58, 0xb6, 0xa6, 0x89, 0x2c, 0x6f, 0x85, 0x84, 0xa5, 0x0b, 0xd9, 0x61, 0x0a, + 0x44, 0x0d, 0x60, 0xd2, 0x55, 0x7f, 0x82, 0x02, 0x6d, 0x0a, 0x5b, 0x89, 0xd1, 0x00, 0x55, 0x1b, + 0xd0, 0x15, 0x8a, 0xe6, 0x42, 0xac, 0xc8, 0x35, 0x45, 0x54, 0xdc, 0x15, 0xb8, 0xab, 0x2a, 0xca, + 0xad, 0xd7, 0x9c, 0x82, 0xf6, 0x3d, 0x7a, 0xeb, 0x3b, 0xe4, 0x98, 0x63, 0xd1, 0x43, 0x50, 0xd8, + 0x97, 0x3e, 0x46, 0xc1, 0xe5, 0x4f, 0x28, 0x59, 0x94, 0x1c, 0x9f, 0xb8, 0xb3, 0x9a, 0xf9, 0xf6, + 0x9b, 0x99, 0x6f, 0x56, 0x0b, 0xdb, 0xa7, 0x63, 0xea, 0xf9, 0xfd, 0x21, 0x31, 0xc5, 0x33, 0x63, + 0x14, 0x32, 0xc1, 0xd0, 0xce, 0x73, 0x22, 0xb0, 0x33, 0xc0, 0x3e, 0x35, 0xe4, 0x8a, 0x85, 0xc4, + 0x48, 0xbd, 0xb4, 0xf7, 0x1d, 0x16, 0x04, 0x8c, 0x9a, 0xf1, 0x27, 0x8e, 0xd0, 0x1a, 0x1e, 0xf3, + 0x98, 0x5c, 0x9a, 0xd1, 0x2a, 0xde, 0xd5, 0xff, 0x52, 0xe0, 0x83, 0x2e, 0xf7, 0x7a, 0x23, 0x17, + 0x0b, 0xf2, 0xd4, 0xea, 0xb4, 0x0f, 0x7e, 0xf2, 0xc5, 0xc0, 0x0d, 0xf1, 0xe4, 0x98, 0x10, 0xa4, + 0xc2, 0x86, 0x13, 0x12, 0x2c, 0x58, 0xa8, 0x2a, 0x7b, 0x4a, 0xab, 0x6a, 0xa5, 0x26, 0xba, 0x03, + 0x37, 0x9e, 0x87, 0x4e, 0xfb, 0xc0, 0xc6, 0xae, 0x1b, 0x12, 0xce, 0xd5, 0x35, 0xf9, 0xfb, 0x75, + 0xb9, 0x79, 0x18, 0xef, 0xa1, 0x9f, 0xa1, 0x4e, 0xc9, 0xc4, 0x9e, 0x24, 0x88, 0xf6, 0x29, 0x21, + 0x6a, 0x25, 0xf2, 0x3b, 0x32, 0x5f, 0xbd, 0xd9, 0x2d, 0xfd, 0xf3, 0x66, 0xf7, 0xae, 0xe7, 0x8b, + 0xc1, 0xb8, 0x6f, 0x38, 0x2c, 0x30, 0x1d, 0xc6, 0x03, 0xc6, 0x93, 0xcf, 0x3e, 0x77, 0x7f, 0x31, + 0xc5, 0x74, 0x44, 0xb8, 0xd1, 0xf3, 0xa9, 0xb0, 0x6a, 0x94, 0x4c, 0x72, 0xcc, 0xf4, 0x3b, 0x70, + 0xbb, 0x90, 0xb6, 0x45, 0xf8, 0x88, 0x51, 0x4e, 0xf4, 0x10, 0x6e, 0x65, 0x4e, 0x27, 0x53, 0x2e, + 0x48, 0xd0, 0x61, 0x54, 0x84, 0xd8, 0x11, 0x4b, 0x32, 0xfb, 0x1a, 0x76, 0x22, 0xd2, 0x5c, 0xfa, + 0xdb, 0x4e, 0x12, 0x30, 0x97, 0xa7, 0x4a, 0xc9, 0x64, 0x16, 0x31, 0xc9, 0x59, 0xbf, 0x0d, 0xbb, + 0x05, 0x67, 0x66, 0xb4, 0x5e, 0xac, 0x81, 0xd6, 0xe5, 0xde, 0x43, 0x32, 0x1a, 0xb2, 0xe9, 0x71, + 0xd2, 0xb4, 0x0e, 0xf3, 0xa9, 0x4c, 0x64, 0x09, 0xb5, 0x06, 0xac, 0x3f, 0x8a, 0x5c, 0x12, 0x12, + 0xb1, 0x81, 0x5a, 0x50, 0x3f, 0x65, 0x21, 0xf1, 0x3d, 0x6a, 0x4b, 0x41, 0xd8, 0xbe, 0xab, 0x96, + 0xf7, 0x94, 0x56, 0xd9, 0xaa, 0x25, 0xfb, 0x9d, 0x68, 0xfb, 0xb1, 0x8b, 0x34, 0xd8, 0x74, 0x89, + 0xe3, 0x07, 0x78, 0xc8, 0xd5, 0x6b, 0x7b, 0x4a, 0xeb, 0x86, 0x95, 0xd9, 0x08, 0xc1, 0x35, 0x8a, + 0x03, 0xa2, 0xae, 0x4b, 0x68, 0xb9, 0x46, 0x37, 0xa1, 0xc2, 0xa7, 0x41, 0x9f, 0x0d, 0xe3, 0xae, + 0x59, 0x89, 0x85, 0xf6, 0xa1, 0xea, 0x30, 0x9f, 0xda, 0x51, 0x7f, 0xd4, 0x8d, 0x3d, 0xa5, 0x55, + 0x6b, 0xd7, 0x8d, 0x44, 0x6c, 0x51, 0x1e, 0x3f, 0x4e, 0x47, 0xc4, 0xda, 0x74, 0x92, 0x15, 0xda, + 0x81, 0xaa, 0x87, 0xb9, 0x3d, 0xf4, 0x03, 0x5f, 0xa8, 0x9b, 0x92, 0xd9, 0xa6, 0x87, 0xf9, 0x77, + 0x91, 0xad, 0x3f, 0x00, 0xbd, 0xb8, 0x16, 0x69, 0xc9, 0xa2, 0x9a, 0xa4, 0x0d, 0x48, 0x6a, 0x92, + 0x98, 0xfa, 0x43, 0x68, 0x74, 0xb9, 0x67, 0x91, 0x80, 0xfd, 0x4a, 0x8e, 0x93, 0x74, 0x99, 0x4f, + 0x97, 0x54, 0x31, 0xcd, 0x74, 0xed, 0x6d, 0xa6, 0x7a, 0x13, 0x3e, 0x5c, 0x84, 0x92, 0xb5, 0xec, + 0xf7, 0xfc, 0x98, 0xa4, 0x0d, 0x3d, 0x9a, 0x0a, 0xe2, 0x30, 0x77, 0xd9, 0x98, 0x7c, 0x0c, 0xf5, + 0x02, 0x05, 0x6d, 0x39, 0xb3, 0xc2, 0x41, 0x07, 0xd0, 0x88, 0x74, 0xd7, 0x4f, 0x40, 0x33, 0xf7, + 0xb2, 0x74, 0x47, 0x94, 0x4c, 0xd2, 0xf3, 0x52, 0xa9, 0xfd, 0x90, 0x9b, 0x81, 0x79, 0x4e, 0x59, + 0xe5, 0xee, 0xc1, 0xf6, 0x0c, 0xec, 0x00, 0xf3, 0x81, 0x64, 0x79, 0xdd, 0xda, 0xca, 0x61, 0x7e, + 0x8b, 0xf9, 0x40, 0xff, 0x53, 0x91, 0xc2, 0xcc, 0x4d, 0xd5, 0x13, 0x3c, 0xe6, 0xc4, 0x3d, 0x11, + 0x58, 0x8c, 0xf9, 0x92, 0x34, 0xef, 0xc2, 0xd6, 0xcc, 0x6d, 0x40, 0xa2, 0x2c, 0xcb, 0xad, 0xaa, + 0x55, 0xcb, 0xdf, 0x07, 0x84, 0xa3, 0x2e, 0x54, 0xb0, 0x23, 0x7c, 0x46, 0x65, 0x5a, 0xb5, 0xf6, + 0xe7, 0xc6, 0x92, 0x7b, 0xcc, 0x88, 0x89, 0xe4, 0x39, 0x1c, 0xca, 0x60, 0x2b, 0x01, 0xd1, 0x3f, + 0x92, 0xe2, 0x29, 0xe0, 0x9b, 0x96, 0xe0, 0x5e, 0x1b, 0xd4, 0x22, 0x24, 0x54, 0x85, 0xf5, 0x27, + 0x87, 0xbd, 0x93, 0x47, 0xf5, 0x12, 0x7a, 0x0f, 0x36, 0x7a, 0xdf, 0xc7, 0x86, 0xd2, 0xfe, 0xaf, + 0x02, 0xe5, 0x2e, 0xf7, 0xd0, 0x1f, 0x0a, 0xdc, 0x2a, 0x1a, 0xd4, 0xfb, 0x4b, 0xc9, 0x17, 0xab, + 0x5a, 0xfb, 0xe6, 0x8a, 0x81, 0x59, 0x53, 0x7f, 0x53, 0x60, 0xfb, 0xa2, 0xe4, 0x3f, 0x59, 0x05, + 0x7b, 0x21, 0x44, 0xfb, 0xf2, 0x9d, 0x43, 0x32, 0x0e, 0x2f, 0x14, 0x68, 0x2c, 0xbc, 0x5a, 0x3f, + 0x5b, 0x85, 0xb9, 0x28, 0x4a, 0xfb, 0xea, 0x2a, 0x51, 0x19, 0x99, 0x97, 0x0a, 0xdc, 0x2c, 0xf8, + 0x0f, 0xfb, 0xe2, 0x72, 0xc0, 0xf3, 0x71, 0xda, 0x83, 0xab, 0xc5, 0x2d, 0xa0, 0x74, 0xe1, 0xbe, + 0xb8, 0x24, 0xa5, 0xf9, 0xb8, 0xcb, 0x52, 0x2a, 0xbc, 0x0b, 0x22, 0x31, 0x17, 0x0d, 0xf7, 0xfd, + 0x77, 0x48, 0x37, 0x1f, 0xb8, 0x5a, 0xcc, 0x2b, 0xc6, 0xf3, 0xe8, 0xf1, 0xab, 0xb3, 0xa6, 0xf2, + 0xfa, 0xac, 0xa9, 0xfc, 0x7b, 0xd6, 0x54, 0x5e, 0x9e, 0x37, 0x4b, 0xaf, 0xcf, 0x9b, 0xa5, 0xbf, + 0xcf, 0x9b, 0xa5, 0xa7, 0x66, 0xee, 0x75, 0x10, 0x41, 0xef, 0xcb, 0x53, 0xcc, 0xf4, 0x14, 0xf3, + 0x99, 0xf9, 0xf6, 0x61, 0x14, 0x3d, 0x15, 0xfa, 0x15, 0xf9, 0xa8, 0xf9, 0xf4, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x16, 0xf6, 0xee, 0xe7, 0x31, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -636,6 +756,7 @@ type MsgClient interface { RemoveForeignCoin(ctx context.Context, in *MsgRemoveForeignCoin, opts ...grpc.CallOption) (*MsgRemoveForeignCoinResponse, error) UpdateSystemContract(ctx context.Context, in *MsgUpdateSystemContract, opts ...grpc.CallOption) (*MsgUpdateSystemContractResponse, error) UpdateZRC20WithdrawFee(ctx context.Context, in *MsgUpdateZRC20WithdrawFee, opts ...grpc.CallOption) (*MsgUpdateZRC20WithdrawFeeResponse, error) + UpdateContractBytecode(ctx context.Context, in *MsgUpdateContractBytecode, opts ...grpc.CallOption) (*MsgUpdateContractBytecodeResponse, error) UpdateZRC20PausedStatus(ctx context.Context, in *MsgUpdateZRC20PausedStatus, opts ...grpc.CallOption) (*MsgUpdateZRC20PausedStatusResponse, error) } @@ -683,6 +804,15 @@ func (c *msgClient) UpdateZRC20WithdrawFee(ctx context.Context, in *MsgUpdateZRC return out, nil } +func (c *msgClient) UpdateContractBytecode(ctx context.Context, in *MsgUpdateContractBytecode, opts ...grpc.CallOption) (*MsgUpdateContractBytecodeResponse, error) { + out := new(MsgUpdateContractBytecodeResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.fungible.Msg/UpdateContractBytecode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) UpdateZRC20PausedStatus(ctx context.Context, in *MsgUpdateZRC20PausedStatus, opts ...grpc.CallOption) (*MsgUpdateZRC20PausedStatusResponse, error) { out := new(MsgUpdateZRC20PausedStatusResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.fungible.Msg/UpdateZRC20PausedStatus", in, out, opts...) @@ -698,6 +828,7 @@ type MsgServer interface { RemoveForeignCoin(context.Context, *MsgRemoveForeignCoin) (*MsgRemoveForeignCoinResponse, error) UpdateSystemContract(context.Context, *MsgUpdateSystemContract) (*MsgUpdateSystemContractResponse, error) UpdateZRC20WithdrawFee(context.Context, *MsgUpdateZRC20WithdrawFee) (*MsgUpdateZRC20WithdrawFeeResponse, error) + UpdateContractBytecode(context.Context, *MsgUpdateContractBytecode) (*MsgUpdateContractBytecodeResponse, error) UpdateZRC20PausedStatus(context.Context, *MsgUpdateZRC20PausedStatus) (*MsgUpdateZRC20PausedStatusResponse, error) } @@ -717,6 +848,9 @@ func (*UnimplementedMsgServer) UpdateSystemContract(ctx context.Context, req *Ms func (*UnimplementedMsgServer) UpdateZRC20WithdrawFee(ctx context.Context, req *MsgUpdateZRC20WithdrawFee) (*MsgUpdateZRC20WithdrawFeeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateZRC20WithdrawFee not implemented") } +func (*UnimplementedMsgServer) UpdateContractBytecode(ctx context.Context, req *MsgUpdateContractBytecode) (*MsgUpdateContractBytecodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateContractBytecode not implemented") +} func (*UnimplementedMsgServer) UpdateZRC20PausedStatus(ctx context.Context, req *MsgUpdateZRC20PausedStatus) (*MsgUpdateZRC20PausedStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateZRC20PausedStatus not implemented") } @@ -797,6 +931,24 @@ func _Msg_UpdateZRC20WithdrawFee_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Msg_UpdateContractBytecode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateContractBytecode) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateContractBytecode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.fungible.Msg/UpdateContractBytecode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateContractBytecode(ctx, req.(*MsgUpdateContractBytecode)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_UpdateZRC20PausedStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgUpdateZRC20PausedStatus) if err := dec(in); err != nil { @@ -835,6 +987,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateZRC20WithdrawFee", Handler: _Msg_UpdateZRC20WithdrawFee_Handler, }, + { + MethodName: "UpdateContractBytecode", + Handler: _Msg_UpdateContractBytecode_Handler, + }, { MethodName: "UpdateZRC20PausedStatus", Handler: _Msg_UpdateZRC20PausedStatus_Handler, @@ -1065,6 +1221,13 @@ func (m *MsgDeployFungibleCoinZRC20Response) MarshalToSizedBuffer(dAtA []byte) ( _ = i var l int _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTx(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -1128,6 +1291,80 @@ func (m *MsgRemoveForeignCoinResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *MsgUpdateContractBytecode) 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 *MsgUpdateContractBytecode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateContractBytecode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewBytecodeAddress) > 0 { + i -= len(m.NewBytecodeAddress) + copy(dAtA[i:], m.NewBytecodeAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewBytecodeAddress))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0x12 + } + 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 *MsgUpdateContractBytecodeResponse) 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 *MsgUpdateContractBytecodeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateContractBytecodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewBytecodeHash) > 0 { + i -= len(m.NewBytecodeHash) + copy(dAtA[i:], m.NewBytecodeHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewBytecodeHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *MsgUpdateZRC20PausedStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1303,6 +1540,10 @@ func (m *MsgDeployFungibleCoinZRC20Response) Size() (n int) { } var l int _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1332,6 +1573,40 @@ func (m *MsgRemoveForeignCoinResponse) Size() (n int) { return n } +func (m *MsgUpdateContractBytecode) 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)) + } + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewBytecodeAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUpdateContractBytecodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.NewBytecodeHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + func (m *MsgUpdateZRC20PausedStatus) Size() (n int) { if m == nil { return 0 @@ -2014,6 +2289,38 @@ func (m *MsgDeployFungibleCoinZRC20Response) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgDeployFungibleCoinZRC20Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", 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.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2199,6 +2506,236 @@ func (m *MsgRemoveForeignCoinResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgUpdateContractBytecode) 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: MsgUpdateContractBytecode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateContractBytecode: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", 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.ContractAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewBytecodeAddress", 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.NewBytecodeAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + 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 *MsgUpdateContractBytecodeResponse) 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: MsgUpdateContractBytecodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateContractBytecodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewBytecodeHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewBytecodeHash = append(m.NewBytecodeHash[:0], dAtA[iNdEx:postIndex]...) + if m.NewBytecodeHash == nil { + m.NewBytecodeHash = []byte{} + } + iNdEx = postIndex + 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 *MsgUpdateZRC20PausedStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/keeper/block_header.go b/x/observer/keeper/block_header.go new file mode 100644 index 0000000000..6bd64b34e4 --- /dev/null +++ b/x/observer/keeper/block_header.go @@ -0,0 +1,78 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/observer/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// SetBlockHeader set a specific block header in the store from its index +func (k Keeper) SetBlockHeader(ctx sdk.Context, header common.BlockHeader) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) + b := k.cdc.MustMarshal(&header) + store.Set(header.Hash, b) +} + +// GetBlockHeader returns a block header from its hash +func (k Keeper) GetBlockHeader(ctx sdk.Context, hash []byte) (val common.BlockHeader, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) + + b := store.Get(hash) + if b == nil { + return val, false + } + + k.cdc.MustUnmarshal(b, &val) + return val, true +} + +// RemoveBlockHeader removes a block header from the store +func (k Keeper) RemoveBlockHeader(ctx sdk.Context, hash []byte) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) + store.Delete(hash) +} + +// GetAllBlockHeaders queries all for block header +func (k Keeper) GetAllBlockHeaders(c context.Context, req *types.QueryAllBlockHeaderRequest) (*types.QueryAllBlockHeaderResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + store := ctx.KVStore(k.storeKey) + blockHeaderStore := prefix.NewStore(store, types.KeyPrefix(types.BlockHeaderKey)) + + var blockHeaders []*common.BlockHeader + pageRes, err := query.Paginate(blockHeaderStore, req.Pagination, func(key []byte, value []byte) error { + var blockHeader common.BlockHeader + if err := k.cdc.Unmarshal(value, &blockHeader); err != nil { + return err + } + + blockHeaders = append(blockHeaders, &blockHeader) + return nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return &types.QueryAllBlockHeaderResponse{BlockHeaders: blockHeaders, Pagination: pageRes}, nil +} + +// GetBlockHeaderByHash queries block header by hash +func (k Keeper) GetBlockHeaderByHash(c context.Context, req *types.QueryGetBlockHeaderByHashRequest) (*types.QueryGetBlockHeaderByHashResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + header, found := k.GetBlockHeader(sdk.UnwrapSDKContext(c), req.BlockHash) + if !found { + return nil, status.Error(codes.NotFound, "not found") + } + + return &types.QueryGetBlockHeaderByHashResponse{BlockHeader: &header}, nil +} diff --git a/x/observer/keeper/grpc_query_prove.go b/x/observer/keeper/grpc_query_prove.go new file mode 100644 index 0000000000..e4880f4c2e --- /dev/null +++ b/x/observer/keeper/grpc_query_prove.go @@ -0,0 +1,47 @@ +package keeper + +import ( + "context" + "fmt" + + "github.com/zeta-chain/zetacore/common" + + sdk "github.com/cosmos/cosmos-sdk/types" + eth "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/zeta-chain/zetacore/x/observer/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k Keeper) Prove(c context.Context, req *types.QueryProveRequest) (*types.QueryProveResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + blockHash := eth.HexToHash(req.BlockHash) + res, found := k.GetBlockHeader(ctx, blockHash.Bytes()) + if !found { + return nil, status.Error(codes.NotFound, "block header not found") + } + + proven := false + + val, err := req.Proof.Verify(res.Header, int(req.TxIndex)) + if err != nil && !common.IsErrorInvalidProof(err) { + return nil, status.Error(codes.Internal, err.Error()) + } + if err == nil { + var txx ethtypes.Transaction + err = txx.UnmarshalBinary(val) + if err != nil { + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to unmarshal transaction: %s", err)) + } + proven = true + } + + return &types.QueryProveResponse{ + Valid: proven, + }, nil +} diff --git a/x/observer/keeper/msg_server_add_block_header.go b/x/observer/keeper/msg_server_add_block_header.go new file mode 100644 index 0000000000..8ee4ffa5cd --- /dev/null +++ b/x/observer/keeper/msg_server_add_block_header.go @@ -0,0 +1,65 @@ +package keeper + +import ( + "context" + "encoding/hex" + + cosmoserrors "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// AddBlockHeader handles adding a block header to the store, through majority voting of observers +func (k msgServer) AddBlockHeader(goCtx context.Context, msg *types.MsgAddBlockHeader) (*types.MsgAddBlockHeaderResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // check authorization for this chain + chain := common.GetChainFromChainID(msg.ChainId) + ok, err := k.IsAuthorized(ctx, msg.Creator, chain) + if !ok { + return nil, cosmoserrors.Wrap(types.ErrNotAuthorizedPolicy, err.Error()) + } + + // add vote to ballot + ballot, _, err := k.FindBallot(ctx, msg.Digest(), chain, types.ObservationType_InBoundTx) + if err != nil { + return nil, cosmoserrors.Wrap(err, "failed to find ballot") + } + ballot, err = k.AddVoteToBallot(ctx, ballot, msg.Creator, types.VoteType_SuccessObservation) + if err != nil { + return nil, cosmoserrors.Wrap(err, "failed to add vote to ballot") + } + _, isFinalized := k.CheckIfFinalizingVote(ctx, ballot) + if !isFinalized { + return &types.MsgAddBlockHeaderResponse{}, nil + } + + /** + * Vote finalized, add block header to store + */ + _, found := k.GetBlockHeader(ctx, msg.BlockHash) + if found { + return nil, cosmoserrors.Wrap(types.ErrBlockAlreadyExist, hex.EncodeToString(msg.BlockHash)) + } + + // NOTE: error is checked in BasicValidation in msg; check again for extra caution + pHash, err := msg.Header.ParentHash() + if err != nil { + return nil, cosmoserrors.Wrap(types.ErrNoParentHash, err.Error()) + } + + // TODO: add check for parent block header's existence here https://github.com/zeta-chain/node/issues/1133 + + bh := common.BlockHeader{ + Header: msg.Header, + Height: msg.Height, + Hash: msg.BlockHash, + ParentHash: pHash, + ChainId: msg.ChainId, + } + k.SetBlockHeader(ctx, bh) + + return &types.MsgAddBlockHeaderResponse{}, nil +} diff --git a/x/observer/types/core_params_mainnet.go b/x/observer/types/core_params_mainnet.go index bc56eb388f..38ab439aab 100644 --- a/x/observer/types/core_params_mainnet.go +++ b/x/observer/types/core_params_mainnet.go @@ -1,11 +1,72 @@ -//go:build !PRIVNET && !TESTNET -// +build !PRIVNET,!TESTNET +//go:build !PRIVNET && !TESTNET && !MOCK_MAINNET +// +build !PRIVNET,!TESTNET,!MOCK_MAINNET package types +import ( + "fmt" + + "github.com/coinbase/rosetta-sdk-go/types" + "github.com/zeta-chain/zetacore/common" +) + func GetCoreParams() CoreParamsList { params := CoreParamsList{ - CoreParams: []*CoreParams{}, + CoreParams: []*CoreParams{ + { + ChainId: common.EthChain().ChainId, + ConfirmationCount: 14, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + InTxTicker: 12, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + { + ChainId: common.BscMainnetChain().ChainId, + ConfirmationCount: 14, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + InTxTicker: 5, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + { + ChainId: common.BtcMainnetChain().ChainId, + ConfirmationCount: 2, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + WatchUtxoTicker: 30, + InTxTicker: 120, + OutTxTicker: 60, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + }, + } + chainList := common.ExternalChainList() + requiredParams := len(chainList) + availableParams := 0 + for _, chain := range chainList { + for _, param := range params.CoreParams { + if chain.ChainId == param.ChainId { + availableParams++ + } + } + } + if availableParams != requiredParams { + panic(fmt.Sprintf("Core params are not available for all chains , DefaultChains : %s , CoreParams : %s", + types.PrettyPrintStruct(chainList), params.String())) } return params } diff --git a/x/observer/types/core_params_mock_mainnet.go b/x/observer/types/core_params_mock_mainnet.go new file mode 100644 index 0000000000..549edc5bf7 --- /dev/null +++ b/x/observer/types/core_params_mock_mainnet.go @@ -0,0 +1,72 @@ +//go:build MOCK_MAINNET +// +build MOCK_MAINNET + +package types + +import ( + "fmt" + + "github.com/coinbase/rosetta-sdk-go/types" + "github.com/zeta-chain/zetacore/common" +) + +func GetCoreParams() CoreParamsList { + params := CoreParamsList{ + CoreParams: []*CoreParams{ + { + ChainId: common.EthChain().ChainId, + ConfirmationCount: 6, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + InTxTicker: 12, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + { + ChainId: common.BscMainnetChain().ChainId, + ConfirmationCount: 6, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + InTxTicker: 5, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + { + ChainId: common.BtcMainnetChain().ChainId, + ConfirmationCount: 2, + ZetaTokenContractAddress: "", + ConnectorContractAddress: "", + Erc20CustodyContractAddress: "", + WatchUtxoTicker: 30, + InTxTicker: 120, + OutTxTicker: 60, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + }, + }, + } + chainList := common.ExternalChainList() + requiredParams := len(chainList) + availableParams := 0 + for _, chain := range chainList { + for _, param := range params.CoreParams { + if chain.ChainId == param.ChainId { + availableParams++ + } + } + } + if availableParams != requiredParams { + panic(fmt.Sprintf("Core params are not available for all chains , DefaultChains : %s , CoreParams : %s", + types.PrettyPrintStruct(chainList), params.String())) + } + return params +} diff --git a/x/observer/types/core_params_privnet.go b/x/observer/types/core_params_privnet.go index 71e9a0525a..832bf57475 100644 --- a/x/observer/types/core_params_privnet.go +++ b/x/observer/types/core_params_privnet.go @@ -26,15 +26,6 @@ func GetCoreParams() CoreParamsList { OutboundTxScheduleInterval: 2, OutboundTxScheduleLookahead: 5, }, - { - - ChainId: common.ZetaChain().ChainId, - ConfirmationCount: 1, - GasPriceTicker: 5, - ZetaTokenContractAddress: "0x2DD9830f8Ac0E421aFF9B7c8f7E9DF6F65DBF6Ea", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - }, { ChainId: common.BtcRegtestChain().ChainId, ConfirmationCount: 2, @@ -49,7 +40,7 @@ func GetCoreParams() CoreParamsList { OutboundTxScheduleLookahead: 5, }}, } - chainList := common.DefaultChainsList() + chainList := common.ExternalChainList() requiredParams := len(chainList) availableParams := 0 for _, chain := range chainList { diff --git a/x/observer/types/core_params_testnet.go b/x/observer/types/core_params_testnet.go index 1505f1ca01..cada5613b3 100644 --- a/x/observer/types/core_params_testnet.go +++ b/x/observer/types/core_params_testnet.go @@ -14,9 +14,10 @@ func GetCoreParams() CoreParamsList { params := CoreParamsList{ CoreParams: []*CoreParams{ { - ChainId: common.GoerliChain().ChainId, - ConfirmationCount: 6, - ZetaTokenContractAddress: "", + ChainId: common.GoerliChain().ChainId, + ConfirmationCount: 6, + // This is the actual Zeta token Goerli testnet, we need to specify this address for the integration tests to pass + ZetaTokenContractAddress: "0x0000c304d2934c00db1d51995b9f6996affd17c0", ConnectorContractAddress: "", Erc20CustodyContractAddress: "", InTxTicker: 12, @@ -52,17 +53,6 @@ func GetCoreParams() CoreParamsList { OutboundTxScheduleInterval: 30, OutboundTxScheduleLookahead: 60, }, - { - ChainId: common.ZetaChain().ChainId, - ConfirmationCount: 3, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 2, - OutTxTicker: 3, - WatchUtxoTicker: 0, - GasPriceTicker: 5, - }, { ChainId: common.BtcTestNetChain().ChainId, ConfirmationCount: 2, @@ -78,7 +68,7 @@ func GetCoreParams() CoreParamsList { }, }, } - chainList := common.DefaultChainsList() + chainList := common.ExternalChainList() requiredParams := len(chainList) availableParams := 0 for _, chain := range chainList { diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index 6823988c3b..afe8422699 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -7,24 +7,26 @@ import ( ) var ( - ErrUnableToAddVote = errorsmod.Register(ModuleName, 1100, "Unable to add vote ") - ErrParamsThreshold = errorsmod.Register(ModuleName, 1101, "Threshold cannot be more than 1") - ErrSupportedChains = errorsmod.Register(ModuleName, 1102, "Err chain not supported") - ErrInvalidStatus = errorsmod.Register(ModuleName, 1103, "Invalid Voting Status") + ErrUnableToAddVote = errorsmod.Register(ModuleName, 1100, "unable to add vote ") + ErrParamsThreshold = errorsmod.Register(ModuleName, 1101, "threshold cannot be more than 1") + ErrSupportedChains = errorsmod.Register(ModuleName, 1102, "chain not supported") + ErrInvalidStatus = errorsmod.Register(ModuleName, 1103, "invalid Voting Status") - ErrObserverNotPresent = errorsmod.Register(ModuleName, 1105, "Observer for type and observation does not exist") - ErrNotValidator = errorsmod.Register(ModuleName, 1106, "User needs to be a validator before applying to become an observer") - ErrValidatorStatus = errorsmod.Register(ModuleName, 1107, "Corresponding validator needs to be bonded and not jailerd") - ErrInvalidAddress = errorsmod.Register(ModuleName, 1108, "Invalid Address") - ErrSelfDelegation = errorsmod.Register(ModuleName, 1109, "Self Delegation for operator not found") - ErrCheckObserverDelegation = errorsmod.Register(ModuleName, 1110, "Observer delegation not sufficient") - ErrNotAuthorizedPolicy = errorsmod.Register(ModuleName, 1111, "Msg Sender is not the authorized policy") - ErrCoreParamsNotSet = errorsmod.Register(ModuleName, 1112, "Core params has not been set") - ErrKeygenNotFound = errorsmod.Register(ModuleName, 1113, "Err Keygen not found, Keygen block can only be updated,New keygen cannot be set") - ErrKeygenBlockTooLow = errorsmod.Register(ModuleName, 1114, "Please set a block number at-least 10 blocks higher than the current block number") - ErrKeygenCompleted = errorsmod.Register(ModuleName, 1115, "Keygen already completed") - ErrNotAuthorized = errorsmod.Register(ModuleName, 1116, "Err not authorized") - ErrInvalidCoinType = errorsmod.Register(ModuleName, 1117, "Invalid coin type") - ErrObserverCountNegative = errorsmod.Register(ModuleName, 1118, "Observer count cannot be negative") - ErrInvalidPubKey = errorsmod.Register(ModuleName, 1119, "Invalid PubKey") + ErrObserverNotPresent = errorsmod.Register(ModuleName, 1105, "observer for type and observation does not exist") + ErrNotValidator = errorsmod.Register(ModuleName, 1106, "user needs to be a validator before applying to become an observer") + ErrValidatorStatus = errorsmod.Register(ModuleName, 1107, "corresponding validator needs to be bonded and not jailerd") + ErrInvalidAddress = errorsmod.Register(ModuleName, 1108, "invalid Address") + ErrSelfDelegation = errorsmod.Register(ModuleName, 1109, "self Delegation for operator not found") + ErrCheckObserverDelegation = errorsmod.Register(ModuleName, 1110, "observer delegation not sufficient") + ErrNotAuthorizedPolicy = errorsmod.Register(ModuleName, 1111, "msg Sender is not the authorized policy") + ErrCoreParamsNotSet = errorsmod.Register(ModuleName, 1112, "core params has not been set") + ErrKeygenNotFound = errorsmod.Register(ModuleName, 1113, "Keygen not found, Keygen block can only be updated,New keygen cannot be set") + ErrKeygenBlockTooLow = errorsmod.Register(ModuleName, 1114, "please set a block number at-least 10 blocks higher than the current block number") + ErrKeygenCompleted = errorsmod.Register(ModuleName, 1115, "keygen already completed") + ErrNotAuthorized = errorsmod.Register(ModuleName, 1116, "not authorized") + + ErrBlockHeaderNotFound = errorsmod.Register(ModuleName, 1117, "block header not found") + ErrUnrecognizedBlockHeader = errorsmod.Register(ModuleName, 1118, "unrecognized block header") + ErrBlockAlreadyExist = errorsmod.Register(ModuleName, 1119, "block already exists") + ErrNoParentHash = errorsmod.Register(ModuleName, 1120, "no parent hash") ) diff --git a/x/observer/types/keys.go b/x/observer/types/keys.go index 4dc482976f..c21e731c22 100644 --- a/x/observer/types/keys.go +++ b/x/observer/types/keys.go @@ -43,6 +43,7 @@ const ( LastBlockObserverCountKey = "ObserverCount-value-" NodeAccountKey = "NodeAccount-value-" KeygenKey = "Keygen-value-" + BlockHeaderKey = "BlockHeader-value-" BallotListKey = "BallotList-value-" ) diff --git a/x/observer/types/messages_add_block_header.go b/x/observer/types/messages_add_block_header.go new file mode 100644 index 0000000000..8db4410195 --- /dev/null +++ b/x/observer/types/messages_add_block_header.go @@ -0,0 +1,79 @@ +package types + +import ( + cosmoserrors "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/ethereum/go-ethereum/crypto" + "github.com/zeta-chain/zetacore/common" +) + +var _ sdk.Msg = &MsgAddBlockHeader{} + +const ( + TypeMsgAddBlockHeader = "add_block_header" +) + +func NewMsgAddBlockHeader(creator string, chainID int64, blockHash []byte, height int64, header common.HeaderData) *MsgAddBlockHeader { + return &MsgAddBlockHeader{ + Creator: creator, + ChainId: chainID, + BlockHash: blockHash, + Height: height, + Header: header, + } +} + +func (msg *MsgAddBlockHeader) Route() string { + return RouterKey +} + +func (msg *MsgAddBlockHeader) Type() string { + return TypeMsgAddBlockHeader +} + +func (msg *MsgAddBlockHeader) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgAddBlockHeader) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgAddBlockHeader) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, err.Error()) + } + + if common.IsEthereum(msg.ChainId) { + if len(msg.BlockHash) > 32 { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid msg.txhash; too long (%d)", len(msg.BlockHash)) + } + } else { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid chain id (%d)", msg.ChainId) + } + + if err := msg.Header.Validate(msg.BlockHash, msg.Height); err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header (%s)", err) + } + + if _, err := msg.Header.ParentHash(); err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "can't get parent hash (%s)", err) + } + + return nil +} + +func (msg *MsgAddBlockHeader) Digest() string { + m := *msg + m.Creator = "" + hash := crypto.Keccak256Hash([]byte(m.String())) + return hash.Hex() +} diff --git a/x/observer/types/params.go b/x/observer/types/params.go index 92ba0d5e0b..660a4e12f9 100644 --- a/x/observer/types/params.go +++ b/x/observer/types/params.go @@ -28,7 +28,7 @@ func DefaultParams() Params { IsSupported: true, Chain: chain, BallotThreshold: sdk.MustNewDecFromStr("0.66"), - MinObserverDelegation: sdk.MustNewDecFromStr("10000000000"), + MinObserverDelegation: sdk.MustNewDecFromStr("1000000000000000000000"), // 1000 ZETA } } return NewParams(observerParams, DefaultAdminPolicy(), 100) diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 7bc6e87576..d1e116394d 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -32,6 +32,126 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type QueryProveRequest struct { + ChainId uint64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + TxHash string `protobuf:"bytes,2,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` + Proof *common.Proof `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"` + BlockHash string `protobuf:"bytes,4,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + TxIndex int64 `protobuf:"varint,5,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` +} + +func (m *QueryProveRequest) Reset() { *m = QueryProveRequest{} } +func (m *QueryProveRequest) String() string { return proto.CompactTextString(m) } +func (*QueryProveRequest) ProtoMessage() {} +func (*QueryProveRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{0} +} +func (m *QueryProveRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryProveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryProveRequest.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 *QueryProveRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryProveRequest.Merge(m, src) +} +func (m *QueryProveRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryProveRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryProveRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryProveRequest proto.InternalMessageInfo + +func (m *QueryProveRequest) GetChainId() uint64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *QueryProveRequest) GetTxHash() string { + if m != nil { + return m.TxHash + } + return "" +} + +func (m *QueryProveRequest) GetProof() *common.Proof { + if m != nil { + return m.Proof + } + return nil +} + +func (m *QueryProveRequest) GetBlockHash() string { + if m != nil { + return m.BlockHash + } + return "" +} + +func (m *QueryProveRequest) GetTxIndex() int64 { + if m != nil { + return m.TxIndex + } + return 0 +} + +type QueryProveResponse struct { + Valid bool `protobuf:"varint,1,opt,name=valid,proto3" json:"valid,omitempty"` +} + +func (m *QueryProveResponse) Reset() { *m = QueryProveResponse{} } +func (m *QueryProveResponse) String() string { return proto.CompactTextString(m) } +func (*QueryProveResponse) ProtoMessage() {} +func (*QueryProveResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{1} +} +func (m *QueryProveResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryProveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryProveResponse.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 *QueryProveResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryProveResponse.Merge(m, src) +} +func (m *QueryProveResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryProveResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryProveResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryProveResponse proto.InternalMessageInfo + +func (m *QueryProveResponse) GetValid() bool { + if m != nil { + return m.Valid + } + return false +} + type QueryParamsRequest struct { } @@ -39,7 +159,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{0} + return fileDescriptor_dcb801e455adaee4, []int{2} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -78,7 +198,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{1} + return fileDescriptor_dcb801e455adaee4, []int{3} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -122,7 +242,7 @@ func (m *QueryBallotByIdentifierRequest) Reset() { *m = QueryBallotByIde func (m *QueryBallotByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierRequest) ProtoMessage() {} func (*QueryBallotByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{2} + return fileDescriptor_dcb801e455adaee4, []int{4} } func (m *QueryBallotByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -167,7 +287,7 @@ func (m *VoterList) Reset() { *m = VoterList{} } func (m *VoterList) String() string { return proto.CompactTextString(m) } func (*VoterList) ProtoMessage() {} func (*VoterList) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{3} + return fileDescriptor_dcb801e455adaee4, []int{5} } func (m *VoterList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -221,7 +341,7 @@ func (m *QueryBallotByIdentifierResponse) Reset() { *m = QueryBallotById func (m *QueryBallotByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierResponse) ProtoMessage() {} func (*QueryBallotByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{4} + return fileDescriptor_dcb801e455adaee4, []int{6} } func (m *QueryBallotByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -286,7 +406,7 @@ func (m *QueryObserversByChainRequest) Reset() { *m = QueryObserversByCh func (m *QueryObserversByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryObserversByChainRequest) ProtoMessage() {} func (*QueryObserversByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{5} + return fileDescriptor_dcb801e455adaee4, []int{7} } func (m *QueryObserversByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -330,7 +450,7 @@ func (m *QueryObserversByChainResponse) Reset() { *m = QueryObserversByC func (m *QueryObserversByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryObserversByChainResponse) ProtoMessage() {} func (*QueryObserversByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{6} + return fileDescriptor_dcb801e455adaee4, []int{8} } func (m *QueryObserversByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -373,7 +493,7 @@ func (m *QueryAllObserverMappersRequest) Reset() { *m = QueryAllObserver func (m *QueryAllObserverMappersRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllObserverMappersRequest) ProtoMessage() {} func (*QueryAllObserverMappersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{7} + return fileDescriptor_dcb801e455adaee4, []int{9} } func (m *QueryAllObserverMappersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -410,7 +530,7 @@ func (m *QueryAllObserverMappersResponse) Reset() { *m = QueryAllObserve func (m *QueryAllObserverMappersResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllObserverMappersResponse) ProtoMessage() {} func (*QueryAllObserverMappersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{8} + return fileDescriptor_dcb801e455adaee4, []int{10} } func (m *QueryAllObserverMappersResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -453,7 +573,7 @@ func (m *QuerySupportedChains) Reset() { *m = QuerySupportedChains{} } func (m *QuerySupportedChains) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChains) ProtoMessage() {} func (*QuerySupportedChains) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{9} + return fileDescriptor_dcb801e455adaee4, []int{11} } func (m *QuerySupportedChains) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -490,7 +610,7 @@ func (m *QuerySupportedChainsResponse) Reset() { *m = QuerySupportedChai func (m *QuerySupportedChainsResponse) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChainsResponse) ProtoMessage() {} func (*QuerySupportedChainsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{10} + return fileDescriptor_dcb801e455adaee4, []int{12} } func (m *QuerySupportedChainsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -534,7 +654,7 @@ func (m *QueryGetCoreParamsForChainRequest) Reset() { *m = QueryGetCoreP func (m *QueryGetCoreParamsForChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsForChainRequest) ProtoMessage() {} func (*QueryGetCoreParamsForChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{11} + return fileDescriptor_dcb801e455adaee4, []int{13} } func (m *QueryGetCoreParamsForChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -578,7 +698,7 @@ func (m *QueryGetCoreParamsForChainResponse) Reset() { *m = QueryGetCore func (m *QueryGetCoreParamsForChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsForChainResponse) ProtoMessage() {} func (*QueryGetCoreParamsForChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{12} + return fileDescriptor_dcb801e455adaee4, []int{14} } func (m *QueryGetCoreParamsForChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -621,7 +741,7 @@ func (m *QueryGetCoreParamsRequest) Reset() { *m = QueryGetCoreParamsReq func (m *QueryGetCoreParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsRequest) ProtoMessage() {} func (*QueryGetCoreParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{13} + return fileDescriptor_dcb801e455adaee4, []int{15} } func (m *QueryGetCoreParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -658,7 +778,7 @@ func (m *QueryGetCoreParamsResponse) Reset() { *m = QueryGetCoreParamsRe func (m *QueryGetCoreParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsResponse) ProtoMessage() {} func (*QueryGetCoreParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{14} + return fileDescriptor_dcb801e455adaee4, []int{16} } func (m *QueryGetCoreParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -702,7 +822,7 @@ func (m *QueryGetNodeAccountRequest) Reset() { *m = QueryGetNodeAccountR func (m *QueryGetNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountRequest) ProtoMessage() {} func (*QueryGetNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{15} + return fileDescriptor_dcb801e455adaee4, []int{17} } func (m *QueryGetNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -746,7 +866,7 @@ func (m *QueryGetNodeAccountResponse) Reset() { *m = QueryGetNodeAccount func (m *QueryGetNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountResponse) ProtoMessage() {} func (*QueryGetNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{16} + return fileDescriptor_dcb801e455adaee4, []int{18} } func (m *QueryGetNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -790,7 +910,7 @@ func (m *QueryAllNodeAccountRequest) Reset() { *m = QueryAllNodeAccountR func (m *QueryAllNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountRequest) ProtoMessage() {} func (*QueryAllNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{17} + return fileDescriptor_dcb801e455adaee4, []int{19} } func (m *QueryAllNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -835,7 +955,7 @@ func (m *QueryAllNodeAccountResponse) Reset() { *m = QueryAllNodeAccount func (m *QueryAllNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountResponse) ProtoMessage() {} func (*QueryAllNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{18} + return fileDescriptor_dcb801e455adaee4, []int{20} } func (m *QueryAllNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -885,7 +1005,7 @@ func (m *QueryGetPermissionFlagsRequest) Reset() { *m = QueryGetPermissi func (m *QueryGetPermissionFlagsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetPermissionFlagsRequest) ProtoMessage() {} func (*QueryGetPermissionFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{19} + return fileDescriptor_dcb801e455adaee4, []int{21} } func (m *QueryGetPermissionFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -922,7 +1042,7 @@ func (m *QueryGetPermissionFlagsResponse) Reset() { *m = QueryGetPermiss func (m *QueryGetPermissionFlagsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetPermissionFlagsResponse) ProtoMessage() {} func (*QueryGetPermissionFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{20} + return fileDescriptor_dcb801e455adaee4, []int{22} } func (m *QueryGetPermissionFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -965,7 +1085,7 @@ func (m *QueryGetKeygenRequest) Reset() { *m = QueryGetKeygenRequest{} } func (m *QueryGetKeygenRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenRequest) ProtoMessage() {} func (*QueryGetKeygenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{21} + return fileDescriptor_dcb801e455adaee4, []int{23} } func (m *QueryGetKeygenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +1122,7 @@ func (m *QueryGetKeygenResponse) Reset() { *m = QueryGetKeygenResponse{} func (m *QueryGetKeygenResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenResponse) ProtoMessage() {} func (*QueryGetKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{22} + return fileDescriptor_dcb801e455adaee4, []int{24} } func (m *QueryGetKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1045,7 +1165,7 @@ func (m *QueryShowObserverCountRequest) Reset() { *m = QueryShowObserver func (m *QueryShowObserverCountRequest) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountRequest) ProtoMessage() {} func (*QueryShowObserverCountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{23} + return fileDescriptor_dcb801e455adaee4, []int{25} } func (m *QueryShowObserverCountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1082,7 +1202,7 @@ func (m *QueryShowObserverCountResponse) Reset() { *m = QueryShowObserve func (m *QueryShowObserverCountResponse) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountResponse) ProtoMessage() {} func (*QueryShowObserverCountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{24} + return fileDescriptor_dcb801e455adaee4, []int{26} } func (m *QueryShowObserverCountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1126,7 +1246,7 @@ func (m *QueryBlameByIdentifierRequest) Reset() { *m = QueryBlameByIdent func (m *QueryBlameByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierRequest) ProtoMessage() {} func (*QueryBlameByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{25} + return fileDescriptor_dcb801e455adaee4, []int{27} } func (m *QueryBlameByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1170,7 +1290,7 @@ func (m *QueryBlameByIdentifierResponse) Reset() { *m = QueryBlameByIden func (m *QueryBlameByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierResponse) ProtoMessage() {} func (*QueryBlameByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{26} + return fileDescriptor_dcb801e455adaee4, []int{28} } func (m *QueryBlameByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1213,7 +1333,7 @@ func (m *QueryAllBlameRecordsRequest) Reset() { *m = QueryAllBlameRecord func (m *QueryAllBlameRecordsRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsRequest) ProtoMessage() {} func (*QueryAllBlameRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{27} + return fileDescriptor_dcb801e455adaee4, []int{29} } func (m *QueryAllBlameRecordsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1250,7 +1370,7 @@ func (m *QueryAllBlameRecordsResponse) Reset() { *m = QueryAllBlameRecor func (m *QueryAllBlameRecordsResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsResponse) ProtoMessage() {} func (*QueryAllBlameRecordsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{28} + return fileDescriptor_dcb801e455adaee4, []int{30} } func (m *QueryAllBlameRecordsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1286,7 +1406,193 @@ func (m *QueryAllBlameRecordsResponse) GetBlameInfo() []*Blame { return nil } +type QueryAllBlockHeaderRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllBlockHeaderRequest) Reset() { *m = QueryAllBlockHeaderRequest{} } +func (m *QueryAllBlockHeaderRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAllBlockHeaderRequest) ProtoMessage() {} +func (*QueryAllBlockHeaderRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{31} +} +func (m *QueryAllBlockHeaderRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllBlockHeaderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllBlockHeaderRequest.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 *QueryAllBlockHeaderRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllBlockHeaderRequest.Merge(m, src) +} +func (m *QueryAllBlockHeaderRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAllBlockHeaderRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllBlockHeaderRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllBlockHeaderRequest proto.InternalMessageInfo + +func (m *QueryAllBlockHeaderRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryAllBlockHeaderResponse struct { + BlockHeaders []*common.BlockHeader `protobuf:"bytes,1,rep,name=block_headers,json=blockHeaders,proto3" json:"block_headers,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllBlockHeaderResponse) Reset() { *m = QueryAllBlockHeaderResponse{} } +func (m *QueryAllBlockHeaderResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAllBlockHeaderResponse) ProtoMessage() {} +func (*QueryAllBlockHeaderResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{32} +} +func (m *QueryAllBlockHeaderResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllBlockHeaderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllBlockHeaderResponse.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 *QueryAllBlockHeaderResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllBlockHeaderResponse.Merge(m, src) +} +func (m *QueryAllBlockHeaderResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAllBlockHeaderResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllBlockHeaderResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllBlockHeaderResponse proto.InternalMessageInfo + +func (m *QueryAllBlockHeaderResponse) GetBlockHeaders() []*common.BlockHeader { + if m != nil { + return m.BlockHeaders + } + return nil +} + +func (m *QueryAllBlockHeaderResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryGetBlockHeaderByHashRequest struct { + BlockHash []byte `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` +} + +func (m *QueryGetBlockHeaderByHashRequest) Reset() { *m = QueryGetBlockHeaderByHashRequest{} } +func (m *QueryGetBlockHeaderByHashRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetBlockHeaderByHashRequest) ProtoMessage() {} +func (*QueryGetBlockHeaderByHashRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{33} +} +func (m *QueryGetBlockHeaderByHashRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetBlockHeaderByHashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetBlockHeaderByHashRequest.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 *QueryGetBlockHeaderByHashRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetBlockHeaderByHashRequest.Merge(m, src) +} +func (m *QueryGetBlockHeaderByHashRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetBlockHeaderByHashRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetBlockHeaderByHashRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetBlockHeaderByHashRequest proto.InternalMessageInfo + +func (m *QueryGetBlockHeaderByHashRequest) GetBlockHash() []byte { + if m != nil { + return m.BlockHash + } + return nil +} + +type QueryGetBlockHeaderByHashResponse struct { + BlockHeader *common.BlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` +} + +func (m *QueryGetBlockHeaderByHashResponse) Reset() { *m = QueryGetBlockHeaderByHashResponse{} } +func (m *QueryGetBlockHeaderByHashResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetBlockHeaderByHashResponse) ProtoMessage() {} +func (*QueryGetBlockHeaderByHashResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{34} +} +func (m *QueryGetBlockHeaderByHashResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetBlockHeaderByHashResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetBlockHeaderByHashResponse.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 *QueryGetBlockHeaderByHashResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetBlockHeaderByHashResponse.Merge(m, src) +} +func (m *QueryGetBlockHeaderByHashResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetBlockHeaderByHashResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetBlockHeaderByHashResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetBlockHeaderByHashResponse proto.InternalMessageInfo + +func (m *QueryGetBlockHeaderByHashResponse) GetBlockHeader() *common.BlockHeader { + if m != nil { + return m.BlockHeader + } + return nil +} + func init() { + proto.RegisterType((*QueryProveRequest)(nil), "zetachain.zetacore.observer.QueryProveRequest") + proto.RegisterType((*QueryProveResponse)(nil), "zetachain.zetacore.observer.QueryProveResponse") proto.RegisterType((*QueryParamsRequest)(nil), "zetachain.zetacore.observer.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "zetachain.zetacore.observer.QueryParamsResponse") proto.RegisterType((*QueryBallotByIdentifierRequest)(nil), "zetachain.zetacore.observer.QueryBallotByIdentifierRequest") @@ -1316,107 +1622,129 @@ func init() { proto.RegisterType((*QueryBlameByIdentifierResponse)(nil), "zetachain.zetacore.observer.QueryBlameByIdentifierResponse") proto.RegisterType((*QueryAllBlameRecordsRequest)(nil), "zetachain.zetacore.observer.QueryAllBlameRecordsRequest") proto.RegisterType((*QueryAllBlameRecordsResponse)(nil), "zetachain.zetacore.observer.QueryAllBlameRecordsResponse") + proto.RegisterType((*QueryAllBlockHeaderRequest)(nil), "zetachain.zetacore.observer.QueryAllBlockHeaderRequest") + proto.RegisterType((*QueryAllBlockHeaderResponse)(nil), "zetachain.zetacore.observer.QueryAllBlockHeaderResponse") + proto.RegisterType((*QueryGetBlockHeaderByHashRequest)(nil), "zetachain.zetacore.observer.QueryGetBlockHeaderByHashRequest") + proto.RegisterType((*QueryGetBlockHeaderByHashResponse)(nil), "zetachain.zetacore.observer.QueryGetBlockHeaderByHashResponse") } func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 1507 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0x5f, 0x6f, 0x13, 0xc7, - 0x16, 0xcf, 0x26, 0xe0, 0x4b, 0x4e, 0x08, 0x49, 0x86, 0x00, 0xc1, 0x01, 0x27, 0x77, 0xb8, 0x80, - 0x21, 0xe0, 0x25, 0x46, 0xba, 0xf7, 0xd2, 0x14, 0x50, 0x1c, 0x41, 0xca, 0x7f, 0x6a, 0x5a, 0x5a, - 0x55, 0x6a, 0xad, 0xb5, 0x3d, 0x71, 0x96, 0xae, 0x77, 0x96, 0xdd, 0x4d, 0xc0, 0x45, 0x91, 0xaa, - 0x7e, 0x02, 0xa4, 0x4a, 0xfd, 0x16, 0xed, 0x03, 0x2f, 0x7d, 0xa8, 0xfa, 0xd2, 0x97, 0xf2, 0x54, - 0x51, 0x55, 0xaa, 0xfa, 0xd2, 0xaa, 0x02, 0x3e, 0x48, 0xb5, 0x33, 0x67, 0xd7, 0xeb, 0xfd, 0x63, - 0xaf, 0xf3, 0xe4, 0xdd, 0x99, 0xf9, 0x9d, 0xf3, 0x3b, 0x67, 0xce, 0x9e, 0xf3, 0x93, 0x61, 0x96, - 0xd7, 0x1d, 0x66, 0x6f, 0x33, 0x5b, 0x7d, 0xbc, 0xc5, 0xec, 0x4e, 0xc9, 0xb2, 0xb9, 0xcb, 0xc9, - 0xfc, 0x17, 0xcc, 0xd5, 0x1a, 0x9b, 0x9a, 0x6e, 0x96, 0xc4, 0x13, 0xb7, 0x59, 0xc9, 0x3f, 0x98, - 0x3f, 0xd8, 0xe0, 0xed, 0x36, 0x37, 0x55, 0xf9, 0x23, 0x11, 0xf9, 0xb3, 0x0d, 0xee, 0xb4, 0xb9, - 0xa3, 0xd6, 0x35, 0x87, 0x49, 0x53, 0xea, 0xf6, 0x72, 0x9d, 0xb9, 0xda, 0xb2, 0x6a, 0x69, 0x2d, - 0xdd, 0xd4, 0x5c, 0x3d, 0x38, 0x3b, 0xdb, 0xe2, 0x2d, 0x2e, 0x1e, 0x55, 0xef, 0x09, 0x57, 0x8f, - 0xb5, 0x38, 0x6f, 0x19, 0x4c, 0xd5, 0x2c, 0x5d, 0xd5, 0x4c, 0x93, 0xbb, 0x02, 0xe2, 0xe0, 0xee, - 0xa1, 0x80, 0x67, 0x5d, 0x33, 0x0c, 0xee, 0xfa, 0xa6, 0xba, 0xcb, 0x86, 0xd6, 0x66, 0xb1, 0xc3, - 0x9f, 0xb3, 0x4e, 0x8b, 0xf9, 0x7e, 0xe7, 0x83, 0x65, 0x93, 0x37, 0x59, 0x4d, 0x6b, 0x34, 0xf8, - 0x96, 0xe9, 0x5b, 0x3a, 0x12, 0x6c, 0xfa, 0x0f, 0x31, 0x63, 0x96, 0x66, 0x6b, 0x6d, 0x9f, 0xd0, - 0x42, 0x77, 0x99, 0xd9, 0x6d, 0xdd, 0x71, 0x74, 0x6e, 0xd6, 0x36, 0x0c, 0xad, 0x85, 0x07, 0xe8, - 0x2c, 0x90, 0xf7, 0xbd, 0x3c, 0xdc, 0x17, 0xa8, 0x2a, 0x7b, 0xbc, 0xc5, 0x1c, 0x97, 0x7e, 0x0c, - 0x07, 0x7b, 0x56, 0x1d, 0x8b, 0x9b, 0x0e, 0x23, 0xab, 0x90, 0x93, 0xd6, 0xe7, 0x94, 0x45, 0xa5, - 0x38, 0x51, 0x3e, 0x51, 0xea, 0x73, 0x03, 0x25, 0x09, 0xae, 0xec, 0x79, 0xf9, 0xd7, 0xc2, 0x48, - 0x15, 0x81, 0xf4, 0x0e, 0x14, 0x84, 0xe5, 0x8a, 0xc8, 0x4f, 0xa5, 0x73, 0xa3, 0xc9, 0x4c, 0x57, - 0xdf, 0xd0, 0x99, 0x8d, 0xbe, 0xc9, 0x12, 0xcc, 0xc8, 0xe4, 0xd5, 0xf4, 0x60, 0x4f, 0xf8, 0x1b, - 0xaf, 0x4e, 0xcb, 0x8d, 0x2e, 0x86, 0xba, 0x30, 0xfe, 0x90, 0xbb, 0xcc, 0xbe, 0xad, 0x3b, 0x2e, - 0x39, 0x01, 0x93, 0xdb, 0xde, 0x4b, 0x4d, 0x6b, 0x36, 0x6d, 0xe6, 0x38, 0x88, 0xda, 0x2f, 0x16, - 0x57, 0xe5, 0x1a, 0xa9, 0xc0, 0xb8, 0xf7, 0x5e, 0x73, 0x3b, 0x16, 0x9b, 0x1b, 0x5d, 0x54, 0x8a, - 0x07, 0xca, 0x27, 0xfb, 0x86, 0xe1, 0xd9, 0xff, 0xa0, 0x63, 0xb1, 0xea, 0xbe, 0x6d, 0x7c, 0xa2, - 0xdf, 0x8f, 0xc2, 0x42, 0x6a, 0x14, 0x98, 0xab, 0x61, 0xc2, 0x20, 0x57, 0x20, 0x27, 0x48, 0x3a, - 0x73, 0xa3, 0x8b, 0x63, 0xc5, 0x89, 0xf2, 0xa9, 0x81, 0x8c, 0x44, 0xc4, 0x55, 0x44, 0x91, 0x8f, - 0x60, 0x5a, 0xee, 0x8a, 0x6a, 0x94, 0xb1, 0x8d, 0x89, 0xd8, 0xce, 0xf5, 0xb5, 0x74, 0xaf, 0x0b, - 0x12, 0x21, 0x4e, 0xf1, 0xde, 0x05, 0x72, 0x17, 0x26, 0x31, 0x0a, 0xc7, 0xd5, 0xdc, 0x2d, 0x67, - 0x6e, 0x8f, 0xb0, 0x7a, 0xa6, 0xaf, 0x55, 0x99, 0x95, 0x07, 0x02, 0x50, 0xdd, 0x5f, 0x0f, 0xbd, - 0xd1, 0x5b, 0x70, 0x4c, 0x24, 0xee, 0x1e, 0x9e, 0x75, 0x2a, 0x9d, 0x35, 0xcf, 0x4a, 0xe8, 0xf2, - 0xc3, 0x81, 0x08, 0x0f, 0x7e, 0xd6, 0x42, 0x1b, 0x02, 0x43, 0x2f, 0xc3, 0xf1, 0x14, 0x63, 0x78, - 0x07, 0xc7, 0x60, 0xdc, 0x27, 0xe5, 0x15, 0xc3, 0x58, 0x71, 0xbc, 0xda, 0x5d, 0xa0, 0x8b, 0x58, - 0x8a, 0xab, 0x86, 0xe1, 0x5b, 0xb8, 0xa3, 0x59, 0x16, 0xb3, 0x83, 0xcf, 0xa0, 0x83, 0xd7, 0x9c, - 0x74, 0x02, 0x5d, 0x3c, 0xf4, 0x33, 0xcf, 0xec, 0x5a, 0x5b, 0xee, 0x09, 0x4f, 0x13, 0xe5, 0xa5, - 0x0c, 0x99, 0xf7, 0xed, 0xf9, 0x89, 0x0f, 0xec, 0xd3, 0xc3, 0x30, 0x2b, 0x5c, 0x3f, 0xd8, 0xb2, - 0x2c, 0x6e, 0xbb, 0xac, 0x29, 0x22, 0x73, 0xe8, 0x35, 0x4c, 0x60, 0x64, 0x3d, 0xe0, 0x73, 0x12, - 0x72, 0xc2, 0xa5, 0xcf, 0x62, 0xb2, 0x84, 0x0d, 0x50, 0x66, 0x06, 0x37, 0xe9, 0x15, 0xf8, 0xb7, - 0x30, 0xb3, 0xce, 0xdc, 0x35, 0x6e, 0x33, 0xf9, 0xa9, 0x5e, 0xe7, 0x76, 0xcf, 0x65, 0x1c, 0x85, - 0x7d, 0xe2, 0x78, 0x4d, 0x6f, 0x8a, 0x3b, 0x18, 0xab, 0xfe, 0x4b, 0xbc, 0xdf, 0x68, 0x52, 0x13, - 0x68, 0x3f, 0x3c, 0x92, 0x79, 0x0f, 0x26, 0xbc, 0xa8, 0x6b, 0x3d, 0x4d, 0xe3, 0x74, 0xdf, 0xbc, - 0x74, 0xad, 0x55, 0xa1, 0x11, 0x3c, 0xd3, 0x79, 0x38, 0x1a, 0xf7, 0xe7, 0x5f, 0xd3, 0x23, 0xc8, - 0x27, 0x6d, 0x22, 0x89, 0xdb, 0x49, 0x24, 0x96, 0x32, 0x92, 0x10, 0x5f, 0x59, 0x98, 0x48, 0xb9, - 0xeb, 0xeb, 0x2e, 0x6f, 0xb2, 0x55, 0xd9, 0x9d, 0xfd, 0x8c, 0xcd, 0xc2, 0x5e, 0xdd, 0x6c, 0xb2, - 0xa7, 0x58, 0xb2, 0xf2, 0x85, 0x3e, 0x82, 0xf9, 0x44, 0x0c, 0x12, 0xbc, 0x05, 0xfb, 0xc3, 0x9d, - 0x1e, 0x19, 0x16, 0xfb, 0x32, 0x0c, 0xdb, 0x99, 0x30, 0xbb, 0x2f, 0xb4, 0x89, 0xfc, 0x56, 0x0d, - 0x23, 0x81, 0xdf, 0x75, 0x80, 0xee, 0x9c, 0x43, 0x47, 0xa7, 0x4a, 0x72, 0x28, 0x96, 0xbc, 0xa1, - 0x58, 0x92, 0xf3, 0x15, 0x87, 0x62, 0xe9, 0xbe, 0xd6, 0x62, 0x88, 0xad, 0x86, 0x90, 0xf4, 0x85, - 0x82, 0x21, 0x45, 0xdd, 0x60, 0x48, 0x37, 0x61, 0x22, 0xb4, 0x8c, 0xa5, 0x38, 0x44, 0x44, 0xa1, - 0x17, 0xb2, 0xde, 0xc3, 0x79, 0x14, 0x6b, 0x68, 0x10, 0x67, 0x49, 0xa4, 0x87, 0xb4, 0xff, 0xbd, - 0xaf, 0x33, 0xf7, 0x7e, 0x30, 0x0c, 0xaf, 0x7b, 0xb3, 0xd0, 0x2f, 0xa4, 0x2f, 0x15, 0xfc, 0xe0, - 0x93, 0x8e, 0x60, 0x68, 0x9f, 0xc2, 0x74, 0x74, 0x94, 0x62, 0x22, 0xfb, 0xb7, 0xda, 0x88, 0x3d, - 0x1c, 0x8b, 0x53, 0x56, 0xef, 0x32, 0x3d, 0x02, 0x87, 0x7c, 0x06, 0xb7, 0x84, 0x2a, 0xf0, 0xb9, - 0x7d, 0x08, 0x87, 0xa3, 0x1b, 0xc8, 0x68, 0x05, 0x72, 0x52, 0x40, 0x64, 0x9a, 0xca, 0x08, 0x46, - 0x08, 0x5d, 0xc0, 0x1e, 0xfa, 0x60, 0x93, 0x3f, 0xf1, 0x7b, 0xd2, 0x5a, 0xa8, 0x64, 0xbc, 0x9c, - 0x14, 0xd2, 0x4e, 0x20, 0x81, 0xcf, 0xe0, 0xa0, 0xa1, 0x39, 0x6e, 0x2d, 0x68, 0x84, 0xe1, 0x3a, - 0x2e, 0xf5, 0x65, 0x73, 0x5b, 0x73, 0xdc, 0x5e, 0xa3, 0x33, 0x46, 0x74, 0x89, 0xde, 0x44, 0x8e, - 0x15, 0x4f, 0x3c, 0x25, 0x49, 0x86, 0x33, 0x30, 0x2d, 0x84, 0x55, 0x7c, 0xd4, 0x4e, 0x89, 0xf5, - 0x90, 0x60, 0x68, 0xf8, 0xfa, 0x23, 0x6e, 0x2b, 0x10, 0x39, 0x80, 0xc6, 0xcc, 0x0d, 0x8e, 0x41, - 0xd0, 0xfe, 0xf3, 0xce, 0x3b, 0x5e, 0x1d, 0x97, 0xae, 0xcc, 0x0d, 0x4e, 0x8f, 0x77, 0xbf, 0x0e, - 0xb9, 0xc7, 0x1a, 0xdc, 0x6e, 0x06, 0x65, 0xa6, 0x61, 0x0f, 0x8f, 0x6d, 0xa7, 0x30, 0x18, 0x1b, - 0x9a, 0x41, 0xf9, 0xed, 0x2c, 0xec, 0x15, 0x3e, 0xc8, 0x73, 0x05, 0x72, 0xb2, 0x77, 0x11, 0xb5, - 0xaf, 0x8d, 0xb8, 0x0c, 0xcc, 0x5f, 0xc8, 0x0e, 0x90, 0xd4, 0xe9, 0x89, 0xaf, 0x7e, 0x7b, 0xfb, - 0xf5, 0xe8, 0x71, 0x32, 0xaf, 0x7a, 0xe7, 0xcf, 0x0b, 0xa8, 0x1a, 0x91, 0xa6, 0xe4, 0x77, 0x05, - 0x48, 0x5c, 0x39, 0x91, 0x95, 0xc1, 0xde, 0x52, 0x55, 0x63, 0xfe, 0xdd, 0xdd, 0x81, 0x91, 0xf6, - 0x35, 0x41, 0xfb, 0x2a, 0xb9, 0x9c, 0x48, 0x1b, 0x15, 0x50, 0xbd, 0x13, 0xaa, 0x2f, 0xf5, 0x59, - 0x4c, 0xdd, 0xed, 0x90, 0x5f, 0x14, 0x98, 0x8e, 0x8a, 0x11, 0x72, 0x69, 0x30, 0xb3, 0x14, 0x35, - 0x94, 0x7f, 0x67, 0x37, 0x50, 0x0c, 0x69, 0x4d, 0x84, 0x74, 0x99, 0xac, 0x24, 0x86, 0x14, 0xa8, - 0x20, 0x2f, 0x2a, 0xb9, 0xf7, 0x2c, 0x26, 0xbc, 0x76, 0xc8, 0x4f, 0x0a, 0x90, 0xb8, 0xf8, 0xc9, - 0x72, 0x53, 0xa9, 0xa2, 0x2a, 0xcb, 0x4d, 0xa5, 0xeb, 0x2d, 0xba, 0x2c, 0xc2, 0x5a, 0x22, 0x67, - 0x12, 0xc3, 0xd2, 0x0c, 0xa3, 0x16, 0x95, 0x63, 0xe4, 0x5b, 0x05, 0xa6, 0x22, 0x72, 0x89, 0x2c, - 0x0f, 0x26, 0x11, 0x81, 0xe4, 0x2f, 0x0d, 0x0d, 0x09, 0x48, 0x9f, 0x13, 0xa4, 0x4f, 0x91, 0xff, - 0x24, 0x92, 0x76, 0x22, 0xdc, 0xfe, 0x54, 0xe0, 0x50, 0xa2, 0xae, 0x22, 0x57, 0x06, 0x53, 0xe8, - 0x27, 0xe8, 0xf2, 0x57, 0x77, 0x8d, 0xcf, 0x54, 0x54, 0x2d, 0xe6, 0xd6, 0x1a, 0x86, 0xce, 0x4c, - 0x17, 0xc5, 0x56, 0x6d, 0x83, 0xdb, 0x7e, 0x75, 0xf9, 0x4a, 0x72, 0x87, 0x7c, 0xa7, 0xc0, 0x64, - 0x8f, 0x1b, 0xf2, 0xdf, 0x21, 0x79, 0xf9, 0xf1, 0xfc, 0x6f, 0x68, 0x5c, 0xa6, 0x0b, 0x11, 0x71, - 0x74, 0x25, 0x23, 0x79, 0xa1, 0xf4, 0xc8, 0x19, 0x92, 0xcd, 0x6d, 0x5c, 0x7e, 0xe5, 0xff, 0x3f, - 0x3c, 0x10, 0x09, 0x5f, 0x10, 0x84, 0xcf, 0x92, 0x62, 0x22, 0xe1, 0x90, 0x00, 0x54, 0x9f, 0x09, - 0xcd, 0xb9, 0xe3, 0x55, 0xfd, 0x81, 0x90, 0xa5, 0x55, 0xc3, 0xc8, 0xc2, 0x3b, 0x51, 0x36, 0x66, - 0xe1, 0x9d, 0x2c, 0x04, 0x69, 0x51, 0xf0, 0xa6, 0x64, 0x71, 0x10, 0x6f, 0xf2, 0x83, 0x02, 0x53, - 0x11, 0x8d, 0x94, 0xa5, 0xcf, 0xa4, 0x8a, 0xb9, 0x2c, 0x7d, 0x26, 0x5d, 0xe6, 0xd1, 0xf3, 0x82, - 0xf8, 0x69, 0x72, 0x32, 0x79, 0x90, 0x45, 0x14, 0x20, 0xf9, 0x46, 0x81, 0x9c, 0x54, 0x56, 0xa4, - 0x9c, 0xc9, 0x6f, 0x8f, 0xb8, 0xcb, 0x5f, 0x1c, 0x0a, 0x93, 0x69, 0xd6, 0x4a, 0x7d, 0x47, 0x7e, - 0x56, 0x60, 0x26, 0xa6, 0xdc, 0x48, 0x86, 0xc1, 0x92, 0x26, 0x08, 0xf3, 0x2b, 0xbb, 0xc2, 0x22, - 0xe7, 0x4b, 0x82, 0xf3, 0x45, 0xb2, 0x1c, 0xe6, 0xec, 0x5b, 0x09, 0xb5, 0xc4, 0x4d, 0xfe, 0x24, - 0x22, 0x27, 0xc9, 0xaf, 0x0a, 0xcc, 0xc4, 0x54, 0x5b, 0x96, 0x48, 0xd2, 0x64, 0x63, 0x96, 0x48, - 0x52, 0x65, 0xe2, 0x80, 0x56, 0x28, 0xf5, 0x5b, 0x54, 0x31, 0x44, 0x34, 0xea, 0x0e, 0xf9, 0x51, - 0x01, 0xb2, 0xce, 0xdc, 0x88, 0x10, 0x24, 0xd9, 0xbe, 0xb7, 0x04, 0x69, 0x99, 0x65, 0x48, 0xa5, - 0xa8, 0x4e, 0x5a, 0x16, 0x01, 0x9d, 0x23, 0x67, 0x53, 0x7b, 0xa2, 0x37, 0x5d, 0x65, 0x0c, 0xb6, - 0xc4, 0x56, 0x6e, 0xbc, 0x7c, 0x5d, 0x50, 0x5e, 0xbd, 0x2e, 0x28, 0x7f, 0xbf, 0x2e, 0x28, 0xcf, - 0xdf, 0x14, 0x46, 0x5e, 0xbd, 0x29, 0x8c, 0xfc, 0xf1, 0xa6, 0x30, 0xf2, 0x89, 0xda, 0xd2, 0xdd, - 0xcd, 0xad, 0x7a, 0xa9, 0xc1, 0xdb, 0x89, 0x57, 0xfd, 0xb4, 0x6b, 0xda, 0xed, 0x58, 0xcc, 0xa9, - 0xe7, 0xc4, 0xff, 0x91, 0x17, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x1f, 0xa0, 0x93, 0x43, 0xeb, - 0x15, 0x00, 0x00, + // 1800 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x4f, 0x1b, 0xcf, + 0x19, 0x66, 0x21, 0x38, 0xf0, 0x1a, 0x02, 0x0c, 0xe4, 0x17, 0x30, 0x60, 0xdc, 0xa1, 0x49, 0x1c, + 0x48, 0xec, 0xe0, 0x48, 0xf9, 0x22, 0x10, 0x61, 0x94, 0x10, 0xf2, 0x49, 0x9d, 0x36, 0xad, 0x5a, + 0xb5, 0xd6, 0xda, 0x1e, 0x8c, 0x93, 0x65, 0xc7, 0xd9, 0x5d, 0x08, 0x6e, 0x84, 0x54, 0xf5, 0xdc, + 0x4a, 0x91, 0x2a, 0xf5, 0xdc, 0x53, 0x6f, 0xed, 0x21, 0x97, 0x1e, 0xa2, 0x5e, 0x7a, 0x69, 0x4e, + 0x55, 0xaa, 0x4a, 0x55, 0x7b, 0x68, 0x55, 0x25, 0xfd, 0x43, 0x7e, 0xda, 0xf9, 0x58, 0x8f, 0xd7, + 0xbb, 0xf6, 0x1a, 0xe5, 0xc4, 0xce, 0xc7, 0xfb, 0xce, 0xf3, 0xbc, 0x33, 0xf3, 0xbe, 0xcf, 0x60, + 0x98, 0xa2, 0x25, 0x9b, 0x58, 0x87, 0xc4, 0xca, 0xbe, 0x3e, 0x20, 0x56, 0x23, 0x53, 0xb7, 0xa8, + 0x43, 0xd1, 0xec, 0xcf, 0x89, 0xa3, 0x97, 0xf7, 0xf4, 0x9a, 0x99, 0x61, 0x5f, 0xd4, 0x22, 0x19, + 0x39, 0x31, 0x31, 0x59, 0xa6, 0xfb, 0xfb, 0xd4, 0xcc, 0xf2, 0x3f, 0xdc, 0x22, 0xb1, 0x54, 0xa6, + 0xf6, 0x3e, 0xb5, 0xb3, 0x25, 0xdd, 0x26, 0xdc, 0x55, 0xf6, 0x70, 0xa5, 0x44, 0x1c, 0x7d, 0x25, + 0x5b, 0xd7, 0xab, 0x35, 0x53, 0x77, 0x6a, 0xde, 0xdc, 0xa9, 0x2a, 0xad, 0x52, 0xf6, 0x99, 0x75, + 0xbf, 0x44, 0xef, 0x5c, 0x95, 0xd2, 0xaa, 0x41, 0xb2, 0x7a, 0xbd, 0x96, 0xd5, 0x4d, 0x93, 0x3a, + 0xcc, 0xc4, 0x16, 0xa3, 0x67, 0x3d, 0x9c, 0x25, 0xdd, 0x30, 0xa8, 0x23, 0x5d, 0x35, 0xbb, 0x0d, + 0x7d, 0x9f, 0xb4, 0x4d, 0x7e, 0x45, 0x1a, 0x55, 0x22, 0xd7, 0x9d, 0xf5, 0xba, 0x4d, 0x5a, 0x21, + 0x45, 0xbd, 0x5c, 0xa6, 0x07, 0xa6, 0xf4, 0x74, 0xce, 0x1b, 0x94, 0x1f, 0x6d, 0xce, 0xea, 0xba, + 0xa5, 0xef, 0x4b, 0x40, 0x0b, 0xcd, 0x6e, 0x62, 0xed, 0xd7, 0x6c, 0xbb, 0x46, 0xcd, 0xe2, 0xae, + 0xa1, 0x57, 0xc5, 0x04, 0xfc, 0x7b, 0x0d, 0x26, 0xbe, 0xe7, 0x06, 0x62, 0xc7, 0xa2, 0x87, 0xa4, + 0x40, 0x5e, 0x1f, 0x10, 0xdb, 0x41, 0x33, 0x30, 0xc4, 0xe2, 0x5a, 0xac, 0x55, 0xa6, 0xb5, 0x94, + 0x96, 0x3e, 0x55, 0x38, 0xcd, 0xda, 0xdb, 0x15, 0x74, 0x0e, 0x4e, 0x3b, 0x47, 0xc5, 0x3d, 0xdd, + 0xde, 0x9b, 0xee, 0x4f, 0x69, 0xe9, 0xe1, 0x42, 0xcc, 0x39, 0x7a, 0xa0, 0xdb, 0x7b, 0x68, 0x11, + 0x06, 0xeb, 0x16, 0xa5, 0xbb, 0xd3, 0x03, 0x29, 0x2d, 0x1d, 0xcf, 0x8d, 0x66, 0x44, 0xe4, 0x77, + 0xdc, 0xce, 0x02, 0x1f, 0x43, 0xf3, 0x00, 0x25, 0x83, 0x96, 0x5f, 0x71, 0x07, 0xa7, 0x98, 0x83, + 0x61, 0xd6, 0xc3, 0x7c, 0xcc, 0xc0, 0x90, 0x73, 0x54, 0xac, 0x99, 0x15, 0x72, 0x34, 0x3d, 0x98, + 0xd2, 0xd2, 0x03, 0x85, 0xd3, 0xce, 0xd1, 0xb6, 0xdb, 0xc4, 0x4b, 0x80, 0x54, 0x9c, 0x76, 0x9d, + 0x9a, 0x36, 0x41, 0x53, 0x30, 0x78, 0xa8, 0x1b, 0x02, 0xe5, 0x50, 0x81, 0x37, 0xf0, 0x94, 0x9c, + 0xcb, 0x42, 0x21, 0x48, 0xe1, 0x1f, 0xc1, 0x64, 0x4b, 0xaf, 0x70, 0xb1, 0x01, 0x31, 0x1e, 0x32, + 0xe6, 0x23, 0x9e, 0x5b, 0xcc, 0x74, 0x38, 0x56, 0x19, 0x6e, 0x9c, 0x3f, 0xf5, 0xf1, 0xbf, 0x0b, + 0x7d, 0x05, 0x61, 0x88, 0x9f, 0x40, 0x92, 0x79, 0xce, 0xb3, 0x4d, 0xcf, 0x37, 0xb6, 0x2b, 0xc4, + 0x74, 0x6a, 0xbb, 0x35, 0x62, 0xc9, 0x80, 0x2e, 0xc3, 0x04, 0x3f, 0x11, 0xc5, 0x9a, 0x37, 0xc6, + 0xd6, 0x1b, 0x2e, 0x8c, 0xf3, 0x81, 0xa6, 0x0d, 0x76, 0x60, 0xf8, 0x05, 0x75, 0x88, 0xf5, 0xb8, + 0x66, 0x3b, 0x68, 0x11, 0x46, 0x0f, 0xdd, 0x46, 0x51, 0xaf, 0x54, 0x2c, 0x62, 0xdb, 0xc2, 0x6a, + 0x84, 0x75, 0x6e, 0xf0, 0x3e, 0x94, 0x87, 0x61, 0xb7, 0x5d, 0x74, 0x1a, 0x75, 0xc2, 0xb6, 0xe5, + 0x4c, 0xee, 0x7c, 0x47, 0x1a, 0xae, 0xff, 0xef, 0x37, 0xea, 0xa4, 0x30, 0x74, 0x28, 0xbe, 0xf0, + 0x9f, 0xfa, 0x61, 0x21, 0x94, 0x85, 0x88, 0x55, 0x2f, 0x34, 0xd0, 0x3a, 0xc4, 0x18, 0x48, 0x7b, + 0xba, 0x3f, 0x35, 0x90, 0x8e, 0xe7, 0x2e, 0x74, 0x45, 0xc4, 0x18, 0x17, 0x84, 0x15, 0xfa, 0x21, + 0x8c, 0xf3, 0x51, 0x76, 0xc5, 0x38, 0xb7, 0x01, 0xc6, 0xed, 0x72, 0x47, 0x4f, 0xcf, 0x9a, 0x46, + 0x8c, 0xe2, 0x18, 0x6d, 0xed, 0x40, 0x4f, 0x61, 0x54, 0xb0, 0xb0, 0x1d, 0xdd, 0x39, 0xb0, 0xd9, + 0x39, 0x3c, 0x93, 0xbb, 0xd4, 0xd1, 0x2b, 0x8f, 0xca, 0x73, 0x66, 0x50, 0x18, 0x29, 0x29, 0x2d, + 0xfc, 0x08, 0xe6, 0x58, 0xe0, 0x9e, 0x89, 0xb9, 0x76, 0xbe, 0xb1, 0xe9, 0x7a, 0x51, 0x36, 0x5f, + 0x25, 0xc2, 0x56, 0x90, 0x51, 0x53, 0x06, 0x98, 0x0d, 0x5e, 0x83, 0xf9, 0x10, 0x67, 0x62, 0x0f, + 0xe6, 0x60, 0x58, 0x82, 0x72, 0x0f, 0xc3, 0x80, 0x7b, 0x83, 0xbc, 0x0e, 0x9c, 0x12, 0x47, 0x71, + 0xc3, 0x30, 0xa4, 0x87, 0x27, 0x7a, 0xbd, 0x4e, 0x2c, 0xef, 0x1a, 0x34, 0xc4, 0x36, 0x07, 0xcd, + 0x10, 0x4b, 0xbc, 0x90, 0x91, 0x27, 0x56, 0x71, 0x9f, 0x8f, 0xb1, 0x95, 0xe2, 0xb9, 0xe5, 0x08, + 0x91, 0x97, 0xfe, 0x64, 0xe0, 0x3d, 0xff, 0xf8, 0x1b, 0x98, 0x62, 0x4b, 0x3f, 0x3f, 0xa8, 0xd7, + 0xa9, 0xe5, 0x90, 0x0a, 0x63, 0x66, 0xe3, 0x7b, 0x22, 0x80, 0xbe, 0x7e, 0x0f, 0xcf, 0x79, 0x88, + 0xb1, 0x25, 0x25, 0x0a, 0x2f, 0xb7, 0xf0, 0xc8, 0x88, 0x41, 0xbc, 0x0e, 0xdf, 0x61, 0x6e, 0xb6, + 0x88, 0xb3, 0x49, 0x2d, 0xc2, 0xaf, 0xea, 0x7d, 0x6a, 0xb5, 0x6c, 0x86, 0x3f, 0xb5, 0x0d, 0x78, + 0xa9, 0x0d, 0x9b, 0x80, 0x3b, 0xd9, 0x0b, 0x30, 0x0f, 0x20, 0xee, 0xb2, 0x2e, 0xb6, 0x24, 0x8d, + 0x8b, 0x1d, 0xe3, 0xd2, 0xf4, 0x56, 0x80, 0xb2, 0xf7, 0x8d, 0x67, 0x61, 0xa6, 0x7d, 0x3d, 0xb9, + 0x4d, 0x2f, 0x21, 0x11, 0x34, 0x28, 0x40, 0x3c, 0x0e, 0x02, 0xb1, 0x1c, 0x11, 0x04, 0xbb, 0x65, + 0x2a, 0x90, 0x5c, 0x73, 0xad, 0xa7, 0xb4, 0x42, 0x36, 0x78, 0xc9, 0x91, 0x11, 0x9b, 0x82, 0x41, + 0x9e, 0x91, 0xf9, 0x91, 0xe5, 0x0d, 0xfc, 0x12, 0x66, 0x03, 0x6d, 0x04, 0xc0, 0x47, 0x30, 0xa2, + 0x96, 0x2f, 0x81, 0x30, 0xdd, 0x11, 0xa1, 0xea, 0x27, 0x6e, 0x36, 0x1b, 0xb8, 0x22, 0xf0, 0x6d, + 0x18, 0x46, 0x00, 0xbe, 0xfb, 0x00, 0xcd, 0xe2, 0x2d, 0x16, 0xba, 0x90, 0xe1, 0x95, 0x3e, 0xe3, + 0x56, 0xfa, 0x0c, 0x17, 0x0d, 0xa2, 0xd2, 0x67, 0x76, 0xf4, 0xaa, 0x2c, 0x74, 0x05, 0xc5, 0x12, + 0xbf, 0xd7, 0x04, 0x25, 0xff, 0x32, 0x82, 0xd2, 0x43, 0x88, 0x2b, 0xdd, 0xe2, 0x28, 0xf6, 0xc0, + 0x48, 0x69, 0xa0, 0xad, 0x16, 0xcc, 0xfd, 0xe2, 0x0c, 0x75, 0xc3, 0xcc, 0x81, 0xb4, 0x80, 0x96, + 0xf7, 0x7d, 0x8b, 0x38, 0x3b, 0x5e, 0x85, 0xbf, 0xef, 0x16, 0x78, 0x79, 0x90, 0x7e, 0xa1, 0x89, + 0x0b, 0x1f, 0x34, 0x45, 0x50, 0xfb, 0x29, 0x8c, 0xfb, 0xf5, 0x81, 0x08, 0x64, 0xe7, 0x54, 0xeb, + 0xf3, 0x27, 0xca, 0xe2, 0x58, 0xbd, 0xb5, 0x1b, 0x9f, 0x83, 0xb3, 0x12, 0xc1, 0x23, 0x26, 0x75, + 0x24, 0xb6, 0x1f, 0xc0, 0x37, 0xfe, 0x01, 0x81, 0x68, 0x15, 0x62, 0x5c, 0x15, 0x45, 0xaa, 0xca, + 0xc2, 0x58, 0x98, 0xe0, 0x05, 0x91, 0x43, 0x9f, 0xef, 0xd1, 0x37, 0x32, 0x27, 0x6d, 0x2a, 0x47, + 0xc6, 0x8d, 0x49, 0x32, 0x6c, 0x86, 0x00, 0xf0, 0x33, 0x98, 0x34, 0x74, 0xdb, 0x29, 0x7a, 0x89, + 0x50, 0x3d, 0xc7, 0x99, 0x8e, 0x68, 0x1e, 0xeb, 0xb6, 0xd3, 0xea, 0x74, 0xc2, 0xf0, 0x77, 0xe1, + 0x87, 0x02, 0x63, 0xde, 0x55, 0x84, 0x41, 0x92, 0xe1, 0x12, 0x8c, 0x33, 0xb5, 0xd8, 0x5e, 0x6a, + 0xc7, 0x58, 0xbf, 0x22, 0x18, 0xca, 0x52, 0x7f, 0xb4, 0xfb, 0xf2, 0x44, 0x0e, 0x08, 0x67, 0xe6, + 0x2e, 0x15, 0x24, 0x70, 0xe7, 0x7a, 0xe7, 0x4e, 0x77, 0xb5, 0x99, 0xbb, 0x94, 0xb9, 0x4b, 0xf1, + 0x7c, 0xf3, 0x76, 0xf0, 0x31, 0x52, 0xa6, 0x56, 0xc5, 0x3b, 0x66, 0xba, 0xc8, 0xe1, 0x6d, 0xc3, + 0x21, 0x08, 0x06, 0x7a, 0x47, 0xa0, 0xa4, 0x81, 0x3c, 0x93, 0x8c, 0x44, 0xaf, 0x34, 0xe3, 0xf5, + 0xb5, 0xd2, 0xc0, 0xef, 0x34, 0x95, 0xa8, 0xb2, 0x8c, 0x20, 0x72, 0x13, 0x46, 0x85, 0x84, 0x65, + 0xfd, 0xb2, 0x26, 0x4d, 0xca, 0x9a, 0xa4, 0xda, 0x8c, 0x94, 0x9a, 0x0d, 0xfb, 0xeb, 0x5d, 0xfa, + 0x0d, 0x48, 0xc9, 0x6b, 0xa3, 0xac, 0x96, 0x6f, 0xb8, 0x1a, 0x5a, 0x86, 0xa3, 0x55, 0x69, 0xbb, + 0xe1, 0x18, 0x51, 0x94, 0x36, 0xfe, 0x49, 0xb3, 0x56, 0x06, 0xb8, 0x10, 0x54, 0xaf, 0xc3, 0x88, + 0x4a, 0x55, 0x04, 0x35, 0x90, 0x69, 0x5c, 0x61, 0x9a, 0xfb, 0xf5, 0x0c, 0x0c, 0x32, 0xef, 0xe8, + 0x9d, 0x06, 0x31, 0x5e, 0x64, 0x50, 0xb6, 0xe3, 0x66, 0xb7, 0xeb, 0xf5, 0xc4, 0xd5, 0xe8, 0x06, + 0x1c, 0x2f, 0x5e, 0xfc, 0xe5, 0x3f, 0xfe, 0xff, 0x9b, 0xfe, 0x79, 0x34, 0x9b, 0x75, 0xe7, 0x5f, + 0x61, 0xa6, 0x59, 0xdf, 0xc3, 0x08, 0xfd, 0x53, 0x03, 0xd4, 0x2e, 0x71, 0xd1, 0x6a, 0xf7, 0xd5, + 0x42, 0xe5, 0x7d, 0xe2, 0xce, 0xc9, 0x8c, 0x05, 0xec, 0x7b, 0x0c, 0xf6, 0x5d, 0xb4, 0x16, 0x08, + 0x5b, 0x48, 0xd5, 0x52, 0x43, 0x49, 0x04, 0xd9, 0xb7, 0x6d, 0x32, 0xfc, 0x18, 0xfd, 0x4d, 0x83, + 0x71, 0xbf, 0x6a, 0x44, 0xb7, 0xba, 0x23, 0x0b, 0x91, 0xad, 0x89, 0xdb, 0x27, 0x31, 0x15, 0x94, + 0x36, 0x19, 0xa5, 0x35, 0xb4, 0x1a, 0x48, 0xc9, 0x93, 0xab, 0x2e, 0x2b, 0x3e, 0xf6, 0xb6, 0x4d, + 0x21, 0x1f, 0xa3, 0xbf, 0x68, 0x80, 0xda, 0x55, 0x6a, 0x94, 0x9d, 0x0a, 0x55, 0xbf, 0x51, 0x76, + 0x2a, 0x5c, 0x18, 0xe3, 0x15, 0x46, 0x6b, 0x19, 0x5d, 0x0a, 0xa4, 0xa5, 0x1b, 0x46, 0xd1, 0xaf, + 0x9b, 0xd1, 0x1f, 0x34, 0x18, 0xf3, 0xe9, 0x5a, 0xb4, 0xd2, 0x1d, 0x84, 0xcf, 0x24, 0x71, 0xab, + 0x67, 0x13, 0x0f, 0xf4, 0x65, 0x06, 0xfa, 0x02, 0xfa, 0x6e, 0x20, 0x68, 0xdb, 0x87, 0xed, 0x3f, + 0x1a, 0x9c, 0x0d, 0x14, 0xc0, 0x68, 0xbd, 0x3b, 0x84, 0x4e, 0xca, 0x3b, 0x71, 0xf7, 0xc4, 0xf6, + 0x91, 0x0e, 0x55, 0x95, 0x38, 0xc5, 0xb2, 0x51, 0x23, 0xa6, 0x23, 0x54, 0x71, 0x71, 0x97, 0x5a, + 0xf2, 0x74, 0x49, 0xc9, 0x7f, 0x8c, 0xfe, 0xa8, 0xc1, 0x68, 0xcb, 0x32, 0xe8, 0x7a, 0x8f, 0xb8, + 0x24, 0x9f, 0x1b, 0x3d, 0xdb, 0x45, 0xda, 0x10, 0xc6, 0xa3, 0xa9, 0xed, 0xd1, 0x7b, 0xad, 0x45, + 0x77, 0xa2, 0x68, 0xcb, 0xb6, 0xeb, 0xe4, 0xc4, 0xcd, 0xde, 0x0d, 0x05, 0xe0, 0xab, 0x0c, 0xf0, + 0x12, 0x4a, 0x07, 0x02, 0x56, 0x94, 0x7a, 0xf6, 0x2d, 0x7b, 0x1c, 0x1c, 0xbb, 0xa7, 0xfe, 0x8c, + 0xe2, 0x69, 0xc3, 0x30, 0xa2, 0xe0, 0x0e, 0xd4, 0xf7, 0x51, 0x70, 0x07, 0x2b, 0x76, 0x9c, 0x66, + 0xb8, 0x31, 0x4a, 0x75, 0xc3, 0x8d, 0x3e, 0x68, 0x30, 0xe6, 0x13, 0xb3, 0x51, 0xf2, 0x4c, 0xa8, + 0xea, 0x8e, 0x92, 0x67, 0xc2, 0xf5, 0x38, 0xbe, 0xc2, 0x80, 0x5f, 0x44, 0xe7, 0x83, 0x0b, 0x99, + 0x4f, 0xaa, 0xa3, 0xdf, 0x6a, 0x10, 0xe3, 0x12, 0x18, 0xe5, 0x22, 0xad, 0xdb, 0xa2, 0xc2, 0x13, + 0xd7, 0x7a, 0xb2, 0x89, 0x54, 0x6b, 0xb9, 0x10, 0x47, 0x7f, 0xd5, 0x60, 0xa2, 0x4d, 0x62, 0xa3, + 0x08, 0x85, 0x25, 0x4c, 0xb9, 0x27, 0x56, 0x4f, 0x64, 0x2b, 0x30, 0xdf, 0x62, 0x98, 0xaf, 0xa1, + 0x15, 0x15, 0xb3, 0xf4, 0xa2, 0xa4, 0xc4, 0x3d, 0xfa, 0xc6, 0xa7, 0xfb, 0xd1, 0xdf, 0x35, 0x98, + 0x68, 0x93, 0xd7, 0x51, 0x98, 0x84, 0xe9, 0xfb, 0x28, 0x4c, 0x42, 0xf5, 0x7c, 0x97, 0x54, 0xc8, + 0x85, 0xb6, 0x5f, 0x31, 0xf8, 0x1e, 0x13, 0xc7, 0xe8, 0xcf, 0x1a, 0xa0, 0x2d, 0xe2, 0xf8, 0x14, + 0x3b, 0x8a, 0x76, 0xdf, 0x02, 0xde, 0x00, 0x51, 0x8a, 0x54, 0xc8, 0xf3, 0x00, 0xe7, 0x18, 0xa1, + 0xcb, 0x68, 0x29, 0x34, 0x27, 0xba, 0xd5, 0x95, 0x73, 0xb0, 0x04, 0xd0, 0x0f, 0x0a, 0x7e, 0x45, + 0x66, 0xdf, 0x88, 0x88, 0xc2, 0xff, 0x82, 0x48, 0xdc, 0xec, 0xdd, 0xb0, 0x47, 0xf4, 0xca, 0xb3, + 0x01, 0xfd, 0x5b, 0x83, 0xa9, 0x20, 0xf5, 0x8d, 0xd6, 0x22, 0x5d, 0xc7, 0x30, 0xe1, 0x9f, 0x58, + 0x3f, 0xa9, 0xb9, 0xe0, 0x92, 0x67, 0x5c, 0xee, 0xa0, 0xdb, 0xa1, 0x5c, 0x54, 0x1e, 0xee, 0x29, + 0x73, 0x5f, 0x18, 0xee, 0xf9, 0x92, 0xaf, 0x8d, 0x63, 0xf4, 0x2b, 0x0d, 0x06, 0xd9, 0x3f, 0xea, + 0x51, 0x26, 0x82, 0x88, 0x57, 0x7e, 0x79, 0x48, 0x64, 0x23, 0xcf, 0x17, 0x70, 0x31, 0x83, 0x3b, + 0x87, 0x12, 0xc1, 0xa9, 0xd2, 0x9d, 0x9b, 0xdf, 0xfe, 0xf8, 0x39, 0xa9, 0x7d, 0xfa, 0x9c, 0xd4, + 0xfe, 0xf7, 0x39, 0xa9, 0xbd, 0xfb, 0x92, 0xec, 0xfb, 0xf4, 0x25, 0xd9, 0xf7, 0xaf, 0x2f, 0xc9, + 0xbe, 0x1f, 0x67, 0xab, 0x35, 0x67, 0xef, 0xa0, 0xe4, 0xbe, 0x68, 0x02, 0x73, 0xc2, 0x51, 0xd3, + 0x95, 0xd3, 0xa8, 0x13, 0xbb, 0x14, 0x63, 0x3f, 0x9b, 0x5c, 0xfb, 0x36, 0x00, 0x00, 0xff, 0xff, + 0x2e, 0xac, 0xc8, 0xff, 0x92, 0x1a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1456,6 +1784,10 @@ type QueryClient interface { BlameByIdentifier(ctx context.Context, in *QueryBlameByIdentifierRequest, opts ...grpc.CallOption) (*QueryBlameByIdentifierResponse, error) // Queries a list of VoterByIdentifier items. GetAllBlameRecords(ctx context.Context, in *QueryAllBlameRecordsRequest, opts ...grpc.CallOption) (*QueryAllBlameRecordsResponse, error) + GetAllBlockHeaders(ctx context.Context, in *QueryAllBlockHeaderRequest, opts ...grpc.CallOption) (*QueryAllBlockHeaderResponse, error) + GetBlockHeaderByHash(ctx context.Context, in *QueryGetBlockHeaderByHashRequest, opts ...grpc.CallOption) (*QueryGetBlockHeaderByHashResponse, error) + // merkle proof verification + Prove(ctx context.Context, in *QueryProveRequest, opts ...grpc.CallOption) (*QueryProveResponse, error) } type queryClient struct { @@ -1592,22 +1924,49 @@ func (c *queryClient) GetAllBlameRecords(ctx context.Context, in *QueryAllBlameR return out, nil } -// QueryServer is the server API for Query service. -type QueryServer interface { - // Parameters queries the parameters of the module. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // Queries a list of VoterByIdentifier items. - BallotByIdentifier(context.Context, *QueryBallotByIdentifierRequest) (*QueryBallotByIdentifierResponse, error) - // Queries a list of ObserversByChainAndType items. - ObserversByChain(context.Context, *QueryObserversByChainRequest) (*QueryObserversByChainResponse, error) - AllObserverMappers(context.Context, *QueryAllObserverMappersRequest) (*QueryAllObserverMappersResponse, error) - SupportedChains(context.Context, *QuerySupportedChains) (*QuerySupportedChainsResponse, error) - // Queries a list of GetClientParamsForChain items. - GetCoreParamsForChain(context.Context, *QueryGetCoreParamsForChainRequest) (*QueryGetCoreParamsForChainResponse, error) - // Queries a list of GetCoreParams items. - GetCoreParams(context.Context, *QueryGetCoreParamsRequest) (*QueryGetCoreParamsResponse, error) - // Queries a nodeAccount by index. - NodeAccount(context.Context, *QueryGetNodeAccountRequest) (*QueryGetNodeAccountResponse, error) +func (c *queryClient) GetAllBlockHeaders(ctx context.Context, in *QueryAllBlockHeaderRequest, opts ...grpc.CallOption) (*QueryAllBlockHeaderResponse, error) { + out := new(QueryAllBlockHeaderResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetAllBlockHeaders", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetBlockHeaderByHash(ctx context.Context, in *QueryGetBlockHeaderByHashRequest, opts ...grpc.CallOption) (*QueryGetBlockHeaderByHashResponse, error) { + out := new(QueryGetBlockHeaderByHashResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetBlockHeaderByHash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Prove(ctx context.Context, in *QueryProveRequest, opts ...grpc.CallOption) (*QueryProveResponse, error) { + out := new(QueryProveResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/Prove", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Parameters queries the parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // Queries a list of VoterByIdentifier items. + BallotByIdentifier(context.Context, *QueryBallotByIdentifierRequest) (*QueryBallotByIdentifierResponse, error) + // Queries a list of ObserversByChainAndType items. + ObserversByChain(context.Context, *QueryObserversByChainRequest) (*QueryObserversByChainResponse, error) + AllObserverMappers(context.Context, *QueryAllObserverMappersRequest) (*QueryAllObserverMappersResponse, error) + SupportedChains(context.Context, *QuerySupportedChains) (*QuerySupportedChainsResponse, error) + // Queries a list of GetClientParamsForChain items. + GetCoreParamsForChain(context.Context, *QueryGetCoreParamsForChainRequest) (*QueryGetCoreParamsForChainResponse, error) + // Queries a list of GetCoreParams items. + GetCoreParams(context.Context, *QueryGetCoreParamsRequest) (*QueryGetCoreParamsResponse, error) + // Queries a nodeAccount by index. + NodeAccount(context.Context, *QueryGetNodeAccountRequest) (*QueryGetNodeAccountResponse, error) // Queries a list of nodeAccount items. NodeAccountAll(context.Context, *QueryAllNodeAccountRequest) (*QueryAllNodeAccountResponse, error) PermissionFlags(context.Context, *QueryGetPermissionFlagsRequest) (*QueryGetPermissionFlagsResponse, error) @@ -1619,6 +1978,10 @@ type QueryServer interface { BlameByIdentifier(context.Context, *QueryBlameByIdentifierRequest) (*QueryBlameByIdentifierResponse, error) // Queries a list of VoterByIdentifier items. GetAllBlameRecords(context.Context, *QueryAllBlameRecordsRequest) (*QueryAllBlameRecordsResponse, error) + GetAllBlockHeaders(context.Context, *QueryAllBlockHeaderRequest) (*QueryAllBlockHeaderResponse, error) + GetBlockHeaderByHash(context.Context, *QueryGetBlockHeaderByHashRequest) (*QueryGetBlockHeaderByHashResponse, error) + // merkle proof verification + Prove(context.Context, *QueryProveRequest) (*QueryProveResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1667,6 +2030,15 @@ func (*UnimplementedQueryServer) BlameByIdentifier(ctx context.Context, req *Que func (*UnimplementedQueryServer) GetAllBlameRecords(ctx context.Context, req *QueryAllBlameRecordsRequest) (*QueryAllBlameRecordsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetAllBlameRecords not implemented") } +func (*UnimplementedQueryServer) GetAllBlockHeaders(ctx context.Context, req *QueryAllBlockHeaderRequest) (*QueryAllBlockHeaderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllBlockHeaders not implemented") +} +func (*UnimplementedQueryServer) GetBlockHeaderByHash(ctx context.Context, req *QueryGetBlockHeaderByHashRequest) (*QueryGetBlockHeaderByHashResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockHeaderByHash not implemented") +} +func (*UnimplementedQueryServer) Prove(ctx context.Context, req *QueryProveRequest) (*QueryProveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Prove not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1924,6 +2296,60 @@ func _Query_GetAllBlameRecords_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Query_GetAllBlockHeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllBlockHeaderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetAllBlockHeaders(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/GetAllBlockHeaders", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetAllBlockHeaders(ctx, req.(*QueryAllBlockHeaderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetBlockHeaderByHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetBlockHeaderByHashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetBlockHeaderByHash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/GetBlockHeaderByHash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetBlockHeaderByHash(ctx, req.(*QueryGetBlockHeaderByHashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Prove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryProveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Prove(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/Prove", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Prove(ctx, req.(*QueryProveRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.observer.Query", HandlerType: (*QueryServer)(nil), @@ -1984,11 +2410,115 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "GetAllBlameRecords", Handler: _Query_GetAllBlameRecords_Handler, }, + { + MethodName: "GetAllBlockHeaders", + Handler: _Query_GetAllBlockHeaders_Handler, + }, + { + MethodName: "GetBlockHeaderByHash", + Handler: _Query_GetBlockHeaderByHash_Handler, + }, + { + MethodName: "Prove", + Handler: _Query_Prove_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "observer/query.proto", } +func (m *QueryProveRequest) 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 *QueryProveRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryProveRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TxIndex != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.TxIndex)) + i-- + dAtA[i] = 0x28 + } + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0x22 + } + if m.Proof != nil { + { + size, err := m.Proof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.TxHash) > 0 { + i -= len(m.TxHash) + copy(dAtA[i:], m.TxHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.TxHash))) + i-- + dAtA[i] = 0x12 + } + if m.ChainId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryProveResponse) 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 *QueryProveResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryProveResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Valid { + i-- + if m.Valid { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2913,99 +3443,287 @@ func (m *QueryAllBlameRecordsResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryAllBlockHeaderRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n +func (m *QueryAllBlockHeaderRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryBallotByIdentifierRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryAllBlockHeaderRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.BallotIdentifier) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *VoterList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.VoterAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.VoteType != 0 { - n += 1 + sovQuery(uint64(m.VoteType)) +func (m *QueryAllBlockHeaderResponse) 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 n + return dAtA[:n], nil } -func (m *QueryBallotByIdentifierResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.BallotIdentifier) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if len(m.Voters) > 0 { - for _, e := range m.Voters { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } - } - if m.ObservationType != 0 { - n += 1 + sovQuery(uint64(m.ObservationType)) - } - if m.BallotStatus != 0 { - n += 1 + sovQuery(uint64(m.BallotStatus)) - } - return n +func (m *QueryAllBlockHeaderResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryObserversByChainRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryAllBlockHeaderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ObservationChain) - if l > 0 { + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.BlockHeaders) > 0 { + for iNdEx := len(m.BlockHeaders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BlockHeaders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetBlockHeaderByHashRequest) 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 *QueryGetBlockHeaderByHashRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetBlockHeaderByHashRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetBlockHeaderByHashResponse) 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 *QueryGetBlockHeaderByHashResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetBlockHeaderByHashResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BlockHeader != nil { + { + size, err := m.BlockHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryProveRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainId != 0 { + n += 1 + sovQuery(uint64(m.ChainId)) + } + l = len(m.TxHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Proof != nil { + l = m.Proof.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.TxIndex != 0 { + n += 1 + sovQuery(uint64(m.TxIndex)) + } + return n +} + +func (m *QueryProveResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Valid { + n += 2 + } + return n +} + +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryBallotByIdentifierRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BallotIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *VoterList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.VoterAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.VoteType != 0 { + n += 1 + sovQuery(uint64(m.VoteType)) + } + return n +} + +func (m *QueryBallotByIdentifierResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BallotIdentifier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.Voters) > 0 { + for _, e := range m.Voters { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.ObservationType != 0 { + n += 1 + sovQuery(uint64(m.ObservationType)) + } + if m.BallotStatus != 0 { + n += 1 + sovQuery(uint64(m.BallotStatus)) + } + return n +} + +func (m *QueryObserversByChainRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ObservationChain) + if l > 0 { n += 1 + l + sovQuery(uint64(l)) } return n @@ -3293,13 +4011,71 @@ func (m *QueryAllBlameRecordsResponse) Size() (n int) { return n } +func (m *QueryAllBlockHeaderRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllBlockHeaderResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.BlockHeaders) > 0 { + for _, e := range m.BlockHeaders { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetBlockHeaderByHashRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetBlockHeaderByHashResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeader != nil { + l = m.BlockHeader.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryProveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3322,15 +4098,273 @@ func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryProveRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryProveRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) + case 1: + 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 ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Proof == nil { + m.Proof = &common.Proof{} + } + if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxIndex", wireType) + } + m.TxIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxIndex |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryProveResponse) 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 ErrIntOverflowQuery + } + 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: QueryProveResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryProveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Valid", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Valid = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsRequest) 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 ErrIntOverflowQuery + } + 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) if err != nil { return err } @@ -3432,7 +4466,344 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryBallotByIdentifierRequest) Unmarshal(dAtA []byte) error { +func (m *QueryBallotByIdentifierRequest) 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 ErrIntOverflowQuery + } + 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: QueryBallotByIdentifierRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBallotByIdentifierRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BallotIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BallotIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VoterList) 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 ErrIntOverflowQuery + } + 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: VoterList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VoterList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VoterAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VoterAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VoteType", wireType) + } + m.VoteType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VoteType |= VoteType(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryBallotByIdentifierResponse) 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 ErrIntOverflowQuery + } + 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: QueryBallotByIdentifierResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBallotByIdentifierResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BallotIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BallotIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voters = append(m.Voters, &VoterList{}) + if err := m.Voters[len(m.Voters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservationType", wireType) + } + m.ObservationType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservationType |= ObservationType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BallotStatus", wireType) + } + m.BallotStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BallotStatus |= BallotStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3455,15 +4826,15 @@ func (m *QueryBallotByIdentifierRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryBallotByIdentifierRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryObserversByChainRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryBallotByIdentifierRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryObserversByChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BallotIdentifier", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObservationChain", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3491,7 +4862,7 @@ func (m *QueryBallotByIdentifierRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BallotIdentifier = string(dAtA[iNdEx:postIndex]) + m.ObservationChain = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3514,7 +4885,7 @@ func (m *QueryBallotByIdentifierRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *VoterList) Unmarshal(dAtA []byte) error { +func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3537,15 +4908,15 @@ func (m *VoterList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: VoterList: wiretype end group for non-group") + return fmt.Errorf("proto: QueryObserversByChainResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: VoterList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryObserversByChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VoterAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Observers", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3573,27 +4944,8 @@ func (m *VoterList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.VoterAddress = string(dAtA[iNdEx:postIndex]) + m.Observers = append(m.Observers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VoteType", wireType) - } - m.VoteType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.VoteType |= VoteType(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3615,7 +4967,7 @@ func (m *VoterList) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryBallotByIdentifierResponse) Unmarshal(dAtA []byte) error { +func (m *QueryAllObserverMappersRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3638,47 +4990,65 @@ func (m *QueryBallotByIdentifierResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryBallotByIdentifierResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllObserverMappersRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryBallotByIdentifierResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllObserverMappersRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BallotIdentifier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllObserverMappersResponse) 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 ErrIntOverflowQuery + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.BallotIdentifier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + 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: QueryAllObserverMappersResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllObserverMappersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Voters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObserverMappers", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3705,49 +5075,11 @@ func (m *QueryBallotByIdentifierResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Voters = append(m.Voters, &VoterList{}) - if err := m.Voters[len(m.Voters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ObserverMappers = append(m.ObserverMappers, &ObserverMapper{}) + if err := m.ObserverMappers[len(m.ObserverMappers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservationType", wireType) - } - m.ObservationType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ObservationType |= ObservationType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BallotStatus", wireType) - } - m.BallotStatus = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.BallotStatus |= BallotStatus(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3769,7 +5101,7 @@ func (m *QueryBallotByIdentifierResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { +func (m *QuerySupportedChains) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3792,44 +5124,12 @@ func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryObserversByChainRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QuerySupportedChains: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryObserversByChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QuerySupportedChains: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservationChain", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ObservationChain = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3851,7 +5151,7 @@ func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { +func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3874,17 +5174,17 @@ func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryObserversByChainResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QuerySupportedChainsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryObserversByChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QuerySupportedChainsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Observers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Chains", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -3894,23 +5194,25 @@ func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.Observers = append(m.Observers, string(dAtA[iNdEx:postIndex])) + m.Chains = append(m.Chains, &common.Chain{}) + if err := m.Chains[len(m.Chains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -3933,7 +5235,7 @@ func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllObserverMappersRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3956,12 +5258,31 @@ func (m *QueryAllObserverMappersRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllObserverMappersRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllObserverMappersRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + 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 ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3983,7 +5304,7 @@ func (m *QueryAllObserverMappersRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllObserverMappersResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4006,15 +5327,15 @@ func (m *QueryAllObserverMappersResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllObserverMappersResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllObserverMappersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObserverMappers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4041,8 +5362,10 @@ func (m *QueryAllObserverMappersResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObserverMappers = append(m.ObserverMappers, &ObserverMapper{}) - if err := m.ObserverMappers[len(m.ObserverMappers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.CoreParams == nil { + m.CoreParams = &CoreParams{} + } + if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4067,7 +5390,7 @@ func (m *QueryAllObserverMappersResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySupportedChains) Unmarshal(dAtA []byte) error { +func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4090,10 +5413,10 @@ func (m *QuerySupportedChains) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySupportedChains: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetCoreParamsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySupportedChains: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetCoreParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -4117,7 +5440,7 @@ func (m *QuerySupportedChains) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4140,15 +5463,15 @@ func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySupportedChainsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetCoreParamsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySupportedChainsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetCoreParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Chains", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4175,8 +5498,10 @@ func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Chains = append(m.Chains, &common.Chain{}) - if err := m.Chains[len(m.Chains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.CoreParams == nil { + m.CoreParams = &CoreParamsList{} + } + if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4201,7 +5526,7 @@ func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetNodeAccountRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4224,17 +5549,17 @@ func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetNodeAccountRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetNodeAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) } - m.ChainId = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4244,11 +5569,24 @@ func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChainId |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Index = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4270,7 +5608,7 @@ func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetNodeAccountResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4293,15 +5631,15 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetNodeAccountResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetNodeAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NodeAccount", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4328,10 +5666,10 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CoreParams == nil { - m.CoreParams = &CoreParams{} + if m.NodeAccount == nil { + m.NodeAccount = &NodeAccount{} } - if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.NodeAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4356,7 +5694,7 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryAllNodeAccountRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4379,12 +5717,48 @@ func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllNodeAccountRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllNodeAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4406,7 +5780,7 @@ func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryAllNodeAccountResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4429,15 +5803,15 @@ func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllNodeAccountResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllNodeAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NodeAccount", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4464,10 +5838,44 @@ func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CoreParams == nil { - m.CoreParams = &CoreParamsList{} + m.NodeAccount = append(m.NodeAccount, &NodeAccount{}) + if err := m.NodeAccount[len(m.NodeAccount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4492,7 +5900,7 @@ func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetNodeAccountRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetPermissionFlagsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4515,44 +5923,12 @@ func (m *QueryGetNodeAccountRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetNodeAccountRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetPermissionFlagsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetNodeAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetPermissionFlagsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Index = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4574,7 +5950,7 @@ func (m *QueryGetNodeAccountRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetNodeAccountResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetPermissionFlagsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4597,15 +5973,15 @@ func (m *QueryGetNodeAccountResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetNodeAccountResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetPermissionFlagsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetNodeAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetPermissionFlagsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeAccount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PermissionFlags", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4632,10 +6008,7 @@ func (m *QueryGetNodeAccountResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NodeAccount == nil { - m.NodeAccount = &NodeAccount{} - } - if err := m.NodeAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.PermissionFlags.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4660,7 +6033,7 @@ func (m *QueryGetNodeAccountResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllNodeAccountRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetKeygenRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4673,58 +6046,22 @@ func (m *QueryAllNodeAccountRequest) Unmarshal(dAtA []byte) error { 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: QueryAllNodeAccountRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllNodeAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGetKeygenRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetKeygenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4746,7 +6083,7 @@ func (m *QueryAllNodeAccountRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllNodeAccountResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetKeygenResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4769,49 +6106,15 @@ func (m *QueryAllNodeAccountResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllNodeAccountResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetKeygenResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllNodeAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetKeygenResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeAccount", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NodeAccount = append(m.NodeAccount, &NodeAccount{}) - if err := m.NodeAccount[len(m.NodeAccount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Keygen", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4838,10 +6141,10 @@ func (m *QueryAllNodeAccountResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} + if m.Keygen == nil { + m.Keygen = &Keygen{} } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Keygen.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4866,7 +6169,7 @@ func (m *QueryAllNodeAccountResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetPermissionFlagsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryShowObserverCountRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4889,10 +6192,10 @@ func (m *QueryGetPermissionFlagsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetPermissionFlagsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryShowObserverCountRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetPermissionFlagsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryShowObserverCountRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -4916,7 +6219,7 @@ func (m *QueryGetPermissionFlagsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetPermissionFlagsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryShowObserverCountResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4939,15 +6242,15 @@ func (m *QueryGetPermissionFlagsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetPermissionFlagsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryShowObserverCountResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetPermissionFlagsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryShowObserverCountResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PermissionFlags", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastObserverCount", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4974,7 +6277,10 @@ func (m *QueryGetPermissionFlagsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.PermissionFlags.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.LastObserverCount == nil { + m.LastObserverCount = &LastObserverCount{} + } + if err := m.LastObserverCount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4999,7 +6305,7 @@ func (m *QueryGetPermissionFlagsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetKeygenRequest) Unmarshal(dAtA []byte) error { +func (m *QueryBlameByIdentifierRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5022,12 +6328,44 @@ func (m *QueryGetKeygenRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetKeygenRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryBlameByIdentifierRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetKeygenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryBlameByIdentifierRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlameIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlameIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -5049,7 +6387,7 @@ func (m *QueryGetKeygenRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetKeygenResponse) Unmarshal(dAtA []byte) error { +func (m *QueryBlameByIdentifierResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5072,15 +6410,15 @@ func (m *QueryGetKeygenResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetKeygenResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryBlameByIdentifierResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetKeygenResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryBlameByIdentifierResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keygen", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlameInfo", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5107,10 +6445,10 @@ func (m *QueryGetKeygenResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Keygen == nil { - m.Keygen = &Keygen{} + if m.BlameInfo == nil { + m.BlameInfo = &Blame{} } - if err := m.Keygen.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.BlameInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5135,7 +6473,7 @@ func (m *QueryGetKeygenResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryShowObserverCountRequest) Unmarshal(dAtA []byte) error { +func (m *QueryAllBlameRecordsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5158,10 +6496,10 @@ func (m *QueryShowObserverCountRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryShowObserverCountRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllBlameRecordsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryShowObserverCountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllBlameRecordsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -5185,7 +6523,7 @@ func (m *QueryShowObserverCountRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryShowObserverCountResponse) Unmarshal(dAtA []byte) error { +func (m *QueryAllBlameRecordsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5208,15 +6546,15 @@ func (m *QueryShowObserverCountResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryShowObserverCountResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllBlameRecordsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryShowObserverCountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllBlameRecordsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastObserverCount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlameInfo", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5243,10 +6581,8 @@ func (m *QueryShowObserverCountResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.LastObserverCount == nil { - m.LastObserverCount = &LastObserverCount{} - } - if err := m.LastObserverCount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.BlameInfo = append(m.BlameInfo, &Blame{}) + if err := m.BlameInfo[len(m.BlameInfo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5271,7 +6607,7 @@ func (m *QueryShowObserverCountResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryBlameByIdentifierRequest) Unmarshal(dAtA []byte) error { +func (m *QueryAllBlockHeaderRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5294,17 +6630,17 @@ func (m *QueryBlameByIdentifierRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryBlameByIdentifierRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllBlockHeaderRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryBlameByIdentifierRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllBlockHeaderRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlameIdentifier", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5314,23 +6650,27 @@ func (m *QueryBlameByIdentifierRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.BlameIdentifier = string(dAtA[iNdEx:postIndex]) + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -5353,7 +6693,7 @@ func (m *QueryBlameByIdentifierRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryBlameByIdentifierResponse) Unmarshal(dAtA []byte) error { +func (m *QueryAllBlockHeaderResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5376,15 +6716,15 @@ func (m *QueryBlameByIdentifierResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryBlameByIdentifierResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllBlockHeaderResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryBlameByIdentifierResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllBlockHeaderResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlameInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeaders", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5411,10 +6751,44 @@ func (m *QueryBlameByIdentifierResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.BlameInfo == nil { - m.BlameInfo = &Blame{} + m.BlockHeaders = append(m.BlockHeaders, &common.BlockHeader{}) + if err := m.BlockHeaders[len(m.BlockHeaders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.BlameInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5439,7 +6813,7 @@ func (m *QueryBlameByIdentifierResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllBlameRecordsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetBlockHeaderByHashRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5462,12 +6836,46 @@ func (m *QueryAllBlameRecordsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllBlameRecordsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetBlockHeaderByHashRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllBlameRecordsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetBlockHeaderByHashRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHash = append(m.BlockHash[:0], dAtA[iNdEx:postIndex]...) + if m.BlockHash == nil { + m.BlockHash = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -5489,7 +6897,7 @@ func (m *QueryAllBlameRecordsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllBlameRecordsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetBlockHeaderByHashResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5512,15 +6920,15 @@ func (m *QueryAllBlameRecordsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllBlameRecordsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetBlockHeaderByHashResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllBlameRecordsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetBlockHeaderByHashResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlameInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeader", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5547,8 +6955,10 @@ func (m *QueryAllBlameRecordsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlameInfo = append(m.BlameInfo, &Blame{}) - if err := m.BlameInfo[len(m.BlameInfo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.BlockHeader == nil { + m.BlockHeader = &common.BlockHeader{} + } + if err := m.BlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index d7e061ea4c..360d1ad447 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -483,6 +483,132 @@ func local_request_Query_GetAllBlameRecords_0(ctx context.Context, marshaler run } +var ( + filter_Query_GetAllBlockHeaders_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_GetAllBlockHeaders_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllBlockHeaderRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetAllBlockHeaders_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetAllBlockHeaders(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetAllBlockHeaders_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllBlockHeaderRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetAllBlockHeaders_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetAllBlockHeaders(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetBlockHeaderByHash_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetBlockHeaderByHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["block_hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "block_hash") + } + + protoReq.BlockHash, err = runtime.Bytes(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "block_hash", err) + } + + msg, err := client.GetBlockHeaderByHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetBlockHeaderByHash_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetBlockHeaderByHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["block_hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "block_hash") + } + + protoReq.BlockHash, err = runtime.Bytes(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "block_hash", err) + } + + msg, err := server.GetBlockHeaderByHash(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_Prove_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_Prove_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryProveRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Prove_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Prove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Prove_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryProveRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Prove_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Prove(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -811,6 +937,75 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_GetAllBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetAllBlockHeaders_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetAllBlockHeaders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetBlockHeaderByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetBlockHeaderByHash_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetBlockHeaderByHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Prove_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Prove_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Prove_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1132,6 +1327,66 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_GetAllBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetAllBlockHeaders_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetAllBlockHeaders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetBlockHeaderByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetBlockHeaderByHash_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetBlockHeaderByHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Prove_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Prove_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Prove_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1163,6 +1418,12 @@ var ( pattern_Query_BlameByIdentifier_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "blame_by_identifier", "blame_identifier"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_GetAllBlameRecords_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_all_blame_records"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_GetAllBlockHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_all_block_headers"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_GetBlockHeaderByHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "get_block_header_by_hash", "block_hash"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Prove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "prove"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -1193,4 +1454,10 @@ var ( forward_Query_BlameByIdentifier_0 = runtime.ForwardResponseMessage forward_Query_GetAllBlameRecords_0 = runtime.ForwardResponseMessage + + forward_Query_GetAllBlockHeaders_0 = runtime.ForwardResponseMessage + + forward_Query_GetBlockHeaderByHash_0 = runtime.ForwardResponseMessage + + forward_Query_Prove_0 = runtime.ForwardResponseMessage ) diff --git a/x/observer/types/tx.pb.go b/x/observer/types/tx.pb.go index d2e91155aa..cb6f2df8f9 100644 --- a/x/observer/types/tx.pb.go +++ b/x/observer/types/tx.pb.go @@ -13,7 +13,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" - _ "github.com/zeta-chain/zetacore/common" + common "github.com/zeta-chain/zetacore/common" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -30,6 +30,118 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type MsgAddBlockHeader 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"` + BlockHash []byte `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + Height int64 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"` + Header common.HeaderData `protobuf:"bytes,5,opt,name=header,proto3" json:"header"` +} + +func (m *MsgAddBlockHeader) Reset() { *m = MsgAddBlockHeader{} } +func (m *MsgAddBlockHeader) String() string { return proto.CompactTextString(m) } +func (*MsgAddBlockHeader) ProtoMessage() {} +func (*MsgAddBlockHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{0} +} +func (m *MsgAddBlockHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddBlockHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddBlockHeader.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 *MsgAddBlockHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddBlockHeader.Merge(m, src) +} +func (m *MsgAddBlockHeader) XXX_Size() int { + return m.Size() +} +func (m *MsgAddBlockHeader) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddBlockHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddBlockHeader proto.InternalMessageInfo + +func (m *MsgAddBlockHeader) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgAddBlockHeader) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *MsgAddBlockHeader) GetBlockHash() []byte { + if m != nil { + return m.BlockHash + } + return nil +} + +func (m *MsgAddBlockHeader) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *MsgAddBlockHeader) GetHeader() common.HeaderData { + if m != nil { + return m.Header + } + return common.HeaderData{} +} + +type MsgAddBlockHeaderResponse struct { +} + +func (m *MsgAddBlockHeaderResponse) Reset() { *m = MsgAddBlockHeaderResponse{} } +func (m *MsgAddBlockHeaderResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAddBlockHeaderResponse) ProtoMessage() {} +func (*MsgAddBlockHeaderResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{1} +} +func (m *MsgAddBlockHeaderResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddBlockHeaderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddBlockHeaderResponse.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 *MsgAddBlockHeaderResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddBlockHeaderResponse.Merge(m, src) +} +func (m *MsgAddBlockHeaderResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAddBlockHeaderResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddBlockHeaderResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddBlockHeaderResponse proto.InternalMessageInfo + type MsgUpdateCoreParams struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` CoreParams *CoreParams `protobuf:"bytes,2,opt,name=coreParams,proto3" json:"coreParams,omitempty"` @@ -39,7 +151,7 @@ func (m *MsgUpdateCoreParams) Reset() { *m = MsgUpdateCoreParams{} } func (m *MsgUpdateCoreParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateCoreParams) ProtoMessage() {} func (*MsgUpdateCoreParams) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{0} + return fileDescriptor_1bcd40fa296a2b1d, []int{2} } func (m *MsgUpdateCoreParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -89,7 +201,7 @@ func (m *MsgUpdateCoreParamsResponse) Reset() { *m = MsgUpdateCoreParams func (m *MsgUpdateCoreParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateCoreParamsResponse) ProtoMessage() {} func (*MsgUpdateCoreParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{1} + return fileDescriptor_1bcd40fa296a2b1d, []int{3} } func (m *MsgUpdateCoreParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -129,7 +241,7 @@ func (m *MsgAddObserver) Reset() { *m = MsgAddObserver{} } func (m *MsgAddObserver) String() string { return proto.CompactTextString(m) } func (*MsgAddObserver) ProtoMessage() {} func (*MsgAddObserver) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{2} + return fileDescriptor_1bcd40fa296a2b1d, []int{4} } func (m *MsgAddObserver) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -193,7 +305,7 @@ func (m *MsgAddObserverResponse) Reset() { *m = MsgAddObserverResponse{} func (m *MsgAddObserverResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddObserverResponse) ProtoMessage() {} func (*MsgAddObserverResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{3} + return fileDescriptor_1bcd40fa296a2b1d, []int{5} } func (m *MsgAddObserverResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -232,7 +344,7 @@ func (m *MsgAddBlameVote) Reset() { *m = MsgAddBlameVote{} } func (m *MsgAddBlameVote) String() string { return proto.CompactTextString(m) } func (*MsgAddBlameVote) ProtoMessage() {} func (*MsgAddBlameVote) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{4} + return fileDescriptor_1bcd40fa296a2b1d, []int{6} } func (m *MsgAddBlameVote) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -289,7 +401,7 @@ func (m *MsgAddBlameVoteResponse) Reset() { *m = MsgAddBlameVoteResponse func (m *MsgAddBlameVoteResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddBlameVoteResponse) ProtoMessage() {} func (*MsgAddBlameVoteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{5} + return fileDescriptor_1bcd40fa296a2b1d, []int{7} } func (m *MsgAddBlameVoteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -328,7 +440,7 @@ func (m *MsgUpdatePermissionFlags) Reset() { *m = MsgUpdatePermissionFla func (m *MsgUpdatePermissionFlags) String() string { return proto.CompactTextString(m) } func (*MsgUpdatePermissionFlags) ProtoMessage() {} func (*MsgUpdatePermissionFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{6} + return fileDescriptor_1bcd40fa296a2b1d, []int{8} } func (m *MsgUpdatePermissionFlags) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +497,7 @@ func (m *MsgUpdatePermissionFlagsResponse) Reset() { *m = MsgUpdatePermi func (m *MsgUpdatePermissionFlagsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdatePermissionFlagsResponse) ProtoMessage() {} func (*MsgUpdatePermissionFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{7} + return fileDescriptor_1bcd40fa296a2b1d, []int{9} } func (m *MsgUpdatePermissionFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -423,7 +535,7 @@ func (m *MsgUpdateKeygen) Reset() { *m = MsgUpdateKeygen{} } func (m *MsgUpdateKeygen) String() string { return proto.CompactTextString(m) } func (*MsgUpdateKeygen) ProtoMessage() {} func (*MsgUpdateKeygen) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{8} + return fileDescriptor_1bcd40fa296a2b1d, []int{10} } func (m *MsgUpdateKeygen) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -473,7 +585,7 @@ func (m *MsgUpdateKeygenResponse) Reset() { *m = MsgUpdateKeygenResponse func (m *MsgUpdateKeygenResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateKeygenResponse) ProtoMessage() {} func (*MsgUpdateKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{9} + return fileDescriptor_1bcd40fa296a2b1d, []int{11} } func (m *MsgUpdateKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -503,6 +615,8 @@ func (m *MsgUpdateKeygenResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateKeygenResponse proto.InternalMessageInfo func init() { + proto.RegisterType((*MsgAddBlockHeader)(nil), "zetachain.zetacore.observer.MsgAddBlockHeader") + proto.RegisterType((*MsgAddBlockHeaderResponse)(nil), "zetachain.zetacore.observer.MsgAddBlockHeaderResponse") proto.RegisterType((*MsgUpdateCoreParams)(nil), "zetachain.zetacore.observer.MsgUpdateCoreParams") proto.RegisterType((*MsgUpdateCoreParamsResponse)(nil), "zetachain.zetacore.observer.MsgUpdateCoreParamsResponse") proto.RegisterType((*MsgAddObserver)(nil), "zetachain.zetacore.observer.MsgAddObserver") @@ -518,47 +632,53 @@ func init() { func init() { proto.RegisterFile("observer/tx.proto", fileDescriptor_1bcd40fa296a2b1d) } var fileDescriptor_1bcd40fa296a2b1d = []byte{ - // 627 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcf, 0x4f, 0xd4, 0x40, - 0x14, 0xa6, 0x82, 0x02, 0x0f, 0x23, 0x50, 0x40, 0x4a, 0x89, 0xcd, 0xa6, 0x17, 0x51, 0xb1, 0x55, - 0xd0, 0xc4, 0x98, 0x78, 0x58, 0x8c, 0x92, 0x8d, 0x41, 0x48, 0x13, 0x3d, 0x78, 0x69, 0xa6, 0x9d, - 0xa1, 0x34, 0xb4, 0x33, 0xcd, 0x4c, 0xd7, 0xb0, 0x1e, 0xbc, 0x7b, 0xd0, 0xf8, 0x47, 0x79, 0xf0, - 0xc8, 0xd1, 0xa3, 0x81, 0xbb, 0x7f, 0x83, 0xd9, 0x99, 0x6d, 0xf7, 0xa7, 0x65, 0xd7, 0xd3, 0xce, - 0xbc, 0xf7, 0xbd, 0xef, 0x7d, 0xef, 0xcd, 0xb7, 0xbb, 0xb0, 0xcc, 0x02, 0x41, 0xf8, 0x47, 0xc2, - 0xdd, 0xfc, 0xcc, 0xc9, 0x38, 0xcb, 0x99, 0xbe, 0xf9, 0x89, 0xe4, 0x28, 0x3c, 0x41, 0x31, 0x75, - 0xe4, 0x89, 0x71, 0xe2, 0x14, 0x28, 0x73, 0x25, 0x64, 0x69, 0xca, 0xa8, 0xab, 0x3e, 0x54, 0x85, - 0xb9, 0x1a, 0xb1, 0x88, 0xc9, 0xa3, 0xdb, 0x3e, 0x15, 0xd1, 0x92, 0x3a, 0x48, 0x50, 0x4a, 0x3a, - 0xd1, 0xf5, 0x32, 0x5a, 0x1c, 0x3a, 0x89, 0xb5, 0x32, 0x91, 0x21, 0x8e, 0x52, 0xa1, 0xc2, 0xf6, - 0x19, 0xac, 0x1c, 0x88, 0xe8, 0x5d, 0x86, 0x51, 0x4e, 0x5e, 0x32, 0x4e, 0x8e, 0x64, 0x52, 0x37, - 0x60, 0x36, 0xe4, 0x04, 0xe5, 0x8c, 0x1b, 0x5a, 0x4d, 0xdb, 0x9a, 0xf7, 0x8a, 0xab, 0xbe, 0x0f, - 0x10, 0x96, 0x38, 0xe3, 0x5a, 0x4d, 0xdb, 0x5a, 0xd8, 0xb9, 0xeb, 0x54, 0xcc, 0xe4, 0x74, 0x69, - 0xbd, 0x9e, 0x52, 0xfb, 0x0e, 0x6c, 0x8e, 0xe8, 0xec, 0x11, 0x91, 0x31, 0x2a, 0x88, 0xfd, 0x43, - 0x83, 0x5b, 0x07, 0x22, 0xaa, 0x63, 0x7c, 0xd8, 0x21, 0xaa, 0x10, 0x75, 0x0f, 0x96, 0x8a, 0x76, - 0x3e, 0xc2, 0x98, 0x13, 0xa1, 0xa4, 0xcd, 0x7b, 0x8b, 0x45, 0xbc, 0xae, 0xc2, 0xfa, 0x73, 0xd8, - 0x90, 0x12, 0x93, 0x98, 0xd0, 0xdc, 0x8f, 0x38, 0xa2, 0x39, 0x21, 0x7e, 0xd6, 0x0c, 0x4e, 0x49, - 0xcb, 0x98, 0x96, 0x35, 0xeb, 0x5d, 0xc0, 0xbe, 0xca, 0x1f, 0xc9, 0xb4, 0xfe, 0x18, 0xd6, 0x10, - 0xc6, 0x3e, 0x65, 0x98, 0xf8, 0x28, 0x0c, 0x59, 0x93, 0xe6, 0x3e, 0xa3, 0x49, 0xcb, 0x98, 0xa9, - 0x69, 0x5b, 0x73, 0x9e, 0x8e, 0x30, 0x7e, 0xcb, 0x30, 0xa9, 0xab, 0xd4, 0x21, 0x4d, 0x5a, 0xb6, - 0x01, 0xb7, 0xfb, 0xa7, 0x28, 0x07, 0xfc, 0xa2, 0xc1, 0xa2, 0x4a, 0xed, 0xb5, 0xdf, 0xef, 0x3d, - 0xcb, 0x49, 0xc5, 0x84, 0x1b, 0x30, 0x27, 0xf7, 0xeb, 0xc7, 0x58, 0x4e, 0x36, 0xed, 0xcd, 0xca, - 0x7b, 0x03, 0xeb, 0x75, 0x00, 0xe9, 0x00, 0x3f, 0xa6, 0xc7, 0x4c, 0x8e, 0xb0, 0xb0, 0x63, 0x57, - 0xbe, 0x88, 0x6c, 0xe8, 0xcd, 0xcb, 0xaa, 0x06, 0x3d, 0x66, 0xf6, 0x06, 0xac, 0x0f, 0x48, 0x29, - 0x65, 0x7e, 0xd3, 0xc0, 0x28, 0xdf, 0xe9, 0x88, 0xf0, 0x34, 0x16, 0x22, 0x66, 0xf4, 0x75, 0x82, - 0xa2, 0x2a, 0x9b, 0xdc, 0x87, 0xa5, 0x58, 0x34, 0x68, 0xc0, 0x9a, 0x14, 0xbf, 0xa2, 0x28, 0x48, - 0x08, 0x96, 0xd2, 0xe6, 0xbc, 0xa1, 0xb8, 0xbe, 0x0d, 0xcb, 0xb1, 0x38, 0x6c, 0xe6, 0x7d, 0x60, - 0xb5, 0xd2, 0xe1, 0x84, 0x6d, 0x43, 0xed, 0x5f, 0x7a, 0x4a, 0xd1, 0x75, 0xb9, 0x5a, 0x85, 0x79, - 0x43, 0x5a, 0x11, 0xa1, 0x15, 0x52, 0x57, 0xe1, 0x7a, 0x90, 0xb0, 0xf0, 0xb4, 0xb3, 0x57, 0x75, - 0xe9, 0xac, 0xa4, 0x97, 0xa2, 0x60, 0xdf, 0xf9, 0x33, 0x03, 0xd3, 0x07, 0x22, 0xd2, 0x19, 0x2c, - 0xf4, 0xda, 0xf3, 0x41, 0xe5, 0xce, 0xfb, 0x5d, 0x60, 0xee, 0x4e, 0x00, 0x2e, 0x1a, 0xeb, 0x9f, - 0x61, 0x69, 0xe8, 0x9b, 0xfa, 0xe8, 0x2a, 0xa2, 0xc1, 0x0a, 0xf3, 0xd9, 0xa4, 0x15, 0x65, 0x7f, - 0x0e, 0x37, 0xfb, 0xec, 0xba, 0x3d, 0xc6, 0x10, 0x25, 0xda, 0x7c, 0x32, 0x09, 0xba, 0xec, 0xf9, - 0x55, 0x83, 0xb5, 0xd1, 0xe6, 0x7b, 0x3a, 0xde, 0x1c, 0x03, 0x65, 0xe6, 0x8b, 0xff, 0x2a, 0xeb, - 0xdd, 0x41, 0x9f, 0xaf, 0xb6, 0xc7, 0xa3, 0x53, 0xe8, 0xab, 0x77, 0x30, 0xca, 0x70, 0x7b, 0x8d, - 0x9f, 0x17, 0x96, 0x76, 0x7e, 0x61, 0x69, 0xbf, 0x2f, 0x2c, 0xed, 0xfb, 0xa5, 0x35, 0x75, 0x7e, - 0x69, 0x4d, 0xfd, 0xba, 0xb4, 0xa6, 0x3e, 0xb8, 0x51, 0x9c, 0x9f, 0x34, 0x03, 0x27, 0x64, 0xa9, - 0xdb, 0xe6, 0x7b, 0x28, 0xa9, 0xdd, 0x82, 0xda, 0x3d, 0x73, 0xbb, 0x7f, 0x40, 0xad, 0x8c, 0x88, - 0xe0, 0x86, 0xfc, 0xd9, 0xdf, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x55, 0xa7, 0x00, 0x99, - 0x06, 0x00, 0x00, + // 731 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x49, 0x6f, 0xd3, 0x40, + 0x14, 0x8e, 0xe9, 0x9a, 0x97, 0xaa, 0x8b, 0xbb, 0x39, 0xa9, 0x1a, 0x22, 0x5f, 0x08, 0x50, 0xe2, + 0x92, 0x02, 0x42, 0x48, 0x1c, 0x52, 0x96, 0x36, 0x42, 0xa5, 0x95, 0x25, 0x38, 0x70, 0xb1, 0xc6, + 0x99, 0x57, 0xc7, 0x6a, 0x3c, 0x13, 0xd9, 0x0e, 0x4a, 0x38, 0x70, 0xe7, 0x00, 0xe2, 0xaf, 0xf0, + 0x1f, 0x38, 0xf4, 0xd8, 0x23, 0x27, 0x84, 0xda, 0x0b, 0x3f, 0x03, 0x79, 0xbc, 0x34, 0x4b, 0x49, + 0x93, 0x9e, 0x3c, 0xf3, 0xde, 0xf7, 0xbe, 0xf7, 0xbd, 0xc5, 0x1a, 0x58, 0xe2, 0xa6, 0x87, 0xee, + 0x47, 0x74, 0x35, 0xbf, 0x5d, 0x6a, 0xba, 0xdc, 0xe7, 0xf2, 0xc6, 0x27, 0xf4, 0x49, 0xad, 0x4e, + 0x6c, 0x56, 0x12, 0x27, 0xee, 0x62, 0x29, 0x46, 0xe5, 0x96, 0x6b, 0xdc, 0x71, 0x38, 0xd3, 0xc2, + 0x4f, 0x18, 0x91, 0x5b, 0xb1, 0xb8, 0xc5, 0xc5, 0x51, 0x0b, 0x4e, 0xb1, 0x35, 0xa1, 0x36, 0x1b, + 0xc4, 0xc1, 0xc8, 0xba, 0x9e, 0x58, 0xe3, 0x43, 0xe4, 0x58, 0x4d, 0x1c, 0x4d, 0xe2, 0x12, 0xc7, + 0x0b, 0xcd, 0xea, 0x0f, 0x09, 0x96, 0x0e, 0x3c, 0xab, 0x42, 0xe9, 0x6e, 0x83, 0xd7, 0x4e, 0xf6, + 0x91, 0x50, 0x74, 0x65, 0x05, 0x66, 0x6a, 0x2e, 0x12, 0x9f, 0xbb, 0x8a, 0x54, 0x90, 0x8a, 0x69, + 0x3d, 0xbe, 0xca, 0x59, 0x98, 0x15, 0xda, 0x0d, 0x9b, 0x2a, 0xb7, 0x0a, 0x52, 0x71, 0x42, 0x9f, + 0x11, 0xf7, 0x2a, 0x95, 0x37, 0x01, 0xcc, 0x80, 0xc3, 0xa8, 0x13, 0xaf, 0xae, 0x4c, 0x14, 0xa4, + 0xe2, 0x9c, 0x9e, 0x16, 0x96, 0x7d, 0xe2, 0xd5, 0xe5, 0x35, 0x98, 0xae, 0xa3, 0x6d, 0xd5, 0x7d, + 0x65, 0x52, 0xc4, 0x45, 0x37, 0x79, 0x3b, 0xb0, 0x07, 0x59, 0x95, 0xa9, 0x82, 0x54, 0xcc, 0x94, + 0xe5, 0x52, 0x54, 0x7c, 0xa8, 0xe5, 0x25, 0xf1, 0xc9, 0xee, 0xe4, 0xe9, 0xef, 0xdb, 0x29, 0x3d, + 0xc2, 0xa9, 0x1b, 0x90, 0x1d, 0x90, 0xac, 0xa3, 0xd7, 0xe4, 0xcc, 0x43, 0xb5, 0x0d, 0xcb, 0x07, + 0x9e, 0xf5, 0xae, 0x49, 0x89, 0x8f, 0x2f, 0xb8, 0x8b, 0x47, 0xa2, 0xda, 0x21, 0x15, 0xed, 0x01, + 0xd4, 0x12, 0x9c, 0xa8, 0x29, 0x53, 0xbe, 0x53, 0x1a, 0x32, 0xa4, 0xd2, 0x25, 0xad, 0xde, 0x15, + 0xaa, 0x6e, 0xc2, 0xc6, 0x15, 0x99, 0x13, 0x61, 0x3f, 0x25, 0x98, 0x0f, 0x65, 0x1f, 0x46, 0x44, + 0x43, 0x44, 0xdd, 0x85, 0xc5, 0x38, 0x9d, 0x41, 0x28, 0x75, 0xd1, 0x0b, 0xa5, 0xa5, 0xf5, 0x85, + 0xd8, 0x5e, 0x09, 0xcd, 0xf2, 0x33, 0xc8, 0x0a, 0x89, 0x0d, 0x1b, 0x99, 0x6f, 0x58, 0x2e, 0x61, + 0x3e, 0xa2, 0xd1, 0x6c, 0x99, 0x27, 0xd8, 0x11, 0x53, 0x48, 0xeb, 0xeb, 0x97, 0x80, 0xbd, 0xd0, + 0x7f, 0x24, 0xdc, 0xf2, 0x43, 0x58, 0x25, 0x94, 0x1a, 0x8c, 0x53, 0x34, 0x48, 0xad, 0xc6, 0x5b, + 0xcc, 0x37, 0x38, 0x6b, 0x74, 0xc4, 0x88, 0x66, 0x75, 0x99, 0x50, 0xfa, 0x96, 0x53, 0xac, 0x84, + 0xae, 0x43, 0xd6, 0xe8, 0xa8, 0x0a, 0xac, 0xf5, 0x56, 0x91, 0x14, 0xf8, 0x45, 0x82, 0x85, 0x78, + 0x2e, 0xc4, 0xc1, 0xf7, 0xdc, 0xc7, 0x9b, 0x2d, 0x52, 0x25, 0x58, 0x24, 0xe2, 0xa0, 0x61, 0xb3, + 0x63, 0x2e, 0x4a, 0xc8, 0x94, 0xd5, 0xa1, 0x13, 0x11, 0x09, 0x83, 0x65, 0x23, 0x0e, 0x56, 0xd9, + 0x31, 0x57, 0xb3, 0xb0, 0xde, 0x27, 0x25, 0x91, 0xf9, 0x4d, 0x02, 0x25, 0x99, 0xd3, 0x11, 0xba, + 0x8e, 0xed, 0x79, 0x36, 0x67, 0xaf, 0x1b, 0xc4, 0x1a, 0xb6, 0x26, 0xf7, 0x60, 0xd1, 0xf6, 0xaa, + 0xcc, 0xe4, 0x2d, 0x46, 0x5f, 0x31, 0x62, 0x36, 0x90, 0x0a, 0x69, 0xb3, 0xfa, 0x80, 0x5d, 0xde, + 0x82, 0x25, 0xdb, 0x3b, 0x6c, 0xf9, 0x3d, 0xe0, 0xb0, 0xa5, 0x83, 0x0e, 0x55, 0x85, 0xc2, 0xff, + 0xf4, 0x24, 0xa2, 0x2b, 0xa2, 0xb5, 0x21, 0xe6, 0x0d, 0x76, 0x2c, 0x64, 0x43, 0xa4, 0xae, 0xc0, + 0x94, 0xf8, 0xed, 0xa2, 0xbe, 0x86, 0x97, 0xa8, 0x25, 0xdd, 0x14, 0x31, 0x7b, 0xf9, 0xef, 0x14, + 0x4c, 0x1c, 0x78, 0x96, 0xcc, 0x21, 0xd3, 0xbd, 0x9e, 0xf7, 0x87, 0xf6, 0xbc, 0x77, 0x0b, 0x72, + 0x3b, 0x63, 0x80, 0xe3, 0xc4, 0xf2, 0x67, 0x58, 0x1c, 0xf8, 0x53, 0xb7, 0xaf, 0x23, 0xea, 0x8f, + 0xc8, 0x3d, 0x1d, 0x37, 0x22, 0xc9, 0xef, 0xc2, 0x5c, 0xcf, 0xba, 0x6e, 0x8d, 0x50, 0x44, 0x82, + 0xce, 0x3d, 0x1a, 0x07, 0x9d, 0xe4, 0xfc, 0x2a, 0xc1, 0xea, 0xd5, 0xcb, 0xf7, 0x78, 0xb4, 0x3a, + 0xfa, 0xc2, 0x72, 0xcf, 0x6f, 0x14, 0xd6, 0xdd, 0x83, 0x9e, 0xbd, 0xda, 0x1a, 0x8d, 0x2e, 0x44, + 0x5f, 0xdf, 0x83, 0xab, 0x16, 0x4e, 0x6e, 0xc3, 0x7c, 0xdf, 0x8b, 0x53, 0x1a, 0xa9, 0x97, 0x09, + 0x3e, 0xf7, 0x64, 0x3c, 0x7c, 0x9c, 0x79, 0xb7, 0x7a, 0x7a, 0x9e, 0x97, 0xce, 0xce, 0xf3, 0xd2, + 0x9f, 0xf3, 0xbc, 0xf4, 0xfd, 0x22, 0x9f, 0x3a, 0xbb, 0xc8, 0xa7, 0x7e, 0x5d, 0xe4, 0x53, 0x1f, + 0x34, 0xcb, 0xf6, 0xeb, 0x2d, 0x33, 0x78, 0x7d, 0xb4, 0x80, 0xf1, 0x81, 0x20, 0xd7, 0x62, 0x72, + 0xad, 0xad, 0x5d, 0xbe, 0xe5, 0x9d, 0x26, 0x7a, 0xe6, 0xb4, 0x78, 0x41, 0x77, 0xfe, 0x05, 0x00, + 0x00, 0xff, 0xff, 0xf9, 0x62, 0xcd, 0x1c, 0xe4, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -578,6 +698,7 @@ type MsgClient interface { AddBlameVote(ctx context.Context, in *MsgAddBlameVote, opts ...grpc.CallOption) (*MsgAddBlameVoteResponse, error) UpdatePermissionFlags(ctx context.Context, in *MsgUpdatePermissionFlags, opts ...grpc.CallOption) (*MsgUpdatePermissionFlagsResponse, error) UpdateKeygen(ctx context.Context, in *MsgUpdateKeygen, opts ...grpc.CallOption) (*MsgUpdateKeygenResponse, error) + AddBlockHeader(ctx context.Context, in *MsgAddBlockHeader, opts ...grpc.CallOption) (*MsgAddBlockHeaderResponse, error) } type msgClient struct { @@ -633,6 +754,15 @@ func (c *msgClient) UpdateKeygen(ctx context.Context, in *MsgUpdateKeygen, opts return out, nil } +func (c *msgClient) AddBlockHeader(ctx context.Context, in *MsgAddBlockHeader, opts ...grpc.CallOption) (*MsgAddBlockHeaderResponse, error) { + out := new(MsgAddBlockHeaderResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Msg/AddBlockHeader", 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) @@ -640,6 +770,7 @@ type MsgServer interface { AddBlameVote(context.Context, *MsgAddBlameVote) (*MsgAddBlameVoteResponse, error) UpdatePermissionFlags(context.Context, *MsgUpdatePermissionFlags) (*MsgUpdatePermissionFlagsResponse, error) UpdateKeygen(context.Context, *MsgUpdateKeygen) (*MsgUpdateKeygenResponse, error) + AddBlockHeader(context.Context, *MsgAddBlockHeader) (*MsgAddBlockHeaderResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -661,6 +792,9 @@ func (*UnimplementedMsgServer) UpdatePermissionFlags(ctx context.Context, req *M func (*UnimplementedMsgServer) UpdateKeygen(ctx context.Context, req *MsgUpdateKeygen) (*MsgUpdateKeygenResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateKeygen not implemented") } +func (*UnimplementedMsgServer) AddBlockHeader(ctx context.Context, req *MsgAddBlockHeader) (*MsgAddBlockHeaderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddBlockHeader not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -756,6 +890,24 @@ func _Msg_UpdateKeygen_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_AddBlockHeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAddBlockHeader) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AddBlockHeader(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Msg/AddBlockHeader", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AddBlockHeader(ctx, req.(*MsgAddBlockHeader)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.observer.Msg", HandlerType: (*MsgServer)(nil), @@ -780,11 +932,95 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateKeygen", Handler: _Msg_UpdateKeygen_Handler, }, + { + MethodName: "AddBlockHeader", + Handler: _Msg_AddBlockHeader_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "observer/tx.proto", } +func (m *MsgAddBlockHeader) 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 *MsgAddBlockHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddBlockHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if m.Height != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x20 + } + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0x1a + } + 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 *MsgAddBlockHeaderResponse) 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 *MsgAddBlockHeaderResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddBlockHeaderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *MsgUpdateCoreParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1139,6 +1375,40 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MsgAddBlockHeader) 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)) + } + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovTx(uint64(m.Height)) + } + l = m.Header.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgAddBlockHeaderResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgUpdateCoreParams) Size() (n int) { if m == nil { return 0 @@ -1286,6 +1556,243 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *MsgAddBlockHeader) 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: MsgAddBlockHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddBlockHeader: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHash = append(m.BlockHash[:0], dAtA[iNdEx:postIndex]...) + if m.BlockHash == nil { + m.BlockHash = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + 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 *MsgAddBlockHeaderResponse) 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: MsgAddBlockHeaderResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddBlockHeaderResponse: 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 (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index c84ff232b7..c9aa882991 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -71,7 +71,6 @@ type BitcoinChainClient struct { const ( minConfirmations = 0 - chunkSize = 1000 maxHeightDiff = 10000 dustOffset = 2000 ) @@ -598,24 +597,13 @@ func (ob *BitcoinChainClient) fetchUTXOS() error { return fmt.Errorf("btc: error decoding wallet address (%s) : %s", tssAddr, err.Error()) } addresses := []btcutil.Address{address} - var utxos []btcjson.ListUnspentResult - // populate utxos array - for i := minConfirmations; i < maxConfirmations; i += chunkSize { - unspents, err := ob.rpcClient.ListUnspentMinMaxAddresses(i, i+chunkSize, addresses) - if err != nil { - return err - } - utxos = append(utxos, unspents...) - //ob.logger.WatchUTXOS.Debug().Msgf("btc: fetched %d utxos", len(unspents)) - //for idx, utxo := range unspents { - // fmt.Printf("utxo %d\n", idx) - // fmt.Printf(" txid: %s\n", utxo.TxID) - // fmt.Printf(" address: %s\n", utxo.Address) - // fmt.Printf(" amount: %f\n", utxo.Amount) - // fmt.Printf(" confirmations: %d\n", utxo.Confirmations) - //} + // fetching all TSS utxos takes 160ms + utxos, err := ob.rpcClient.ListUnspentMinMaxAddresses(0, maxConfirmations, addresses) + if err != nil { + return err } + //ob.logger.WatchUTXOS.Debug().Msgf("btc: fetched %d utxos in confirmation range [0, %d]", len(unspents), maxConfirmations) // rigid sort to make utxo list deterministic sort.SliceStable(utxos, func(i, j int) bool { diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index a9c9c91b3c..70f1ce0739 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -13,7 +13,6 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" flag "github.com/spf13/pflag" rpchttp "github.com/tendermint/tendermint/rpc/client/http" - "github.com/zeta-chain/zetacore/app" ) // Broadcast Broadcasts tx to metachain. Returns txHash and error @@ -119,11 +118,10 @@ func (b *ZetaCoreBridge) GetContext() client.Context { ctx = ctx.WithFromAddress(addr) ctx = ctx.WithBroadcastMode("sync") - encodingConfig := app.MakeEncodingConfig() - ctx = ctx.WithCodec(encodingConfig.Codec) - ctx = ctx.WithInterfaceRegistry(encodingConfig.InterfaceRegistry) - ctx = ctx.WithTxConfig(encodingConfig.TxConfig) - ctx = ctx.WithLegacyAmino(encodingConfig.Amino) + ctx = ctx.WithCodec(b.encodingCfg.Codec) + ctx = ctx.WithInterfaceRegistry(b.encodingCfg.InterfaceRegistry) + ctx = ctx.WithTxConfig(b.encodingCfg.TxConfig) + ctx = ctx.WithLegacyAmino(b.encodingCfg.Amino) ctx = ctx.WithAccountRetriever(authtypes.AccountRetriever{}) remote := b.cfg.ChainRPC diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 4b0ab4cd94..6f9f53c6a7 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -254,7 +254,7 @@ func (signer *BTCSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out } to, ok := addr.(*btcutil.AddressWitnessPubKeyHash) if err != nil || !ok { - logger.Error().Err(err).Msgf("cannot decode address %s ", params.Receiver) + logger.Error().Err(err).Msgf("cannot convert address %s to P2WPKH address", params.Receiver) return } @@ -287,7 +287,7 @@ func (signer *BTCSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out continue } logger.Info().Msgf("Broadcast success: nonce %d to chain %s outTxHash %s", outboundTxTssNonce, btcClient.chain.String(), outTxHash) - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(btcClient.chain.ChainId, outboundTxTssNonce, outTxHash) + zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(btcClient.chain.ChainId, outboundTxTssNonce, outTxHash, nil, "", -1) if err != nil { logger.Err(err).Msgf("Unable to add to tracker on ZetaCore: nonce %d chain %s outTxHash %s", outboundTxTssNonce, btcClient.chain.ChainName, outTxHash) } diff --git a/zetaclient/config/config_mainnet.go b/zetaclient/config/config_mainnet.go index 1622edf923..646b8b3460 100644 --- a/zetaclient/config/config_mainnet.go +++ b/zetaclient/config/config_mainnet.go @@ -1,10 +1,11 @@ -//go:build !PRIVNET && !TESTNET -// +build !PRIVNET,!TESTNET +//go:build !PRIVNET && !TESTNET && !MOCK_MAINNET +// +build !PRIVNET,!TESTNET,!MOCK_MAINNET package config import ( "github.com/btcsuite/btcd/chaincfg" + "github.com/zeta-chain/zetacore/common" ) const ( @@ -21,9 +22,6 @@ const ( // Constants // #nosec G101 const ( - DevEthBlockTime = 2 - - // to catch up: MaxBlocksPerPeriod = 100 ) @@ -42,13 +40,24 @@ func GetERC20CustodyABI() string { } var ( - BitconNetParams = &chaincfg.RegressionNetParams + BitconNetParams = &chaincfg.MainNetParams ) func New() Config { return Config{ - EVMChainConfigs: nil, - BitcoinConfig: nil, - ChainsEnabled: nil, + EVMChainConfigs: evmChainConfigs, + BitcoinConfig: BitcoinConfig, + ChainsEnabled: []common.Chain{}, } } + +var BitcoinConfig = &BTCConfig{} + +var evmChainConfigs = map[int64]*EVMConfig{ + common.EthChain().ChainId: { + Chain: common.EthChain(), + }, + common.BscMainnetChain().ChainId: { + Chain: common.BscMainnetChain(), + }, +} diff --git a/zetaclient/config/config_mock_mainnet.go b/zetaclient/config/config_mock_mainnet.go new file mode 100644 index 0000000000..fe7195d1cd --- /dev/null +++ b/zetaclient/config/config_mock_mainnet.go @@ -0,0 +1,63 @@ +//go:build MOCK_MAINNET +// +build MOCK_MAINNET + +package config + +import ( + "github.com/btcsuite/btcd/chaincfg" + "github.com/zeta-chain/zetacore/common" +) + +const ( + BtcConfirmationCount = 1 + DevEthConfirmationCount = 2 +) + +const ( + // #nosec G101 + TssTestPrivkey = "2082bc9775d6ee5a05ef221a9d1c00b3cc3ecb274a4317acc0a182bc1e05d1bb" + TssTestAddress = "0xE80B6467863EbF8865092544f441da8fD3cF6074" +) + +// Constants +// #nosec G101 +const ( + MaxBlocksPerPeriod = 100 +) + +const ( + ConnectorAbiString = ` +[{"inputs":[{"internalType":"address","name":"_zetaTokenAddress","type":"address"},{"internalType":"address","name":"_tssAddress","type":"address"},{"internalType":"address","name":"_tssAddressUpdater","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"originSenderAddress","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"destinationAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"ZetaReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"originSenderAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"ZetaReverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"originSenderAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"zetaParams","type":"bytes"}],"name":"ZetaSent","type":"event"},{"inputs":[],"name":"getLockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"originSenderAddress","type":"bytes"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"onReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"originSenderAddress","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"onRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTssAddressUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"zetaParams","type":"bytes"}],"internalType":"struct ZetaInterfaces.SendInput","name":"input","type":"tuple"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tssAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tssAddressUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tssAddress","type":"address"}],"name":"updateTssAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"zetaToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]` + ERC20CustodyAbiString = ` +[{"inputs":[{"internalType":"address","name":"_TSSAddress","type":"address"},{"internalType":"address","name":"_TSSAddressUpdater","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidTSSUpdater","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"Unwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"TSSAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TSSAddressUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTSSAddressUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"unwhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateTSSAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]` +) + +func GetConnectorABI() string { + return ConnectorAbiString +} +func GetERC20CustodyABI() string { + return ERC20CustodyAbiString +} + +var ( + BitconNetParams = &chaincfg.MainNetParams +) + +func New() Config { + return Config{ + EVMChainConfigs: evmChainConfigs, + BitcoinConfig: BitcoinConfig, + ChainsEnabled: []common.Chain{}, + } +} + +var BitcoinConfig = &BTCConfig{} + +var evmChainConfigs = map[int64]*EVMConfig{ + common.EthChain().ChainId: { + Chain: common.EthChain(), + }, + common.BscMainnetChain().ChainId: { + Chain: common.BscMainnetChain(), + }, +} diff --git a/zetaclient/config/config_privnet.go b/zetaclient/config/config_privnet.go index 90776a1561..d801c8dbd7 100644 --- a/zetaclient/config/config_privnet.go +++ b/zetaclient/config/config_privnet.go @@ -59,7 +59,4 @@ var evmChainConfigs = map[int64]*EVMConfig{ Chain: common.GoerliChain(), Endpoint: "http://eth:8545", }, - common.ZetaChain().ChainId: { - Chain: common.ZetaChain(), - }, } diff --git a/zetaclient/config/config_testnet.go b/zetaclient/config/config_testnet.go index 3524049268..5a3bf948e0 100644 --- a/zetaclient/config/config_testnet.go +++ b/zetaclient/config/config_testnet.go @@ -73,7 +73,4 @@ var evmChainsConfig = map[int64]*EVMConfig{ Chain: common.MumbaiChain(), Endpoint: "", }, - common.ZetaChain().ChainId: { - Chain: common.ZetaChain(), - }, } diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 7162091f3d..16b0ae9645 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -16,11 +16,12 @@ import ( "sync/atomic" "time" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "cosmossdk.io/math" + "github.com/ethereum/go-ethereum/rlp" + lru "github.com/hashicorp/golang-lru" "github.com/pkg/errors" + "gorm.io/driver/sqlite" + "gorm.io/gorm" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -90,6 +91,8 @@ type EVMChainClient struct { cfg *config.Config params observertypes.CoreParams ts *TelemetryServer + + BlockCache *lru.Cache } var _ ChainClient = (*EVMChainClient)(nil) @@ -134,6 +137,12 @@ func NewEVMChainClient(bridge *ZetaCoreBridge, tss TSSSigner, dbpath string, met } ob.EvmClient = client + ob.BlockCache, err = lru.New(1000) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("failed to create block cache") + return nil, err + } + if ob.chain.IsKlaytnChain() { kclient, err := Dial(evmCfg.Endpoint) if err != nil { @@ -445,6 +454,13 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co return false, false, nil } +// The lowest nonce we observe outTx for each chain +var lowestOutTxNonceToObserve = map[int64]uint64{ + 5: 70000, // Goerli + 97: 95000, // BSC testnet + 80001: 120000, // Mumbai +} + // FIXME: there's a chance that a txhash in OutTxChan may not deliver when Stop() is called // observeOutTx periodically checks all the txhash in potential outbound txs func (ob *EVMChainClient) observeOutTx() { @@ -473,8 +489,12 @@ func (ob *EVMChainClient) observeOutTx() { }) outTimeout := time.After(time.Duration(timeoutNonce) * time.Second) TRACKERLOOP: + // Skip old gabbage trackers as we spent too much time on querying them for _, tracker := range trackers { nonceInt := tracker.Nonce + if nonceInt < lowestOutTxNonceToObserve[ob.chain.ChainId] { + continue + } TXHASHLOOP: for _, txHash := range tracker.HashList { //inTimeout := time.After(3000 * time.Millisecond) @@ -698,14 +718,16 @@ func (ob *EVMChainClient) observeInTX() error { continue } destAddr := clienttypes.BytesToEthHex(event.DestinationAddress) - cfgDest, found := ob.cfg.GetEVMConfig(destChain.ChainId) - if !found { - ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) - continue - } - if strings.EqualFold(destAddr, cfgDest.ZetaTokenContractAddress) { - ob.logger.ExternalChainWatcher.Warn().Msgf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) - continue + if destChain.IsExternalChain() { + cfgDest, found := ob.cfg.GetEVMConfig(destChain.ChainId) + if !found { + ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) + continue + } + if strings.EqualFold(destAddr, cfgDest.ZetaTokenContractAddress) { + ob.logger.ExternalChainWatcher.Warn().Msgf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) + continue + } } zetaHash, err := ob.zetaClient.PostSend( event.ZetaTxSenderAddress.Hex(), @@ -764,8 +786,22 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) continue } + + // get the sender of the event's transaction + tx, _, err := ob.EvmClient.TransactionByHash(context.Background(), event.Raw.TxHash) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) + continue + } + signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) + sender, err := signer.Sender(tx) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) + continue + } + zetaHash, err := ob.zetaClient.PostSend( - "", + sender.Hex(), ob.chain.ChainId, "", clienttypes.BytesToEthHex(event.Recipient), @@ -783,7 +819,7 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") continue } - ob.logger.ExternalChainWatcher.Info().Msgf("ZRC20Cusotdy Deposited event detected and reported: PostSend zeta tx: %s", zetaHash) + ob.logger.ExternalChainWatcher.Info().Msgf("ZRC20Custody Deposited event detected and reported: PostSend zeta tx: %s", zetaHash) } }() @@ -799,12 +835,29 @@ func (ob *EVMChainClient) observeInTX() error { if !ob.chain.IsKlaytnChain() { for bn := startBlock; bn <= toBlock; bn++ { //block, err := ob.EvmClient.BlockByNumber(context.Background(), big.NewInt(int64(bn))) - block, err := ob.EvmClient.BlockByNumber(context.Background(), big.NewInt(bn)) + block, err := ob.GetBlockByNumberCached(bn) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("error getting block: %d", bn) continue } - //ob.logger.ExternalChainWatcher.Debug().Msgf("block %d: num txs: %d", bn, len(block.Transactions())) + _ = ob.BlockCache.Add(block.Hash(), block) + headerRLP, err := rlp.EncodeToBytes(block.Header()) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("error encoding block header: %d", bn) + continue + } + + _, err = ob.zetaClient.PostAddBlockHeader( + ob.chain.ChainId, + block.Hash().Bytes(), + block.Number().Int64(), + common.NewEthereumHeader(headerRLP), + ) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("error posting block header: %d", bn) + continue + } + for _, tx := range block.Transactions() { if tx.To() == nil { continue @@ -813,6 +866,7 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation!: %s", tx.Hash().Hex()) continue } + if *tx.To() == tssAddress { receipt, err := ob.EvmClient.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { @@ -834,6 +888,7 @@ func (ob *EVMChainClient) observeInTX() error { continue } } + zetaHash, err := ob.ReportTokenSentToTSS(tx.Hash(), tx.Value(), receipt, from, tx.Data()) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") @@ -931,7 +986,7 @@ func (ob *EVMChainClient) WatchGasPrice() { height, _ := ob.zetaClient.GetBlockHeight() ob.logger.WatchGasPrice.Error().Err(err).Msgf("PostGasPrice error at zeta block : %d ", height) } - ticker.UpdateInterval(ob.GetCoreParams().InTxTicker, ob.logger.WatchGasPrice) + ticker.UpdateInterval(ob.GetCoreParams().GasPriceTicker, ob.logger.WatchGasPrice) case <-ob.stop: ob.logger.WatchGasPrice.Info().Msg("WatchGasPrice stopped") return @@ -1129,3 +1184,15 @@ func (ob *EVMChainClient) GetTxID(nonce uint64) string { tssAddr := ob.Tss.EVMAddress().String() return fmt.Sprintf("%d-%s-%d", ob.chain.ChainId, tssAddr, nonce) } + +func (ob *EVMChainClient) GetBlockByNumberCached(blockNumber int64) (*ethtypes.Block, error) { + if block, ok := ob.BlockCache.Get(blockNumber); ok { + return block.(*ethtypes.Block), nil + } + block, err := ob.EvmClient.BlockByNumber(context.Background(), big.NewInt(blockNumber)) + if err != nil { + return nil, err + } + ob.BlockCache.Add(blockNumber, block) + return block, nil +} diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index 6f9984e3e0..cb321801af 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -494,7 +494,7 @@ func (signer *EVMSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out log.Warn().Err(err).Msgf("OutTx Broadcast error") retry, report := HandleBroadcastError(err, strconv.FormatUint(send.GetCurrentOutTxParam().OutboundTxTssNonce, 10), toChain.String(), outTxHash) if report { - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash) + zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash, nil, "", -1) if err != nil { logger.Err(err).Msgf("Unable to add to tracker on ZetaCore: nonce %d chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) } @@ -507,7 +507,7 @@ func (signer *EVMSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out continue } logger.Info().Msgf("Broadcast success: nonce %d to chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash) + zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash, nil, "", -1) if err != nil { logger.Err(err).Msgf("Unable to add to tracker on ZetaCore: nonce %d chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) } diff --git a/zetaclient/query.go b/zetaclient/query.go index 8e4ab27329..283f2410fe 100644 --- a/zetaclient/query.go +++ b/zetaclient/query.go @@ -259,7 +259,7 @@ func (b *ZetaCoreBridge) GetAllOutTxTrackerByChain(chain common.Chain, order Ord Pagination: &query.PageRequest{ Key: nil, Offset: 0, - Limit: 1000, + Limit: 2000, CountTotal: false, Reverse: false, }, @@ -289,6 +289,15 @@ func (b *ZetaCoreBridge) GetClientParams(chainID int64) (zetaObserverTypes.Query return *resp, nil } +func (b *ZetaCoreBridge) GetSupportedChains() ([]*common.Chain, error) { + client := zetaObserverTypes.NewQueryClient(b.grpcConn) + resp, err := client.SupportedChains(context.Background(), &zetaObserverTypes.QuerySupportedChains{}) + if err != nil { + return nil, err + } + return resp.GetChains(), nil +} + func (b *ZetaCoreBridge) GetPendingNonces() (*types.QueryAllPendingNoncesResponse, error) { client := types.NewQueryClient(b.grpcConn) resp, err := client.PendingNoncesAll(context.Background(), &types.QueryAllPendingNoncesRequest{}) @@ -297,3 +306,18 @@ func (b *ZetaCoreBridge) GetPendingNonces() (*types.QueryAllPendingNoncesRespons } return resp, nil } + +func (b *ZetaCoreBridge) Prove(blockHash string, txHash string, txIndex int64, proof *common.Proof, chainID uint64) (bool, error) { + client := zetaObserverTypes.NewQueryClient(b.grpcConn) + resp, err := client.Prove(context.Background(), &zetaObserverTypes.QueryProveRequest{ + BlockHash: blockHash, + TxIndex: txIndex, + Proof: proof, + ChainId: chainID, + TxHash: txHash, + }) + if err != nil { + return false, err + } + return resp.Valid, nil +} diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index d0e540017d..d171c74ff9 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -173,6 +173,7 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, chain *common.Chain) digestBase64[i] = base64.StdEncoding.EncodeToString(digest) } keysignReq := keysign.NewRequest(tssPubkey, digestBase64, int64(height), nil, "0.14.0") + ksRes, err := tss.Server.KeySign(keysignReq) if err != nil { log.Warn().Err(err).Msg("keysign fail") diff --git a/zetaclient/tx.go b/zetaclient/tx.go index ea0335ee01..e88e469044 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -20,11 +20,12 @@ const ( PostGasPriceGasLimit = 1_500_000 AddTxHashToOutTxTrackerGasLimit = 200_000 PostNonceGasLimit = 200_000 - PostSendEVMGasLimit = 1_000_000 // likely emit a lot of logs, so costly + PostSendEVMGasLimit = 1_500_000 // likely emit a lot of logs, so costly PostSendNonEVMGasLimit = 1_000_000 PostReceiveConfirmationGasLimit = 200_000 PostBlameDataGasLimit = 200_000 DefaultGasLimit = 200_000 + PostProveOutboundTxGasLimit = 400_000 DefaultRetryCount = 5 DefaultRetryInterval = 5 ) @@ -53,9 +54,9 @@ func (b *ZetaCoreBridge) PostGasPrice(chain common.Chain, gasPrice uint64, suppl return "", fmt.Errorf("post gasprice failed after %d retries", DefaultRetryInterval) } -func (b *ZetaCoreBridge) AddTxHashToOutTxTracker(chainID int64, nonce uint64, txHash string) (string, error) { +func (b *ZetaCoreBridge) AddTxHashToOutTxTracker(chainID int64, nonce uint64, txHash string, proof *common.Proof, blockHash string, txIndex int64) (string, error) { signerAddress := b.keys.GetOperatorAddress().String() - msg := types.NewMsgAddToOutTxTracker(signerAddress, chainID, nonce, txHash) + msg := types.NewMsgAddToOutTxTracker(signerAddress, chainID, nonce, txHash, proof, blockHash, txIndex) authzMsg, authzSigner := b.WrapMessageWithAuthz(msg) zetaTxHash, err := b.Broadcast(AddTxHashToOutTxTrackerGasLimit, authzMsg, authzSigner) if err != nil { @@ -189,3 +190,20 @@ func (b *ZetaCoreBridge) PostBlameData(blame *blame.Blame, chainID int64, index } return "", fmt.Errorf("post blame data failed after %d retries", DefaultRetryCount) } + +func (b *ZetaCoreBridge) PostAddBlockHeader(chainID int64, txhash []byte, height int64, header common.HeaderData) (string, error) { + signerAddress := b.keys.GetOperatorAddress().String() + msg := observerTypes.NewMsgAddBlockHeader(signerAddress, chainID, txhash, height, header) + authzMsg, authzSigner := b.WrapMessageWithAuthz(msg) + + var gasLimit uint64 = DefaultGasLimit + for i := 0; i < DefaultRetryCount; i++ { + zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) + if err == nil { + return zetaTxHash, nil + } + b.logger.Error().Err(err).Msgf("PostAddBlockHeader broadcast fail | Retry count : %d", i+1) + time.Sleep(DefaultRetryInterval * time.Second) + } + return "", fmt.Errorf("post add block header failed after %d retries", DefaultRetryCount) +} diff --git a/zetaclient/zetabridge.go b/zetaclient/zetabridge.go index 64a7a565bd..ab56d9d715 100644 --- a/zetaclient/zetabridge.go +++ b/zetaclient/zetabridge.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/zeta-chain/zetacore/common" "sync" @@ -32,6 +34,7 @@ import ( //"strconv" //"strings" + "github.com/zeta-chain/zetacore/app" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/config" @@ -46,6 +49,7 @@ type ZetaCoreBridge struct { grpcConn *grpc.ClientConn httpClient *retryablehttp.Client cfg config.ClientConfiguration + encodingCfg params.EncodingConfig keys *Keys broadcastLock *sync.RWMutex zetaChainID string @@ -92,6 +96,7 @@ func NewZetaCoreBridge(k *Keys, chainIP string, signerName string, chainID strin accountNumber: accountsMap, seqNumber: seqMap, cfg: cfg, + encodingCfg: app.MakeEncodingConfig(), keys: k, broadcastLock: &sync.RWMutex{}, lastOutTxReportTime: map[string]time.Time{}, @@ -171,33 +176,40 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err if err != nil { return err } - newChains := make([]common.Chain, len(coreParams)) + newEVMParams := make(map[int64]*observertypes.CoreParams) var newBTCParams *observertypes.CoreParams // check and update core params for each chain - for i, params := range coreParams { + for _, params := range coreParams { err := config.ValidateCoreParams(params) if err != nil { - b.logger.Err(err).Msgf("Invalid core params for chain %s", common.GetChainFromChainID(params.ChainId).ChainName) + b.logger.Debug().Err(err).Msgf("Invalid core params for chain %s", common.GetChainFromChainID(params.ChainId).ChainName) } - newChains[i] = *common.GetChainFromChainID(params.ChainId) if common.IsBitcoinChain(params.ChainId) { newBTCParams = params } else { newEVMParams[params.ChainId] = params } } + + chains, err := b.GetSupportedChains() + if err != nil { + return err + } + newChains := make([]common.Chain, len(chains)) + for i, chain := range chains { + newChains[i] = *chain + } keyGen, err := b.GetKeyGen() if err != nil { b.logger.Info().Msg("Unable to fetch keygen from zetacore") } cfg.UpdateCoreParams(keyGen, newChains, newEVMParams, newBTCParams, init, b.logger) - cfg.Keygen = *keyGen tss, err := b.GetCurrentTss() if err != nil { - b.logger.Error().Err(err).Msg("Unable to fetch TSS from zetacore") + b.logger.Debug().Err(err).Msg("Unable to fetch TSS from zetacore") } else { cfg.CurrentTssPubkey = tss.GetTssPubkey() }