From 91ce0705df37554496dc2a5a552b3cbdff6a8e18 Mon Sep 17 00:00:00 2001 From: d1onys1us <13951458+d1onys1us@users.noreply.github.com> Date: Wed, 1 May 2024 15:49:37 -0400 Subject: [PATCH] add taiko-client at d2e9667 --- .../taiko-client/.github/workflows/docker.yml | 49 + .../.github/workflows/lint-pr.yml | 14 + .../.github/workflows/openai-review.yml | 36 + .../.github/workflows/release-please.yml | 12 + .../.github/workflows/swagger.yml | 61 + .../taiko-client/.github/workflows/test.yml | 97 + packages/taiko-client/.gitignore | 29 + packages/taiko-client/.golangci.yml | 91 + .../.release-please-manifest.json | 3 + packages/taiko-client/.swaggo | 2 + packages/taiko-client/CHANGELOG.md | 540 +++ packages/taiko-client/Dockerfile | 17 + packages/taiko-client/LICENSE.md | 21 + packages/taiko-client/Makefile | 42 + packages/taiko-client/README.md | 59 + packages/taiko-client/bindings/.githead | 1 + .../bindings/encoding/custom_error.go | 100 + .../bindings/encoding/custom_error_test.go | 42 + .../taiko-client/bindings/encoding/input.go | 416 ++ .../bindings/encoding/input_test.go | 101 + .../taiko-client/bindings/encoding/struct.go | 112 + .../bindings/encoding/struct_test.go | 72 + .../bindings/gen_address_manager.go | 1935 ++++++++ .../bindings/gen_assignment_hook.go | 2110 +++++++++ .../bindings/gen_guardian_prover.go | 2489 ++++++++++ .../bindings/gen_guardian_verifier.go | 1757 +++++++ .../bindings/gen_lib_proposing.go | 337 ++ .../taiko-client/bindings/gen_lib_proving.go | 611 +++ .../taiko-client/bindings/gen_lib_utils.go | 181 + .../bindings/gen_lib_verifying.go | 471 ++ .../taiko-client/bindings/gen_sgx_verifier.go | 2346 ++++++++++ .../taiko-client/bindings/gen_taiko_l1.go | 4097 +++++++++++++++++ .../taiko-client/bindings/gen_taiko_l2.go | 2267 +++++++++ .../taiko-client/bindings/gen_taiko_token.go | 3238 +++++++++++++ .../bindings/gen_tier_provider.go | 1831 ++++++++ packages/taiko-client/cmd/flags/common.go | 181 + packages/taiko-client/cmd/flags/driver.go | 62 + packages/taiko-client/cmd/flags/proposer.go | 169 + packages/taiko-client/cmd/flags/prover.go | 244 + packages/taiko-client/cmd/flags/txmgr.go | 103 + packages/taiko-client/cmd/logger/logger.go | 27 + packages/taiko-client/cmd/main.go | 57 + .../taiko-client/cmd/utils/sub_command.go | 63 + packages/taiko-client/codecov.yml | 6 + packages/taiko-client/docs/docs.go | 170 + packages/taiko-client/docs/swagger.json | 143 + packages/taiko-client/docs/swagger.yaml | 93 + .../anchor_tx_constructor.go | 143 + .../anchor_tx_constructor_test.go | 109 + .../beaconsync/progress_tracker.go | 260 ++ .../beaconsync/progress_tracker_test.go | 90 + .../driver/chain_syncer/beaconsync/syncer.go | 124 + .../driver/chain_syncer/blob/syncer.go | 677 +++ .../driver/chain_syncer/blob/syncer_test.go | 242 + .../driver/chain_syncer/chain_syncer.go | 211 + .../driver/chain_syncer/chain_syncer_test.go | 161 + packages/taiko-client/driver/config.go | 76 + packages/taiko-client/driver/config_test.go | 98 + packages/taiko-client/driver/driver.go | 259 ++ packages/taiko-client/driver/driver_test.go | 340 ++ .../driver/signer/fixed_k_signer.go | 87 + .../driver/signer/fixed_k_signer_test.go | 46 + .../taiko-client/driver/state/l1_current.go | 61 + .../driver/state/l1_current_test.go | 37 + packages/taiko-client/driver/state/state.go | 207 + .../taiko-client/driver/state/state_test.go | 80 + .../driver/txlist_fetcher/blob.go | 67 + .../driver/txlist_fetcher/calldata.go | 27 + .../driver/txlist_fetcher/interface.go | 14 + packages/taiko-client/go.mod | 257 ++ packages/taiko-client/go.sum | 1690 +++++++ packages/taiko-client/index.html | 29 + .../taiko-client/integration_test/README.md | 23 + .../integration_test/deploy_l1_contract.sh | 19 + .../integration_test/entrypoint.sh | 52 + .../taiko-client/integration_test/l1_env.sh | 42 + .../taiko-client/integration_test/test_env.sh | 49 + .../taiko-client/internal/docker/.gitignore | 1 + .../internal/docker/docker_env.sh | 33 + .../internal/docker/nodes/docker-compose.yml | 67 + .../internal/docker/nodes/jwt.hex | 1 + .../taiko-client/internal/docker/start.sh | 14 + packages/taiko-client/internal/docker/stop.sh | 9 + .../taiko-client/internal/metrics/metrics.go | 90 + .../taiko-client/internal/testutils/helper.go | 366 ++ .../internal/testutils/interfaces.go | 17 + .../taiko-client/internal/testutils/suite.go | 190 + .../taiko-client/internal/utils/test_utils.go | 16 + .../taiko-client/internal/utils/util_test.go | 49 + packages/taiko-client/internal/utils/utils.go | 162 + .../taiko-client/internal/version/version.go | 24 + .../chain_iterator/block_batch_iterator.go | 283 ++ .../block_batch_iterator_test.go | 268 ++ .../event_iterator/block_proposed_iterator.go | 144 + packages/taiko-client/pkg/error.go | 12 + packages/taiko-client/pkg/flags/config.go | 31 + packages/taiko-client/pkg/jwt/jwt.go | 39 + packages/taiko-client/pkg/jwt/jwt_test.go | 41 + packages/taiko-client/pkg/rpc/beaconclient.go | 109 + .../taiko-client/pkg/rpc/blob_datasource.go | 111 + packages/taiko-client/pkg/rpc/blob_tx.go | 137 + packages/taiko-client/pkg/rpc/blob_tx_test.go | 74 + packages/taiko-client/pkg/rpc/client.go | 154 + packages/taiko-client/pkg/rpc/client_test.go | 46 + packages/taiko-client/pkg/rpc/dial.go | 74 + packages/taiko-client/pkg/rpc/dial_test.go | 81 + packages/taiko-client/pkg/rpc/engine.go | 130 + packages/taiko-client/pkg/rpc/engine_test.go | 41 + packages/taiko-client/pkg/rpc/ethclient.go | 420 ++ .../taiko-client/pkg/rpc/ethclient_test.go | 170 + packages/taiko-client/pkg/rpc/fallback.go | 29 + .../taiko-client/pkg/rpc/fallback_test.go | 13 + packages/taiko-client/pkg/rpc/methods.go | 726 +++ packages/taiko-client/pkg/rpc/methods_test.go | 126 + packages/taiko-client/pkg/rpc/subscription.go | 129 + .../taiko-client/pkg/rpc/subscription_test.go | 53 + packages/taiko-client/pkg/rpc/utils.go | 346 ++ packages/taiko-client/pkg/rpc/utils_test.go | 59 + .../pkg/txlist_validator/tx_list_validator.go | 56 + .../tx_list_validator_test.go | 111 + packages/taiko-client/proposer/config.go | 136 + packages/taiko-client/proposer/config_test.go | 154 + packages/taiko-client/proposer/proposer.go | 445 ++ .../taiko-client/proposer/proposer_test.go | 382 ++ .../prover_selector/eth_fee_eoa_selector.go | 283 ++ .../eth_fee_eoa_selector_test.go | 69 + .../proposer/prover_selector/interface.go | 20 + .../proposer/transaction_builder/blob.go | 142 + .../proposer/transaction_builder/calldata.go | 122 + .../transaction_builder/calldata_test.go | 19 + .../proposer/transaction_builder/common.go | 26 + .../transaction_builder/common_test.go | 80 + .../proposer/transaction_builder/interface.go | 19 + .../anchor_tx_validator.go | 77 + .../anchor_tx_validator_test.go | 85 + packages/taiko-client/prover/config.go | 214 + packages/taiko-client/prover/config_test.go | 141 + .../event_handler/assignment_expired.go | 83 + .../prover/event_handler/block_proposed.go | 415 ++ .../event_handler/block_proposed_test.go | 66 + .../prover/event_handler/block_verified.go | 25 + .../event_handler/block_verified_test.go | 22 + .../prover/event_handler/interface.go | 36 + .../event_handler/transition_contested.go | 111 + .../prover/event_handler/transition_proved.go | 92 + .../event_handler/transition_proved_test.go | 133 + .../taiko-client/prover/event_handler/util.go | 148 + .../prover/event_handler/util_test.go | 52 + packages/taiko-client/prover/guardian.go | 58 + .../guardian_prover.go | 252 + .../guardian_prover_heartbeater/interface.go | 30 + packages/taiko-client/prover/init.go | 245 + packages/taiko-client/prover/init_test.go | 44 + .../prover/proof_producer/dummy_producer.go | 31 + .../proof_producer/dummy_producer_test.go | 50 + .../proof_producer/guardian_producer.go | 60 + .../proof_producer/guardian_producer_test.go | 90 + .../proof_producer/optimistic_producer.go | 39 + .../optimistic_producer_test.go | 93 + .../prover/proof_producer/proof_producer.go | 69 + .../prover/proof_producer/sgx_producer.go | 214 + .../proof_producer/sgx_producer_test.go | 51 + .../prover/proof_submitter/interface.go | 31 + .../prover/proof_submitter/proof_contester.go | 124 + .../proof_submitter/proof_contester_test.go | 24 + .../prover/proof_submitter/proof_submitter.go | 197 + .../proof_submitter/proof_submitter_test.go | 212 + .../proof_submitter/transaction/builder.go | 94 + .../transaction/builder_test.go | 19 + .../proof_submitter/transaction/sender.go | 163 + .../transaction/sender_test.go | 100 + packages/taiko-client/prover/prover.go | 474 ++ packages/taiko-client/prover/prover_test.go | 548 +++ packages/taiko-client/prover/server/api.go | 285 ++ .../taiko-client/prover/server/api_test.go | 50 + packages/taiko-client/prover/server/server.go | 146 + .../taiko-client/prover/server/server_test.go | 127 + .../taiko-client/prover/shared_state/state.go | 54 + .../prover/shared_state/state_test.go | 44 + .../taiko-client/release-please-config.json | 11 + packages/taiko-client/scripts/common.sh | 44 + packages/taiko-client/scripts/gen_bindings.sh | 80 + .../taiko-client/scripts/gen_swagger_json.sh | 3 + 183 files changed, 45287 insertions(+) create mode 100644 packages/taiko-client/.github/workflows/docker.yml create mode 100644 packages/taiko-client/.github/workflows/lint-pr.yml create mode 100644 packages/taiko-client/.github/workflows/openai-review.yml create mode 100644 packages/taiko-client/.github/workflows/release-please.yml create mode 100644 packages/taiko-client/.github/workflows/swagger.yml create mode 100644 packages/taiko-client/.github/workflows/test.yml create mode 100644 packages/taiko-client/.gitignore create mode 100644 packages/taiko-client/.golangci.yml create mode 100644 packages/taiko-client/.release-please-manifest.json create mode 100644 packages/taiko-client/.swaggo create mode 100644 packages/taiko-client/CHANGELOG.md create mode 100644 packages/taiko-client/Dockerfile create mode 100644 packages/taiko-client/LICENSE.md create mode 100644 packages/taiko-client/Makefile create mode 100644 packages/taiko-client/README.md create mode 100644 packages/taiko-client/bindings/.githead create mode 100644 packages/taiko-client/bindings/encoding/custom_error.go create mode 100644 packages/taiko-client/bindings/encoding/custom_error_test.go create mode 100644 packages/taiko-client/bindings/encoding/input.go create mode 100644 packages/taiko-client/bindings/encoding/input_test.go create mode 100644 packages/taiko-client/bindings/encoding/struct.go create mode 100644 packages/taiko-client/bindings/encoding/struct_test.go create mode 100644 packages/taiko-client/bindings/gen_address_manager.go create mode 100644 packages/taiko-client/bindings/gen_assignment_hook.go create mode 100644 packages/taiko-client/bindings/gen_guardian_prover.go create mode 100644 packages/taiko-client/bindings/gen_guardian_verifier.go create mode 100644 packages/taiko-client/bindings/gen_lib_proposing.go create mode 100644 packages/taiko-client/bindings/gen_lib_proving.go create mode 100644 packages/taiko-client/bindings/gen_lib_utils.go create mode 100644 packages/taiko-client/bindings/gen_lib_verifying.go create mode 100644 packages/taiko-client/bindings/gen_sgx_verifier.go create mode 100644 packages/taiko-client/bindings/gen_taiko_l1.go create mode 100644 packages/taiko-client/bindings/gen_taiko_l2.go create mode 100644 packages/taiko-client/bindings/gen_taiko_token.go create mode 100644 packages/taiko-client/bindings/gen_tier_provider.go create mode 100644 packages/taiko-client/cmd/flags/common.go create mode 100644 packages/taiko-client/cmd/flags/driver.go create mode 100644 packages/taiko-client/cmd/flags/proposer.go create mode 100644 packages/taiko-client/cmd/flags/prover.go create mode 100644 packages/taiko-client/cmd/flags/txmgr.go create mode 100644 packages/taiko-client/cmd/logger/logger.go create mode 100644 packages/taiko-client/cmd/main.go create mode 100644 packages/taiko-client/cmd/utils/sub_command.go create mode 100644 packages/taiko-client/codecov.yml create mode 100644 packages/taiko-client/docs/docs.go create mode 100644 packages/taiko-client/docs/swagger.json create mode 100644 packages/taiko-client/docs/swagger.yaml create mode 100644 packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor.go create mode 100644 packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor_test.go create mode 100644 packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go create mode 100644 packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go create mode 100644 packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go create mode 100644 packages/taiko-client/driver/chain_syncer/blob/syncer.go create mode 100644 packages/taiko-client/driver/chain_syncer/blob/syncer_test.go create mode 100644 packages/taiko-client/driver/chain_syncer/chain_syncer.go create mode 100644 packages/taiko-client/driver/chain_syncer/chain_syncer_test.go create mode 100644 packages/taiko-client/driver/config.go create mode 100644 packages/taiko-client/driver/config_test.go create mode 100644 packages/taiko-client/driver/driver.go create mode 100644 packages/taiko-client/driver/driver_test.go create mode 100644 packages/taiko-client/driver/signer/fixed_k_signer.go create mode 100644 packages/taiko-client/driver/signer/fixed_k_signer_test.go create mode 100644 packages/taiko-client/driver/state/l1_current.go create mode 100644 packages/taiko-client/driver/state/l1_current_test.go create mode 100644 packages/taiko-client/driver/state/state.go create mode 100644 packages/taiko-client/driver/state/state_test.go create mode 100644 packages/taiko-client/driver/txlist_fetcher/blob.go create mode 100644 packages/taiko-client/driver/txlist_fetcher/calldata.go create mode 100644 packages/taiko-client/driver/txlist_fetcher/interface.go create mode 100644 packages/taiko-client/go.mod create mode 100644 packages/taiko-client/go.sum create mode 100644 packages/taiko-client/index.html create mode 100644 packages/taiko-client/integration_test/README.md create mode 100755 packages/taiko-client/integration_test/deploy_l1_contract.sh create mode 100755 packages/taiko-client/integration_test/entrypoint.sh create mode 100755 packages/taiko-client/integration_test/l1_env.sh create mode 100755 packages/taiko-client/integration_test/test_env.sh create mode 100644 packages/taiko-client/internal/docker/.gitignore create mode 100755 packages/taiko-client/internal/docker/docker_env.sh create mode 100644 packages/taiko-client/internal/docker/nodes/docker-compose.yml create mode 100644 packages/taiko-client/internal/docker/nodes/jwt.hex create mode 100755 packages/taiko-client/internal/docker/start.sh create mode 100755 packages/taiko-client/internal/docker/stop.sh create mode 100644 packages/taiko-client/internal/metrics/metrics.go create mode 100644 packages/taiko-client/internal/testutils/helper.go create mode 100644 packages/taiko-client/internal/testutils/interfaces.go create mode 100644 packages/taiko-client/internal/testutils/suite.go create mode 100644 packages/taiko-client/internal/utils/test_utils.go create mode 100644 packages/taiko-client/internal/utils/util_test.go create mode 100644 packages/taiko-client/internal/utils/utils.go create mode 100644 packages/taiko-client/internal/version/version.go create mode 100644 packages/taiko-client/pkg/chain_iterator/block_batch_iterator.go create mode 100644 packages/taiko-client/pkg/chain_iterator/block_batch_iterator_test.go create mode 100644 packages/taiko-client/pkg/chain_iterator/event_iterator/block_proposed_iterator.go create mode 100644 packages/taiko-client/pkg/error.go create mode 100644 packages/taiko-client/pkg/flags/config.go create mode 100644 packages/taiko-client/pkg/jwt/jwt.go create mode 100644 packages/taiko-client/pkg/jwt/jwt_test.go create mode 100644 packages/taiko-client/pkg/rpc/beaconclient.go create mode 100644 packages/taiko-client/pkg/rpc/blob_datasource.go create mode 100644 packages/taiko-client/pkg/rpc/blob_tx.go create mode 100644 packages/taiko-client/pkg/rpc/blob_tx_test.go create mode 100644 packages/taiko-client/pkg/rpc/client.go create mode 100644 packages/taiko-client/pkg/rpc/client_test.go create mode 100644 packages/taiko-client/pkg/rpc/dial.go create mode 100644 packages/taiko-client/pkg/rpc/dial_test.go create mode 100644 packages/taiko-client/pkg/rpc/engine.go create mode 100644 packages/taiko-client/pkg/rpc/engine_test.go create mode 100644 packages/taiko-client/pkg/rpc/ethclient.go create mode 100644 packages/taiko-client/pkg/rpc/ethclient_test.go create mode 100644 packages/taiko-client/pkg/rpc/fallback.go create mode 100644 packages/taiko-client/pkg/rpc/fallback_test.go create mode 100644 packages/taiko-client/pkg/rpc/methods.go create mode 100644 packages/taiko-client/pkg/rpc/methods_test.go create mode 100644 packages/taiko-client/pkg/rpc/subscription.go create mode 100644 packages/taiko-client/pkg/rpc/subscription_test.go create mode 100644 packages/taiko-client/pkg/rpc/utils.go create mode 100644 packages/taiko-client/pkg/rpc/utils_test.go create mode 100644 packages/taiko-client/pkg/txlist_validator/tx_list_validator.go create mode 100644 packages/taiko-client/pkg/txlist_validator/tx_list_validator_test.go create mode 100644 packages/taiko-client/proposer/config.go create mode 100644 packages/taiko-client/proposer/config_test.go create mode 100644 packages/taiko-client/proposer/proposer.go create mode 100644 packages/taiko-client/proposer/proposer_test.go create mode 100644 packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector.go create mode 100644 packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector_test.go create mode 100644 packages/taiko-client/proposer/prover_selector/interface.go create mode 100644 packages/taiko-client/proposer/transaction_builder/blob.go create mode 100644 packages/taiko-client/proposer/transaction_builder/calldata.go create mode 100644 packages/taiko-client/proposer/transaction_builder/calldata_test.go create mode 100644 packages/taiko-client/proposer/transaction_builder/common.go create mode 100644 packages/taiko-client/proposer/transaction_builder/common_test.go create mode 100644 packages/taiko-client/proposer/transaction_builder/interface.go create mode 100644 packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator.go create mode 100644 packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator_test.go create mode 100644 packages/taiko-client/prover/config.go create mode 100644 packages/taiko-client/prover/config_test.go create mode 100644 packages/taiko-client/prover/event_handler/assignment_expired.go create mode 100644 packages/taiko-client/prover/event_handler/block_proposed.go create mode 100644 packages/taiko-client/prover/event_handler/block_proposed_test.go create mode 100644 packages/taiko-client/prover/event_handler/block_verified.go create mode 100644 packages/taiko-client/prover/event_handler/block_verified_test.go create mode 100644 packages/taiko-client/prover/event_handler/interface.go create mode 100644 packages/taiko-client/prover/event_handler/transition_contested.go create mode 100644 packages/taiko-client/prover/event_handler/transition_proved.go create mode 100644 packages/taiko-client/prover/event_handler/transition_proved_test.go create mode 100644 packages/taiko-client/prover/event_handler/util.go create mode 100644 packages/taiko-client/prover/event_handler/util_test.go create mode 100644 packages/taiko-client/prover/guardian.go create mode 100644 packages/taiko-client/prover/guardian_prover_heartbeater/guardian_prover.go create mode 100644 packages/taiko-client/prover/guardian_prover_heartbeater/interface.go create mode 100644 packages/taiko-client/prover/init.go create mode 100644 packages/taiko-client/prover/init_test.go create mode 100644 packages/taiko-client/prover/proof_producer/dummy_producer.go create mode 100644 packages/taiko-client/prover/proof_producer/dummy_producer_test.go create mode 100644 packages/taiko-client/prover/proof_producer/guardian_producer.go create mode 100644 packages/taiko-client/prover/proof_producer/guardian_producer_test.go create mode 100644 packages/taiko-client/prover/proof_producer/optimistic_producer.go create mode 100644 packages/taiko-client/prover/proof_producer/optimistic_producer_test.go create mode 100644 packages/taiko-client/prover/proof_producer/proof_producer.go create mode 100644 packages/taiko-client/prover/proof_producer/sgx_producer.go create mode 100644 packages/taiko-client/prover/proof_producer/sgx_producer_test.go create mode 100644 packages/taiko-client/prover/proof_submitter/interface.go create mode 100644 packages/taiko-client/prover/proof_submitter/proof_contester.go create mode 100644 packages/taiko-client/prover/proof_submitter/proof_contester_test.go create mode 100644 packages/taiko-client/prover/proof_submitter/proof_submitter.go create mode 100644 packages/taiko-client/prover/proof_submitter/proof_submitter_test.go create mode 100644 packages/taiko-client/prover/proof_submitter/transaction/builder.go create mode 100644 packages/taiko-client/prover/proof_submitter/transaction/builder_test.go create mode 100644 packages/taiko-client/prover/proof_submitter/transaction/sender.go create mode 100644 packages/taiko-client/prover/proof_submitter/transaction/sender_test.go create mode 100644 packages/taiko-client/prover/prover.go create mode 100644 packages/taiko-client/prover/prover_test.go create mode 100644 packages/taiko-client/prover/server/api.go create mode 100644 packages/taiko-client/prover/server/api_test.go create mode 100644 packages/taiko-client/prover/server/server.go create mode 100644 packages/taiko-client/prover/server/server_test.go create mode 100644 packages/taiko-client/prover/shared_state/state.go create mode 100644 packages/taiko-client/prover/shared_state/state_test.go create mode 100644 packages/taiko-client/release-please-config.json create mode 100644 packages/taiko-client/scripts/common.sh create mode 100755 packages/taiko-client/scripts/gen_bindings.sh create mode 100755 packages/taiko-client/scripts/gen_swagger_json.sh diff --git a/packages/taiko-client/.github/workflows/docker.yml b/packages/taiko-client/.github/workflows/docker.yml new file mode 100644 index 00000000000..8c37cb2b064 --- /dev/null +++ b/packages/taiko-client/.github/workflows/docker.yml @@ -0,0 +1,49 @@ +name: "Push docker image to GAR" + +on: + push: + branches: [main] + tags: + - "v*" + +jobs: + push-docker-image: + name: Build and push docker image + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Login to GAR + uses: docker/login-action@v2 + with: + registry: us-docker.pkg.dev + username: _json_key + password: ${{ secrets.GAR_JSON_KEY }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: | + us-docker.pkg.dev/evmchain/images/taiko-client + tags: | + type=ref,event=branch + type=ref,event=pr + type=ref,event=tag + type=sha + + - name: Build and push + uses: docker/build-push-action@v2 + with: + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/packages/taiko-client/.github/workflows/lint-pr.yml b/packages/taiko-client/.github/workflows/lint-pr.yml new file mode 100644 index 00000000000..ce00cc6b1e4 --- /dev/null +++ b/packages/taiko-client/.github/workflows/lint-pr.yml @@ -0,0 +1,14 @@ +name: "Lint PR" + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/packages/taiko-client/.github/workflows/openai-review.yml b/packages/taiko-client/.github/workflows/openai-review.yml new file mode 100644 index 00000000000..25d3c99cf7b --- /dev/null +++ b/packages/taiko-client/.github/workflows/openai-review.yml @@ -0,0 +1,36 @@ +on: [pull_request] + +jobs: + add_pr_comment: + permissions: write-all + runs-on: ubuntu-latest + name: OpenAI PR Comment + if: "contains(github.event.pull_request.labels.*.name, 'option.review-by-ai')" + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 2 + - id: patch + run: | + patch_output=$(curl --silent --request GET \ + --url https://api.github.com/repos/$PATCH_REPO/pulls/$PATCH_PR \ + --header "Accept: application/vnd.github.v3.patch" \ + --header "Authorization: Bearer $PATCH_GITHUB_TOKEN") + echo $patch_output + echo "GIT_PATCH_OUTPUT=$(echo $patch_output)" >> $GITHUB_ENV + env: + PATCH_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PATCH_PR: ${{ github.event.pull_request.number }} + PATCH_REPO: ${{ github.repository }} + - id: review + uses: taikoxyz/openai-review-action@main + with: + GIT_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + GIT_PATCH_OUTPUT: ${{ env.GIT_PATCH_OUTPUT }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + OPENAI_ORG_KEY: ${{ secrets.OPENAI_ORG_KEY }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_TITLE: ${{ github.event.pull_request.title }} + REPOSITORY_NAME: ${{ github.repository }} diff --git a/packages/taiko-client/.github/workflows/release-please.yml b/packages/taiko-client/.github/workflows/release-please.yml new file mode 100644 index 00000000000..bc8f1e16f37 --- /dev/null +++ b/packages/taiko-client/.github/workflows/release-please.yml @@ -0,0 +1,12 @@ +on: + push: + branches: + - main +name: release-please +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: google-github-actions/release-please-action@v3 + with: + command: manifest diff --git a/packages/taiko-client/.github/workflows/swagger.yml b/packages/taiko-client/.github/workflows/swagger.yml new file mode 100644 index 00000000000..3f459f91539 --- /dev/null +++ b/packages/taiko-client/.github/workflows/swagger.yml @@ -0,0 +1,61 @@ +name: Swagger + +on: + push: + branches: + - main + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + name: Swagger autogen docs + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.21 + cache: true + + - name: install swag cli + run: go install github.com/swaggo/swag/cmd/swag@latest + + - name: swag init + run: ./scripts/gen_swagger_json.sh + + deploy: + if: ${{ always() }} + needs: build + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + name: github pages deploy swagger docs + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Setup Pages + uses: actions/configure-pages@v3 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: '.' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/packages/taiko-client/.github/workflows/test.yml b/packages/taiko-client/.github/workflows/test.yml new file mode 100644 index 00000000000..d4a2b5d97c4 --- /dev/null +++ b/packages/taiko-client/.github/workflows/test.yml @@ -0,0 +1,97 @@ +name: "CI" + +on: + push: + branches: [main] + pull_request: + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + repository: taikoxyz/taiko-client + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.21 + cache: true + + - name: Lint + run: make lint + + integration_tests: + name: Integration tests + runs-on: ubuntu-latest + env: + CLIENT_DIR: taiko-client + TAIKO_MONO_DIR: taiko-mono + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.11.0 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v3 + with: + repository: taikoxyz/taiko-client + path: ${{ env.CLIENT_DIR }} + + - uses: actions/checkout@v3 + with: + repository: taikoxyz/taiko-mono + path: ${{ env.TAIKO_MONO_DIR }} + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.21 + cache: true + cache-dependency-path: ${{ env.CLIENT_DIR }}/go.sum + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + + - uses: pnpm/action-setup@v2 + name: Install pnpm + id: pnpm-install + with: + version: 8.4.0 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install protocol dependencies + working-directory: ${{ env.TAIKO_MONO_DIR }} + run: cd ./packages/protocol && pnpm install + + - name: Test + working-directory: ${{ env.CLIENT_DIR }} + run: | + TAIKO_MONO_DIR=${GITHUB_WORKSPACE}/${TAIKO_MONO_DIR} make test + + - name: Codecov.io + uses: codecov/codecov-action@v3 + with: + files: ${{ env.CLIENT_DIR }}/coverage.out diff --git a/packages/taiko-client/.gitignore b/packages/taiko-client/.gitignore new file mode 100644 index 00000000000..1b8b8a58b57 --- /dev/null +++ b/packages/taiko-client/.gitignore @@ -0,0 +1,29 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +.env +bin +coverage.out +prover/dbPath +dbdata + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Editors +.vscode + +# Testing +integration_test/nodes/deployments/mainnet.json +.env + +\.idea/ diff --git a/packages/taiko-client/.golangci.yml b/packages/taiko-client/.golangci.yml new file mode 100644 index 00000000000..495fbed11dc --- /dev/null +++ b/packages/taiko-client/.golangci.yml @@ -0,0 +1,91 @@ +# This file configures github.com/golangci/golangci-lint. + +run: + timeout: 20m + tests: true + skip-dirs-use-default: true + skip-files: + - bindings/gen_taiko_l1.go + - bindings/gen_taiko_l2.go + +issues: + # List of regexps of issue texts to exclude. + # + # But independently of this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. + # To list all excluded by default patterns execute `golangci-lint run --help` + # + # Default: https://golangci-lint.run/usage/false-positives/#default-exclusions + exclude: + - abcdef + +linters: + disable-all: true + enable: + - bidichk + - bodyclose + - durationcheck + - exportloopref + - errcheck + - errchkjson + - errname + - errorlint + - exhaustive + - goconst + - goimports + - gosimple + - govet + - gosec + - gofmt + - ineffassign + - importas + - lll + - makezero + - misspell + - misspell + - megacheck + - revive + - staticcheck + - sqlclosecheck + - staticcheck + - stylecheck + - typecheck + - unconvert + - unused + - whitespace + +linters-settings: + gofmt: + simplify: true + goconst: + min-len: 3 + min-occurrences: 6 + goimports: + local-prefixes: github.com/taikoxyz/taiko-client + +severity: + # Set the default severity for issues. + # + # If severity rules are defined and the issues do not match or no severity is provided to the rule + # this will be the default severity applied. + # Severities should match the supported severity names of the selected out format. + # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity + # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel + # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance + # + # Default: "" + default-severity: error + # If set to true `severity-rules` regular expressions become case-sensitive. + # Default: false + case-sensitive: true + # When a list of severity rules are provided, severity information will be added to lint issues. + # Severity rules have the same filtering capability as exclude rules + # except you are allowed to specify one matcher per severity rule. + # Only affects out formats that support setting severity information. + # + # Default: [] + rules: + - linters: + - dupl + severity: info diff --git a/packages/taiko-client/.release-please-manifest.json b/packages/taiko-client/.release-please-manifest.json new file mode 100644 index 00000000000..788b0fa7632 --- /dev/null +++ b/packages/taiko-client/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.22.0" +} diff --git a/packages/taiko-client/.swaggo b/packages/taiko-client/.swaggo new file mode 100644 index 00000000000..8cc34d878a4 --- /dev/null +++ b/packages/taiko-client/.swaggo @@ -0,0 +1,2 @@ +replace common.Address string +replace encoding.TierFee uint64 \ No newline at end of file diff --git a/packages/taiko-client/CHANGELOG.md b/packages/taiko-client/CHANGELOG.md new file mode 100644 index 00000000000..f222801caf4 --- /dev/null +++ b/packages/taiko-client/CHANGELOG.md @@ -0,0 +1,540 @@ +# Changelog + +## [0.22.0](https://github.com/taikoxyz/taiko-client/compare/v0.21.0...v0.22.0) (2024-04-19) + + +### Features + +* **bindings:** update Go contract bindings && bump `taiko-geth` version ([#727](https://github.com/taikoxyz/taiko-client/issues/727)) ([1003687](https://github.com/taikoxyz/taiko-client/commit/1003687d909fe72936834ba345deeb294fa06d8e)) +* **cmd:** default unit for all related flags / logs ([#729](https://github.com/taikoxyz/taiko-client/issues/729)) ([ec7ba9d](https://github.com/taikoxyz/taiko-client/commit/ec7ba9d696fe1b051de5e12878553fe035c046fa)) +* **driver:** only allow one successful beacon sync ([#718](https://github.com/taikoxyz/taiko-client/issues/718)) ([e6d48ab](https://github.com/taikoxyz/taiko-client/commit/e6d48abb4308c93e7bc3e0d070e7934bb5cfe9b6)) +* **metrics:** collect `txmgr` metrics ([#725](https://github.com/taikoxyz/taiko-client/issues/725)) ([7fb762a](https://github.com/taikoxyz/taiko-client/commit/7fb762a6cf101b905f1d3bcb8c0adacd77467518)) +* **metrics:** remove an unused metric ([#712](https://github.com/taikoxyz/taiko-client/issues/712)) ([76f4003](https://github.com/taikoxyz/taiko-client/commit/76f40038cef70e4736f87c9568c8a70779b47d98)) +* **metrics:** remove some unused metrics ([#724](https://github.com/taikoxyz/taiko-client/issues/724)) ([bce8ebb](https://github.com/taikoxyz/taiko-client/commit/bce8ebbdffd7144be3d54b75efdae2c08e74d455)) +* **proposer:** introduce `TxSender` for proposer ([#723](https://github.com/taikoxyz/taiko-client/issues/723)) ([c71155e](https://github.com/taikoxyz/taiko-client/commit/c71155e1fa2d0ba0359d36ab98d450855e022dfa)) +* **prover:** check proof status before sending the transaction ([#731](https://github.com/taikoxyz/taiko-client/issues/731)) ([a9d637a](https://github.com/taikoxyz/taiko-client/commit/a9d637a2fd086d6dfc0236c6f13c918c7eb7816c)) +* **prover:** introduce three `raiko` related flags ([#711](https://github.com/taikoxyz/taiko-client/issues/711)) ([7540be2](https://github.com/taikoxyz/taiko-client/commit/7540be21d88a4689f03aa866d93475843f798770)) +* **prover:** use `--guardian.submissionDelay` flag ([#730](https://github.com/taikoxyz/taiko-client/issues/730)) ([c7db741](https://github.com/taikoxyz/taiko-client/commit/c7db7419a66ffa3cfd21b28a32ac3a1528e09b48)) +* **rpc:** improve `L2ParentByBlockID` ([#715](https://github.com/taikoxyz/taiko-client/issues/715)) ([036f8e6](https://github.com/taikoxyz/taiko-client/commit/036f8e643b09c0125a7cf4a0da265463289596df)) +* **rpc:** keep retrying when connecting to endpoints ([#708](https://github.com/taikoxyz/taiko-client/issues/708)) ([771f133](https://github.com/taikoxyz/taiko-client/commit/771f1334e7efacc17e6ff0f5768a5cf54eecafb3)) +* **rpc:** remove `WaitL1Origin()` method ([#716](https://github.com/taikoxyz/taiko-client/issues/716)) ([70913c6](https://github.com/taikoxyz/taiko-client/commit/70913c60edc87bb93cbc185277f4862c5420cade)) + + +### Bug Fixes + +* **proposer:** fix an issue in `ProposeOp` ([#728](https://github.com/taikoxyz/taiko-client/issues/728)) ([24a8e1d](https://github.com/taikoxyz/taiko-client/commit/24a8e1d52270c9f1681a2e1d6ca376d7c1faf4a7)) + +## [0.21.0](https://github.com/taikoxyz/taiko-client/compare/v0.20.0...v0.21.0) (2024-04-10) + + +### Features + +* **bindings:** bump bindings ([#671](https://github.com/taikoxyz/taiko-client/issues/671)) ([16fe52a](https://github.com/taikoxyz/taiko-client/commit/16fe52a94337ab27a53c8c6213a6c13702b79171)) +* **bindings:** update Go contract bindings ([#680](https://github.com/taikoxyz/taiko-client/issues/680)) ([b64bf1a](https://github.com/taikoxyz/taiko-client/commit/b64bf1a6a5a5ebce0c312d40ea13155db55d0b21)) +* **bindings:** update Go contract bindings ([#689](https://github.com/taikoxyz/taiko-client/issues/689)) ([fd98d4b](https://github.com/taikoxyz/taiko-client/commit/fd98d4bab4be82d0220e8805e17592feceabb519)) +* **bindings:** update Go contract bindings ([#697](https://github.com/taikoxyz/taiko-client/issues/697)) ([993d491](https://github.com/taikoxyz/taiko-client/commit/993d4919958181e38cc413a73ea278c8ab5ab439)) +* **bindings:** update Go contract bindings ([#705](https://github.com/taikoxyz/taiko-client/issues/705)) ([a97255d](https://github.com/taikoxyz/taiko-client/commit/a97255dd18df15a4a2ad47f900bc5458679546d6)) +* **cmd:** revert `SubcommandApplication` context changes ([#701](https://github.com/taikoxyz/taiko-client/issues/701)) ([985f030](https://github.com/taikoxyz/taiko-client/commit/985f030209029c3f8fca6dc814b524c7ef16b898)) +* **driver:** add blob datasource ([#688](https://github.com/taikoxyz/taiko-client/issues/688)) ([a598847](https://github.com/taikoxyz/taiko-client/commit/a5988478251179a72dd7b5ca71754b8c0fbeb666)) +* **driver:** fix the latest verified block hash check when using snap sync ([#700](https://github.com/taikoxyz/taiko-client/issues/700)) ([3cae4ea](https://github.com/taikoxyz/taiko-client/commit/3cae4eadc24f07b87808db0df419c894b0c93357)) +* **driver:** improve driver implementation ([#672](https://github.com/taikoxyz/taiko-client/issues/672)) ([55717c8](https://github.com/taikoxyz/taiko-client/commit/55717c8ff8c9541640c5368c2e937451ae6af7aa)) +* **driver:** update snap sync strategy ([#695](https://github.com/taikoxyz/taiko-client/issues/695)) ([7a68a25](https://github.com/taikoxyz/taiko-client/commit/7a68a25f6c16878e0cf44b3ef3816e9f6544d263)) +* **flags:** remove `--rpc.waitReceiptTimeout` flag ([#684](https://github.com/taikoxyz/taiko-client/issues/684)) ([a70519b](https://github.com/taikoxyz/taiko-client/commit/a70519b585ac19a1ad8df629edf8364a3afaf8cf)) +* **pkg:** update `WaitTillL2ExecutionEngineSynced` ([#677](https://github.com/taikoxyz/taiko-client/issues/677)) ([2c2b996](https://github.com/taikoxyz/taiko-client/commit/2c2b996be04d445b289a9c65aebb01f4afd1ed3b)) +* **proof_producer:** update `sgxProducer` request body ([#693](https://github.com/taikoxyz/taiko-client/issues/693)) ([ba40ced](https://github.com/taikoxyz/taiko-client/commit/ba40ceddea6857f68d9a0187e490306038ee1e48)) +* **proof_producer:** update SGX `proofParam.bootstrap` to `false` ([#694](https://github.com/taikoxyz/taiko-client/issues/694)) ([78d5303](https://github.com/taikoxyz/taiko-client/commit/78d5303033992c46f7edd22ae1384eff59fa735d)) +* **proposer:** add more tests for propsoer ([#686](https://github.com/taikoxyz/taiko-client/issues/686)) ([cd26204](https://github.com/taikoxyz/taiko-client/commit/cd2620486c8cd8e1c4f293036e4afc3dabec46cb)) +* **proposer:** improve proposing strategy ([#682](https://github.com/taikoxyz/taiko-client/issues/682)) ([62cc7ff](https://github.com/taikoxyz/taiko-client/commit/62cc7ffcc3e7b08fb1bd040081a34bf676ec0832)) +* **proposer:** remove `--tierFee.max` flag ([#702](https://github.com/taikoxyz/taiko-client/issues/702)) ([553c432](https://github.com/taikoxyz/taiko-client/commit/553c4322812f69e8ace719612e4c3f7696263cd2)) +* **prover_producer:** update `SGXRequestProofBodyParam` ([#691](https://github.com/taikoxyz/taiko-client/issues/691)) ([41c2019](https://github.com/taikoxyz/taiko-client/commit/41c201937aa5613e3d4d81a3478f2c67a942b387)) +* **prover:** stop retrying when error is `vm.ErrExecutionReverted` ([#706](https://github.com/taikoxyz/taiko-client/issues/706)) ([971f581](https://github.com/taikoxyz/taiko-client/commit/971f5815d767c0d152cac510c67928dc4e355279)) + + +### Bug Fixes + +* **pkg:** remove redundant alias ([#665](https://github.com/taikoxyz/taiko-client/issues/665)) ([bd1c324](https://github.com/taikoxyz/taiko-client/commit/bd1c3241554cbbf3a905a3cf1554368870dacf9e)) +* **proposer:** fix tier fee ([#687](https://github.com/taikoxyz/taiko-client/issues/687)) ([651f188](https://github.com/taikoxyz/taiko-client/commit/651f18891d77e87f9ee4906b7298e8ab89deb1ee)) +* **proposer:** rename `lastUnfilteredPoolContentProposedAt` ([#685](https://github.com/taikoxyz/taiko-client/issues/685)) ([8c85703](https://github.com/taikoxyz/taiko-client/commit/8c8570313a2e37f63284a1f78eee2d7eded09dde)) +* **prover:** do not retry when the status in receipt is not `types.ReceiptStatusSuccessful` ([#675](https://github.com/taikoxyz/taiko-client/issues/675)) ([5f91e0e](https://github.com/taikoxyz/taiko-client/commit/5f91e0e4f2788b71f3ea6c814171a0d4532c0918)) +* **prover:** fix `tx.gasLimit` flag for prover ([#692](https://github.com/taikoxyz/taiko-client/issues/692)) ([6683d54](https://github.com/taikoxyz/taiko-client/commit/6683d54e7526c53197e9bc6d414f2cfca586a1bd)) +* **prover:** fix a check in `isValidProof()` ([#679](https://github.com/taikoxyz/taiko-client/issues/679)) ([16857ba](https://github.com/taikoxyz/taiko-client/commit/16857ba2d07bc969223f90fcd20c5dbae084beaa)) + +## [0.20.0](https://github.com/taikoxyz/taiko-client/compare/v0.19.0...v0.20.0) (2024-03-28) + + +### Features + +* **all:** clean up unused signal service related code ([#581](https://github.com/taikoxyz/taiko-client/issues/581)) ([13f896a](https://github.com/taikoxyz/taiko-client/commit/13f896af4689df14853ceb838fd6eb1e0a64a9ba)) +* **all:** use an unified transaction sender implementation ([#560](https://github.com/taikoxyz/taiko-client/issues/560)) ([1bd56c0](https://github.com/taikoxyz/taiko-client/commit/1bd56c0d660842fb499336d011e87d7b30c527b9)) +* **bindings:** update Go contract bindings ([#561](https://github.com/taikoxyz/taiko-client/issues/561)) ([bacedb0](https://github.com/taikoxyz/taiko-client/commit/bacedb0c3dcffd973c61e901529cfba773812e64)) +* **bindings:** update Go contract bindings ([#570](https://github.com/taikoxyz/taiko-client/issues/570)) ([e70b7a0](https://github.com/taikoxyz/taiko-client/commit/e70b7a031bc069d527d5518d7928f969fd2c15c1)) +* **bindings:** update Go contract bindings ([#574](https://github.com/taikoxyz/taiko-client/issues/574)) ([ac9788f](https://github.com/taikoxyz/taiko-client/commit/ac9788f44b5fbb56a1f438a77114a8601e84689f)) +* **bindings:** update Go contract bindings ([#583](https://github.com/taikoxyz/taiko-client/issues/583)) ([1acfc5f](https://github.com/taikoxyz/taiko-client/commit/1acfc5f982c48843fecdceec0dd07dad1d1154e4)) +* **bindings:** update Go contract bindings ([#587](https://github.com/taikoxyz/taiko-client/issues/587)) ([2237295](https://github.com/taikoxyz/taiko-client/commit/2237295da0fb9cf259e8dc58de1426e4f1a67989)) +* **bindings:** update Go contract bindings ([#607](https://github.com/taikoxyz/taiko-client/issues/607)) ([1b03e6a](https://github.com/taikoxyz/taiko-client/commit/1b03e6a8aadfb960ba2d91a1796ff70a92bcb9fb)) +* **bindings:** update Go contract bindings ([#619](https://github.com/taikoxyz/taiko-client/issues/619)) ([4145dae](https://github.com/taikoxyz/taiko-client/commit/4145dae931b414eb719f1fab565f5d2156cec12a)) +* **bindings:** update Go contract bindings ([#646](https://github.com/taikoxyz/taiko-client/issues/646)) ([13c6ac2](https://github.com/taikoxyz/taiko-client/commit/13c6ac2ba96c5c4de7da8a20ebe6bbf66e872c8f)) +* **bindings:** update Go contract bindings ([#657](https://github.com/taikoxyz/taiko-client/issues/657)) ([eb3cd58](https://github.com/taikoxyz/taiko-client/commit/eb3cd5832b3e7713eb7bcf5716deb6f6fb5fbca5)) +* **bindings:** update Go contract bindings ([#660](https://github.com/taikoxyz/taiko-client/issues/660)) ([6fe4dda](https://github.com/taikoxyz/taiko-client/commit/6fe4dda3752164dd441e49cdc15ba6584b9be568)) +* **bindings:** update Go contract bindings && add more logs for prover ([#632](https://github.com/taikoxyz/taiko-client/issues/632)) ([1c90c6a](https://github.com/taikoxyz/taiko-client/commit/1c90c6a4ed3244e0bd176625f17cfbcbc1f36c0e)) +* **blob:** fix bug when blob decode with 0 ([#627](https://github.com/taikoxyz/taiko-client/issues/627)) ([df0e897](https://github.com/taikoxyz/taiko-client/commit/df0e8974ae79f116363f027116d13532349929e6)) +* **blob:** set min blob fee ([#636](https://github.com/taikoxyz/taiko-client/issues/636)) ([1727fc5](https://github.com/taikoxyz/taiko-client/commit/1727fc532d505526d99e85a11d4927b7bf32f73c)) +* **driver:** fix a block number issue ([#656](https://github.com/taikoxyz/taiko-client/issues/656)) ([eced566](https://github.com/taikoxyz/taiko-client/commit/eced566090f4c98456efa4a5e00544d1bccfd915)) +* **driver:** improve driver implementation ([#639](https://github.com/taikoxyz/taiko-client/issues/639)) ([fbd4d06](https://github.com/taikoxyz/taiko-client/commit/fbd4d06ac41cfd13aba729d037f664947f984092)) +* **driver:** improve driver state ([#591](https://github.com/taikoxyz/taiko-client/issues/591)) ([1fd9084](https://github.com/taikoxyz/taiko-client/commit/1fd908415d9ef2d7956d1c3565ad4f18f003dc76)) +* **driver:** introduce `StateVariablesUpdated` event ([#666](https://github.com/taikoxyz/taiko-client/issues/666)) ([8ecd440](https://github.com/taikoxyz/taiko-client/commit/8ecd44066eccf674561713ce21187f5cd23bd21a)) +* **driver:** update `defaultMaxTxPerBlock` ([#604](https://github.com/taikoxyz/taiko-client/issues/604)) ([3f99b4a](https://github.com/taikoxyz/taiko-client/commit/3f99b4a67896e1fa88a0cfcb8eff8eabc779d6b7)) +* **driver:** update `ForkchoiceStateV1` params ([#640](https://github.com/taikoxyz/taiko-client/issues/640)) ([9cbe4b8](https://github.com/taikoxyz/taiko-client/commit/9cbe4b8d3c499d97f6e0aadc298075f6764681f7)) +* **metrics:** add more transaction sender metrics ([#630](https://github.com/taikoxyz/taiko-client/issues/630)) ([26ed379](https://github.com/taikoxyz/taiko-client/commit/26ed3793b5bf93ef215960c99598fa7e1603a730)) +* **metrics:** update default metrics registry ([#617](https://github.com/taikoxyz/taiko-client/issues/617)) ([e1f5393](https://github.com/taikoxyz/taiko-client/commit/e1f5393849f79a3f4618f9fb1bf671513787ec70)) +* **pkg:** improve / simplify reorg check logic ([#647](https://github.com/taikoxyz/taiko-client/issues/647)) ([0b08772](https://github.com/taikoxyz/taiko-client/commit/0b0877278177613b9871258847c9fe8cbbd2c1ea)) +* **pkg:** improve sender ([#603](https://github.com/taikoxyz/taiko-client/issues/603)) ([af4f072](https://github.com/taikoxyz/taiko-client/commit/af4f072e6b942f85572a97a723ddfb3eff3b6ea0)) +* **pkg:** introduce `blob.go` ([#644](https://github.com/taikoxyz/taiko-client/issues/644)) ([995b449](https://github.com/taikoxyz/taiko-client/commit/995b449fbc5d398dc793d647ee58b55df2dffdd7)) +* **pkg:** make `chainID` part of `rpc.EthClient` ([#563](https://github.com/taikoxyz/taiko-client/issues/563)) ([f5d1146](https://github.com/taikoxyz/taiko-client/commit/f5d11460aa1bf740a037aa328dc8a2878b94832a)) +* **pkg:** move `sender` from `internal` to `pkg` ([#626](https://github.com/taikoxyz/taiko-client/issues/626)) ([05100b3](https://github.com/taikoxyz/taiko-client/commit/05100b3860ad37222946aaec3d8ae10794fd9108)) +* **pkg:** remove `defaultMaxTransactionsPerBlock` config ([#611](https://github.com/taikoxyz/taiko-client/issues/611)) ([1b21e4c](https://github.com/taikoxyz/taiko-client/commit/1b21e4c42d6e41e931e2bcc93dc4e19115acceaf)) +* **pkg:** remove `IsArchiveNode` check for L1 endpoint ([#652](https://github.com/taikoxyz/taiko-client/issues/652)) ([fed3a27](https://github.com/taikoxyz/taiko-client/commit/fed3a27c17260e81726f946170b3f02e5af5197e)) +* **proposer:** add more logs for debugging ([#643](https://github.com/taikoxyz/taiko-client/issues/643)) ([a554017](https://github.com/taikoxyz/taiko-client/commit/a55401758756eefb29929657cda10311bbc4ee17)) +* **proposer:** improve proposer flag configs ([#589](https://github.com/taikoxyz/taiko-client/issues/589)) ([8159155](https://github.com/taikoxyz/taiko-client/commit/815915523dcce292c1c22caba4fde82cddb2e740)) +* **proposer:** introduce `zlib` for transactions list bytes compression ([#649](https://github.com/taikoxyz/taiko-client/issues/649)) ([dd50068](https://github.com/taikoxyz/taiko-client/commit/dd500684e4af894a89f2ef5e6641f58f1a57e6b8)) +* **proposer:** introduce proposer transaction builder ([#612](https://github.com/taikoxyz/taiko-client/issues/612)) ([9bd2aea](https://github.com/taikoxyz/taiko-client/commit/9bd2aea11e25273349130cdc0f9503fe86af9fa6)) +* **prover:** add `--prover.minEthBalance` and `--prover.minTaikoTokenBalance` flags ([#641](https://github.com/taikoxyz/taiko-client/issues/641)) ([1a7128b](https://github.com/taikoxyz/taiko-client/commit/1a7128b472115b697dac2fa00db8d901994f5c19)) +* **prover:** clean up `PSE_ZKEVM` related code ([#582](https://github.com/taikoxyz/taiko-client/issues/582)) ([ffcc2b2](https://github.com/taikoxyz/taiko-client/commit/ffcc2b2451e2a29a144c33b202ad1b311a07bf42)) +* **prover:** cleanup more database related code ([#621](https://github.com/taikoxyz/taiko-client/issues/621)) ([58c2d10](https://github.com/taikoxyz/taiko-client/commit/58c2d10a3c2dcbd16ec343f59242d01f8a3e1ec9)) +* **prover:** fix a `RequestProof` issue ([#588](https://github.com/taikoxyz/taiko-client/issues/588)) ([0f15192](https://github.com/taikoxyz/taiko-client/commit/0f15192abe0c3169544bb1e705d583d045c31359)) +* **prover:** fix bug ([#655](https://github.com/taikoxyz/taiko-client/issues/655)) ([d110fb4](https://github.com/taikoxyz/taiko-client/commit/d110fb4b80dec2520d3d667f41bd5ea94615217b)) +* **prover:** improve prover ([#633](https://github.com/taikoxyz/taiko-client/issues/633)) ([b80ce2c](https://github.com/taikoxyz/taiko-client/commit/b80ce2c4c576b6f00da07500044d464735f3f7f4)) +* **prover:** improve prover implementation ([#616](https://github.com/taikoxyz/taiko-client/issues/616)) ([b7af09c](https://github.com/taikoxyz/taiko-client/commit/b7af09cb247214d1b5d1c6d177fa2fb013f803da)) +* **prover:** improve prover implementation ([#635](https://github.com/taikoxyz/taiko-client/issues/635)) ([5983828](https://github.com/taikoxyz/taiko-client/commit/59838286c5b0ef4e0f4680126ac6be155059a2b0)) +* **prover:** improve prover server tier fees check ([#642](https://github.com/taikoxyz/taiko-client/issues/642)) ([662d99f](https://github.com/taikoxyz/taiko-client/commit/662d99ff33c15568663610e91d41c8f44ff4a12f)) +* **prover:** parse contest submission custom errors ([#624](https://github.com/taikoxyz/taiko-client/issues/624)) ([2d00517](https://github.com/taikoxyz/taiko-client/commit/2d005175904dda7cad0836c275b2b6319ae5a114)) +* **prover:** remove more database related code ([#623](https://github.com/taikoxyz/taiko-client/issues/623)) ([3963208](https://github.com/taikoxyz/taiko-client/commit/39632084b033bccc3aba716c9a37f7155477097d)) +* **prover:** update `SGXProducer` ([#566](https://github.com/taikoxyz/taiko-client/issues/566)) ([93e0660](https://github.com/taikoxyz/taiko-client/commit/93e0660917c37451d95b6d0600041f473d6f391e)) +* **prover:** update server APIs ([#618](https://github.com/taikoxyz/taiko-client/issues/618)) ([64ec861](https://github.com/taikoxyz/taiko-client/commit/64ec861e88a0db6754364d113c91ddf24a95c15f)) +* **repo:** introduce `txmgr` package ([#658](https://github.com/taikoxyz/taiko-client/issues/658)) ([ba65882](https://github.com/taikoxyz/taiko-client/commit/ba65882b894ffcc02b248f12d62364838476b3da)) +* **sender:** add `sender.GetOpts` method ([#613](https://github.com/taikoxyz/taiko-client/issues/613)) ([2644e60](https://github.com/taikoxyz/taiko-client/commit/2644e607b54d7ba3b7d174ed170f5d49750a69a0)) +* **sender:** change to use tick and remove handle reorg function ([#571](https://github.com/taikoxyz/taiko-client/issues/571)) ([27f79c0](https://github.com/taikoxyz/taiko-client/commit/27f79c0500540b147bba180cbfd617474d60f165)) +* **sender:** fix a `gasLimt` default value bug ([#585](https://github.com/taikoxyz/taiko-client/issues/585)) ([d323c6f](https://github.com/taikoxyz/taiko-client/commit/d323c6ff602caefee837e112c7b86f5b349f95fe)) +* **sender:** improve `adjustGasFee` ([#637](https://github.com/taikoxyz/taiko-client/issues/637)) ([090a466](https://github.com/taikoxyz/taiko-client/commit/090a4665d26c7e819c6b81c99a7482d2a3341ac2)) +* **sender:** improve default values setting ([#628](https://github.com/taikoxyz/taiko-client/issues/628)) ([d734626](https://github.com/taikoxyz/taiko-client/commit/d734626f58ec4dcec027b2302bab0365bf85beba)) +* **sender:** no `MaxGasFee` default value ([#596](https://github.com/taikoxyz/taiko-client/issues/596)) ([540fd77](https://github.com/taikoxyz/taiko-client/commit/540fd7726635def149444c3eda2feae73fbcb321)) +* **sender:** upgrade sender txID ([#625](https://github.com/taikoxyz/taiko-client/issues/625)) ([0aaf06b](https://github.com/taikoxyz/taiko-client/commit/0aaf06bb0940e6d2dac45b702d6b042bda64898f)) +* **tx_list_validator:** remove unused code in `tx_list_validator` package ([#609](https://github.com/taikoxyz/taiko-client/issues/609)) ([cc4e302](https://github.com/taikoxyz/taiko-client/commit/cc4e3026051c8bfbeed590d5acde921bfb40a0f3)) +* **utils:** replace `mathutils` ([#595](https://github.com/taikoxyz/taiko-client/issues/595)) ([514869d](https://github.com/taikoxyz/taiko-client/commit/514869da1dec700db0b42be08156438b643132f0)) + + +### Bug Fixes + +* **cmd:** fix some context close issues ([#650](https://github.com/taikoxyz/taiko-client/issues/650)) ([f561847](https://github.com/taikoxyz/taiko-client/commit/f561847ad6aede44aea309084b28d363fdc3aa9e)) +* **driver:** fix a blob decoding issue ([#629](https://github.com/taikoxyz/taiko-client/issues/629)) ([0a29936](https://github.com/taikoxyz/taiko-client/commit/0a29936f34478d6e0be810eb2d9cd445948892f2)) +* **driver:** fix a reorg check issue in driver ([#634](https://github.com/taikoxyz/taiko-client/issues/634)) ([7abd6d0](https://github.com/taikoxyz/taiko-client/commit/7abd6d0d54267d7f7092f502cdfe3c4554329bec)) +* **flag:** add a missing flag configuration for prover ([#567](https://github.com/taikoxyz/taiko-client/issues/567)) ([6d6d9c6](https://github.com/taikoxyz/taiko-client/commit/6d6d9c60e3caf498e1f1f8a9c6d5e8c0020814b9)) +* **flags:** fix a small issue in `txmgr` flags ([#661](https://github.com/taikoxyz/taiko-client/issues/661)) ([c1765c8](https://github.com/taikoxyz/taiko-client/commit/c1765c83a945f6b817db528b4516bfc2fca1d700)) +* **flags:** fix logger level flags ([#575](https://github.com/taikoxyz/taiko-client/issues/575)) ([d315605](https://github.com/taikoxyz/taiko-client/commit/d315605d7d101f723a5c870571848fba50c8c6ae)) +* **pkg:** fix a bug in transaction sender ([#606](https://github.com/taikoxyz/taiko-client/issues/606)) ([40325bc](https://github.com/taikoxyz/taiko-client/commit/40325bc346aace3bb8c42ed8cb54bd00173f4734)) +* **pkg:** fix a sender error check issue ([#602](https://github.com/taikoxyz/taiko-client/issues/602)) ([f801f28](https://github.com/taikoxyz/taiko-client/commit/f801f28050159f9c41e706c8d90bf4cdef188816)) +* **pkg:** fix a typo ([#597](https://github.com/taikoxyz/taiko-client/issues/597)) ([428a89e](https://github.com/taikoxyz/taiko-client/commit/428a89e0641c4ed91b6800d06d7dfd1f8849feef)) +* **propsoer:** use `L1BlockBuilderTip` flag value ([#584](https://github.com/taikoxyz/taiko-client/issues/584)) ([2068697](https://github.com/taikoxyz/taiko-client/commit/20686979fe62f92967afe4fc245a800a6d04acec)) +* **transaction_builder:** fix an issue in `BlobTransactionBuilder.Build` ([#662](https://github.com/taikoxyz/taiko-client/issues/662)) ([45ef240](https://github.com/taikoxyz/taiko-client/commit/45ef240fe40026d7648b4c6cdbf9cc83ba4d5ee9)) + +## [0.19.0](https://github.com/taikoxyz/taiko-client/compare/v0.18.0...v0.19.0) (2024-02-19) + + +### Features + +* **all:** changes based on protocol `TaikoL1.getBlock()` update ([#558](https://github.com/taikoxyz/taiko-client/issues/558)) ([c853370](https://github.com/taikoxyz/taiko-client/commit/c853370c7ec85d1fea058b667097430f13b744fd)) +* **all:** sync state root rather than signal service's storage root ([#549](https://github.com/taikoxyz/taiko-client/issues/549)) ([b05c0d6](https://github.com/taikoxyz/taiko-client/commit/b05c0d6d2f1bf94051297df15330ccce669eb63e)) +* **bindings:** try parsing more custom errors ([#531](https://github.com/taikoxyz/taiko-client/issues/531)) ([025d985](https://github.com/taikoxyz/taiko-client/commit/025d9852ba5c06983b50836c21e7ad5a8f8c04b2)) +* **bindings:** update `AssigmentHook` signing based on protocol updates ([#519](https://github.com/taikoxyz/taiko-client/issues/519)) ([73a6047](https://github.com/taikoxyz/taiko-client/commit/73a604757995460fdc481548e56111766b63b307)) +* **bindings:** update Go contract bindings ([#471](https://github.com/taikoxyz/taiko-client/issues/471)) ([23ce311](https://github.com/taikoxyz/taiko-client/commit/23ce3119478eaa025d05890a5b1c8188216beb29)) +* **bindings:** update Go contract bindings ([#520](https://github.com/taikoxyz/taiko-client/issues/520)) ([386e848](https://github.com/taikoxyz/taiko-client/commit/386e848f33157ef63ff58919eb7ecf4c4fb4b1c5)) +* **bindings:** update Go contract bindings ([#551](https://github.com/taikoxyz/taiko-client/issues/551)) ([4ace57c](https://github.com/taikoxyz/taiko-client/commit/4ace57c1d1f4bcc3473a341eaa5f16918a84aea3)) +* **bindings:** update Go contract bindings ([#553](https://github.com/taikoxyz/taiko-client/issues/553)) ([77d270b](https://github.com/taikoxyz/taiko-client/commit/77d270ba8b13d3946fbe94a8a7ccac17a363207a)) +* **bindings:** update Go contracts bindings ([#543](https://github.com/taikoxyz/taiko-client/issues/543)) ([ec81ff3](https://github.com/taikoxyz/taiko-client/commit/ec81ff39686e94b4a0bbb99f48fadce18371ce0c)) +* **client:** upgrade shell scripts and replace docker image links ([#495](https://github.com/taikoxyz/taiko-client/issues/495)) ([8f0b4c8](https://github.com/taikoxyz/taiko-client/commit/8f0b4c811574259b24a49573eaef77bd6887f12d)) +* **config:** simplify config loading ([#507](https://github.com/taikoxyz/taiko-client/issues/507)) ([5f9d843](https://github.com/taikoxyz/taiko-client/commit/5f9d8435ba73267761fe5ee2d186aa34822823e7)) +* **docs:** add `README` for debugging tests ([#498](https://github.com/taikoxyz/taiko-client/issues/498)) ([b4a102d](https://github.com/taikoxyz/taiko-client/commit/b4a102d6779548a4ff5ac1a7d7dce6bc487c26ac)) +* **docs:** update swag and swagger docs ([#482](https://github.com/taikoxyz/taiko-client/issues/482)) ([1e26b9e](https://github.com/taikoxyz/taiko-client/commit/1e26b9e6a78c2356064e0d041621192f70cfcada)) +* **driver:** update `TaikoL2.anchor` transaction gas limit ([#559](https://github.com/taikoxyz/taiko-client/issues/559)) ([fb9cd12](https://github.com/taikoxyz/taiko-client/commit/fb9cd12c6fb595ab37a4913b0c384c7d49087fd0)) +* **driver:** updates based on the protocol `ICrossChainSync` changes ([#555](https://github.com/taikoxyz/taiko-client/issues/555)) ([09248b9](https://github.com/taikoxyz/taiko-client/commit/09248b973c05809299b8e0ca1146e0d5a0d2f3e5)) +* **internal:** add `internal` dir and format import order ([#506](https://github.com/taikoxyz/taiko-client/issues/506)) ([fdcb4bc](https://github.com/taikoxyz/taiko-client/commit/fdcb4bc8212ffe654a1784bb6f4e2dc6c2119367)) +* **metrics:** add some new metrics ([#479](https://github.com/taikoxyz/taiko-client/issues/479)) ([cfeffca](https://github.com/taikoxyz/taiko-client/commit/cfeffca2d447d1e2c0eff059570dd94696c4bbf9)) +* **pkg:** fix a log issue in `ensureGenesisMatched` && update a config ([#504](https://github.com/taikoxyz/taiko-client/issues/504)) ([4c01872](https://github.com/taikoxyz/taiko-client/commit/4c018728150857c484ef247ce03045ba462ce80e)) +* **pkg:** remove reverse iterator ([#509](https://github.com/taikoxyz/taiko-client/issues/509)) ([9929585](https://github.com/taikoxyz/taiko-client/commit/992958550c975bc2afa67a9164766e3a9f345265)) +* **proposer:** add flag for adding tip to assignmenthook ([#540](https://github.com/taikoxyz/taiko-client/issues/540)) ([4619778](https://github.com/taikoxyz/taiko-client/commit/46197780f94e61c54409a043221060aca606e908)) +* **proposer:** changes based on protocol `AssignmentHook` updates ([#502](https://github.com/taikoxyz/taiko-client/issues/502)) ([3908adb](https://github.com/taikoxyz/taiko-client/commit/3908adb79e1a5738b822b58cfa873f7d70357edb)) +* **proposer:** improve some wording in blob transactions implementation ([#556](https://github.com/taikoxyz/taiko-client/issues/556)) ([192aa38](https://github.com/taikoxyz/taiko-client/commit/192aa385f62013181b0e132779193aa9d8704f32)) +* **proposer:** improved shuffle function to preserve original prover endpoints slice ([#475](https://github.com/taikoxyz/taiko-client/issues/475)) ([6b25d9d](https://github.com/taikoxyz/taiko-client/commit/6b25d9d21ac787e7de0239e3eb4ebdc15376ac38)) +* **proposer:** optimize proposer logs ([#464](https://github.com/taikoxyz/taiko-client/issues/464)) ([c7e899d](https://github.com/taikoxyz/taiko-client/commit/c7e899d547009b32e3d0762c55707cb4b85dcb8f)) +* **proposer:** restore l2.suggestedFeeRecipient flag ([#550](https://github.com/taikoxyz/taiko-client/issues/550)) ([b93cfcf](https://github.com/taikoxyz/taiko-client/commit/b93cfcf8fc60e85d7223bf22540ce42ad13f416b)) +* **prover:** add `--prover.enableLivenessBondProof` flag for guardian prover ([#530](https://github.com/taikoxyz/taiko-client/issues/530)) ([9fa5ab6](https://github.com/taikoxyz/taiko-client/commit/9fa5ab6174efce6ee747281a9a37c5afe2856640)) +* **prover:** add more comments to prover package ([#491](https://github.com/taikoxyz/taiko-client/issues/491)) ([2156b49](https://github.com/taikoxyz/taiko-client/commit/2156b49202318447ecafdbf4b53a6209b711f1e0)) +* **prover:** additional startup info for guardian prover ([#552](https://github.com/taikoxyz/taiko-client/issues/552)) ([6fefa6e](https://github.com/taikoxyz/taiko-client/commit/6fefa6e81f217a88d90afd55fb457be3978ac74d)) +* **prover:** always send guardian proofs for guardian provers ([#470](https://github.com/taikoxyz/taiko-client/issues/470)) ([657f0e4](https://github.com/taikoxyz/taiko-client/commit/657f0e42d33447728c6028f7e7d4482343032962)) +* **prover:** change block signing to use timestamp as key ([#466](https://github.com/taikoxyz/taiko-client/issues/466)) ([eb5bc7a](https://github.com/taikoxyz/taiko-client/commit/eb5bc7a8b541e17e52f8b32b3f7d2104ad6ce0eb)) +* **prover:** check guardian prover contract address ([#497](https://github.com/taikoxyz/taiko-client/issues/497)) ([3794caf](https://github.com/taikoxyz/taiko-client/commit/3794caf8c0b3a6cc0d4b0692b0ca69e57fcabc05)) +* **prover:** fix / upgrade integration test ([#496](https://github.com/taikoxyz/taiko-client/issues/496)) ([c63e681](https://github.com/taikoxyz/taiko-client/commit/c63e681910e03cea2e15eeb551f8fd1938736fc8)) +* **prover:** fix a SGX proof producer issue ([#477](https://github.com/taikoxyz/taiko-client/issues/477)) ([cd742f7](https://github.com/taikoxyz/taiko-client/commit/cd742f754cd62d3b18033d1e1481a9e9f4ad896d)) +* **prover:** fix a tier selection issue ([#534](https://github.com/taikoxyz/taiko-client/issues/534)) ([c73661e](https://github.com/taikoxyz/taiko-client/commit/c73661ebbf880556699020acc0a74a98f10a427b)) +* **prover:** guardian prover startup ([#529](https://github.com/taikoxyz/taiko-client/issues/529)) ([5401a80](https://github.com/taikoxyz/taiko-client/commit/5401a802ca2cb47e3904326190bf9afec5b62fe2)) +* **prover:** increase wait time before sending to `proofWindowExpiredCh` ([#505](https://github.com/taikoxyz/taiko-client/issues/505)) ([6c52594](https://github.com/taikoxyz/taiko-client/commit/6c5259448b39513736645d544496562928908e2a)) +* **prover:** introduce `SGXAndZkevmRpcdProducer` ([#476](https://github.com/taikoxyz/taiko-client/issues/476)) ([1750a4b](https://github.com/taikoxyz/taiko-client/commit/1750a4bd4e52db80ab281f2b4ba1153fd28e0e51)) +* **prover:** move sub event logic into event function. ([#513](https://github.com/taikoxyz/taiko-client/issues/513)) ([d7aad5a](https://github.com/taikoxyz/taiko-client/commit/d7aad5a623e70bfea02eef9af78e2eea4f43b357)) +* **prover:** refactor of guardian prover heartbeat signing / sending ([#472](https://github.com/taikoxyz/taiko-client/issues/472)) ([630924e](https://github.com/taikoxyz/taiko-client/commit/630924e4a331007e135dcfe61e9c48cf190d9647)) +* **prover:** remove `result` channel in `proof_producer.go` ([#516](https://github.com/taikoxyz/taiko-client/issues/516)) ([46779ca](https://github.com/taikoxyz/taiko-client/commit/46779caabe1f1903dfe917896f69eaf49045cf9b)) +* **prover:** remove capacity manager ([#478](https://github.com/taikoxyz/taiko-client/issues/478)) ([8972ee1](https://github.com/taikoxyz/taiko-client/commit/8972ee1d70ae08736f74348e3467880e712e9a30)) +* **prover:** set `AssignmentHook` allowance ([#486](https://github.com/taikoxyz/taiko-client/issues/486)) ([a2af478](https://github.com/taikoxyz/taiko-client/commit/a2af4789b7b5975b1365b601eace18fdea4ee978)) +* **prover:** set default `--prover.proveUnassignedBlocks` and `--mode.contester` value for guardian provers ([#492](https://github.com/taikoxyz/taiko-client/issues/492)) ([d5b798d](https://github.com/taikoxyz/taiko-client/commit/d5b798dbd8568af2e71285b6a29c0c4a327198e1)) +* **prover:** support SGX prover with raiko-host ([#473](https://github.com/taikoxyz/taiko-client/issues/473)) ([a27d353](https://github.com/taikoxyz/taiko-client/commit/a27d35351c6a8f7232cdb098b7888ebc80c200f2)) +* **prover:** update unretryable error check ([#532](https://github.com/taikoxyz/taiko-client/issues/532)) ([a5b067f](https://github.com/taikoxyz/taiko-client/commit/a5b067fde9301aa7b735f41a1fae0efa3fa48b54)) +* **repo:** implement EIP-4844 in client ([#526](https://github.com/taikoxyz/taiko-client/issues/526)) ([103cad2](https://github.com/taikoxyz/taiko-client/commit/103cad295adf9d29a2e5603a377d223c303eedd4)) +* **rpc:** improve reorg checks ([#510](https://github.com/taikoxyz/taiko-client/issues/510)) ([d375ee0](https://github.com/taikoxyz/taiko-client/commit/d375ee04f8a9dbc698d0c0b37492d2f4b4949329)) +* **rpc:** simplify RPC clients ([#521](https://github.com/taikoxyz/taiko-client/issues/521)) ([bbe9ed7](https://github.com/taikoxyz/taiko-client/commit/bbe9ed764e00029f54baec9e7c51664ee36c489b)) +* **test:** Upgrade test scripts ([#557](https://github.com/taikoxyz/taiko-client/issues/557)) ([940440c](https://github.com/taikoxyz/taiko-client/commit/940440cf918c3c3aebad622522243f3eb8d354b2)) +* **test:** use dynamic docker port ([#517](https://github.com/taikoxyz/taiko-client/issues/517)) ([430abd6](https://github.com/taikoxyz/taiko-client/commit/430abd6deed8117b2287183a662276607adb50b9)) + + +### Bug Fixes + +* **bindings:** fix `AssignmentHookABI` variable typo ([#468](https://github.com/taikoxyz/taiko-client/issues/468)) ([3b057f3](https://github.com/taikoxyz/taiko-client/commit/3b057f321bf051c150319406a76a3bbf03127572)) +* **docs:** fix swagger script ([#484](https://github.com/taikoxyz/taiko-client/issues/484)) ([a624c18](https://github.com/taikoxyz/taiko-client/commit/a624c183465fc0cfaea24f5b3db71eb11607ba3e)) +* **protocol:** fix an issue for prover initialization ([#480](https://github.com/taikoxyz/taiko-client/issues/480)) ([c656ddb](https://github.com/taikoxyz/taiko-client/commit/c656ddb6699c5834b99c7a774566bbfb3253a7d6)) +* **prover:** change separator ([#469](https://github.com/taikoxyz/taiko-client/issues/469)) ([8e8897f](https://github.com/taikoxyz/taiko-client/commit/8e8897fbe905fc14279988028407f3773e1d0a00)) +* **prover:** fix `--prover.allowance` flag ([#490](https://github.com/taikoxyz/taiko-client/issues/490)) ([271fb6f](https://github.com/taikoxyz/taiko-client/commit/271fb6f5737a8b297c6a6aefee1ec7ff2a71b1c5)) +* **prover:** fix `guardianProverSender.SendStartup` ([#533](https://github.com/taikoxyz/taiko-client/issues/533)) ([416ad68](https://github.com/taikoxyz/taiko-client/commit/416ad684a1ee128221ae1be2c6ed756e9de2b78a)) +* **prover:** fix guardian prover `log` package import ([#485](https://github.com/taikoxyz/taiko-client/issues/485)) ([e294b0b](https://github.com/taikoxyz/taiko-client/commit/e294b0bfb8cd493af736df70d3478882bb016b39)) +* **prover:** fix guardian prover database key ([#522](https://github.com/taikoxyz/taiko-client/issues/522)) ([35eee7c](https://github.com/taikoxyz/taiko-client/commit/35eee7c9fd5dc77d7eb61585f36d10fbf7179aaa)) +* **prover:** only store signed block after successfully sending http request ([#489](https://github.com/taikoxyz/taiko-client/issues/489)) ([956e202](https://github.com/taikoxyz/taiko-client/commit/956e20290681337fa03638437b390c2423802d58)) +* **rpc:** fix a bug / update logic ([#501](https://github.com/taikoxyz/taiko-client/issues/501)) ([0bb53b4](https://github.com/taikoxyz/taiko-client/commit/0bb53b406ed0fcebb9eba81700c3408ac54fc737)) +* **rpc:** fix an issue in `checkSyncedL1SnippetFromAnchor` && add more logs ([#511](https://github.com/taikoxyz/taiko-client/issues/511)) ([b2f2f0b](https://github.com/taikoxyz/taiko-client/commit/b2f2f0b71c3b698934b4041adac8c932c9983e34)) +* **test:** fix workflow errors ([#525](https://github.com/taikoxyz/taiko-client/issues/525)) ([60f128b](https://github.com/taikoxyz/taiko-client/commit/60f128b61fa48950b4b0afd6797626d4f03e070f)) + +## [0.18.0](https://github.com/taikoxyz/taiko-client/compare/v0.17.0...v0.18.0) (2023-12-03) + + +### Features + +* **bindings:** update Go contract bindings ([#443](https://github.com/taikoxyz/taiko-client/issues/443)) ([b155b5a](https://github.com/taikoxyz/taiko-client/commit/b155b5a173eabb9ca5a13ae7f10c47d5f506b8ae)) +* **bindings:** update Go contract bindings based on latest A6 protocol changes ([#435](https://github.com/taikoxyz/taiko-client/issues/435)) ([7e39dc2](https://github.com/taikoxyz/taiko-client/commit/7e39dc23eac6558de4de114725b5cb4020312d68)) +* **bindings:** update Go contract bindings based on the latest contestable zkRollup protocol ([#429](https://github.com/taikoxyz/taiko-client/issues/429)) ([d33e19b](https://github.com/taikoxyz/taiko-client/commit/d33e19be64929f820a8841e49fad8d0d541bd368)) +* **bindings:** update Go contract bindings for the latest protocol ([#441](https://github.com/taikoxyz/taiko-client/issues/441)) ([02c981d](https://github.com/taikoxyz/taiko-client/commit/02c981d4d700c3e1ca8032307945dee5723be3a2)) +* **bindings:** updates related to TaikoToken && guardian prover changes ([#436](https://github.com/taikoxyz/taiko-client/issues/436)) ([9066722](https://github.com/taikoxyz/taiko-client/commit/9066722ae4dc7637c0db3acb2699ce11d63c5962)) +* **docs:** host swagger doc by github page ([#427](https://github.com/taikoxyz/taiko-client/issues/427)) ([ab4e613](https://github.com/taikoxyz/taiko-client/commit/ab4e613de050d7e77b7942f02f9d596bf718fc75)) +* **driver:** improve `ResetL1Current` method based on the latest protocol changes ([#445](https://github.com/taikoxyz/taiko-client/issues/445)) ([ddf6980](https://github.com/taikoxyz/taiko-client/commit/ddf6980a97d7c14239458cdde535066aea14912d)) +* **driver:** update `anchorGasLimit` based on the latest `TaikoL2` contract ([#437](https://github.com/taikoxyz/taiko-client/issues/437)) ([171600a](https://github.com/taikoxyz/taiko-client/commit/171600ad7c107056081a4bac9e4a6d9eebd9c393)) +* **pkg:** update `defaultMaxTransactionsPerBlock` to `150` ([#438](https://github.com/taikoxyz/taiko-client/issues/438)) ([93b9ecf](https://github.com/taikoxyz/taiko-client/commit/93b9ecf635869964eb12b3dae3e304184a83becb)) +* **proposer:** remove `--l2.suggestedFeeRecipient` flag ([#442](https://github.com/taikoxyz/taiko-client/issues/442)) ([405b9ed](https://github.com/taikoxyz/taiko-client/commit/405b9ed03c7a2749f56fdb16849281a284bcc562)) +* **prover:** add `--prover.blockSlippage` flag ([#449](https://github.com/taikoxyz/taiko-client/issues/449)) ([0ee8259](https://github.com/taikoxyz/taiko-client/commit/0ee82593c2fc2704a2c8f0130fd1887bc67f764b)) +* **prover:** guardian prover block signature && bindings updates for based contestable zkRollup ([#450](https://github.com/taikoxyz/taiko-client/issues/450)) ([904d3e7](https://github.com/taikoxyz/taiko-client/commit/904d3e76dd67c71ea225144d12526e0291e2b39f)) +* **prover:** improve `/status` API ([#444](https://github.com/taikoxyz/taiko-client/issues/444)) ([e688c25](https://github.com/taikoxyz/taiko-client/commit/e688c256109e20ed5ea29fc03e97433acf7002bf)) +* **prover:** increase the assignment expiration waiting time ([#431](https://github.com/taikoxyz/taiko-client/issues/431)) ([579dcc5](https://github.com/taikoxyz/taiko-client/commit/579dcc50686f73f42961f1624f067ede52701b4e)) +* **prover:** more accurate `provingWindowExpiresAt` calculation && update bindings ([#433](https://github.com/taikoxyz/taiko-client/issues/433)) ([72c528f](https://github.com/taikoxyz/taiko-client/commit/72c528f8df4994f13060c92cc1c1162a228dfd49)) +* **test:** fix `suite.go` ([#453](https://github.com/taikoxyz/taiko-client/issues/453)) ([38fbb66](https://github.com/taikoxyz/taiko-client/commit/38fbb662c9ec46e4ea55689970faa70b56eeed4f)) + + +### Bug Fixes + +* **docs:** fix swagger generation ([#455](https://github.com/taikoxyz/taiko-client/issues/455)) ([9533761](https://github.com/taikoxyz/taiko-client/commit/9533761cfea43a5bf0d9093694ede881e0c95996)) +* **prover:** fix guardian prover APIs ([#459](https://github.com/taikoxyz/taiko-client/issues/459)) ([08c77f2](https://github.com/taikoxyz/taiko-client/commit/08c77f244dfc4630c767b826b3156fad7b09dca4)) +* **prover:** fix Guardian prover waiting ([#462](https://github.com/taikoxyz/taiko-client/issues/462)) ([8266845](https://github.com/taikoxyz/taiko-client/commit/82668458bb9050bca4d676b73299d7595c772851)) +* **prover:** guardian prover sign wait ([#461](https://github.com/taikoxyz/taiko-client/issues/461)) ([51fd8f9](https://github.com/taikoxyz/taiko-client/commit/51fd8f9e31d9e44eb0e9b82a500ad83ab52b1e92)) +* **prover:** reorder guardian prover signature && add allowance flag ([#457](https://github.com/taikoxyz/taiko-client/issues/457)) ([4bc2a63](https://github.com/taikoxyz/taiko-client/commit/4bc2a63c57c3897b2634abc40af72e55522d4af6)) +* **server:** fix a typo in `license.url` ([#460](https://github.com/taikoxyz/taiko-client/issues/460)) ([d632109](https://github.com/taikoxyz/taiko-client/commit/d63210935f21173e8b03a4a09cb72eabf70c7ef0)) +* **tests:** fix workflow errors ([#440](https://github.com/taikoxyz/taiko-client/issues/440)) ([8b3cef2](https://github.com/taikoxyz/taiko-client/commit/8b3cef2f7a90dfb9b08fdebe7bd8edd63776db00)) + +## [0.17.0](https://github.com/taikoxyz/taiko-client/compare/v0.16.0...v0.17.0) (2023-10-16) + + +### Features + +* **all:** changes based on contestable zkRollup protocol design ([#414](https://github.com/taikoxyz/taiko-client/issues/414)) ([25a0c3b](https://github.com/taikoxyz/taiko-client/commit/25a0c3bc6507c22f28817c2a1e966ea7199699d8)) + + +### Bug Fixes + +* **prover:** fix L1 height used in `onBlockProven` handler ([#421](https://github.com/taikoxyz/taiko-client/issues/421)) ([4a1012a](https://github.com/taikoxyz/taiko-client/commit/4a1012ac702acc4d1d1bae5c295cdad02c99caef)) + +## [0.16.0](https://github.com/taikoxyz/taiko-client/compare/v0.15.0...v0.16.0) (2023-09-30) + + +### Features + +* **all:** some client optimizations ([#376](https://github.com/taikoxyz/taiko-client/issues/376)) ([91bba90](https://github.com/taikoxyz/taiko-client/commit/91bba902febbf6ce8d4fd37dfb2b0fe7c181191d)) +* **bindings:** update contract bindings ([#394](https://github.com/taikoxyz/taiko-client/issues/394)) ([5b9346b](https://github.com/taikoxyz/taiko-client/commit/5b9346b9587c155372cede757f048e2c9faea4a2)) +* **flag:** fix some typo ([#391](https://github.com/taikoxyz/taiko-client/issues/391)) ([5f7f1dd](https://github.com/taikoxyz/taiko-client/commit/5f7f1dd8248a204d8451e0c5fd37ede870fa7f07)) +* **proposer:** shuffle prover endpoints before assigning proof tasks ([#390](https://github.com/taikoxyz/taiko-client/issues/390)) ([96488d0](https://github.com/taikoxyz/taiko-client/commit/96488d0f7045174b227a20bc51b241d25f683098)) +* **proposer:** update oracle proof assignment ([#393](https://github.com/taikoxyz/taiko-client/issues/393)) ([29c2d4b](https://github.com/taikoxyz/taiko-client/commit/29c2d4ba23e2d2d9d1d8389b68679b851a3fd33e)) +* **proposer:** update prover endpoint scheme check ([#400](https://github.com/taikoxyz/taiko-client/issues/400)) ([ce8bd1d](https://github.com/taikoxyz/taiko-client/commit/ce8bd1d78002209227d283a89c08775fa06bc431)) +* **prover_selector:** check prover's token balance ([#406](https://github.com/taikoxyz/taiko-client/issues/406)) ([834c0ea](https://github.com/taikoxyz/taiko-client/commit/834c0ea62353a5a92245ac5412b7d8714d92c4da)) +* **prover:** add more capacity related logs ([#408](https://github.com/taikoxyz/taiko-client/issues/408)) ([22014b2](https://github.com/taikoxyz/taiko-client/commit/22014b2f2b9bf4f35590273c64b888920ce82ffc)) +* **prover:** always use the oracle prover private key when an oracle prover starting a server ([#395](https://github.com/taikoxyz/taiko-client/issues/395)) ([cc28d63](https://github.com/taikoxyz/taiko-client/commit/cc28d631cb3c6ba0365034f0a9cbe3d6ce44492a)) +* **prover:** check `transition.blockHash` before proof generation ([#415](https://github.com/taikoxyz/taiko-client/issues/415)) ([dd77f7a](https://github.com/taikoxyz/taiko-client/commit/dd77f7a07b56abb2724a7a46113b9f39e922a13b)) +* **prover:** increase `gasTipCap` when resending `TaikoL1.proveBlock` transactions ([#411](https://github.com/taikoxyz/taiko-client/issues/411)) ([f192e0a](https://github.com/taikoxyz/taiko-client/commit/f192e0a6b8237fa5cbcdc80d91f4333e76a1afc3)) +* **prover:** release capacity when the corresponding local proof generation is canceled ([#402](https://github.com/taikoxyz/taiko-client/issues/402)) ([1eab54d](https://github.com/taikoxyz/taiko-client/commit/1eab54deb024baa1e5c46a725153172ed289b9f8)) +* **prover:** tie capacity to a specific block id ([#413](https://github.com/taikoxyz/taiko-client/issues/413)) ([bdca930](https://github.com/taikoxyz/taiko-client/commit/bdca930f47f7efd2e3661d57a3507eae09db339d)) +* **prover:** update APIs && integrate swagger docs ([#386](https://github.com/taikoxyz/taiko-client/issues/386)) ([ebdb3da](https://github.com/taikoxyz/taiko-client/commit/ebdb3daba25921b572578fca2f5c981e4e014e54)) +* **prover:** use `httptest.Server` to simplify the prover server tests ([#389](https://github.com/taikoxyz/taiko-client/issues/389)) ([84eedae](https://github.com/taikoxyz/taiko-client/commit/84eedaedfe01e736d7c6a8523e68c4fad878e8c4)) + + +### Bug Fixes + +* **ci:** fix workflow errors ([#410](https://github.com/taikoxyz/taiko-client/issues/410)) ([5a3b655](https://github.com/taikoxyz/taiko-client/commit/5a3b6551458ebe6212c2ad7dee0a9291be42fd86)) +* **proposer:** fix proposing fee initialization ([#396](https://github.com/taikoxyz/taiko-client/issues/396)) ([2f2007d](https://github.com/taikoxyz/taiko-client/commit/2f2007d5810b8994172a59cb88052b9b8b8acb87)) +* **prover:** capacity needs to be taken before generating proof ([#412](https://github.com/taikoxyz/taiko-client/issues/412)) ([7d9c244](https://github.com/taikoxyz/taiko-client/commit/7d9c2446a45f3d338c222ea5bd269ea49fcb135b)) +* **prover:** check latest verified ID on proof submission ([#387](https://github.com/taikoxyz/taiko-client/issues/387)) ([8157550](https://github.com/taikoxyz/taiko-client/commit/81575502e88f06f34a2f36baa6bad66d0fa12884)) +* **prover:** fix a capacity release issue ([#405](https://github.com/taikoxyz/taiko-client/issues/405)) ([4ab061f](https://github.com/taikoxyz/taiko-client/commit/4ab061f9f2c6fecfdcc164ade398e0acbacbf8cd)) +* **prover:** prover rpc didnt have taiko token address ([#407](https://github.com/taikoxyz/taiko-client/issues/407)) ([4e0e390](https://github.com/taikoxyz/taiko-client/commit/4e0e390abebbd8ec3b56f0fe729a7573c26e1fdd)) +* **test:** fix flags related tests ([#409](https://github.com/taikoxyz/taiko-client/issues/409)) ([4f0a602](https://github.com/taikoxyz/taiko-client/commit/4f0a6020b22473c83743450197f68393410adf2d)) + +## [0.15.0](https://github.com/taikoxyz/taiko-client/compare/v0.14.0...v0.15.0) (2023-09-04) + + +### Features + +* **all:** update bindings based on latest tokenomics changes ([#367](https://github.com/taikoxyz/taiko-client/issues/367)) ([28ea4db](https://github.com/taikoxyz/taiko-client/commit/28ea4dbb658a7e708ffb7bc54a194a29d7013f18)) +* **bindings:** rename fork choice to state transition ([#372](https://github.com/taikoxyz/taiko-client/issues/372)) ([e09fd97](https://github.com/taikoxyz/taiko-client/commit/e09fd977b0fe2fa2efa8642b419d3dda21d8f3b0)) +* **bindings:** update bindings && remove unused files ([#360](https://github.com/taikoxyz/taiko-client/issues/360)) ([24b9309](https://github.com/taikoxyz/taiko-client/commit/24b9309532089f74ba0c3b04db721f6c6d6cd0a0)) +* **bindings:** update contract bindings ([#377](https://github.com/taikoxyz/taiko-client/issues/377)) ([becdd73](https://github.com/taikoxyz/taiko-client/commit/becdd735e83a5b444ed04671e4957ce44ab222a1)) +* **pkg:** add `isSyncing` method ([#379](https://github.com/taikoxyz/taiko-client/issues/379)) ([9c7a19a](https://github.com/taikoxyz/taiko-client/commit/9c7a19a1f32ea6a8ba7082bfff2deb04f8826a05)) +* **proposer:** update proposing retry policy ([#366](https://github.com/taikoxyz/taiko-client/issues/366)) ([e0adf17](https://github.com/taikoxyz/taiko-client/commit/e0adf175b87ec1ba4c5b4068794e6842b1ca129f)) + + +### Bug Fixes + +* **all:** fix missing logs should be print in stderr ([#370](https://github.com/taikoxyz/taiko-client/issues/370)) ([af6531b](https://github.com/taikoxyz/taiko-client/commit/af6531bb1fe2cc43a32772d264b56b8e5f243786)) +* **prover:** add to wait group in prover ([#373](https://github.com/taikoxyz/taiko-client/issues/373)) ([edf95a7](https://github.com/taikoxyz/taiko-client/commit/edf95a72a91005f6be5402b17b145928e55d9256)) +* **prover:** fix `maxRetry` configuration when submitting proofs ([#364](https://github.com/taikoxyz/taiko-client/issues/364)) ([b6cd4db](https://github.com/taikoxyz/taiko-client/commit/b6cd4db1cffd15f95f383b2c5058d1c95d30d473)) +* **prover:** fix some typo ([#374](https://github.com/taikoxyz/taiko-client/issues/374)) ([355e68b](https://github.com/taikoxyz/taiko-client/commit/355e68bc53bf01684198076fdd0c8a3ddb4bbed3)) + +## [0.14.0](https://github.com/taikoxyz/taiko-client/compare/v0.13.0...v0.14.0) (2023-08-09) + + +### Features + +* **bindings:** update `TaikoL1BlockMetadataInput` ([#359](https://github.com/taikoxyz/taiko-client/issues/359)) ([1beae59](https://github.com/taikoxyz/taiko-client/commit/1beae59cfbe1345a5bb69714b25ba4397173be45)) +* **bindings:** update go contract bindings ([#346](https://github.com/taikoxyz/taiko-client/issues/346)) ([c6454af](https://github.com/taikoxyz/taiko-client/commit/c6454afe28b3a86c8d33c8434cfd345318116076)) +* **bindings:** update go contract bindings ([#352](https://github.com/taikoxyz/taiko-client/issues/352)) ([b9da8f6](https://github.com/taikoxyz/taiko-client/commit/b9da8f68e733a51255c1307d016d1ff9e241f3c9)) +* **driver:** update `l1Current` check in `ProcessL1Blocks` ([#340](https://github.com/taikoxyz/taiko-client/issues/340)) ([d67f287](https://github.com/taikoxyz/taiko-client/commit/d67f287bd5cce08aa5b7ba9fd33fc00e91ad6190)) +* **pkg:** add default timeout for `GetStorageRoot` ([#347](https://github.com/taikoxyz/taiko-client/issues/347)) ([9a4dee0](https://github.com/taikoxyz/taiko-client/commit/9a4dee04f90e521832efef5febeebb1231e22a19)) +* **pkg:** improve archive node check ([#334](https://github.com/taikoxyz/taiko-client/issues/334)) ([c6cd1b0](https://github.com/taikoxyz/taiko-client/commit/c6cd1b0492499b3c686ac282d65743793bd162da)) +* **pkg:** introduce `EthClient` with a timeout attached ([#337](https://github.com/taikoxyz/taiko-client/issues/337)) ([1608aba](https://github.com/taikoxyz/taiko-client/commit/1608abae268bbbe6671ec9eb89fed2846065852c)) +* **pkg:** optimize `CheckL1ReorgFromL1Cursor` ([#329](https://github.com/taikoxyz/taiko-client/issues/329)) ([ed63c1f](https://github.com/taikoxyz/taiko-client/commit/ed63c1f8e4ba6a9fd40b1d1d5f3bba217d470f4b)) +* **pkg:** Wait receipt timeout ([#343](https://github.com/taikoxyz/taiko-client/issues/343)) ([cf261d3](https://github.com/taikoxyz/taiko-client/commit/cf261d377f61ea0b0ff049be7e8c8eb75264f386)) +* **proposer:** add `--proposeBlockTxGasTipCap` flag ([#349](https://github.com/taikoxyz/taiko-client/issues/349)) ([e40115b](https://github.com/taikoxyz/taiko-client/commit/e40115b97002661def8eed8dfb768ad28c19f0ea)) +* **proposer:** update pool content query ([#341](https://github.com/taikoxyz/taiko-client/issues/341)) ([221a3b9](https://github.com/taikoxyz/taiko-client/commit/221a3b92b77f4b3d3e5499eb27fa289ae44b0151)) +* **proposer:** use `TaikoConfig.blockMaxGasLimit` as proposed block gasLimit && remove some unused flags ([#344](https://github.com/taikoxyz/taiko-client/issues/344)) ([f0a3da7](https://github.com/taikoxyz/taiko-client/commit/f0a3da7d6bf8af222ae6e780218ccca2c7861137)) +* **prover:** add `--proofSubmissionMaxRetry` flag ([#333](https://github.com/taikoxyz/taiko-client/issues/333)) ([8d92b7a](https://github.com/taikoxyz/taiko-client/commit/8d92b7aa96d22ca20de57fd02e52d7f3f6ff9a5f)) +* **prover:** changes based on `proofVerifier` protocol updates ([#338](https://github.com/taikoxyz/taiko-client/issues/338)) ([6dcb34a](https://github.com/taikoxyz/taiko-client/commit/6dcb34aab3619731852a19a09b54aadce34de999)) +* **prover:** prove block tx gas limit ([#357](https://github.com/taikoxyz/taiko-client/issues/357)) ([8ed4da2](https://github.com/taikoxyz/taiko-client/commit/8ed4da2f0bd0bf5f215767b1bd44106dd878431f)) +* **rpc:** check if L1 rpc is an archive node ([#332](https://github.com/taikoxyz/taiko-client/issues/332)) ([b1aa1d3](https://github.com/taikoxyz/taiko-client/commit/b1aa1d388d407f2f5cb14275c006b1a22213b8ff)) + + +### Bug Fixes + +* **pkg:** fix returned context error from `WaitL1Origin` ([#331](https://github.com/taikoxyz/taiko-client/issues/331)) ([0ebf121](https://github.com/taikoxyz/taiko-client/commit/0ebf121dcae5e75d359bc7818aa98fa6f7b1bc20)) +* **pkg:** set more RPC context timeout ([#356](https://github.com/taikoxyz/taiko-client/issues/356)) ([ffe2f90](https://github.com/taikoxyz/taiko-client/commit/ffe2f906808f99a48f6a848351c9a34ea63f02b7)) +* **prover:** default prove unassigned blocks to false ([#354](https://github.com/taikoxyz/taiko-client/issues/354)) ([ed34ef6](https://github.com/taikoxyz/taiko-client/commit/ed34ef670a3deef5f4db88429cd13c5bdb108289)) +* **prover:** fix `onBlockProposed` reorg detection ([#348](https://github.com/taikoxyz/taiko-client/issues/348)) ([4877e01](https://github.com/taikoxyz/taiko-client/commit/4877e01f7c35f0cbce329e14948dd78b5de0c911)) + +## [0.13.0](https://github.com/taikoxyz/taiko-client/compare/v0.12.0...v0.13.0) (2023-07-23) + + +### Features + +* **cmd:** update `proveUnassignedBlocks` flag name ([#315](https://github.com/taikoxyz/taiko-client/issues/315)) ([df640d9](https://github.com/taikoxyz/taiko-client/commit/df640d9d49ceb84268801021ba70fea8e278f39e)) +* **driver:** improve `ProcessL1Blocks` for reorg handling ([#325](https://github.com/taikoxyz/taiko-client/issues/325)) ([7272e15](https://github.com/taikoxyz/taiko-client/commit/7272e15650e9ab6aded598e9edcae2659b9d045d)) +* **proposer:** add `--txpool.localsOnly` flag ([#326](https://github.com/taikoxyz/taiko-client/issues/326)) ([b292754](https://github.com/taikoxyz/taiko-client/commit/b2927541706e7827dad652140361f4ccf91d1afb)) +* **proposer:** handle transaction replacement underpriced error ([#322](https://github.com/taikoxyz/taiko-client/issues/322)) ([2273d10](https://github.com/taikoxyz/taiko-client/commit/2273d105b5dfa6479dc2aa74c16fd0365d06e31a)) +* **prover:** add `--oracleProofSubmissionDelay` flag ([#320](https://github.com/taikoxyz/taiko-client/issues/320)) ([85adc04](https://github.com/taikoxyz/taiko-client/commit/85adc04dceabd6218afee72f748e17d69182d81d)) +* **prover:** add some prover metrics for Alpha-4 protocol ([#319](https://github.com/taikoxyz/taiko-client/issues/319)) ([d8ff623](https://github.com/taikoxyz/taiko-client/commit/d8ff623a441226c736bd4c52d95df69dd2ce4c86)) +* **prover:** flag for proving unassigned proofs or not ([#314](https://github.com/taikoxyz/taiko-client/issues/314)) ([13e6d1d](https://github.com/taikoxyz/taiko-client/commit/13e6d1d87d661c1bdcd9e1537b10b42b33888298)) +* **prover:** generate an oracle proof if the incoming proof is incorrect ([#311](https://github.com/taikoxyz/taiko-client/issues/311)) ([003a86b](https://github.com/taikoxyz/taiko-client/commit/003a86bfd3e8f00a4b3c35d048ede6177739a45e)) +* **prover:** optimize `skipProofWindowExpiredCheck` check && update `NeedNewProof` check ([#313](https://github.com/taikoxyz/taiko-client/issues/313)) ([b0b4c25](https://github.com/taikoxyz/taiko-client/commit/b0b4c252291ff8d163d2eb71114aa7d63c821c7e)) +* **prover:** update `l1Current` cursor to record L1 hash ([#327](https://github.com/taikoxyz/taiko-client/issues/327)) ([4a5adb5](https://github.com/taikoxyz/taiko-client/commit/4a5adb523374008a37831da5febff9a3501a4e81)) +* **prover:** update open proving blocks check ([#316](https://github.com/taikoxyz/taiko-client/issues/316)) ([b34930c](https://github.com/taikoxyz/taiko-client/commit/b34930cd4982672bbea962f3706cb83d7e964963)) + + +### Bug Fixes + +* **ci:** fix workflow `pnpm install` error ([#321](https://github.com/taikoxyz/taiko-client/issues/321)) ([9eefc8d](https://github.com/taikoxyz/taiko-client/commit/9eefc8d401a35eee1c9b31f5e3c93e18e2754013)) +* **prover:** add end height for block filtering if `startHeight` is not nil, and don't block when notifying ([#317](https://github.com/taikoxyz/taiko-client/issues/317)) ([aaec1bb](https://github.com/taikoxyz/taiko-client/commit/aaec1bbdd54df6d60ce39428febbb2747838c31a)) +* **prover:** move concurrency guard ([#318](https://github.com/taikoxyz/taiko-client/issues/318)) ([af29c95](https://github.com/taikoxyz/taiko-client/commit/af29c9503def11c373c16555c020307348c5cff6)) + +## [0.12.0](https://github.com/taikoxyz/taiko-client/compare/v0.11.0...v0.12.0) (2023-07-10) + + +### Features + +* **all:** update bindings && integrate new circuits for L3 ([#290](https://github.com/taikoxyz/taiko-client/issues/290)) ([59469fa](https://github.com/taikoxyz/taiko-client/commit/59469fac2fefe1046d805dc1f19911150e453d87)) +* **bindings:** update contract bindings ([#310](https://github.com/taikoxyz/taiko-client/issues/310)) ([021f113](https://github.com/taikoxyz/taiko-client/commit/021f113c2add574843f889b525d55789752b1bd6)) +* **prover:** add some prover logs ([#305](https://github.com/taikoxyz/taiko-client/issues/305)) ([e36c76c](https://github.com/taikoxyz/taiko-client/commit/e36c76c7ea6d912477dc8ce61e4639faef00eb5c)) +* **prover:** implement staking based tokenomics in client ([#292](https://github.com/taikoxyz/taiko-client/issues/292)) ([7324547](https://github.com/taikoxyz/taiko-client/commit/7324547a80182e93193479089bd334fcce5df7ce)) + + +### Bug Fixes + +* **driver:** fix a P2P sync issue ([#298](https://github.com/taikoxyz/taiko-client/issues/298)) ([2ffa052](https://github.com/taikoxyz/taiko-client/commit/2ffa0528110db70f34dd3ef6f48008487caa78a2)) +* **prover:** fix a fork choice checking issue ([#309](https://github.com/taikoxyz/taiko-client/issues/309)) ([a393ed8](https://github.com/taikoxyz/taiko-client/commit/a393ed85fed4046039b66bda51bb645ed84d8461)) +* **prover:** fix an unlock issue ([#306](https://github.com/taikoxyz/taiko-client/issues/306)) ([392eb78](https://github.com/taikoxyz/taiko-client/commit/392eb78f3721fedea66bd2f361010e2495e385c6)) + +## [0.11.0](https://github.com/taikoxyz/taiko-client/compare/v0.10.0...v0.11.0) (2023-06-26) + + +### Features + +* **all:** disable no beacon client seen warning ([#279](https://github.com/taikoxyz/taiko-client/issues/279)) ([cdabcac](https://github.com/taikoxyz/taiko-client/commit/cdabcacb36303667560300775573a4db55fbd5d4)) +* **driver:** check the mismatch of last verified block ([#296](https://github.com/taikoxyz/taiko-client/issues/296)) ([79fda87](https://github.com/taikoxyz/taiko-client/commit/79fda8792b29d506b5fa653ed78304d34e892003)) +* **driver:** improve error messages ([#289](https://github.com/taikoxyz/taiko-client/issues/289)) ([90e365a](https://github.com/taikoxyz/taiko-client/commit/90e365a79759e0ea701619594b0bf71db4dd3b44)) +* **driver:** improve sync progress information ([#288](https://github.com/taikoxyz/taiko-client/issues/288)) ([45d73b9](https://github.com/taikoxyz/taiko-client/commit/45d73b9da34232cf6a3c8636e97aef5854bb86bb)) +* **flags:** add retry related flags ([#281](https://github.com/taikoxyz/taiko-client/issues/281)) ([2df4105](https://github.com/taikoxyz/taiko-client/commit/2df4105ab344fb118435b7ef53bcf13ac10f5dc7)) +* **metrics:** add `ProverNormalProofRewardGauge` metrics ([#275](https://github.com/taikoxyz/taiko-client/issues/275)) ([cd4e40d](https://github.com/taikoxyz/taiko-client/commit/cd4e40dd477895746843021732a1beba14fa248a)) +* **proposer:** add `waitReceiptTimeout` when proposing ([#282](https://github.com/taikoxyz/taiko-client/issues/282)) ([ebf3162](https://github.com/taikoxyz/taiko-client/commit/ebf31623dc491887a25a76da0078559d0b86865c)) +* **prover:** improve retry policy for prover ([#280](https://github.com/taikoxyz/taiko-client/issues/280)) ([344bac1](https://github.com/taikoxyz/taiko-client/commit/344bac1435812770c5a1e39efad1545b98d4b106)) + + +### Bug Fixes + +* **driver:** fix an issue in `checkLastVerifiedBlockMismatch` ([#297](https://github.com/taikoxyz/taiko-client/issues/297)) ([a68730c](https://github.com/taikoxyz/taiko-client/commit/a68730c0d9cc1b15cdd314ad7939f8971104b362)) +* **driver:** fix geth lag to verified block when syncing ([#294](https://github.com/taikoxyz/taiko-client/issues/294)) ([c57f6e8](https://github.com/taikoxyz/taiko-client/commit/c57f6e8ac84ad55c0d51bfae278c88f7694c2265)) +* **pkg:** minor fixes for `WaitReceipt` ([#284](https://github.com/taikoxyz/taiko-client/issues/284)) ([feaa2b6](https://github.com/taikoxyz/taiko-client/commit/feaa2b6487e1578c4082ba0b4be087a627512c4b)) +* **prover:** ensure L2 reorg finished before generating proofs && add `verificationCheckTicker` ([#277](https://github.com/taikoxyz/taiko-client/issues/277)) ([6fa24ea](https://github.com/taikoxyz/taiko-client/commit/6fa24ea2b4674865dc381098e57a2171c9fce95b)) + +## [0.10.0](https://github.com/taikoxyz/taiko-client/compare/v0.9.0...v0.10.0) (2023-06-08) + + +### Features + +* **all:** improve proposer && prover logs ([#264](https://github.com/taikoxyz/taiko-client/issues/264)) ([6d0a724](https://github.com/taikoxyz/taiko-client/commit/6d0a7248d78fcd0a73e53a89a21adbeff7f3b61b)) +* **driver:** add proof reward metric ([#273](https://github.com/taikoxyz/taiko-client/issues/273)) ([1e00560](https://github.com/taikoxyz/taiko-client/commit/1e00560a1564d61448687ad933fe39a301020bf9)) +* **driver:** optimize error handling for `CalldataSyncer` ([#262](https://github.com/taikoxyz/taiko-client/issues/262)) ([580e354](https://github.com/taikoxyz/taiko-client/commit/580e35487b32566761721422bf8d0ca9e5071ed5)) +* **pkg:** optimize `WaitL1Origin` ([#267](https://github.com/taikoxyz/taiko-client/issues/267)) ([2d1fda9](https://github.com/taikoxyz/taiko-client/commit/2d1fda90ec54fb25eee789968b9d2177017ace6f)) +* **pkg:** update logs when dialing ethclients ([#263](https://github.com/taikoxyz/taiko-client/issues/263)) ([99c980b](https://github.com/taikoxyz/taiko-client/commit/99c980becd0ea2872e6f91b8f422fe66ca8ebfb2)) +* **proposer:** add `--maxProposedTxListsPerEpoch` flag ([#258](https://github.com/taikoxyz/taiko-client/issues/258)) ([2cfcf81](https://github.com/taikoxyz/taiko-client/commit/2cfcf814200c2d41d539a427c94fe2a7fefcaf21)) +* **prover:** check if a system proof has already been submitted by another system prover ([#274](https://github.com/taikoxyz/taiko-client/issues/274)) ([1fcb244](https://github.com/taikoxyz/taiko-client/commit/1fcb244b29467fcdb7972a724a1ace8b94a67eb8)) +* **prover:** improve `onBlockProposed` listener ([#266](https://github.com/taikoxyz/taiko-client/issues/266)) ([5cbdcac](https://github.com/taikoxyz/taiko-client/commit/5cbdcacaa7f902875bb870ea909c7b5ad92220dd)) +* **prover:** improve `ZkevmRpcdProducer` logs ([#265](https://github.com/taikoxyz/taiko-client/issues/265)) ([d3fdd94](https://github.com/taikoxyz/taiko-client/commit/d3fdd94f95593567350a86bead5750b12cfd31be)) +* **prover:** update proof submission logs ([#261](https://github.com/taikoxyz/taiko-client/issues/261)) ([ea87f7f](https://github.com/taikoxyz/taiko-client/commit/ea87f7f8252073814007d9d54d71cc00171237d7)) + + +### Bug Fixes + +* **driver:** fix an issue for P2P sync timeout ([#268](https://github.com/taikoxyz/taiko-client/issues/268)) ([3aee10c](https://github.com/taikoxyz/taiko-client/commit/3aee10c0ba9170eb652e059c51ce029b2af8a3a4)) +* **prover:** fix a `targetDelay` calculation issue ([#272](https://github.com/taikoxyz/taiko-client/issues/272)) ([ffcfb53](https://github.com/taikoxyz/taiko-client/commit/ffcfb53e1be7ffe04fdb67ef9a176cc37b7369da)) + +## [0.9.0](https://github.com/taikoxyz/taiko-client/compare/v0.8.0...v0.9.0) (2023-06-04) + + +### Features + +* **all:** check L1 reorg before each operation ([#252](https://github.com/taikoxyz/taiko-client/issues/252)) ([e76b03f](https://github.com/taikoxyz/taiko-client/commit/e76b03f4af7ab1d300d206c246f736b0c5cb2241)) +* **all:** rename `treasure` to `treasury` ([#233](https://github.com/taikoxyz/taiko-client/issues/233)) ([252959f](https://github.com/taikoxyz/taiko-client/commit/252959f6e80f731da7526c655aeac0eec3b428b2)) +* **all:** update protocol bindings and some related changes ([#237](https://github.com/taikoxyz/taiko-client/issues/237)) ([3e12042](https://github.com/taikoxyz/taiko-client/commit/3e12042a9a5b5b9baca7de1b342788b22b2ca17e)) +* **bindings:** update bindings with EthDeposit changes ([#255](https://github.com/taikoxyz/taiko-client/issues/255)) ([f91f2dd](https://github.com/taikoxyz/taiko-client/commit/f91f2dd64e1fe25bc55790a8a93ea0ffab54ca3b)) +* **bindings:** update go contract bindings ([#243](https://github.com/taikoxyz/taiko-client/issues/243)) ([132500e](https://github.com/taikoxyz/taiko-client/commit/132500e27d135e6e5f89c96716a0bb2d17b6801b)) +* **driver:** optimize reorg handling && add more tests ([#256](https://github.com/taikoxyz/taiko-client/issues/256)) ([20c38a1](https://github.com/taikoxyz/taiko-client/commit/20c38a171ef617ddeecbe325d29d64c963792c07)) +* **pkg:** do not return error when genesis block not found ([#244](https://github.com/taikoxyz/taiko-client/issues/244)) ([8033e31](https://github.com/taikoxyz/taiko-client/commit/8033e31728c946a80fdd3d07f737241c7e19edf8)) +* **proof_producer:** update request parameters based on new circuits changes ([#240](https://github.com/taikoxyz/taiko-client/issues/240)) ([31521ef](https://github.com/taikoxyz/taiko-client/commit/31521ef8b7362dacbf183dc8c7d9a6020d1b0fc4)) +* **proposer:** add a `--minimalBlockGasLimit` flag to mitigate the potential gas estimation issue ([#225](https://github.com/taikoxyz/taiko-client/issues/225)) ([ab8305d](https://github.com/taikoxyz/taiko-client/commit/ab8305d39d1ca3375c6477b84d4afe5c729e815f)) +* **proposer:** add a new metric to track block fee ([#224](https://github.com/taikoxyz/taiko-client/issues/224)) ([98c17f0](https://github.com/taikoxyz/taiko-client/commit/98c17f00ade4fa20251a59b3aba4cad9e1eb1bd8)) +* **proposer:** propose multiple L2 blocks in one L1 block ([#254](https://github.com/taikoxyz/taiko-client/issues/254)) ([36ba5db](https://github.com/taikoxyz/taiko-client/commit/36ba5dbcc2863dc34fda2e59bf8a9d30d3665d04)) +* **prover:** add `--expectedReward` flag ([#248](https://github.com/taikoxyz/taiko-client/issues/248)) ([f64a762](https://github.com/taikoxyz/taiko-client/commit/f64a7620726019a2e7f5eada7b92087663b273fd)) +* **prover:** improve proof submission delay calculation ([#249](https://github.com/taikoxyz/taiko-client/issues/249)) ([7cc5d54](https://github.com/taikoxyz/taiko-client/commit/7cc5d541bef0eac9078bc93eb5f1d9954b164e9b)) +* **prover:** normal prover should wait targetProofTime before submitting proofs ([#232](https://github.com/taikoxyz/taiko-client/issues/232)) ([2128ddc](https://github.com/taikoxyz/taiko-client/commit/2128ddc325aaf8acf538fdd50e299187da8543dd)) +* **prover:** remove submission delay when running as a system prover ([#221](https://github.com/taikoxyz/taiko-client/issues/221)) ([49a25dd](https://github.com/taikoxyz/taiko-client/commit/49a25dd72888ee54209ddce51c6a701803728d86)) +* **prover:** remove the unnecessary special proof delay ([#226](https://github.com/taikoxyz/taiko-client/issues/226)) ([dcead44](https://github.com/taikoxyz/taiko-client/commit/dcead44a32ec9d064af423af0f2effea8b819fca)) +* **prover:** updates based on protocol `proofTimeTarget` changes ([#227](https://github.com/taikoxyz/taiko-client/issues/227)) ([c6ea860](https://github.com/taikoxyz/taiko-client/commit/c6ea860d736828fdb50e16447dee44733371c06f)) +* **repo:** enable OpenAI-based review ([#235](https://github.com/taikoxyz/taiko-client/issues/235)) ([88e4dae](https://github.com/taikoxyz/taiko-client/commit/88e4dae2e37c58273438335daade21587f25ec27)) + + +### Bug Fixes + +* **driver:** handle reorg ([#216](https://github.com/taikoxyz/taiko-client/issues/216)) ([fc2ec63](https://github.com/taikoxyz/taiko-client/commit/fc2ec637f5509b67572bb4d978f7bc41860e9b43)) +* **flag:** add a missing driver flag to configuration ([#246](https://github.com/taikoxyz/taiko-client/issues/246)) ([0b60243](https://github.com/taikoxyz/taiko-client/commit/0b60243fbc03bbfc2aceb8933ae9901d4b385117)) +* **prover:** fix an issue in prover event loop ([#257](https://github.com/taikoxyz/taiko-client/issues/257)) ([c550f09](https://github.com/taikoxyz/taiko-client/commit/c550f09d33f638f38461e576684432d90d850ac3)) +* **prover:** update bindings && fix a delay calculation issue ([#242](https://github.com/taikoxyz/taiko-client/issues/242)) ([49c3d69](https://github.com/taikoxyz/taiko-client/commit/49c3d6957b296b1312a53fcb5122fcd944b77c2d)) +* **repo:** fix openAI review workflow ([#253](https://github.com/taikoxyz/taiko-client/issues/253)) ([f44530b](https://github.com/taikoxyz/taiko-client/commit/f44530b428396b8514f974cf8ec476078d20c9d6)) + +## [0.8.0](https://github.com/taikoxyz/taiko-client/compare/v0.7.0...v0.8.0) (2023-05-12) + + +### Features + +* **proposer:** check tko balance and fee before proposing ([#205](https://github.com/taikoxyz/taiko-client/issues/205)) ([cc0da63](https://github.com/taikoxyz/taiko-client/commit/cc0da632c825c1379f039f489d7426548527cc80)) +* **prover:** add oracle proof submission delay ([#199](https://github.com/taikoxyz/taiko-client/issues/199)) ([7b5ed94](https://github.com/taikoxyz/taiko-client/commit/7b5ed94d12b0982de46e5ed66b38cffcf9c0c0d4)) +* **prover:** add special prover (system / oracle) ([#214](https://github.com/taikoxyz/taiko-client/issues/214)) ([1020377](https://github.com/taikoxyz/taiko-client/commit/1020377bec7115efd757a6c2ea78cfe9a97b6430)) +* **prover:** cancel proof if it becomes verified ([#207](https://github.com/taikoxyz/taiko-client/issues/207)) ([74d1729](https://github.com/taikoxyz/taiko-client/commit/74d17296c48a323e3ed78424b98aea9a93e081ca)) +* **prover:** implementing `--graffiti` flag for prover as input to block evidence ([#209](https://github.com/taikoxyz/taiko-client/issues/209)) ([2340210](https://github.com/taikoxyz/taiko-client/commit/2340210437a14618774265d2ad2f80989296aeae)) +* **prover:** improve oracle proof submission delay ([#212](https://github.com/taikoxyz/taiko-client/issues/212)) ([20c1423](https://github.com/taikoxyz/taiko-client/commit/20c14235b087e4624427879aa587a1599690dbbb)) +* **prover:** update `ZkevmRpcdProducer` to integrate new circuits ([#217](https://github.com/taikoxyz/taiko-client/issues/217)) ([81cf612](https://github.com/taikoxyz/taiko-client/commit/81cf6120c1610f7a8edaa183eb9a0fbbeb45b5f1)) +* **prover:** update canceling proof logic ([#218](https://github.com/taikoxyz/taiko-client/issues/218)) ([21d7e78](https://github.com/taikoxyz/taiko-client/commit/21d7e78d2e83fdd060fbc0303b244dee9777fcc4)) +* **prover:** update skip checking for system prover ([#215](https://github.com/taikoxyz/taiko-client/issues/215)) ([79ba210](https://github.com/taikoxyz/taiko-client/commit/79ba2104216dfee0a1b1556c4abc5abc76c5a266)) + + +### Bug Fixes + +* **driver:** fix `GetBasefee` parameters ([#210](https://github.com/taikoxyz/taiko-client/issues/210)) ([b5dc5c5](https://github.com/taikoxyz/taiko-client/commit/b5dc5c589d26b8e9e2420ecb38ea5c83b2ae7c2e)) +* **prover:** fix some oracle proof submission issues ([#211](https://github.com/taikoxyz/taiko-client/issues/211)) ([e061540](https://github.com/taikoxyz/taiko-client/commit/e06154058127962b90d5ab4a95cfec7c71942de3)) +* **prover:** submit L2 signal root with submitting proof ([#220](https://github.com/taikoxyz/taiko-client/issues/220)) ([8b030ed](https://github.com/taikoxyz/taiko-client/commit/8b030ed1a8fcf1a948a2272ff8ae3927c8957d84)) +* **prover:** submit L2 signal service root instead of L1 when submitting proof ([#219](https://github.com/taikoxyz/taiko-client/issues/219)) ([74fe156](https://github.com/taikoxyz/taiko-client/commit/74fe1567d0cc43e2d26d3f4af777794bc6c3a9f5)) + +## [0.7.0](https://github.com/taikoxyz/taiko-client/compare/v0.6.0...v0.7.0) (2023-04-28) + + +### Features + +* **all:** update client software based on the new protocol upgrade ([#185](https://github.com/taikoxyz/taiko-client/issues/185)) ([54f7a4c](https://github.com/taikoxyz/taiko-client/commit/54f7a4cb2db72a4ffa9a199e2af1f0d709a1ac27)) +* **driver:** changes based on protocol L2 EIP-1559 design ([#188](https://github.com/taikoxyz/taiko-client/issues/188)) ([82e8b97](https://github.com/taikoxyz/taiko-client/commit/82e8b9741782258840696701993b6d009d0260e0)) +* **prover:** add oracle prover flag ([#194](https://github.com/taikoxyz/taiko-client/issues/194)) ([ebbc725](https://github.com/taikoxyz/taiko-client/commit/ebbc72559a70c9aefc34286b05b1f4261bae8cd6)) +* **prover:** proof skip ([#198](https://github.com/taikoxyz/taiko-client/issues/198)) ([8607af8](https://github.com/taikoxyz/taiko-client/commit/8607af826ed9561a6bdae74074a517f1424e7a69)) + +## [0.6.0](https://github.com/taikoxyz/taiko-client/compare/v0.5.0...v0.6.0) (2023-03-20) + + +### Features + +* **docs:** remove concept docs and refer to website ([#180](https://github.com/taikoxyz/taiko-client/pull/180)) ([a8dcdac](https://github.com/taikoxyz/taiko-client/commit/a8dcdac77c1a5e3f85e4d7a4b912cfb3d903a3d9)) +* **flags:** update txpool.locals flag usage ([#181](https://github.com/taikoxyz/taiko-client/pull/181)) ([dac6102](https://github.com/taikoxyz/taiko-client/commit/dac6102d7508b9bdcb248eab4dcf469022353aa8)) +* **proposer:** add `proposeEmptyBlockGasLimit` ([#178](https://github.com/taikoxyz/taiko-client/issues/178)) ([e64d769](https://github.com/taikoxyz/taiko-client/commit/e64d769f45d072b151f429f61c1fe2ab07dec0dc)) + + +## [0.5.0](https://github.com/taikoxyz/taiko-client/compare/v0.4.0...v0.5.0) (2023-03-08) + + +### Features + +* **pkg:** improve `BlockBatchIterator` ([#173](https://github.com/taikoxyz/taiko-client/issues/173)) ([4fab06a](https://github.com/taikoxyz/taiko-client/commit/4fab06a9cba17c5e4da09acbe9b95949d6c4d47f)) +* **proposer,prover:** make `context.Context` part of `proposer.waitTillSynced` && `ProofProducer.RequestProof`'s parameters ([#169](https://github.com/taikoxyz/taiko-client/issues/169)) ([4b11e29](https://github.com/taikoxyz/taiko-client/commit/4b11e29689b8fac85023669443c351f428a54fea)) +* **proposer:** new flag to propose empty blocks ([#175](https://github.com/taikoxyz/taiko-client/issues/175)) ([6621a5c](https://github.com/taikoxyz/taiko-client/commit/6621a5c89a92e7593f702e4c82e69d1215b2ca59)) +* **proposer:** remove `poolContentSplitter` in proposer ([#159](https://github.com/taikoxyz/taiko-client/issues/159)) ([e26c831](https://github.com/taikoxyz/taiko-client/commit/e26c831a42fdf448b32bcf75c1f1f87bd71df481)) +* **proposer:** remove an unused flag ([#176](https://github.com/taikoxyz/taiko-client/issues/176)) ([7d2126e](https://github.com/taikoxyz/taiko-client/commit/7d2126efe256bcb698b3d4df7352efdbff957ace)) +* **prover:** ensure L2 EE is fully synced when calling `initL1Current` ([#170](https://github.com/taikoxyz/taiko-client/issues/170)) ([6c85058](https://github.com/taikoxyz/taiko-client/commit/6c8505827c035cc7456967bc8aab8bec1861e19b)) +* **prover:** new flags for `zkevm-chain` ([#166](https://github.com/taikoxyz/taiko-client/issues/166)) ([1c90a3d](https://github.com/taikoxyz/taiko-client/commit/1c90a3d6b7cada0b116875d88f0952993b54bb5f)) +* **prover:** tracking for most recent block ID to ensure (relatively) consecutive proving by notification system ([#174](https://github.com/taikoxyz/taiko-client/issues/174)) ([e500039](https://github.com/taikoxyz/taiko-client/commit/e5000395a3a28bd282df64f54867fd771143a56a)) + + +### Bug Fixes + +* **proposer:** remove an unused metric from proposer ([#171](https://github.com/taikoxyz/taiko-client/issues/171)) ([8df5eea](https://github.com/taikoxyz/taiko-client/commit/8df5eea1d9f1482a10b7d395ae19953f5d6ea6ce)) + +## [0.4.0](https://github.com/taikoxyz/taiko-client/compare/v0.3.0...v0.4.0) (2023-02-22) + + +### Features + +* **all:** update contract bindings && some improvements based on Alex's feedback ([#153](https://github.com/taikoxyz/taiko-client/issues/153)) ([bdaa292](https://github.com/taikoxyz/taiko-client/commit/bdaa2920bcb113d3887409edb17462b5e0d3a2c5)) +* **bindings:** parse solidity custom errors ([#163](https://github.com/taikoxyz/taiko-client/issues/163)) ([9a79127](https://github.com/taikoxyz/taiko-client/commit/9a79127a5a3cddf4e95ac899943e6551b02cf432)) + + +### Bug Fixes + +* **driver:** fix an issue in sync status checking ([#162](https://github.com/taikoxyz/taiko-client/issues/162)) ([4b21027](https://github.com/taikoxyz/taiko-client/commit/4b2102720e2c1c2fcaef1853ad74b91c6d08aaaa)) +* **proposer:** fix a proposer nonce order issue ([#157](https://github.com/taikoxyz/taiko-client/issues/157)) ([80fc0e9](https://github.com/taikoxyz/taiko-client/commit/80fc0e94d819f93ecdeac492eb1f35d5f2bb09ce)) + +## [0.3.0](https://github.com/taikoxyz/taiko-client/compare/v0.2.4...v0.3.0) (2023-02-15) + + +### Features + +* **prover:** improve the check for whether the current block still needs a new proof ([#145](https://github.com/taikoxyz/taiko-client/issues/145)) ([6c00fc5](https://github.com/taikoxyz/taiko-client/commit/6c00fc544b1ed92a4e38860059ef463282648a42)) +* **prover:** update `ZkevmRpcdProducer` to make it connecting to a real proverd service ([#121](https://github.com/taikoxyz/taiko-client/issues/121)) ([8c8ee9c](https://github.com/taikoxyz/taiko-client/commit/8c8ee9c2c3266e25e4233821034b89f50bb08c33)) +* **repo:** implement release please ([#148](https://github.com/taikoxyz/taiko-client/issues/148)) ([d8f3ad8](https://github.com/taikoxyz/taiko-client/commit/d8f3ad80d358fe547d356b7f7d7fd6e6ca9279ce)) diff --git a/packages/taiko-client/Dockerfile b/packages/taiko-client/Dockerfile new file mode 100644 index 00000000000..7e27763b298 --- /dev/null +++ b/packages/taiko-client/Dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.21-alpine as builder + +RUN apk update && apk add --no-cache --update gcc musl-dev linux-headers git make build-base + +WORKDIR /taiko-client +COPY . . +RUN make build + +FROM alpine:latest + +RUN apk add --no-cache ca-certificates libstdc++ + +COPY --from=builder /taiko-client/bin/taiko-client /usr/local/bin/ + +EXPOSE 6060 + +ENTRYPOINT ["taiko-client"] diff --git a/packages/taiko-client/LICENSE.md b/packages/taiko-client/LICENSE.md new file mode 100644 index 00000000000..e1eaaa7b0e3 --- /dev/null +++ b/packages/taiko-client/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Taiko Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/taiko-client/Makefile b/packages/taiko-client/Makefile new file mode 100644 index 00000000000..1c14e6e4687 --- /dev/null +++ b/packages/taiko-client/Makefile @@ -0,0 +1,42 @@ +GIT_COMMIT := $(shell git rev-parse HEAD) +GIT_DATE := $(shell git show -s --format='%ct') + +LD_FLAGS_ARGS +=-X github.com/taikoxyz/taiko-client/version.GitCommit=$(GIT_COMMIT) +LD_FLAGS_ARGS +=-X github.com/taikoxyz/taiko-client/version.GitDate=$(GIT_DATE) + +LD_FLAGS := -ldflags "$(LD_FLAGS_ARGS)" + +build: + @GO111MODULE=on CGO_CFLAGS="-O -D__BLST_PORTABLE__" CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" go build -v $(LD_FLAGS) -o bin/taiko-client cmd/main.go + +clean: + @rm -rf bin/* + +lint: + @go install golang.org/x/tools/cmd/goimports@latest \ + && go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.2 \ + && goimports -local "github.com/taikoxyz/taiko-client" -w ./ \ + && golangci-lint run + +test: + @TAIKO_MONO_DIR=${TAIKO_MONO_DIR} \ + PACKAGE=${PACKAGE} \ + RUN_TESTS=true \ + ./integration_test/entrypoint.sh + +dev_net: + @TAIKO_MONO_DIR=${TAIKO_MONO_DIR} \ + COMPILE_PROTOCOL=${COMPILE_PROTOCOL} \ + ./integration_test/entrypoint.sh + +gen_bindings: + @TAIKO_MONO_DIR=${TAIKO_MONO_DIR} \ + TAIKO_GETH_DIR=${TAIKO_GETH_DIR} \ + ./scripts/gen_bindings.sh + +.PHONY: build \ + clean \ + lint \ + test \ + dev_net \ + gen_bindings diff --git a/packages/taiko-client/README.md b/packages/taiko-client/README.md new file mode 100644 index 00000000000..588b89807c9 --- /dev/null +++ b/packages/taiko-client/README.md @@ -0,0 +1,59 @@ +# taiko-client + +[![CI](https://github.com/taikoxyz/taiko-client/actions/workflows/test.yml/badge.svg)](https://github.com/taikoxyz/taiko-client/actions/workflows/test.yml) +[![Codecov](https://img.shields.io/codecov/c/github/taikoxyz/taiko-client?logo=codecov&token=OH6BJMVP6O)](https://codecov.io/gh/taikoxyz/taiko-client) + +Taiko protocol's client software implementation in Go. Learn more about Taiko nodes with [the docs](https://docs.taiko.xyz/core-concepts/taiko-nodes/). + +## Project structure + +| Path | Description | +| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `bindings/` | [Go contract bindings](https://geth.ethereum.org/docs/dapp/native-bindings) for Taiko smart contracts, and few related utility functions | +| `cmd/` | Main executable for this project | +| `docs/` | Documentation | +| `driver/` | Driver sub-command | +| `integration_test/` | Scripts to do the integration testing of all client software | +| `metrics/` | Metrics related | +| `pkg/` | Library code which used by all sub-commands | +| `proposer/` | Proposer sub-command | +| `prover/` | Prover sub-command | +| `scripts/` | Helpful scripts | +| `testutils/` | Test utils | +| `version/` | Version information | + +## Build the source + +Building the `taiko-client` binary requires a Go compiler. Once installed, run: + +```sh +make build +``` + +## Usage + +Review all available sub-commands: + +```sh +bin/taiko-client --help +``` + +Review each sub-command's command line flags: + +```sh +bin/taiko-client --help +``` + +## Testing + +Ensure you have Docker running, and pnpm installed. + +Then, run the integration tests: + +1. Start Docker locally +2. Perform a `pnpm install` in `taiko-mono/packages/protocol` +3. Replace `` and execute: + +```sh +TAIKO_MONO_DIR= make test +``` diff --git a/packages/taiko-client/bindings/.githead b/packages/taiko-client/bindings/.githead new file mode 100644 index 00000000000..adf6192c7c7 --- /dev/null +++ b/packages/taiko-client/bindings/.githead @@ -0,0 +1 @@ +56dddf2b64778f7b119628b3a5fb50dc4825fd8a diff --git a/packages/taiko-client/bindings/encoding/custom_error.go b/packages/taiko-client/bindings/encoding/custom_error.go new file mode 100644 index 00000000000..df598b49494 --- /dev/null +++ b/packages/taiko-client/bindings/encoding/custom_error.go @@ -0,0 +1,100 @@ +package encoding + +import ( + "context" + "errors" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// BlockHashContractCallerAndChainReader represents a contract caller and chain reader. +type BlockHashContractCallerAndChainReader interface { + bind.BlockHashContractCaller + ethereum.TransactionReader + ethereum.ChainReader +} + +// TryParsingCustomErrorFromReceipt tries to parse the custom error from the given receipt. +func TryParsingCustomErrorFromReceipt( + ctx context.Context, + rpc BlockHashContractCallerAndChainReader, + from common.Address, + receipt *types.Receipt, +) error { + // Get the block header of the receipt. + header, err := rpc.HeaderByHash(ctx, receipt.BlockHash) + if err != nil { + return err + } + + // Fetch the raw transaction. + tx, _, err := rpc.TransactionByHash(ctx, receipt.TxHash) + if err != nil { + return err + } + + // Call the contract at the block hash. + _, err = rpc.CallContractAtHash(ctx, ethereum.CallMsg{ + From: from, + To: tx.To(), + Gas: tx.Gas(), + GasFeeCap: tx.GasFeeCap(), + GasTipCap: tx.GasTipCap(), + Value: tx.Value(), + Data: tx.Data(), + AccessList: tx.AccessList(), + BlobGasFeeCap: tx.BlobGasFeeCap(), + BlobHashes: tx.BlobHashes(), + }, header.ParentHash) + + return TryParsingCustomError(err) +} + +// TryParsingCustomError tries to checks whether the given error is one of the +// custom errors defined the protocol ABIs, if so, it will return +// the matched custom error, otherwise, it simply returns the original error. +func TryParsingCustomError(originalError error) error { + if originalError == nil { + return nil + } + + errData := getErrorData(originalError) + + // if errData is unparsable and returns 0x, we should not match any errors. + if errData == "0x" { + return originalError + } + + for _, customErrors := range customErrorMaps { + for _, customError := range customErrors { + if strings.HasPrefix(customError.ID.Hex(), errData) { + return errors.New(customError.Name) + } + } + } + + return originalError +} + +// getErrorData tries to parse the actual custom error data from the given error. +func getErrorData(err error) string { + // Geth node custom errors, the actual struct of this error is go-ethereum's . + gethJSONError, ok := err.(interface{ ErrorData() interface{} }) // nolint: errorlint + if ok { + if errData, ok := gethJSONError.ErrorData().(string); ok { + return errData + } + } + + // Hardhat node custom errors, example: + // "VM Exception while processing transaction: reverted with an unrecognized custom error (return data: 0xb6d363fd)" + if strings.Contains(err.Error(), "reverted with an unrecognized custom error") { + return err.Error()[len(err.Error())-11 : len(err.Error())-1] + } + + return err.Error() +} diff --git a/packages/taiko-client/bindings/encoding/custom_error_test.go b/packages/taiko-client/bindings/encoding/custom_error_test.go new file mode 100644 index 00000000000..a7cf6d691cc --- /dev/null +++ b/packages/taiko-client/bindings/encoding/custom_error_test.go @@ -0,0 +1,42 @@ +package encoding + +import ( + "errors" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +type testJSONError struct{} + +func (e *testJSONError) Error() string { return common.Bytes2Hex(randomBytes(10)) } + +func (e *testJSONError) ErrorData() interface{} { return "0x8a1c400f" } + +type emptyTestJSONError struct{} + +func (e *emptyTestJSONError) Error() string { return "execution reverted" } + +func (e *emptyTestJSONError) ErrorData() interface{} { return "0x" } + +func TestTryParsingCustomError(t *testing.T) { + randomErr := common.Bytes2Hex(randomBytes(10)) + require.Equal(t, randomErr, TryParsingCustomError(errors.New(randomErr)).Error()) + + err := TryParsingCustomError(errors.New( + // L1_INVALID_BLOCK_ID + "VM Exception while processing transaction: reverted with an unrecognized custom error (return data: 0x8a1c400f)", + )) + + require.True(t, strings.HasPrefix(err.Error(), "L1_INVALID_BLOCK_ID")) + + err = TryParsingCustomError(&testJSONError{}) + + require.True(t, strings.HasPrefix(err.Error(), "L1_INVALID_BLOCK_ID")) + + err = TryParsingCustomError(&emptyTestJSONError{}) + + require.Equal(t, err.Error(), "execution reverted") +} diff --git a/packages/taiko-client/bindings/encoding/input.go b/packages/taiko-client/bindings/encoding/input.go new file mode 100644 index 00000000000..032a82df799 --- /dev/null +++ b/packages/taiko-client/bindings/encoding/input.go @@ -0,0 +1,416 @@ +package encoding + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" +) + +// ABI arguments marshaling components. +var ( + blockMetadataComponents = []abi.ArgumentMarshaling{ + { + Name: "l1Hash", + Type: "bytes32", + }, + { + Name: "difficulty", + Type: "bytes32", + }, + { + Name: "blobHash", + Type: "bytes32", + }, + { + Name: "extraData", + Type: "bytes32", + }, + { + Name: "depositsHash", + Type: "bytes32", + }, + { + Name: "coinbase", + Type: "address", + }, + { + Name: "id", + Type: "uint64", + }, + { + Name: "gasLimit", + Type: "uint32", + }, + { + Name: "timestamp", + Type: "uint64", + }, + { + Name: "l1Height", + Type: "uint64", + }, + { + Name: "minTier", + Type: "uint16", + }, + { + Name: "blobUsed", + Type: "bool", + }, + { + Name: "parentMetaHash", + Type: "bytes32", + }, + { + Name: "sender", + Type: "address", + }, + } + transitionComponents = []abi.ArgumentMarshaling{ + { + Name: "parentHash", + Type: "bytes32", + }, + { + Name: "blockHash", + Type: "bytes32", + }, + { + Name: "stateRoot", + Type: "bytes32", + }, + { + Name: "graffiti", + Type: "bytes32", + }, + } + tierProofComponents = []abi.ArgumentMarshaling{ + { + Name: "tier", + Type: "uint16", + }, + { + Name: "data", + Type: "bytes", + }, + } + blockParamsComponents = []abi.ArgumentMarshaling{ + { + Name: "assignedProver", + Type: "address", + }, + { + Name: "coinbase", + Type: "address", + }, + { + Name: "extraData", + Type: "bytes32", + }, + { + Name: "parentMetaHash", + Type: "bytes32", + }, + { + Name: "hookCalls", + Type: "tuple[]", + Components: []abi.ArgumentMarshaling{ + { + Name: "hook", + Type: "address", + }, + { + Name: "data", + Type: "bytes", + }, + }, + }, + { + Name: "signature", + Type: "bytes", + }, + } + proverAssignmentComponents = []abi.ArgumentMarshaling{ + { + Name: "feeToken", + Type: "address", + }, + { + Name: "expiry", + Type: "uint64", + }, + { + Name: "maxBlockId", + Type: "uint64", + }, + { + Name: "maxProposedIn", + Type: "uint64", + }, + { + Name: "metaHash", + Type: "bytes32", + }, + { + Name: "parentMetaHash", + Type: "bytes32", + }, + { + Name: "tierFees", + Type: "tuple[]", + Components: []abi.ArgumentMarshaling{ + { + Name: "tier", + Type: "uint16", + }, + { + Name: "fee", + Type: "uint128", + }, + }, + }, + { + Name: "signature", + Type: "bytes", + }, + } + assignmentHookInputComponents = []abi.ArgumentMarshaling{ + { + Name: "assignment", + Type: "tuple", + Components: proverAssignmentComponents, + }, + { + Name: "tip", + Type: "uint256", + }, + } +) + +var ( + assignmentHookInputType, _ = abi.NewType("tuple", "AssignmentHook.Input", assignmentHookInputComponents) + assignmentHookInputArgs = abi.Arguments{{Name: "AssignmentHook.Input", Type: assignmentHookInputType}} + blockParamsComponentsType, _ = abi.NewType("tuple", "TaikoData.BlockParams", blockParamsComponents) + blockParamsComponentsArgs = abi.Arguments{{Name: "TaikoData.BlockParams", Type: blockParamsComponentsType}} + // ProverAssignmentPayload + bytes32Type, _ = abi.NewType("bytes32", "", nil) + addressType, _ = abi.NewType("address", "", nil) + uint64Type, _ = abi.NewType("uint64", "", nil) + tierFeesType, _ = abi.NewType( + "tuple[]", + "", + []abi.ArgumentMarshaling{ + { + Name: "tier", + Type: "uint16", + }, + { + Name: "fee", + Type: "uint128", + }, + }, + ) + proverAssignmentHashPayloadArgs = abi.Arguments{ + {Name: "_assignment.metaHash", Type: bytes32Type}, + {Name: "_assignment.parentMetaHash", Type: bytes32Type}, + {Name: "_assignment.feeToken", Type: addressType}, + {Name: "_assignment.expiry", Type: uint64Type}, + {Name: "_assignment.maxBlockId", Type: uint64Type}, + {Name: "_assignment.maxProposedIn", Type: uint64Type}, + {Name: "_assignment.tierFees", Type: tierFeesType}, + } + blockMetadataComponentsType, _ = abi.NewType("tuple", "TaikoData.BlockMetadata", blockMetadataComponents) + transitionComponentsType, _ = abi.NewType("tuple", "TaikoData.Transition", transitionComponents) + tierProofComponentsType, _ = abi.NewType("tuple", "TaikoData.TierProof", tierProofComponents) + proveBlockInputArgs = abi.Arguments{ + {Name: "TaikoData.BlockMetadata", Type: blockMetadataComponentsType}, + {Name: "TaikoData.Transition", Type: transitionComponentsType}, + {Name: "TaikoData.TierProof", Type: tierProofComponentsType}, + } +) + +// Contract ABIs. +var ( + TaikoL1ABI *abi.ABI + TaikoL2ABI *abi.ABI + TaikoTokenABI *abi.ABI + GuardianProverABI *abi.ABI + LibProposingABI *abi.ABI + LibProvingABI *abi.ABI + LibUtilsABI *abi.ABI + LibVerifyingABI *abi.ABI + AssignmentHookABI *abi.ABI + SGXVerifierABI *abi.ABI + GuardianVerifierABI *abi.ABI + + customErrorMaps []map[string]abi.Error +) + +func init() { + var err error + + if TaikoL1ABI, err = bindings.TaikoL1ClientMetaData.GetAbi(); err != nil { + log.Crit("Get TaikoL1 ABI error", "error", err) + } + + if TaikoL2ABI, err = bindings.TaikoL2ClientMetaData.GetAbi(); err != nil { + log.Crit("Get TaikoL2 ABI error", "error", err) + } + + if TaikoTokenABI, err = bindings.TaikoTokenMetaData.GetAbi(); err != nil { + log.Crit("Get TaikoToken ABI error", "error", err) + } + + if GuardianProverABI, err = bindings.GuardianProverMetaData.GetAbi(); err != nil { + log.Crit("Get GuardianProver ABI error", "error", err) + } + + if LibProposingABI, err = bindings.LibProposingMetaData.GetAbi(); err != nil { + log.Crit("Get LibProposing ABI error", "error", err) + } + + if LibProvingABI, err = bindings.LibProvingMetaData.GetAbi(); err != nil { + log.Crit("Get LibProving ABI error", "error", err) + } + + if LibUtilsABI, err = bindings.LibUtilsMetaData.GetAbi(); err != nil { + log.Crit("Get LibUtils ABI error", "error", err) + } + + if LibVerifyingABI, err = bindings.LibVerifyingMetaData.GetAbi(); err != nil { + log.Crit("Get LibVerifying ABI error", "error", err) + } + + if AssignmentHookABI, err = bindings.AssignmentHookMetaData.GetAbi(); err != nil { + log.Crit("Get AssignmentHook ABI error", "error", err) + } + + if SGXVerifierABI, err = bindings.SgxVerifierMetaData.GetAbi(); err != nil { + log.Crit("Get SGXVerifier ABI error", err) + } + + if GuardianVerifierABI, err = bindings.GuardianVerifierMetaData.GetAbi(); err != nil { + log.Crit("Get GuardianVerifier ABI error", "error", err) + } + + customErrorMaps = []map[string]abi.Error{ + TaikoL1ABI.Errors, + TaikoL2ABI.Errors, + GuardianProverABI.Errors, + LibProposingABI.Errors, + LibProvingABI.Errors, + LibUtilsABI.Errors, + LibVerifyingABI.Errors, + AssignmentHookABI.Errors, + SGXVerifierABI.Errors, + GuardianVerifierABI.Errors, + } +} + +// EncodeBlockParams performs the solidity `abi.encode` for the given blockParams. +func EncodeBlockParams(params *BlockParams) ([]byte, error) { + b, err := blockParamsComponentsArgs.Pack(params) + if err != nil { + return nil, fmt.Errorf("failed to abi.encode block params, %w", err) + } + return b, nil +} + +// EncodeAssignmentHookInput performs the solidity `abi.encode` for the given input +func EncodeAssignmentHookInput(input *AssignmentHookInput) ([]byte, error) { + b, err := assignmentHookInputArgs.Pack(input) + if err != nil { + return nil, fmt.Errorf("failed to abi.encode assignment hook input params, %w", err) + } + return b, nil +} + +// EncodeProverAssignmentPayload performs the solidity `abi.encode` for the given proverAssignment payload. +func EncodeProverAssignmentPayload( + chainID uint64, + taikoAddress common.Address, + assignmentHookAddress common.Address, + blockProposer common.Address, + assignedProver common.Address, + blobHash common.Hash, + feeToken common.Address, + expiry uint64, + maxBlockID uint64, + maxProposedIn uint64, + tierFees []TierFee, +) ([]byte, error) { + hashBytesPayload, err := proverAssignmentHashPayloadArgs.Pack( + common.Hash{}, + common.Hash{}, + feeToken, + expiry, + maxBlockID, + maxProposedIn, + tierFees, + ) + if err != nil { + return nil, fmt.Errorf("failed to abi.encode prover assignment hash payload, %w", err) + } + + chainIDBytes := make([]byte, 8) + binary.BigEndian.PutUint64(chainIDBytes, chainID) + + return bytes.Join([][]byte{ + common.RightPadBytes([]byte("PROVER_ASSIGNMENT"), 32), + chainIDBytes, + taikoAddress.Bytes(), + blockProposer.Bytes(), + assignedProver.Bytes(), + blobHash.Bytes(), + crypto.Keccak256Hash(hashBytesPayload).Bytes(), + assignmentHookAddress.Bytes(), + }, nil), nil +} + +// EncodeProveBlockInput performs the solidity `abi.encode` for the given TaikoL1.proveBlock input. +func EncodeProveBlockInput( + meta *bindings.TaikoDataBlockMetadata, + transition *bindings.TaikoDataTransition, + tierProof *bindings.TaikoDataTierProof, +) ([]byte, error) { + b, err := proveBlockInputArgs.Pack(meta, transition, tierProof) + if err != nil { + return nil, fmt.Errorf("failed to abi.encode TakoL1.proveBlock input, %w", err) + } + return b, nil +} + +// UnpackTxListBytes unpacks the input data of a TaikoL1.proposeBlock transaction, and returns the txList bytes. +func UnpackTxListBytes(txData []byte) ([]byte, error) { + method, err := TaikoL1ABI.MethodById(txData) + if err != nil { + return nil, err + } + + // Only check for safety. + if method.Name != "proposeBlock" { + return nil, fmt.Errorf("invalid method name: %s", method.Name) + } + + args := map[string]interface{}{} + + if err := method.Inputs.UnpackIntoMap(args, txData[4:]); err != nil { + return nil, err + } + + inputs, ok := args["_txList"].([]byte) + + if !ok { + return nil, errors.New("failed to get txList bytes") + } + + return inputs, nil +} diff --git a/packages/taiko-client/bindings/encoding/input_test.go b/packages/taiko-client/bindings/encoding/input_test.go new file mode 100644 index 00000000000..86b3f067ad7 --- /dev/null +++ b/packages/taiko-client/bindings/encoding/input_test.go @@ -0,0 +1,101 @@ +package encoding + +import ( + "context" + "math/big" + "os" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" +) + +func TestEncodeProverAssignmentPayload(t *testing.T) { + encoded, err := EncodeProverAssignmentPayload( + randomHash().Big().Uint64(), + common.BytesToAddress(randomBytes(20)), + common.BytesToAddress(randomBytes(20)), + common.BytesToAddress(randomBytes(20)), + common.BytesToAddress(randomBytes(20)), + common.BytesToHash(randomBytes(32)), + common.BytesToAddress(randomBytes(20)), + 120, + 1024, + 0, + []TierFee{{Tier: 0, Fee: common.Big1}}, + ) + + require.Nil(t, err) + require.NotNil(t, encoded) +} + +func TestEncodeAssignmentHookInput(t *testing.T) { + encoded, err := EncodeAssignmentHookInput(&AssignmentHookInput{ + Assignment: &ProverAssignment{ + FeeToken: common.Address{}, + Expiry: 1, + MaxBlockId: 1, + MaxProposedIn: 1, + MetaHash: [32]byte{0xff}, + TierFees: []TierFee{{Tier: 0, Fee: common.Big1}}, + Signature: []byte{0xff}, + }, + Tip: big.NewInt(1), + }) + + require.Nil(t, err) + require.NotNil(t, encoded) +} + +func TestUnpackTxListBytes(t *testing.T) { + _, err := UnpackTxListBytes(randomBytes(1024)) + require.NotNil(t, err) + + _, err = UnpackTxListBytes( + hexutil.MustDecode( + "0xa0ca2d080000000000000000000000000000000000000000000000000000000000000" + + "aa8e2b9725cce28787e99447c383d95a9ba83125fe31a9ffa9cbb2c504da86926ab", + ), + ) + require.ErrorContains(t, err, "no method with id") + + cli, err := ethclient.Dial(os.Getenv("L1_NODE_WS_ENDPOINT")) + require.Nil(t, err) + + chainID, err := cli.ChainID(context.Background()) + require.Nil(t, err) + + taikoL1, err := bindings.NewTaikoL1Client( + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + cli, + ) + require.Nil(t, err) + + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + require.Nil(t, err) + + opts, err := bind.NewKeyedTransactorWithChainID(l1ProposerPrivKey, chainID) + require.Nil(t, err) + + opts.NoSend = true + opts.GasLimit = randomHash().Big().Uint64() + + txListBytes := randomBytes(1024) + + tx, err := taikoL1.ProposeBlock( + opts, + randomBytes(1024), + txListBytes, + ) + require.Nil(t, err) + + b, err := UnpackTxListBytes(tx.Data()) + require.Nil(t, err) + require.Equal(t, txListBytes, b) +} diff --git a/packages/taiko-client/bindings/encoding/struct.go b/packages/taiko-client/bindings/encoding/struct.go new file mode 100644 index 00000000000..1cfe974bfb6 --- /dev/null +++ b/packages/taiko-client/bindings/encoding/struct.go @@ -0,0 +1,112 @@ +package encoding + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Tier IDs defined in protocol. +var ( + TierOptimisticID uint16 = 100 + TierSgxID uint16 = 200 + TierSgxAndZkVMID uint16 = 300 + TierGuardianID uint16 = 1000 + ProtocolTiers = []uint16{ + TierOptimisticID, + TierSgxID, + TierSgxAndZkVMID, + TierGuardianID, + } + GoldenTouchPrivKey = "92954368afd3caa1f3ce3ead0069c1af414054aefe1ef9aeacc1bf426222ce38" +) + +// HookCall should be same with TaikoData.HookCall +type HookCall struct { + Hook common.Address + Data []byte +} + +// BlockParams should be same with TaikoData.BlockParams. +type BlockParams struct { + AssignedProver common.Address + Coinbase common.Address + ExtraData [32]byte + ParentMetaHash [32]byte + HookCalls []HookCall + Signature []byte +} + +// TierFee should be same with TaikoData.TierFee. +type TierFee struct { + Tier uint16 + Fee *big.Int +} + +// ProverAssignment should be same with TaikoData.ProverAssignment. +type ProverAssignment struct { + FeeToken common.Address + Expiry uint64 + MaxBlockId uint64 // nolint: revive,stylecheck + MaxProposedIn uint64 + MetaHash [32]byte + ParentMetaHash [32]byte + TierFees []TierFee + Signature []byte +} + +// AssignmentHookInput should be same as AssignmentHook.Input +type AssignmentHookInput struct { + Assignment *ProverAssignment + Tip *big.Int +} + +// ToExecutableData converts a GETH *types.Header to *engine.ExecutableData. +func ToExecutableData(header *types.Header) *engine.ExecutableData { + executableData := &engine.ExecutableData{ + ParentHash: header.ParentHash, + FeeRecipient: header.Coinbase, + StateRoot: header.Root, + ReceiptsRoot: header.ReceiptHash, + LogsBloom: header.Bloom.Bytes(), + Random: header.MixDigest, + Number: header.Number.Uint64(), + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Timestamp: header.Time, + ExtraData: header.Extra, + BaseFeePerGas: header.BaseFee, + BlockHash: header.Hash(), + TxHash: header.TxHash, + } + + if header.WithdrawalsHash != nil { + executableData.WithdrawalsHash = *header.WithdrawalsHash + } + + return executableData +} + +// BloomToBytes converts a types.Bloom to [8][32]byte slice. +func BloomToBytes(bloom types.Bloom) [8][32]byte { + b := [8][32]byte{} + + for i := 0; i < 8; i++ { + copy(b[i][:], bloom[i*32:(i+1)*32]) + } + + return b +} + +// BytesToBloom converts a [8][32]byte slice to types.Bloom. +func BytesToBloom(b [8][32]byte) types.Bloom { + bytes := []byte{} + + for i := 0; i < 8; i++ { + bytes = append(bytes, b[i][:]...) + } + + return types.BytesToBloom(bytes) +} diff --git a/packages/taiko-client/bindings/encoding/struct_test.go b/packages/taiko-client/bindings/encoding/struct_test.go new file mode 100644 index 00000000000..85a8436893a --- /dev/null +++ b/packages/taiko-client/bindings/encoding/struct_test.go @@ -0,0 +1,72 @@ +package encoding + +import ( + "crypto/rand" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/internal/utils" +) + +var ( + testHeader = &types.Header{ + ParentHash: randomHash(), + UncleHash: types.EmptyUncleHash, + Coinbase: common.BytesToAddress(randomHash().Bytes()), + Root: randomHash(), + TxHash: randomHash(), + ReceiptHash: randomHash(), + Bloom: types.BytesToBloom(randomHash().Bytes()), + Difficulty: new(big.Int).SetUint64(utils.RandUint64(nil)), + Number: new(big.Int).SetUint64(utils.RandUint64(nil)), + GasLimit: utils.RandUint64(nil), + GasUsed: utils.RandUint64(nil), + Time: uint64(time.Now().Unix()), + Extra: randomHash().Bytes(), + MixDigest: randomHash(), + Nonce: types.EncodeNonce(utils.RandUint64(nil)), + BaseFee: new(big.Int).SetUint64(utils.RandUint64(nil)), + } +) + +func TestToExecutableData(t *testing.T) { + data := ToExecutableData(testHeader) + require.Equal(t, testHeader.ParentHash, data.ParentHash) + require.Equal(t, testHeader.Coinbase, data.FeeRecipient) + require.Equal(t, testHeader.Root, data.StateRoot) + require.Equal(t, testHeader.ReceiptHash, data.ReceiptsRoot) + require.Equal(t, testHeader.Bloom.Bytes(), data.LogsBloom) + require.Equal(t, testHeader.MixDigest, data.Random) + require.Equal(t, testHeader.Number.Uint64(), data.Number) + require.Equal(t, testHeader.GasLimit, data.GasLimit) + require.Equal(t, testHeader.GasUsed, data.GasUsed) + require.Equal(t, testHeader.Time, data.Timestamp) + require.Equal(t, testHeader.Extra, data.ExtraData) + require.Equal(t, testHeader.BaseFee, data.BaseFeePerGas) + require.Equal(t, testHeader.Hash(), data.BlockHash) + require.Equal(t, testHeader.TxHash, data.TxHash) +} + +// randomHash generates a random blob of data and returns it as a hash. +func randomHash() common.Hash { + var hash common.Hash + if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { + panic(err) + } + return hash +} + +// randomBytes generates a random bytes. +func randomBytes(size int) (b []byte) { + b = make([]byte, size) + if _, err := rand.Read(b); err != nil { + log.Crit("Generate random bytes error", "error", err) + } + return +} diff --git a/packages/taiko-client/bindings/gen_address_manager.go b/packages/taiko-client/bindings/gen_address_manager.go new file mode 100644 index 00000000000..cc7117e036a --- /dev/null +++ b/packages/taiko-client/bindings/gen_address_manager.go @@ -0,0 +1,1935 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// AddressManagerMetaData contains all meta data concerning the AddressManager contract. +var AddressManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAddress\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setAddress\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_newAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AddressSet\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"oldAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AM_ADDRESS_ALREADY_SET\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AM_PAUSE_UNSUPPORTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// AddressManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use AddressManagerMetaData.ABI instead. +var AddressManagerABI = AddressManagerMetaData.ABI + +// AddressManager is an auto generated Go binding around an Ethereum contract. +type AddressManager struct { + AddressManagerCaller // Read-only binding to the contract + AddressManagerTransactor // Write-only binding to the contract + AddressManagerFilterer // Log filterer for contract events +} + +// AddressManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type AddressManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AddressManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AddressManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AddressManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AddressManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AddressManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AddressManagerSession struct { + Contract *AddressManager // 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 +} + +// AddressManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AddressManagerCallerSession struct { + Contract *AddressManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AddressManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AddressManagerTransactorSession struct { + Contract *AddressManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AddressManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type AddressManagerRaw struct { + Contract *AddressManager // Generic contract binding to access the raw methods on +} + +// AddressManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AddressManagerCallerRaw struct { + Contract *AddressManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// AddressManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AddressManagerTransactorRaw struct { + Contract *AddressManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAddressManager creates a new instance of AddressManager, bound to a specific deployed contract. +func NewAddressManager(address common.Address, backend bind.ContractBackend) (*AddressManager, error) { + contract, err := bindAddressManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AddressManager{AddressManagerCaller: AddressManagerCaller{contract: contract}, AddressManagerTransactor: AddressManagerTransactor{contract: contract}, AddressManagerFilterer: AddressManagerFilterer{contract: contract}}, nil +} + +// NewAddressManagerCaller creates a new read-only instance of AddressManager, bound to a specific deployed contract. +func NewAddressManagerCaller(address common.Address, caller bind.ContractCaller) (*AddressManagerCaller, error) { + contract, err := bindAddressManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AddressManagerCaller{contract: contract}, nil +} + +// NewAddressManagerTransactor creates a new write-only instance of AddressManager, bound to a specific deployed contract. +func NewAddressManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AddressManagerTransactor, error) { + contract, err := bindAddressManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AddressManagerTransactor{contract: contract}, nil +} + +// NewAddressManagerFilterer creates a new log filterer instance of AddressManager, bound to a specific deployed contract. +func NewAddressManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AddressManagerFilterer, error) { + contract, err := bindAddressManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AddressManagerFilterer{contract: contract}, nil +} + +// bindAddressManager binds a generic wrapper to an already deployed contract. +func bindAddressManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AddressManagerMetaData.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 (_AddressManager *AddressManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AddressManager.Contract.AddressManagerCaller.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 (_AddressManager *AddressManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.Contract.AddressManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AddressManager *AddressManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AddressManager.Contract.AddressManagerTransactor.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 (_AddressManager *AddressManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AddressManager.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 (_AddressManager *AddressManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AddressManager *AddressManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AddressManager.Contract.contract.Transact(opts, method, params...) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AddressManager *AddressManagerCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AddressManager *AddressManagerSession) AddressManager() (common.Address, error) { + return _AddressManager.Contract.AddressManager(&_AddressManager.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AddressManager *AddressManagerCallerSession) AddressManager() (common.Address, error) { + return _AddressManager.Contract.AddressManager(&_AddressManager.CallOpts) +} + +// GetAddress is a free data retrieval call binding the contract method 0x28f713cc. +// +// Solidity: function getAddress(uint64 _chainId, bytes32 _name) view returns(address) +func (_AddressManager *AddressManagerCaller) GetAddress(opts *bind.CallOpts, _chainId uint64, _name [32]byte) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "getAddress", _chainId, _name) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetAddress is a free data retrieval call binding the contract method 0x28f713cc. +// +// Solidity: function getAddress(uint64 _chainId, bytes32 _name) view returns(address) +func (_AddressManager *AddressManagerSession) GetAddress(_chainId uint64, _name [32]byte) (common.Address, error) { + return _AddressManager.Contract.GetAddress(&_AddressManager.CallOpts, _chainId, _name) +} + +// GetAddress is a free data retrieval call binding the contract method 0x28f713cc. +// +// Solidity: function getAddress(uint64 _chainId, bytes32 _name) view returns(address) +func (_AddressManager *AddressManagerCallerSession) GetAddress(_chainId uint64, _name [32]byte) (common.Address, error) { + return _AddressManager.Contract.GetAddress(&_AddressManager.CallOpts, _chainId, _name) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AddressManager *AddressManagerCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AddressManager *AddressManagerSession) LastUnpausedAt() (uint64, error) { + return _AddressManager.Contract.LastUnpausedAt(&_AddressManager.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AddressManager *AddressManagerCallerSession) LastUnpausedAt() (uint64, error) { + return _AddressManager.Contract.LastUnpausedAt(&_AddressManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AddressManager *AddressManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AddressManager *AddressManagerSession) Owner() (common.Address, error) { + return _AddressManager.Contract.Owner(&_AddressManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AddressManager *AddressManagerCallerSession) Owner() (common.Address, error) { + return _AddressManager.Contract.Owner(&_AddressManager.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AddressManager *AddressManagerCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AddressManager *AddressManagerSession) Paused() (bool, error) { + return _AddressManager.Contract.Paused(&_AddressManager.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AddressManager *AddressManagerCallerSession) Paused() (bool, error) { + return _AddressManager.Contract.Paused(&_AddressManager.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AddressManager *AddressManagerCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AddressManager *AddressManagerSession) PendingOwner() (common.Address, error) { + return _AddressManager.Contract.PendingOwner(&_AddressManager.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AddressManager *AddressManagerCallerSession) PendingOwner() (common.Address, error) { + return _AddressManager.Contract.PendingOwner(&_AddressManager.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AddressManager *AddressManagerCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AddressManager *AddressManagerSession) ProxiableUUID() ([32]byte, error) { + return _AddressManager.Contract.ProxiableUUID(&_AddressManager.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AddressManager *AddressManagerCallerSession) ProxiableUUID() ([32]byte, error) { + return _AddressManager.Contract.ProxiableUUID(&_AddressManager.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AddressManager.Contract.Resolve(&_AddressManager.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AddressManager.Contract.Resolve(&_AddressManager.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _AddressManager.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AddressManager.Contract.Resolve0(&_AddressManager.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AddressManager *AddressManagerCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AddressManager.Contract.Resolve0(&_AddressManager.CallOpts, _name, _allowZeroAddress) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AddressManager *AddressManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AddressManager *AddressManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _AddressManager.Contract.AcceptOwnership(&_AddressManager.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AddressManager *AddressManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AddressManager.Contract.AcceptOwnership(&_AddressManager.TransactOpts) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_AddressManager *AddressManagerTransactor) Init(opts *bind.TransactOpts, _owner common.Address) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "init", _owner) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_AddressManager *AddressManagerSession) Init(_owner common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.Init(&_AddressManager.TransactOpts, _owner) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_AddressManager *AddressManagerTransactorSession) Init(_owner common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.Init(&_AddressManager.TransactOpts, _owner) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AddressManager *AddressManagerTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AddressManager *AddressManagerSession) Pause() (*types.Transaction, error) { + return _AddressManager.Contract.Pause(&_AddressManager.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AddressManager *AddressManagerTransactorSession) Pause() (*types.Transaction, error) { + return _AddressManager.Contract.Pause(&_AddressManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AddressManager *AddressManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AddressManager *AddressManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _AddressManager.Contract.RenounceOwnership(&_AddressManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AddressManager *AddressManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _AddressManager.Contract.RenounceOwnership(&_AddressManager.TransactOpts) +} + +// SetAddress is a paid mutator transaction binding the contract method 0xd8f4648f. +// +// Solidity: function setAddress(uint64 _chainId, bytes32 _name, address _newAddress) returns() +func (_AddressManager *AddressManagerTransactor) SetAddress(opts *bind.TransactOpts, _chainId uint64, _name [32]byte, _newAddress common.Address) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "setAddress", _chainId, _name, _newAddress) +} + +// SetAddress is a paid mutator transaction binding the contract method 0xd8f4648f. +// +// Solidity: function setAddress(uint64 _chainId, bytes32 _name, address _newAddress) returns() +func (_AddressManager *AddressManagerSession) SetAddress(_chainId uint64, _name [32]byte, _newAddress common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.SetAddress(&_AddressManager.TransactOpts, _chainId, _name, _newAddress) +} + +// SetAddress is a paid mutator transaction binding the contract method 0xd8f4648f. +// +// Solidity: function setAddress(uint64 _chainId, bytes32 _name, address _newAddress) returns() +func (_AddressManager *AddressManagerTransactorSession) SetAddress(_chainId uint64, _name [32]byte, _newAddress common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.SetAddress(&_AddressManager.TransactOpts, _chainId, _name, _newAddress) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AddressManager *AddressManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AddressManager *AddressManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.TransferOwnership(&_AddressManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AddressManager *AddressManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.TransferOwnership(&_AddressManager.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AddressManager *AddressManagerTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AddressManager *AddressManagerSession) Unpause() (*types.Transaction, error) { + return _AddressManager.Contract.Unpause(&_AddressManager.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AddressManager *AddressManagerTransactorSession) Unpause() (*types.Transaction, error) { + return _AddressManager.Contract.Unpause(&_AddressManager.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AddressManager *AddressManagerTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AddressManager *AddressManagerSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.UpgradeTo(&_AddressManager.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AddressManager *AddressManagerTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _AddressManager.Contract.UpgradeTo(&_AddressManager.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AddressManager *AddressManagerTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AddressManager.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AddressManager *AddressManagerSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AddressManager.Contract.UpgradeToAndCall(&_AddressManager.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AddressManager *AddressManagerTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AddressManager.Contract.UpgradeToAndCall(&_AddressManager.TransactOpts, newImplementation, data) +} + +// AddressManagerAddressSetIterator is returned from FilterAddressSet and is used to iterate over the raw logs and unpacked data for AddressSet events raised by the AddressManager contract. +type AddressManagerAddressSetIterator struct { + Event *AddressManagerAddressSet // 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 *AddressManagerAddressSetIterator) 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(AddressManagerAddressSet) + 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(AddressManagerAddressSet) + 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 *AddressManagerAddressSetIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerAddressSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerAddressSet represents a AddressSet event raised by the AddressManager contract. +type AddressManagerAddressSet struct { + ChainId uint64 + Name [32]byte + NewAddress common.Address + OldAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddressSet is a free log retrieval operation binding the contract event 0x500dcd607a98daece9bccc2511bf6032471252929de73caf507aae0e082f8453. +// +// Solidity: event AddressSet(uint64 indexed chainId, bytes32 indexed name, address newAddress, address oldAddress) +func (_AddressManager *AddressManagerFilterer) FilterAddressSet(opts *bind.FilterOpts, chainId []uint64, name [][32]byte) (*AddressManagerAddressSetIterator, error) { + + var chainIdRule []interface{} + for _, chainIdItem := range chainId { + chainIdRule = append(chainIdRule, chainIdItem) + } + var nameRule []interface{} + for _, nameItem := range name { + nameRule = append(nameRule, nameItem) + } + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "AddressSet", chainIdRule, nameRule) + if err != nil { + return nil, err + } + return &AddressManagerAddressSetIterator{contract: _AddressManager.contract, event: "AddressSet", logs: logs, sub: sub}, nil +} + +// WatchAddressSet is a free log subscription operation binding the contract event 0x500dcd607a98daece9bccc2511bf6032471252929de73caf507aae0e082f8453. +// +// Solidity: event AddressSet(uint64 indexed chainId, bytes32 indexed name, address newAddress, address oldAddress) +func (_AddressManager *AddressManagerFilterer) WatchAddressSet(opts *bind.WatchOpts, sink chan<- *AddressManagerAddressSet, chainId []uint64, name [][32]byte) (event.Subscription, error) { + + var chainIdRule []interface{} + for _, chainIdItem := range chainId { + chainIdRule = append(chainIdRule, chainIdItem) + } + var nameRule []interface{} + for _, nameItem := range name { + nameRule = append(nameRule, nameItem) + } + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "AddressSet", chainIdRule, nameRule) + 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(AddressManagerAddressSet) + if err := _AddressManager.contract.UnpackLog(event, "AddressSet", 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 +} + +// ParseAddressSet is a log parse operation binding the contract event 0x500dcd607a98daece9bccc2511bf6032471252929de73caf507aae0e082f8453. +// +// Solidity: event AddressSet(uint64 indexed chainId, bytes32 indexed name, address newAddress, address oldAddress) +func (_AddressManager *AddressManagerFilterer) ParseAddressSet(log types.Log) (*AddressManagerAddressSet, error) { + event := new(AddressManagerAddressSet) + if err := _AddressManager.contract.UnpackLog(event, "AddressSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the AddressManager contract. +type AddressManagerAdminChangedIterator struct { + Event *AddressManagerAdminChanged // 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 *AddressManagerAdminChangedIterator) 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(AddressManagerAdminChanged) + 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(AddressManagerAdminChanged) + 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 *AddressManagerAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerAdminChanged represents a AdminChanged event raised by the AddressManager contract. +type AddressManagerAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AddressManager *AddressManagerFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*AddressManagerAdminChangedIterator, error) { + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &AddressManagerAdminChangedIterator{contract: _AddressManager.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AddressManager *AddressManagerFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *AddressManagerAdminChanged) (event.Subscription, error) { + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "AdminChanged") + 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(AddressManagerAdminChanged) + if err := _AddressManager.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AddressManager *AddressManagerFilterer) ParseAdminChanged(log types.Log) (*AddressManagerAdminChanged, error) { + event := new(AddressManagerAdminChanged) + if err := _AddressManager.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the AddressManager contract. +type AddressManagerBeaconUpgradedIterator struct { + Event *AddressManagerBeaconUpgraded // 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 *AddressManagerBeaconUpgradedIterator) 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(AddressManagerBeaconUpgraded) + 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(AddressManagerBeaconUpgraded) + 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 *AddressManagerBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerBeaconUpgraded represents a BeaconUpgraded event raised by the AddressManager contract. +type AddressManagerBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AddressManager *AddressManagerFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*AddressManagerBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &AddressManagerBeaconUpgradedIterator{contract: _AddressManager.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AddressManager *AddressManagerFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *AddressManagerBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(AddressManagerBeaconUpgraded) + if err := _AddressManager.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AddressManager *AddressManagerFilterer) ParseBeaconUpgraded(log types.Log) (*AddressManagerBeaconUpgraded, error) { + event := new(AddressManagerBeaconUpgraded) + if err := _AddressManager.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the AddressManager contract. +type AddressManagerInitializedIterator struct { + Event *AddressManagerInitialized // 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 *AddressManagerInitializedIterator) 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(AddressManagerInitialized) + 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(AddressManagerInitialized) + 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 *AddressManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerInitialized represents a Initialized event raised by the AddressManager contract. +type AddressManagerInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AddressManager *AddressManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*AddressManagerInitializedIterator, error) { + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &AddressManagerInitializedIterator{contract: _AddressManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AddressManager *AddressManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *AddressManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "Initialized") + 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(AddressManagerInitialized) + if err := _AddressManager.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AddressManager *AddressManagerFilterer) ParseInitialized(log types.Log) (*AddressManagerInitialized, error) { + event := new(AddressManagerInitialized) + if err := _AddressManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the AddressManager contract. +type AddressManagerOwnershipTransferStartedIterator struct { + Event *AddressManagerOwnershipTransferStarted // 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 *AddressManagerOwnershipTransferStartedIterator) 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(AddressManagerOwnershipTransferStarted) + 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(AddressManagerOwnershipTransferStarted) + 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 *AddressManagerOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the AddressManager contract. +type AddressManagerOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*AddressManagerOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &AddressManagerOwnershipTransferStartedIterator{contract: _AddressManager.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *AddressManagerOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(AddressManagerOwnershipTransferStarted) + if err := _AddressManager.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) ParseOwnershipTransferStarted(log types.Log) (*AddressManagerOwnershipTransferStarted, error) { + event := new(AddressManagerOwnershipTransferStarted) + if err := _AddressManager.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the AddressManager contract. +type AddressManagerOwnershipTransferredIterator struct { + Event *AddressManagerOwnershipTransferred // 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 *AddressManagerOwnershipTransferredIterator) 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(AddressManagerOwnershipTransferred) + 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(AddressManagerOwnershipTransferred) + 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 *AddressManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerOwnershipTransferred represents a OwnershipTransferred event raised by the AddressManager contract. +type AddressManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*AddressManagerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &AddressManagerOwnershipTransferredIterator{contract: _AddressManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AddressManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(AddressManagerOwnershipTransferred) + if err := _AddressManager.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AddressManager *AddressManagerFilterer) ParseOwnershipTransferred(log types.Log) (*AddressManagerOwnershipTransferred, error) { + event := new(AddressManagerOwnershipTransferred) + if err := _AddressManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the AddressManager contract. +type AddressManagerPausedIterator struct { + Event *AddressManagerPaused // 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 *AddressManagerPausedIterator) 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(AddressManagerPaused) + 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(AddressManagerPaused) + 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 *AddressManagerPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerPaused represents a Paused event raised by the AddressManager contract. +type AddressManagerPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AddressManager *AddressManagerFilterer) FilterPaused(opts *bind.FilterOpts) (*AddressManagerPausedIterator, error) { + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &AddressManagerPausedIterator{contract: _AddressManager.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AddressManager *AddressManagerFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *AddressManagerPaused) (event.Subscription, error) { + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "Paused") + 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(AddressManagerPaused) + if err := _AddressManager.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AddressManager *AddressManagerFilterer) ParsePaused(log types.Log) (*AddressManagerPaused, error) { + event := new(AddressManagerPaused) + if err := _AddressManager.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the AddressManager contract. +type AddressManagerUnpausedIterator struct { + Event *AddressManagerUnpaused // 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 *AddressManagerUnpausedIterator) 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(AddressManagerUnpaused) + 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(AddressManagerUnpaused) + 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 *AddressManagerUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerUnpaused represents a Unpaused event raised by the AddressManager contract. +type AddressManagerUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AddressManager *AddressManagerFilterer) FilterUnpaused(opts *bind.FilterOpts) (*AddressManagerUnpausedIterator, error) { + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &AddressManagerUnpausedIterator{contract: _AddressManager.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AddressManager *AddressManagerFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AddressManagerUnpaused) (event.Subscription, error) { + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "Unpaused") + 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(AddressManagerUnpaused) + if err := _AddressManager.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AddressManager *AddressManagerFilterer) ParseUnpaused(log types.Log) (*AddressManagerUnpaused, error) { + event := new(AddressManagerUnpaused) + if err := _AddressManager.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AddressManagerUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the AddressManager contract. +type AddressManagerUpgradedIterator struct { + Event *AddressManagerUpgraded // 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 *AddressManagerUpgradedIterator) 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(AddressManagerUpgraded) + 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(AddressManagerUpgraded) + 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 *AddressManagerUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AddressManagerUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AddressManagerUpgraded represents a Upgraded event raised by the AddressManager contract. +type AddressManagerUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AddressManager *AddressManagerFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*AddressManagerUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _AddressManager.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &AddressManagerUpgradedIterator{contract: _AddressManager.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AddressManager *AddressManagerFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *AddressManagerUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _AddressManager.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(AddressManagerUpgraded) + if err := _AddressManager.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AddressManager *AddressManagerFilterer) ParseUpgraded(log types.Log) (*AddressManagerUpgraded, error) { + event := new(AddressManagerUpgraded) + if err := _AddressManager.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_assignment_hook.go b/packages/taiko-client/bindings/gen_assignment_hook.go new file mode 100644 index 00000000000..8a83785a1f3 --- /dev/null +++ b/packages/taiko-client/bindings/gen_assignment_hook.go @@ -0,0 +1,2110 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// AssignmentHookProverAssignment is an auto generated low-level Go binding around an user-defined struct. +type AssignmentHookProverAssignment struct { + FeeToken common.Address + Expiry uint64 + MaxBlockId uint64 + MaxProposedIn uint64 + MetaHash [32]byte + ParentMetaHash [32]byte + TierFees []TaikoDataTierFee + Signature []byte +} + +// TaikoDataTierFee is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataTierFee struct { + Tier uint16 + Fee *big.Int +} + +// AssignmentHookMetaData contains all meta data concerning the AssignmentHook contract. +var AssignmentHookMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"MAX_GAS_PAYING_PROVER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashAssignment\",\"inputs\":[{\"name\":\"_assignment\",\"type\":\"tuple\",\"internalType\":\"structAssignmentHook.ProverAssignment\",\"components\":[{\"name\":\"feeToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maxBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maxProposedIn\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"tierFees\",\"type\":\"tuple[]\",\"internalType\":\"structTaikoData.TierFee[]\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"fee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"_taikoL1Address\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_blockProposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_assignedProver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onBlockProposed\",\"inputs\":[{\"name\":\"_blk\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Block\",\"components\":[{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"assignedProver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"proposedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"proposedIn\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"nextTransitionId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"verifiedTransitionId\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"_meta\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockAssigned\",\"inputs\":[{\"name\":\"assignedProver\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"meta\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"assignment\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structAssignmentHook.ProverAssignment\",\"components\":[{\"name\":\"feeToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maxBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maxProposedIn\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"tierFees\",\"type\":\"tuple[]\",\"internalType\":\"structTaikoData.TierFee[]\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"fee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EtherPaymentFailed\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"maxGas\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ETH_TRANSFER_FAILED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"HOOK_ASSIGNMENT_EXPIRED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"HOOK_ASSIGNMENT_INVALID_SIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"HOOK_TIER_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// AssignmentHookABI is the input ABI used to generate the binding from. +// Deprecated: Use AssignmentHookMetaData.ABI instead. +var AssignmentHookABI = AssignmentHookMetaData.ABI + +// AssignmentHook is an auto generated Go binding around an Ethereum contract. +type AssignmentHook struct { + AssignmentHookCaller // Read-only binding to the contract + AssignmentHookTransactor // Write-only binding to the contract + AssignmentHookFilterer // Log filterer for contract events +} + +// AssignmentHookCaller is an auto generated read-only Go binding around an Ethereum contract. +type AssignmentHookCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AssignmentHookTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AssignmentHookTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AssignmentHookFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AssignmentHookFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AssignmentHookSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AssignmentHookSession struct { + Contract *AssignmentHook // 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 +} + +// AssignmentHookCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AssignmentHookCallerSession struct { + Contract *AssignmentHookCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AssignmentHookTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AssignmentHookTransactorSession struct { + Contract *AssignmentHookTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AssignmentHookRaw is an auto generated low-level Go binding around an Ethereum contract. +type AssignmentHookRaw struct { + Contract *AssignmentHook // Generic contract binding to access the raw methods on +} + +// AssignmentHookCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AssignmentHookCallerRaw struct { + Contract *AssignmentHookCaller // Generic read-only contract binding to access the raw methods on +} + +// AssignmentHookTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AssignmentHookTransactorRaw struct { + Contract *AssignmentHookTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAssignmentHook creates a new instance of AssignmentHook, bound to a specific deployed contract. +func NewAssignmentHook(address common.Address, backend bind.ContractBackend) (*AssignmentHook, error) { + contract, err := bindAssignmentHook(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AssignmentHook{AssignmentHookCaller: AssignmentHookCaller{contract: contract}, AssignmentHookTransactor: AssignmentHookTransactor{contract: contract}, AssignmentHookFilterer: AssignmentHookFilterer{contract: contract}}, nil +} + +// NewAssignmentHookCaller creates a new read-only instance of AssignmentHook, bound to a specific deployed contract. +func NewAssignmentHookCaller(address common.Address, caller bind.ContractCaller) (*AssignmentHookCaller, error) { + contract, err := bindAssignmentHook(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AssignmentHookCaller{contract: contract}, nil +} + +// NewAssignmentHookTransactor creates a new write-only instance of AssignmentHook, bound to a specific deployed contract. +func NewAssignmentHookTransactor(address common.Address, transactor bind.ContractTransactor) (*AssignmentHookTransactor, error) { + contract, err := bindAssignmentHook(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AssignmentHookTransactor{contract: contract}, nil +} + +// NewAssignmentHookFilterer creates a new log filterer instance of AssignmentHook, bound to a specific deployed contract. +func NewAssignmentHookFilterer(address common.Address, filterer bind.ContractFilterer) (*AssignmentHookFilterer, error) { + contract, err := bindAssignmentHook(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AssignmentHookFilterer{contract: contract}, nil +} + +// bindAssignmentHook binds a generic wrapper to an already deployed contract. +func bindAssignmentHook(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AssignmentHookMetaData.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 (_AssignmentHook *AssignmentHookRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AssignmentHook.Contract.AssignmentHookCaller.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 (_AssignmentHook *AssignmentHookRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.Contract.AssignmentHookTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AssignmentHook *AssignmentHookRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AssignmentHook.Contract.AssignmentHookTransactor.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 (_AssignmentHook *AssignmentHookCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AssignmentHook.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 (_AssignmentHook *AssignmentHookTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AssignmentHook *AssignmentHookTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AssignmentHook.Contract.contract.Transact(opts, method, params...) +} + +// MAXGASPAYINGPROVER is a free data retrieval call binding the contract method 0x12925031. +// +// Solidity: function MAX_GAS_PAYING_PROVER() view returns(uint256) +func (_AssignmentHook *AssignmentHookCaller) MAXGASPAYINGPROVER(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "MAX_GAS_PAYING_PROVER") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MAXGASPAYINGPROVER is a free data retrieval call binding the contract method 0x12925031. +// +// Solidity: function MAX_GAS_PAYING_PROVER() view returns(uint256) +func (_AssignmentHook *AssignmentHookSession) MAXGASPAYINGPROVER() (*big.Int, error) { + return _AssignmentHook.Contract.MAXGASPAYINGPROVER(&_AssignmentHook.CallOpts) +} + +// MAXGASPAYINGPROVER is a free data retrieval call binding the contract method 0x12925031. +// +// Solidity: function MAX_GAS_PAYING_PROVER() view returns(uint256) +func (_AssignmentHook *AssignmentHookCallerSession) MAXGASPAYINGPROVER() (*big.Int, error) { + return _AssignmentHook.Contract.MAXGASPAYINGPROVER(&_AssignmentHook.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AssignmentHook *AssignmentHookCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AssignmentHook *AssignmentHookSession) AddressManager() (common.Address, error) { + return _AssignmentHook.Contract.AddressManager(&_AssignmentHook.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_AssignmentHook *AssignmentHookCallerSession) AddressManager() (common.Address, error) { + return _AssignmentHook.Contract.AddressManager(&_AssignmentHook.CallOpts) +} + +// HashAssignment is a free data retrieval call binding the contract method 0xaf3a0228. +// +// Solidity: function hashAssignment((address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) _assignment, address _taikoL1Address, address _blockProposer, address _assignedProver, bytes32 _blobHash) view returns(bytes32) +func (_AssignmentHook *AssignmentHookCaller) HashAssignment(opts *bind.CallOpts, _assignment AssignmentHookProverAssignment, _taikoL1Address common.Address, _blockProposer common.Address, _assignedProver common.Address, _blobHash [32]byte) ([32]byte, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "hashAssignment", _assignment, _taikoL1Address, _blockProposer, _assignedProver, _blobHash) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// HashAssignment is a free data retrieval call binding the contract method 0xaf3a0228. +// +// Solidity: function hashAssignment((address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) _assignment, address _taikoL1Address, address _blockProposer, address _assignedProver, bytes32 _blobHash) view returns(bytes32) +func (_AssignmentHook *AssignmentHookSession) HashAssignment(_assignment AssignmentHookProverAssignment, _taikoL1Address common.Address, _blockProposer common.Address, _assignedProver common.Address, _blobHash [32]byte) ([32]byte, error) { + return _AssignmentHook.Contract.HashAssignment(&_AssignmentHook.CallOpts, _assignment, _taikoL1Address, _blockProposer, _assignedProver, _blobHash) +} + +// HashAssignment is a free data retrieval call binding the contract method 0xaf3a0228. +// +// Solidity: function hashAssignment((address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) _assignment, address _taikoL1Address, address _blockProposer, address _assignedProver, bytes32 _blobHash) view returns(bytes32) +func (_AssignmentHook *AssignmentHookCallerSession) HashAssignment(_assignment AssignmentHookProverAssignment, _taikoL1Address common.Address, _blockProposer common.Address, _assignedProver common.Address, _blobHash [32]byte) ([32]byte, error) { + return _AssignmentHook.Contract.HashAssignment(&_AssignmentHook.CallOpts, _assignment, _taikoL1Address, _blockProposer, _assignedProver, _blobHash) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AssignmentHook *AssignmentHookCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AssignmentHook *AssignmentHookSession) LastUnpausedAt() (uint64, error) { + return _AssignmentHook.Contract.LastUnpausedAt(&_AssignmentHook.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_AssignmentHook *AssignmentHookCallerSession) LastUnpausedAt() (uint64, error) { + return _AssignmentHook.Contract.LastUnpausedAt(&_AssignmentHook.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AssignmentHook *AssignmentHookCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AssignmentHook *AssignmentHookSession) Owner() (common.Address, error) { + return _AssignmentHook.Contract.Owner(&_AssignmentHook.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_AssignmentHook *AssignmentHookCallerSession) Owner() (common.Address, error) { + return _AssignmentHook.Contract.Owner(&_AssignmentHook.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AssignmentHook *AssignmentHookCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AssignmentHook *AssignmentHookSession) Paused() (bool, error) { + return _AssignmentHook.Contract.Paused(&_AssignmentHook.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_AssignmentHook *AssignmentHookCallerSession) Paused() (bool, error) { + return _AssignmentHook.Contract.Paused(&_AssignmentHook.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AssignmentHook *AssignmentHookCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AssignmentHook *AssignmentHookSession) PendingOwner() (common.Address, error) { + return _AssignmentHook.Contract.PendingOwner(&_AssignmentHook.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_AssignmentHook *AssignmentHookCallerSession) PendingOwner() (common.Address, error) { + return _AssignmentHook.Contract.PendingOwner(&_AssignmentHook.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AssignmentHook *AssignmentHookCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AssignmentHook *AssignmentHookSession) ProxiableUUID() ([32]byte, error) { + return _AssignmentHook.Contract.ProxiableUUID(&_AssignmentHook.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_AssignmentHook *AssignmentHookCallerSession) ProxiableUUID() ([32]byte, error) { + return _AssignmentHook.Contract.ProxiableUUID(&_AssignmentHook.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AssignmentHook.Contract.Resolve(&_AssignmentHook.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AssignmentHook.Contract.Resolve(&_AssignmentHook.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _AssignmentHook.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AssignmentHook.Contract.Resolve0(&_AssignmentHook.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_AssignmentHook *AssignmentHookCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _AssignmentHook.Contract.Resolve0(&_AssignmentHook.CallOpts, _name, _allowZeroAddress) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AssignmentHook *AssignmentHookTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AssignmentHook *AssignmentHookSession) AcceptOwnership() (*types.Transaction, error) { + return _AssignmentHook.Contract.AcceptOwnership(&_AssignmentHook.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_AssignmentHook *AssignmentHookTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AssignmentHook.Contract.AcceptOwnership(&_AssignmentHook.TransactOpts) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_AssignmentHook *AssignmentHookTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "init", _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_AssignmentHook *AssignmentHookSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.Init(&_AssignmentHook.TransactOpts, _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_AssignmentHook *AssignmentHookTransactorSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.Init(&_AssignmentHook.TransactOpts, _owner, _addressManager) +} + +// OnBlockProposed is a paid mutator transaction binding the contract method 0x36b6ea4e. +// +// Solidity: function onBlockProposed((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) _blk, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, bytes _data) payable returns() +func (_AssignmentHook *AssignmentHookTransactor) OnBlockProposed(opts *bind.TransactOpts, _blk TaikoDataBlock, _meta TaikoDataBlockMetadata, _data []byte) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "onBlockProposed", _blk, _meta, _data) +} + +// OnBlockProposed is a paid mutator transaction binding the contract method 0x36b6ea4e. +// +// Solidity: function onBlockProposed((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) _blk, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, bytes _data) payable returns() +func (_AssignmentHook *AssignmentHookSession) OnBlockProposed(_blk TaikoDataBlock, _meta TaikoDataBlockMetadata, _data []byte) (*types.Transaction, error) { + return _AssignmentHook.Contract.OnBlockProposed(&_AssignmentHook.TransactOpts, _blk, _meta, _data) +} + +// OnBlockProposed is a paid mutator transaction binding the contract method 0x36b6ea4e. +// +// Solidity: function onBlockProposed((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) _blk, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, bytes _data) payable returns() +func (_AssignmentHook *AssignmentHookTransactorSession) OnBlockProposed(_blk TaikoDataBlock, _meta TaikoDataBlockMetadata, _data []byte) (*types.Transaction, error) { + return _AssignmentHook.Contract.OnBlockProposed(&_AssignmentHook.TransactOpts, _blk, _meta, _data) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AssignmentHook *AssignmentHookTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AssignmentHook *AssignmentHookSession) Pause() (*types.Transaction, error) { + return _AssignmentHook.Contract.Pause(&_AssignmentHook.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_AssignmentHook *AssignmentHookTransactorSession) Pause() (*types.Transaction, error) { + return _AssignmentHook.Contract.Pause(&_AssignmentHook.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AssignmentHook *AssignmentHookTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AssignmentHook *AssignmentHookSession) RenounceOwnership() (*types.Transaction, error) { + return _AssignmentHook.Contract.RenounceOwnership(&_AssignmentHook.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_AssignmentHook *AssignmentHookTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _AssignmentHook.Contract.RenounceOwnership(&_AssignmentHook.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AssignmentHook *AssignmentHookTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AssignmentHook *AssignmentHookSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.TransferOwnership(&_AssignmentHook.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_AssignmentHook *AssignmentHookTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.TransferOwnership(&_AssignmentHook.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AssignmentHook *AssignmentHookTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AssignmentHook *AssignmentHookSession) Unpause() (*types.Transaction, error) { + return _AssignmentHook.Contract.Unpause(&_AssignmentHook.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_AssignmentHook *AssignmentHookTransactorSession) Unpause() (*types.Transaction, error) { + return _AssignmentHook.Contract.Unpause(&_AssignmentHook.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AssignmentHook *AssignmentHookTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AssignmentHook *AssignmentHookSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.UpgradeTo(&_AssignmentHook.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_AssignmentHook *AssignmentHookTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _AssignmentHook.Contract.UpgradeTo(&_AssignmentHook.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AssignmentHook *AssignmentHookTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AssignmentHook.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AssignmentHook *AssignmentHookSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AssignmentHook.Contract.UpgradeToAndCall(&_AssignmentHook.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_AssignmentHook *AssignmentHookTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _AssignmentHook.Contract.UpgradeToAndCall(&_AssignmentHook.TransactOpts, newImplementation, data) +} + +// AssignmentHookAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the AssignmentHook contract. +type AssignmentHookAdminChangedIterator struct { + Event *AssignmentHookAdminChanged // 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 *AssignmentHookAdminChangedIterator) 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(AssignmentHookAdminChanged) + 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(AssignmentHookAdminChanged) + 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 *AssignmentHookAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookAdminChanged represents a AdminChanged event raised by the AssignmentHook contract. +type AssignmentHookAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AssignmentHook *AssignmentHookFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*AssignmentHookAdminChangedIterator, error) { + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &AssignmentHookAdminChangedIterator{contract: _AssignmentHook.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AssignmentHook *AssignmentHookFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *AssignmentHookAdminChanged) (event.Subscription, error) { + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "AdminChanged") + 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(AssignmentHookAdminChanged) + if err := _AssignmentHook.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_AssignmentHook *AssignmentHookFilterer) ParseAdminChanged(log types.Log) (*AssignmentHookAdminChanged, error) { + event := new(AssignmentHookAdminChanged) + if err := _AssignmentHook.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the AssignmentHook contract. +type AssignmentHookBeaconUpgradedIterator struct { + Event *AssignmentHookBeaconUpgraded // 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 *AssignmentHookBeaconUpgradedIterator) 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(AssignmentHookBeaconUpgraded) + 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(AssignmentHookBeaconUpgraded) + 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 *AssignmentHookBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookBeaconUpgraded represents a BeaconUpgraded event raised by the AssignmentHook contract. +type AssignmentHookBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AssignmentHook *AssignmentHookFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*AssignmentHookBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &AssignmentHookBeaconUpgradedIterator{contract: _AssignmentHook.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AssignmentHook *AssignmentHookFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *AssignmentHookBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(AssignmentHookBeaconUpgraded) + if err := _AssignmentHook.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_AssignmentHook *AssignmentHookFilterer) ParseBeaconUpgraded(log types.Log) (*AssignmentHookBeaconUpgraded, error) { + event := new(AssignmentHookBeaconUpgraded) + if err := _AssignmentHook.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookBlockAssignedIterator is returned from FilterBlockAssigned and is used to iterate over the raw logs and unpacked data for BlockAssigned events raised by the AssignmentHook contract. +type AssignmentHookBlockAssignedIterator struct { + Event *AssignmentHookBlockAssigned // 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 *AssignmentHookBlockAssignedIterator) 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(AssignmentHookBlockAssigned) + 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(AssignmentHookBlockAssigned) + 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 *AssignmentHookBlockAssignedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookBlockAssignedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookBlockAssigned represents a BlockAssigned event raised by the AssignmentHook contract. +type AssignmentHookBlockAssigned struct { + AssignedProver common.Address + Meta TaikoDataBlockMetadata + Assignment AssignmentHookProverAssignment + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockAssigned is a free log retrieval operation binding the contract event 0x983b2c64d5e49fdb74b580110b1c64f6f6572b114331e9fee6b7531627eaf0b1. +// +// Solidity: event BlockAssigned(address indexed assignedProver, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) assignment) +func (_AssignmentHook *AssignmentHookFilterer) FilterBlockAssigned(opts *bind.FilterOpts, assignedProver []common.Address) (*AssignmentHookBlockAssignedIterator, error) { + + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "BlockAssigned", assignedProverRule) + if err != nil { + return nil, err + } + return &AssignmentHookBlockAssignedIterator{contract: _AssignmentHook.contract, event: "BlockAssigned", logs: logs, sub: sub}, nil +} + +// WatchBlockAssigned is a free log subscription operation binding the contract event 0x983b2c64d5e49fdb74b580110b1c64f6f6572b114331e9fee6b7531627eaf0b1. +// +// Solidity: event BlockAssigned(address indexed assignedProver, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) assignment) +func (_AssignmentHook *AssignmentHookFilterer) WatchBlockAssigned(opts *bind.WatchOpts, sink chan<- *AssignmentHookBlockAssigned, assignedProver []common.Address) (event.Subscription, error) { + + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "BlockAssigned", assignedProverRule) + 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(AssignmentHookBlockAssigned) + if err := _AssignmentHook.contract.UnpackLog(event, "BlockAssigned", 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 +} + +// ParseBlockAssigned is a log parse operation binding the contract event 0x983b2c64d5e49fdb74b580110b1c64f6f6572b114331e9fee6b7531627eaf0b1. +// +// Solidity: event BlockAssigned(address indexed assignedProver, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint64,uint64,uint64,bytes32,bytes32,(uint16,uint128)[],bytes) assignment) +func (_AssignmentHook *AssignmentHookFilterer) ParseBlockAssigned(log types.Log) (*AssignmentHookBlockAssigned, error) { + event := new(AssignmentHookBlockAssigned) + if err := _AssignmentHook.contract.UnpackLog(event, "BlockAssigned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookEtherPaymentFailedIterator is returned from FilterEtherPaymentFailed and is used to iterate over the raw logs and unpacked data for EtherPaymentFailed events raised by the AssignmentHook contract. +type AssignmentHookEtherPaymentFailedIterator struct { + Event *AssignmentHookEtherPaymentFailed // 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 *AssignmentHookEtherPaymentFailedIterator) 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(AssignmentHookEtherPaymentFailed) + 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(AssignmentHookEtherPaymentFailed) + 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 *AssignmentHookEtherPaymentFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookEtherPaymentFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookEtherPaymentFailed represents a EtherPaymentFailed event raised by the AssignmentHook contract. +type AssignmentHookEtherPaymentFailed struct { + To common.Address + MaxGas *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEtherPaymentFailed is a free log retrieval operation binding the contract event 0x193fbe934858a5b7669033de55612da355d11604360d59535b5bfaa25c42209e. +// +// Solidity: event EtherPaymentFailed(address to, uint256 maxGas) +func (_AssignmentHook *AssignmentHookFilterer) FilterEtherPaymentFailed(opts *bind.FilterOpts) (*AssignmentHookEtherPaymentFailedIterator, error) { + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "EtherPaymentFailed") + if err != nil { + return nil, err + } + return &AssignmentHookEtherPaymentFailedIterator{contract: _AssignmentHook.contract, event: "EtherPaymentFailed", logs: logs, sub: sub}, nil +} + +// WatchEtherPaymentFailed is a free log subscription operation binding the contract event 0x193fbe934858a5b7669033de55612da355d11604360d59535b5bfaa25c42209e. +// +// Solidity: event EtherPaymentFailed(address to, uint256 maxGas) +func (_AssignmentHook *AssignmentHookFilterer) WatchEtherPaymentFailed(opts *bind.WatchOpts, sink chan<- *AssignmentHookEtherPaymentFailed) (event.Subscription, error) { + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "EtherPaymentFailed") + 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(AssignmentHookEtherPaymentFailed) + if err := _AssignmentHook.contract.UnpackLog(event, "EtherPaymentFailed", 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 +} + +// ParseEtherPaymentFailed is a log parse operation binding the contract event 0x193fbe934858a5b7669033de55612da355d11604360d59535b5bfaa25c42209e. +// +// Solidity: event EtherPaymentFailed(address to, uint256 maxGas) +func (_AssignmentHook *AssignmentHookFilterer) ParseEtherPaymentFailed(log types.Log) (*AssignmentHookEtherPaymentFailed, error) { + event := new(AssignmentHookEtherPaymentFailed) + if err := _AssignmentHook.contract.UnpackLog(event, "EtherPaymentFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the AssignmentHook contract. +type AssignmentHookInitializedIterator struct { + Event *AssignmentHookInitialized // 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 *AssignmentHookInitializedIterator) 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(AssignmentHookInitialized) + 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(AssignmentHookInitialized) + 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 *AssignmentHookInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookInitialized represents a Initialized event raised by the AssignmentHook contract. +type AssignmentHookInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AssignmentHook *AssignmentHookFilterer) FilterInitialized(opts *bind.FilterOpts) (*AssignmentHookInitializedIterator, error) { + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &AssignmentHookInitializedIterator{contract: _AssignmentHook.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AssignmentHook *AssignmentHookFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *AssignmentHookInitialized) (event.Subscription, error) { + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "Initialized") + 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(AssignmentHookInitialized) + if err := _AssignmentHook.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_AssignmentHook *AssignmentHookFilterer) ParseInitialized(log types.Log) (*AssignmentHookInitialized, error) { + event := new(AssignmentHookInitialized) + if err := _AssignmentHook.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the AssignmentHook contract. +type AssignmentHookOwnershipTransferStartedIterator struct { + Event *AssignmentHookOwnershipTransferStarted // 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 *AssignmentHookOwnershipTransferStartedIterator) 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(AssignmentHookOwnershipTransferStarted) + 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(AssignmentHookOwnershipTransferStarted) + 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 *AssignmentHookOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the AssignmentHook contract. +type AssignmentHookOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*AssignmentHookOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &AssignmentHookOwnershipTransferStartedIterator{contract: _AssignmentHook.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *AssignmentHookOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(AssignmentHookOwnershipTransferStarted) + if err := _AssignmentHook.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) ParseOwnershipTransferStarted(log types.Log) (*AssignmentHookOwnershipTransferStarted, error) { + event := new(AssignmentHookOwnershipTransferStarted) + if err := _AssignmentHook.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the AssignmentHook contract. +type AssignmentHookOwnershipTransferredIterator struct { + Event *AssignmentHookOwnershipTransferred // 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 *AssignmentHookOwnershipTransferredIterator) 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(AssignmentHookOwnershipTransferred) + 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(AssignmentHookOwnershipTransferred) + 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 *AssignmentHookOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookOwnershipTransferred represents a OwnershipTransferred event raised by the AssignmentHook contract. +type AssignmentHookOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*AssignmentHookOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &AssignmentHookOwnershipTransferredIterator{contract: _AssignmentHook.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AssignmentHookOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(AssignmentHookOwnershipTransferred) + if err := _AssignmentHook.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_AssignmentHook *AssignmentHookFilterer) ParseOwnershipTransferred(log types.Log) (*AssignmentHookOwnershipTransferred, error) { + event := new(AssignmentHookOwnershipTransferred) + if err := _AssignmentHook.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the AssignmentHook contract. +type AssignmentHookPausedIterator struct { + Event *AssignmentHookPaused // 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 *AssignmentHookPausedIterator) 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(AssignmentHookPaused) + 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(AssignmentHookPaused) + 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 *AssignmentHookPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookPaused represents a Paused event raised by the AssignmentHook contract. +type AssignmentHookPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AssignmentHook *AssignmentHookFilterer) FilterPaused(opts *bind.FilterOpts) (*AssignmentHookPausedIterator, error) { + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &AssignmentHookPausedIterator{contract: _AssignmentHook.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AssignmentHook *AssignmentHookFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *AssignmentHookPaused) (event.Subscription, error) { + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "Paused") + 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(AssignmentHookPaused) + if err := _AssignmentHook.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_AssignmentHook *AssignmentHookFilterer) ParsePaused(log types.Log) (*AssignmentHookPaused, error) { + event := new(AssignmentHookPaused) + if err := _AssignmentHook.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the AssignmentHook contract. +type AssignmentHookUnpausedIterator struct { + Event *AssignmentHookUnpaused // 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 *AssignmentHookUnpausedIterator) 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(AssignmentHookUnpaused) + 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(AssignmentHookUnpaused) + 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 *AssignmentHookUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookUnpaused represents a Unpaused event raised by the AssignmentHook contract. +type AssignmentHookUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AssignmentHook *AssignmentHookFilterer) FilterUnpaused(opts *bind.FilterOpts) (*AssignmentHookUnpausedIterator, error) { + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &AssignmentHookUnpausedIterator{contract: _AssignmentHook.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AssignmentHook *AssignmentHookFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AssignmentHookUnpaused) (event.Subscription, error) { + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "Unpaused") + 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(AssignmentHookUnpaused) + if err := _AssignmentHook.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_AssignmentHook *AssignmentHookFilterer) ParseUnpaused(log types.Log) (*AssignmentHookUnpaused, error) { + event := new(AssignmentHookUnpaused) + if err := _AssignmentHook.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AssignmentHookUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the AssignmentHook contract. +type AssignmentHookUpgradedIterator struct { + Event *AssignmentHookUpgraded // 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 *AssignmentHookUpgradedIterator) 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(AssignmentHookUpgraded) + 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(AssignmentHookUpgraded) + 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 *AssignmentHookUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AssignmentHookUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AssignmentHookUpgraded represents a Upgraded event raised by the AssignmentHook contract. +type AssignmentHookUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AssignmentHook *AssignmentHookFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*AssignmentHookUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _AssignmentHook.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &AssignmentHookUpgradedIterator{contract: _AssignmentHook.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AssignmentHook *AssignmentHookFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *AssignmentHookUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _AssignmentHook.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(AssignmentHookUpgraded) + if err := _AssignmentHook.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_AssignmentHook *AssignmentHookFilterer) ParseUpgraded(log types.Log) (*AssignmentHookUpgraded, error) { + event := new(AssignmentHookUpgraded) + if err := _AssignmentHook.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_guardian_prover.go b/packages/taiko-client/bindings/gen_guardian_prover.go new file mode 100644 index 00000000000..89c310e158e --- /dev/null +++ b/packages/taiko-client/bindings/gen_guardian_prover.go @@ -0,0 +1,2489 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// IVerifierContext is an auto generated low-level Go binding around an user-defined struct. +type IVerifierContext struct { + MetaHash [32]byte + BlobHash [32]byte + Prover common.Address + BlockId uint64 + IsContesting bool + BlobUsed bool + MsgSender common.Address +} + +// TaikoDataTierProof is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataTierProof struct { + Tier uint16 + Data []byte +} + +// GuardianProverMetaData contains all meta data concerning the GuardianProver contract. +var GuardianProverMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"_meta\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"_tran\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_proof\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TierProof\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"approved_\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"enableTaikoTokenAllowance\",\"inputs\":[{\"name\":\"_enable\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"guardianIds\",\"inputs\":[{\"name\":\"guardian\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"id\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"guardians\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isApproved\",\"inputs\":[{\"name\":\"_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"minGuardians\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numGuardians\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setGuardians\",\"inputs\":[{\"name\":\"_newGuardians\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"_minGuardians\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifyProof\",\"inputs\":[{\"name\":\"_ctx\",\"type\":\"tuple\",\"internalType\":\"structIVerifier.Context\",\"components\":[{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"prover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"isContesting\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"msgSender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TierProof\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawTaikoToken\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Approved\",\"inputs\":[{\"name\":\"operationId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"approvalBits\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"minGuardiansReached\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GuardianApproval\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"},{\"name\":\"proofData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GuardiansUpdated\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"guardians\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"GV_PERMISSION_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GV_ZERO_ADDRESS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_GUARDIAN\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_GUARDIAN_SET\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_MIN_GUARDIANS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PROOF\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// GuardianProverABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardianProverMetaData.ABI instead. +var GuardianProverABI = GuardianProverMetaData.ABI + +// GuardianProver is an auto generated Go binding around an Ethereum contract. +type GuardianProver struct { + GuardianProverCaller // Read-only binding to the contract + GuardianProverTransactor // Write-only binding to the contract + GuardianProverFilterer // Log filterer for contract events +} + +// GuardianProverCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardianProverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianProverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardianProverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianProverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardianProverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianProverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardianProverSession struct { + Contract *GuardianProver // 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 +} + +// GuardianProverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GuardianProverCallerSession struct { + Contract *GuardianProverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// GuardianProverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GuardianProverTransactorSession struct { + Contract *GuardianProverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GuardianProverRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardianProverRaw struct { + Contract *GuardianProver // Generic contract binding to access the raw methods on +} + +// GuardianProverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardianProverCallerRaw struct { + Contract *GuardianProverCaller // Generic read-only contract binding to access the raw methods on +} + +// GuardianProverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardianProverTransactorRaw struct { + Contract *GuardianProverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewGuardianProver creates a new instance of GuardianProver, bound to a specific deployed contract. +func NewGuardianProver(address common.Address, backend bind.ContractBackend) (*GuardianProver, error) { + contract, err := bindGuardianProver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &GuardianProver{GuardianProverCaller: GuardianProverCaller{contract: contract}, GuardianProverTransactor: GuardianProverTransactor{contract: contract}, GuardianProverFilterer: GuardianProverFilterer{contract: contract}}, nil +} + +// NewGuardianProverCaller creates a new read-only instance of GuardianProver, bound to a specific deployed contract. +func NewGuardianProverCaller(address common.Address, caller bind.ContractCaller) (*GuardianProverCaller, error) { + contract, err := bindGuardianProver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GuardianProverCaller{contract: contract}, nil +} + +// NewGuardianProverTransactor creates a new write-only instance of GuardianProver, bound to a specific deployed contract. +func NewGuardianProverTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardianProverTransactor, error) { + contract, err := bindGuardianProver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GuardianProverTransactor{contract: contract}, nil +} + +// NewGuardianProverFilterer creates a new log filterer instance of GuardianProver, bound to a specific deployed contract. +func NewGuardianProverFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardianProverFilterer, error) { + contract, err := bindGuardianProver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &GuardianProverFilterer{contract: contract}, nil +} + +// bindGuardianProver binds a generic wrapper to an already deployed contract. +func bindGuardianProver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := GuardianProverMetaData.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 (_GuardianProver *GuardianProverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardianProver.Contract.GuardianProverCaller.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 (_GuardianProver *GuardianProverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.Contract.GuardianProverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GuardianProver *GuardianProverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardianProver.Contract.GuardianProverTransactor.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 (_GuardianProver *GuardianProverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardianProver.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 (_GuardianProver *GuardianProverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GuardianProver *GuardianProverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardianProver.Contract.contract.Transact(opts, method, params...) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianProver *GuardianProverCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianProver *GuardianProverSession) AddressManager() (common.Address, error) { + return _GuardianProver.Contract.AddressManager(&_GuardianProver.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianProver *GuardianProverCallerSession) AddressManager() (common.Address, error) { + return _GuardianProver.Contract.AddressManager(&_GuardianProver.CallOpts) +} + +// GuardianIds is a free data retrieval call binding the contract method 0xb6158373. +// +// Solidity: function guardianIds(address guardian) view returns(uint256 id) +func (_GuardianProver *GuardianProverCaller) GuardianIds(opts *bind.CallOpts, guardian common.Address) (*big.Int, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "guardianIds", guardian) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GuardianIds is a free data retrieval call binding the contract method 0xb6158373. +// +// Solidity: function guardianIds(address guardian) view returns(uint256 id) +func (_GuardianProver *GuardianProverSession) GuardianIds(guardian common.Address) (*big.Int, error) { + return _GuardianProver.Contract.GuardianIds(&_GuardianProver.CallOpts, guardian) +} + +// GuardianIds is a free data retrieval call binding the contract method 0xb6158373. +// +// Solidity: function guardianIds(address guardian) view returns(uint256 id) +func (_GuardianProver *GuardianProverCallerSession) GuardianIds(guardian common.Address) (*big.Int, error) { + return _GuardianProver.Contract.GuardianIds(&_GuardianProver.CallOpts, guardian) +} + +// Guardians is a free data retrieval call binding the contract method 0xf560c734. +// +// Solidity: function guardians(uint256 ) view returns(address) +func (_GuardianProver *GuardianProverCaller) Guardians(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "guardians", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Guardians is a free data retrieval call binding the contract method 0xf560c734. +// +// Solidity: function guardians(uint256 ) view returns(address) +func (_GuardianProver *GuardianProverSession) Guardians(arg0 *big.Int) (common.Address, error) { + return _GuardianProver.Contract.Guardians(&_GuardianProver.CallOpts, arg0) +} + +// Guardians is a free data retrieval call binding the contract method 0xf560c734. +// +// Solidity: function guardians(uint256 ) view returns(address) +func (_GuardianProver *GuardianProverCallerSession) Guardians(arg0 *big.Int) (common.Address, error) { + return _GuardianProver.Contract.Guardians(&_GuardianProver.CallOpts, arg0) +} + +// IsApproved is a free data retrieval call binding the contract method 0x48aefc32. +// +// Solidity: function isApproved(bytes32 _hash) view returns(bool) +func (_GuardianProver *GuardianProverCaller) IsApproved(opts *bind.CallOpts, _hash [32]byte) (bool, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "isApproved", _hash) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsApproved is a free data retrieval call binding the contract method 0x48aefc32. +// +// Solidity: function isApproved(bytes32 _hash) view returns(bool) +func (_GuardianProver *GuardianProverSession) IsApproved(_hash [32]byte) (bool, error) { + return _GuardianProver.Contract.IsApproved(&_GuardianProver.CallOpts, _hash) +} + +// IsApproved is a free data retrieval call binding the contract method 0x48aefc32. +// +// Solidity: function isApproved(bytes32 _hash) view returns(bool) +func (_GuardianProver *GuardianProverCallerSession) IsApproved(_hash [32]byte) (bool, error) { + return _GuardianProver.Contract.IsApproved(&_GuardianProver.CallOpts, _hash) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianProver *GuardianProverCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianProver *GuardianProverSession) LastUnpausedAt() (uint64, error) { + return _GuardianProver.Contract.LastUnpausedAt(&_GuardianProver.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianProver *GuardianProverCallerSession) LastUnpausedAt() (uint64, error) { + return _GuardianProver.Contract.LastUnpausedAt(&_GuardianProver.CallOpts) +} + +// MinGuardians is a free data retrieval call binding the contract method 0x2d6f5ca7. +// +// Solidity: function minGuardians() view returns(uint32) +func (_GuardianProver *GuardianProverCaller) MinGuardians(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "minGuardians") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// MinGuardians is a free data retrieval call binding the contract method 0x2d6f5ca7. +// +// Solidity: function minGuardians() view returns(uint32) +func (_GuardianProver *GuardianProverSession) MinGuardians() (uint32, error) { + return _GuardianProver.Contract.MinGuardians(&_GuardianProver.CallOpts) +} + +// MinGuardians is a free data retrieval call binding the contract method 0x2d6f5ca7. +// +// Solidity: function minGuardians() view returns(uint32) +func (_GuardianProver *GuardianProverCallerSession) MinGuardians() (uint32, error) { + return _GuardianProver.Contract.MinGuardians(&_GuardianProver.CallOpts) +} + +// NumGuardians is a free data retrieval call binding the contract method 0xd13cbca3. +// +// Solidity: function numGuardians() view returns(uint256) +func (_GuardianProver *GuardianProverCaller) NumGuardians(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "numGuardians") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NumGuardians is a free data retrieval call binding the contract method 0xd13cbca3. +// +// Solidity: function numGuardians() view returns(uint256) +func (_GuardianProver *GuardianProverSession) NumGuardians() (*big.Int, error) { + return _GuardianProver.Contract.NumGuardians(&_GuardianProver.CallOpts) +} + +// NumGuardians is a free data retrieval call binding the contract method 0xd13cbca3. +// +// Solidity: function numGuardians() view returns(uint256) +func (_GuardianProver *GuardianProverCallerSession) NumGuardians() (*big.Int, error) { + return _GuardianProver.Contract.NumGuardians(&_GuardianProver.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianProver *GuardianProverCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianProver *GuardianProverSession) Owner() (common.Address, error) { + return _GuardianProver.Contract.Owner(&_GuardianProver.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianProver *GuardianProverCallerSession) Owner() (common.Address, error) { + return _GuardianProver.Contract.Owner(&_GuardianProver.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianProver *GuardianProverCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianProver *GuardianProverSession) Paused() (bool, error) { + return _GuardianProver.Contract.Paused(&_GuardianProver.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianProver *GuardianProverCallerSession) Paused() (bool, error) { + return _GuardianProver.Contract.Paused(&_GuardianProver.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianProver *GuardianProverCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianProver *GuardianProverSession) PendingOwner() (common.Address, error) { + return _GuardianProver.Contract.PendingOwner(&_GuardianProver.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianProver *GuardianProverCallerSession) PendingOwner() (common.Address, error) { + return _GuardianProver.Contract.PendingOwner(&_GuardianProver.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianProver *GuardianProverCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianProver *GuardianProverSession) ProxiableUUID() ([32]byte, error) { + return _GuardianProver.Contract.ProxiableUUID(&_GuardianProver.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianProver *GuardianProverCallerSession) ProxiableUUID() ([32]byte, error) { + return _GuardianProver.Contract.ProxiableUUID(&_GuardianProver.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianProver.Contract.Resolve(&_GuardianProver.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianProver.Contract.Resolve(&_GuardianProver.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianProver.Contract.Resolve0(&_GuardianProver.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianProver *GuardianProverCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianProver.Contract.Resolve0(&_GuardianProver.CallOpts, _name, _allowZeroAddress) +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) ) view returns() +func (_GuardianProver *GuardianProverCaller) VerifyProof(opts *bind.CallOpts, _ctx IVerifierContext, arg1 TaikoDataTransition, arg2 TaikoDataTierProof) error { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "verifyProof", _ctx, arg1, arg2) + + if err != nil { + return err + } + + return err + +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) ) view returns() +func (_GuardianProver *GuardianProverSession) VerifyProof(_ctx IVerifierContext, arg1 TaikoDataTransition, arg2 TaikoDataTierProof) error { + return _GuardianProver.Contract.VerifyProof(&_GuardianProver.CallOpts, _ctx, arg1, arg2) +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) ) view returns() +func (_GuardianProver *GuardianProverCallerSession) VerifyProof(_ctx IVerifierContext, arg1 TaikoDataTransition, arg2 TaikoDataTierProof) error { + return _GuardianProver.Contract.VerifyProof(&_GuardianProver.CallOpts, _ctx, arg1, arg2) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint32) +func (_GuardianProver *GuardianProverCaller) Version(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _GuardianProver.contract.Call(opts, &out, "version") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint32) +func (_GuardianProver *GuardianProverSession) Version() (uint32, error) { + return _GuardianProver.Contract.Version(&_GuardianProver.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint32) +func (_GuardianProver *GuardianProverCallerSession) Version() (uint32, error) { + return _GuardianProver.Contract.Version(&_GuardianProver.CallOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianProver *GuardianProverTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianProver *GuardianProverSession) AcceptOwnership() (*types.Transaction, error) { + return _GuardianProver.Contract.AcceptOwnership(&_GuardianProver.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianProver *GuardianProverTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _GuardianProver.Contract.AcceptOwnership(&_GuardianProver.TransactOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x98984761. +// +// Solidity: function approve((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns(bool approved_) +func (_GuardianProver *GuardianProverTransactor) Approve(opts *bind.TransactOpts, _meta TaikoDataBlockMetadata, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "approve", _meta, _tran, _proof) +} + +// Approve is a paid mutator transaction binding the contract method 0x98984761. +// +// Solidity: function approve((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns(bool approved_) +func (_GuardianProver *GuardianProverSession) Approve(_meta TaikoDataBlockMetadata, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _GuardianProver.Contract.Approve(&_GuardianProver.TransactOpts, _meta, _tran, _proof) +} + +// Approve is a paid mutator transaction binding the contract method 0x98984761. +// +// Solidity: function approve((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) _meta, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns(bool approved_) +func (_GuardianProver *GuardianProverTransactorSession) Approve(_meta TaikoDataBlockMetadata, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _GuardianProver.Contract.Approve(&_GuardianProver.TransactOpts, _meta, _tran, _proof) +} + +// EnableTaikoTokenAllowance is a paid mutator transaction binding the contract method 0x8e1bacd7. +// +// Solidity: function enableTaikoTokenAllowance(bool _enable) returns() +func (_GuardianProver *GuardianProverTransactor) EnableTaikoTokenAllowance(opts *bind.TransactOpts, _enable bool) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "enableTaikoTokenAllowance", _enable) +} + +// EnableTaikoTokenAllowance is a paid mutator transaction binding the contract method 0x8e1bacd7. +// +// Solidity: function enableTaikoTokenAllowance(bool _enable) returns() +func (_GuardianProver *GuardianProverSession) EnableTaikoTokenAllowance(_enable bool) (*types.Transaction, error) { + return _GuardianProver.Contract.EnableTaikoTokenAllowance(&_GuardianProver.TransactOpts, _enable) +} + +// EnableTaikoTokenAllowance is a paid mutator transaction binding the contract method 0x8e1bacd7. +// +// Solidity: function enableTaikoTokenAllowance(bool _enable) returns() +func (_GuardianProver *GuardianProverTransactorSession) EnableTaikoTokenAllowance(_enable bool) (*types.Transaction, error) { + return _GuardianProver.Contract.EnableTaikoTokenAllowance(&_GuardianProver.TransactOpts, _enable) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianProver *GuardianProverTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "init", _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianProver *GuardianProverSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.Init(&_GuardianProver.TransactOpts, _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianProver *GuardianProverTransactorSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.Init(&_GuardianProver.TransactOpts, _owner, _addressManager) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianProver *GuardianProverTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianProver *GuardianProverSession) Pause() (*types.Transaction, error) { + return _GuardianProver.Contract.Pause(&_GuardianProver.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianProver *GuardianProverTransactorSession) Pause() (*types.Transaction, error) { + return _GuardianProver.Contract.Pause(&_GuardianProver.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianProver *GuardianProverTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianProver *GuardianProverSession) RenounceOwnership() (*types.Transaction, error) { + return _GuardianProver.Contract.RenounceOwnership(&_GuardianProver.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianProver *GuardianProverTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _GuardianProver.Contract.RenounceOwnership(&_GuardianProver.TransactOpts) +} + +// SetGuardians is a paid mutator transaction binding the contract method 0xe94e9e99. +// +// Solidity: function setGuardians(address[] _newGuardians, uint8 _minGuardians) returns() +func (_GuardianProver *GuardianProverTransactor) SetGuardians(opts *bind.TransactOpts, _newGuardians []common.Address, _minGuardians uint8) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "setGuardians", _newGuardians, _minGuardians) +} + +// SetGuardians is a paid mutator transaction binding the contract method 0xe94e9e99. +// +// Solidity: function setGuardians(address[] _newGuardians, uint8 _minGuardians) returns() +func (_GuardianProver *GuardianProverSession) SetGuardians(_newGuardians []common.Address, _minGuardians uint8) (*types.Transaction, error) { + return _GuardianProver.Contract.SetGuardians(&_GuardianProver.TransactOpts, _newGuardians, _minGuardians) +} + +// SetGuardians is a paid mutator transaction binding the contract method 0xe94e9e99. +// +// Solidity: function setGuardians(address[] _newGuardians, uint8 _minGuardians) returns() +func (_GuardianProver *GuardianProverTransactorSession) SetGuardians(_newGuardians []common.Address, _minGuardians uint8) (*types.Transaction, error) { + return _GuardianProver.Contract.SetGuardians(&_GuardianProver.TransactOpts, _newGuardians, _minGuardians) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianProver *GuardianProverTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianProver *GuardianProverSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.TransferOwnership(&_GuardianProver.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianProver *GuardianProverTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.TransferOwnership(&_GuardianProver.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianProver *GuardianProverTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianProver *GuardianProverSession) Unpause() (*types.Transaction, error) { + return _GuardianProver.Contract.Unpause(&_GuardianProver.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianProver *GuardianProverTransactorSession) Unpause() (*types.Transaction, error) { + return _GuardianProver.Contract.Unpause(&_GuardianProver.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianProver *GuardianProverTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianProver *GuardianProverSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.UpgradeTo(&_GuardianProver.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianProver *GuardianProverTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _GuardianProver.Contract.UpgradeTo(&_GuardianProver.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianProver *GuardianProverTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianProver *GuardianProverSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianProver.Contract.UpgradeToAndCall(&_GuardianProver.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianProver *GuardianProverTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianProver.Contract.UpgradeToAndCall(&_GuardianProver.TransactOpts, newImplementation, data) +} + +// WithdrawTaikoToken is a paid mutator transaction binding the contract method 0x694074c0. +// +// Solidity: function withdrawTaikoToken(address _to, uint256 _amount) returns() +func (_GuardianProver *GuardianProverTransactor) WithdrawTaikoToken(opts *bind.TransactOpts, _to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _GuardianProver.contract.Transact(opts, "withdrawTaikoToken", _to, _amount) +} + +// WithdrawTaikoToken is a paid mutator transaction binding the contract method 0x694074c0. +// +// Solidity: function withdrawTaikoToken(address _to, uint256 _amount) returns() +func (_GuardianProver *GuardianProverSession) WithdrawTaikoToken(_to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _GuardianProver.Contract.WithdrawTaikoToken(&_GuardianProver.TransactOpts, _to, _amount) +} + +// WithdrawTaikoToken is a paid mutator transaction binding the contract method 0x694074c0. +// +// Solidity: function withdrawTaikoToken(address _to, uint256 _amount) returns() +func (_GuardianProver *GuardianProverTransactorSession) WithdrawTaikoToken(_to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _GuardianProver.Contract.WithdrawTaikoToken(&_GuardianProver.TransactOpts, _to, _amount) +} + +// GuardianProverAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the GuardianProver contract. +type GuardianProverAdminChangedIterator struct { + Event *GuardianProverAdminChanged // 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 *GuardianProverAdminChangedIterator) 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(GuardianProverAdminChanged) + 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(GuardianProverAdminChanged) + 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 *GuardianProverAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverAdminChanged represents a AdminChanged event raised by the GuardianProver contract. +type GuardianProverAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianProver *GuardianProverFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*GuardianProverAdminChangedIterator, error) { + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &GuardianProverAdminChangedIterator{contract: _GuardianProver.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianProver *GuardianProverFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *GuardianProverAdminChanged) (event.Subscription, error) { + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "AdminChanged") + 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(GuardianProverAdminChanged) + if err := _GuardianProver.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianProver *GuardianProverFilterer) ParseAdminChanged(log types.Log) (*GuardianProverAdminChanged, error) { + event := new(GuardianProverAdminChanged) + if err := _GuardianProver.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverApprovedIterator is returned from FilterApproved and is used to iterate over the raw logs and unpacked data for Approved events raised by the GuardianProver contract. +type GuardianProverApprovedIterator struct { + Event *GuardianProverApproved // 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 *GuardianProverApprovedIterator) 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(GuardianProverApproved) + 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(GuardianProverApproved) + 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 *GuardianProverApprovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverApproved represents a Approved event raised by the GuardianProver contract. +type GuardianProverApproved struct { + OperationId *big.Int + ApprovalBits *big.Int + MinGuardiansReached bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproved is a free log retrieval operation binding the contract event 0x344afde5e92a836ece804d851bb090d420129616171e9911ade0a3f4d785e311. +// +// Solidity: event Approved(uint256 indexed operationId, uint256 approvalBits, bool minGuardiansReached) +func (_GuardianProver *GuardianProverFilterer) FilterApproved(opts *bind.FilterOpts, operationId []*big.Int) (*GuardianProverApprovedIterator, error) { + + var operationIdRule []interface{} + for _, operationIdItem := range operationId { + operationIdRule = append(operationIdRule, operationIdItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "Approved", operationIdRule) + if err != nil { + return nil, err + } + return &GuardianProverApprovedIterator{contract: _GuardianProver.contract, event: "Approved", logs: logs, sub: sub}, nil +} + +// WatchApproved is a free log subscription operation binding the contract event 0x344afde5e92a836ece804d851bb090d420129616171e9911ade0a3f4d785e311. +// +// Solidity: event Approved(uint256 indexed operationId, uint256 approvalBits, bool minGuardiansReached) +func (_GuardianProver *GuardianProverFilterer) WatchApproved(opts *bind.WatchOpts, sink chan<- *GuardianProverApproved, operationId []*big.Int) (event.Subscription, error) { + + var operationIdRule []interface{} + for _, operationIdItem := range operationId { + operationIdRule = append(operationIdRule, operationIdItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "Approved", operationIdRule) + 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(GuardianProverApproved) + if err := _GuardianProver.contract.UnpackLog(event, "Approved", 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 +} + +// ParseApproved is a log parse operation binding the contract event 0x344afde5e92a836ece804d851bb090d420129616171e9911ade0a3f4d785e311. +// +// Solidity: event Approved(uint256 indexed operationId, uint256 approvalBits, bool minGuardiansReached) +func (_GuardianProver *GuardianProverFilterer) ParseApproved(log types.Log) (*GuardianProverApproved, error) { + event := new(GuardianProverApproved) + if err := _GuardianProver.contract.UnpackLog(event, "Approved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the GuardianProver contract. +type GuardianProverBeaconUpgradedIterator struct { + Event *GuardianProverBeaconUpgraded // 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 *GuardianProverBeaconUpgradedIterator) 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(GuardianProverBeaconUpgraded) + 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(GuardianProverBeaconUpgraded) + 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 *GuardianProverBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverBeaconUpgraded represents a BeaconUpgraded event raised by the GuardianProver contract. +type GuardianProverBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianProver *GuardianProverFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*GuardianProverBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &GuardianProverBeaconUpgradedIterator{contract: _GuardianProver.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianProver *GuardianProverFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *GuardianProverBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(GuardianProverBeaconUpgraded) + if err := _GuardianProver.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianProver *GuardianProverFilterer) ParseBeaconUpgraded(log types.Log) (*GuardianProverBeaconUpgraded, error) { + event := new(GuardianProverBeaconUpgraded) + if err := _GuardianProver.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverGuardianApprovalIterator is returned from FilterGuardianApproval and is used to iterate over the raw logs and unpacked data for GuardianApproval events raised by the GuardianProver contract. +type GuardianProverGuardianApprovalIterator struct { + Event *GuardianProverGuardianApproval // 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 *GuardianProverGuardianApprovalIterator) 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(GuardianProverGuardianApproval) + 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(GuardianProverGuardianApproval) + 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 *GuardianProverGuardianApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverGuardianApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverGuardianApproval represents a GuardianApproval event raised by the GuardianProver contract. +type GuardianProverGuardianApproval struct { + Addr common.Address + BlockId *big.Int + BlockHash [32]byte + Approved bool + ProofData []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardianApproval is a free log retrieval operation binding the contract event 0xbff049f26ec63ed683b70f6c889078b391f9621229a4243aaa40a50628545ef2. +// +// Solidity: event GuardianApproval(address indexed addr, uint256 indexed blockId, bytes32 indexed blockHash, bool approved, bytes proofData) +func (_GuardianProver *GuardianProverFilterer) FilterGuardianApproval(opts *bind.FilterOpts, addr []common.Address, blockId []*big.Int, blockHash [][32]byte) (*GuardianProverGuardianApprovalIterator, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var blockHashRule []interface{} + for _, blockHashItem := range blockHash { + blockHashRule = append(blockHashRule, blockHashItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "GuardianApproval", addrRule, blockIdRule, blockHashRule) + if err != nil { + return nil, err + } + return &GuardianProverGuardianApprovalIterator{contract: _GuardianProver.contract, event: "GuardianApproval", logs: logs, sub: sub}, nil +} + +// WatchGuardianApproval is a free log subscription operation binding the contract event 0xbff049f26ec63ed683b70f6c889078b391f9621229a4243aaa40a50628545ef2. +// +// Solidity: event GuardianApproval(address indexed addr, uint256 indexed blockId, bytes32 indexed blockHash, bool approved, bytes proofData) +func (_GuardianProver *GuardianProverFilterer) WatchGuardianApproval(opts *bind.WatchOpts, sink chan<- *GuardianProverGuardianApproval, addr []common.Address, blockId []*big.Int, blockHash [][32]byte) (event.Subscription, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var blockHashRule []interface{} + for _, blockHashItem := range blockHash { + blockHashRule = append(blockHashRule, blockHashItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "GuardianApproval", addrRule, blockIdRule, blockHashRule) + 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(GuardianProverGuardianApproval) + if err := _GuardianProver.contract.UnpackLog(event, "GuardianApproval", 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 +} + +// ParseGuardianApproval is a log parse operation binding the contract event 0xbff049f26ec63ed683b70f6c889078b391f9621229a4243aaa40a50628545ef2. +// +// Solidity: event GuardianApproval(address indexed addr, uint256 indexed blockId, bytes32 indexed blockHash, bool approved, bytes proofData) +func (_GuardianProver *GuardianProverFilterer) ParseGuardianApproval(log types.Log) (*GuardianProverGuardianApproval, error) { + event := new(GuardianProverGuardianApproval) + if err := _GuardianProver.contract.UnpackLog(event, "GuardianApproval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverGuardiansUpdatedIterator is returned from FilterGuardiansUpdated and is used to iterate over the raw logs and unpacked data for GuardiansUpdated events raised by the GuardianProver contract. +type GuardianProverGuardiansUpdatedIterator struct { + Event *GuardianProverGuardiansUpdated // 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 *GuardianProverGuardiansUpdatedIterator) 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(GuardianProverGuardiansUpdated) + 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(GuardianProverGuardiansUpdated) + 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 *GuardianProverGuardiansUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverGuardiansUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverGuardiansUpdated represents a GuardiansUpdated event raised by the GuardianProver contract. +type GuardianProverGuardiansUpdated struct { + Version uint32 + Guardians []common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardiansUpdated is a free log retrieval operation binding the contract event 0x5132e5b598a417dfc5c7488e5360aef3e865fe4b238cd5ea2a8282e0ca8d10ef. +// +// Solidity: event GuardiansUpdated(uint32 version, address[] guardians) +func (_GuardianProver *GuardianProverFilterer) FilterGuardiansUpdated(opts *bind.FilterOpts) (*GuardianProverGuardiansUpdatedIterator, error) { + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "GuardiansUpdated") + if err != nil { + return nil, err + } + return &GuardianProverGuardiansUpdatedIterator{contract: _GuardianProver.contract, event: "GuardiansUpdated", logs: logs, sub: sub}, nil +} + +// WatchGuardiansUpdated is a free log subscription operation binding the contract event 0x5132e5b598a417dfc5c7488e5360aef3e865fe4b238cd5ea2a8282e0ca8d10ef. +// +// Solidity: event GuardiansUpdated(uint32 version, address[] guardians) +func (_GuardianProver *GuardianProverFilterer) WatchGuardiansUpdated(opts *bind.WatchOpts, sink chan<- *GuardianProverGuardiansUpdated) (event.Subscription, error) { + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "GuardiansUpdated") + 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(GuardianProverGuardiansUpdated) + if err := _GuardianProver.contract.UnpackLog(event, "GuardiansUpdated", 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 +} + +// ParseGuardiansUpdated is a log parse operation binding the contract event 0x5132e5b598a417dfc5c7488e5360aef3e865fe4b238cd5ea2a8282e0ca8d10ef. +// +// Solidity: event GuardiansUpdated(uint32 version, address[] guardians) +func (_GuardianProver *GuardianProverFilterer) ParseGuardiansUpdated(log types.Log) (*GuardianProverGuardiansUpdated, error) { + event := new(GuardianProverGuardiansUpdated) + if err := _GuardianProver.contract.UnpackLog(event, "GuardiansUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the GuardianProver contract. +type GuardianProverInitializedIterator struct { + Event *GuardianProverInitialized // 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 *GuardianProverInitializedIterator) 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(GuardianProverInitialized) + 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(GuardianProverInitialized) + 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 *GuardianProverInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverInitialized represents a Initialized event raised by the GuardianProver contract. +type GuardianProverInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianProver *GuardianProverFilterer) FilterInitialized(opts *bind.FilterOpts) (*GuardianProverInitializedIterator, error) { + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &GuardianProverInitializedIterator{contract: _GuardianProver.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianProver *GuardianProverFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *GuardianProverInitialized) (event.Subscription, error) { + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "Initialized") + 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(GuardianProverInitialized) + if err := _GuardianProver.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianProver *GuardianProverFilterer) ParseInitialized(log types.Log) (*GuardianProverInitialized, error) { + event := new(GuardianProverInitialized) + if err := _GuardianProver.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the GuardianProver contract. +type GuardianProverOwnershipTransferStartedIterator struct { + Event *GuardianProverOwnershipTransferStarted // 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 *GuardianProverOwnershipTransferStartedIterator) 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(GuardianProverOwnershipTransferStarted) + 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(GuardianProverOwnershipTransferStarted) + 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 *GuardianProverOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the GuardianProver contract. +type GuardianProverOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*GuardianProverOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &GuardianProverOwnershipTransferStartedIterator{contract: _GuardianProver.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *GuardianProverOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(GuardianProverOwnershipTransferStarted) + if err := _GuardianProver.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) ParseOwnershipTransferStarted(log types.Log) (*GuardianProverOwnershipTransferStarted, error) { + event := new(GuardianProverOwnershipTransferStarted) + if err := _GuardianProver.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the GuardianProver contract. +type GuardianProverOwnershipTransferredIterator struct { + Event *GuardianProverOwnershipTransferred // 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 *GuardianProverOwnershipTransferredIterator) 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(GuardianProverOwnershipTransferred) + 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(GuardianProverOwnershipTransferred) + 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 *GuardianProverOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverOwnershipTransferred represents a OwnershipTransferred event raised by the GuardianProver contract. +type GuardianProverOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*GuardianProverOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &GuardianProverOwnershipTransferredIterator{contract: _GuardianProver.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *GuardianProverOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(GuardianProverOwnershipTransferred) + if err := _GuardianProver.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianProver *GuardianProverFilterer) ParseOwnershipTransferred(log types.Log) (*GuardianProverOwnershipTransferred, error) { + event := new(GuardianProverOwnershipTransferred) + if err := _GuardianProver.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the GuardianProver contract. +type GuardianProverPausedIterator struct { + Event *GuardianProverPaused // 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 *GuardianProverPausedIterator) 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(GuardianProverPaused) + 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(GuardianProverPaused) + 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 *GuardianProverPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverPaused represents a Paused event raised by the GuardianProver contract. +type GuardianProverPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianProver *GuardianProverFilterer) FilterPaused(opts *bind.FilterOpts) (*GuardianProverPausedIterator, error) { + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &GuardianProverPausedIterator{contract: _GuardianProver.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianProver *GuardianProverFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *GuardianProverPaused) (event.Subscription, error) { + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "Paused") + 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(GuardianProverPaused) + if err := _GuardianProver.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianProver *GuardianProverFilterer) ParsePaused(log types.Log) (*GuardianProverPaused, error) { + event := new(GuardianProverPaused) + if err := _GuardianProver.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the GuardianProver contract. +type GuardianProverUnpausedIterator struct { + Event *GuardianProverUnpaused // 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 *GuardianProverUnpausedIterator) 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(GuardianProverUnpaused) + 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(GuardianProverUnpaused) + 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 *GuardianProverUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverUnpaused represents a Unpaused event raised by the GuardianProver contract. +type GuardianProverUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianProver *GuardianProverFilterer) FilterUnpaused(opts *bind.FilterOpts) (*GuardianProverUnpausedIterator, error) { + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &GuardianProverUnpausedIterator{contract: _GuardianProver.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianProver *GuardianProverFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *GuardianProverUnpaused) (event.Subscription, error) { + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "Unpaused") + 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(GuardianProverUnpaused) + if err := _GuardianProver.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianProver *GuardianProverFilterer) ParseUnpaused(log types.Log) (*GuardianProverUnpaused, error) { + event := new(GuardianProverUnpaused) + if err := _GuardianProver.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianProverUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the GuardianProver contract. +type GuardianProverUpgradedIterator struct { + Event *GuardianProverUpgraded // 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 *GuardianProverUpgradedIterator) 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(GuardianProverUpgraded) + 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(GuardianProverUpgraded) + 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 *GuardianProverUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianProverUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianProverUpgraded represents a Upgraded event raised by the GuardianProver contract. +type GuardianProverUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianProver *GuardianProverFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*GuardianProverUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _GuardianProver.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &GuardianProverUpgradedIterator{contract: _GuardianProver.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianProver *GuardianProverFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *GuardianProverUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _GuardianProver.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(GuardianProverUpgraded) + if err := _GuardianProver.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianProver *GuardianProverFilterer) ParseUpgraded(log types.Log) (*GuardianProverUpgraded, error) { + event := new(GuardianProverUpgraded) + if err := _GuardianProver.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_guardian_verifier.go b/packages/taiko-client/bindings/gen_guardian_verifier.go new file mode 100644 index 00000000000..77946e304ea --- /dev/null +++ b/packages/taiko-client/bindings/gen_guardian_verifier.go @@ -0,0 +1,1757 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// GuardianVerifierMetaData contains all meta data concerning the GuardianVerifier contract. +var GuardianVerifierMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifyProof\",\"inputs\":[{\"name\":\"_ctx\",\"type\":\"tuple\",\"internalType\":\"structIVerifier.Context\",\"components\":[{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"prover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"isContesting\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"msgSender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_proof\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TierProof\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"GV_INVALID_PROOF\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GV_PERMISSION_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// GuardianVerifierABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardianVerifierMetaData.ABI instead. +var GuardianVerifierABI = GuardianVerifierMetaData.ABI + +// GuardianVerifier is an auto generated Go binding around an Ethereum contract. +type GuardianVerifier struct { + GuardianVerifierCaller // Read-only binding to the contract + GuardianVerifierTransactor // Write-only binding to the contract + GuardianVerifierFilterer // Log filterer for contract events +} + +// GuardianVerifierCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardianVerifierCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianVerifierTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardianVerifierTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianVerifierFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardianVerifierFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardianVerifierSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardianVerifierSession struct { + Contract *GuardianVerifier // 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 +} + +// GuardianVerifierCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GuardianVerifierCallerSession struct { + Contract *GuardianVerifierCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// GuardianVerifierTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GuardianVerifierTransactorSession struct { + Contract *GuardianVerifierTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GuardianVerifierRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardianVerifierRaw struct { + Contract *GuardianVerifier // Generic contract binding to access the raw methods on +} + +// GuardianVerifierCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardianVerifierCallerRaw struct { + Contract *GuardianVerifierCaller // Generic read-only contract binding to access the raw methods on +} + +// GuardianVerifierTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardianVerifierTransactorRaw struct { + Contract *GuardianVerifierTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewGuardianVerifier creates a new instance of GuardianVerifier, bound to a specific deployed contract. +func NewGuardianVerifier(address common.Address, backend bind.ContractBackend) (*GuardianVerifier, error) { + contract, err := bindGuardianVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &GuardianVerifier{GuardianVerifierCaller: GuardianVerifierCaller{contract: contract}, GuardianVerifierTransactor: GuardianVerifierTransactor{contract: contract}, GuardianVerifierFilterer: GuardianVerifierFilterer{contract: contract}}, nil +} + +// NewGuardianVerifierCaller creates a new read-only instance of GuardianVerifier, bound to a specific deployed contract. +func NewGuardianVerifierCaller(address common.Address, caller bind.ContractCaller) (*GuardianVerifierCaller, error) { + contract, err := bindGuardianVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GuardianVerifierCaller{contract: contract}, nil +} + +// NewGuardianVerifierTransactor creates a new write-only instance of GuardianVerifier, bound to a specific deployed contract. +func NewGuardianVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardianVerifierTransactor, error) { + contract, err := bindGuardianVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GuardianVerifierTransactor{contract: contract}, nil +} + +// NewGuardianVerifierFilterer creates a new log filterer instance of GuardianVerifier, bound to a specific deployed contract. +func NewGuardianVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardianVerifierFilterer, error) { + contract, err := bindGuardianVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &GuardianVerifierFilterer{contract: contract}, nil +} + +// bindGuardianVerifier binds a generic wrapper to an already deployed contract. +func bindGuardianVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := GuardianVerifierMetaData.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 (_GuardianVerifier *GuardianVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardianVerifier.Contract.GuardianVerifierCaller.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 (_GuardianVerifier *GuardianVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.Contract.GuardianVerifierTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GuardianVerifier *GuardianVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardianVerifier.Contract.GuardianVerifierTransactor.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 (_GuardianVerifier *GuardianVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardianVerifier.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 (_GuardianVerifier *GuardianVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GuardianVerifier *GuardianVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardianVerifier.Contract.contract.Transact(opts, method, params...) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianVerifier *GuardianVerifierCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianVerifier *GuardianVerifierSession) AddressManager() (common.Address, error) { + return _GuardianVerifier.Contract.AddressManager(&_GuardianVerifier.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_GuardianVerifier *GuardianVerifierCallerSession) AddressManager() (common.Address, error) { + return _GuardianVerifier.Contract.AddressManager(&_GuardianVerifier.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianVerifier *GuardianVerifierCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianVerifier *GuardianVerifierSession) LastUnpausedAt() (uint64, error) { + return _GuardianVerifier.Contract.LastUnpausedAt(&_GuardianVerifier.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_GuardianVerifier *GuardianVerifierCallerSession) LastUnpausedAt() (uint64, error) { + return _GuardianVerifier.Contract.LastUnpausedAt(&_GuardianVerifier.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianVerifier *GuardianVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianVerifier *GuardianVerifierSession) Owner() (common.Address, error) { + return _GuardianVerifier.Contract.Owner(&_GuardianVerifier.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_GuardianVerifier *GuardianVerifierCallerSession) Owner() (common.Address, error) { + return _GuardianVerifier.Contract.Owner(&_GuardianVerifier.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianVerifier *GuardianVerifierCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianVerifier *GuardianVerifierSession) Paused() (bool, error) { + return _GuardianVerifier.Contract.Paused(&_GuardianVerifier.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_GuardianVerifier *GuardianVerifierCallerSession) Paused() (bool, error) { + return _GuardianVerifier.Contract.Paused(&_GuardianVerifier.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianVerifier *GuardianVerifierCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianVerifier *GuardianVerifierSession) PendingOwner() (common.Address, error) { + return _GuardianVerifier.Contract.PendingOwner(&_GuardianVerifier.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_GuardianVerifier *GuardianVerifierCallerSession) PendingOwner() (common.Address, error) { + return _GuardianVerifier.Contract.PendingOwner(&_GuardianVerifier.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianVerifier *GuardianVerifierCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianVerifier *GuardianVerifierSession) ProxiableUUID() ([32]byte, error) { + return _GuardianVerifier.Contract.ProxiableUUID(&_GuardianVerifier.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_GuardianVerifier *GuardianVerifierCallerSession) ProxiableUUID() ([32]byte, error) { + return _GuardianVerifier.Contract.ProxiableUUID(&_GuardianVerifier.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianVerifier.Contract.Resolve(&_GuardianVerifier.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianVerifier.Contract.Resolve(&_GuardianVerifier.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianVerifier.Contract.Resolve0(&_GuardianVerifier.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_GuardianVerifier *GuardianVerifierCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _GuardianVerifier.Contract.Resolve0(&_GuardianVerifier.CallOpts, _name, _allowZeroAddress) +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) _proof) view returns() +func (_GuardianVerifier *GuardianVerifierCaller) VerifyProof(opts *bind.CallOpts, _ctx IVerifierContext, arg1 TaikoDataTransition, _proof TaikoDataTierProof) error { + var out []interface{} + err := _GuardianVerifier.contract.Call(opts, &out, "verifyProof", _ctx, arg1, _proof) + + if err != nil { + return err + } + + return err + +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) _proof) view returns() +func (_GuardianVerifier *GuardianVerifierSession) VerifyProof(_ctx IVerifierContext, arg1 TaikoDataTransition, _proof TaikoDataTierProof) error { + return _GuardianVerifier.Contract.VerifyProof(&_GuardianVerifier.CallOpts, _ctx, arg1, _proof) +} + +// VerifyProof is a free data retrieval call binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) , (uint16,bytes) _proof) view returns() +func (_GuardianVerifier *GuardianVerifierCallerSession) VerifyProof(_ctx IVerifierContext, arg1 TaikoDataTransition, _proof TaikoDataTierProof) error { + return _GuardianVerifier.Contract.VerifyProof(&_GuardianVerifier.CallOpts, _ctx, arg1, _proof) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianVerifier *GuardianVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianVerifier *GuardianVerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _GuardianVerifier.Contract.AcceptOwnership(&_GuardianVerifier.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _GuardianVerifier.Contract.AcceptOwnership(&_GuardianVerifier.TransactOpts) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianVerifier *GuardianVerifierTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "init", _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianVerifier *GuardianVerifierSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.Init(&_GuardianVerifier.TransactOpts, _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.Init(&_GuardianVerifier.TransactOpts, _owner, _addressManager) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianVerifier *GuardianVerifierTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianVerifier *GuardianVerifierSession) Pause() (*types.Transaction, error) { + return _GuardianVerifier.Contract.Pause(&_GuardianVerifier.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) Pause() (*types.Transaction, error) { + return _GuardianVerifier.Contract.Pause(&_GuardianVerifier.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianVerifier *GuardianVerifierTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianVerifier *GuardianVerifierSession) RenounceOwnership() (*types.Transaction, error) { + return _GuardianVerifier.Contract.RenounceOwnership(&_GuardianVerifier.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _GuardianVerifier.Contract.RenounceOwnership(&_GuardianVerifier.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianVerifier *GuardianVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianVerifier *GuardianVerifierSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.TransferOwnership(&_GuardianVerifier.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.TransferOwnership(&_GuardianVerifier.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianVerifier *GuardianVerifierTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianVerifier *GuardianVerifierSession) Unpause() (*types.Transaction, error) { + return _GuardianVerifier.Contract.Unpause(&_GuardianVerifier.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) Unpause() (*types.Transaction, error) { + return _GuardianVerifier.Contract.Unpause(&_GuardianVerifier.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianVerifier *GuardianVerifierTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianVerifier *GuardianVerifierSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.UpgradeTo(&_GuardianVerifier.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _GuardianVerifier.Contract.UpgradeTo(&_GuardianVerifier.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianVerifier *GuardianVerifierTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianVerifier.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianVerifier *GuardianVerifierSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianVerifier.Contract.UpgradeToAndCall(&_GuardianVerifier.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_GuardianVerifier *GuardianVerifierTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _GuardianVerifier.Contract.UpgradeToAndCall(&_GuardianVerifier.TransactOpts, newImplementation, data) +} + +// GuardianVerifierAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the GuardianVerifier contract. +type GuardianVerifierAdminChangedIterator struct { + Event *GuardianVerifierAdminChanged // 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 *GuardianVerifierAdminChangedIterator) 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(GuardianVerifierAdminChanged) + 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(GuardianVerifierAdminChanged) + 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 *GuardianVerifierAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierAdminChanged represents a AdminChanged event raised by the GuardianVerifier contract. +type GuardianVerifierAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*GuardianVerifierAdminChangedIterator, error) { + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &GuardianVerifierAdminChangedIterator{contract: _GuardianVerifier.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *GuardianVerifierAdminChanged) (event.Subscription, error) { + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "AdminChanged") + 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(GuardianVerifierAdminChanged) + if err := _GuardianVerifier.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseAdminChanged(log types.Log) (*GuardianVerifierAdminChanged, error) { + event := new(GuardianVerifierAdminChanged) + if err := _GuardianVerifier.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the GuardianVerifier contract. +type GuardianVerifierBeaconUpgradedIterator struct { + Event *GuardianVerifierBeaconUpgraded // 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 *GuardianVerifierBeaconUpgradedIterator) 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(GuardianVerifierBeaconUpgraded) + 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(GuardianVerifierBeaconUpgraded) + 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 *GuardianVerifierBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierBeaconUpgraded represents a BeaconUpgraded event raised by the GuardianVerifier contract. +type GuardianVerifierBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*GuardianVerifierBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &GuardianVerifierBeaconUpgradedIterator{contract: _GuardianVerifier.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *GuardianVerifierBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(GuardianVerifierBeaconUpgraded) + if err := _GuardianVerifier.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseBeaconUpgraded(log types.Log) (*GuardianVerifierBeaconUpgraded, error) { + event := new(GuardianVerifierBeaconUpgraded) + if err := _GuardianVerifier.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the GuardianVerifier contract. +type GuardianVerifierInitializedIterator struct { + Event *GuardianVerifierInitialized // 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 *GuardianVerifierInitializedIterator) 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(GuardianVerifierInitialized) + 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(GuardianVerifierInitialized) + 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 *GuardianVerifierInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierInitialized represents a Initialized event raised by the GuardianVerifier contract. +type GuardianVerifierInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterInitialized(opts *bind.FilterOpts) (*GuardianVerifierInitializedIterator, error) { + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &GuardianVerifierInitializedIterator{contract: _GuardianVerifier.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *GuardianVerifierInitialized) (event.Subscription, error) { + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "Initialized") + 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(GuardianVerifierInitialized) + if err := _GuardianVerifier.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseInitialized(log types.Log) (*GuardianVerifierInitialized, error) { + event := new(GuardianVerifierInitialized) + if err := _GuardianVerifier.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the GuardianVerifier contract. +type GuardianVerifierOwnershipTransferStartedIterator struct { + Event *GuardianVerifierOwnershipTransferStarted // 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 *GuardianVerifierOwnershipTransferStartedIterator) 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(GuardianVerifierOwnershipTransferStarted) + 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(GuardianVerifierOwnershipTransferStarted) + 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 *GuardianVerifierOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the GuardianVerifier contract. +type GuardianVerifierOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*GuardianVerifierOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &GuardianVerifierOwnershipTransferStartedIterator{contract: _GuardianVerifier.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *GuardianVerifierOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(GuardianVerifierOwnershipTransferStarted) + if err := _GuardianVerifier.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseOwnershipTransferStarted(log types.Log) (*GuardianVerifierOwnershipTransferStarted, error) { + event := new(GuardianVerifierOwnershipTransferStarted) + if err := _GuardianVerifier.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the GuardianVerifier contract. +type GuardianVerifierOwnershipTransferredIterator struct { + Event *GuardianVerifierOwnershipTransferred // 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 *GuardianVerifierOwnershipTransferredIterator) 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(GuardianVerifierOwnershipTransferred) + 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(GuardianVerifierOwnershipTransferred) + 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 *GuardianVerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierOwnershipTransferred represents a OwnershipTransferred event raised by the GuardianVerifier contract. +type GuardianVerifierOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*GuardianVerifierOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &GuardianVerifierOwnershipTransferredIterator{contract: _GuardianVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *GuardianVerifierOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(GuardianVerifierOwnershipTransferred) + if err := _GuardianVerifier.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*GuardianVerifierOwnershipTransferred, error) { + event := new(GuardianVerifierOwnershipTransferred) + if err := _GuardianVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the GuardianVerifier contract. +type GuardianVerifierPausedIterator struct { + Event *GuardianVerifierPaused // 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 *GuardianVerifierPausedIterator) 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(GuardianVerifierPaused) + 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(GuardianVerifierPaused) + 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 *GuardianVerifierPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierPaused represents a Paused event raised by the GuardianVerifier contract. +type GuardianVerifierPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterPaused(opts *bind.FilterOpts) (*GuardianVerifierPausedIterator, error) { + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &GuardianVerifierPausedIterator{contract: _GuardianVerifier.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *GuardianVerifierPaused) (event.Subscription, error) { + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "Paused") + 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(GuardianVerifierPaused) + if err := _GuardianVerifier.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) ParsePaused(log types.Log) (*GuardianVerifierPaused, error) { + event := new(GuardianVerifierPaused) + if err := _GuardianVerifier.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the GuardianVerifier contract. +type GuardianVerifierUnpausedIterator struct { + Event *GuardianVerifierUnpaused // 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 *GuardianVerifierUnpausedIterator) 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(GuardianVerifierUnpaused) + 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(GuardianVerifierUnpaused) + 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 *GuardianVerifierUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierUnpaused represents a Unpaused event raised by the GuardianVerifier contract. +type GuardianVerifierUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterUnpaused(opts *bind.FilterOpts) (*GuardianVerifierUnpausedIterator, error) { + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &GuardianVerifierUnpausedIterator{contract: _GuardianVerifier.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *GuardianVerifierUnpaused) (event.Subscription, error) { + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "Unpaused") + 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(GuardianVerifierUnpaused) + if err := _GuardianVerifier.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseUnpaused(log types.Log) (*GuardianVerifierUnpaused, error) { + event := new(GuardianVerifierUnpaused) + if err := _GuardianVerifier.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardianVerifierUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the GuardianVerifier contract. +type GuardianVerifierUpgradedIterator struct { + Event *GuardianVerifierUpgraded // 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 *GuardianVerifierUpgradedIterator) 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(GuardianVerifierUpgraded) + 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(GuardianVerifierUpgraded) + 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 *GuardianVerifierUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardianVerifierUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GuardianVerifierUpgraded represents a Upgraded event raised by the GuardianVerifier contract. +type GuardianVerifierUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianVerifier *GuardianVerifierFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*GuardianVerifierUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _GuardianVerifier.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &GuardianVerifierUpgradedIterator{contract: _GuardianVerifier.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianVerifier *GuardianVerifierFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *GuardianVerifierUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _GuardianVerifier.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(GuardianVerifierUpgraded) + if err := _GuardianVerifier.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_GuardianVerifier *GuardianVerifierFilterer) ParseUpgraded(log types.Log) (*GuardianVerifierUpgraded, error) { + event := new(GuardianVerifierUpgraded) + if err := _GuardianVerifier.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_lib_proposing.go b/packages/taiko-client/bindings/gen_lib_proposing.go new file mode 100644 index 00000000000..3e35789ee88 --- /dev/null +++ b/packages/taiko-client/bindings/gen_lib_proposing.go @@ -0,0 +1,337 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// LibProposingMetaData contains all meta data concerning the LibProposing contract. +var LibProposingMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"event\",\"name\":\"BlockProposed\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"assignedProver\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"meta\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"depositsProcessed\",\"type\":\"tuple[]\",\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_AVAILABLE\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_HOOK\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PROVER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_SIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_LIVENESS_BOND_NOT_RECEIVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TOO_MANY_BLOCKS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNAUTHORIZED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_PARENT\",\"inputs\":[]}]", +} + +// LibProposingABI is the input ABI used to generate the binding from. +// Deprecated: Use LibProposingMetaData.ABI instead. +var LibProposingABI = LibProposingMetaData.ABI + +// LibProposing is an auto generated Go binding around an Ethereum contract. +type LibProposing struct { + LibProposingCaller // Read-only binding to the contract + LibProposingTransactor // Write-only binding to the contract + LibProposingFilterer // Log filterer for contract events +} + +// LibProposingCaller is an auto generated read-only Go binding around an Ethereum contract. +type LibProposingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProposingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type LibProposingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProposingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type LibProposingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProposingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type LibProposingSession struct { + Contract *LibProposing // 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 +} + +// LibProposingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type LibProposingCallerSession struct { + Contract *LibProposingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// LibProposingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type LibProposingTransactorSession struct { + Contract *LibProposingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// LibProposingRaw is an auto generated low-level Go binding around an Ethereum contract. +type LibProposingRaw struct { + Contract *LibProposing // Generic contract binding to access the raw methods on +} + +// LibProposingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type LibProposingCallerRaw struct { + Contract *LibProposingCaller // Generic read-only contract binding to access the raw methods on +} + +// LibProposingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type LibProposingTransactorRaw struct { + Contract *LibProposingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewLibProposing creates a new instance of LibProposing, bound to a specific deployed contract. +func NewLibProposing(address common.Address, backend bind.ContractBackend) (*LibProposing, error) { + contract, err := bindLibProposing(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LibProposing{LibProposingCaller: LibProposingCaller{contract: contract}, LibProposingTransactor: LibProposingTransactor{contract: contract}, LibProposingFilterer: LibProposingFilterer{contract: contract}}, nil +} + +// NewLibProposingCaller creates a new read-only instance of LibProposing, bound to a specific deployed contract. +func NewLibProposingCaller(address common.Address, caller bind.ContractCaller) (*LibProposingCaller, error) { + contract, err := bindLibProposing(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LibProposingCaller{contract: contract}, nil +} + +// NewLibProposingTransactor creates a new write-only instance of LibProposing, bound to a specific deployed contract. +func NewLibProposingTransactor(address common.Address, transactor bind.ContractTransactor) (*LibProposingTransactor, error) { + contract, err := bindLibProposing(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LibProposingTransactor{contract: contract}, nil +} + +// NewLibProposingFilterer creates a new log filterer instance of LibProposing, bound to a specific deployed contract. +func NewLibProposingFilterer(address common.Address, filterer bind.ContractFilterer) (*LibProposingFilterer, error) { + contract, err := bindLibProposing(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LibProposingFilterer{contract: contract}, nil +} + +// bindLibProposing binds a generic wrapper to an already deployed contract. +func bindLibProposing(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LibProposingMetaData.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 (_LibProposing *LibProposingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibProposing.Contract.LibProposingCaller.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 (_LibProposing *LibProposingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibProposing.Contract.LibProposingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibProposing *LibProposingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibProposing.Contract.LibProposingTransactor.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 (_LibProposing *LibProposingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibProposing.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 (_LibProposing *LibProposingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibProposing.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibProposing *LibProposingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibProposing.Contract.contract.Transact(opts, method, params...) +} + +// LibProposingBlockProposedIterator is returned from FilterBlockProposed and is used to iterate over the raw logs and unpacked data for BlockProposed events raised by the LibProposing contract. +type LibProposingBlockProposedIterator struct { + Event *LibProposingBlockProposed // 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 *LibProposingBlockProposedIterator) 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(LibProposingBlockProposed) + 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(LibProposingBlockProposed) + 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 *LibProposingBlockProposedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibProposingBlockProposedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibProposingBlockProposed represents a BlockProposed event raised by the LibProposing contract. +type LibProposingBlockProposed struct { + BlockId *big.Int + AssignedProver common.Address + LivenessBond *big.Int + Meta TaikoDataBlockMetadata + DepositsProcessed []TaikoDataEthDeposit + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockProposed is a free log retrieval operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_LibProposing *LibProposingFilterer) FilterBlockProposed(opts *bind.FilterOpts, blockId []*big.Int, assignedProver []common.Address) (*LibProposingBlockProposedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _LibProposing.contract.FilterLogs(opts, "BlockProposed", blockIdRule, assignedProverRule) + if err != nil { + return nil, err + } + return &LibProposingBlockProposedIterator{contract: _LibProposing.contract, event: "BlockProposed", logs: logs, sub: sub}, nil +} + +// WatchBlockProposed is a free log subscription operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_LibProposing *LibProposingFilterer) WatchBlockProposed(opts *bind.WatchOpts, sink chan<- *LibProposingBlockProposed, blockId []*big.Int, assignedProver []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _LibProposing.contract.WatchLogs(opts, "BlockProposed", blockIdRule, assignedProverRule) + 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(LibProposingBlockProposed) + if err := _LibProposing.contract.UnpackLog(event, "BlockProposed", 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 +} + +// ParseBlockProposed is a log parse operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_LibProposing *LibProposingFilterer) ParseBlockProposed(log types.Log) (*LibProposingBlockProposed, error) { + event := new(LibProposingBlockProposed) + if err := _LibProposing.contract.UnpackLog(event, "BlockProposed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_lib_proving.go b/packages/taiko-client/bindings/gen_lib_proving.go new file mode 100644 index 00000000000..a95a8249d99 --- /dev/null +++ b/packages/taiko-client/bindings/gen_lib_proving.go @@ -0,0 +1,611 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// LibProvingMetaData contains all meta data concerning the LibProving contract. +var LibProvingMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"event\",\"name\":\"ProvingPaused\",\"inputs\":[{\"name\":\"paused\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionContested\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"contester\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionProved\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"L1_ALREADY_CONTESTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_ALREADY_PROVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_CANNOT_CONTEST\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_BLOCK_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TIER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TRANSITION\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_NOT_ASSIGNED_PROVER\",\"inputs\":[]}]", +} + +// LibProvingABI is the input ABI used to generate the binding from. +// Deprecated: Use LibProvingMetaData.ABI instead. +var LibProvingABI = LibProvingMetaData.ABI + +// LibProving is an auto generated Go binding around an Ethereum contract. +type LibProving struct { + LibProvingCaller // Read-only binding to the contract + LibProvingTransactor // Write-only binding to the contract + LibProvingFilterer // Log filterer for contract events +} + +// LibProvingCaller is an auto generated read-only Go binding around an Ethereum contract. +type LibProvingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProvingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type LibProvingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProvingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type LibProvingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibProvingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type LibProvingSession struct { + Contract *LibProving // 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 +} + +// LibProvingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type LibProvingCallerSession struct { + Contract *LibProvingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// LibProvingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type LibProvingTransactorSession struct { + Contract *LibProvingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// LibProvingRaw is an auto generated low-level Go binding around an Ethereum contract. +type LibProvingRaw struct { + Contract *LibProving // Generic contract binding to access the raw methods on +} + +// LibProvingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type LibProvingCallerRaw struct { + Contract *LibProvingCaller // Generic read-only contract binding to access the raw methods on +} + +// LibProvingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type LibProvingTransactorRaw struct { + Contract *LibProvingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewLibProving creates a new instance of LibProving, bound to a specific deployed contract. +func NewLibProving(address common.Address, backend bind.ContractBackend) (*LibProving, error) { + contract, err := bindLibProving(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LibProving{LibProvingCaller: LibProvingCaller{contract: contract}, LibProvingTransactor: LibProvingTransactor{contract: contract}, LibProvingFilterer: LibProvingFilterer{contract: contract}}, nil +} + +// NewLibProvingCaller creates a new read-only instance of LibProving, bound to a specific deployed contract. +func NewLibProvingCaller(address common.Address, caller bind.ContractCaller) (*LibProvingCaller, error) { + contract, err := bindLibProving(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LibProvingCaller{contract: contract}, nil +} + +// NewLibProvingTransactor creates a new write-only instance of LibProving, bound to a specific deployed contract. +func NewLibProvingTransactor(address common.Address, transactor bind.ContractTransactor) (*LibProvingTransactor, error) { + contract, err := bindLibProving(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LibProvingTransactor{contract: contract}, nil +} + +// NewLibProvingFilterer creates a new log filterer instance of LibProving, bound to a specific deployed contract. +func NewLibProvingFilterer(address common.Address, filterer bind.ContractFilterer) (*LibProvingFilterer, error) { + contract, err := bindLibProving(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LibProvingFilterer{contract: contract}, nil +} + +// bindLibProving binds a generic wrapper to an already deployed contract. +func bindLibProving(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LibProvingMetaData.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 (_LibProving *LibProvingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibProving.Contract.LibProvingCaller.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 (_LibProving *LibProvingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibProving.Contract.LibProvingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibProving *LibProvingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibProving.Contract.LibProvingTransactor.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 (_LibProving *LibProvingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibProving.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 (_LibProving *LibProvingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibProving.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibProving *LibProvingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibProving.Contract.contract.Transact(opts, method, params...) +} + +// LibProvingProvingPausedIterator is returned from FilterProvingPaused and is used to iterate over the raw logs and unpacked data for ProvingPaused events raised by the LibProving contract. +type LibProvingProvingPausedIterator struct { + Event *LibProvingProvingPaused // 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 *LibProvingProvingPausedIterator) 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(LibProvingProvingPaused) + 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(LibProvingProvingPaused) + 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 *LibProvingProvingPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibProvingProvingPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibProvingProvingPaused represents a ProvingPaused event raised by the LibProving contract. +type LibProvingProvingPaused struct { + Paused bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterProvingPaused is a free log retrieval operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_LibProving *LibProvingFilterer) FilterProvingPaused(opts *bind.FilterOpts) (*LibProvingProvingPausedIterator, error) { + + logs, sub, err := _LibProving.contract.FilterLogs(opts, "ProvingPaused") + if err != nil { + return nil, err + } + return &LibProvingProvingPausedIterator{contract: _LibProving.contract, event: "ProvingPaused", logs: logs, sub: sub}, nil +} + +// WatchProvingPaused is a free log subscription operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_LibProving *LibProvingFilterer) WatchProvingPaused(opts *bind.WatchOpts, sink chan<- *LibProvingProvingPaused) (event.Subscription, error) { + + logs, sub, err := _LibProving.contract.WatchLogs(opts, "ProvingPaused") + 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(LibProvingProvingPaused) + if err := _LibProving.contract.UnpackLog(event, "ProvingPaused", 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 +} + +// ParseProvingPaused is a log parse operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_LibProving *LibProvingFilterer) ParseProvingPaused(log types.Log) (*LibProvingProvingPaused, error) { + event := new(LibProvingProvingPaused) + if err := _LibProving.contract.UnpackLog(event, "ProvingPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LibProvingTransitionContestedIterator is returned from FilterTransitionContested and is used to iterate over the raw logs and unpacked data for TransitionContested events raised by the LibProving contract. +type LibProvingTransitionContestedIterator struct { + Event *LibProvingTransitionContested // 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 *LibProvingTransitionContestedIterator) 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(LibProvingTransitionContested) + 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(LibProvingTransitionContested) + 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 *LibProvingTransitionContestedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibProvingTransitionContestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibProvingTransitionContested represents a TransitionContested event raised by the LibProving contract. +type LibProvingTransitionContested struct { + BlockId *big.Int + Tran TaikoDataTransition + Contester common.Address + ContestBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionContested is a free log retrieval operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_LibProving *LibProvingFilterer) FilterTransitionContested(opts *bind.FilterOpts, blockId []*big.Int) (*LibProvingTransitionContestedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _LibProving.contract.FilterLogs(opts, "TransitionContested", blockIdRule) + if err != nil { + return nil, err + } + return &LibProvingTransitionContestedIterator{contract: _LibProving.contract, event: "TransitionContested", logs: logs, sub: sub}, nil +} + +// WatchTransitionContested is a free log subscription operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_LibProving *LibProvingFilterer) WatchTransitionContested(opts *bind.WatchOpts, sink chan<- *LibProvingTransitionContested, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _LibProving.contract.WatchLogs(opts, "TransitionContested", blockIdRule) + 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(LibProvingTransitionContested) + if err := _LibProving.contract.UnpackLog(event, "TransitionContested", 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 +} + +// ParseTransitionContested is a log parse operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_LibProving *LibProvingFilterer) ParseTransitionContested(log types.Log) (*LibProvingTransitionContested, error) { + event := new(LibProvingTransitionContested) + if err := _LibProving.contract.UnpackLog(event, "TransitionContested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LibProvingTransitionProvedIterator is returned from FilterTransitionProved and is used to iterate over the raw logs and unpacked data for TransitionProved events raised by the LibProving contract. +type LibProvingTransitionProvedIterator struct { + Event *LibProvingTransitionProved // 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 *LibProvingTransitionProvedIterator) 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(LibProvingTransitionProved) + 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(LibProvingTransitionProved) + 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 *LibProvingTransitionProvedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibProvingTransitionProvedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibProvingTransitionProved represents a TransitionProved event raised by the LibProving contract. +type LibProvingTransitionProved struct { + BlockId *big.Int + Tran TaikoDataTransition + Prover common.Address + ValidityBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionProved is a free log retrieval operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_LibProving *LibProvingFilterer) FilterTransitionProved(opts *bind.FilterOpts, blockId []*big.Int) (*LibProvingTransitionProvedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _LibProving.contract.FilterLogs(opts, "TransitionProved", blockIdRule) + if err != nil { + return nil, err + } + return &LibProvingTransitionProvedIterator{contract: _LibProving.contract, event: "TransitionProved", logs: logs, sub: sub}, nil +} + +// WatchTransitionProved is a free log subscription operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_LibProving *LibProvingFilterer) WatchTransitionProved(opts *bind.WatchOpts, sink chan<- *LibProvingTransitionProved, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _LibProving.contract.WatchLogs(opts, "TransitionProved", blockIdRule) + 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(LibProvingTransitionProved) + if err := _LibProving.contract.UnpackLog(event, "TransitionProved", 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 +} + +// ParseTransitionProved is a log parse operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_LibProving *LibProvingFilterer) ParseTransitionProved(log types.Log) (*LibProvingTransitionProved, error) { + event := new(LibProvingTransitionProved) + if err := _LibProving.contract.UnpackLog(event, "TransitionProved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_lib_utils.go b/packages/taiko-client/bindings/gen_lib_utils.go new file mode 100644 index 00000000000..09043e7ebba --- /dev/null +++ b/packages/taiko-client/bindings/gen_lib_utils.go @@ -0,0 +1,181 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// LibUtilsMetaData contains all meta data concerning the LibUtils contract. +var LibUtilsMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_BLOCK_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"inputs\":[]}]", +} + +// LibUtilsABI is the input ABI used to generate the binding from. +// Deprecated: Use LibUtilsMetaData.ABI instead. +var LibUtilsABI = LibUtilsMetaData.ABI + +// LibUtils is an auto generated Go binding around an Ethereum contract. +type LibUtils struct { + LibUtilsCaller // Read-only binding to the contract + LibUtilsTransactor // Write-only binding to the contract + LibUtilsFilterer // Log filterer for contract events +} + +// LibUtilsCaller is an auto generated read-only Go binding around an Ethereum contract. +type LibUtilsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibUtilsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type LibUtilsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibUtilsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type LibUtilsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibUtilsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type LibUtilsSession struct { + Contract *LibUtils // 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 +} + +// LibUtilsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type LibUtilsCallerSession struct { + Contract *LibUtilsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// LibUtilsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type LibUtilsTransactorSession struct { + Contract *LibUtilsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// LibUtilsRaw is an auto generated low-level Go binding around an Ethereum contract. +type LibUtilsRaw struct { + Contract *LibUtils // Generic contract binding to access the raw methods on +} + +// LibUtilsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type LibUtilsCallerRaw struct { + Contract *LibUtilsCaller // Generic read-only contract binding to access the raw methods on +} + +// LibUtilsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type LibUtilsTransactorRaw struct { + Contract *LibUtilsTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewLibUtils creates a new instance of LibUtils, bound to a specific deployed contract. +func NewLibUtils(address common.Address, backend bind.ContractBackend) (*LibUtils, error) { + contract, err := bindLibUtils(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LibUtils{LibUtilsCaller: LibUtilsCaller{contract: contract}, LibUtilsTransactor: LibUtilsTransactor{contract: contract}, LibUtilsFilterer: LibUtilsFilterer{contract: contract}}, nil +} + +// NewLibUtilsCaller creates a new read-only instance of LibUtils, bound to a specific deployed contract. +func NewLibUtilsCaller(address common.Address, caller bind.ContractCaller) (*LibUtilsCaller, error) { + contract, err := bindLibUtils(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LibUtilsCaller{contract: contract}, nil +} + +// NewLibUtilsTransactor creates a new write-only instance of LibUtils, bound to a specific deployed contract. +func NewLibUtilsTransactor(address common.Address, transactor bind.ContractTransactor) (*LibUtilsTransactor, error) { + contract, err := bindLibUtils(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LibUtilsTransactor{contract: contract}, nil +} + +// NewLibUtilsFilterer creates a new log filterer instance of LibUtils, bound to a specific deployed contract. +func NewLibUtilsFilterer(address common.Address, filterer bind.ContractFilterer) (*LibUtilsFilterer, error) { + contract, err := bindLibUtils(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LibUtilsFilterer{contract: contract}, nil +} + +// bindLibUtils binds a generic wrapper to an already deployed contract. +func bindLibUtils(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LibUtilsMetaData.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 (_LibUtils *LibUtilsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibUtils.Contract.LibUtilsCaller.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 (_LibUtils *LibUtilsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibUtils.Contract.LibUtilsTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibUtils *LibUtilsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibUtils.Contract.LibUtilsTransactor.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 (_LibUtils *LibUtilsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibUtils.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 (_LibUtils *LibUtilsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibUtils.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibUtils *LibUtilsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibUtils.Contract.contract.Transact(opts, method, params...) +} diff --git a/packages/taiko-client/bindings/gen_lib_verifying.go b/packages/taiko-client/bindings/gen_lib_verifying.go new file mode 100644 index 00000000000..b69d8478c0e --- /dev/null +++ b/packages/taiko-client/bindings/gen_lib_verifying.go @@ -0,0 +1,471 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// LibVerifyingMetaData contains all meta data concerning the LibVerifying contract. +var LibVerifyingMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"event\",\"name\":\"BlockVerified\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StateVariablesUpdated\",\"inputs\":[{\"name\":\"slotB\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_CONFIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_GENESIS_HASH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_ID_ZERO\",\"inputs\":[]}]", +} + +// LibVerifyingABI is the input ABI used to generate the binding from. +// Deprecated: Use LibVerifyingMetaData.ABI instead. +var LibVerifyingABI = LibVerifyingMetaData.ABI + +// LibVerifying is an auto generated Go binding around an Ethereum contract. +type LibVerifying struct { + LibVerifyingCaller // Read-only binding to the contract + LibVerifyingTransactor // Write-only binding to the contract + LibVerifyingFilterer // Log filterer for contract events +} + +// LibVerifyingCaller is an auto generated read-only Go binding around an Ethereum contract. +type LibVerifyingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibVerifyingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type LibVerifyingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibVerifyingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type LibVerifyingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LibVerifyingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type LibVerifyingSession struct { + Contract *LibVerifying // 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 +} + +// LibVerifyingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type LibVerifyingCallerSession struct { + Contract *LibVerifyingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// LibVerifyingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type LibVerifyingTransactorSession struct { + Contract *LibVerifyingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// LibVerifyingRaw is an auto generated low-level Go binding around an Ethereum contract. +type LibVerifyingRaw struct { + Contract *LibVerifying // Generic contract binding to access the raw methods on +} + +// LibVerifyingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type LibVerifyingCallerRaw struct { + Contract *LibVerifyingCaller // Generic read-only contract binding to access the raw methods on +} + +// LibVerifyingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type LibVerifyingTransactorRaw struct { + Contract *LibVerifyingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewLibVerifying creates a new instance of LibVerifying, bound to a specific deployed contract. +func NewLibVerifying(address common.Address, backend bind.ContractBackend) (*LibVerifying, error) { + contract, err := bindLibVerifying(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LibVerifying{LibVerifyingCaller: LibVerifyingCaller{contract: contract}, LibVerifyingTransactor: LibVerifyingTransactor{contract: contract}, LibVerifyingFilterer: LibVerifyingFilterer{contract: contract}}, nil +} + +// NewLibVerifyingCaller creates a new read-only instance of LibVerifying, bound to a specific deployed contract. +func NewLibVerifyingCaller(address common.Address, caller bind.ContractCaller) (*LibVerifyingCaller, error) { + contract, err := bindLibVerifying(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LibVerifyingCaller{contract: contract}, nil +} + +// NewLibVerifyingTransactor creates a new write-only instance of LibVerifying, bound to a specific deployed contract. +func NewLibVerifyingTransactor(address common.Address, transactor bind.ContractTransactor) (*LibVerifyingTransactor, error) { + contract, err := bindLibVerifying(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LibVerifyingTransactor{contract: contract}, nil +} + +// NewLibVerifyingFilterer creates a new log filterer instance of LibVerifying, bound to a specific deployed contract. +func NewLibVerifyingFilterer(address common.Address, filterer bind.ContractFilterer) (*LibVerifyingFilterer, error) { + contract, err := bindLibVerifying(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LibVerifyingFilterer{contract: contract}, nil +} + +// bindLibVerifying binds a generic wrapper to an already deployed contract. +func bindLibVerifying(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LibVerifyingMetaData.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 (_LibVerifying *LibVerifyingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibVerifying.Contract.LibVerifyingCaller.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 (_LibVerifying *LibVerifyingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibVerifying.Contract.LibVerifyingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibVerifying *LibVerifyingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibVerifying.Contract.LibVerifyingTransactor.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 (_LibVerifying *LibVerifyingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LibVerifying.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 (_LibVerifying *LibVerifyingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LibVerifying.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_LibVerifying *LibVerifyingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LibVerifying.Contract.contract.Transact(opts, method, params...) +} + +// LibVerifyingBlockVerifiedIterator is returned from FilterBlockVerified and is used to iterate over the raw logs and unpacked data for BlockVerified events raised by the LibVerifying contract. +type LibVerifyingBlockVerifiedIterator struct { + Event *LibVerifyingBlockVerified // 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 *LibVerifyingBlockVerifiedIterator) 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(LibVerifyingBlockVerified) + 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(LibVerifyingBlockVerified) + 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 *LibVerifyingBlockVerifiedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibVerifyingBlockVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibVerifyingBlockVerified represents a BlockVerified event raised by the LibVerifying contract. +type LibVerifyingBlockVerified struct { + BlockId *big.Int + Prover common.Address + BlockHash [32]byte + StateRoot [32]byte + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockVerified is a free log retrieval operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_LibVerifying *LibVerifyingFilterer) FilterBlockVerified(opts *bind.FilterOpts, blockId []*big.Int, prover []common.Address) (*LibVerifyingBlockVerifiedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _LibVerifying.contract.FilterLogs(opts, "BlockVerified", blockIdRule, proverRule) + if err != nil { + return nil, err + } + return &LibVerifyingBlockVerifiedIterator{contract: _LibVerifying.contract, event: "BlockVerified", logs: logs, sub: sub}, nil +} + +// WatchBlockVerified is a free log subscription operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_LibVerifying *LibVerifyingFilterer) WatchBlockVerified(opts *bind.WatchOpts, sink chan<- *LibVerifyingBlockVerified, blockId []*big.Int, prover []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _LibVerifying.contract.WatchLogs(opts, "BlockVerified", blockIdRule, proverRule) + 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(LibVerifyingBlockVerified) + if err := _LibVerifying.contract.UnpackLog(event, "BlockVerified", 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 +} + +// ParseBlockVerified is a log parse operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_LibVerifying *LibVerifyingFilterer) ParseBlockVerified(log types.Log) (*LibVerifyingBlockVerified, error) { + event := new(LibVerifyingBlockVerified) + if err := _LibVerifying.contract.UnpackLog(event, "BlockVerified", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LibVerifyingStateVariablesUpdatedIterator is returned from FilterStateVariablesUpdated and is used to iterate over the raw logs and unpacked data for StateVariablesUpdated events raised by the LibVerifying contract. +type LibVerifyingStateVariablesUpdatedIterator struct { + Event *LibVerifyingStateVariablesUpdated // 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 *LibVerifyingStateVariablesUpdatedIterator) 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(LibVerifyingStateVariablesUpdated) + 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(LibVerifyingStateVariablesUpdated) + 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 *LibVerifyingStateVariablesUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LibVerifyingStateVariablesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LibVerifyingStateVariablesUpdated represents a StateVariablesUpdated event raised by the LibVerifying contract. +type LibVerifyingStateVariablesUpdated struct { + SlotB TaikoDataSlotB + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStateVariablesUpdated is a free log retrieval operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_LibVerifying *LibVerifyingFilterer) FilterStateVariablesUpdated(opts *bind.FilterOpts) (*LibVerifyingStateVariablesUpdatedIterator, error) { + + logs, sub, err := _LibVerifying.contract.FilterLogs(opts, "StateVariablesUpdated") + if err != nil { + return nil, err + } + return &LibVerifyingStateVariablesUpdatedIterator{contract: _LibVerifying.contract, event: "StateVariablesUpdated", logs: logs, sub: sub}, nil +} + +// WatchStateVariablesUpdated is a free log subscription operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_LibVerifying *LibVerifyingFilterer) WatchStateVariablesUpdated(opts *bind.WatchOpts, sink chan<- *LibVerifyingStateVariablesUpdated) (event.Subscription, error) { + + logs, sub, err := _LibVerifying.contract.WatchLogs(opts, "StateVariablesUpdated") + 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(LibVerifyingStateVariablesUpdated) + if err := _LibVerifying.contract.UnpackLog(event, "StateVariablesUpdated", 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 +} + +// ParseStateVariablesUpdated is a log parse operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_LibVerifying *LibVerifyingFilterer) ParseStateVariablesUpdated(log types.Log) (*LibVerifyingStateVariablesUpdated, error) { + event := new(LibVerifyingStateVariablesUpdated) + if err := _LibVerifying.contract.UnpackLog(event, "StateVariablesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_sgx_verifier.go b/packages/taiko-client/bindings/gen_sgx_verifier.go new file mode 100644 index 00000000000..504b8c9c143 --- /dev/null +++ b/packages/taiko-client/bindings/gen_sgx_verifier.go @@ -0,0 +1,2346 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// V3StructCertificationData is an auto generated low-level Go binding around an user-defined struct. +type V3StructCertificationData struct { + CertType uint16 + CertDataSize uint32 + DecodedCertDataArray [3][]byte +} + +// V3StructECDSAQuoteV3AuthData is an auto generated low-level Go binding around an user-defined struct. +type V3StructECDSAQuoteV3AuthData struct { + Ecdsa256BitSignature []byte + EcdsaAttestationKey []byte + PckSignedQeReport V3StructEnclaveReport + QeReportSignature []byte + QeAuthData V3StructQEAuthData + Certification V3StructCertificationData +} + +// V3StructEnclaveReport is an auto generated low-level Go binding around an user-defined struct. +type V3StructEnclaveReport struct { + CpuSvn [16]byte + MiscSelect [4]byte + Reserved1 [28]byte + Attributes [16]byte + MrEnclave [32]byte + Reserved2 [32]byte + MrSigner [32]byte + Reserved3 []byte + IsvProdId uint16 + IsvSvn uint16 + Reserved4 []byte + ReportData []byte +} + +// V3StructHeader is an auto generated low-level Go binding around an user-defined struct. +type V3StructHeader struct { + Version [2]byte + AttestationKeyType [2]byte + TeeType [4]byte + QeSvn [2]byte + PceSvn [2]byte + QeVendorId [16]byte + UserData [20]byte +} + +// V3StructParsedV3QuoteStruct is an auto generated low-level Go binding around an user-defined struct. +type V3StructParsedV3QuoteStruct struct { + Header V3StructHeader + LocalEnclaveReport V3StructEnclaveReport + V3AuthData V3StructECDSAQuoteV3AuthData +} + +// V3StructQEAuthData is an auto generated low-level Go binding around an user-defined struct. +type V3StructQEAuthData struct { + ParsedDataSize uint16 + Data []byte +} + +// SgxVerifierMetaData contains all meta data concerning the SgxVerifier contract. +var SgxVerifierMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"INSTANCE_EXPIRY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"INSTANCE_VALIDITY_DELAY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addInstances\",\"inputs\":[{\"name\":\"_instances\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addressRegistered\",\"inputs\":[{\"name\":\"instanceAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"alreadyAttested\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deleteInstances\",\"inputs\":[{\"name\":\"_ids\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"instances\",\"inputs\":[{\"name\":\"instanceId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"validSince\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextInstanceId\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerInstance\",\"inputs\":[{\"name\":\"_attestation\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.ParsedV3QuoteStruct\",\"components\":[{\"name\":\"header\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.Header\",\"components\":[{\"name\":\"version\",\"type\":\"bytes2\",\"internalType\":\"bytes2\"},{\"name\":\"attestationKeyType\",\"type\":\"bytes2\",\"internalType\":\"bytes2\"},{\"name\":\"teeType\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"qeSvn\",\"type\":\"bytes2\",\"internalType\":\"bytes2\"},{\"name\":\"pceSvn\",\"type\":\"bytes2\",\"internalType\":\"bytes2\"},{\"name\":\"qeVendorId\",\"type\":\"bytes16\",\"internalType\":\"bytes16\"},{\"name\":\"userData\",\"type\":\"bytes20\",\"internalType\":\"bytes20\"}]},{\"name\":\"localEnclaveReport\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.EnclaveReport\",\"components\":[{\"name\":\"cpuSvn\",\"type\":\"bytes16\",\"internalType\":\"bytes16\"},{\"name\":\"miscSelect\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"reserved1\",\"type\":\"bytes28\",\"internalType\":\"bytes28\"},{\"name\":\"attributes\",\"type\":\"bytes16\",\"internalType\":\"bytes16\"},{\"name\":\"mrEnclave\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"reserved2\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"mrSigner\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"reserved3\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"isvProdId\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"isvSvn\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"reserved4\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"reportData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"v3AuthData\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.ECDSAQuoteV3AuthData\",\"components\":[{\"name\":\"ecdsa256BitSignature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"ecdsaAttestationKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"pckSignedQeReport\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.EnclaveReport\",\"components\":[{\"name\":\"cpuSvn\",\"type\":\"bytes16\",\"internalType\":\"bytes16\"},{\"name\":\"miscSelect\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"reserved1\",\"type\":\"bytes28\",\"internalType\":\"bytes28\"},{\"name\":\"attributes\",\"type\":\"bytes16\",\"internalType\":\"bytes16\"},{\"name\":\"mrEnclave\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"reserved2\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"mrSigner\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"reserved3\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"isvProdId\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"isvSvn\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"reserved4\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"reportData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"qeReportSignature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"qeAuthData\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.QEAuthData\",\"components\":[{\"name\":\"parsedDataSize\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"certification\",\"type\":\"tuple\",\"internalType\":\"structV3Struct.CertificationData\",\"components\":[{\"name\":\"certType\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"certDataSize\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"decodedCertDataArray\",\"type\":\"bytes[3]\",\"internalType\":\"bytes[3]\"}]}]}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifyProof\",\"inputs\":[{\"name\":\"_ctx\",\"type\":\"tuple\",\"internalType\":\"structIVerifier.Context\",\"components\":[{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"prover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"isContesting\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"msgSender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"_tran\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_proof\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TierProof\",\"components\":[{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InstanceAdded\",\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"instance\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"replaced\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"validSince\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InstanceDeleted\",\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"instance\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"SGX_ALREADY_ATTESTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SGX_INVALID_ATTESTATION\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SGX_INVALID_INSTANCE\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SGX_INVALID_PROOF\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SGX_RA_NOT_SUPPORTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// SgxVerifierABI is the input ABI used to generate the binding from. +// Deprecated: Use SgxVerifierMetaData.ABI instead. +var SgxVerifierABI = SgxVerifierMetaData.ABI + +// SgxVerifier is an auto generated Go binding around an Ethereum contract. +type SgxVerifier struct { + SgxVerifierCaller // Read-only binding to the contract + SgxVerifierTransactor // Write-only binding to the contract + SgxVerifierFilterer // Log filterer for contract events +} + +// SgxVerifierCaller is an auto generated read-only Go binding around an Ethereum contract. +type SgxVerifierCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SgxVerifierTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SgxVerifierTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SgxVerifierFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SgxVerifierFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SgxVerifierSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SgxVerifierSession struct { + Contract *SgxVerifier // 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 +} + +// SgxVerifierCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SgxVerifierCallerSession struct { + Contract *SgxVerifierCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SgxVerifierTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SgxVerifierTransactorSession struct { + Contract *SgxVerifierTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SgxVerifierRaw is an auto generated low-level Go binding around an Ethereum contract. +type SgxVerifierRaw struct { + Contract *SgxVerifier // Generic contract binding to access the raw methods on +} + +// SgxVerifierCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SgxVerifierCallerRaw struct { + Contract *SgxVerifierCaller // Generic read-only contract binding to access the raw methods on +} + +// SgxVerifierTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SgxVerifierTransactorRaw struct { + Contract *SgxVerifierTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSgxVerifier creates a new instance of SgxVerifier, bound to a specific deployed contract. +func NewSgxVerifier(address common.Address, backend bind.ContractBackend) (*SgxVerifier, error) { + contract, err := bindSgxVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SgxVerifier{SgxVerifierCaller: SgxVerifierCaller{contract: contract}, SgxVerifierTransactor: SgxVerifierTransactor{contract: contract}, SgxVerifierFilterer: SgxVerifierFilterer{contract: contract}}, nil +} + +// NewSgxVerifierCaller creates a new read-only instance of SgxVerifier, bound to a specific deployed contract. +func NewSgxVerifierCaller(address common.Address, caller bind.ContractCaller) (*SgxVerifierCaller, error) { + contract, err := bindSgxVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SgxVerifierCaller{contract: contract}, nil +} + +// NewSgxVerifierTransactor creates a new write-only instance of SgxVerifier, bound to a specific deployed contract. +func NewSgxVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*SgxVerifierTransactor, error) { + contract, err := bindSgxVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SgxVerifierTransactor{contract: contract}, nil +} + +// NewSgxVerifierFilterer creates a new log filterer instance of SgxVerifier, bound to a specific deployed contract. +func NewSgxVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*SgxVerifierFilterer, error) { + contract, err := bindSgxVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SgxVerifierFilterer{contract: contract}, nil +} + +// bindSgxVerifier binds a generic wrapper to an already deployed contract. +func bindSgxVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := SgxVerifierMetaData.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 (_SgxVerifier *SgxVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SgxVerifier.Contract.SgxVerifierCaller.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 (_SgxVerifier *SgxVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.Contract.SgxVerifierTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SgxVerifier *SgxVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SgxVerifier.Contract.SgxVerifierTransactor.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 (_SgxVerifier *SgxVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SgxVerifier.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 (_SgxVerifier *SgxVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SgxVerifier *SgxVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SgxVerifier.Contract.contract.Transact(opts, method, params...) +} + +// INSTANCEEXPIRY is a free data retrieval call binding the contract method 0xd632cf35. +// +// Solidity: function INSTANCE_EXPIRY() view returns(uint64) +func (_SgxVerifier *SgxVerifierCaller) INSTANCEEXPIRY(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "INSTANCE_EXPIRY") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// INSTANCEEXPIRY is a free data retrieval call binding the contract method 0xd632cf35. +// +// Solidity: function INSTANCE_EXPIRY() view returns(uint64) +func (_SgxVerifier *SgxVerifierSession) INSTANCEEXPIRY() (uint64, error) { + return _SgxVerifier.Contract.INSTANCEEXPIRY(&_SgxVerifier.CallOpts) +} + +// INSTANCEEXPIRY is a free data retrieval call binding the contract method 0xd632cf35. +// +// Solidity: function INSTANCE_EXPIRY() view returns(uint64) +func (_SgxVerifier *SgxVerifierCallerSession) INSTANCEEXPIRY() (uint64, error) { + return _SgxVerifier.Contract.INSTANCEEXPIRY(&_SgxVerifier.CallOpts) +} + +// INSTANCEVALIDITYDELAY is a free data retrieval call binding the contract method 0xb51ec328. +// +// Solidity: function INSTANCE_VALIDITY_DELAY() view returns(uint64) +func (_SgxVerifier *SgxVerifierCaller) INSTANCEVALIDITYDELAY(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "INSTANCE_VALIDITY_DELAY") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// INSTANCEVALIDITYDELAY is a free data retrieval call binding the contract method 0xb51ec328. +// +// Solidity: function INSTANCE_VALIDITY_DELAY() view returns(uint64) +func (_SgxVerifier *SgxVerifierSession) INSTANCEVALIDITYDELAY() (uint64, error) { + return _SgxVerifier.Contract.INSTANCEVALIDITYDELAY(&_SgxVerifier.CallOpts) +} + +// INSTANCEVALIDITYDELAY is a free data retrieval call binding the contract method 0xb51ec328. +// +// Solidity: function INSTANCE_VALIDITY_DELAY() view returns(uint64) +func (_SgxVerifier *SgxVerifierCallerSession) INSTANCEVALIDITYDELAY() (uint64, error) { + return _SgxVerifier.Contract.INSTANCEVALIDITYDELAY(&_SgxVerifier.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_SgxVerifier *SgxVerifierCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_SgxVerifier *SgxVerifierSession) AddressManager() (common.Address, error) { + return _SgxVerifier.Contract.AddressManager(&_SgxVerifier.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_SgxVerifier *SgxVerifierCallerSession) AddressManager() (common.Address, error) { + return _SgxVerifier.Contract.AddressManager(&_SgxVerifier.CallOpts) +} + +// AddressRegistered is a free data retrieval call binding the contract method 0x9d7809b5. +// +// Solidity: function addressRegistered(address instanceAddress) view returns(bool alreadyAttested) +func (_SgxVerifier *SgxVerifierCaller) AddressRegistered(opts *bind.CallOpts, instanceAddress common.Address) (bool, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "addressRegistered", instanceAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// AddressRegistered is a free data retrieval call binding the contract method 0x9d7809b5. +// +// Solidity: function addressRegistered(address instanceAddress) view returns(bool alreadyAttested) +func (_SgxVerifier *SgxVerifierSession) AddressRegistered(instanceAddress common.Address) (bool, error) { + return _SgxVerifier.Contract.AddressRegistered(&_SgxVerifier.CallOpts, instanceAddress) +} + +// AddressRegistered is a free data retrieval call binding the contract method 0x9d7809b5. +// +// Solidity: function addressRegistered(address instanceAddress) view returns(bool alreadyAttested) +func (_SgxVerifier *SgxVerifierCallerSession) AddressRegistered(instanceAddress common.Address) (bool, error) { + return _SgxVerifier.Contract.AddressRegistered(&_SgxVerifier.CallOpts, instanceAddress) +} + +// Instances is a free data retrieval call binding the contract method 0xa2f7b3a5. +// +// Solidity: function instances(uint256 instanceId) view returns(address addr, uint64 validSince) +func (_SgxVerifier *SgxVerifierCaller) Instances(opts *bind.CallOpts, instanceId *big.Int) (struct { + Addr common.Address + ValidSince uint64 +}, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "instances", instanceId) + + outstruct := new(struct { + Addr common.Address + ValidSince uint64 + }) + if err != nil { + return *outstruct, err + } + + outstruct.Addr = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.ValidSince = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +// Instances is a free data retrieval call binding the contract method 0xa2f7b3a5. +// +// Solidity: function instances(uint256 instanceId) view returns(address addr, uint64 validSince) +func (_SgxVerifier *SgxVerifierSession) Instances(instanceId *big.Int) (struct { + Addr common.Address + ValidSince uint64 +}, error) { + return _SgxVerifier.Contract.Instances(&_SgxVerifier.CallOpts, instanceId) +} + +// Instances is a free data retrieval call binding the contract method 0xa2f7b3a5. +// +// Solidity: function instances(uint256 instanceId) view returns(address addr, uint64 validSince) +func (_SgxVerifier *SgxVerifierCallerSession) Instances(instanceId *big.Int) (struct { + Addr common.Address + ValidSince uint64 +}, error) { + return _SgxVerifier.Contract.Instances(&_SgxVerifier.CallOpts, instanceId) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_SgxVerifier *SgxVerifierCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_SgxVerifier *SgxVerifierSession) LastUnpausedAt() (uint64, error) { + return _SgxVerifier.Contract.LastUnpausedAt(&_SgxVerifier.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_SgxVerifier *SgxVerifierCallerSession) LastUnpausedAt() (uint64, error) { + return _SgxVerifier.Contract.LastUnpausedAt(&_SgxVerifier.CallOpts) +} + +// NextInstanceId is a free data retrieval call binding the contract method 0xee45abb0. +// +// Solidity: function nextInstanceId() view returns(uint256) +func (_SgxVerifier *SgxVerifierCaller) NextInstanceId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "nextInstanceId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NextInstanceId is a free data retrieval call binding the contract method 0xee45abb0. +// +// Solidity: function nextInstanceId() view returns(uint256) +func (_SgxVerifier *SgxVerifierSession) NextInstanceId() (*big.Int, error) { + return _SgxVerifier.Contract.NextInstanceId(&_SgxVerifier.CallOpts) +} + +// NextInstanceId is a free data retrieval call binding the contract method 0xee45abb0. +// +// Solidity: function nextInstanceId() view returns(uint256) +func (_SgxVerifier *SgxVerifierCallerSession) NextInstanceId() (*big.Int, error) { + return _SgxVerifier.Contract.NextInstanceId(&_SgxVerifier.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SgxVerifier *SgxVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SgxVerifier *SgxVerifierSession) Owner() (common.Address, error) { + return _SgxVerifier.Contract.Owner(&_SgxVerifier.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SgxVerifier *SgxVerifierCallerSession) Owner() (common.Address, error) { + return _SgxVerifier.Contract.Owner(&_SgxVerifier.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_SgxVerifier *SgxVerifierCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_SgxVerifier *SgxVerifierSession) Paused() (bool, error) { + return _SgxVerifier.Contract.Paused(&_SgxVerifier.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_SgxVerifier *SgxVerifierCallerSession) Paused() (bool, error) { + return _SgxVerifier.Contract.Paused(&_SgxVerifier.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_SgxVerifier *SgxVerifierCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_SgxVerifier *SgxVerifierSession) PendingOwner() (common.Address, error) { + return _SgxVerifier.Contract.PendingOwner(&_SgxVerifier.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_SgxVerifier *SgxVerifierCallerSession) PendingOwner() (common.Address, error) { + return _SgxVerifier.Contract.PendingOwner(&_SgxVerifier.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_SgxVerifier *SgxVerifierCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_SgxVerifier *SgxVerifierSession) ProxiableUUID() ([32]byte, error) { + return _SgxVerifier.Contract.ProxiableUUID(&_SgxVerifier.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_SgxVerifier *SgxVerifierCallerSession) ProxiableUUID() ([32]byte, error) { + return _SgxVerifier.Contract.ProxiableUUID(&_SgxVerifier.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _SgxVerifier.Contract.Resolve(&_SgxVerifier.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _SgxVerifier.Contract.Resolve(&_SgxVerifier.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _SgxVerifier.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _SgxVerifier.Contract.Resolve0(&_SgxVerifier.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_SgxVerifier *SgxVerifierCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _SgxVerifier.Contract.Resolve0(&_SgxVerifier.CallOpts, _name, _allowZeroAddress) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_SgxVerifier *SgxVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_SgxVerifier *SgxVerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _SgxVerifier.Contract.AcceptOwnership(&_SgxVerifier.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_SgxVerifier *SgxVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _SgxVerifier.Contract.AcceptOwnership(&_SgxVerifier.TransactOpts) +} + +// AddInstances is a paid mutator transaction binding the contract method 0x16107290. +// +// Solidity: function addInstances(address[] _instances) returns(uint256[]) +func (_SgxVerifier *SgxVerifierTransactor) AddInstances(opts *bind.TransactOpts, _instances []common.Address) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "addInstances", _instances) +} + +// AddInstances is a paid mutator transaction binding the contract method 0x16107290. +// +// Solidity: function addInstances(address[] _instances) returns(uint256[]) +func (_SgxVerifier *SgxVerifierSession) AddInstances(_instances []common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.AddInstances(&_SgxVerifier.TransactOpts, _instances) +} + +// AddInstances is a paid mutator transaction binding the contract method 0x16107290. +// +// Solidity: function addInstances(address[] _instances) returns(uint256[]) +func (_SgxVerifier *SgxVerifierTransactorSession) AddInstances(_instances []common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.AddInstances(&_SgxVerifier.TransactOpts, _instances) +} + +// DeleteInstances is a paid mutator transaction binding the contract method 0x4ef36a56. +// +// Solidity: function deleteInstances(uint256[] _ids) returns() +func (_SgxVerifier *SgxVerifierTransactor) DeleteInstances(opts *bind.TransactOpts, _ids []*big.Int) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "deleteInstances", _ids) +} + +// DeleteInstances is a paid mutator transaction binding the contract method 0x4ef36a56. +// +// Solidity: function deleteInstances(uint256[] _ids) returns() +func (_SgxVerifier *SgxVerifierSession) DeleteInstances(_ids []*big.Int) (*types.Transaction, error) { + return _SgxVerifier.Contract.DeleteInstances(&_SgxVerifier.TransactOpts, _ids) +} + +// DeleteInstances is a paid mutator transaction binding the contract method 0x4ef36a56. +// +// Solidity: function deleteInstances(uint256[] _ids) returns() +func (_SgxVerifier *SgxVerifierTransactorSession) DeleteInstances(_ids []*big.Int) (*types.Transaction, error) { + return _SgxVerifier.Contract.DeleteInstances(&_SgxVerifier.TransactOpts, _ids) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_SgxVerifier *SgxVerifierTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "init", _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_SgxVerifier *SgxVerifierSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.Init(&_SgxVerifier.TransactOpts, _owner, _addressManager) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(address _owner, address _addressManager) returns() +func (_SgxVerifier *SgxVerifierTransactorSession) Init(_owner common.Address, _addressManager common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.Init(&_SgxVerifier.TransactOpts, _owner, _addressManager) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_SgxVerifier *SgxVerifierTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_SgxVerifier *SgxVerifierSession) Pause() (*types.Transaction, error) { + return _SgxVerifier.Contract.Pause(&_SgxVerifier.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_SgxVerifier *SgxVerifierTransactorSession) Pause() (*types.Transaction, error) { + return _SgxVerifier.Contract.Pause(&_SgxVerifier.TransactOpts) +} + +// RegisterInstance is a paid mutator transaction binding the contract method 0xa91951a2. +// +// Solidity: function registerInstance(((bytes2,bytes2,bytes4,bytes2,bytes2,bytes16,bytes20),(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),(bytes,bytes,(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),bytes,(uint16,bytes),(uint16,uint32,bytes[3]))) _attestation) returns(uint256) +func (_SgxVerifier *SgxVerifierTransactor) RegisterInstance(opts *bind.TransactOpts, _attestation V3StructParsedV3QuoteStruct) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "registerInstance", _attestation) +} + +// RegisterInstance is a paid mutator transaction binding the contract method 0xa91951a2. +// +// Solidity: function registerInstance(((bytes2,bytes2,bytes4,bytes2,bytes2,bytes16,bytes20),(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),(bytes,bytes,(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),bytes,(uint16,bytes),(uint16,uint32,bytes[3]))) _attestation) returns(uint256) +func (_SgxVerifier *SgxVerifierSession) RegisterInstance(_attestation V3StructParsedV3QuoteStruct) (*types.Transaction, error) { + return _SgxVerifier.Contract.RegisterInstance(&_SgxVerifier.TransactOpts, _attestation) +} + +// RegisterInstance is a paid mutator transaction binding the contract method 0xa91951a2. +// +// Solidity: function registerInstance(((bytes2,bytes2,bytes4,bytes2,bytes2,bytes16,bytes20),(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),(bytes,bytes,(bytes16,bytes4,bytes28,bytes16,bytes32,bytes32,bytes32,bytes,uint16,uint16,bytes,bytes),bytes,(uint16,bytes),(uint16,uint32,bytes[3]))) _attestation) returns(uint256) +func (_SgxVerifier *SgxVerifierTransactorSession) RegisterInstance(_attestation V3StructParsedV3QuoteStruct) (*types.Transaction, error) { + return _SgxVerifier.Contract.RegisterInstance(&_SgxVerifier.TransactOpts, _attestation) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SgxVerifier *SgxVerifierTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SgxVerifier *SgxVerifierSession) RenounceOwnership() (*types.Transaction, error) { + return _SgxVerifier.Contract.RenounceOwnership(&_SgxVerifier.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SgxVerifier *SgxVerifierTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SgxVerifier.Contract.RenounceOwnership(&_SgxVerifier.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SgxVerifier *SgxVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SgxVerifier *SgxVerifierSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.TransferOwnership(&_SgxVerifier.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SgxVerifier *SgxVerifierTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.TransferOwnership(&_SgxVerifier.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SgxVerifier *SgxVerifierTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SgxVerifier *SgxVerifierSession) Unpause() (*types.Transaction, error) { + return _SgxVerifier.Contract.Unpause(&_SgxVerifier.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SgxVerifier *SgxVerifierTransactorSession) Unpause() (*types.Transaction, error) { + return _SgxVerifier.Contract.Unpause(&_SgxVerifier.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_SgxVerifier *SgxVerifierTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_SgxVerifier *SgxVerifierSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.UpgradeTo(&_SgxVerifier.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_SgxVerifier *SgxVerifierTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _SgxVerifier.Contract.UpgradeTo(&_SgxVerifier.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_SgxVerifier *SgxVerifierTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_SgxVerifier *SgxVerifierSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _SgxVerifier.Contract.UpgradeToAndCall(&_SgxVerifier.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_SgxVerifier *SgxVerifierTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _SgxVerifier.Contract.UpgradeToAndCall(&_SgxVerifier.TransactOpts, newImplementation, data) +} + +// VerifyProof is a paid mutator transaction binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns() +func (_SgxVerifier *SgxVerifierTransactor) VerifyProof(opts *bind.TransactOpts, _ctx IVerifierContext, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _SgxVerifier.contract.Transact(opts, "verifyProof", _ctx, _tran, _proof) +} + +// VerifyProof is a paid mutator transaction binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns() +func (_SgxVerifier *SgxVerifierSession) VerifyProof(_ctx IVerifierContext, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _SgxVerifier.Contract.VerifyProof(&_SgxVerifier.TransactOpts, _ctx, _tran, _proof) +} + +// VerifyProof is a paid mutator transaction binding the contract method 0x21e89968. +// +// Solidity: function verifyProof((bytes32,bytes32,address,uint64,bool,bool,address) _ctx, (bytes32,bytes32,bytes32,bytes32) _tran, (uint16,bytes) _proof) returns() +func (_SgxVerifier *SgxVerifierTransactorSession) VerifyProof(_ctx IVerifierContext, _tran TaikoDataTransition, _proof TaikoDataTierProof) (*types.Transaction, error) { + return _SgxVerifier.Contract.VerifyProof(&_SgxVerifier.TransactOpts, _ctx, _tran, _proof) +} + +// SgxVerifierAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the SgxVerifier contract. +type SgxVerifierAdminChangedIterator struct { + Event *SgxVerifierAdminChanged // 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 *SgxVerifierAdminChangedIterator) 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(SgxVerifierAdminChanged) + 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(SgxVerifierAdminChanged) + 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 *SgxVerifierAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierAdminChanged represents a AdminChanged event raised by the SgxVerifier contract. +type SgxVerifierAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_SgxVerifier *SgxVerifierFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*SgxVerifierAdminChangedIterator, error) { + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &SgxVerifierAdminChangedIterator{contract: _SgxVerifier.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_SgxVerifier *SgxVerifierFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *SgxVerifierAdminChanged) (event.Subscription, error) { + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "AdminChanged") + 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(SgxVerifierAdminChanged) + if err := _SgxVerifier.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_SgxVerifier *SgxVerifierFilterer) ParseAdminChanged(log types.Log) (*SgxVerifierAdminChanged, error) { + event := new(SgxVerifierAdminChanged) + if err := _SgxVerifier.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the SgxVerifier contract. +type SgxVerifierBeaconUpgradedIterator struct { + Event *SgxVerifierBeaconUpgraded // 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 *SgxVerifierBeaconUpgradedIterator) 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(SgxVerifierBeaconUpgraded) + 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(SgxVerifierBeaconUpgraded) + 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 *SgxVerifierBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierBeaconUpgraded represents a BeaconUpgraded event raised by the SgxVerifier contract. +type SgxVerifierBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_SgxVerifier *SgxVerifierFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*SgxVerifierBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &SgxVerifierBeaconUpgradedIterator{contract: _SgxVerifier.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_SgxVerifier *SgxVerifierFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *SgxVerifierBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(SgxVerifierBeaconUpgraded) + if err := _SgxVerifier.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_SgxVerifier *SgxVerifierFilterer) ParseBeaconUpgraded(log types.Log) (*SgxVerifierBeaconUpgraded, error) { + event := new(SgxVerifierBeaconUpgraded) + if err := _SgxVerifier.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SgxVerifier contract. +type SgxVerifierInitializedIterator struct { + Event *SgxVerifierInitialized // 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 *SgxVerifierInitializedIterator) 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(SgxVerifierInitialized) + 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(SgxVerifierInitialized) + 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 *SgxVerifierInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierInitialized represents a Initialized event raised by the SgxVerifier contract. +type SgxVerifierInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SgxVerifier *SgxVerifierFilterer) FilterInitialized(opts *bind.FilterOpts) (*SgxVerifierInitializedIterator, error) { + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &SgxVerifierInitializedIterator{contract: _SgxVerifier.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SgxVerifier *SgxVerifierFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SgxVerifierInitialized) (event.Subscription, error) { + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "Initialized") + 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(SgxVerifierInitialized) + if err := _SgxVerifier.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SgxVerifier *SgxVerifierFilterer) ParseInitialized(log types.Log) (*SgxVerifierInitialized, error) { + event := new(SgxVerifierInitialized) + if err := _SgxVerifier.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierInstanceAddedIterator is returned from FilterInstanceAdded and is used to iterate over the raw logs and unpacked data for InstanceAdded events raised by the SgxVerifier contract. +type SgxVerifierInstanceAddedIterator struct { + Event *SgxVerifierInstanceAdded // 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 *SgxVerifierInstanceAddedIterator) 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(SgxVerifierInstanceAdded) + 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(SgxVerifierInstanceAdded) + 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 *SgxVerifierInstanceAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierInstanceAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierInstanceAdded represents a InstanceAdded event raised by the SgxVerifier contract. +type SgxVerifierInstanceAdded struct { + Id *big.Int + Instance common.Address + Replaced common.Address + ValidSince *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInstanceAdded is a free log retrieval operation binding the contract event 0xbbe529d240965181270c1e2e32a80761e8807dda1ee9765e326178bd6804a9cb. +// +// Solidity: event InstanceAdded(uint256 indexed id, address indexed instance, address replaced, uint256 validSince) +func (_SgxVerifier *SgxVerifierFilterer) FilterInstanceAdded(opts *bind.FilterOpts, id []*big.Int, instance []common.Address) (*SgxVerifierInstanceAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var instanceRule []interface{} + for _, instanceItem := range instance { + instanceRule = append(instanceRule, instanceItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "InstanceAdded", idRule, instanceRule) + if err != nil { + return nil, err + } + return &SgxVerifierInstanceAddedIterator{contract: _SgxVerifier.contract, event: "InstanceAdded", logs: logs, sub: sub}, nil +} + +// WatchInstanceAdded is a free log subscription operation binding the contract event 0xbbe529d240965181270c1e2e32a80761e8807dda1ee9765e326178bd6804a9cb. +// +// Solidity: event InstanceAdded(uint256 indexed id, address indexed instance, address replaced, uint256 validSince) +func (_SgxVerifier *SgxVerifierFilterer) WatchInstanceAdded(opts *bind.WatchOpts, sink chan<- *SgxVerifierInstanceAdded, id []*big.Int, instance []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var instanceRule []interface{} + for _, instanceItem := range instance { + instanceRule = append(instanceRule, instanceItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "InstanceAdded", idRule, instanceRule) + 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(SgxVerifierInstanceAdded) + if err := _SgxVerifier.contract.UnpackLog(event, "InstanceAdded", 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 +} + +// ParseInstanceAdded is a log parse operation binding the contract event 0xbbe529d240965181270c1e2e32a80761e8807dda1ee9765e326178bd6804a9cb. +// +// Solidity: event InstanceAdded(uint256 indexed id, address indexed instance, address replaced, uint256 validSince) +func (_SgxVerifier *SgxVerifierFilterer) ParseInstanceAdded(log types.Log) (*SgxVerifierInstanceAdded, error) { + event := new(SgxVerifierInstanceAdded) + if err := _SgxVerifier.contract.UnpackLog(event, "InstanceAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierInstanceDeletedIterator is returned from FilterInstanceDeleted and is used to iterate over the raw logs and unpacked data for InstanceDeleted events raised by the SgxVerifier contract. +type SgxVerifierInstanceDeletedIterator struct { + Event *SgxVerifierInstanceDeleted // 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 *SgxVerifierInstanceDeletedIterator) 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(SgxVerifierInstanceDeleted) + 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(SgxVerifierInstanceDeleted) + 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 *SgxVerifierInstanceDeletedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierInstanceDeletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierInstanceDeleted represents a InstanceDeleted event raised by the SgxVerifier contract. +type SgxVerifierInstanceDeleted struct { + Id *big.Int + Instance common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInstanceDeleted is a free log retrieval operation binding the contract event 0x89d0dca869ffe08b709ca9ff5adfd5ee8d9de2750d0561e15df614c7a2596d8e. +// +// Solidity: event InstanceDeleted(uint256 indexed id, address indexed instance) +func (_SgxVerifier *SgxVerifierFilterer) FilterInstanceDeleted(opts *bind.FilterOpts, id []*big.Int, instance []common.Address) (*SgxVerifierInstanceDeletedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var instanceRule []interface{} + for _, instanceItem := range instance { + instanceRule = append(instanceRule, instanceItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "InstanceDeleted", idRule, instanceRule) + if err != nil { + return nil, err + } + return &SgxVerifierInstanceDeletedIterator{contract: _SgxVerifier.contract, event: "InstanceDeleted", logs: logs, sub: sub}, nil +} + +// WatchInstanceDeleted is a free log subscription operation binding the contract event 0x89d0dca869ffe08b709ca9ff5adfd5ee8d9de2750d0561e15df614c7a2596d8e. +// +// Solidity: event InstanceDeleted(uint256 indexed id, address indexed instance) +func (_SgxVerifier *SgxVerifierFilterer) WatchInstanceDeleted(opts *bind.WatchOpts, sink chan<- *SgxVerifierInstanceDeleted, id []*big.Int, instance []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var instanceRule []interface{} + for _, instanceItem := range instance { + instanceRule = append(instanceRule, instanceItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "InstanceDeleted", idRule, instanceRule) + 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(SgxVerifierInstanceDeleted) + if err := _SgxVerifier.contract.UnpackLog(event, "InstanceDeleted", 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 +} + +// ParseInstanceDeleted is a log parse operation binding the contract event 0x89d0dca869ffe08b709ca9ff5adfd5ee8d9de2750d0561e15df614c7a2596d8e. +// +// Solidity: event InstanceDeleted(uint256 indexed id, address indexed instance) +func (_SgxVerifier *SgxVerifierFilterer) ParseInstanceDeleted(log types.Log) (*SgxVerifierInstanceDeleted, error) { + event := new(SgxVerifierInstanceDeleted) + if err := _SgxVerifier.contract.UnpackLog(event, "InstanceDeleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the SgxVerifier contract. +type SgxVerifierOwnershipTransferStartedIterator struct { + Event *SgxVerifierOwnershipTransferStarted // 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 *SgxVerifierOwnershipTransferStartedIterator) 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(SgxVerifierOwnershipTransferStarted) + 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(SgxVerifierOwnershipTransferStarted) + 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 *SgxVerifierOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the SgxVerifier contract. +type SgxVerifierOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SgxVerifierOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SgxVerifierOwnershipTransferStartedIterator{contract: _SgxVerifier.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *SgxVerifierOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(SgxVerifierOwnershipTransferStarted) + if err := _SgxVerifier.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) ParseOwnershipTransferStarted(log types.Log) (*SgxVerifierOwnershipTransferStarted, error) { + event := new(SgxVerifierOwnershipTransferStarted) + if err := _SgxVerifier.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SgxVerifier contract. +type SgxVerifierOwnershipTransferredIterator struct { + Event *SgxVerifierOwnershipTransferred // 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 *SgxVerifierOwnershipTransferredIterator) 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(SgxVerifierOwnershipTransferred) + 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(SgxVerifierOwnershipTransferred) + 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 *SgxVerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierOwnershipTransferred represents a OwnershipTransferred event raised by the SgxVerifier contract. +type SgxVerifierOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SgxVerifierOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SgxVerifierOwnershipTransferredIterator{contract: _SgxVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SgxVerifierOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(SgxVerifierOwnershipTransferred) + if err := _SgxVerifier.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SgxVerifier *SgxVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*SgxVerifierOwnershipTransferred, error) { + event := new(SgxVerifierOwnershipTransferred) + if err := _SgxVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the SgxVerifier contract. +type SgxVerifierPausedIterator struct { + Event *SgxVerifierPaused // 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 *SgxVerifierPausedIterator) 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(SgxVerifierPaused) + 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(SgxVerifierPaused) + 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 *SgxVerifierPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierPaused represents a Paused event raised by the SgxVerifier contract. +type SgxVerifierPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_SgxVerifier *SgxVerifierFilterer) FilterPaused(opts *bind.FilterOpts) (*SgxVerifierPausedIterator, error) { + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &SgxVerifierPausedIterator{contract: _SgxVerifier.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_SgxVerifier *SgxVerifierFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *SgxVerifierPaused) (event.Subscription, error) { + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "Paused") + 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(SgxVerifierPaused) + if err := _SgxVerifier.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_SgxVerifier *SgxVerifierFilterer) ParsePaused(log types.Log) (*SgxVerifierPaused, error) { + event := new(SgxVerifierPaused) + if err := _SgxVerifier.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the SgxVerifier contract. +type SgxVerifierUnpausedIterator struct { + Event *SgxVerifierUnpaused // 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 *SgxVerifierUnpausedIterator) 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(SgxVerifierUnpaused) + 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(SgxVerifierUnpaused) + 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 *SgxVerifierUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierUnpaused represents a Unpaused event raised by the SgxVerifier contract. +type SgxVerifierUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_SgxVerifier *SgxVerifierFilterer) FilterUnpaused(opts *bind.FilterOpts) (*SgxVerifierUnpausedIterator, error) { + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &SgxVerifierUnpausedIterator{contract: _SgxVerifier.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_SgxVerifier *SgxVerifierFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *SgxVerifierUnpaused) (event.Subscription, error) { + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "Unpaused") + 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(SgxVerifierUnpaused) + if err := _SgxVerifier.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_SgxVerifier *SgxVerifierFilterer) ParseUnpaused(log types.Log) (*SgxVerifierUnpaused, error) { + event := new(SgxVerifierUnpaused) + if err := _SgxVerifier.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SgxVerifierUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the SgxVerifier contract. +type SgxVerifierUpgradedIterator struct { + Event *SgxVerifierUpgraded // 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 *SgxVerifierUpgradedIterator) 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(SgxVerifierUpgraded) + 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(SgxVerifierUpgraded) + 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 *SgxVerifierUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SgxVerifierUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SgxVerifierUpgraded represents a Upgraded event raised by the SgxVerifier contract. +type SgxVerifierUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_SgxVerifier *SgxVerifierFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*SgxVerifierUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _SgxVerifier.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &SgxVerifierUpgradedIterator{contract: _SgxVerifier.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_SgxVerifier *SgxVerifierFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *SgxVerifierUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _SgxVerifier.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(SgxVerifierUpgraded) + if err := _SgxVerifier.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_SgxVerifier *SgxVerifierFilterer) ParseUpgraded(log types.Log) (*SgxVerifierUpgraded, error) { + event := new(SgxVerifierUpgraded) + if err := _SgxVerifier.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_taiko_l1.go b/packages/taiko-client/bindings/gen_taiko_l1.go new file mode 100644 index 00000000000..4bf08c12b05 --- /dev/null +++ b/packages/taiko-client/bindings/gen_taiko_l1.go @@ -0,0 +1,4097 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// TaikoDataBlock is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataBlock struct { + MetaHash [32]byte + AssignedProver common.Address + LivenessBond *big.Int + BlockId uint64 + ProposedAt uint64 + ProposedIn uint64 + NextTransitionId uint32 + VerifiedTransitionId uint32 +} + +// TaikoDataBlockMetadata is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataBlockMetadata struct { + L1Hash [32]byte + Difficulty [32]byte + BlobHash [32]byte + ExtraData [32]byte + DepositsHash [32]byte + Coinbase common.Address + Id uint64 + GasLimit uint32 + Timestamp uint64 + L1Height uint64 + MinTier uint16 + BlobUsed bool + ParentMetaHash [32]byte + Sender common.Address +} + +// TaikoDataConfig is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataConfig struct { + ChainId uint64 + BlockMaxProposals uint64 + BlockRingBufferSize uint64 + MaxBlocksToVerifyPerProposal uint64 + BlockMaxGasLimit uint32 + LivenessBond *big.Int + BlockSyncThreshold uint8 +} + +// TaikoDataEthDeposit is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataEthDeposit struct { + Recipient common.Address + Amount *big.Int + Id uint64 +} + +// TaikoDataSlotA is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataSlotA struct { + GenesisHeight uint64 + GenesisTimestamp uint64 + LastSyncedBlockId uint64 + LastSynecdAt uint64 +} + +// TaikoDataSlotB is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataSlotB struct { + NumBlocks uint64 + LastVerifiedBlockId uint64 + ProvingPaused bool + ReservedB1 uint8 + ReservedB2 uint16 + ReservedB3 uint32 + LastUnpausedAt uint64 +} + +// TaikoDataTransition is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataTransition struct { + ParentHash [32]byte + BlockHash [32]byte + StateRoot [32]byte + Graffiti [32]byte +} + +// TaikoDataTransitionState is an auto generated low-level Go binding around an user-defined struct. +type TaikoDataTransitionState struct { + Key [32]byte + BlockHash [32]byte + StateRoot [32]byte + Prover common.Address + ValidityBond *big.Int + Contester common.Address + ContestBond *big.Int + Timestamp uint64 + Tier uint16 + Reserved1 uint8 +} + +// TaikoL1ClientMetaData contains all meta data concerning the TaikoL1Client contract. +var TaikoL1ClientMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBlock\",\"inputs\":[{\"name\":\"_blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"blk_\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Block\",\"components\":[{\"name\":\"metaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"assignedProver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"proposedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"proposedIn\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"nextTransitionId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"verifiedTransitionId\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.Config\",\"components\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blockMaxProposals\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blockRingBufferSize\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maxBlocksToVerifyPerProposal\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blockMaxGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"blockSyncThreshold\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getStateVariables\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotA\",\"components\":[{\"name\":\"genesisHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"genesisTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSyncedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSynecdAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTransition\",\"inputs\":[{\"name\":\"_blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_tid\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TransitionState\",\"components\":[{\"name\":\"key\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"prover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"contester\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reserved1\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTransition\",\"inputs\":[{\"name\":\"_blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.TransitionState\",\"components\":[{\"name\":\"key\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"prover\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"contester\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"tier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reserved1\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_toPause\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"init2\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseProving\",\"inputs\":[{\"name\":\"_pause\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposeBlock\",\"inputs\":[{\"name\":\"_params\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_txList\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"meta_\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"deposits_\",\"type\":\"tuple[]\",\"internalType\":\"structTaikoData.EthDeposit[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"proveBlock\",\"inputs\":[{\"name\":\"_blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_input\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"slotA\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotA\",\"components\":[{\"name\":\"genesisHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"genesisTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSyncedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSynecdAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"slotB\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"state\",\"inputs\":[],\"outputs\":[{\"name\":\"__reserve1\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"slotA\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotA\",\"components\":[{\"name\":\"genesisHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"genesisTimestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSyncedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastSynecdAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"slotB\",\"type\":\"tuple\",\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifyBlocks\",\"inputs\":[{\"name\":\"_maxBlocksToVerify\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockProposed\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"assignedProver\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"meta\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"depositsProcessed\",\"type\":\"tuple[]\",\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockProposed\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"assignedProver\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"livenessBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"meta\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"components\":[{\"name\":\"l1Hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"difficulty\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blobHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extraData\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"depositsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"coinbase\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"gasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"l1Height\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minTier\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"blobUsed\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"parentMetaHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"depositsProcessed\",\"type\":\"tuple[]\",\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockVerified\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockVerified\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EthDeposited\",\"inputs\":[{\"name\":\"deposit\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"id\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProvingPaused\",\"inputs\":[{\"name\":\"paused\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProvingPaused\",\"inputs\":[{\"name\":\"paused\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StateVariablesUpdated\",\"inputs\":[{\"name\":\"slotB\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StateVariablesUpdated\",\"inputs\":[{\"name\":\"slotB\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.SlotB\",\"components\":[{\"name\":\"numBlocks\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"provingPaused\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"__reservedB1\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"__reservedB2\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"__reservedB3\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"lastUnpausedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionContested\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"contester\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionContested\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"contester\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionProved\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransitionProved\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"tran\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTaikoData.Transition\",\"components\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"graffiti\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"prover\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"indexed\":false,\"internalType\":\"uint96\"},{\"name\":\"tier\",\"type\":\"uint16\",\"indexed\":false,\"internalType\":\"uint16\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ETH_TRANSFER_FAILED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_ALREADY_CONTESTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_ALREADY_CONTESTED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_ALREADY_PROVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_ALREADY_PROVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_AVAILABLE\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_AVAILABLE\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOB_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_BLOCK_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_CANNOT_CONTEST\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_CANNOT_CONTEST\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_BLOCK_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_BLOCK_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_BLOCK_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_CONFIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_CONFIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_GENESIS_HASH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_GENESIS_HASH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_HOOK\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_HOOK\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PARAM\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PROVER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_PROVER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_SIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_SIG\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TIER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TIER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TRANSITION\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_INVALID_TRANSITION\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_LIVENESS_BOND_NOT_RECEIVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_LIVENESS_BOND_NOT_RECEIVED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_NOT_ASSIGNED_PROVER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_NOT_ASSIGNED_PROVER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_PROVING_PAUSED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_RECEIVE_DISABLED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TOO_MANY_BLOCKS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TOO_MANY_BLOCKS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_ID_ZERO\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_ID_ZERO\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_TRANSITION_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNAUTHORIZED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNAUTHORIZED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_PARENT\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_PARENT\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1_UNEXPECTED_TRANSITION_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// TaikoL1ClientABI is the input ABI used to generate the binding from. +// Deprecated: Use TaikoL1ClientMetaData.ABI instead. +var TaikoL1ClientABI = TaikoL1ClientMetaData.ABI + +// TaikoL1Client is an auto generated Go binding around an Ethereum contract. +type TaikoL1Client struct { + TaikoL1ClientCaller // Read-only binding to the contract + TaikoL1ClientTransactor // Write-only binding to the contract + TaikoL1ClientFilterer // Log filterer for contract events +} + +// TaikoL1ClientCaller is an auto generated read-only Go binding around an Ethereum contract. +type TaikoL1ClientCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL1ClientTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TaikoL1ClientTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL1ClientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TaikoL1ClientFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL1ClientSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TaikoL1ClientSession struct { + Contract *TaikoL1Client // 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 +} + +// TaikoL1ClientCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TaikoL1ClientCallerSession struct { + Contract *TaikoL1ClientCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TaikoL1ClientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TaikoL1ClientTransactorSession struct { + Contract *TaikoL1ClientTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TaikoL1ClientRaw is an auto generated low-level Go binding around an Ethereum contract. +type TaikoL1ClientRaw struct { + Contract *TaikoL1Client // Generic contract binding to access the raw methods on +} + +// TaikoL1ClientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TaikoL1ClientCallerRaw struct { + Contract *TaikoL1ClientCaller // Generic read-only contract binding to access the raw methods on +} + +// TaikoL1ClientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TaikoL1ClientTransactorRaw struct { + Contract *TaikoL1ClientTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTaikoL1Client creates a new instance of TaikoL1Client, bound to a specific deployed contract. +func NewTaikoL1Client(address common.Address, backend bind.ContractBackend) (*TaikoL1Client, error) { + contract, err := bindTaikoL1Client(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TaikoL1Client{TaikoL1ClientCaller: TaikoL1ClientCaller{contract: contract}, TaikoL1ClientTransactor: TaikoL1ClientTransactor{contract: contract}, TaikoL1ClientFilterer: TaikoL1ClientFilterer{contract: contract}}, nil +} + +// NewTaikoL1ClientCaller creates a new read-only instance of TaikoL1Client, bound to a specific deployed contract. +func NewTaikoL1ClientCaller(address common.Address, caller bind.ContractCaller) (*TaikoL1ClientCaller, error) { + contract, err := bindTaikoL1Client(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TaikoL1ClientCaller{contract: contract}, nil +} + +// NewTaikoL1ClientTransactor creates a new write-only instance of TaikoL1Client, bound to a specific deployed contract. +func NewTaikoL1ClientTransactor(address common.Address, transactor bind.ContractTransactor) (*TaikoL1ClientTransactor, error) { + contract, err := bindTaikoL1Client(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TaikoL1ClientTransactor{contract: contract}, nil +} + +// NewTaikoL1ClientFilterer creates a new log filterer instance of TaikoL1Client, bound to a specific deployed contract. +func NewTaikoL1ClientFilterer(address common.Address, filterer bind.ContractFilterer) (*TaikoL1ClientFilterer, error) { + contract, err := bindTaikoL1Client(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TaikoL1ClientFilterer{contract: contract}, nil +} + +// bindTaikoL1Client binds a generic wrapper to an already deployed contract. +func bindTaikoL1Client(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TaikoL1ClientMetaData.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 (_TaikoL1Client *TaikoL1ClientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoL1Client.Contract.TaikoL1ClientCaller.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 (_TaikoL1Client *TaikoL1ClientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.Contract.TaikoL1ClientTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoL1Client *TaikoL1ClientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoL1Client.Contract.TaikoL1ClientTransactor.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 (_TaikoL1Client *TaikoL1ClientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoL1Client.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 (_TaikoL1Client *TaikoL1ClientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoL1Client *TaikoL1ClientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoL1Client.Contract.contract.Transact(opts, method, params...) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL1Client *TaikoL1ClientSession) AddressManager() (common.Address, error) { + return _TaikoL1Client.Contract.AddressManager(&_TaikoL1Client.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCallerSession) AddressManager() (common.Address, error) { + return _TaikoL1Client.Contract.AddressManager(&_TaikoL1Client.CallOpts) +} + +// GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. +// +// Solidity: function getBlock(uint64 _blockId) view returns((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) blk_) +func (_TaikoL1Client *TaikoL1ClientCaller) GetBlock(opts *bind.CallOpts, _blockId uint64) (TaikoDataBlock, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "getBlock", _blockId) + + if err != nil { + return *new(TaikoDataBlock), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataBlock)).(*TaikoDataBlock) + + return out0, err + +} + +// GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. +// +// Solidity: function getBlock(uint64 _blockId) view returns((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) blk_) +func (_TaikoL1Client *TaikoL1ClientSession) GetBlock(_blockId uint64) (TaikoDataBlock, error) { + return _TaikoL1Client.Contract.GetBlock(&_TaikoL1Client.CallOpts, _blockId) +} + +// GetBlock is a free data retrieval call binding the contract method 0x5fa15e79. +// +// Solidity: function getBlock(uint64 _blockId) view returns((bytes32,address,uint96,uint64,uint64,uint64,uint32,uint32) blk_) +func (_TaikoL1Client *TaikoL1ClientCallerSession) GetBlock(_blockId uint64) (TaikoDataBlock, error) { + return _TaikoL1Client.Contract.GetBlock(&_TaikoL1Client.CallOpts, _blockId) +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint64,uint64,uint64,uint64,uint32,uint96,uint8)) +func (_TaikoL1Client *TaikoL1ClientCaller) GetConfig(opts *bind.CallOpts) (TaikoDataConfig, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "getConfig") + + if err != nil { + return *new(TaikoDataConfig), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataConfig)).(*TaikoDataConfig) + + return out0, err + +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint64,uint64,uint64,uint64,uint32,uint96,uint8)) +func (_TaikoL1Client *TaikoL1ClientSession) GetConfig() (TaikoDataConfig, error) { + return _TaikoL1Client.Contract.GetConfig(&_TaikoL1Client.CallOpts) +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint64,uint64,uint64,uint64,uint32,uint96,uint8)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) GetConfig() (TaikoDataConfig, error) { + return _TaikoL1Client.Contract.GetConfig(&_TaikoL1Client.CallOpts) +} + +// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5. +// +// Solidity: function getStateVariables() view returns((uint64,uint64,uint64,uint64), (uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientCaller) GetStateVariables(opts *bind.CallOpts) (TaikoDataSlotA, TaikoDataSlotB, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "getStateVariables") + + if err != nil { + return *new(TaikoDataSlotA), *new(TaikoDataSlotB), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataSlotA)).(*TaikoDataSlotA) + out1 := *abi.ConvertType(out[1], new(TaikoDataSlotB)).(*TaikoDataSlotB) + + return out0, out1, err + +} + +// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5. +// +// Solidity: function getStateVariables() view returns((uint64,uint64,uint64,uint64), (uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientSession) GetStateVariables() (TaikoDataSlotA, TaikoDataSlotB, error) { + return _TaikoL1Client.Contract.GetStateVariables(&_TaikoL1Client.CallOpts) +} + +// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5. +// +// Solidity: function getStateVariables() view returns((uint64,uint64,uint64,uint64), (uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) GetStateVariables() (TaikoDataSlotA, TaikoDataSlotB, error) { + return _TaikoL1Client.Contract.GetStateVariables(&_TaikoL1Client.CallOpts) +} + +// GetTransition is a free data retrieval call binding the contract method 0x563479a5. +// +// Solidity: function getTransition(uint64 _blockId, uint32 _tid) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientCaller) GetTransition(opts *bind.CallOpts, _blockId uint64, _tid uint32) (TaikoDataTransitionState, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "getTransition", _blockId, _tid) + + if err != nil { + return *new(TaikoDataTransitionState), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataTransitionState)).(*TaikoDataTransitionState) + + return out0, err + +} + +// GetTransition is a free data retrieval call binding the contract method 0x563479a5. +// +// Solidity: function getTransition(uint64 _blockId, uint32 _tid) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientSession) GetTransition(_blockId uint64, _tid uint32) (TaikoDataTransitionState, error) { + return _TaikoL1Client.Contract.GetTransition(&_TaikoL1Client.CallOpts, _blockId, _tid) +} + +// GetTransition is a free data retrieval call binding the contract method 0x563479a5. +// +// Solidity: function getTransition(uint64 _blockId, uint32 _tid) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) GetTransition(_blockId uint64, _tid uint32) (TaikoDataTransitionState, error) { + return _TaikoL1Client.Contract.GetTransition(&_TaikoL1Client.CallOpts, _blockId, _tid) +} + +// GetTransition0 is a free data retrieval call binding the contract method 0xfd257e29. +// +// Solidity: function getTransition(uint64 _blockId, bytes32 _parentHash) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientCaller) GetTransition0(opts *bind.CallOpts, _blockId uint64, _parentHash [32]byte) (TaikoDataTransitionState, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "getTransition0", _blockId, _parentHash) + + if err != nil { + return *new(TaikoDataTransitionState), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataTransitionState)).(*TaikoDataTransitionState) + + return out0, err + +} + +// GetTransition0 is a free data retrieval call binding the contract method 0xfd257e29. +// +// Solidity: function getTransition(uint64 _blockId, bytes32 _parentHash) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientSession) GetTransition0(_blockId uint64, _parentHash [32]byte) (TaikoDataTransitionState, error) { + return _TaikoL1Client.Contract.GetTransition0(&_TaikoL1Client.CallOpts, _blockId, _parentHash) +} + +// GetTransition0 is a free data retrieval call binding the contract method 0xfd257e29. +// +// Solidity: function getTransition(uint64 _blockId, bytes32 _parentHash) view returns((bytes32,bytes32,bytes32,address,uint96,address,uint96,uint64,uint16,uint8)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) GetTransition0(_blockId uint64, _parentHash [32]byte) (TaikoDataTransitionState, error) { + return _TaikoL1Client.Contract.GetTransition0(&_TaikoL1Client.CallOpts, _blockId, _parentHash) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL1Client *TaikoL1ClientCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL1Client *TaikoL1ClientSession) LastUnpausedAt() (uint64, error) { + return _TaikoL1Client.Contract.LastUnpausedAt(&_TaikoL1Client.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL1Client *TaikoL1ClientCallerSession) LastUnpausedAt() (uint64, error) { + return _TaikoL1Client.Contract.LastUnpausedAt(&_TaikoL1Client.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientSession) Owner() (common.Address, error) { + return _TaikoL1Client.Contract.Owner(&_TaikoL1Client.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCallerSession) Owner() (common.Address, error) { + return _TaikoL1Client.Contract.Owner(&_TaikoL1Client.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL1Client *TaikoL1ClientCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL1Client *TaikoL1ClientSession) Paused() (bool, error) { + return _TaikoL1Client.Contract.Paused(&_TaikoL1Client.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL1Client *TaikoL1ClientCallerSession) Paused() (bool, error) { + return _TaikoL1Client.Contract.Paused(&_TaikoL1Client.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientSession) PendingOwner() (common.Address, error) { + return _TaikoL1Client.Contract.PendingOwner(&_TaikoL1Client.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL1Client *TaikoL1ClientCallerSession) PendingOwner() (common.Address, error) { + return _TaikoL1Client.Contract.PendingOwner(&_TaikoL1Client.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL1Client *TaikoL1ClientCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL1Client *TaikoL1ClientSession) ProxiableUUID() ([32]byte, error) { + return _TaikoL1Client.Contract.ProxiableUUID(&_TaikoL1Client.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL1Client *TaikoL1ClientCallerSession) ProxiableUUID() ([32]byte, error) { + return _TaikoL1Client.Contract.ProxiableUUID(&_TaikoL1Client.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL1Client.Contract.Resolve(&_TaikoL1Client.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL1Client.Contract.Resolve(&_TaikoL1Client.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL1Client.Contract.Resolve0(&_TaikoL1Client.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL1Client *TaikoL1ClientCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL1Client.Contract.Resolve0(&_TaikoL1Client.CallOpts, _name, _allowZeroAddress) +} + +// SlotA is a free data retrieval call binding the contract method 0xc7821568. +// +// Solidity: function slotA() view returns((uint64,uint64,uint64,uint64)) +func (_TaikoL1Client *TaikoL1ClientCaller) SlotA(opts *bind.CallOpts) (TaikoDataSlotA, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "slotA") + + if err != nil { + return *new(TaikoDataSlotA), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataSlotA)).(*TaikoDataSlotA) + + return out0, err + +} + +// SlotA is a free data retrieval call binding the contract method 0xc7821568. +// +// Solidity: function slotA() view returns((uint64,uint64,uint64,uint64)) +func (_TaikoL1Client *TaikoL1ClientSession) SlotA() (TaikoDataSlotA, error) { + return _TaikoL1Client.Contract.SlotA(&_TaikoL1Client.CallOpts) +} + +// SlotA is a free data retrieval call binding the contract method 0xc7821568. +// +// Solidity: function slotA() view returns((uint64,uint64,uint64,uint64)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) SlotA() (TaikoDataSlotA, error) { + return _TaikoL1Client.Contract.SlotA(&_TaikoL1Client.CallOpts) +} + +// SlotB is a free data retrieval call binding the contract method 0x19e8dce2. +// +// Solidity: function slotB() view returns((uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientCaller) SlotB(opts *bind.CallOpts) (TaikoDataSlotB, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "slotB") + + if err != nil { + return *new(TaikoDataSlotB), err + } + + out0 := *abi.ConvertType(out[0], new(TaikoDataSlotB)).(*TaikoDataSlotB) + + return out0, err + +} + +// SlotB is a free data retrieval call binding the contract method 0x19e8dce2. +// +// Solidity: function slotB() view returns((uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientSession) SlotB() (TaikoDataSlotB, error) { + return _TaikoL1Client.Contract.SlotB(&_TaikoL1Client.CallOpts) +} + +// SlotB is a free data retrieval call binding the contract method 0x19e8dce2. +// +// Solidity: function slotB() view returns((uint64,uint64,bool,uint8,uint16,uint32,uint64)) +func (_TaikoL1Client *TaikoL1ClientCallerSession) SlotB() (TaikoDataSlotB, error) { + return _TaikoL1Client.Contract.SlotB(&_TaikoL1Client.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(bytes32 __reserve1, (uint64,uint64,uint64,uint64) slotA, (uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientCaller) State(opts *bind.CallOpts) (struct { + Reserve1 [32]byte + SlotA TaikoDataSlotA + SlotB TaikoDataSlotB +}, error) { + var out []interface{} + err := _TaikoL1Client.contract.Call(opts, &out, "state") + + outstruct := new(struct { + Reserve1 [32]byte + SlotA TaikoDataSlotA + SlotB TaikoDataSlotB + }) + if err != nil { + return *outstruct, err + } + + outstruct.Reserve1 = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.SlotA = *abi.ConvertType(out[1], new(TaikoDataSlotA)).(*TaikoDataSlotA) + outstruct.SlotB = *abi.ConvertType(out[2], new(TaikoDataSlotB)).(*TaikoDataSlotB) + + return *outstruct, err + +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(bytes32 __reserve1, (uint64,uint64,uint64,uint64) slotA, (uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientSession) State() (struct { + Reserve1 [32]byte + SlotA TaikoDataSlotA + SlotB TaikoDataSlotB +}, error) { + return _TaikoL1Client.Contract.State(&_TaikoL1Client.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(bytes32 __reserve1, (uint64,uint64,uint64,uint64) slotA, (uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientCallerSession) State() (struct { + Reserve1 [32]byte + SlotA TaikoDataSlotA + SlotB TaikoDataSlotB +}, error) { + return _TaikoL1Client.Contract.State(&_TaikoL1Client.CallOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoL1Client.Contract.AcceptOwnership(&_TaikoL1Client.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoL1Client.Contract.AcceptOwnership(&_TaikoL1Client.TransactOpts) +} + +// Init is a paid mutator transaction binding the contract method 0x29d1b62f. +// +// Solidity: function init(address _owner, address _addressManager, bytes32 _genesisBlockHash, bool _toPause) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address, _genesisBlockHash [32]byte, _toPause bool) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "init", _owner, _addressManager, _genesisBlockHash, _toPause) +} + +// Init is a paid mutator transaction binding the contract method 0x29d1b62f. +// +// Solidity: function init(address _owner, address _addressManager, bytes32 _genesisBlockHash, bool _toPause) returns() +func (_TaikoL1Client *TaikoL1ClientSession) Init(_owner common.Address, _addressManager common.Address, _genesisBlockHash [32]byte, _toPause bool) (*types.Transaction, error) { + return _TaikoL1Client.Contract.Init(&_TaikoL1Client.TransactOpts, _owner, _addressManager, _genesisBlockHash, _toPause) +} + +// Init is a paid mutator transaction binding the contract method 0x29d1b62f. +// +// Solidity: function init(address _owner, address _addressManager, bytes32 _genesisBlockHash, bool _toPause) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) Init(_owner common.Address, _addressManager common.Address, _genesisBlockHash [32]byte, _toPause bool) (*types.Transaction, error) { + return _TaikoL1Client.Contract.Init(&_TaikoL1Client.TransactOpts, _owner, _addressManager, _genesisBlockHash, _toPause) +} + +// Init2 is a paid mutator transaction binding the contract method 0x069489a2. +// +// Solidity: function init2() returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) Init2(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "init2") +} + +// Init2 is a paid mutator transaction binding the contract method 0x069489a2. +// +// Solidity: function init2() returns() +func (_TaikoL1Client *TaikoL1ClientSession) Init2() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Init2(&_TaikoL1Client.TransactOpts) +} + +// Init2 is a paid mutator transaction binding the contract method 0x069489a2. +// +// Solidity: function init2() returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) Init2() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Init2(&_TaikoL1Client.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL1Client *TaikoL1ClientSession) Pause() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Pause(&_TaikoL1Client.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) Pause() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Pause(&_TaikoL1Client.TransactOpts) +} + +// PauseProving is a paid mutator transaction binding the contract method 0xff00c391. +// +// Solidity: function pauseProving(bool _pause) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) PauseProving(opts *bind.TransactOpts, _pause bool) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "pauseProving", _pause) +} + +// PauseProving is a paid mutator transaction binding the contract method 0xff00c391. +// +// Solidity: function pauseProving(bool _pause) returns() +func (_TaikoL1Client *TaikoL1ClientSession) PauseProving(_pause bool) (*types.Transaction, error) { + return _TaikoL1Client.Contract.PauseProving(&_TaikoL1Client.TransactOpts, _pause) +} + +// PauseProving is a paid mutator transaction binding the contract method 0xff00c391. +// +// Solidity: function pauseProving(bool _pause) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) PauseProving(_pause bool) (*types.Transaction, error) { + return _TaikoL1Client.Contract.PauseProving(&_TaikoL1Client.TransactOpts, _pause) +} + +// ProposeBlock is a paid mutator transaction binding the contract method 0xef16e845. +// +// Solidity: function proposeBlock(bytes _params, bytes _txList) payable returns((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta_, (address,uint96,uint64)[] deposits_) +func (_TaikoL1Client *TaikoL1ClientTransactor) ProposeBlock(opts *bind.TransactOpts, _params []byte, _txList []byte) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "proposeBlock", _params, _txList) +} + +// ProposeBlock is a paid mutator transaction binding the contract method 0xef16e845. +// +// Solidity: function proposeBlock(bytes _params, bytes _txList) payable returns((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta_, (address,uint96,uint64)[] deposits_) +func (_TaikoL1Client *TaikoL1ClientSession) ProposeBlock(_params []byte, _txList []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.ProposeBlock(&_TaikoL1Client.TransactOpts, _params, _txList) +} + +// ProposeBlock is a paid mutator transaction binding the contract method 0xef16e845. +// +// Solidity: function proposeBlock(bytes _params, bytes _txList) payable returns((bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta_, (address,uint96,uint64)[] deposits_) +func (_TaikoL1Client *TaikoL1ClientTransactorSession) ProposeBlock(_params []byte, _txList []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.ProposeBlock(&_TaikoL1Client.TransactOpts, _params, _txList) +} + +// ProveBlock is a paid mutator transaction binding the contract method 0x10d008bd. +// +// Solidity: function proveBlock(uint64 _blockId, bytes _input) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) ProveBlock(opts *bind.TransactOpts, _blockId uint64, _input []byte) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "proveBlock", _blockId, _input) +} + +// ProveBlock is a paid mutator transaction binding the contract method 0x10d008bd. +// +// Solidity: function proveBlock(uint64 _blockId, bytes _input) returns() +func (_TaikoL1Client *TaikoL1ClientSession) ProveBlock(_blockId uint64, _input []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.ProveBlock(&_TaikoL1Client.TransactOpts, _blockId, _input) +} + +// ProveBlock is a paid mutator transaction binding the contract method 0x10d008bd. +// +// Solidity: function proveBlock(uint64 _blockId, bytes _input) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) ProveBlock(_blockId uint64, _input []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.ProveBlock(&_TaikoL1Client.TransactOpts, _blockId, _input) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoL1Client.Contract.RenounceOwnership(&_TaikoL1Client.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoL1Client.Contract.RenounceOwnership(&_TaikoL1Client.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL1Client *TaikoL1ClientSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoL1Client.Contract.TransferOwnership(&_TaikoL1Client.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoL1Client.Contract.TransferOwnership(&_TaikoL1Client.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL1Client *TaikoL1ClientSession) Unpause() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Unpause(&_TaikoL1Client.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) Unpause() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Unpause(&_TaikoL1Client.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL1Client *TaikoL1ClientSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL1Client.Contract.UpgradeTo(&_TaikoL1Client.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL1Client.Contract.UpgradeTo(&_TaikoL1Client.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL1Client *TaikoL1ClientSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.UpgradeToAndCall(&_TaikoL1Client.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL1Client.Contract.UpgradeToAndCall(&_TaikoL1Client.TransactOpts, newImplementation, data) +} + +// VerifyBlocks is a paid mutator transaction binding the contract method 0x8778209d. +// +// Solidity: function verifyBlocks(uint64 _maxBlocksToVerify) returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) VerifyBlocks(opts *bind.TransactOpts, _maxBlocksToVerify uint64) (*types.Transaction, error) { + return _TaikoL1Client.contract.Transact(opts, "verifyBlocks", _maxBlocksToVerify) +} + +// VerifyBlocks is a paid mutator transaction binding the contract method 0x8778209d. +// +// Solidity: function verifyBlocks(uint64 _maxBlocksToVerify) returns() +func (_TaikoL1Client *TaikoL1ClientSession) VerifyBlocks(_maxBlocksToVerify uint64) (*types.Transaction, error) { + return _TaikoL1Client.Contract.VerifyBlocks(&_TaikoL1Client.TransactOpts, _maxBlocksToVerify) +} + +// VerifyBlocks is a paid mutator transaction binding the contract method 0x8778209d. +// +// Solidity: function verifyBlocks(uint64 _maxBlocksToVerify) returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) VerifyBlocks(_maxBlocksToVerify uint64) (*types.Transaction, error) { + return _TaikoL1Client.Contract.VerifyBlocks(&_TaikoL1Client.TransactOpts, _maxBlocksToVerify) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TaikoL1Client *TaikoL1ClientTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL1Client.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TaikoL1Client *TaikoL1ClientSession) Receive() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Receive(&_TaikoL1Client.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TaikoL1Client *TaikoL1ClientTransactorSession) Receive() (*types.Transaction, error) { + return _TaikoL1Client.Contract.Receive(&_TaikoL1Client.TransactOpts) +} + +// TaikoL1ClientAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TaikoL1Client contract. +type TaikoL1ClientAdminChangedIterator struct { + Event *TaikoL1ClientAdminChanged // 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 *TaikoL1ClientAdminChangedIterator) 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(TaikoL1ClientAdminChanged) + 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(TaikoL1ClientAdminChanged) + 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 *TaikoL1ClientAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientAdminChanged represents a AdminChanged event raised by the TaikoL1Client contract. +type TaikoL1ClientAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TaikoL1ClientAdminChangedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TaikoL1ClientAdminChangedIterator{contract: _TaikoL1Client.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "AdminChanged") + 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(TaikoL1ClientAdminChanged) + if err := _TaikoL1Client.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseAdminChanged(log types.Log) (*TaikoL1ClientAdminChanged, error) { + event := new(TaikoL1ClientAdminChanged) + if err := _TaikoL1Client.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the TaikoL1Client contract. +type TaikoL1ClientBeaconUpgradedIterator struct { + Event *TaikoL1ClientBeaconUpgraded // 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 *TaikoL1ClientBeaconUpgradedIterator) 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(TaikoL1ClientBeaconUpgraded) + 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(TaikoL1ClientBeaconUpgraded) + 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 *TaikoL1ClientBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientBeaconUpgraded represents a BeaconUpgraded event raised by the TaikoL1Client contract. +type TaikoL1ClientBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*TaikoL1ClientBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientBeaconUpgradedIterator{contract: _TaikoL1Client.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(TaikoL1ClientBeaconUpgraded) + if err := _TaikoL1Client.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseBeaconUpgraded(log types.Log) (*TaikoL1ClientBeaconUpgraded, error) { + event := new(TaikoL1ClientBeaconUpgraded) + if err := _TaikoL1Client.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientBlockProposedIterator is returned from FilterBlockProposed and is used to iterate over the raw logs and unpacked data for BlockProposed events raised by the TaikoL1Client contract. +type TaikoL1ClientBlockProposedIterator struct { + Event *TaikoL1ClientBlockProposed // 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 *TaikoL1ClientBlockProposedIterator) 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(TaikoL1ClientBlockProposed) + 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(TaikoL1ClientBlockProposed) + 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 *TaikoL1ClientBlockProposedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientBlockProposedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientBlockProposed represents a BlockProposed event raised by the TaikoL1Client contract. +type TaikoL1ClientBlockProposed struct { + BlockId *big.Int + AssignedProver common.Address + LivenessBond *big.Int + Meta TaikoDataBlockMetadata + DepositsProcessed []TaikoDataEthDeposit + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockProposed is a free log retrieval operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterBlockProposed(opts *bind.FilterOpts, blockId []*big.Int, assignedProver []common.Address) (*TaikoL1ClientBlockProposedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "BlockProposed", blockIdRule, assignedProverRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientBlockProposedIterator{contract: _TaikoL1Client.contract, event: "BlockProposed", logs: logs, sub: sub}, nil +} + +// WatchBlockProposed is a free log subscription operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchBlockProposed(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientBlockProposed, blockId []*big.Int, assignedProver []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "BlockProposed", blockIdRule, assignedProverRule) + 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(TaikoL1ClientBlockProposed) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockProposed", 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 +} + +// ParseBlockProposed is a log parse operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseBlockProposed(log types.Log) (*TaikoL1ClientBlockProposed, error) { + event := new(TaikoL1ClientBlockProposed) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockProposed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientBlockProposed0Iterator is returned from FilterBlockProposed0 and is used to iterate over the raw logs and unpacked data for BlockProposed0 events raised by the TaikoL1Client contract. +type TaikoL1ClientBlockProposed0Iterator struct { + Event *TaikoL1ClientBlockProposed0 // 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 *TaikoL1ClientBlockProposed0Iterator) 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(TaikoL1ClientBlockProposed0) + 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(TaikoL1ClientBlockProposed0) + 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 *TaikoL1ClientBlockProposed0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientBlockProposed0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientBlockProposed0 represents a BlockProposed0 event raised by the TaikoL1Client contract. +type TaikoL1ClientBlockProposed0 struct { + BlockId *big.Int + AssignedProver common.Address + LivenessBond *big.Int + Meta TaikoDataBlockMetadata + DepositsProcessed []TaikoDataEthDeposit + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockProposed0 is a free log retrieval operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterBlockProposed0(opts *bind.FilterOpts, blockId []*big.Int, assignedProver []common.Address) (*TaikoL1ClientBlockProposed0Iterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "BlockProposed0", blockIdRule, assignedProverRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientBlockProposed0Iterator{contract: _TaikoL1Client.contract, event: "BlockProposed0", logs: logs, sub: sub}, nil +} + +// WatchBlockProposed0 is a free log subscription operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchBlockProposed0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientBlockProposed0, blockId []*big.Int, assignedProver []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var assignedProverRule []interface{} + for _, assignedProverItem := range assignedProver { + assignedProverRule = append(assignedProverRule, assignedProverItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "BlockProposed0", blockIdRule, assignedProverRule) + 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(TaikoL1ClientBlockProposed0) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockProposed0", 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 +} + +// ParseBlockProposed0 is a log parse operation binding the contract event 0xcda4e564245eb15494bc6da29f6a42e1941cf57f5314bf35bab8a1fca0a9c60a. +// +// Solidity: event BlockProposed(uint256 indexed blockId, address indexed assignedProver, uint96 livenessBond, (bytes32,bytes32,bytes32,bytes32,bytes32,address,uint64,uint32,uint64,uint64,uint16,bool,bytes32,address) meta, (address,uint96,uint64)[] depositsProcessed) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseBlockProposed0(log types.Log) (*TaikoL1ClientBlockProposed0, error) { + event := new(TaikoL1ClientBlockProposed0) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockProposed0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientBlockVerifiedIterator is returned from FilterBlockVerified and is used to iterate over the raw logs and unpacked data for BlockVerified events raised by the TaikoL1Client contract. +type TaikoL1ClientBlockVerifiedIterator struct { + Event *TaikoL1ClientBlockVerified // 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 *TaikoL1ClientBlockVerifiedIterator) 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(TaikoL1ClientBlockVerified) + 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(TaikoL1ClientBlockVerified) + 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 *TaikoL1ClientBlockVerifiedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientBlockVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientBlockVerified represents a BlockVerified event raised by the TaikoL1Client contract. +type TaikoL1ClientBlockVerified struct { + BlockId *big.Int + Prover common.Address + BlockHash [32]byte + StateRoot [32]byte + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockVerified is a free log retrieval operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterBlockVerified(opts *bind.FilterOpts, blockId []*big.Int, prover []common.Address) (*TaikoL1ClientBlockVerifiedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "BlockVerified", blockIdRule, proverRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientBlockVerifiedIterator{contract: _TaikoL1Client.contract, event: "BlockVerified", logs: logs, sub: sub}, nil +} + +// WatchBlockVerified is a free log subscription operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchBlockVerified(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientBlockVerified, blockId []*big.Int, prover []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "BlockVerified", blockIdRule, proverRule) + 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(TaikoL1ClientBlockVerified) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockVerified", 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 +} + +// ParseBlockVerified is a log parse operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseBlockVerified(log types.Log) (*TaikoL1ClientBlockVerified, error) { + event := new(TaikoL1ClientBlockVerified) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockVerified", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientBlockVerified0Iterator is returned from FilterBlockVerified0 and is used to iterate over the raw logs and unpacked data for BlockVerified0 events raised by the TaikoL1Client contract. +type TaikoL1ClientBlockVerified0Iterator struct { + Event *TaikoL1ClientBlockVerified0 // 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 *TaikoL1ClientBlockVerified0Iterator) 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(TaikoL1ClientBlockVerified0) + 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(TaikoL1ClientBlockVerified0) + 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 *TaikoL1ClientBlockVerified0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientBlockVerified0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientBlockVerified0 represents a BlockVerified0 event raised by the TaikoL1Client contract. +type TaikoL1ClientBlockVerified0 struct { + BlockId *big.Int + Prover common.Address + BlockHash [32]byte + StateRoot [32]byte + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockVerified0 is a free log retrieval operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterBlockVerified0(opts *bind.FilterOpts, blockId []*big.Int, prover []common.Address) (*TaikoL1ClientBlockVerified0Iterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "BlockVerified0", blockIdRule, proverRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientBlockVerified0Iterator{contract: _TaikoL1Client.contract, event: "BlockVerified0", logs: logs, sub: sub}, nil +} + +// WatchBlockVerified0 is a free log subscription operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchBlockVerified0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientBlockVerified0, blockId []*big.Int, prover []common.Address) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + var proverRule []interface{} + for _, proverItem := range prover { + proverRule = append(proverRule, proverItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "BlockVerified0", blockIdRule, proverRule) + 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(TaikoL1ClientBlockVerified0) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockVerified0", 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 +} + +// ParseBlockVerified0 is a log parse operation binding the contract event 0xdecbd2c61cbda254917d6fd4c980a470701e8f9f1b744f6ad163ca70ca5db289. +// +// Solidity: event BlockVerified(uint256 indexed blockId, address indexed prover, bytes32 blockHash, bytes32 stateRoot, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseBlockVerified0(log types.Log) (*TaikoL1ClientBlockVerified0, error) { + event := new(TaikoL1ClientBlockVerified0) + if err := _TaikoL1Client.contract.UnpackLog(event, "BlockVerified0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientEthDepositedIterator is returned from FilterEthDeposited and is used to iterate over the raw logs and unpacked data for EthDeposited events raised by the TaikoL1Client contract. +type TaikoL1ClientEthDepositedIterator struct { + Event *TaikoL1ClientEthDeposited // 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 *TaikoL1ClientEthDepositedIterator) 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(TaikoL1ClientEthDeposited) + 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(TaikoL1ClientEthDeposited) + 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 *TaikoL1ClientEthDepositedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientEthDepositedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientEthDeposited represents a EthDeposited event raised by the TaikoL1Client contract. +type TaikoL1ClientEthDeposited struct { + Deposit TaikoDataEthDeposit + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEthDeposited is a free log retrieval operation binding the contract event 0x7120a3b075ad25974c5eed76dedb3a217c76c9c6d1f1e201caeba9b89de9a9d9. +// +// Solidity: event EthDeposited((address,uint96,uint64) deposit) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterEthDeposited(opts *bind.FilterOpts) (*TaikoL1ClientEthDepositedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "EthDeposited") + if err != nil { + return nil, err + } + return &TaikoL1ClientEthDepositedIterator{contract: _TaikoL1Client.contract, event: "EthDeposited", logs: logs, sub: sub}, nil +} + +// WatchEthDeposited is a free log subscription operation binding the contract event 0x7120a3b075ad25974c5eed76dedb3a217c76c9c6d1f1e201caeba9b89de9a9d9. +// +// Solidity: event EthDeposited((address,uint96,uint64) deposit) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchEthDeposited(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientEthDeposited) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "EthDeposited") + 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(TaikoL1ClientEthDeposited) + if err := _TaikoL1Client.contract.UnpackLog(event, "EthDeposited", 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 +} + +// ParseEthDeposited is a log parse operation binding the contract event 0x7120a3b075ad25974c5eed76dedb3a217c76c9c6d1f1e201caeba9b89de9a9d9. +// +// Solidity: event EthDeposited((address,uint96,uint64) deposit) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseEthDeposited(log types.Log) (*TaikoL1ClientEthDeposited, error) { + event := new(TaikoL1ClientEthDeposited) + if err := _TaikoL1Client.contract.UnpackLog(event, "EthDeposited", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TaikoL1Client contract. +type TaikoL1ClientInitializedIterator struct { + Event *TaikoL1ClientInitialized // 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 *TaikoL1ClientInitializedIterator) 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(TaikoL1ClientInitialized) + 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(TaikoL1ClientInitialized) + 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 *TaikoL1ClientInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientInitialized represents a Initialized event raised by the TaikoL1Client contract. +type TaikoL1ClientInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterInitialized(opts *bind.FilterOpts) (*TaikoL1ClientInitializedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TaikoL1ClientInitializedIterator{contract: _TaikoL1Client.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientInitialized) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "Initialized") + 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(TaikoL1ClientInitialized) + if err := _TaikoL1Client.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseInitialized(log types.Log) (*TaikoL1ClientInitialized, error) { + event := new(TaikoL1ClientInitialized) + if err := _TaikoL1Client.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the TaikoL1Client contract. +type TaikoL1ClientOwnershipTransferStartedIterator struct { + Event *TaikoL1ClientOwnershipTransferStarted // 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 *TaikoL1ClientOwnershipTransferStartedIterator) 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(TaikoL1ClientOwnershipTransferStarted) + 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(TaikoL1ClientOwnershipTransferStarted) + 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 *TaikoL1ClientOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the TaikoL1Client contract. +type TaikoL1ClientOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoL1ClientOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientOwnershipTransferStartedIterator{contract: _TaikoL1Client.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(TaikoL1ClientOwnershipTransferStarted) + if err := _TaikoL1Client.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseOwnershipTransferStarted(log types.Log) (*TaikoL1ClientOwnershipTransferStarted, error) { + event := new(TaikoL1ClientOwnershipTransferStarted) + if err := _TaikoL1Client.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TaikoL1Client contract. +type TaikoL1ClientOwnershipTransferredIterator struct { + Event *TaikoL1ClientOwnershipTransferred // 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 *TaikoL1ClientOwnershipTransferredIterator) 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(TaikoL1ClientOwnershipTransferred) + 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(TaikoL1ClientOwnershipTransferred) + 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 *TaikoL1ClientOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientOwnershipTransferred represents a OwnershipTransferred event raised by the TaikoL1Client contract. +type TaikoL1ClientOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoL1ClientOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientOwnershipTransferredIterator{contract: _TaikoL1Client.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(TaikoL1ClientOwnershipTransferred) + if err := _TaikoL1Client.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseOwnershipTransferred(log types.Log) (*TaikoL1ClientOwnershipTransferred, error) { + event := new(TaikoL1ClientOwnershipTransferred) + if err := _TaikoL1Client.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the TaikoL1Client contract. +type TaikoL1ClientPausedIterator struct { + Event *TaikoL1ClientPaused // 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 *TaikoL1ClientPausedIterator) 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(TaikoL1ClientPaused) + 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(TaikoL1ClientPaused) + 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 *TaikoL1ClientPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientPaused represents a Paused event raised by the TaikoL1Client contract. +type TaikoL1ClientPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterPaused(opts *bind.FilterOpts) (*TaikoL1ClientPausedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &TaikoL1ClientPausedIterator{contract: _TaikoL1Client.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientPaused) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "Paused") + 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(TaikoL1ClientPaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParsePaused(log types.Log) (*TaikoL1ClientPaused, error) { + event := new(TaikoL1ClientPaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientProvingPausedIterator is returned from FilterProvingPaused and is used to iterate over the raw logs and unpacked data for ProvingPaused events raised by the TaikoL1Client contract. +type TaikoL1ClientProvingPausedIterator struct { + Event *TaikoL1ClientProvingPaused // 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 *TaikoL1ClientProvingPausedIterator) 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(TaikoL1ClientProvingPaused) + 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(TaikoL1ClientProvingPaused) + 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 *TaikoL1ClientProvingPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientProvingPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientProvingPaused represents a ProvingPaused event raised by the TaikoL1Client contract. +type TaikoL1ClientProvingPaused struct { + Paused bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterProvingPaused is a free log retrieval operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterProvingPaused(opts *bind.FilterOpts) (*TaikoL1ClientProvingPausedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "ProvingPaused") + if err != nil { + return nil, err + } + return &TaikoL1ClientProvingPausedIterator{contract: _TaikoL1Client.contract, event: "ProvingPaused", logs: logs, sub: sub}, nil +} + +// WatchProvingPaused is a free log subscription operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchProvingPaused(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientProvingPaused) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "ProvingPaused") + 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(TaikoL1ClientProvingPaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "ProvingPaused", 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 +} + +// ParseProvingPaused is a log parse operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseProvingPaused(log types.Log) (*TaikoL1ClientProvingPaused, error) { + event := new(TaikoL1ClientProvingPaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "ProvingPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientProvingPaused0Iterator is returned from FilterProvingPaused0 and is used to iterate over the raw logs and unpacked data for ProvingPaused0 events raised by the TaikoL1Client contract. +type TaikoL1ClientProvingPaused0Iterator struct { + Event *TaikoL1ClientProvingPaused0 // 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 *TaikoL1ClientProvingPaused0Iterator) 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(TaikoL1ClientProvingPaused0) + 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(TaikoL1ClientProvingPaused0) + 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 *TaikoL1ClientProvingPaused0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientProvingPaused0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientProvingPaused0 represents a ProvingPaused0 event raised by the TaikoL1Client contract. +type TaikoL1ClientProvingPaused0 struct { + Paused bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterProvingPaused0 is a free log retrieval operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterProvingPaused0(opts *bind.FilterOpts) (*TaikoL1ClientProvingPaused0Iterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "ProvingPaused0") + if err != nil { + return nil, err + } + return &TaikoL1ClientProvingPaused0Iterator{contract: _TaikoL1Client.contract, event: "ProvingPaused0", logs: logs, sub: sub}, nil +} + +// WatchProvingPaused0 is a free log subscription operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchProvingPaused0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientProvingPaused0) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "ProvingPaused0") + 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(TaikoL1ClientProvingPaused0) + if err := _TaikoL1Client.contract.UnpackLog(event, "ProvingPaused0", 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 +} + +// ParseProvingPaused0 is a log parse operation binding the contract event 0xed64db85835d07c3c990b8ebdd55e32d64e5ed53143b6ef2179e7bfaf17ddc3b. +// +// Solidity: event ProvingPaused(bool paused) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseProvingPaused0(log types.Log) (*TaikoL1ClientProvingPaused0, error) { + event := new(TaikoL1ClientProvingPaused0) + if err := _TaikoL1Client.contract.UnpackLog(event, "ProvingPaused0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientStateVariablesUpdatedIterator is returned from FilterStateVariablesUpdated and is used to iterate over the raw logs and unpacked data for StateVariablesUpdated events raised by the TaikoL1Client contract. +type TaikoL1ClientStateVariablesUpdatedIterator struct { + Event *TaikoL1ClientStateVariablesUpdated // 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 *TaikoL1ClientStateVariablesUpdatedIterator) 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(TaikoL1ClientStateVariablesUpdated) + 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(TaikoL1ClientStateVariablesUpdated) + 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 *TaikoL1ClientStateVariablesUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientStateVariablesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientStateVariablesUpdated represents a StateVariablesUpdated event raised by the TaikoL1Client contract. +type TaikoL1ClientStateVariablesUpdated struct { + SlotB TaikoDataSlotB + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStateVariablesUpdated is a free log retrieval operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterStateVariablesUpdated(opts *bind.FilterOpts) (*TaikoL1ClientStateVariablesUpdatedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "StateVariablesUpdated") + if err != nil { + return nil, err + } + return &TaikoL1ClientStateVariablesUpdatedIterator{contract: _TaikoL1Client.contract, event: "StateVariablesUpdated", logs: logs, sub: sub}, nil +} + +// WatchStateVariablesUpdated is a free log subscription operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchStateVariablesUpdated(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientStateVariablesUpdated) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "StateVariablesUpdated") + 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(TaikoL1ClientStateVariablesUpdated) + if err := _TaikoL1Client.contract.UnpackLog(event, "StateVariablesUpdated", 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 +} + +// ParseStateVariablesUpdated is a log parse operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseStateVariablesUpdated(log types.Log) (*TaikoL1ClientStateVariablesUpdated, error) { + event := new(TaikoL1ClientStateVariablesUpdated) + if err := _TaikoL1Client.contract.UnpackLog(event, "StateVariablesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientStateVariablesUpdated0Iterator is returned from FilterStateVariablesUpdated0 and is used to iterate over the raw logs and unpacked data for StateVariablesUpdated0 events raised by the TaikoL1Client contract. +type TaikoL1ClientStateVariablesUpdated0Iterator struct { + Event *TaikoL1ClientStateVariablesUpdated0 // 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 *TaikoL1ClientStateVariablesUpdated0Iterator) 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(TaikoL1ClientStateVariablesUpdated0) + 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(TaikoL1ClientStateVariablesUpdated0) + 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 *TaikoL1ClientStateVariablesUpdated0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientStateVariablesUpdated0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientStateVariablesUpdated0 represents a StateVariablesUpdated0 event raised by the TaikoL1Client contract. +type TaikoL1ClientStateVariablesUpdated0 struct { + SlotB TaikoDataSlotB + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStateVariablesUpdated0 is a free log retrieval operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterStateVariablesUpdated0(opts *bind.FilterOpts) (*TaikoL1ClientStateVariablesUpdated0Iterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "StateVariablesUpdated0") + if err != nil { + return nil, err + } + return &TaikoL1ClientStateVariablesUpdated0Iterator{contract: _TaikoL1Client.contract, event: "StateVariablesUpdated0", logs: logs, sub: sub}, nil +} + +// WatchStateVariablesUpdated0 is a free log subscription operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchStateVariablesUpdated0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientStateVariablesUpdated0) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "StateVariablesUpdated0") + 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(TaikoL1ClientStateVariablesUpdated0) + if err := _TaikoL1Client.contract.UnpackLog(event, "StateVariablesUpdated0", 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 +} + +// ParseStateVariablesUpdated0 is a log parse operation binding the contract event 0xdf66aee38ea9fe523cfd238705d455a354305a646748dbb931898b51cee4727b. +// +// Solidity: event StateVariablesUpdated((uint64,uint64,bool,uint8,uint16,uint32,uint64) slotB) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseStateVariablesUpdated0(log types.Log) (*TaikoL1ClientStateVariablesUpdated0, error) { + event := new(TaikoL1ClientStateVariablesUpdated0) + if err := _TaikoL1Client.contract.UnpackLog(event, "StateVariablesUpdated0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientTransitionContestedIterator is returned from FilterTransitionContested and is used to iterate over the raw logs and unpacked data for TransitionContested events raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionContestedIterator struct { + Event *TaikoL1ClientTransitionContested // 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 *TaikoL1ClientTransitionContestedIterator) 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(TaikoL1ClientTransitionContested) + 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(TaikoL1ClientTransitionContested) + 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 *TaikoL1ClientTransitionContestedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientTransitionContestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientTransitionContested represents a TransitionContested event raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionContested struct { + BlockId *big.Int + Tran TaikoDataTransition + Contester common.Address + ContestBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionContested is a free log retrieval operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterTransitionContested(opts *bind.FilterOpts, blockId []*big.Int) (*TaikoL1ClientTransitionContestedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "TransitionContested", blockIdRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientTransitionContestedIterator{contract: _TaikoL1Client.contract, event: "TransitionContested", logs: logs, sub: sub}, nil +} + +// WatchTransitionContested is a free log subscription operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchTransitionContested(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientTransitionContested, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "TransitionContested", blockIdRule) + 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(TaikoL1ClientTransitionContested) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionContested", 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 +} + +// ParseTransitionContested is a log parse operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseTransitionContested(log types.Log) (*TaikoL1ClientTransitionContested, error) { + event := new(TaikoL1ClientTransitionContested) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionContested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientTransitionContested0Iterator is returned from FilterTransitionContested0 and is used to iterate over the raw logs and unpacked data for TransitionContested0 events raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionContested0Iterator struct { + Event *TaikoL1ClientTransitionContested0 // 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 *TaikoL1ClientTransitionContested0Iterator) 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(TaikoL1ClientTransitionContested0) + 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(TaikoL1ClientTransitionContested0) + 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 *TaikoL1ClientTransitionContested0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientTransitionContested0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientTransitionContested0 represents a TransitionContested0 event raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionContested0 struct { + BlockId *big.Int + Tran TaikoDataTransition + Contester common.Address + ContestBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionContested0 is a free log retrieval operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterTransitionContested0(opts *bind.FilterOpts, blockId []*big.Int) (*TaikoL1ClientTransitionContested0Iterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "TransitionContested0", blockIdRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientTransitionContested0Iterator{contract: _TaikoL1Client.contract, event: "TransitionContested0", logs: logs, sub: sub}, nil +} + +// WatchTransitionContested0 is a free log subscription operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchTransitionContested0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientTransitionContested0, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "TransitionContested0", blockIdRule) + 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(TaikoL1ClientTransitionContested0) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionContested0", 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 +} + +// ParseTransitionContested0 is a log parse operation binding the contract event 0xb4c0a86c1ff239277697775b1e91d3375fd3a5ef6b345aa4e2f6001c890558f6. +// +// Solidity: event TransitionContested(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address contester, uint96 contestBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseTransitionContested0(log types.Log) (*TaikoL1ClientTransitionContested0, error) { + event := new(TaikoL1ClientTransitionContested0) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionContested0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientTransitionProvedIterator is returned from FilterTransitionProved and is used to iterate over the raw logs and unpacked data for TransitionProved events raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionProvedIterator struct { + Event *TaikoL1ClientTransitionProved // 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 *TaikoL1ClientTransitionProvedIterator) 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(TaikoL1ClientTransitionProved) + 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(TaikoL1ClientTransitionProved) + 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 *TaikoL1ClientTransitionProvedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientTransitionProvedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientTransitionProved represents a TransitionProved event raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionProved struct { + BlockId *big.Int + Tran TaikoDataTransition + Prover common.Address + ValidityBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionProved is a free log retrieval operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterTransitionProved(opts *bind.FilterOpts, blockId []*big.Int) (*TaikoL1ClientTransitionProvedIterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "TransitionProved", blockIdRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientTransitionProvedIterator{contract: _TaikoL1Client.contract, event: "TransitionProved", logs: logs, sub: sub}, nil +} + +// WatchTransitionProved is a free log subscription operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchTransitionProved(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientTransitionProved, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "TransitionProved", blockIdRule) + 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(TaikoL1ClientTransitionProved) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionProved", 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 +} + +// ParseTransitionProved is a log parse operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseTransitionProved(log types.Log) (*TaikoL1ClientTransitionProved, error) { + event := new(TaikoL1ClientTransitionProved) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionProved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientTransitionProved0Iterator is returned from FilterTransitionProved0 and is used to iterate over the raw logs and unpacked data for TransitionProved0 events raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionProved0Iterator struct { + Event *TaikoL1ClientTransitionProved0 // 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 *TaikoL1ClientTransitionProved0Iterator) 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(TaikoL1ClientTransitionProved0) + 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(TaikoL1ClientTransitionProved0) + 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 *TaikoL1ClientTransitionProved0Iterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientTransitionProved0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientTransitionProved0 represents a TransitionProved0 event raised by the TaikoL1Client contract. +type TaikoL1ClientTransitionProved0 struct { + BlockId *big.Int + Tran TaikoDataTransition + Prover common.Address + ValidityBond *big.Int + Tier uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransitionProved0 is a free log retrieval operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterTransitionProved0(opts *bind.FilterOpts, blockId []*big.Int) (*TaikoL1ClientTransitionProved0Iterator, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "TransitionProved0", blockIdRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientTransitionProved0Iterator{contract: _TaikoL1Client.contract, event: "TransitionProved0", logs: logs, sub: sub}, nil +} + +// WatchTransitionProved0 is a free log subscription operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchTransitionProved0(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientTransitionProved0, blockId []*big.Int) (event.Subscription, error) { + + var blockIdRule []interface{} + for _, blockIdItem := range blockId { + blockIdRule = append(blockIdRule, blockIdItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "TransitionProved0", blockIdRule) + 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(TaikoL1ClientTransitionProved0) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionProved0", 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 +} + +// ParseTransitionProved0 is a log parse operation binding the contract event 0xc195e4be3b936845492b8be4b1cf604db687a4d79ad84d979499c136f8e6701f. +// +// Solidity: event TransitionProved(uint256 indexed blockId, (bytes32,bytes32,bytes32,bytes32) tran, address prover, uint96 validityBond, uint16 tier) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseTransitionProved0(log types.Log) (*TaikoL1ClientTransitionProved0, error) { + event := new(TaikoL1ClientTransitionProved0) + if err := _TaikoL1Client.contract.UnpackLog(event, "TransitionProved0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the TaikoL1Client contract. +type TaikoL1ClientUnpausedIterator struct { + Event *TaikoL1ClientUnpaused // 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 *TaikoL1ClientUnpausedIterator) 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(TaikoL1ClientUnpaused) + 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(TaikoL1ClientUnpaused) + 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 *TaikoL1ClientUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientUnpaused represents a Unpaused event raised by the TaikoL1Client contract. +type TaikoL1ClientUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterUnpaused(opts *bind.FilterOpts) (*TaikoL1ClientUnpausedIterator, error) { + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &TaikoL1ClientUnpausedIterator{contract: _TaikoL1Client.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientUnpaused) (event.Subscription, error) { + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "Unpaused") + 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(TaikoL1ClientUnpaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseUnpaused(log types.Log) (*TaikoL1ClientUnpaused, error) { + event := new(TaikoL1ClientUnpaused) + if err := _TaikoL1Client.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL1ClientUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TaikoL1Client contract. +type TaikoL1ClientUpgradedIterator struct { + Event *TaikoL1ClientUpgraded // 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 *TaikoL1ClientUpgradedIterator) 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(TaikoL1ClientUpgraded) + 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(TaikoL1ClientUpgraded) + 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 *TaikoL1ClientUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL1ClientUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL1ClientUpgraded represents a Upgraded event raised by the TaikoL1Client contract. +type TaikoL1ClientUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL1Client *TaikoL1ClientFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TaikoL1ClientUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoL1Client.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TaikoL1ClientUpgradedIterator{contract: _TaikoL1Client.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL1Client *TaikoL1ClientFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoL1ClientUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoL1Client.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(TaikoL1ClientUpgraded) + if err := _TaikoL1Client.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL1Client *TaikoL1ClientFilterer) ParseUpgraded(log types.Log) (*TaikoL1ClientUpgraded, error) { + event := new(TaikoL1ClientUpgraded) + if err := _TaikoL1Client.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_taiko_l2.go b/packages/taiko-client/bindings/gen_taiko_l2.go new file mode 100644 index 00000000000..69a02fc254f --- /dev/null +++ b/packages/taiko-client/bindings/gen_taiko_l2.go @@ -0,0 +1,2267 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// LibL2ConfigConfig is an auto generated low-level Go binding around an user-defined struct. +type LibL2ConfigConfig struct { + GasTargetPerL1Block uint32 + BasefeeAdjustmentQuotient uint8 + GasExcessMinValue uint64 +} + +// TaikoL2ClientMetaData contains all meta data concerning the TaikoL2Client contract. +var TaikoL2ClientMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"GOLDEN_TOUCH_ADDRESS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"anchor\",\"inputs\":[{\"name\":\"_l1BlockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l1StateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l1BlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_parentGasUsed\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"gasExcess\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBasefee\",\"inputs\":[{\"name\":\"_l1BlockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_parentGasUsed\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"basefee_\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasExcess_\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBlockHash\",\"inputs\":[{\"name\":\"_blockId\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structLibL2Config.Config\",\"components\":[{\"name\":\"gasTargetPerL1Block\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"basefeeAdjustmentQuotient\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"gasExcessMinValue\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addressManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_l1ChainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_gasExcess\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1ChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2Hashes\",\"inputs\":[{\"name\":\"blockId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"blockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastSyncedBlock\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"parentTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"publicInputHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"skipFeeCheck\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"_token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Anchored\",\"inputs\":[{\"name\":\"parentHash\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"gasExcess\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"EIP1559_INVALID_PARAMS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ETH_TRANSFER_FAILED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_BASEFEE_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_INVALID_L1_CHAIN_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_INVALID_L2_CHAIN_ID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_INVALID_PARAM\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_INVALID_SENDER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_PUBLIC_INPUT_HASH_MISMATCH\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L2_TOO_LATE\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"Overflow\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// TaikoL2ClientABI is the input ABI used to generate the binding from. +// Deprecated: Use TaikoL2ClientMetaData.ABI instead. +var TaikoL2ClientABI = TaikoL2ClientMetaData.ABI + +// TaikoL2Client is an auto generated Go binding around an Ethereum contract. +type TaikoL2Client struct { + TaikoL2ClientCaller // Read-only binding to the contract + TaikoL2ClientTransactor // Write-only binding to the contract + TaikoL2ClientFilterer // Log filterer for contract events +} + +// TaikoL2ClientCaller is an auto generated read-only Go binding around an Ethereum contract. +type TaikoL2ClientCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL2ClientTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TaikoL2ClientTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL2ClientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TaikoL2ClientFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoL2ClientSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TaikoL2ClientSession struct { + Contract *TaikoL2Client // 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 +} + +// TaikoL2ClientCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TaikoL2ClientCallerSession struct { + Contract *TaikoL2ClientCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TaikoL2ClientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TaikoL2ClientTransactorSession struct { + Contract *TaikoL2ClientTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TaikoL2ClientRaw is an auto generated low-level Go binding around an Ethereum contract. +type TaikoL2ClientRaw struct { + Contract *TaikoL2Client // Generic contract binding to access the raw methods on +} + +// TaikoL2ClientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TaikoL2ClientCallerRaw struct { + Contract *TaikoL2ClientCaller // Generic read-only contract binding to access the raw methods on +} + +// TaikoL2ClientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TaikoL2ClientTransactorRaw struct { + Contract *TaikoL2ClientTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTaikoL2Client creates a new instance of TaikoL2Client, bound to a specific deployed contract. +func NewTaikoL2Client(address common.Address, backend bind.ContractBackend) (*TaikoL2Client, error) { + contract, err := bindTaikoL2Client(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TaikoL2Client{TaikoL2ClientCaller: TaikoL2ClientCaller{contract: contract}, TaikoL2ClientTransactor: TaikoL2ClientTransactor{contract: contract}, TaikoL2ClientFilterer: TaikoL2ClientFilterer{contract: contract}}, nil +} + +// NewTaikoL2ClientCaller creates a new read-only instance of TaikoL2Client, bound to a specific deployed contract. +func NewTaikoL2ClientCaller(address common.Address, caller bind.ContractCaller) (*TaikoL2ClientCaller, error) { + contract, err := bindTaikoL2Client(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TaikoL2ClientCaller{contract: contract}, nil +} + +// NewTaikoL2ClientTransactor creates a new write-only instance of TaikoL2Client, bound to a specific deployed contract. +func NewTaikoL2ClientTransactor(address common.Address, transactor bind.ContractTransactor) (*TaikoL2ClientTransactor, error) { + contract, err := bindTaikoL2Client(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TaikoL2ClientTransactor{contract: contract}, nil +} + +// NewTaikoL2ClientFilterer creates a new log filterer instance of TaikoL2Client, bound to a specific deployed contract. +func NewTaikoL2ClientFilterer(address common.Address, filterer bind.ContractFilterer) (*TaikoL2ClientFilterer, error) { + contract, err := bindTaikoL2Client(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TaikoL2ClientFilterer{contract: contract}, nil +} + +// bindTaikoL2Client binds a generic wrapper to an already deployed contract. +func bindTaikoL2Client(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TaikoL2ClientMetaData.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 (_TaikoL2Client *TaikoL2ClientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoL2Client.Contract.TaikoL2ClientCaller.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 (_TaikoL2Client *TaikoL2ClientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.Contract.TaikoL2ClientTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoL2Client *TaikoL2ClientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoL2Client.Contract.TaikoL2ClientTransactor.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 (_TaikoL2Client *TaikoL2ClientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoL2Client.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 (_TaikoL2Client *TaikoL2ClientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoL2Client *TaikoL2ClientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoL2Client.Contract.contract.Transact(opts, method, params...) +} + +// GOLDENTOUCHADDRESS is a free data retrieval call binding the contract method 0x9ee512f2. +// +// Solidity: function GOLDEN_TOUCH_ADDRESS() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) GOLDENTOUCHADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "GOLDEN_TOUCH_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GOLDENTOUCHADDRESS is a free data retrieval call binding the contract method 0x9ee512f2. +// +// Solidity: function GOLDEN_TOUCH_ADDRESS() view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) GOLDENTOUCHADDRESS() (common.Address, error) { + return _TaikoL2Client.Contract.GOLDENTOUCHADDRESS(&_TaikoL2Client.CallOpts) +} + +// GOLDENTOUCHADDRESS is a free data retrieval call binding the contract method 0x9ee512f2. +// +// Solidity: function GOLDEN_TOUCH_ADDRESS() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) GOLDENTOUCHADDRESS() (common.Address, error) { + return _TaikoL2Client.Contract.GOLDENTOUCHADDRESS(&_TaikoL2Client.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) AddressManager() (common.Address, error) { + return _TaikoL2Client.Contract.AddressManager(&_TaikoL2Client.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) AddressManager() (common.Address, error) { + return _TaikoL2Client.Contract.AddressManager(&_TaikoL2Client.CallOpts) +} + +// GasExcess is a free data retrieval call binding the contract method 0xf535bd56. +// +// Solidity: function gasExcess() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCaller) GasExcess(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "gasExcess") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GasExcess is a free data retrieval call binding the contract method 0xf535bd56. +// +// Solidity: function gasExcess() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientSession) GasExcess() (uint64, error) { + return _TaikoL2Client.Contract.GasExcess(&_TaikoL2Client.CallOpts) +} + +// GasExcess is a free data retrieval call binding the contract method 0xf535bd56. +// +// Solidity: function gasExcess() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCallerSession) GasExcess() (uint64, error) { + return _TaikoL2Client.Contract.GasExcess(&_TaikoL2Client.CallOpts) +} + +// GetBasefee is a free data retrieval call binding the contract method 0xa7e022d1. +// +// Solidity: function getBasefee(uint64 _l1BlockId, uint32 _parentGasUsed) view returns(uint256 basefee_, uint64 gasExcess_) +func (_TaikoL2Client *TaikoL2ClientCaller) GetBasefee(opts *bind.CallOpts, _l1BlockId uint64, _parentGasUsed uint32) (struct { + Basefee *big.Int + GasExcess uint64 +}, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "getBasefee", _l1BlockId, _parentGasUsed) + + outstruct := new(struct { + Basefee *big.Int + GasExcess uint64 + }) + if err != nil { + return *outstruct, err + } + + outstruct.Basefee = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.GasExcess = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +// GetBasefee is a free data retrieval call binding the contract method 0xa7e022d1. +// +// Solidity: function getBasefee(uint64 _l1BlockId, uint32 _parentGasUsed) view returns(uint256 basefee_, uint64 gasExcess_) +func (_TaikoL2Client *TaikoL2ClientSession) GetBasefee(_l1BlockId uint64, _parentGasUsed uint32) (struct { + Basefee *big.Int + GasExcess uint64 +}, error) { + return _TaikoL2Client.Contract.GetBasefee(&_TaikoL2Client.CallOpts, _l1BlockId, _parentGasUsed) +} + +// GetBasefee is a free data retrieval call binding the contract method 0xa7e022d1. +// +// Solidity: function getBasefee(uint64 _l1BlockId, uint32 _parentGasUsed) view returns(uint256 basefee_, uint64 gasExcess_) +func (_TaikoL2Client *TaikoL2ClientCallerSession) GetBasefee(_l1BlockId uint64, _parentGasUsed uint32) (struct { + Basefee *big.Int + GasExcess uint64 +}, error) { + return _TaikoL2Client.Contract.GetBasefee(&_TaikoL2Client.CallOpts, _l1BlockId, _parentGasUsed) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0x23ac7136. +// +// Solidity: function getBlockHash(uint64 _blockId) view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCaller) GetBlockHash(opts *bind.CallOpts, _blockId uint64) ([32]byte, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "getBlockHash", _blockId) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockHash is a free data retrieval call binding the contract method 0x23ac7136. +// +// Solidity: function getBlockHash(uint64 _blockId) view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientSession) GetBlockHash(_blockId uint64) ([32]byte, error) { + return _TaikoL2Client.Contract.GetBlockHash(&_TaikoL2Client.CallOpts, _blockId) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0x23ac7136. +// +// Solidity: function getBlockHash(uint64 _blockId) view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCallerSession) GetBlockHash(_blockId uint64) ([32]byte, error) { + return _TaikoL2Client.Contract.GetBlockHash(&_TaikoL2Client.CallOpts, _blockId) +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint32,uint8,uint64)) +func (_TaikoL2Client *TaikoL2ClientCaller) GetConfig(opts *bind.CallOpts) (LibL2ConfigConfig, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "getConfig") + + if err != nil { + return *new(LibL2ConfigConfig), err + } + + out0 := *abi.ConvertType(out[0], new(LibL2ConfigConfig)).(*LibL2ConfigConfig) + + return out0, err + +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint32,uint8,uint64)) +func (_TaikoL2Client *TaikoL2ClientSession) GetConfig() (LibL2ConfigConfig, error) { + return _TaikoL2Client.Contract.GetConfig(&_TaikoL2Client.CallOpts) +} + +// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4. +// +// Solidity: function getConfig() view returns((uint32,uint8,uint64)) +func (_TaikoL2Client *TaikoL2ClientCallerSession) GetConfig() (LibL2ConfigConfig, error) { + return _TaikoL2Client.Contract.GetConfig(&_TaikoL2Client.CallOpts) +} + +// L1ChainId is a free data retrieval call binding the contract method 0x12622e5b. +// +// Solidity: function l1ChainId() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCaller) L1ChainId(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "l1ChainId") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// L1ChainId is a free data retrieval call binding the contract method 0x12622e5b. +// +// Solidity: function l1ChainId() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientSession) L1ChainId() (uint64, error) { + return _TaikoL2Client.Contract.L1ChainId(&_TaikoL2Client.CallOpts) +} + +// L1ChainId is a free data retrieval call binding the contract method 0x12622e5b. +// +// Solidity: function l1ChainId() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCallerSession) L1ChainId() (uint64, error) { + return _TaikoL2Client.Contract.L1ChainId(&_TaikoL2Client.CallOpts) +} + +// L2Hashes is a free data retrieval call binding the contract method 0x8551f41e. +// +// Solidity: function l2Hashes(uint256 blockId) view returns(bytes32 blockHash) +func (_TaikoL2Client *TaikoL2ClientCaller) L2Hashes(opts *bind.CallOpts, blockId *big.Int) ([32]byte, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "l2Hashes", blockId) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// L2Hashes is a free data retrieval call binding the contract method 0x8551f41e. +// +// Solidity: function l2Hashes(uint256 blockId) view returns(bytes32 blockHash) +func (_TaikoL2Client *TaikoL2ClientSession) L2Hashes(blockId *big.Int) ([32]byte, error) { + return _TaikoL2Client.Contract.L2Hashes(&_TaikoL2Client.CallOpts, blockId) +} + +// L2Hashes is a free data retrieval call binding the contract method 0x8551f41e. +// +// Solidity: function l2Hashes(uint256 blockId) view returns(bytes32 blockHash) +func (_TaikoL2Client *TaikoL2ClientCallerSession) L2Hashes(blockId *big.Int) ([32]byte, error) { + return _TaikoL2Client.Contract.L2Hashes(&_TaikoL2Client.CallOpts, blockId) +} + +// LastSyncedBlock is a free data retrieval call binding the contract method 0x33d5ac9b. +// +// Solidity: function lastSyncedBlock() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCaller) LastSyncedBlock(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "lastSyncedBlock") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastSyncedBlock is a free data retrieval call binding the contract method 0x33d5ac9b. +// +// Solidity: function lastSyncedBlock() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientSession) LastSyncedBlock() (uint64, error) { + return _TaikoL2Client.Contract.LastSyncedBlock(&_TaikoL2Client.CallOpts) +} + +// LastSyncedBlock is a free data retrieval call binding the contract method 0x33d5ac9b. +// +// Solidity: function lastSyncedBlock() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCallerSession) LastSyncedBlock() (uint64, error) { + return _TaikoL2Client.Contract.LastSyncedBlock(&_TaikoL2Client.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientSession) LastUnpausedAt() (uint64, error) { + return _TaikoL2Client.Contract.LastUnpausedAt(&_TaikoL2Client.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCallerSession) LastUnpausedAt() (uint64, error) { + return _TaikoL2Client.Contract.LastUnpausedAt(&_TaikoL2Client.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) Owner() (common.Address, error) { + return _TaikoL2Client.Contract.Owner(&_TaikoL2Client.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) Owner() (common.Address, error) { + return _TaikoL2Client.Contract.Owner(&_TaikoL2Client.CallOpts) +} + +// ParentTimestamp is a free data retrieval call binding the contract method 0x539b8ade. +// +// Solidity: function parentTimestamp() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCaller) ParentTimestamp(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "parentTimestamp") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ParentTimestamp is a free data retrieval call binding the contract method 0x539b8ade. +// +// Solidity: function parentTimestamp() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientSession) ParentTimestamp() (uint64, error) { + return _TaikoL2Client.Contract.ParentTimestamp(&_TaikoL2Client.CallOpts) +} + +// ParentTimestamp is a free data retrieval call binding the contract method 0x539b8ade. +// +// Solidity: function parentTimestamp() view returns(uint64) +func (_TaikoL2Client *TaikoL2ClientCallerSession) ParentTimestamp() (uint64, error) { + return _TaikoL2Client.Contract.ParentTimestamp(&_TaikoL2Client.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL2Client *TaikoL2ClientCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL2Client *TaikoL2ClientSession) Paused() (bool, error) { + return _TaikoL2Client.Contract.Paused(&_TaikoL2Client.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoL2Client *TaikoL2ClientCallerSession) Paused() (bool, error) { + return _TaikoL2Client.Contract.Paused(&_TaikoL2Client.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) PendingOwner() (common.Address, error) { + return _TaikoL2Client.Contract.PendingOwner(&_TaikoL2Client.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) PendingOwner() (common.Address, error) { + return _TaikoL2Client.Contract.PendingOwner(&_TaikoL2Client.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientSession) ProxiableUUID() ([32]byte, error) { + return _TaikoL2Client.Contract.ProxiableUUID(&_TaikoL2Client.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCallerSession) ProxiableUUID() ([32]byte, error) { + return _TaikoL2Client.Contract.ProxiableUUID(&_TaikoL2Client.CallOpts) +} + +// PublicInputHash is a free data retrieval call binding the contract method 0xdac5df78. +// +// Solidity: function publicInputHash() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCaller) PublicInputHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "publicInputHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PublicInputHash is a free data retrieval call binding the contract method 0xdac5df78. +// +// Solidity: function publicInputHash() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientSession) PublicInputHash() ([32]byte, error) { + return _TaikoL2Client.Contract.PublicInputHash(&_TaikoL2Client.CallOpts) +} + +// PublicInputHash is a free data retrieval call binding the contract method 0xdac5df78. +// +// Solidity: function publicInputHash() view returns(bytes32) +func (_TaikoL2Client *TaikoL2ClientCallerSession) PublicInputHash() ([32]byte, error) { + return _TaikoL2Client.Contract.PublicInputHash(&_TaikoL2Client.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL2Client.Contract.Resolve(&_TaikoL2Client.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL2Client.Contract.Resolve(&_TaikoL2Client.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL2Client.Contract.Resolve0(&_TaikoL2Client.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoL2Client *TaikoL2ClientCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoL2Client.Contract.Resolve0(&_TaikoL2Client.CallOpts, _name, _allowZeroAddress) +} + +// SkipFeeCheck is a free data retrieval call binding the contract method 0x2f980473. +// +// Solidity: function skipFeeCheck() pure returns(bool) +func (_TaikoL2Client *TaikoL2ClientCaller) SkipFeeCheck(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TaikoL2Client.contract.Call(opts, &out, "skipFeeCheck") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SkipFeeCheck is a free data retrieval call binding the contract method 0x2f980473. +// +// Solidity: function skipFeeCheck() pure returns(bool) +func (_TaikoL2Client *TaikoL2ClientSession) SkipFeeCheck() (bool, error) { + return _TaikoL2Client.Contract.SkipFeeCheck(&_TaikoL2Client.CallOpts) +} + +// SkipFeeCheck is a free data retrieval call binding the contract method 0x2f980473. +// +// Solidity: function skipFeeCheck() pure returns(bool) +func (_TaikoL2Client *TaikoL2ClientCallerSession) SkipFeeCheck() (bool, error) { + return _TaikoL2Client.Contract.SkipFeeCheck(&_TaikoL2Client.CallOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoL2Client.Contract.AcceptOwnership(&_TaikoL2Client.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoL2Client.Contract.AcceptOwnership(&_TaikoL2Client.TransactOpts) +} + +// Anchor is a paid mutator transaction binding the contract method 0xda69d3db. +// +// Solidity: function anchor(bytes32 _l1BlockHash, bytes32 _l1StateRoot, uint64 _l1BlockId, uint32 _parentGasUsed) returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) Anchor(opts *bind.TransactOpts, _l1BlockHash [32]byte, _l1StateRoot [32]byte, _l1BlockId uint64, _parentGasUsed uint32) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "anchor", _l1BlockHash, _l1StateRoot, _l1BlockId, _parentGasUsed) +} + +// Anchor is a paid mutator transaction binding the contract method 0xda69d3db. +// +// Solidity: function anchor(bytes32 _l1BlockHash, bytes32 _l1StateRoot, uint64 _l1BlockId, uint32 _parentGasUsed) returns() +func (_TaikoL2Client *TaikoL2ClientSession) Anchor(_l1BlockHash [32]byte, _l1StateRoot [32]byte, _l1BlockId uint64, _parentGasUsed uint32) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Anchor(&_TaikoL2Client.TransactOpts, _l1BlockHash, _l1StateRoot, _l1BlockId, _parentGasUsed) +} + +// Anchor is a paid mutator transaction binding the contract method 0xda69d3db. +// +// Solidity: function anchor(bytes32 _l1BlockHash, bytes32 _l1StateRoot, uint64 _l1BlockId, uint32 _parentGasUsed) returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) Anchor(_l1BlockHash [32]byte, _l1StateRoot [32]byte, _l1BlockId uint64, _parentGasUsed uint32) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Anchor(&_TaikoL2Client.TransactOpts, _l1BlockHash, _l1StateRoot, _l1BlockId, _parentGasUsed) +} + +// Init is a paid mutator transaction binding the contract method 0x5950f9f1. +// +// Solidity: function init(address _owner, address _addressManager, uint64 _l1ChainId, uint64 _gasExcess) returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _addressManager common.Address, _l1ChainId uint64, _gasExcess uint64) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "init", _owner, _addressManager, _l1ChainId, _gasExcess) +} + +// Init is a paid mutator transaction binding the contract method 0x5950f9f1. +// +// Solidity: function init(address _owner, address _addressManager, uint64 _l1ChainId, uint64 _gasExcess) returns() +func (_TaikoL2Client *TaikoL2ClientSession) Init(_owner common.Address, _addressManager common.Address, _l1ChainId uint64, _gasExcess uint64) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Init(&_TaikoL2Client.TransactOpts, _owner, _addressManager, _l1ChainId, _gasExcess) +} + +// Init is a paid mutator transaction binding the contract method 0x5950f9f1. +// +// Solidity: function init(address _owner, address _addressManager, uint64 _l1ChainId, uint64 _gasExcess) returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) Init(_owner common.Address, _addressManager common.Address, _l1ChainId uint64, _gasExcess uint64) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Init(&_TaikoL2Client.TransactOpts, _owner, _addressManager, _l1ChainId, _gasExcess) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL2Client *TaikoL2ClientSession) Pause() (*types.Transaction, error) { + return _TaikoL2Client.Contract.Pause(&_TaikoL2Client.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) Pause() (*types.Transaction, error) { + return _TaikoL2Client.Contract.Pause(&_TaikoL2Client.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoL2Client.Contract.RenounceOwnership(&_TaikoL2Client.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoL2Client.Contract.RenounceOwnership(&_TaikoL2Client.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL2Client *TaikoL2ClientSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.TransferOwnership(&_TaikoL2Client.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.TransferOwnership(&_TaikoL2Client.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL2Client *TaikoL2ClientSession) Unpause() (*types.Transaction, error) { + return _TaikoL2Client.Contract.Unpause(&_TaikoL2Client.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) Unpause() (*types.Transaction, error) { + return _TaikoL2Client.Contract.Unpause(&_TaikoL2Client.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL2Client *TaikoL2ClientSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.UpgradeTo(&_TaikoL2Client.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.UpgradeTo(&_TaikoL2Client.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL2Client *TaikoL2ClientSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL2Client.Contract.UpgradeToAndCall(&_TaikoL2Client.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoL2Client.Contract.UpgradeToAndCall(&_TaikoL2Client.TransactOpts, newImplementation, data) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf940e385. +// +// Solidity: function withdraw(address _token, address _to) returns() +func (_TaikoL2Client *TaikoL2ClientTransactor) Withdraw(opts *bind.TransactOpts, _token common.Address, _to common.Address) (*types.Transaction, error) { + return _TaikoL2Client.contract.Transact(opts, "withdraw", _token, _to) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf940e385. +// +// Solidity: function withdraw(address _token, address _to) returns() +func (_TaikoL2Client *TaikoL2ClientSession) Withdraw(_token common.Address, _to common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Withdraw(&_TaikoL2Client.TransactOpts, _token, _to) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf940e385. +// +// Solidity: function withdraw(address _token, address _to) returns() +func (_TaikoL2Client *TaikoL2ClientTransactorSession) Withdraw(_token common.Address, _to common.Address) (*types.Transaction, error) { + return _TaikoL2Client.Contract.Withdraw(&_TaikoL2Client.TransactOpts, _token, _to) +} + +// TaikoL2ClientAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TaikoL2Client contract. +type TaikoL2ClientAdminChangedIterator struct { + Event *TaikoL2ClientAdminChanged // 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 *TaikoL2ClientAdminChangedIterator) 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(TaikoL2ClientAdminChanged) + 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(TaikoL2ClientAdminChanged) + 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 *TaikoL2ClientAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientAdminChanged represents a AdminChanged event raised by the TaikoL2Client contract. +type TaikoL2ClientAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TaikoL2ClientAdminChangedIterator, error) { + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TaikoL2ClientAdminChangedIterator{contract: _TaikoL2Client.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "AdminChanged") + 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(TaikoL2ClientAdminChanged) + if err := _TaikoL2Client.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseAdminChanged(log types.Log) (*TaikoL2ClientAdminChanged, error) { + event := new(TaikoL2ClientAdminChanged) + if err := _TaikoL2Client.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientAnchoredIterator is returned from FilterAnchored and is used to iterate over the raw logs and unpacked data for Anchored events raised by the TaikoL2Client contract. +type TaikoL2ClientAnchoredIterator struct { + Event *TaikoL2ClientAnchored // 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 *TaikoL2ClientAnchoredIterator) 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(TaikoL2ClientAnchored) + 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(TaikoL2ClientAnchored) + 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 *TaikoL2ClientAnchoredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientAnchoredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientAnchored represents a Anchored event raised by the TaikoL2Client contract. +type TaikoL2ClientAnchored struct { + ParentHash [32]byte + GasExcess uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAnchored is a free log retrieval operation binding the contract event 0x41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4. +// +// Solidity: event Anchored(bytes32 parentHash, uint64 gasExcess) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterAnchored(opts *bind.FilterOpts) (*TaikoL2ClientAnchoredIterator, error) { + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "Anchored") + if err != nil { + return nil, err + } + return &TaikoL2ClientAnchoredIterator{contract: _TaikoL2Client.contract, event: "Anchored", logs: logs, sub: sub}, nil +} + +// WatchAnchored is a free log subscription operation binding the contract event 0x41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4. +// +// Solidity: event Anchored(bytes32 parentHash, uint64 gasExcess) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchAnchored(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientAnchored) (event.Subscription, error) { + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "Anchored") + 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(TaikoL2ClientAnchored) + if err := _TaikoL2Client.contract.UnpackLog(event, "Anchored", 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 +} + +// ParseAnchored is a log parse operation binding the contract event 0x41c3f410f5c8ac36bb46b1dccef0de0f964087c9e688795fa02ecfa2c20b3fe4. +// +// Solidity: event Anchored(bytes32 parentHash, uint64 gasExcess) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseAnchored(log types.Log) (*TaikoL2ClientAnchored, error) { + event := new(TaikoL2ClientAnchored) + if err := _TaikoL2Client.contract.UnpackLog(event, "Anchored", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the TaikoL2Client contract. +type TaikoL2ClientBeaconUpgradedIterator struct { + Event *TaikoL2ClientBeaconUpgraded // 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 *TaikoL2ClientBeaconUpgradedIterator) 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(TaikoL2ClientBeaconUpgraded) + 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(TaikoL2ClientBeaconUpgraded) + 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 *TaikoL2ClientBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientBeaconUpgraded represents a BeaconUpgraded event raised by the TaikoL2Client contract. +type TaikoL2ClientBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*TaikoL2ClientBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &TaikoL2ClientBeaconUpgradedIterator{contract: _TaikoL2Client.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(TaikoL2ClientBeaconUpgraded) + if err := _TaikoL2Client.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseBeaconUpgraded(log types.Log) (*TaikoL2ClientBeaconUpgraded, error) { + event := new(TaikoL2ClientBeaconUpgraded) + if err := _TaikoL2Client.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TaikoL2Client contract. +type TaikoL2ClientInitializedIterator struct { + Event *TaikoL2ClientInitialized // 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 *TaikoL2ClientInitializedIterator) 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(TaikoL2ClientInitialized) + 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(TaikoL2ClientInitialized) + 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 *TaikoL2ClientInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientInitialized represents a Initialized event raised by the TaikoL2Client contract. +type TaikoL2ClientInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterInitialized(opts *bind.FilterOpts) (*TaikoL2ClientInitializedIterator, error) { + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TaikoL2ClientInitializedIterator{contract: _TaikoL2Client.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientInitialized) (event.Subscription, error) { + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "Initialized") + 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(TaikoL2ClientInitialized) + if err := _TaikoL2Client.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseInitialized(log types.Log) (*TaikoL2ClientInitialized, error) { + event := new(TaikoL2ClientInitialized) + if err := _TaikoL2Client.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the TaikoL2Client contract. +type TaikoL2ClientOwnershipTransferStartedIterator struct { + Event *TaikoL2ClientOwnershipTransferStarted // 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 *TaikoL2ClientOwnershipTransferStartedIterator) 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(TaikoL2ClientOwnershipTransferStarted) + 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(TaikoL2ClientOwnershipTransferStarted) + 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 *TaikoL2ClientOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the TaikoL2Client contract. +type TaikoL2ClientOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoL2ClientOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoL2ClientOwnershipTransferStartedIterator{contract: _TaikoL2Client.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(TaikoL2ClientOwnershipTransferStarted) + if err := _TaikoL2Client.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseOwnershipTransferStarted(log types.Log) (*TaikoL2ClientOwnershipTransferStarted, error) { + event := new(TaikoL2ClientOwnershipTransferStarted) + if err := _TaikoL2Client.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TaikoL2Client contract. +type TaikoL2ClientOwnershipTransferredIterator struct { + Event *TaikoL2ClientOwnershipTransferred // 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 *TaikoL2ClientOwnershipTransferredIterator) 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(TaikoL2ClientOwnershipTransferred) + 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(TaikoL2ClientOwnershipTransferred) + 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 *TaikoL2ClientOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientOwnershipTransferred represents a OwnershipTransferred event raised by the TaikoL2Client contract. +type TaikoL2ClientOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoL2ClientOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoL2ClientOwnershipTransferredIterator{contract: _TaikoL2Client.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(TaikoL2ClientOwnershipTransferred) + if err := _TaikoL2Client.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseOwnershipTransferred(log types.Log) (*TaikoL2ClientOwnershipTransferred, error) { + event := new(TaikoL2ClientOwnershipTransferred) + if err := _TaikoL2Client.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the TaikoL2Client contract. +type TaikoL2ClientPausedIterator struct { + Event *TaikoL2ClientPaused // 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 *TaikoL2ClientPausedIterator) 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(TaikoL2ClientPaused) + 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(TaikoL2ClientPaused) + 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 *TaikoL2ClientPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientPaused represents a Paused event raised by the TaikoL2Client contract. +type TaikoL2ClientPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterPaused(opts *bind.FilterOpts) (*TaikoL2ClientPausedIterator, error) { + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &TaikoL2ClientPausedIterator{contract: _TaikoL2Client.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientPaused) (event.Subscription, error) { + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "Paused") + 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(TaikoL2ClientPaused) + if err := _TaikoL2Client.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParsePaused(log types.Log) (*TaikoL2ClientPaused, error) { + event := new(TaikoL2ClientPaused) + if err := _TaikoL2Client.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the TaikoL2Client contract. +type TaikoL2ClientUnpausedIterator struct { + Event *TaikoL2ClientUnpaused // 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 *TaikoL2ClientUnpausedIterator) 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(TaikoL2ClientUnpaused) + 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(TaikoL2ClientUnpaused) + 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 *TaikoL2ClientUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientUnpaused represents a Unpaused event raised by the TaikoL2Client contract. +type TaikoL2ClientUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterUnpaused(opts *bind.FilterOpts) (*TaikoL2ClientUnpausedIterator, error) { + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &TaikoL2ClientUnpausedIterator{contract: _TaikoL2Client.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientUnpaused) (event.Subscription, error) { + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "Unpaused") + 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(TaikoL2ClientUnpaused) + if err := _TaikoL2Client.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseUnpaused(log types.Log) (*TaikoL2ClientUnpaused, error) { + event := new(TaikoL2ClientUnpaused) + if err := _TaikoL2Client.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoL2ClientUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TaikoL2Client contract. +type TaikoL2ClientUpgradedIterator struct { + Event *TaikoL2ClientUpgraded // 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 *TaikoL2ClientUpgradedIterator) 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(TaikoL2ClientUpgraded) + 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(TaikoL2ClientUpgraded) + 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 *TaikoL2ClientUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoL2ClientUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoL2ClientUpgraded represents a Upgraded event raised by the TaikoL2Client contract. +type TaikoL2ClientUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL2Client *TaikoL2ClientFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TaikoL2ClientUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoL2Client.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TaikoL2ClientUpgradedIterator{contract: _TaikoL2Client.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL2Client *TaikoL2ClientFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoL2ClientUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoL2Client.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(TaikoL2ClientUpgraded) + if err := _TaikoL2Client.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoL2Client *TaikoL2ClientFilterer) ParseUpgraded(log types.Log) (*TaikoL2ClientUpgraded, error) { + event := new(TaikoL2ClientUpgraded) + if err := _TaikoL2Client.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_taiko_token.go b/packages/taiko-client/bindings/gen_taiko_token.go new file mode 100644 index 00000000000..37c614bf729 --- /dev/null +++ b/packages/taiko-client/bindings/gen_taiko_token.go @@ -0,0 +1,3238 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// ERC20VotesUpgradeableCheckpoint is an auto generated low-level Go binding around an user-defined struct. +type ERC20VotesUpgradeableCheckpoint struct { + FromBlock uint32 + Votes *big.Int +} + +// TaikoTokenMetaData contains all meta data concerning the TaikoToken contract. +var TaikoTokenMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"CLOCK_MODE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"DOMAIN_SEPARATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burn\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"checkpoints\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"pos\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structERC20VotesUpgradeable.Checkpoint\",\"components\":[{\"name\":\"fromBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"votes\",\"type\":\"uint224\",\"internalType\":\"uint224\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"clock\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint48\",\"internalType\":\"uint48\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decreaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"subtractedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegate\",\"inputs\":[{\"name\":\"delegatee\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegateBySig\",\"inputs\":[{\"name\":\"delegatee\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegates\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eip712Domain\",\"inputs\":[],\"outputs\":[{\"name\":\"fields\",\"type\":\"bytes1\",\"internalType\":\"bytes1\"},{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"chainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"verifyingContract\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"extensions\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPastTotalSupply\",\"inputs\":[{\"name\":\"timepoint\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPastVotes\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"timepoint\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getVotes\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"increaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"addedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nonces\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"numCheckpoints\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"permit\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"deadline\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegateChanged\",\"inputs\":[{\"name\":\"delegator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"fromDelegate\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"toDelegate\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegateVotesChanged\",\"inputs\":[{\"name\":\"delegate\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"previousBalance\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newBalance\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EIP712DomainChanged\",\"inputs\":[],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"TKO_INVALID_ADDR\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// TaikoTokenABI is the input ABI used to generate the binding from. +// Deprecated: Use TaikoTokenMetaData.ABI instead. +var TaikoTokenABI = TaikoTokenMetaData.ABI + +// TaikoToken is an auto generated Go binding around an Ethereum contract. +type TaikoToken struct { + TaikoTokenCaller // Read-only binding to the contract + TaikoTokenTransactor // Write-only binding to the contract + TaikoTokenFilterer // Log filterer for contract events +} + +// TaikoTokenCaller is an auto generated read-only Go binding around an Ethereum contract. +type TaikoTokenCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoTokenTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TaikoTokenTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoTokenFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TaikoTokenFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TaikoTokenSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TaikoTokenSession struct { + Contract *TaikoToken // 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 +} + +// TaikoTokenCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TaikoTokenCallerSession struct { + Contract *TaikoTokenCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TaikoTokenTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TaikoTokenTransactorSession struct { + Contract *TaikoTokenTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TaikoTokenRaw is an auto generated low-level Go binding around an Ethereum contract. +type TaikoTokenRaw struct { + Contract *TaikoToken // Generic contract binding to access the raw methods on +} + +// TaikoTokenCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TaikoTokenCallerRaw struct { + Contract *TaikoTokenCaller // Generic read-only contract binding to access the raw methods on +} + +// TaikoTokenTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TaikoTokenTransactorRaw struct { + Contract *TaikoTokenTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTaikoToken creates a new instance of TaikoToken, bound to a specific deployed contract. +func NewTaikoToken(address common.Address, backend bind.ContractBackend) (*TaikoToken, error) { + contract, err := bindTaikoToken(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TaikoToken{TaikoTokenCaller: TaikoTokenCaller{contract: contract}, TaikoTokenTransactor: TaikoTokenTransactor{contract: contract}, TaikoTokenFilterer: TaikoTokenFilterer{contract: contract}}, nil +} + +// NewTaikoTokenCaller creates a new read-only instance of TaikoToken, bound to a specific deployed contract. +func NewTaikoTokenCaller(address common.Address, caller bind.ContractCaller) (*TaikoTokenCaller, error) { + contract, err := bindTaikoToken(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TaikoTokenCaller{contract: contract}, nil +} + +// NewTaikoTokenTransactor creates a new write-only instance of TaikoToken, bound to a specific deployed contract. +func NewTaikoTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*TaikoTokenTransactor, error) { + contract, err := bindTaikoToken(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TaikoTokenTransactor{contract: contract}, nil +} + +// NewTaikoTokenFilterer creates a new log filterer instance of TaikoToken, bound to a specific deployed contract. +func NewTaikoTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*TaikoTokenFilterer, error) { + contract, err := bindTaikoToken(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TaikoTokenFilterer{contract: contract}, nil +} + +// bindTaikoToken binds a generic wrapper to an already deployed contract. +func bindTaikoToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TaikoTokenMetaData.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 (_TaikoToken *TaikoTokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoToken.Contract.TaikoTokenCaller.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 (_TaikoToken *TaikoTokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.Contract.TaikoTokenTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoToken *TaikoTokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoToken.Contract.TaikoTokenTransactor.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 (_TaikoToken *TaikoTokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TaikoToken.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 (_TaikoToken *TaikoTokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TaikoToken *TaikoTokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TaikoToken.Contract.contract.Transact(opts, method, params...) +} + +// CLOCKMODE is a free data retrieval call binding the contract method 0x4bf5d7e9. +// +// Solidity: function CLOCK_MODE() pure returns(string) +func (_TaikoToken *TaikoTokenCaller) CLOCKMODE(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "CLOCK_MODE") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// CLOCKMODE is a free data retrieval call binding the contract method 0x4bf5d7e9. +// +// Solidity: function CLOCK_MODE() pure returns(string) +func (_TaikoToken *TaikoTokenSession) CLOCKMODE() (string, error) { + return _TaikoToken.Contract.CLOCKMODE(&_TaikoToken.CallOpts) +} + +// CLOCKMODE is a free data retrieval call binding the contract method 0x4bf5d7e9. +// +// Solidity: function CLOCK_MODE() pure returns(string) +func (_TaikoToken *TaikoTokenCallerSession) CLOCKMODE() (string, error) { + return _TaikoToken.Contract.CLOCKMODE(&_TaikoToken.CallOpts) +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_TaikoToken *TaikoTokenCaller) DOMAINSEPARATOR(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "DOMAIN_SEPARATOR") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_TaikoToken *TaikoTokenSession) DOMAINSEPARATOR() ([32]byte, error) { + return _TaikoToken.Contract.DOMAINSEPARATOR(&_TaikoToken.CallOpts) +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_TaikoToken *TaikoTokenCallerSession) DOMAINSEPARATOR() ([32]byte, error) { + return _TaikoToken.Contract.DOMAINSEPARATOR(&_TaikoToken.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoToken *TaikoTokenCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoToken *TaikoTokenSession) AddressManager() (common.Address, error) { + return _TaikoToken.Contract.AddressManager(&_TaikoToken.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) AddressManager() (common.Address, error) { + return _TaikoToken.Contract.AddressManager(&_TaikoToken.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TaikoToken.Contract.Allowance(&_TaikoToken.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 (_TaikoToken *TaikoTokenCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TaikoToken.Contract.Allowance(&_TaikoToken.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) BalanceOf(account common.Address) (*big.Int, error) { + return _TaikoToken.Contract.BalanceOf(&_TaikoToken.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _TaikoToken.Contract.BalanceOf(&_TaikoToken.CallOpts, account) +} + +// Checkpoints is a free data retrieval call binding the contract method 0xf1127ed8. +// +// Solidity: function checkpoints(address account, uint32 pos) view returns((uint32,uint224)) +func (_TaikoToken *TaikoTokenCaller) Checkpoints(opts *bind.CallOpts, account common.Address, pos uint32) (ERC20VotesUpgradeableCheckpoint, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "checkpoints", account, pos) + + if err != nil { + return *new(ERC20VotesUpgradeableCheckpoint), err + } + + out0 := *abi.ConvertType(out[0], new(ERC20VotesUpgradeableCheckpoint)).(*ERC20VotesUpgradeableCheckpoint) + + return out0, err + +} + +// Checkpoints is a free data retrieval call binding the contract method 0xf1127ed8. +// +// Solidity: function checkpoints(address account, uint32 pos) view returns((uint32,uint224)) +func (_TaikoToken *TaikoTokenSession) Checkpoints(account common.Address, pos uint32) (ERC20VotesUpgradeableCheckpoint, error) { + return _TaikoToken.Contract.Checkpoints(&_TaikoToken.CallOpts, account, pos) +} + +// Checkpoints is a free data retrieval call binding the contract method 0xf1127ed8. +// +// Solidity: function checkpoints(address account, uint32 pos) view returns((uint32,uint224)) +func (_TaikoToken *TaikoTokenCallerSession) Checkpoints(account common.Address, pos uint32) (ERC20VotesUpgradeableCheckpoint, error) { + return _TaikoToken.Contract.Checkpoints(&_TaikoToken.CallOpts, account, pos) +} + +// Clock is a free data retrieval call binding the contract method 0x91ddadf4. +// +// Solidity: function clock() view returns(uint48) +func (_TaikoToken *TaikoTokenCaller) Clock(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "clock") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Clock is a free data retrieval call binding the contract method 0x91ddadf4. +// +// Solidity: function clock() view returns(uint48) +func (_TaikoToken *TaikoTokenSession) Clock() (*big.Int, error) { + return _TaikoToken.Contract.Clock(&_TaikoToken.CallOpts) +} + +// Clock is a free data retrieval call binding the contract method 0x91ddadf4. +// +// Solidity: function clock() view returns(uint48) +func (_TaikoToken *TaikoTokenCallerSession) Clock() (*big.Int, error) { + return _TaikoToken.Contract.Clock(&_TaikoToken.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TaikoToken *TaikoTokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) Decimals() (uint8, error) { + return _TaikoToken.Contract.Decimals(&_TaikoToken.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TaikoToken *TaikoTokenCallerSession) Decimals() (uint8, error) { + return _TaikoToken.Contract.Decimals(&_TaikoToken.CallOpts) +} + +// Delegates is a free data retrieval call binding the contract method 0x587cde1e. +// +// Solidity: function delegates(address account) view returns(address) +func (_TaikoToken *TaikoTokenCaller) Delegates(opts *bind.CallOpts, account common.Address) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "delegates", account) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Delegates is a free data retrieval call binding the contract method 0x587cde1e. +// +// Solidity: function delegates(address account) view returns(address) +func (_TaikoToken *TaikoTokenSession) Delegates(account common.Address) (common.Address, error) { + return _TaikoToken.Contract.Delegates(&_TaikoToken.CallOpts, account) +} + +// Delegates is a free data retrieval call binding the contract method 0x587cde1e. +// +// Solidity: function delegates(address account) view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) Delegates(account common.Address) (common.Address, error) { + return _TaikoToken.Contract.Delegates(&_TaikoToken.CallOpts, account) +} + +// Eip712Domain is a free data retrieval call binding the contract method 0x84b0196e. +// +// Solidity: function eip712Domain() view returns(bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions) +func (_TaikoToken *TaikoTokenCaller) Eip712Domain(opts *bind.CallOpts) (struct { + Fields [1]byte + Name string + Version string + ChainId *big.Int + VerifyingContract common.Address + Salt [32]byte + Extensions []*big.Int +}, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "eip712Domain") + + outstruct := new(struct { + Fields [1]byte + Name string + Version string + ChainId *big.Int + VerifyingContract common.Address + Salt [32]byte + Extensions []*big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Fields = *abi.ConvertType(out[0], new([1]byte)).(*[1]byte) + outstruct.Name = *abi.ConvertType(out[1], new(string)).(*string) + outstruct.Version = *abi.ConvertType(out[2], new(string)).(*string) + outstruct.ChainId = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.VerifyingContract = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) + outstruct.Salt = *abi.ConvertType(out[5], new([32]byte)).(*[32]byte) + outstruct.Extensions = *abi.ConvertType(out[6], new([]*big.Int)).(*[]*big.Int) + + return *outstruct, err + +} + +// Eip712Domain is a free data retrieval call binding the contract method 0x84b0196e. +// +// Solidity: function eip712Domain() view returns(bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions) +func (_TaikoToken *TaikoTokenSession) Eip712Domain() (struct { + Fields [1]byte + Name string + Version string + ChainId *big.Int + VerifyingContract common.Address + Salt [32]byte + Extensions []*big.Int +}, error) { + return _TaikoToken.Contract.Eip712Domain(&_TaikoToken.CallOpts) +} + +// Eip712Domain is a free data retrieval call binding the contract method 0x84b0196e. +// +// Solidity: function eip712Domain() view returns(bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions) +func (_TaikoToken *TaikoTokenCallerSession) Eip712Domain() (struct { + Fields [1]byte + Name string + Version string + ChainId *big.Int + VerifyingContract common.Address + Salt [32]byte + Extensions []*big.Int +}, error) { + return _TaikoToken.Contract.Eip712Domain(&_TaikoToken.CallOpts) +} + +// GetPastTotalSupply is a free data retrieval call binding the contract method 0x8e539e8c. +// +// Solidity: function getPastTotalSupply(uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) GetPastTotalSupply(opts *bind.CallOpts, timepoint *big.Int) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "getPastTotalSupply", timepoint) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetPastTotalSupply is a free data retrieval call binding the contract method 0x8e539e8c. +// +// Solidity: function getPastTotalSupply(uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenSession) GetPastTotalSupply(timepoint *big.Int) (*big.Int, error) { + return _TaikoToken.Contract.GetPastTotalSupply(&_TaikoToken.CallOpts, timepoint) +} + +// GetPastTotalSupply is a free data retrieval call binding the contract method 0x8e539e8c. +// +// Solidity: function getPastTotalSupply(uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) GetPastTotalSupply(timepoint *big.Int) (*big.Int, error) { + return _TaikoToken.Contract.GetPastTotalSupply(&_TaikoToken.CallOpts, timepoint) +} + +// GetPastVotes is a free data retrieval call binding the contract method 0x3a46b1a8. +// +// Solidity: function getPastVotes(address account, uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) GetPastVotes(opts *bind.CallOpts, account common.Address, timepoint *big.Int) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "getPastVotes", account, timepoint) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetPastVotes is a free data retrieval call binding the contract method 0x3a46b1a8. +// +// Solidity: function getPastVotes(address account, uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenSession) GetPastVotes(account common.Address, timepoint *big.Int) (*big.Int, error) { + return _TaikoToken.Contract.GetPastVotes(&_TaikoToken.CallOpts, account, timepoint) +} + +// GetPastVotes is a free data retrieval call binding the contract method 0x3a46b1a8. +// +// Solidity: function getPastVotes(address account, uint256 timepoint) view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) GetPastVotes(account common.Address, timepoint *big.Int) (*big.Int, error) { + return _TaikoToken.Contract.GetPastVotes(&_TaikoToken.CallOpts, account, timepoint) +} + +// GetVotes is a free data retrieval call binding the contract method 0x9ab24eb0. +// +// Solidity: function getVotes(address account) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) GetVotes(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "getVotes", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVotes is a free data retrieval call binding the contract method 0x9ab24eb0. +// +// Solidity: function getVotes(address account) view returns(uint256) +func (_TaikoToken *TaikoTokenSession) GetVotes(account common.Address) (*big.Int, error) { + return _TaikoToken.Contract.GetVotes(&_TaikoToken.CallOpts, account) +} + +// GetVotes is a free data retrieval call binding the contract method 0x9ab24eb0. +// +// Solidity: function getVotes(address account) view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) GetVotes(account common.Address) (*big.Int, error) { + return _TaikoToken.Contract.GetVotes(&_TaikoToken.CallOpts, account) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoToken *TaikoTokenCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoToken *TaikoTokenSession) LastUnpausedAt() (uint64, error) { + return _TaikoToken.Contract.LastUnpausedAt(&_TaikoToken.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TaikoToken *TaikoTokenCallerSession) LastUnpausedAt() (uint64, error) { + return _TaikoToken.Contract.LastUnpausedAt(&_TaikoToken.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TaikoToken *TaikoTokenCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) Name() (string, error) { + return _TaikoToken.Contract.Name(&_TaikoToken.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TaikoToken *TaikoTokenCallerSession) Name() (string, error) { + return _TaikoToken.Contract.Name(&_TaikoToken.CallOpts) +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address owner) view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) Nonces(opts *bind.CallOpts, owner common.Address) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "nonces", owner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address owner) view returns(uint256) +func (_TaikoToken *TaikoTokenSession) Nonces(owner common.Address) (*big.Int, error) { + return _TaikoToken.Contract.Nonces(&_TaikoToken.CallOpts, owner) +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address owner) view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) Nonces(owner common.Address) (*big.Int, error) { + return _TaikoToken.Contract.Nonces(&_TaikoToken.CallOpts, owner) +} + +// NumCheckpoints is a free data retrieval call binding the contract method 0x6fcfff45. +// +// Solidity: function numCheckpoints(address account) view returns(uint32) +func (_TaikoToken *TaikoTokenCaller) NumCheckpoints(opts *bind.CallOpts, account common.Address) (uint32, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "numCheckpoints", account) + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// NumCheckpoints is a free data retrieval call binding the contract method 0x6fcfff45. +// +// Solidity: function numCheckpoints(address account) view returns(uint32) +func (_TaikoToken *TaikoTokenSession) NumCheckpoints(account common.Address) (uint32, error) { + return _TaikoToken.Contract.NumCheckpoints(&_TaikoToken.CallOpts, account) +} + +// NumCheckpoints is a free data retrieval call binding the contract method 0x6fcfff45. +// +// Solidity: function numCheckpoints(address account) view returns(uint32) +func (_TaikoToken *TaikoTokenCallerSession) NumCheckpoints(account common.Address) (uint32, error) { + return _TaikoToken.Contract.NumCheckpoints(&_TaikoToken.CallOpts, account) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoToken *TaikoTokenCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoToken *TaikoTokenSession) Owner() (common.Address, error) { + return _TaikoToken.Contract.Owner(&_TaikoToken.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) Owner() (common.Address, error) { + return _TaikoToken.Contract.Owner(&_TaikoToken.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoToken *TaikoTokenCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoToken *TaikoTokenSession) Paused() (bool, error) { + return _TaikoToken.Contract.Paused(&_TaikoToken.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TaikoToken *TaikoTokenCallerSession) Paused() (bool, error) { + return _TaikoToken.Contract.Paused(&_TaikoToken.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoToken *TaikoTokenCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoToken *TaikoTokenSession) PendingOwner() (common.Address, error) { + return _TaikoToken.Contract.PendingOwner(&_TaikoToken.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) PendingOwner() (common.Address, error) { + return _TaikoToken.Contract.PendingOwner(&_TaikoToken.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoToken *TaikoTokenCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoToken *TaikoTokenSession) ProxiableUUID() ([32]byte, error) { + return _TaikoToken.Contract.ProxiableUUID(&_TaikoToken.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TaikoToken *TaikoTokenCallerSession) ProxiableUUID() ([32]byte, error) { + return _TaikoToken.Contract.ProxiableUUID(&_TaikoToken.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoToken.Contract.Resolve(&_TaikoToken.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoToken.Contract.Resolve(&_TaikoToken.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TaikoToken.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoToken.Contract.Resolve0(&_TaikoToken.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TaikoToken *TaikoTokenCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TaikoToken.Contract.Resolve0(&_TaikoToken.CallOpts, _name, _allowZeroAddress) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TaikoToken *TaikoTokenCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) Symbol() (string, error) { + return _TaikoToken.Contract.Symbol(&_TaikoToken.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TaikoToken *TaikoTokenCallerSession) Symbol() (string, error) { + return _TaikoToken.Contract.Symbol(&_TaikoToken.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TaikoToken *TaikoTokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TaikoToken.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 (_TaikoToken *TaikoTokenSession) TotalSupply() (*big.Int, error) { + return _TaikoToken.Contract.TotalSupply(&_TaikoToken.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TaikoToken *TaikoTokenCallerSession) TotalSupply() (*big.Int, error) { + return _TaikoToken.Contract.TotalSupply(&_TaikoToken.CallOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoToken *TaikoTokenTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoToken *TaikoTokenSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoToken.Contract.AcceptOwnership(&_TaikoToken.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TaikoToken *TaikoTokenTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TaikoToken.Contract.AcceptOwnership(&_TaikoToken.TransactOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.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 (_TaikoToken *TaikoTokenSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Approve(&_TaikoToken.TransactOpts, spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Approve(&_TaikoToken.TransactOpts, spender, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. +// +// Solidity: function burn(address _from, uint256 _amount) returns() +func (_TaikoToken *TaikoTokenTransactor) Burn(opts *bind.TransactOpts, _from common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "burn", _from, _amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. +// +// Solidity: function burn(address _from, uint256 _amount) returns() +func (_TaikoToken *TaikoTokenSession) Burn(_from common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Burn(&_TaikoToken.TransactOpts, _from, _amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. +// +// Solidity: function burn(address _from, uint256 _amount) returns() +func (_TaikoToken *TaikoTokenTransactorSession) Burn(_from common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Burn(&_TaikoToken.TransactOpts, _from, _amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) +func (_TaikoToken *TaikoTokenTransactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) +func (_TaikoToken *TaikoTokenSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.DecreaseAllowance(&_TaikoToken.TransactOpts, spender, subtractedValue) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 subtractedValue) returns(bool) +func (_TaikoToken *TaikoTokenTransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.DecreaseAllowance(&_TaikoToken.TransactOpts, spender, subtractedValue) +} + +// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. +// +// Solidity: function delegate(address delegatee) returns() +func (_TaikoToken *TaikoTokenTransactor) Delegate(opts *bind.TransactOpts, delegatee common.Address) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "delegate", delegatee) +} + +// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. +// +// Solidity: function delegate(address delegatee) returns() +func (_TaikoToken *TaikoTokenSession) Delegate(delegatee common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.Delegate(&_TaikoToken.TransactOpts, delegatee) +} + +// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. +// +// Solidity: function delegate(address delegatee) returns() +func (_TaikoToken *TaikoTokenTransactorSession) Delegate(delegatee common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.Delegate(&_TaikoToken.TransactOpts, delegatee) +} + +// DelegateBySig is a paid mutator transaction binding the contract method 0xc3cda520. +// +// Solidity: function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenTransactor) DelegateBySig(opts *bind.TransactOpts, delegatee common.Address, nonce *big.Int, expiry *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "delegateBySig", delegatee, nonce, expiry, v, r, s) +} + +// DelegateBySig is a paid mutator transaction binding the contract method 0xc3cda520. +// +// Solidity: function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenSession) DelegateBySig(delegatee common.Address, nonce *big.Int, expiry *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.Contract.DelegateBySig(&_TaikoToken.TransactOpts, delegatee, nonce, expiry, v, r, s) +} + +// DelegateBySig is a paid mutator transaction binding the contract method 0xc3cda520. +// +// Solidity: function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenTransactorSession) DelegateBySig(delegatee common.Address, nonce *big.Int, expiry *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.Contract.DelegateBySig(&_TaikoToken.TransactOpts, delegatee, nonce, expiry, v, r, s) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) +func (_TaikoToken *TaikoTokenTransactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "increaseAllowance", spender, addedValue) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) +func (_TaikoToken *TaikoTokenSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.IncreaseAllowance(&_TaikoToken.TransactOpts, spender, addedValue) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 addedValue) returns(bool) +func (_TaikoToken *TaikoTokenTransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.IncreaseAllowance(&_TaikoToken.TransactOpts, spender, addedValue) +} + +// Init is a paid mutator transaction binding the contract method 0xef2423fa. +// +// Solidity: function init(address _owner, string _name, string _symbol, address _recipient) returns() +func (_TaikoToken *TaikoTokenTransactor) Init(opts *bind.TransactOpts, _owner common.Address, _name string, _symbol string, _recipient common.Address) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "init", _owner, _name, _symbol, _recipient) +} + +// Init is a paid mutator transaction binding the contract method 0xef2423fa. +// +// Solidity: function init(address _owner, string _name, string _symbol, address _recipient) returns() +func (_TaikoToken *TaikoTokenSession) Init(_owner common.Address, _name string, _symbol string, _recipient common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.Init(&_TaikoToken.TransactOpts, _owner, _name, _symbol, _recipient) +} + +// Init is a paid mutator transaction binding the contract method 0xef2423fa. +// +// Solidity: function init(address _owner, string _name, string _symbol, address _recipient) returns() +func (_TaikoToken *TaikoTokenTransactorSession) Init(_owner common.Address, _name string, _symbol string, _recipient common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.Init(&_TaikoToken.TransactOpts, _owner, _name, _symbol, _recipient) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoToken *TaikoTokenTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoToken *TaikoTokenSession) Pause() (*types.Transaction, error) { + return _TaikoToken.Contract.Pause(&_TaikoToken.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TaikoToken *TaikoTokenTransactorSession) Pause() (*types.Transaction, error) { + return _TaikoToken.Contract.Pause(&_TaikoToken.TransactOpts) +} + +// Permit is a paid mutator transaction binding the contract method 0xd505accf. +// +// Solidity: function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenTransactor) Permit(opts *bind.TransactOpts, owner common.Address, spender common.Address, value *big.Int, deadline *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "permit", owner, spender, value, deadline, v, r, s) +} + +// Permit is a paid mutator transaction binding the contract method 0xd505accf. +// +// Solidity: function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenSession) Permit(owner common.Address, spender common.Address, value *big.Int, deadline *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.Contract.Permit(&_TaikoToken.TransactOpts, owner, spender, value, deadline, v, r, s) +} + +// Permit is a paid mutator transaction binding the contract method 0xd505accf. +// +// Solidity: function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) returns() +func (_TaikoToken *TaikoTokenTransactorSession) Permit(owner common.Address, spender common.Address, value *big.Int, deadline *big.Int, v uint8, r [32]byte, s [32]byte) (*types.Transaction, error) { + return _TaikoToken.Contract.Permit(&_TaikoToken.TransactOpts, owner, spender, value, deadline, v, r, s) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoToken *TaikoTokenTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoToken *TaikoTokenSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoToken.Contract.RenounceOwnership(&_TaikoToken.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TaikoToken *TaikoTokenTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TaikoToken.Contract.RenounceOwnership(&_TaikoToken.TransactOpts) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactor) Transfer(opts *bind.TransactOpts, _to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "transfer", _to, _amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenSession) Transfer(_to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Transfer(&_TaikoToken.TransactOpts, _to, _amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactorSession) Transfer(_to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.Transfer(&_TaikoToken.TransactOpts, _to, _amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactor) TransferFrom(opts *bind.TransactOpts, _from common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "transferFrom", _from, _to, _amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenSession) TransferFrom(_from common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.TransferFrom(&_TaikoToken.TransactOpts, _from, _to, _amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address _from, address _to, uint256 _amount) returns(bool) +func (_TaikoToken *TaikoTokenTransactorSession) TransferFrom(_from common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) { + return _TaikoToken.Contract.TransferFrom(&_TaikoToken.TransactOpts, _from, _to, _amount) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoToken *TaikoTokenTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoToken *TaikoTokenSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.TransferOwnership(&_TaikoToken.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TaikoToken *TaikoTokenTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.TransferOwnership(&_TaikoToken.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoToken *TaikoTokenTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoToken *TaikoTokenSession) Unpause() (*types.Transaction, error) { + return _TaikoToken.Contract.Unpause(&_TaikoToken.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TaikoToken *TaikoTokenTransactorSession) Unpause() (*types.Transaction, error) { + return _TaikoToken.Contract.Unpause(&_TaikoToken.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoToken *TaikoTokenTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoToken *TaikoTokenSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.UpgradeTo(&_TaikoToken.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TaikoToken *TaikoTokenTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TaikoToken.Contract.UpgradeTo(&_TaikoToken.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoToken *TaikoTokenTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoToken.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoToken *TaikoTokenSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoToken.Contract.UpgradeToAndCall(&_TaikoToken.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TaikoToken *TaikoTokenTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TaikoToken.Contract.UpgradeToAndCall(&_TaikoToken.TransactOpts, newImplementation, data) +} + +// TaikoTokenAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TaikoToken contract. +type TaikoTokenAdminChangedIterator struct { + Event *TaikoTokenAdminChanged // 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 *TaikoTokenAdminChangedIterator) 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(TaikoTokenAdminChanged) + 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(TaikoTokenAdminChanged) + 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 *TaikoTokenAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenAdminChanged represents a AdminChanged event raised by the TaikoToken contract. +type TaikoTokenAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoToken *TaikoTokenFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TaikoTokenAdminChangedIterator, error) { + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TaikoTokenAdminChangedIterator{contract: _TaikoToken.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoToken *TaikoTokenFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TaikoTokenAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "AdminChanged") + 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(TaikoTokenAdminChanged) + if err := _TaikoToken.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TaikoToken *TaikoTokenFilterer) ParseAdminChanged(log types.Log) (*TaikoTokenAdminChanged, error) { + event := new(TaikoTokenAdminChanged) + if err := _TaikoToken.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the TaikoToken contract. +type TaikoTokenApprovalIterator struct { + Event *TaikoTokenApproval // 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 *TaikoTokenApprovalIterator) 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(TaikoTokenApproval) + 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(TaikoTokenApproval) + 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 *TaikoTokenApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenApproval represents a Approval event raised by the TaikoToken contract. +type TaikoTokenApproval 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 (_TaikoToken *TaikoTokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TaikoTokenApprovalIterator, 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 := _TaikoToken.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &TaikoTokenApprovalIterator{contract: _TaikoToken.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 (_TaikoToken *TaikoTokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TaikoTokenApproval, 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 := _TaikoToken.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(TaikoTokenApproval) + if err := _TaikoToken.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 (_TaikoToken *TaikoTokenFilterer) ParseApproval(log types.Log) (*TaikoTokenApproval, error) { + event := new(TaikoTokenApproval) + if err := _TaikoToken.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the TaikoToken contract. +type TaikoTokenBeaconUpgradedIterator struct { + Event *TaikoTokenBeaconUpgraded // 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 *TaikoTokenBeaconUpgradedIterator) 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(TaikoTokenBeaconUpgraded) + 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(TaikoTokenBeaconUpgraded) + 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 *TaikoTokenBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenBeaconUpgraded represents a BeaconUpgraded event raised by the TaikoToken contract. +type TaikoTokenBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoToken *TaikoTokenFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*TaikoTokenBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &TaikoTokenBeaconUpgradedIterator{contract: _TaikoToken.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoToken *TaikoTokenFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoTokenBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(TaikoTokenBeaconUpgraded) + if err := _TaikoToken.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TaikoToken *TaikoTokenFilterer) ParseBeaconUpgraded(log types.Log) (*TaikoTokenBeaconUpgraded, error) { + event := new(TaikoTokenBeaconUpgraded) + if err := _TaikoToken.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenDelegateChangedIterator is returned from FilterDelegateChanged and is used to iterate over the raw logs and unpacked data for DelegateChanged events raised by the TaikoToken contract. +type TaikoTokenDelegateChangedIterator struct { + Event *TaikoTokenDelegateChanged // 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 *TaikoTokenDelegateChangedIterator) 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(TaikoTokenDelegateChanged) + 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(TaikoTokenDelegateChanged) + 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 *TaikoTokenDelegateChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenDelegateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenDelegateChanged represents a DelegateChanged event raised by the TaikoToken contract. +type TaikoTokenDelegateChanged struct { + Delegator common.Address + FromDelegate common.Address + ToDelegate common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegateChanged is a free log retrieval operation binding the contract event 0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f. +// +// Solidity: event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate) +func (_TaikoToken *TaikoTokenFilterer) FilterDelegateChanged(opts *bind.FilterOpts, delegator []common.Address, fromDelegate []common.Address, toDelegate []common.Address) (*TaikoTokenDelegateChangedIterator, error) { + + var delegatorRule []interface{} + for _, delegatorItem := range delegator { + delegatorRule = append(delegatorRule, delegatorItem) + } + var fromDelegateRule []interface{} + for _, fromDelegateItem := range fromDelegate { + fromDelegateRule = append(fromDelegateRule, fromDelegateItem) + } + var toDelegateRule []interface{} + for _, toDelegateItem := range toDelegate { + toDelegateRule = append(toDelegateRule, toDelegateItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "DelegateChanged", delegatorRule, fromDelegateRule, toDelegateRule) + if err != nil { + return nil, err + } + return &TaikoTokenDelegateChangedIterator{contract: _TaikoToken.contract, event: "DelegateChanged", logs: logs, sub: sub}, nil +} + +// WatchDelegateChanged is a free log subscription operation binding the contract event 0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f. +// +// Solidity: event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate) +func (_TaikoToken *TaikoTokenFilterer) WatchDelegateChanged(opts *bind.WatchOpts, sink chan<- *TaikoTokenDelegateChanged, delegator []common.Address, fromDelegate []common.Address, toDelegate []common.Address) (event.Subscription, error) { + + var delegatorRule []interface{} + for _, delegatorItem := range delegator { + delegatorRule = append(delegatorRule, delegatorItem) + } + var fromDelegateRule []interface{} + for _, fromDelegateItem := range fromDelegate { + fromDelegateRule = append(fromDelegateRule, fromDelegateItem) + } + var toDelegateRule []interface{} + for _, toDelegateItem := range toDelegate { + toDelegateRule = append(toDelegateRule, toDelegateItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "DelegateChanged", delegatorRule, fromDelegateRule, toDelegateRule) + 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(TaikoTokenDelegateChanged) + if err := _TaikoToken.contract.UnpackLog(event, "DelegateChanged", 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 +} + +// ParseDelegateChanged is a log parse operation binding the contract event 0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f. +// +// Solidity: event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate) +func (_TaikoToken *TaikoTokenFilterer) ParseDelegateChanged(log types.Log) (*TaikoTokenDelegateChanged, error) { + event := new(TaikoTokenDelegateChanged) + if err := _TaikoToken.contract.UnpackLog(event, "DelegateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenDelegateVotesChangedIterator is returned from FilterDelegateVotesChanged and is used to iterate over the raw logs and unpacked data for DelegateVotesChanged events raised by the TaikoToken contract. +type TaikoTokenDelegateVotesChangedIterator struct { + Event *TaikoTokenDelegateVotesChanged // 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 *TaikoTokenDelegateVotesChangedIterator) 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(TaikoTokenDelegateVotesChanged) + 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(TaikoTokenDelegateVotesChanged) + 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 *TaikoTokenDelegateVotesChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenDelegateVotesChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenDelegateVotesChanged represents a DelegateVotesChanged event raised by the TaikoToken contract. +type TaikoTokenDelegateVotesChanged struct { + Delegate common.Address + PreviousBalance *big.Int + NewBalance *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegateVotesChanged is a free log retrieval operation binding the contract event 0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724. +// +// Solidity: event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance) +func (_TaikoToken *TaikoTokenFilterer) FilterDelegateVotesChanged(opts *bind.FilterOpts, delegate []common.Address) (*TaikoTokenDelegateVotesChangedIterator, error) { + + var delegateRule []interface{} + for _, delegateItem := range delegate { + delegateRule = append(delegateRule, delegateItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "DelegateVotesChanged", delegateRule) + if err != nil { + return nil, err + } + return &TaikoTokenDelegateVotesChangedIterator{contract: _TaikoToken.contract, event: "DelegateVotesChanged", logs: logs, sub: sub}, nil +} + +// WatchDelegateVotesChanged is a free log subscription operation binding the contract event 0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724. +// +// Solidity: event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance) +func (_TaikoToken *TaikoTokenFilterer) WatchDelegateVotesChanged(opts *bind.WatchOpts, sink chan<- *TaikoTokenDelegateVotesChanged, delegate []common.Address) (event.Subscription, error) { + + var delegateRule []interface{} + for _, delegateItem := range delegate { + delegateRule = append(delegateRule, delegateItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "DelegateVotesChanged", delegateRule) + 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(TaikoTokenDelegateVotesChanged) + if err := _TaikoToken.contract.UnpackLog(event, "DelegateVotesChanged", 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 +} + +// ParseDelegateVotesChanged is a log parse operation binding the contract event 0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724. +// +// Solidity: event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance) +func (_TaikoToken *TaikoTokenFilterer) ParseDelegateVotesChanged(log types.Log) (*TaikoTokenDelegateVotesChanged, error) { + event := new(TaikoTokenDelegateVotesChanged) + if err := _TaikoToken.contract.UnpackLog(event, "DelegateVotesChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenEIP712DomainChangedIterator is returned from FilterEIP712DomainChanged and is used to iterate over the raw logs and unpacked data for EIP712DomainChanged events raised by the TaikoToken contract. +type TaikoTokenEIP712DomainChangedIterator struct { + Event *TaikoTokenEIP712DomainChanged // 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 *TaikoTokenEIP712DomainChangedIterator) 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(TaikoTokenEIP712DomainChanged) + 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(TaikoTokenEIP712DomainChanged) + 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 *TaikoTokenEIP712DomainChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenEIP712DomainChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenEIP712DomainChanged represents a EIP712DomainChanged event raised by the TaikoToken contract. +type TaikoTokenEIP712DomainChanged struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEIP712DomainChanged is a free log retrieval operation binding the contract event 0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31. +// +// Solidity: event EIP712DomainChanged() +func (_TaikoToken *TaikoTokenFilterer) FilterEIP712DomainChanged(opts *bind.FilterOpts) (*TaikoTokenEIP712DomainChangedIterator, error) { + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "EIP712DomainChanged") + if err != nil { + return nil, err + } + return &TaikoTokenEIP712DomainChangedIterator{contract: _TaikoToken.contract, event: "EIP712DomainChanged", logs: logs, sub: sub}, nil +} + +// WatchEIP712DomainChanged is a free log subscription operation binding the contract event 0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31. +// +// Solidity: event EIP712DomainChanged() +func (_TaikoToken *TaikoTokenFilterer) WatchEIP712DomainChanged(opts *bind.WatchOpts, sink chan<- *TaikoTokenEIP712DomainChanged) (event.Subscription, error) { + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "EIP712DomainChanged") + 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(TaikoTokenEIP712DomainChanged) + if err := _TaikoToken.contract.UnpackLog(event, "EIP712DomainChanged", 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 +} + +// ParseEIP712DomainChanged is a log parse operation binding the contract event 0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31. +// +// Solidity: event EIP712DomainChanged() +func (_TaikoToken *TaikoTokenFilterer) ParseEIP712DomainChanged(log types.Log) (*TaikoTokenEIP712DomainChanged, error) { + event := new(TaikoTokenEIP712DomainChanged) + if err := _TaikoToken.contract.UnpackLog(event, "EIP712DomainChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TaikoToken contract. +type TaikoTokenInitializedIterator struct { + Event *TaikoTokenInitialized // 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 *TaikoTokenInitializedIterator) 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(TaikoTokenInitialized) + 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(TaikoTokenInitialized) + 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 *TaikoTokenInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenInitialized represents a Initialized event raised by the TaikoToken contract. +type TaikoTokenInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoToken *TaikoTokenFilterer) FilterInitialized(opts *bind.FilterOpts) (*TaikoTokenInitializedIterator, error) { + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TaikoTokenInitializedIterator{contract: _TaikoToken.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoToken *TaikoTokenFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TaikoTokenInitialized) (event.Subscription, error) { + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "Initialized") + 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(TaikoTokenInitialized) + if err := _TaikoToken.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TaikoToken *TaikoTokenFilterer) ParseInitialized(log types.Log) (*TaikoTokenInitialized, error) { + event := new(TaikoTokenInitialized) + if err := _TaikoToken.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the TaikoToken contract. +type TaikoTokenOwnershipTransferStartedIterator struct { + Event *TaikoTokenOwnershipTransferStarted // 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 *TaikoTokenOwnershipTransferStartedIterator) 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(TaikoTokenOwnershipTransferStarted) + 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(TaikoTokenOwnershipTransferStarted) + 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 *TaikoTokenOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the TaikoToken contract. +type TaikoTokenOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoTokenOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoTokenOwnershipTransferStartedIterator{contract: _TaikoToken.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *TaikoTokenOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(TaikoTokenOwnershipTransferStarted) + if err := _TaikoToken.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) ParseOwnershipTransferStarted(log types.Log) (*TaikoTokenOwnershipTransferStarted, error) { + event := new(TaikoTokenOwnershipTransferStarted) + if err := _TaikoToken.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TaikoToken contract. +type TaikoTokenOwnershipTransferredIterator struct { + Event *TaikoTokenOwnershipTransferred // 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 *TaikoTokenOwnershipTransferredIterator) 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(TaikoTokenOwnershipTransferred) + 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(TaikoTokenOwnershipTransferred) + 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 *TaikoTokenOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenOwnershipTransferred represents a OwnershipTransferred event raised by the TaikoToken contract. +type TaikoTokenOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoTokenOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TaikoTokenOwnershipTransferredIterator{contract: _TaikoToken.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TaikoTokenOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(TaikoTokenOwnershipTransferred) + if err := _TaikoToken.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TaikoToken *TaikoTokenFilterer) ParseOwnershipTransferred(log types.Log) (*TaikoTokenOwnershipTransferred, error) { + event := new(TaikoTokenOwnershipTransferred) + if err := _TaikoToken.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the TaikoToken contract. +type TaikoTokenPausedIterator struct { + Event *TaikoTokenPaused // 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 *TaikoTokenPausedIterator) 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(TaikoTokenPaused) + 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(TaikoTokenPaused) + 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 *TaikoTokenPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenPaused represents a Paused event raised by the TaikoToken contract. +type TaikoTokenPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoToken *TaikoTokenFilterer) FilterPaused(opts *bind.FilterOpts) (*TaikoTokenPausedIterator, error) { + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &TaikoTokenPausedIterator{contract: _TaikoToken.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoToken *TaikoTokenFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *TaikoTokenPaused) (event.Subscription, error) { + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "Paused") + 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(TaikoTokenPaused) + if err := _TaikoToken.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TaikoToken *TaikoTokenFilterer) ParsePaused(log types.Log) (*TaikoTokenPaused, error) { + event := new(TaikoTokenPaused) + if err := _TaikoToken.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the TaikoToken contract. +type TaikoTokenTransferIterator struct { + Event *TaikoTokenTransfer // 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 *TaikoTokenTransferIterator) 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(TaikoTokenTransfer) + 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(TaikoTokenTransfer) + 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 *TaikoTokenTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenTransfer represents a Transfer event raised by the TaikoToken contract. +type TaikoTokenTransfer 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 (_TaikoToken *TaikoTokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TaikoTokenTransferIterator, 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 := _TaikoToken.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &TaikoTokenTransferIterator{contract: _TaikoToken.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 (_TaikoToken *TaikoTokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TaikoTokenTransfer, 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 := _TaikoToken.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(TaikoTokenTransfer) + if err := _TaikoToken.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 (_TaikoToken *TaikoTokenFilterer) ParseTransfer(log types.Log) (*TaikoTokenTransfer, error) { + event := new(TaikoTokenTransfer) + if err := _TaikoToken.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the TaikoToken contract. +type TaikoTokenUnpausedIterator struct { + Event *TaikoTokenUnpaused // 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 *TaikoTokenUnpausedIterator) 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(TaikoTokenUnpaused) + 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(TaikoTokenUnpaused) + 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 *TaikoTokenUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenUnpaused represents a Unpaused event raised by the TaikoToken contract. +type TaikoTokenUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoToken *TaikoTokenFilterer) FilterUnpaused(opts *bind.FilterOpts) (*TaikoTokenUnpausedIterator, error) { + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &TaikoTokenUnpausedIterator{contract: _TaikoToken.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoToken *TaikoTokenFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *TaikoTokenUnpaused) (event.Subscription, error) { + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "Unpaused") + 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(TaikoTokenUnpaused) + if err := _TaikoToken.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TaikoToken *TaikoTokenFilterer) ParseUnpaused(log types.Log) (*TaikoTokenUnpaused, error) { + event := new(TaikoTokenUnpaused) + if err := _TaikoToken.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TaikoTokenUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TaikoToken contract. +type TaikoTokenUpgradedIterator struct { + Event *TaikoTokenUpgraded // 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 *TaikoTokenUpgradedIterator) 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(TaikoTokenUpgraded) + 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(TaikoTokenUpgraded) + 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 *TaikoTokenUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TaikoTokenUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TaikoTokenUpgraded represents a Upgraded event raised by the TaikoToken contract. +type TaikoTokenUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoToken *TaikoTokenFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TaikoTokenUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoToken.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TaikoTokenUpgradedIterator{contract: _TaikoToken.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoToken *TaikoTokenFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TaikoTokenUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TaikoToken.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(TaikoTokenUpgraded) + if err := _TaikoToken.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TaikoToken *TaikoTokenFilterer) ParseUpgraded(log types.Log) (*TaikoTokenUpgraded, error) { + event := new(TaikoTokenUpgraded) + if err := _TaikoToken.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/bindings/gen_tier_provider.go b/packages/taiko-client/bindings/gen_tier_provider.go new file mode 100644 index 00000000000..31a6c18804e --- /dev/null +++ b/packages/taiko-client/bindings/gen_tier_provider.go @@ -0,0 +1,1831 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +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 +) + +// ITierProviderTier is an auto generated low-level Go binding around an user-defined struct. +type ITierProviderTier struct { + VerifierName [32]byte + ValidityBond *big.Int + ContestBond *big.Int + CooldownWindow *big.Int + ProvingWindow uint16 + MaxBlocksToVerifyPerProof uint8 +} + +// TierProviderMetaData contains all meta data concerning the TierProvider contract. +var TierProviderMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMinTier\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getTier\",\"inputs\":[{\"name\":\"_tierId\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structITierProvider.Tier\",\"components\":[{\"name\":\"verifierName\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validityBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"contestBond\",\"type\":\"uint96\",\"internalType\":\"uint96\"},{\"name\":\"cooldownWindow\",\"type\":\"uint24\",\"internalType\":\"uint24\"},{\"name\":\"provingWindow\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"maxBlocksToVerifyPerProof\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getTierIds\",\"inputs\":[],\"outputs\":[{\"name\":\"tiers_\",\"type\":\"uint16[]\",\"internalType\":\"uint16[]\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"init\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"lastUnpausedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"_name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_allowZeroAddress\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BeaconUpgraded\",\"inputs\":[{\"name\":\"beacon\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"INVALID_PAUSE_STATUS\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"REENTRANT_CALL\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_DENIED\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_INVALID_MANAGER\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_UNEXPECTED_CHAINID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"RESOLVER_ZERO_ADDR\",\"inputs\":[{\"name\":\"chainId\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"name\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"TIER_NOT_FOUND\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZERO_ADDR_MANAGER\",\"inputs\":[]}]", +} + +// TierProviderABI is the input ABI used to generate the binding from. +// Deprecated: Use TierProviderMetaData.ABI instead. +var TierProviderABI = TierProviderMetaData.ABI + +// TierProvider is an auto generated Go binding around an Ethereum contract. +type TierProvider struct { + TierProviderCaller // Read-only binding to the contract + TierProviderTransactor // Write-only binding to the contract + TierProviderFilterer // Log filterer for contract events +} + +// TierProviderCaller is an auto generated read-only Go binding around an Ethereum contract. +type TierProviderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TierProviderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TierProviderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TierProviderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TierProviderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TierProviderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TierProviderSession struct { + Contract *TierProvider // 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 +} + +// TierProviderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TierProviderCallerSession struct { + Contract *TierProviderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TierProviderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TierProviderTransactorSession struct { + Contract *TierProviderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TierProviderRaw is an auto generated low-level Go binding around an Ethereum contract. +type TierProviderRaw struct { + Contract *TierProvider // Generic contract binding to access the raw methods on +} + +// TierProviderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TierProviderCallerRaw struct { + Contract *TierProviderCaller // Generic read-only contract binding to access the raw methods on +} + +// TierProviderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TierProviderTransactorRaw struct { + Contract *TierProviderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTierProvider creates a new instance of TierProvider, bound to a specific deployed contract. +func NewTierProvider(address common.Address, backend bind.ContractBackend) (*TierProvider, error) { + contract, err := bindTierProvider(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TierProvider{TierProviderCaller: TierProviderCaller{contract: contract}, TierProviderTransactor: TierProviderTransactor{contract: contract}, TierProviderFilterer: TierProviderFilterer{contract: contract}}, nil +} + +// NewTierProviderCaller creates a new read-only instance of TierProvider, bound to a specific deployed contract. +func NewTierProviderCaller(address common.Address, caller bind.ContractCaller) (*TierProviderCaller, error) { + contract, err := bindTierProvider(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TierProviderCaller{contract: contract}, nil +} + +// NewTierProviderTransactor creates a new write-only instance of TierProvider, bound to a specific deployed contract. +func NewTierProviderTransactor(address common.Address, transactor bind.ContractTransactor) (*TierProviderTransactor, error) { + contract, err := bindTierProvider(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TierProviderTransactor{contract: contract}, nil +} + +// NewTierProviderFilterer creates a new log filterer instance of TierProvider, bound to a specific deployed contract. +func NewTierProviderFilterer(address common.Address, filterer bind.ContractFilterer) (*TierProviderFilterer, error) { + contract, err := bindTierProvider(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TierProviderFilterer{contract: contract}, nil +} + +// bindTierProvider binds a generic wrapper to an already deployed contract. +func bindTierProvider(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TierProviderMetaData.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 (_TierProvider *TierProviderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TierProvider.Contract.TierProviderCaller.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 (_TierProvider *TierProviderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.Contract.TierProviderTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TierProvider *TierProviderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TierProvider.Contract.TierProviderTransactor.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 (_TierProvider *TierProviderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TierProvider.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 (_TierProvider *TierProviderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TierProvider *TierProviderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TierProvider.Contract.contract.Transact(opts, method, params...) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TierProvider *TierProviderCaller) AddressManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "addressManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TierProvider *TierProviderSession) AddressManager() (common.Address, error) { + return _TierProvider.Contract.AddressManager(&_TierProvider.CallOpts) +} + +// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f. +// +// Solidity: function addressManager() view returns(address) +func (_TierProvider *TierProviderCallerSession) AddressManager() (common.Address, error) { + return _TierProvider.Contract.AddressManager(&_TierProvider.CallOpts) +} + +// GetMinTier is a free data retrieval call binding the contract method 0x59ab4e23. +// +// Solidity: function getMinTier(uint256 ) pure returns(uint16) +func (_TierProvider *TierProviderCaller) GetMinTier(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "getMinTier", arg0) + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// GetMinTier is a free data retrieval call binding the contract method 0x59ab4e23. +// +// Solidity: function getMinTier(uint256 ) pure returns(uint16) +func (_TierProvider *TierProviderSession) GetMinTier(arg0 *big.Int) (uint16, error) { + return _TierProvider.Contract.GetMinTier(&_TierProvider.CallOpts, arg0) +} + +// GetMinTier is a free data retrieval call binding the contract method 0x59ab4e23. +// +// Solidity: function getMinTier(uint256 ) pure returns(uint16) +func (_TierProvider *TierProviderCallerSession) GetMinTier(arg0 *big.Int) (uint16, error) { + return _TierProvider.Contract.GetMinTier(&_TierProvider.CallOpts, arg0) +} + +// GetTier is a free data retrieval call binding the contract method 0x576c3de7. +// +// Solidity: function getTier(uint16 _tierId) pure returns((bytes32,uint96,uint96,uint24,uint16,uint8)) +func (_TierProvider *TierProviderCaller) GetTier(opts *bind.CallOpts, _tierId uint16) (ITierProviderTier, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "getTier", _tierId) + + if err != nil { + return *new(ITierProviderTier), err + } + + out0 := *abi.ConvertType(out[0], new(ITierProviderTier)).(*ITierProviderTier) + + return out0, err + +} + +// GetTier is a free data retrieval call binding the contract method 0x576c3de7. +// +// Solidity: function getTier(uint16 _tierId) pure returns((bytes32,uint96,uint96,uint24,uint16,uint8)) +func (_TierProvider *TierProviderSession) GetTier(_tierId uint16) (ITierProviderTier, error) { + return _TierProvider.Contract.GetTier(&_TierProvider.CallOpts, _tierId) +} + +// GetTier is a free data retrieval call binding the contract method 0x576c3de7. +// +// Solidity: function getTier(uint16 _tierId) pure returns((bytes32,uint96,uint96,uint24,uint16,uint8)) +func (_TierProvider *TierProviderCallerSession) GetTier(_tierId uint16) (ITierProviderTier, error) { + return _TierProvider.Contract.GetTier(&_TierProvider.CallOpts, _tierId) +} + +// GetTierIds is a free data retrieval call binding the contract method 0xd8cde1c6. +// +// Solidity: function getTierIds() pure returns(uint16[] tiers_) +func (_TierProvider *TierProviderCaller) GetTierIds(opts *bind.CallOpts) ([]uint16, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "getTierIds") + + if err != nil { + return *new([]uint16), err + } + + out0 := *abi.ConvertType(out[0], new([]uint16)).(*[]uint16) + + return out0, err + +} + +// GetTierIds is a free data retrieval call binding the contract method 0xd8cde1c6. +// +// Solidity: function getTierIds() pure returns(uint16[] tiers_) +func (_TierProvider *TierProviderSession) GetTierIds() ([]uint16, error) { + return _TierProvider.Contract.GetTierIds(&_TierProvider.CallOpts) +} + +// GetTierIds is a free data retrieval call binding the contract method 0xd8cde1c6. +// +// Solidity: function getTierIds() pure returns(uint16[] tiers_) +func (_TierProvider *TierProviderCallerSession) GetTierIds() ([]uint16, error) { + return _TierProvider.Contract.GetTierIds(&_TierProvider.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TierProvider *TierProviderCaller) LastUnpausedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "lastUnpausedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TierProvider *TierProviderSession) LastUnpausedAt() (uint64, error) { + return _TierProvider.Contract.LastUnpausedAt(&_TierProvider.CallOpts) +} + +// LastUnpausedAt is a free data retrieval call binding the contract method 0xe07baba6. +// +// Solidity: function lastUnpausedAt() view returns(uint64) +func (_TierProvider *TierProviderCallerSession) LastUnpausedAt() (uint64, error) { + return _TierProvider.Contract.LastUnpausedAt(&_TierProvider.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TierProvider *TierProviderCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TierProvider *TierProviderSession) Owner() (common.Address, error) { + return _TierProvider.Contract.Owner(&_TierProvider.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TierProvider *TierProviderCallerSession) Owner() (common.Address, error) { + return _TierProvider.Contract.Owner(&_TierProvider.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TierProvider *TierProviderCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TierProvider *TierProviderSession) Paused() (bool, error) { + return _TierProvider.Contract.Paused(&_TierProvider.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_TierProvider *TierProviderCallerSession) Paused() (bool, error) { + return _TierProvider.Contract.Paused(&_TierProvider.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TierProvider *TierProviderCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TierProvider *TierProviderSession) PendingOwner() (common.Address, error) { + return _TierProvider.Contract.PendingOwner(&_TierProvider.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TierProvider *TierProviderCallerSession) PendingOwner() (common.Address, error) { + return _TierProvider.Contract.PendingOwner(&_TierProvider.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TierProvider *TierProviderCaller) ProxiableUUID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "proxiableUUID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TierProvider *TierProviderSession) ProxiableUUID() ([32]byte, error) { + return _TierProvider.Contract.ProxiableUUID(&_TierProvider.CallOpts) +} + +// ProxiableUUID is a free data retrieval call binding the contract method 0x52d1902d. +// +// Solidity: function proxiableUUID() view returns(bytes32) +func (_TierProvider *TierProviderCallerSession) ProxiableUUID() ([32]byte, error) { + return _TierProvider.Contract.ProxiableUUID(&_TierProvider.CallOpts) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderCaller) Resolve(opts *bind.CallOpts, _chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "resolve", _chainId, _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TierProvider.Contract.Resolve(&_TierProvider.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve is a free data retrieval call binding the contract method 0x3eb6b8cf. +// +// Solidity: function resolve(uint64 _chainId, bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderCallerSession) Resolve(_chainId uint64, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TierProvider.Contract.Resolve(&_TierProvider.CallOpts, _chainId, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderCaller) Resolve0(opts *bind.CallOpts, _name [32]byte, _allowZeroAddress bool) (common.Address, error) { + var out []interface{} + err := _TierProvider.contract.Call(opts, &out, "resolve0", _name, _allowZeroAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TierProvider.Contract.Resolve0(&_TierProvider.CallOpts, _name, _allowZeroAddress) +} + +// Resolve0 is a free data retrieval call binding the contract method 0xa86f9d9e. +// +// Solidity: function resolve(bytes32 _name, bool _allowZeroAddress) view returns(address) +func (_TierProvider *TierProviderCallerSession) Resolve0(_name [32]byte, _allowZeroAddress bool) (common.Address, error) { + return _TierProvider.Contract.Resolve0(&_TierProvider.CallOpts, _name, _allowZeroAddress) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TierProvider *TierProviderTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TierProvider *TierProviderSession) AcceptOwnership() (*types.Transaction, error) { + return _TierProvider.Contract.AcceptOwnership(&_TierProvider.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TierProvider *TierProviderTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TierProvider.Contract.AcceptOwnership(&_TierProvider.TransactOpts) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_TierProvider *TierProviderTransactor) Init(opts *bind.TransactOpts, _owner common.Address) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "init", _owner) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_TierProvider *TierProviderSession) Init(_owner common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.Init(&_TierProvider.TransactOpts, _owner) +} + +// Init is a paid mutator transaction binding the contract method 0x19ab453c. +// +// Solidity: function init(address _owner) returns() +func (_TierProvider *TierProviderTransactorSession) Init(_owner common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.Init(&_TierProvider.TransactOpts, _owner) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TierProvider *TierProviderTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TierProvider *TierProviderSession) Pause() (*types.Transaction, error) { + return _TierProvider.Contract.Pause(&_TierProvider.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_TierProvider *TierProviderTransactorSession) Pause() (*types.Transaction, error) { + return _TierProvider.Contract.Pause(&_TierProvider.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TierProvider *TierProviderTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TierProvider *TierProviderSession) RenounceOwnership() (*types.Transaction, error) { + return _TierProvider.Contract.RenounceOwnership(&_TierProvider.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TierProvider *TierProviderTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TierProvider.Contract.RenounceOwnership(&_TierProvider.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TierProvider *TierProviderTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TierProvider *TierProviderSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.TransferOwnership(&_TierProvider.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TierProvider *TierProviderTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.TransferOwnership(&_TierProvider.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TierProvider *TierProviderTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TierProvider *TierProviderSession) Unpause() (*types.Transaction, error) { + return _TierProvider.Contract.Unpause(&_TierProvider.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_TierProvider *TierProviderTransactorSession) Unpause() (*types.Transaction, error) { + return _TierProvider.Contract.Unpause(&_TierProvider.TransactOpts) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TierProvider *TierProviderTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "upgradeTo", newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TierProvider *TierProviderSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.UpgradeTo(&_TierProvider.TransactOpts, newImplementation) +} + +// UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. +// +// Solidity: function upgradeTo(address newImplementation) returns() +func (_TierProvider *TierProviderTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { + return _TierProvider.Contract.UpgradeTo(&_TierProvider.TransactOpts, newImplementation) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TierProvider *TierProviderTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TierProvider.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TierProvider *TierProviderSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TierProvider.Contract.UpgradeToAndCall(&_TierProvider.TransactOpts, newImplementation, data) +} + +// UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. +// +// Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() +func (_TierProvider *TierProviderTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { + return _TierProvider.Contract.UpgradeToAndCall(&_TierProvider.TransactOpts, newImplementation, data) +} + +// TierProviderAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TierProvider contract. +type TierProviderAdminChangedIterator struct { + Event *TierProviderAdminChanged // 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 *TierProviderAdminChangedIterator) 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(TierProviderAdminChanged) + 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(TierProviderAdminChanged) + 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 *TierProviderAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderAdminChanged represents a AdminChanged event raised by the TierProvider contract. +type TierProviderAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TierProvider *TierProviderFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TierProviderAdminChangedIterator, error) { + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TierProviderAdminChangedIterator{contract: _TierProvider.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TierProvider *TierProviderFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TierProviderAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "AdminChanged") + 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(TierProviderAdminChanged) + if err := _TierProvider.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TierProvider *TierProviderFilterer) ParseAdminChanged(log types.Log) (*TierProviderAdminChanged, error) { + event := new(TierProviderAdminChanged) + if err := _TierProvider.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the TierProvider contract. +type TierProviderBeaconUpgradedIterator struct { + Event *TierProviderBeaconUpgraded // 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 *TierProviderBeaconUpgradedIterator) 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(TierProviderBeaconUpgraded) + 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(TierProviderBeaconUpgraded) + 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 *TierProviderBeaconUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderBeaconUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderBeaconUpgraded represents a BeaconUpgraded event raised by the TierProvider contract. +type TierProviderBeaconUpgraded struct { + Beacon common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TierProvider *TierProviderFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*TierProviderBeaconUpgradedIterator, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) + if err != nil { + return nil, err + } + return &TierProviderBeaconUpgradedIterator{contract: _TierProvider.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil +} + +// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TierProvider *TierProviderFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *TierProviderBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { + + var beaconRule []interface{} + for _, beaconItem := range beacon { + beaconRule = append(beaconRule, beaconItem) + } + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) + 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(TierProviderBeaconUpgraded) + if err := _TierProvider.contract.UnpackLog(event, "BeaconUpgraded", 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 +} + +// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. +// +// Solidity: event BeaconUpgraded(address indexed beacon) +func (_TierProvider *TierProviderFilterer) ParseBeaconUpgraded(log types.Log) (*TierProviderBeaconUpgraded, error) { + event := new(TierProviderBeaconUpgraded) + if err := _TierProvider.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TierProvider contract. +type TierProviderInitializedIterator struct { + Event *TierProviderInitialized // 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 *TierProviderInitializedIterator) 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(TierProviderInitialized) + 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(TierProviderInitialized) + 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 *TierProviderInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderInitialized represents a Initialized event raised by the TierProvider contract. +type TierProviderInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TierProvider *TierProviderFilterer) FilterInitialized(opts *bind.FilterOpts) (*TierProviderInitializedIterator, error) { + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TierProviderInitializedIterator{contract: _TierProvider.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TierProvider *TierProviderFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TierProviderInitialized) (event.Subscription, error) { + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "Initialized") + 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(TierProviderInitialized) + if err := _TierProvider.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TierProvider *TierProviderFilterer) ParseInitialized(log types.Log) (*TierProviderInitialized, error) { + event := new(TierProviderInitialized) + if err := _TierProvider.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the TierProvider contract. +type TierProviderOwnershipTransferStartedIterator struct { + Event *TierProviderOwnershipTransferStarted // 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 *TierProviderOwnershipTransferStartedIterator) 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(TierProviderOwnershipTransferStarted) + 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(TierProviderOwnershipTransferStarted) + 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 *TierProviderOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the TierProvider contract. +type TierProviderOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TierProviderOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TierProviderOwnershipTransferStartedIterator{contract: _TierProvider.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *TierProviderOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + 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(TierProviderOwnershipTransferStarted) + if err := _TierProvider.contract.UnpackLog(event, "OwnershipTransferStarted", 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 +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) ParseOwnershipTransferStarted(log types.Log) (*TierProviderOwnershipTransferStarted, error) { + event := new(TierProviderOwnershipTransferStarted) + if err := _TierProvider.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TierProvider contract. +type TierProviderOwnershipTransferredIterator struct { + Event *TierProviderOwnershipTransferred // 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 *TierProviderOwnershipTransferredIterator) 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(TierProviderOwnershipTransferred) + 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(TierProviderOwnershipTransferred) + 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 *TierProviderOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderOwnershipTransferred represents a OwnershipTransferred event raised by the TierProvider contract. +type TierProviderOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TierProviderOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TierProviderOwnershipTransferredIterator{contract: _TierProvider.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TierProviderOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + 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(TierProviderOwnershipTransferred) + if err := _TierProvider.contract.UnpackLog(event, "OwnershipTransferred", 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 +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TierProvider *TierProviderFilterer) ParseOwnershipTransferred(log types.Log) (*TierProviderOwnershipTransferred, error) { + event := new(TierProviderOwnershipTransferred) + if err := _TierProvider.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the TierProvider contract. +type TierProviderPausedIterator struct { + Event *TierProviderPaused // 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 *TierProviderPausedIterator) 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(TierProviderPaused) + 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(TierProviderPaused) + 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 *TierProviderPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderPaused represents a Paused event raised by the TierProvider contract. +type TierProviderPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TierProvider *TierProviderFilterer) FilterPaused(opts *bind.FilterOpts) (*TierProviderPausedIterator, error) { + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &TierProviderPausedIterator{contract: _TierProvider.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TierProvider *TierProviderFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *TierProviderPaused) (event.Subscription, error) { + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "Paused") + 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(TierProviderPaused) + if err := _TierProvider.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_TierProvider *TierProviderFilterer) ParsePaused(log types.Log) (*TierProviderPaused, error) { + event := new(TierProviderPaused) + if err := _TierProvider.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the TierProvider contract. +type TierProviderUnpausedIterator struct { + Event *TierProviderUnpaused // 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 *TierProviderUnpausedIterator) 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(TierProviderUnpaused) + 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(TierProviderUnpaused) + 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 *TierProviderUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderUnpaused represents a Unpaused event raised by the TierProvider contract. +type TierProviderUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TierProvider *TierProviderFilterer) FilterUnpaused(opts *bind.FilterOpts) (*TierProviderUnpausedIterator, error) { + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &TierProviderUnpausedIterator{contract: _TierProvider.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TierProvider *TierProviderFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *TierProviderUnpaused) (event.Subscription, error) { + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "Unpaused") + 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(TierProviderUnpaused) + if err := _TierProvider.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_TierProvider *TierProviderFilterer) ParseUnpaused(log types.Log) (*TierProviderUnpaused, error) { + event := new(TierProviderUnpaused) + if err := _TierProvider.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TierProviderUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TierProvider contract. +type TierProviderUpgradedIterator struct { + Event *TierProviderUpgraded // 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 *TierProviderUpgradedIterator) 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(TierProviderUpgraded) + 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(TierProviderUpgraded) + 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 *TierProviderUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TierProviderUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TierProviderUpgraded represents a Upgraded event raised by the TierProvider contract. +type TierProviderUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TierProvider *TierProviderFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TierProviderUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TierProvider.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TierProviderUpgradedIterator{contract: _TierProvider.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TierProvider *TierProviderFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TierProviderUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TierProvider.contract.WatchLogs(opts, "Upgraded", implementationRule) + 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(TierProviderUpgraded) + if err := _TierProvider.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TierProvider *TierProviderFilterer) ParseUpgraded(log types.Log) (*TierProviderUpgraded, error) { + event := new(TierProviderUpgraded) + if err := _TierProvider.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/packages/taiko-client/cmd/flags/common.go b/packages/taiko-client/cmd/flags/common.go new file mode 100644 index 00000000000..f5e8887616d --- /dev/null +++ b/packages/taiko-client/cmd/flags/common.go @@ -0,0 +1,181 @@ +package flags + +import ( + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/urfave/cli/v2" +) + +var ( + commonCategory = "COMMON" + metricsCategory = "METRICS" + loggingCategory = "LOGGING" + driverCategory = "DRIVER" + proposerCategory = "PROPOSER" + proverCategory = "PROVER" + txmgrCategory = "TX_MANAGER" +) + +// Required flags used by all client software. +var ( + L1WSEndpoint = &cli.StringFlag{ + Name: "l1.ws", + Usage: "Websocket RPC endpoint of a L1 ethereum node", + Required: true, + Category: commonCategory, + EnvVars: []string{"L1_WS"}, + } + L2WSEndpoint = &cli.StringFlag{ + Name: "l2.ws", + Usage: "Websocket RPC endpoint of a L2 taiko-geth execution engine", + Required: true, + Category: commonCategory, + EnvVars: []string{"L2_WS"}, + } + L1HTTPEndpoint = &cli.StringFlag{ + Name: "l1.http", + Usage: "HTTP RPC endpoint of a L1 ethereum node", + Required: true, + Category: commonCategory, + EnvVars: []string{"L1_HTTP"}, + } + L1BeaconEndpoint = &cli.StringFlag{ + Name: "l1.beacon", + Usage: "HTTP RPC endpoint of a L1 beacon node", + Category: commonCategory, + EnvVars: []string{"L1_BEACON"}, + } + L2HTTPEndpoint = &cli.StringFlag{ + Name: "l2.http", + Usage: "HTTP RPC endpoint of a L2 taiko-geth execution engine", + Required: true, + Category: commonCategory, + EnvVars: []string{"L2_HTTP"}, + } + L2AuthEndpoint = &cli.StringFlag{ + Name: "l2.auth", + Usage: "Authenticated HTTP RPC endpoint of a L2 taiko-geth execution engine", + Required: true, + Category: commonCategory, + EnvVars: []string{"L2_AUTH"}, + } + JWTSecret = &cli.StringFlag{ + Name: "jwtSecret", + Usage: "Path to a JWT secret to use for authenticated RPC endpoints", + Required: true, + Category: commonCategory, + EnvVars: []string{"JWT_SECRET"}, + } + TaikoL1Address = &cli.StringFlag{ + Name: "taikoL1", + Usage: "TaikoL1 contract `address`", + Required: true, + Category: commonCategory, + EnvVars: []string{"TAIKO_L1"}, + } + TaikoL2Address = &cli.StringFlag{ + Name: "taikoL2", + Usage: "TaikoL2 contract `address`", + Required: true, + Category: commonCategory, + EnvVars: []string{"TAIKO_L2"}, + } + TaikoTokenAddress = &cli.StringFlag{ + Name: "taikoToken", + Usage: "TaikoToken contract `address`", + Required: true, + Category: commonCategory, + EnvVars: []string{"TAIKO_TOKEN"}, + } + // Optional flags used by all client software. + // Logging + Verbosity = &cli.IntFlag{ + Name: "verbosity", + Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail", + Value: 3, + Category: loggingCategory, + EnvVars: []string{"VERBOSITY"}, + } + LogJSON = &cli.BoolFlag{ + Name: "log.json", + Usage: "Format logs with JSON", + Category: loggingCategory, + EnvVars: []string{"LOG_JSON"}, + } + // Metrics + MetricsEnabled = &cli.BoolFlag{ + Name: "metrics", + Usage: "Enable metrics collection and reporting", + Category: metricsCategory, + Value: false, + EnvVars: []string{"METRICS"}, + } + MetricsAddr = &cli.StringFlag{ + Name: "metrics.addr", + Usage: "Metrics reporting server listening address", + Category: metricsCategory, + Value: "0.0.0.0", + EnvVars: []string{"METRICS_ADDR"}, + } + MetricsPort = &cli.IntFlag{ + Name: "metrics.port", + Usage: "Metrics reporting server listening port", + Category: metricsCategory, + Value: 6060, + EnvVars: []string{"METRICS_PORT"}, + } + BackOffMaxRetries = &cli.Uint64Flag{ + Name: "backoff.maxRetries", + Usage: "Max retry times when there is an error", + Category: commonCategory, + Value: 10, + EnvVars: []string{"BACKOFF_MAX_RETRIES"}, + } + BackOffRetryInterval = &cli.DurationFlag{ + Name: "backoff.retryInterval", + Usage: "Retry interval in seconds when there is an error", + Category: commonCategory, + Value: backoff.DefaultMaxInterval, + EnvVars: []string{"BACKOFF_RETRY_INTERVAL"}, + } + RPCTimeout = &cli.DurationFlag{ + Name: "rpc.timeout", + Usage: "Timeout in seconds for RPC calls", + Category: commonCategory, + Value: 12 * time.Second, + EnvVars: []string{"RPC_TIMEOUT"}, + } + AssignmentHookAddress = &cli.StringFlag{ + Name: "assignmentHookAddress", + Usage: "Address of the AssignmentHook contract", + Category: commonCategory, + EnvVars: []string{"ASSIGNMENT_HOOK_ADDRESS"}, + } +) + +// CommonFlags All common flags. +var CommonFlags = []cli.Flag{ + // Required + L1WSEndpoint, + TaikoL1Address, + TaikoL2Address, + // Optional + Verbosity, + LogJSON, + MetricsEnabled, + MetricsAddr, + MetricsPort, + BackOffMaxRetries, + BackOffRetryInterval, + RPCTimeout, +} + +// MergeFlags merges the given flag slices. +func MergeFlags(groups ...[]cli.Flag) []cli.Flag { + var merged []cli.Flag + for _, group := range groups { + merged = append(merged, group...) + } + return merged +} diff --git a/packages/taiko-client/cmd/flags/driver.go b/packages/taiko-client/cmd/flags/driver.go new file mode 100644 index 00000000000..eab6e480854 --- /dev/null +++ b/packages/taiko-client/cmd/flags/driver.go @@ -0,0 +1,62 @@ +package flags + +import ( + "time" + + "github.com/urfave/cli/v2" +) + +// Optional flags used by driver. +var ( + P2PSync = &cli.BoolFlag{ + Name: "p2p.sync", + Usage: "Try P2P syncing blocks between L2 execution engines, " + + "will be helpful to bring a new node online quickly", + Value: false, + Category: driverCategory, + EnvVars: []string{"P2P_SYNC"}, + } + P2PSyncTimeout = &cli.DurationFlag{ + Name: "p2p.syncTimeout", + Usage: "P2P syncing timeout, if no sync progress is made within this time span, " + + "driver will stop the P2P sync and insert all remaining L2 blocks one by one", + Value: 1 * time.Hour, + Category: driverCategory, + EnvVars: []string{"P2P_SYNC_TIMEOUT"}, + } + CheckPointSyncURL = &cli.StringFlag{ + Name: "p2p.checkPointSyncUrl", + Usage: "HTTP RPC endpoint of another synced L2 execution engine node", + Category: driverCategory, + EnvVars: []string{"P2P_CHECK_POINT_SYNC_URL"}, + } + // syncer specific flag + MaxExponent = &cli.Uint64Flag{ + Name: "syncer.maxExponent", + Usage: "Maximum exponent of retrieving L1 blocks when there is a mismatch between protocol and L2 EE," + + "0 means that it is reset to the genesis height", + Value: 0, + Category: driverCategory, + EnvVars: []string{"SYNCER_MAX_EXPONENT"}, + } + // blob server endpoint + BlobServerEndpoint = &cli.StringFlag{ + Name: "blob.server", + Usage: "Blob sidecar storage server", + Category: driverCategory, + EnvVars: []string{"BLOB_SERVER"}, + } +) + +// DriverFlags All driver flags. +var DriverFlags = MergeFlags(CommonFlags, []cli.Flag{ + L1BeaconEndpoint, + L2WSEndpoint, + L2AuthEndpoint, + JWTSecret, + P2PSync, + P2PSyncTimeout, + CheckPointSyncURL, + MaxExponent, + BlobServerEndpoint, +}) diff --git a/packages/taiko-client/cmd/flags/proposer.go b/packages/taiko-client/cmd/flags/proposer.go new file mode 100644 index 00000000000..f9982686ad7 --- /dev/null +++ b/packages/taiko-client/cmd/flags/proposer.go @@ -0,0 +1,169 @@ +package flags + +import ( + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/internal/version" +) + +// Required flags used by proposer. +var ( + L1ProposerPrivKey = &cli.StringFlag{ + Name: "l1.proposerPrivKey", + Usage: "Private key of the L1 proposer, who will send TaikoL1.proposeBlock transactions", + Required: true, + Category: proposerCategory, + EnvVars: []string{"L1_PROPOSER_PRIV_KEY"}, + } + ProverEndpoints = &cli.StringFlag{ + Name: "proverEndpoints", + Usage: "Comma-delineated list of prover endpoints proposer should query when attempting to propose a block", + Required: true, + Category: proposerCategory, + EnvVars: []string{"PROVER_ENDPOINTS"}, + } + L2SuggestedFeeRecipient = &cli.StringFlag{ + Name: "l2.suggestedFeeRecipient", + Usage: "Address of the proposed block's suggested L2 fee recipient", + Required: true, + Category: proposerCategory, + EnvVars: []string{"L2_SUGGESTED_FEE_RECIPIENT"}, + } +) + +// Optional flags used by proposer. +var ( + // Tier fee related. + OptimisticTierFee = &cli.Float64Flag{ + Name: "tierFee.optimistic", + Usage: "Initial tier fee (in GWei) paid to prover to generate an optimistic proofs", + Category: proposerCategory, + EnvVars: []string{"TIER_FEE_OPTIMISTIC"}, + } + SgxTierFee = &cli.Float64Flag{ + Name: "tierFee.sgx", + Usage: "Initial tier fee (in GWei) paid to prover to generate a SGX proofs", + Category: proposerCategory, + EnvVars: []string{"TIER_FEE_SGX"}, + } + TierFeePriceBump = &cli.Uint64Flag{ + Name: "tierFee.priceBump", + Usage: "Price bump percentage when no prover wants to accept the block at initial fee", + Value: 10, + Category: proposerCategory, + EnvVars: []string{"TIER_FEE_PRICE_BUMP"}, + } + MaxTierFeePriceBumps = &cli.Uint64Flag{ + Name: "tierFee.maxPriceBumps", + Usage: "If nobody accepts block at initial tier fee, how many iterations to increase tier fee before giving up", + Category: proposerCategory, + Value: 3, + EnvVars: []string{"TIER_FEE_MAX_PRICE_BUMPS"}, + } + // Proposing epoch related. + ProposeInterval = &cli.DurationFlag{ + Name: "epoch.interval", + Usage: "Time interval to propose L2 pending transactions", + Category: proposerCategory, + Value: 0, + EnvVars: []string{"EPOCH_INTERVAL"}, + } + MinGasUsed = &cli.Uint64Flag{ + Name: "epoch.minGasUsed", + Usage: "Minimum gas used for a transactions list to propose", + Category: proposerCategory, + Value: 0, + EnvVars: []string{"EPOCH_MIN_GAS_USED"}, + } + MinTxListBytes = &cli.Uint64Flag{ + Name: "epoch.minTxListBytes", + Usage: "Minimum bytes for a transactions list to propose", + Category: proposerCategory, + Value: 0, + EnvVars: []string{"EPOCH_MIN_TX_LIST_BYTES"}, + } + MinProposingInternal = &cli.DurationFlag{ + Name: "epoch.minProposingInterval", + Usage: "Minimum time interval to force proposing a block, even if there are no transaction in mempool", + Category: proposerCategory, + Value: 0, + EnvVars: []string{"EPOCH_MIN_PROPOSING_INTERNAL"}, + } + // Proposing metadata related. + ExtraData = &cli.StringFlag{ + Name: "extraData", + Usage: "Block extra data set by the proposer (default = client version)", + Value: version.CommitVersion(), + Category: proposerCategory, + EnvVars: []string{"EXTRA_DATA"}, + } + // Transactions pool related. + TxPoolLocals = &cli.StringSliceFlag{ + Name: "txPool.locals", + Usage: "Comma separated accounts to treat as locals (priority inclusion)", + Category: proposerCategory, + EnvVars: []string{"TX_POOL_LOCALS"}, + } + TxPoolLocalsOnly = &cli.BoolFlag{ + Name: "txPool.localsOnly", + Usage: "If set to true, proposer will only propose transactions of local accounts", + Value: false, + Category: proposerCategory, + EnvVars: []string{"TX_POOL_LOCALS_ONLY"}, + } + MaxProposedTxListsPerEpoch = &cli.Uint64Flag{ + Name: "txPool.maxTxListsPerEpoch", + Usage: "Maximum number of transaction lists which will be proposed inside one proposing epoch", + Value: 1, + Category: proposerCategory, + EnvVars: []string{"TX_POOL_MAX_TX_LISTS_PER_EPOCH"}, + } + ProposeBlockIncludeParentMetaHash = &cli.BoolFlag{ + Name: "includeParentMetaHash", + Usage: "Include parent meta hash when proposing block", + Value: false, + Category: proposerCategory, + EnvVars: []string{"INCLUDE_PARENT_META_HASH"}, + } + // Transaction related. + BlobAllowed = &cli.BoolFlag{ + Name: "l1.blobAllowed", + Usage: "Send EIP-4844 blob transactions when proposing blocks", + Value: false, + EnvVars: []string{"L1_BLOB_ALLOWED"}, + } + L1BlockBuilderTip = &cli.Uint64Flag{ + Name: "l1.blockBuilderTip", + Usage: "Amount you wish to tip the L1 block builder", + Value: 0, + Category: proposerCategory, + EnvVars: []string{"L1_BLOCK_BUILDER_TIP"}, + } +) + +// ProposerFlags All proposer flags. +var ProposerFlags = MergeFlags(CommonFlags, []cli.Flag{ + L2HTTPEndpoint, + L2AuthEndpoint, + JWTSecret, + TaikoTokenAddress, + L1ProposerPrivKey, + L2SuggestedFeeRecipient, + ProposeInterval, + TxPoolLocals, + TxPoolLocalsOnly, + ExtraData, + MinGasUsed, + MinTxListBytes, + MinProposingInternal, + MaxProposedTxListsPerEpoch, + ProverEndpoints, + OptimisticTierFee, + SgxTierFee, + TierFeePriceBump, + MaxTierFeePriceBumps, + ProposeBlockIncludeParentMetaHash, + AssignmentHookAddress, + BlobAllowed, + L1BlockBuilderTip, +}, TxmgrFlags) diff --git a/packages/taiko-client/cmd/flags/prover.go b/packages/taiko-client/cmd/flags/prover.go new file mode 100644 index 00000000000..0e533270f62 --- /dev/null +++ b/packages/taiko-client/cmd/flags/prover.go @@ -0,0 +1,244 @@ +package flags + +import ( + "time" + + "github.com/urfave/cli/v2" +) + +// Required flags used by prover. +var ( + L1ProverPrivKey = &cli.StringFlag{ + Name: "l1.proverPrivKey", + Usage: "Private key of L1 prover, who will send TaikoL1.proveBlock transactions", + Required: true, + Category: proverCategory, + EnvVars: []string{"L1_PROVER_PRIV_KEY"}, + } + ProverCapacity = &cli.Uint64Flag{ + Name: "prover.capacity", + Usage: "Capacity of prover", + Required: true, + Category: proverCategory, + EnvVars: []string{"PROVER_CAPACITY"}, + } +) + +// Optional flags used by prover. +var ( + RaikoHostEndpoint = &cli.StringFlag{ + Name: "raiko.host", + Usage: "RPC endpoint of a Raiko host service", + Category: proverCategory, + EnvVars: []string{"RAIKO_HOST"}, + } + RaikoL1Endpoint = &cli.StringFlag{ + Name: "raiko.l1", + Usage: "L1 RPC endpoint which will be sent to the Raiko service", + Category: proverCategory, + EnvVars: []string{"RAIKO_L1"}, + } + RaikoL1BeaconEndpoint = &cli.StringFlag{ + Name: "raiko.l1Beacon", + Usage: "L1 beacon RPC endpoint which will be sent to the Raiko service", + Category: proverCategory, + EnvVars: []string{"RAIKO_L1_BEACON"}, + } + RaikoL2Endpoint = &cli.StringFlag{ + Name: "raiko.l2", + Usage: "L2 RPC endpoint which will be sent to the Raiko service", + Category: proverCategory, + EnvVars: []string{"RAIKO_L2"}, + } + StartingBlockID = &cli.Uint64Flag{ + Name: "prover.startingBlockID", + Usage: "If set, prover will start proving blocks from the block with this ID", + Category: proverCategory, + EnvVars: []string{"PROVER_STARTING_BLOCK_ID"}, + } + Graffiti = &cli.StringFlag{ + Name: "prover.graffiti", + Usage: "When string is passed, adds additional graffiti info to proof evidence", + Category: proverCategory, + Value: "", + EnvVars: []string{"PROVER_GRAFFITI"}, + } + // Proving strategy. + ProveUnassignedBlocks = &cli.BoolFlag{ + Name: "prover.proveUnassignedBlocks", + Usage: "Whether you want to prove unassigned blocks, or only work on assigned proofs", + Category: proverCategory, + Value: false, + EnvVars: []string{"PROVER_PROVE_UNASSIGNED_BLOCKS"}, + } + MinEthBalance = &cli.Float64Flag{ + Name: "prover.minEthBalance", + Usage: "Minimum ETH balance (in Ether) a prover wants to keep", + Category: proverCategory, + Value: 0, + EnvVars: []string{"PROVER_MIN_ETH_BALANCE"}, + } + MinTaikoTokenBalance = &cli.Float64Flag{ + Name: "prover.minTaikoTokenBalance", + Usage: "Minimum Taiko token balance without decimal a prover wants to keep", + Category: proverCategory, + Value: 0, + EnvVars: []string{"PROVER_MIN_TAIKO_TOKEN_BALANCE"}, + } + // Tier fee related. + MinOptimisticTierFee = &cli.Uint64Flag{ + Name: "minTierFee.optimistic", + Usage: "Minimum accepted fee for generating an optimistic proof", + Category: proverCategory, + EnvVars: []string{"MIN_TIER_FEE_OPTIMISTIC"}, + } + MinSgxTierFee = &cli.Uint64Flag{ + Name: "minTierFee.sgx", + Usage: "Minimum accepted fee for generating a SGX proof", + Category: proverCategory, + EnvVars: []string{"MIN_TIER_FEE_SGX"}, + } + MinSgxAndZkVMTierFee = &cli.Uint64Flag{ + Name: "minTierFee.sgxAndZkvm", + Usage: "Minimum accepted fee for generating a SGX + zkVM proof", + Category: proverCategory, + EnvVars: []string{"MIN_TIER_FEE_SGX_AND_ZKVM"}, + } + // Running mode + ContesterMode = &cli.BoolFlag{ + Name: "mode.contester", + Usage: "Whether you want to contest wrong transitions with higher tier proofs", + Category: proverCategory, + Value: false, + EnvVars: []string{"MODE_CONTESTER"}, + } + // HTTP server related. + ProverHTTPServerPort = &cli.Uint64Flag{ + Name: "prover.port", + Usage: "Port to expose for http server", + Category: proverCategory, + Value: 9876, + EnvVars: []string{"PROVER_PORT"}, + } + MaxExpiry = &cli.DurationFlag{ + Name: "http.maxExpiry", + Usage: "Maximum accepted expiry in seconds for accepting proving a block", + Value: 1 * time.Hour, + Category: proverCategory, + EnvVars: []string{"HTTP_MAX_EXPIRY"}, + } + // Special flags for testing. + Dummy = &cli.BoolFlag{ + Name: "prover.dummy", + Usage: "Produce dummy proofs, testing purposes only", + Value: false, + Category: proverCategory, + EnvVars: []string{"PROVER_DUMMY"}, + } + // Max slippage allowed + MaxAcceptableBlockSlippage = &cli.Uint64Flag{ + Name: "prover.blockSlippage", + Usage: "Maximum accepted slippage difference for blockID for accepting proving a block", + Value: 1024, + Category: proverCategory, + EnvVars: []string{"PROVER_BLOCK_SLIPPAGE"}, + } + // Max amount of L1 blocks that can pass before block is invalid + MaxProposedIn = &cli.Uint64Flag{ + Name: "prover.maxProposedIn", + Usage: "Maximum amount of L1 blocks that can pass before block can not be proposed. 0 means no limit.", + Value: 0, + Category: proverCategory, + EnvVars: []string{"PROVER_MAX_PROPOSED_IN"}, + } + Allowance = &cli.Float64Flag{ + Name: "prover.allowance", + Usage: "Amount without decimal to approve AssignmentHook contract for TaikoToken usage", + Category: proverCategory, + EnvVars: []string{"PROVER_ALLOWANCE"}, + } + GuardianProverHealthCheckServerEndpoint = &cli.StringFlag{ + Name: "prover.guardianProverHealthCheckServerEndpoint", + Usage: "HTTP endpoint for main guardian prover health check server", + Category: proverCategory, + EnvVars: []string{"PROVER_GUARDIAN_PROVER_HEALTH_CHECK_SERVER_ENDPOINT"}, + } + // Guardian prover specific flag + GuardianProver = &cli.StringFlag{ + Name: "guardianProver", + Usage: "GuardianProver contract `address`", + Category: proverCategory, + EnvVars: []string{"GUARDIAN_PROVER"}, + } + GuardianProofSubmissionDelay = &cli.DurationFlag{ + Name: "guardian.submissionDelay", + Usage: "Guardian proof submission delay", + Value: 1 * time.Hour, + Category: proverCategory, + EnvVars: []string{"GUARDIAN_SUBMISSION_DELAY"}, + } + EnableLivenessBondProof = &cli.BoolFlag{ + Name: "prover.enableLivenessBondProof", + Usage: "Toggles whether the proof is a dummy proof or returns keccak256(RETURN_LIVENESS_BOND) as proof", + Value: false, + Category: proverCategory, + EnvVars: []string{"PROVER_ENABLE_LIVENESS_BOND_PROOF"}, + } + L1NodeVersion = &cli.StringFlag{ + Name: "prover.l1NodeVersion", + Usage: "Version or tag or the L1 Node Version used as an L1 RPC Url by this guardian prover", + Category: proverCategory, + EnvVars: []string{"PROVER_L1_NODE_VERSION"}, + } + L2NodeVersion = &cli.StringFlag{ + Name: "prover.l2NodeVersion", + Usage: "Version or tag or the L2 Node Version used as an L2 RPC Url by this guardian prover", + Category: proverCategory, + EnvVars: []string{"PROVER_L2_NODE_VERSION"}, + } + // Confirmations specific flag + BlockConfirmations = &cli.Uint64Flag{ + Name: "prover.blockConfirmations", + Usage: "Confirmations to the latest L1 block before submitting a proof for a L2 block", + Value: 6, + Category: proverCategory, + EnvVars: []string{"PROVER_BLOCK_CONFIRMATIONS"}, + } +) + +// ProverFlags All prover flags. +var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{ + L1HTTPEndpoint, + L1BeaconEndpoint, + L2WSEndpoint, + L2HTTPEndpoint, + RaikoHostEndpoint, + RaikoL1Endpoint, + RaikoL1BeaconEndpoint, + RaikoL2Endpoint, + L1ProverPrivKey, + MinOptimisticTierFee, + MinSgxTierFee, + MinSgxAndZkVMTierFee, + MinEthBalance, + MinTaikoTokenBalance, + StartingBlockID, + Dummy, + GuardianProver, + GuardianProofSubmissionDelay, + GuardianProverHealthCheckServerEndpoint, + Graffiti, + ProveUnassignedBlocks, + ContesterMode, + ProverHTTPServerPort, + ProverCapacity, + MaxExpiry, + MaxProposedIn, + TaikoTokenAddress, + MaxAcceptableBlockSlippage, + AssignmentHookAddress, + Allowance, + L1NodeVersion, + L2NodeVersion, + BlockConfirmations, +}, TxmgrFlags) diff --git a/packages/taiko-client/cmd/flags/txmgr.go b/packages/taiko-client/cmd/flags/txmgr.go new file mode 100644 index 00000000000..640f13a457f --- /dev/null +++ b/packages/taiko-client/cmd/flags/txmgr.go @@ -0,0 +1,103 @@ +package flags + +import ( + "time" + + "github.com/urfave/cli/v2" +) + +var ( + NumConfirmations = &cli.Uint64Flag{ + Name: "tx.numConfirmations", + Usage: "Number of confirmations which we will wait after sending a transaction", + Value: 0, + Category: txmgrCategory, + EnvVars: []string{"TX_NUM_CONFIRMATIONS"}, + } + SafeAbortNonceTooLowCount = &cli.Uint64Flag{ + Name: "tx.safeAbortNonceTooLowCount", + Usage: "Number of ErrNonceTooLow observations required to give up on " + + "a tx at a particular nonce without receiving confirmation", + Value: 3, + Category: txmgrCategory, + EnvVars: []string{"TX_SAFE_ABORT_NONCE_TOO_LOW_COUNT"}, + } + FeeLimitMultiplier = &cli.Uint64Flag{ + Name: "tx.feeLimitMultiplier", + Usage: "The multiplier applied to fee suggestions to put a hard limit on fee increases", + Value: 10, + Category: txmgrCategory, + EnvVars: []string{"TX_FEE_LIMIT_MULTIPLIER"}, + } + FeeLimitThreshold = &cli.Float64Flag{ + Name: "tx.feeLimitThreshold", + Usage: "The minimum threshold (in GWei) at which fee bumping starts to be capped. " + + "Allows arbitrary fee bumps below this threshold.", + Value: 100.0, + Category: txmgrCategory, + EnvVars: []string{"TX_FEE_LIMIT_THRESHOLD"}, + } + MinTipCap = &cli.Float64Flag{ + Name: "tx.minTipCap", + Usage: "Enforces a minimum tip cap (in GWei) to use when determining tx fees. 1 GWei by default.", + Value: 1.0, + Category: txmgrCategory, + EnvVars: []string{"TX_MIN_TIP_CAP"}, + } + MinBaseFee = &cli.Float64Flag{ + Name: "tx.minBaseFee", + Usage: "Enforces a minimum base fee (in GWei) to assume when determining tx fees. 1 GWei by default.", + Value: 1.0, + Category: txmgrCategory, + EnvVars: []string{"TX_MIN_BASE_FEE"}, + } + ResubmissionTimeout = &cli.DurationFlag{ + Name: "tx.resubmissionTimeout", + Usage: "Duration we will wait before resubmitting a transaction to L1", + Value: 48 * time.Second, + Category: txmgrCategory, + EnvVars: []string{"TX_RESUBMISSION_TIMEOUT"}, + } + TxSendTimeout = &cli.DurationFlag{ + Name: "tx.sendTimeout", + Usage: "Timeout for sending transactions. If 0 it is disabled.", + Value: 0, + Category: txmgrCategory, + EnvVars: []string{"TX_SEND_TIMEOUT"}, + } + TxNotInMempoolTimeout = &cli.DurationFlag{ + Name: "tx.notInMempoolTimeout", + Usage: "Timeout for aborting a tx send if the tx does not make it to the mempool.", + Value: 2 * time.Minute, + Category: txmgrCategory, + EnvVars: []string{"TX_NOT_IN_MEMPOOL_TIMEOUT"}, + } + ReceiptQueryInterval = &cli.DurationFlag{ + Name: "tx.receiptQueryInterval", + Usage: "Frequency to poll for receipts", + Value: 12 * time.Second, + Category: txmgrCategory, + EnvVars: []string{"TX_RECEIPT_QUERY_INTERVAL"}, + } + TxGasLimit = &cli.Uint64Flag{ + Name: "tx.gasLimit", + Usage: "Gas limit will be used for transactions (0 means using gas estimation)", + Value: 0, + Category: txmgrCategory, + EnvVars: []string{"TX_GAS_LIMIT"}, + } +) + +var TxmgrFlags = []cli.Flag{ + NumConfirmations, + SafeAbortNonceTooLowCount, + FeeLimitMultiplier, + FeeLimitThreshold, + MinTipCap, + MinBaseFee, + ResubmissionTimeout, + TxSendTimeout, + TxNotInMempoolTimeout, + ReceiptQueryInterval, + TxGasLimit, +} diff --git a/packages/taiko-client/cmd/logger/logger.go b/packages/taiko-client/cmd/logger/logger.go new file mode 100644 index 00000000000..f339a3db03a --- /dev/null +++ b/packages/taiko-client/cmd/logger/logger.go @@ -0,0 +1,27 @@ +package logger + +import ( + "os" + + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" +) + +// InitLogger initializes the root logger with the command line flags. +func InitLogger(c *cli.Context) { + var ( + slogVerbosity = log.FromLegacyLevel(c.Int(flags.Verbosity.Name)) + ) + + if c.Bool(flags.LogJSON.Name) { + glogger := log.NewGlogHandler(log.NewGlogHandler(log.JSONHandler(os.Stdout))) + glogger.Verbosity(slogVerbosity) + log.SetDefault(log.NewLogger(glogger)) + } else { + glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stdout, true)) + glogger.Verbosity(slogVerbosity) + log.SetDefault(log.NewLogger(glogger)) + } +} diff --git a/packages/taiko-client/cmd/main.go b/packages/taiko-client/cmd/main.go new file mode 100644 index 00000000000..faa81b91690 --- /dev/null +++ b/packages/taiko-client/cmd/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/cmd/utils" + "github.com/taikoxyz/taiko-client/driver" + "github.com/taikoxyz/taiko-client/internal/version" + "github.com/taikoxyz/taiko-client/proposer" + "github.com/taikoxyz/taiko-client/prover" +) + +func main() { + app := cli.NewApp() + + app.Name = "Taiko Clients" + app.Usage = "The taiko client software command line interface" + app.Copyright = "Copyright 2021-2022 Taiko Labs" + app.Version = version.CommitVersion() + app.Description = "Client software implementation in Golang for Taiko protocol" + app.Authors = []*cli.Author{{Name: "Taiko Labs", Email: "info@taiko.xyz"}} + app.EnableBashCompletion = true + + // All supported sub commands. + app.Commands = []*cli.Command{ + { + Name: "driver", + Flags: flags.DriverFlags, + Usage: "Starts the driver software", + Description: "Taiko driver software", + Action: utils.SubcommandAction(new(driver.Driver)), + }, + { + Name: "proposer", + Flags: flags.ProposerFlags, + Usage: "Starts the proposer software", + Description: "Taiko proposer software", + Action: utils.SubcommandAction(new(proposer.Proposer)), + }, + { + Name: "prover", + Flags: flags.ProverFlags, + Usage: "Starts the prover software", + Description: "Taiko prover software", + Action: utils.SubcommandAction(new(prover.Prover)), + }, + } + + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/packages/taiko-client/cmd/utils/sub_command.go b/packages/taiko-client/cmd/utils/sub_command.go new file mode 100644 index 00000000000..d4149a19ec3 --- /dev/null +++ b/packages/taiko-client/cmd/utils/sub_command.go @@ -0,0 +1,63 @@ +package utils + +import ( + "context" + "os" + "os/signal" + "syscall" + + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/logger" + "github.com/taikoxyz/taiko-client/internal/metrics" +) + +type SubcommandApplication interface { + InitFromCli(context.Context, *cli.Context) error + Name() string + Start() error + Close(context.Context) +} + +func SubcommandAction(app SubcommandApplication) cli.ActionFunc { + return func(c *cli.Context) error { + logger.InitLogger(c) + + ctx, ctxClose := context.WithCancel(context.Background()) + defer ctxClose() + + if err := app.InitFromCli(ctx, c); err != nil { + return err + } + + log.Info("Starting Taiko client application", "name", app.Name()) + + if err := app.Start(); err != nil { + log.Error("Starting application error", "name", app.Name(), "error", err) + return err + } + + if err := metrics.Serve(ctx, c); err != nil { + log.Error("Starting metrics server error", "error", err) + return err + } + + defer func() { + ctxClose() + app.Close(ctx) + log.Info("Application stopped", "name", app.Name()) + }() + + quitCh := make(chan os.Signal, 1) + signal.Notify(quitCh, []os.Signal{ + os.Interrupt, + os.Kill, + syscall.SIGTERM, + syscall.SIGQUIT, + }...) + <-quitCh + + return nil + } +} diff --git a/packages/taiko-client/codecov.yml b/packages/taiko-client/codecov.yml new file mode 100644 index 00000000000..677e4001775 --- /dev/null +++ b/packages/taiko-client/codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + patch: off + project: off +fixes: + - "taiko-client/::" diff --git a/packages/taiko-client/docs/docs.go b/packages/taiko-client/docs/docs.go new file mode 100644 index 00000000000..3dab57e7c64 --- /dev/null +++ b/packages/taiko-client/docs/docs.go @@ -0,0 +1,170 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "https://community.taiko.xyz/", + "email": "info@taiko.xyz" + }, + "license": { + "name": "MIT", + "url": "https://github.com/taikoxyz/taiko-client/blob/main/LICENSE.md" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/assignment": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Try to accept a block proof assignment", + "parameters": [ + { + "description": "assignment request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/server.CreateAssignmentRequestBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/server.ProposeBlockResponse" + } + }, + "422": { + "description": "prover does not have capacity", + "schema": { + "type": "string" + } + } + } + } + }, + "/status": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Get current prover server status", + "operationId": "get-status", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/server.Status" + } + } + } + } + } + }, + "definitions": { + "server.CreateAssignmentRequestBody": { + "type": "object", + "properties": { + "blobHash": { + "type": "array", + "items": { + "type": "integer" + } + }, + "expiry": { + "type": "integer" + }, + "feeToken": { + "type": "string" + }, + "proposer": { + "type": "string" + }, + "tierFees": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "server.ProposeBlockResponse": { + "type": "object", + "properties": { + "maxBlockID": { + "type": "integer" + }, + "maxProposedIn": { + "type": "integer" + }, + "prover": { + "type": "string" + }, + "signedPayload": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "server.Status": { + "type": "object", + "properties": { + "maxExpiry": { + "type": "integer" + }, + "minOptimisticTierFee": { + "type": "integer" + }, + "minSgxAndZkVMTierFee": { + "type": "integer" + }, + "minSgxTierFee": { + "type": "integer" + }, + "prover": { + "type": "string" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "Taiko Prover Server API", + Description: "", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/packages/taiko-client/docs/swagger.json b/packages/taiko-client/docs/swagger.json new file mode 100644 index 00000000000..607f9139a21 --- /dev/null +++ b/packages/taiko-client/docs/swagger.json @@ -0,0 +1,143 @@ +{ + "swagger": "2.0", + "info": { + "title": "Taiko Prover Server API", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "https://community.taiko.xyz/", + "email": "info@taiko.xyz" + }, + "license": { + "name": "MIT", + "url": "https://github.com/taikoxyz/taiko-client/blob/main/LICENSE.md" + }, + "version": "1.0" + }, + "paths": { + "/assignment": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Try to accept a block proof assignment", + "parameters": [ + { + "description": "assignment request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/server.CreateAssignmentRequestBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/server.ProposeBlockResponse" + } + }, + "422": { + "description": "prover does not have capacity", + "schema": { + "type": "string" + } + } + } + } + }, + "/status": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Get current prover server status", + "operationId": "get-status", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/server.Status" + } + } + } + } + } + }, + "definitions": { + "server.CreateAssignmentRequestBody": { + "type": "object", + "properties": { + "blobHash": { + "type": "array", + "items": { + "type": "integer" + } + }, + "expiry": { + "type": "integer" + }, + "feeToken": { + "type": "string" + }, + "proposer": { + "type": "string" + }, + "tierFees": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "server.ProposeBlockResponse": { + "type": "object", + "properties": { + "maxBlockID": { + "type": "integer" + }, + "maxProposedIn": { + "type": "integer" + }, + "prover": { + "type": "string" + }, + "signedPayload": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "server.Status": { + "type": "object", + "properties": { + "maxExpiry": { + "type": "integer" + }, + "minOptimisticTierFee": { + "type": "integer" + }, + "minSgxAndZkVMTierFee": { + "type": "integer" + }, + "minSgxTierFee": { + "type": "integer" + }, + "prover": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/packages/taiko-client/docs/swagger.yaml b/packages/taiko-client/docs/swagger.yaml new file mode 100644 index 00000000000..579acff4b28 --- /dev/null +++ b/packages/taiko-client/docs/swagger.yaml @@ -0,0 +1,93 @@ +definitions: + server.CreateAssignmentRequestBody: + properties: + blobHash: + items: + type: integer + type: array + expiry: + type: integer + feeToken: + type: string + proposer: + type: string + tierFees: + items: + type: integer + type: array + type: object + server.ProposeBlockResponse: + properties: + maxBlockID: + type: integer + maxProposedIn: + type: integer + prover: + type: string + signedPayload: + items: + type: integer + type: array + type: object + server.Status: + properties: + maxExpiry: + type: integer + minOptimisticTierFee: + type: integer + minSgxAndZkVMTierFee: + type: integer + minSgxTierFee: + type: integer + prover: + type: string + type: object +info: + contact: + email: info@taiko.xyz + name: API Support + url: https://community.taiko.xyz/ + license: + name: MIT + url: https://github.com/taikoxyz/taiko-client/blob/main/LICENSE.md + termsOfService: http://swagger.io/terms/ + title: Taiko Prover Server API + version: "1.0" +paths: + /assignment: + post: + consumes: + - application/json + parameters: + - description: assignment request body + in: body + name: body + required: true + schema: + $ref: '#/definitions/server.CreateAssignmentRequestBody' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/server.ProposeBlockResponse' + "422": + description: prover does not have capacity + schema: + type: string + summary: Try to accept a block proof assignment + /status: + get: + consumes: + - application/json + operationId: get-status + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/server.Status' + summary: Get current prover server status +swagger: "2.0" diff --git a/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor.go b/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor.go new file mode 100644 index 00000000000..0c014aa055b --- /dev/null +++ b/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor.go @@ -0,0 +1,143 @@ +package anchortxconstructor + +import ( + "context" + "fmt" + "math/big" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "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/log" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver/signer" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// Each TaikoL2.anchor transaction should use this value as it's gas limit. +const AnchorGasLimit = 250_000 + +// AnchorTxConstructor is responsible for assembling the anchor transaction (TaikoL2.anchor) in +// each L2 block, which must be the first transaction, and its sender must be the golden touch account. +type AnchorTxConstructor struct { + rpc *rpc.Client + goldenTouchAddress common.Address + signer *signer.FixedKSigner +} + +// New creates a new AnchorConstructor instance. +func New(rpc *rpc.Client) (*AnchorTxConstructor, error) { + goldenTouchAddress, err := rpc.TaikoL2.GOLDENTOUCHADDRESS(nil) + if err != nil { + return nil, err + } + + signer, err := signer.NewFixedKSigner("0x" + encoding.GoldenTouchPrivKey) + if err != nil { + return nil, fmt.Errorf("invalid golden touch private key %s", encoding.GoldenTouchPrivKey) + } + + return &AnchorTxConstructor{rpc, goldenTouchAddress, signer}, nil +} + +// AssembleAnchorTx assembles a signed TaikoL2.anchor transaction. +func (c *AnchorTxConstructor) AssembleAnchorTx( + ctx context.Context, + // Parameters of the TaikoL2.anchor transaction. + l1Height *big.Int, + l1Hash common.Hash, + // Height of the L2 block which including the TaikoL2.anchor transaction. + l2Height *big.Int, + baseFee *big.Int, + parentGasUsed uint64, +) (*types.Transaction, error) { + opts, err := c.transactOpts(ctx, l2Height, baseFee) + if err != nil { + return nil, err + } + + l1Header, err := c.rpc.L1.HeaderByHash(ctx, l1Hash) + if err != nil { + return nil, err + } + + log.Info( + "Anchor arguments", + "l2Height", l2Height, + "l1Height", l1Height, + "l1Hash", l1Hash, + "stateRoot", l1Header.Root, + "baseFee", utils.WeiToGWei(baseFee), + "gasUsed", parentGasUsed, + ) + + return c.rpc.TaikoL2.Anchor(opts, l1Hash, l1Header.Root, l1Height.Uint64(), uint32(parentGasUsed)) +} + +// transactOpts is a utility method to create some transact options of the anchor transaction in given L2 block with +// golden touch account's private key. +func (c *AnchorTxConstructor) transactOpts( + ctx context.Context, + l2Height *big.Int, + baseFee *big.Int, +) (*bind.TransactOpts, error) { + var ( + signer = types.LatestSignerForChainID(c.rpc.L2.ChainID) + parentHeight = new(big.Int).Sub(l2Height, common.Big1) + ) + + // Get the nonce of golden touch account at the specified parentHeight. + nonce, err := c.rpc.L2AccountNonce(ctx, c.goldenTouchAddress, parentHeight) + if err != nil { + return nil, err + } + + log.Info( + "Golden touch account nonce", + "address", c.goldenTouchAddress, + "nonce", nonce, + "parent", parentHeight, + ) + + return &bind.TransactOpts{ + From: c.goldenTouchAddress, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != c.goldenTouchAddress { + return nil, bind.ErrNotAuthorized + } + signature, err := c.signTxPayload(signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + Nonce: new(big.Int).SetUint64(nonce), + Context: ctx, + GasFeeCap: baseFee, + GasTipCap: common.Big0, + GasLimit: AnchorGasLimit, + NoSend: true, + }, nil +} + +// signTxPayload calculates an ECDSA signature for an anchor transaction. +func (c *AnchorTxConstructor) signTxPayload(hash []byte) ([]byte, error) { + if len(hash) != 32 { + return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) + } + + // Try k = 1. + sig, ok := c.signer.SignWithK(new(secp256k1.ModNScalar).SetInt(1))(hash) + if !ok { + // Try k = 2. + sig, ok = c.signer.SignWithK(new(secp256k1.ModNScalar).SetInt(2))(hash) + if !ok { + log.Crit("Failed to sign TaikoL2.anchor transaction using K = 1 and K = 2") + } + } + + return sig[:], nil +} diff --git a/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor_test.go b/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor_test.go new file mode 100644 index 00000000000..135179779a5 --- /dev/null +++ b/packages/taiko-client/driver/anchor_tx_constructor/anchor_tx_constructor_test.go @@ -0,0 +1,109 @@ +package anchortxconstructor + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +type AnchorTxConstructorTestSuite struct { + testutils.ClientTestSuite + l1Height *big.Int + l1Hash common.Hash + c *AnchorTxConstructor +} + +func (s *AnchorTxConstructorTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + c, err := New(s.RPCClient) + s.Nil(err) + head, err := s.RPCClient.L1.BlockByNumber(context.Background(), nil) + s.Nil(err) + s.l1Height = head.Number() + s.l1Hash = head.Hash() + s.c = c +} + +func (s *AnchorTxConstructorTestSuite) TestGasLimit() { + s.Greater(AnchorGasLimit, 0) +} + +func (s *AnchorTxConstructorTestSuite) TestAssembleAnchorTx() { + tx, err := s.c.AssembleAnchorTx(context.Background(), s.l1Height, s.l1Hash, common.Big1, common.Big256, 1024) + s.Nil(err) + s.NotNil(tx) +} + +func (s *AnchorTxConstructorTestSuite) TestNewAnchorTransactor() { + goldenTouchAddress, err := s.RPCClient.TaikoL2.GOLDENTOUCHADDRESS(nil) + s.Nil(err) + + c, err := New(s.RPCClient) + s.Nil(err) + + opts, err := c.transactOpts(context.Background(), common.Big1, common.Big256) + s.Nil(err) + s.Equal(true, opts.NoSend) + s.Equal(common.Big0, opts.Nonce) + s.Equal(goldenTouchAddress, opts.From) + s.Equal(common.Big256, opts.GasFeeCap) + s.Equal(common.Big0, opts.GasTipCap) +} + +func (s *AnchorTxConstructorTestSuite) TestCancelCtxTransactOpts() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + opts, err := s.c.transactOpts(ctx, common.Big1, common.Big256) + s.Nil(opts) + s.ErrorContains(err, "context canceled") +} + +func (s *AnchorTxConstructorTestSuite) TestSign() { + // Payload 1 + hash := hexutil.MustDecode("0x44943399d1507f3ce7525e9be2f987c3db9136dc759cb7f92f742154196868b9") + signatureBytes := testutils.SignatureFromRSV( + "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "0x782a1e70872ecc1a9f740dd445664543f8b7598c94582720bca9a8c48d6a4766", + 1, + ) + pubKey, err := crypto.Ecrecover(hash, signatureBytes) + s.Nil(err) + isValid := crypto.VerifySignature(pubKey, hash, signatureBytes[:64]) + s.True(isValid) + signed, err := s.c.signTxPayload(hash) + s.Nil(err) + s.Equal(signatureBytes, signed) + + // Payload 2 + hash = hexutil.MustDecode("0x663d210fa6dba171546498489de1ba024b89db49e21662f91bf83cdffe788820") + signatureBytes = testutils.SignatureFromRSV( + "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "0x568130fab1a3a9e63261d4278a7e130588beb51f27de7c20d0258d38a85a27ff", + 1, + ) + pubKey, err = crypto.Ecrecover(hash, signatureBytes) + s.Nil(err) + isValid = crypto.VerifySignature(pubKey, hash, signatureBytes[:64]) + s.True(isValid) + signed, err = s.c.signTxPayload(hash) + s.Nil(err) + s.Equal(signatureBytes, signed) +} + +func (s *AnchorTxConstructorTestSuite) TestSignShortHash() { + rand := testutils.RandomHash().Bytes() + hash := rand[:len(rand)-2] + _, err := s.c.signTxPayload(hash) + s.ErrorContains(err, "hash is required to be exactly 32 bytes") +} + +func TestAnchorTxConstructorTestSuite(t *testing.T) { + suite.Run(t, new(AnchorTxConstructorTestSuite)) +} diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go new file mode 100644 index 00000000000..84ce02e34a4 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go @@ -0,0 +1,260 @@ +package beaconsync + +import ( + "context" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +var ( + syncProgressCheckInterval = 12 * time.Second +) + +// SyncProgressTracker is responsible for tracking the L2 execution engine's sync progress, after +// a beacon sync is triggered, and check whether the L2 execution is not able to sync through P2P (due to no +// connected peer or some other reasons). +type SyncProgressTracker struct { + // RPC client + client *rpc.EthClient + + // Meta data + triggered bool + lastSyncedBlockID *big.Int + lastSyncedBlockHash common.Hash + + // Out-of-sync check related + lastSyncProgress *ethereum.SyncProgress + lastProgressedTime time.Time + timeout time.Duration + outOfSync bool + ticker *time.Ticker + + // A marker to indicate whether the beacon sync has been finished. + finished bool + + // Read-write mutex + mutex sync.RWMutex +} + +// NewSyncProgressTracker creates a new SyncProgressTracker instance. +func NewSyncProgressTracker(c *rpc.EthClient, timeout time.Duration) *SyncProgressTracker { + return &SyncProgressTracker{client: c, timeout: timeout, ticker: time.NewTicker(syncProgressCheckInterval)} +} + +// Track starts the inner event loop, to monitor the sync progress. +func (t *SyncProgressTracker) Track(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case <-t.ticker.C: + t.track(ctx) + } + } +} + +// track is the internal implementation of MonitorSyncProgress, tries to +// track the L2 execution engine's beacon sync progress. +func (t *SyncProgressTracker) track(ctx context.Context) { + t.mutex.Lock() + defer t.mutex.Unlock() + + if !t.triggered { + log.Debug("Beacon sync not triggered") + return + } + + if t.outOfSync { + return + } + + progress, err := t.client.SyncProgress(ctx) + if err != nil { + log.Error("Get L2 execution engine sync progress error", "error", err) + return + } + + if progress != nil { + log.Info( + "L2 execution engine sync progress", + "progress", progress, + "lastProgressedTime", t.lastProgressedTime, + "timeout", t.timeout, + ) + } + + if progress == nil { + headHeight, err := t.client.BlockNumber(ctx) + if err != nil { + log.Error("Get L2 execution engine head height error", "error", err) + return + } + + if new(big.Int).SetUint64(headHeight).Cmp(t.lastSyncedBlockID) >= 0 { + t.lastProgressedTime = time.Now() + log.Info( + "L2 execution engine has finished the P2P sync work, all verified blocks synced, "+ + "will switch to insert pending blocks one by one", + "lastSyncedBlockID", t.lastSyncedBlockID, + "lastSyncedBlockHash", t.lastSyncedBlockHash, + ) + return + } + + log.Info("L2 execution engine has not started P2P syncing yet", "timeout", t.timeout) + } + + defer func() { t.lastSyncProgress = progress }() + + // Check whether the L2 execution engine has synced any new block through P2P since last event loop. + if syncProgressed(t.lastSyncProgress, progress) { + t.outOfSync = false + t.lastProgressedTime = time.Now() + return + } + + // Has not synced any new block since last loop, check whether reaching the timeout. + if time.Since(t.lastProgressedTime) > t.timeout { + // Mark the L2 execution engine out of sync. + t.outOfSync = true + + log.Warn( + "L2 execution engine is not able to sync through P2P", + "lastProgressedTime", t.lastProgressedTime, + "timeout", t.timeout, + ) + } +} + +// UpdateMeta updates the inner beacon sync metadata. +func (t *SyncProgressTracker) UpdateMeta(id *big.Int, blockHash common.Hash) { + t.mutex.Lock() + defer t.mutex.Unlock() + + log.Debug("Update sync progress tracker meta", "id", id, "hash", blockHash) + + if !t.triggered { + t.lastProgressedTime = time.Now() + } + + t.triggered = true + t.lastSyncedBlockID = id + t.lastSyncedBlockHash = blockHash +} + +// ClearMeta cleans the inner beacon sync metadata. +func (t *SyncProgressTracker) ClearMeta() { + t.mutex.Lock() + defer t.mutex.Unlock() + + log.Debug("Clear sync progress tracker meta") + + t.triggered = false + t.lastSyncedBlockID = nil + t.lastSyncedBlockHash = common.Hash{} + t.outOfSync = false +} + +// HeadChanged checks if a new beacon sync request will be needed. +func (t *SyncProgressTracker) HeadChanged(newID *big.Int) bool { + t.mutex.RLock() + defer t.mutex.RUnlock() + + if !t.triggered { + return true + } + + return t.lastSyncedBlockID != nil && t.lastSyncedBlockID != newID +} + +// OutOfSync tells whether the L2 execution engine is marked as out of sync. +func (t *SyncProgressTracker) OutOfSync() bool { + t.mutex.RLock() + defer t.mutex.RUnlock() + + return t.outOfSync +} + +// Triggered returns tracker.triggered. +func (t *SyncProgressTracker) Triggered() bool { + t.mutex.RLock() + defer t.mutex.RUnlock() + + return t.triggered +} + +// LastSyncedBlockID returns tracker.lastSyncedBlockID. +func (t *SyncProgressTracker) LastSyncedBlockID() *big.Int { + t.mutex.RLock() + defer t.mutex.RUnlock() + + if t.lastSyncedBlockID == nil { + return nil + } + + return new(big.Int).Set(t.lastSyncedBlockID) +} + +// LastSyncedBlockHash returns tracker.lastSyncedBlockHash. +func (t *SyncProgressTracker) LastSyncedBlockHash() common.Hash { + t.mutex.RLock() + defer t.mutex.RUnlock() + + return t.lastSyncedBlockHash +} + +// syncProgressed checks whether there is any new progress since last sync progress check. +func syncProgressed(last *ethereum.SyncProgress, new *ethereum.SyncProgress) bool { + if last == nil { + return false + } + + if new == nil { + return true + } + + // Block + if new.CurrentBlock > last.CurrentBlock { + return true + } + + // Fast sync fields + if new.PulledStates > last.PulledStates { + return true + } + + // Snap sync fields + if new.SyncedAccounts > last.SyncedAccounts || + new.SyncedAccountBytes > last.SyncedAccountBytes || + new.SyncedBytecodes > last.SyncedBytecodes || + new.SyncedBytecodeBytes > last.SyncedBytecodeBytes || + new.SyncedStorage > last.SyncedStorage || + new.SyncedStorageBytes > last.SyncedStorageBytes || + new.HealedTrienodes > last.HealedTrienodes || + new.HealedTrienodeBytes > last.HealedTrienodeBytes || + new.HealedBytecodes > last.HealedBytecodes || + new.HealedBytecodeBytes > last.HealedBytecodeBytes || + new.HealingTrienodes > last.HealingTrienodes || + new.HealingBytecode > last.HealingBytecode { + return true + } + + return false +} + +// MarkFinished marks the current beacon sync as finished. +func (t *SyncProgressTracker) MarkFinished() { + t.finished = true +} + +// Finished returns whether the current beacon sync has been finished. +func (t *SyncProgressTracker) Finished() bool { + return t.finished +} diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go new file mode 100644 index 00000000000..aec59e245a5 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go @@ -0,0 +1,90 @@ +package beaconsync + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +type BeaconSyncProgressTrackerTestSuite struct { + testutils.ClientTestSuite + t *SyncProgressTracker +} + +func (s *BeaconSyncProgressTrackerTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + s.t = NewSyncProgressTracker(s.RPCClient.L2, 30*time.Second) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestSyncProgressed() { + s.False(syncProgressed(nil, ðereum.SyncProgress{}), nil) + s.False(syncProgressed(ðereum.SyncProgress{}, ðereum.SyncProgress{})) + + // Block + s.True(syncProgressed(ðereum.SyncProgress{CurrentBlock: 0}, ðereum.SyncProgress{CurrentBlock: 1})) + s.False(syncProgressed(ðereum.SyncProgress{CurrentBlock: 0}, ðereum.SyncProgress{CurrentBlock: 0})) + s.False(syncProgressed(ðereum.SyncProgress{CurrentBlock: 1}, ðereum.SyncProgress{CurrentBlock: 1})) + + // Fast sync fields + s.True(syncProgressed(ðereum.SyncProgress{PulledStates: 0}, ðereum.SyncProgress{PulledStates: 1})) + + // Snap sync fields + s.True(syncProgressed(ðereum.SyncProgress{SyncedAccounts: 0}, ðereum.SyncProgress{SyncedAccounts: 1})) + s.True(syncProgressed(ðereum.SyncProgress{SyncedAccountBytes: 0}, ðereum.SyncProgress{SyncedAccountBytes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{SyncedBytecodes: 0}, ðereum.SyncProgress{SyncedBytecodes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{SyncedBytecodeBytes: 0}, ðereum.SyncProgress{SyncedBytecodeBytes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{SyncedStorage: 0}, ðereum.SyncProgress{SyncedStorage: 1})) + s.True(syncProgressed(ðereum.SyncProgress{SyncedStorageBytes: 0}, ðereum.SyncProgress{SyncedStorageBytes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealedTrienodes: 0}, ðereum.SyncProgress{HealedTrienodes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealedTrienodeBytes: 0}, ðereum.SyncProgress{HealedTrienodeBytes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealedBytecodes: 0}, ðereum.SyncProgress{HealedBytecodes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealedBytecodeBytes: 0}, ðereum.SyncProgress{HealedBytecodeBytes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealingTrienodes: 0}, ðereum.SyncProgress{HealingTrienodes: 1})) + s.True(syncProgressed(ðereum.SyncProgress{HealingBytecode: 0}, ðereum.SyncProgress{HealingBytecode: 1})) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestClearMeta() { + s.t.triggered = true + s.t.ClearMeta() + s.False(s.t.triggered) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestHeadChanged() { + s.True(s.t.HeadChanged(common.Big256)) + s.t.triggered = true + s.False(s.t.HeadChanged(common.Big256)) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestOutOfSync() { + s.False(s.t.OutOfSync()) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestTriggered() { + s.False(s.t.Triggered()) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestLastSyncedBlockID() { + s.Nil(s.t.LastSyncedBlockID()) + s.t.lastSyncedBlockID = common.Big1 + s.Equal(common.Big1.Uint64(), s.t.LastSyncedBlockID().Uint64()) +} + +func (s *BeaconSyncProgressTrackerTestSuite) TestLastSyncedVerifiedBlockHash() { + s.Equal( + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + s.t.LastSyncedBlockHash(), + ) + randomHash := testutils.RandomHash() + s.t.lastSyncedBlockHash = randomHash + s.Equal(randomHash, s.t.LastSyncedBlockHash()) +} + +func TestBeaconSyncProgressTrackerTestSuite(t *testing.T) { + suite.Run(t, new(BeaconSyncProgressTrackerTestSuite)) +} diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go new file mode 100644 index 00000000000..9ac12beed52 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -0,0 +1,124 @@ +package beaconsync + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// Syncer responsible for letting the L2 execution engine catching up with protocol's latest +// verified block through P2P beacon sync. +type Syncer struct { + ctx context.Context + rpc *rpc.Client + state *state.State + syncMode string + progressTracker *SyncProgressTracker // Sync progress tracker +} + +// NewSyncer creates a new syncer instance. +func NewSyncer( + ctx context.Context, + rpc *rpc.Client, + state *state.State, + syncMode string, + progressTracker *SyncProgressTracker, +) *Syncer { + return &Syncer{ctx, rpc, state, syncMode, progressTracker} +} + +// TriggerBeaconSync triggers the L2 execution engine to start performing a beacon sync, if the +// latest verified block has changed. +func (s *Syncer) TriggerBeaconSync(blockID uint64) error { + latestVerifiedHeadPayload, err := s.getVerifiedBlockPayload(s.ctx, blockID) + if err != nil { + return err + } + + if !s.progressTracker.HeadChanged(new(big.Int).SetUint64(blockID)) { + log.Debug("Verified head has not changed", "blockID", blockID, "hash", latestVerifiedHeadPayload.BlockHash) + return nil + } + + if s.progressTracker.Triggered() { + if s.progressTracker.lastSyncProgress == nil { + log.Info( + "Syncing beacon headers, please check L2 execution engine logs for progress", + "currentSyncHead", s.progressTracker.LastSyncedBlockID(), + "newBlockID", blockID, + ) + } + } + + status, err := s.rpc.L2Engine.NewPayload(s.ctx, latestVerifiedHeadPayload) + if err != nil { + return err + } + + if status.Status != engine.SYNCING && status.Status != engine.VALID { + return fmt.Errorf("unexpected NewPayload response status: %s", status.Status) + } + + fcRes, err := s.rpc.L2Engine.ForkchoiceUpdate(s.ctx, &engine.ForkchoiceStateV1{ + HeadBlockHash: latestVerifiedHeadPayload.BlockHash, + SafeBlockHash: latestVerifiedHeadPayload.BlockHash, + FinalizedBlockHash: latestVerifiedHeadPayload.BlockHash, + }, nil) + if err != nil { + return err + } + if fcRes.PayloadStatus.Status != engine.SYNCING { + return fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) + } + + // Update sync status. + s.progressTracker.UpdateMeta(new(big.Int).SetUint64(blockID), latestVerifiedHeadPayload.BlockHash) + + log.Info( + "⛓️ Beacon sync triggered", + "newHeadID", blockID, + "newHeadHash", s.progressTracker.LastSyncedBlockHash(), + ) + + return nil +} + +// getVerifiedBlockPayload fetches the latest verified block's header, and converts it to an Engine API executable data, +// which will be used to let the node start beacon syncing. +func (s *Syncer) getVerifiedBlockPayload(ctx context.Context, blockID uint64) (*engine.ExecutableData, error) { + header, err := s.rpc.L2CheckPoint.HeaderByNumber(s.ctx, new(big.Int).SetUint64(blockID)) + if err != nil { + return nil, err + } + + if s.syncMode == downloader.FullSync.String() { + blockInfo, err := s.rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(blockID)) + if err != nil { + return nil, err + } + ts, err := s.rpc.GetTransition(ctx, new(big.Int).SetUint64(blockInfo.BlockId), blockInfo.VerifiedTransitionId) + if err != nil { + return nil, err + } + if header.Hash() != ts.BlockHash { + return nil, fmt.Errorf( + "latest verified block hash mismatch: %s != %s", + header.Hash(), + common.BytesToHash(ts.BlockHash[:]), + ) + } + } + + log.Info("Latest verified block header retrieved", "hash", header.Hash()) + + return encoding.ToExecutableData(header), nil +} diff --git a/packages/taiko-client/driver/chain_syncer/blob/syncer.go b/packages/taiko-client/driver/chain_syncer/blob/syncer.go new file mode 100644 index 00000000000..3db1945b168 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/blob/syncer.go @@ -0,0 +1,677 @@ +package blob + +import ( + "context" + "errors" + "fmt" + "math/big" + "net/url" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/rpc" + + anchorTxConstructor "github.com/taikoxyz/taiko-client/driver/anchor_tx_constructor" + txlistfetcher "github.com/taikoxyz/taiko-client/driver/txlist_fetcher" + eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" + txListValidator "github.com/taikoxyz/taiko-client/pkg/txlist_validator" +) + +// Syncer responsible for letting the L2 execution engine catching up with protocol's latest +// pending block through deriving L1 calldata. +type Syncer struct { + ctx context.Context + rpc *rpc.Client + state *state.State + progressTracker *beaconsync.SyncProgressTracker // Sync progress tracker + anchorConstructor *anchorTxConstructor.AnchorTxConstructor // TaikoL2.anchor transactions constructor + txListValidator *txListValidator.TxListValidator // Transactions list validator + // Used by BlockInserter + lastInsertedBlockID *big.Int + reorgDetectedFlag bool + maxRetrieveExponent uint64 + blobDatasource *rpc.BlobDataSource +} + +// NewSyncer creates a new syncer instance. +func NewSyncer( + ctx context.Context, + client *rpc.Client, + state *state.State, + progressTracker *beaconsync.SyncProgressTracker, + maxRetrieveExponent uint64, + blobServerEndpoint *url.URL, +) (*Syncer, error) { + configs, err := client.TaikoL1.GetConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return nil, fmt.Errorf("failed to get protocol configs: %w", err) + } + + constructor, err := anchorTxConstructor.New(client) + if err != nil { + return nil, fmt.Errorf("failed to initialize anchor constructor: %w", err) + } + + return &Syncer{ + ctx: ctx, + rpc: client, + state: state, + progressTracker: progressTracker, + anchorConstructor: constructor, + txListValidator: txListValidator.NewTxListValidator( + uint64(configs.BlockMaxGasLimit), + rpc.BlockMaxTxListBytes, + client.L2.ChainID, + ), + maxRetrieveExponent: maxRetrieveExponent, + blobDatasource: rpc.NewBlobDataSource( + ctx, + client, + blobServerEndpoint, + ), + }, nil +} + +// ProcessL1Blocks fetches all `TaikoL1.BlockProposed` events between given +// L1 block heights, and then tries inserting them into L2 execution engine's blockchain. +func (s *Syncer) ProcessL1Blocks(ctx context.Context) error { + for { + if err := s.processL1Blocks(ctx); err != nil { + return err + } + + // If the L1 chain has been reorged, we process the new L1 blocks again with + // the new L1Current cursor. + if s.reorgDetectedFlag { + s.reorgDetectedFlag = false + continue + } + + return nil + } +} + +// processL1Blocks is the inner method which responsible for processing +// all new L1 blocks. +func (s *Syncer) processL1Blocks(ctx context.Context) error { + l1End := s.state.GetL1Head() + startL1Current := s.state.GetL1Current() + // If there is a L1 reorg, sometimes this will happen. + if startL1Current.Number.Uint64() >= l1End.Number.Uint64() && startL1Current.Hash() != l1End.Hash() { + newL1Current, err := s.rpc.L1.HeaderByNumber(ctx, new(big.Int).Sub(l1End.Number, common.Big1)) + if err != nil { + return err + } + + log.Info( + "Reorg detected", + "oldL1CurrentHeight", startL1Current.Number, + "oldL1CurrentHash", startL1Current.Hash(), + "newL1CurrentHeight", newL1Current.Number, + "newL1CurrentHash", newL1Current.Hash(), + "l1Head", l1End.Number, + ) + + s.state.SetL1Current(newL1Current) + s.lastInsertedBlockID = nil + } + + iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{ + Client: s.rpc.L1, + TaikoL1: s.rpc.TaikoL1, + StartHeight: s.state.GetL1Current().Number, + EndHeight: l1End.Number, + FilterQuery: nil, + OnBlockProposedEvent: s.onBlockProposed, + }) + if err != nil { + return err + } + + if err := iter.Iter(); err != nil { + return err + } + + // If there is a L1 reorg, we don't update the L1Current cursor. + if !s.reorgDetectedFlag { + s.state.SetL1Current(l1End) + metrics.DriverL1CurrentHeightGauge.Set(float64(s.state.GetL1Current().Number.Uint64())) + } + + return nil +} + +// OnBlockProposed is a `BlockProposed` event callback which responsible for +// inserting the proposed block one by one to the L2 execution engine. +func (s *Syncer) onBlockProposed( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + endIter eventIterator.EndBlockProposedEventIterFunc, +) error { + // We simply ignore the genesis block's `BlockProposed` event. + if event.BlockId.Cmp(common.Big0) == 0 { + return nil + } + + // If we are not inserting a block whose parent block is the latest verified block in protocol, + // and the node hasn't just finished the P2P sync, we check if the L1 chain has been reorged. + if !s.progressTracker.Triggered() { + reorgCheckResult, err := s.checkReorg(ctx, event) + if err != nil { + return err + } + + if reorgCheckResult.IsReorged { + log.Info( + "Reset L1Current cursor due to L1 reorg", + "l1CurrentHeightOld", s.state.GetL1Current().Number, + "l1CurrentHashOld", s.state.GetL1Current().Hash(), + "l1CurrentHeightNew", reorgCheckResult.L1CurrentToReset.Number, + "l1CurrentHashNew", reorgCheckResult.L1CurrentToReset.Hash(), + "lastInsertedBlockIDOld", s.lastInsertedBlockID, + "lastInsertedBlockIDNew", reorgCheckResult.LastHandledBlockIDToReset, + ) + s.state.SetL1Current(reorgCheckResult.L1CurrentToReset) + s.lastInsertedBlockID = reorgCheckResult.LastHandledBlockIDToReset + s.reorgDetectedFlag = true + endIter() + + return nil + } + } + // Ignore those already inserted blocks. + if s.lastInsertedBlockID != nil && event.BlockId.Cmp(s.lastInsertedBlockID) <= 0 { + return nil + } + + log.Info( + "New BlockProposed event", + "l1Height", event.Raw.BlockNumber, + "l1Hash", event.Raw.BlockHash, + "blockID", event.BlockId, + "removed", event.Raw.Removed, + ) + + // If the event's timestamp is in the future, we wait until the timestamp is reached, should + // only happen when testing. + if event.Meta.Timestamp > uint64(time.Now().Unix()) { + log.Warn("Future L2 block, waiting", "L2BlockTimestamp", event.Meta.Timestamp, "now", time.Now().Unix()) + time.Sleep(time.Until(time.Unix(int64(event.Meta.Timestamp), 0))) + } + + // Fetch the L2 parent block, if the node is just finished a P2P sync, we simply use the tracker's + // last synced verified block as the parent, otherwise, we fetch the parent block from L2 EE. + var ( + parent *types.Header + err error + ) + if s.progressTracker.Triggered() { + // Already synced through beacon sync, just skip this event. + if event.BlockId.Cmp(s.progressTracker.LastSyncedBlockID()) <= 0 { + return nil + } + + parent, err = s.rpc.L2.HeaderByHash(ctx, s.progressTracker.LastSyncedBlockHash()) + } else { + parent, err = s.rpc.L2ParentByBlockID(ctx, event.BlockId) + } + if err != nil { + return fmt.Errorf("failed to fetch L2 parent block: %w", err) + } + + log.Debug( + "Parent block", + "height", parent.Number, + "hash", parent.Hash(), + "beaconSyncTriggered", s.progressTracker.Triggered(), + ) + + tx, err := s.rpc.L1.TransactionInBlock(ctx, event.Raw.BlockHash, event.Raw.TxIndex) + if err != nil { + return fmt.Errorf("failed to fetch original TaikoL1.proposeBlock transaction: %w", err) + } + + // Decode transactions list. + var txListDecoder txlistfetcher.TxListFetcher + if event.Meta.BlobUsed { + txListDecoder = txlistfetcher.NewBlobTxListFetcher(s.rpc.L1Beacon, s.blobDatasource) + } else { + txListDecoder = new(txlistfetcher.CalldataFetcher) + } + txListBytes, err := txListDecoder.Fetch(ctx, tx, &event.Meta) + if err != nil { + if errors.Is(err, rpc.ErrBlobInvalid) { + log.Info("Invalid blob detected", "blockID", event.BlockId) + txListBytes = []byte{} + } else { + return fmt.Errorf("failed to decode tx list: %w", err) + } + } + + if txListBytes, err = utils.Decompress(txListBytes); err != nil { + return fmt.Errorf("failed to decompress tx list bytes: %w", err) + } + + // If the transactions list is invalid, we simply insert an empty L2 block. + if !s.txListValidator.ValidateTxList(event.BlockId, txListBytes, event.Meta.BlobUsed) { + log.Info("Invalid transactions list, insert an empty L2 block instead", "blockID", event.BlockId) + txListBytes = []byte{} + } + + payloadData, err := s.insertNewHead( + ctx, + event, + parent, + s.state.GetHeadBlockID(), + txListBytes, + &rawdb.L1Origin{ + BlockID: event.BlockId, + L2BlockHash: common.Hash{}, // Will be set by taiko-geth. + L1BlockHeight: new(big.Int).SetUint64(event.Raw.BlockNumber), + L1BlockHash: event.Raw.BlockHash, + }, + ) + if err != nil { + return fmt.Errorf("failed to insert new head to L2 execution engine: %w", err) + } + + log.Debug("Payload data", "hash", payloadData.BlockHash, "txs", len(payloadData.Transactions)) + + log.Info( + "🔗 New L2 block inserted", + "blockID", event.BlockId, + "height", payloadData.Number, + "hash", payloadData.BlockHash, + "transactions", len(payloadData.Transactions), + "baseFee", utils.WeiToGWei(payloadData.BaseFeePerGas), + "withdrawals", len(payloadData.Withdrawals), + ) + + metrics.DriverL1CurrentHeightGauge.Set(float64(event.Raw.BlockNumber)) + s.lastInsertedBlockID = event.BlockId + + if s.progressTracker.Triggered() { + s.progressTracker.ClearMeta() + } + + return nil +} + +// insertNewHead tries to insert a new head block to the L2 execution engine's local +// block chain through Engine APIs. +func (s *Syncer) insertNewHead( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + parent *types.Header, + headBlockID *big.Int, + txListBytes []byte, + l1Origin *rawdb.L1Origin, +) (*engine.ExecutableData, error) { + log.Debug( + "Try to insert a new L2 head block", + "parentNumber", parent.Number, + "parentHash", parent.Hash(), + "headBlockID", headBlockID, + "l1Origin", l1Origin, + ) + + // Insert a TaikoL2.anchor transaction at transactions list head + var txList []*types.Transaction + if len(txListBytes) != 0 { + if err := rlp.DecodeBytes(txListBytes, &txList); err != nil { + log.Error("Invalid txList bytes", "blockID", event.BlockId) + return nil, err + } + } + + // Get L2 baseFee + baseFeeInfo, err := s.rpc.TaikoL2.GetBasefee( + &bind.CallOpts{BlockNumber: parent.Number, Context: ctx}, + event.Meta.L1Height, + uint32(parent.GasUsed), + ) + if err != nil { + return nil, fmt.Errorf("failed to get L2 baseFee: %w", encoding.TryParsingCustomError(err)) + } + + log.Info( + "L2 baseFee", + "blockID", event.BlockId, + "baseFee", utils.WeiToGWei(baseFeeInfo.Basefee), + "syncedL1Height", event.Meta.L1Height, + "parentGasUsed", parent.GasUsed, + ) + + // Get withdrawals + withdrawals := make(types.Withdrawals, len(event.DepositsProcessed)) + for i, d := range event.DepositsProcessed { + withdrawals[i] = &types.Withdrawal{Address: d.Recipient, Amount: d.Amount.Uint64(), Index: d.Id} + } + + // Assemble a TaikoL2.anchor transaction + anchorTx, err := s.anchorConstructor.AssembleAnchorTx( + ctx, + new(big.Int).SetUint64(event.Meta.L1Height), + event.Meta.L1Hash, + new(big.Int).Add(parent.Number, common.Big1), + baseFeeInfo.Basefee, + parent.GasUsed, + ) + if err != nil { + return nil, fmt.Errorf("failed to create TaikoL2.anchor transaction: %w", err) + } + + // Insert the anchor transaction at the head of the transactions list + txList = append([]*types.Transaction{anchorTx}, txList...) + if txListBytes, err = rlp.EncodeToBytes(txList); err != nil { + log.Error("Encode txList error", "blockID", event.BlockId, "error", err) + return nil, err + } + + payload, err := s.createExecutionPayloads( + ctx, + event, + parent.Hash(), + l1Origin, + headBlockID, + txListBytes, + baseFeeInfo.Basefee, + withdrawals, + ) + if err != nil { + return nil, fmt.Errorf("failed to create execution payloads: %w", err) + } + + fc := &engine.ForkchoiceStateV1{HeadBlockHash: payload.BlockHash} + if err = s.fillForkchoiceState(ctx, event, fc); err != nil { + return nil, err + } + + // Update the fork choice + fcRes, err := s.rpc.L2Engine.ForkchoiceUpdate(ctx, fc, nil) + if err != nil { + return nil, err + } + if fcRes.PayloadStatus.Status != engine.VALID { + return nil, fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) + } + + return payload, nil +} + +// fillForkchoiceState fills the forkchoice state with the finalized block hash and the safe block hash. +func (s *Syncer) fillForkchoiceState( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + fc *engine.ForkchoiceStateV1, +) error { + // If the event is emitted from the genesis block, we don't need to fill the forkchoice state, + // should only happen when testing. + if event.Raw.BlockNumber == 0 { + return nil + } + + // Fetch the latest verified block's header from protocol. + variables, err := s.rpc.GetTaikoDataSlotBByNumber(ctx, event.Raw.BlockNumber) + if err != nil { + return err + } + finalizeHeader, err := s.rpc.L2.HeaderByNumber(ctx, new(big.Int).SetUint64(variables.LastVerifiedBlockId)) + if err != nil { + return err + } + + // Fill the forkchoice state. + fc.FinalizedBlockHash = finalizeHeader.Hash() + fc.SafeBlockHash = finalizeHeader.ParentHash + + return nil +} + +// createExecutionPayloads creates a new execution payloads through +// Engine APIs. +func (s *Syncer) createExecutionPayloads( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + parentHash common.Hash, + l1Origin *rawdb.L1Origin, + headBlockID *big.Int, + txListBytes []byte, + baseFee *big.Int, + withdrawals types.Withdrawals, +) (payloadData *engine.ExecutableData, err error) { + fc := &engine.ForkchoiceStateV1{HeadBlockHash: parentHash} + attributes := &engine.PayloadAttributes{ + Timestamp: event.Meta.Timestamp, + Random: event.Meta.Difficulty, + SuggestedFeeRecipient: event.Meta.Coinbase, + Withdrawals: withdrawals, + BlockMetadata: &engine.BlockMetadata{ + HighestBlockID: headBlockID, + Beneficiary: event.Meta.Coinbase, + GasLimit: uint64(event.Meta.GasLimit) + anchorTxConstructor.AnchorGasLimit, + Timestamp: event.Meta.Timestamp, + TxList: txListBytes, + MixHash: event.Meta.Difficulty, + ExtraData: event.Meta.ExtraData[:], + }, + BaseFeePerGas: baseFee, + L1Origin: l1Origin, + } + + log.Debug( + "PayloadAttributes", + "blockID", event.BlockId, + "timestamp", attributes.Timestamp, + "random", attributes.Random, + "suggestedFeeRecipient", attributes.SuggestedFeeRecipient, + "withdrawals", len(attributes.Withdrawals), + "highestBlockID", attributes.BlockMetadata.HighestBlockID, + "gasLimit", attributes.BlockMetadata.GasLimit, + "timestamp", attributes.BlockMetadata.Timestamp, + "mixHash", attributes.BlockMetadata.MixHash, + "baseFee", utils.WeiToGWei(attributes.BaseFeePerGas), + "extraData", string(attributes.BlockMetadata.ExtraData), + "l1OriginHeight", attributes.L1Origin.L1BlockHeight, + "l1OriginHash", attributes.L1Origin.L1BlockHash, + ) + + // Step 1, prepare a payload + fcRes, err := s.rpc.L2Engine.ForkchoiceUpdate(ctx, fc, attributes) + if err != nil { + return nil, fmt.Errorf("failed to update fork choice: %w", err) + } + if fcRes.PayloadStatus.Status != engine.VALID { + return nil, fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) + } + if fcRes.PayloadID == nil { + return nil, errors.New("empty payload ID") + } + + // Step 2, get the payload + payload, err := s.rpc.L2Engine.GetPayload(ctx, fcRes.PayloadID) + if err != nil { + return nil, fmt.Errorf("failed to get payload: %w", err) + } + + log.Debug( + "Payload", + "blockID", event.BlockId, + "baseFee", utils.WeiToGWei(payload.BaseFeePerGas), + "number", payload.Number, + "hash", payload.BlockHash, + "gasLimit", payload.GasLimit, + "gasUsed", payload.GasUsed, + "timestamp", payload.Timestamp, + "withdrawalsHash", payload.WithdrawalsHash, + ) + + // Step 3, execute the payload + execStatus, err := s.rpc.L2Engine.NewPayload(ctx, payload) + if err != nil { + return nil, fmt.Errorf("failed to create a new payload: %w", err) + } + if execStatus.Status != engine.VALID { + return nil, fmt.Errorf("unexpected NewPayload response status: %s", execStatus.Status) + } + + return payload, nil +} + +// checkLastVerifiedBlockMismatch checks if there is a mismatch between protocol's last verified block hash and +// the corresponding L2 EE block hash. +func (s *Syncer) checkLastVerifiedBlockMismatch(ctx context.Context) (*rpc.ReorgCheckResult, error) { + var ( + reorgCheckResult = new(rpc.ReorgCheckResult) + err error + ) + + stateVars, err := s.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: ctx}) + if err != nil { + return nil, err + } + + if s.state.GetL2Head().Number.Uint64() < stateVars.B.LastVerifiedBlockId { + return reorgCheckResult, nil + } + + genesisL1Header, err := s.rpc.GetGenesisL1Header(ctx) + if err != nil { + return nil, fmt.Errorf("failed to fetch genesis L1 header: %w", err) + } + reorgCheckResult, err = s.retrievePastBlock(ctx, stateVars.B.LastVerifiedBlockId, 0, genesisL1Header) + if err != nil { + return nil, err + } + + return reorgCheckResult, nil +} + +// retrievePastBlock find proper L1 header and L2 block id to reset when there is a mismatch +func (s *Syncer) retrievePastBlock( + ctx context.Context, + blockID uint64, + retries uint64, + genesisL1Header *types.Header) (*rpc.ReorgCheckResult, error) { + if retries > s.maxRetrieveExponent { + return &rpc.ReorgCheckResult{ + IsReorged: true, + L1CurrentToReset: genesisL1Header, + LastHandledBlockIDToReset: new(big.Int).SetUint64(blockID), + }, nil + } + + var ( + reorgCheckResult = new(rpc.ReorgCheckResult) + err error + currentBlockID uint64 + l1HeaderToSet = genesisL1Header + ) + + if val := uint64(1 << retries); blockID > val { + currentBlockID = blockID - val + 1 + } else { + currentBlockID = 0 + } + + blockInfo, err := s.rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(currentBlockID)) + if err != nil { + return nil, err + } + ts, err := s.rpc.GetTransition(ctx, new(big.Int).SetUint64(blockInfo.BlockId), blockInfo.VerifiedTransitionId) + if err != nil { + return nil, err + } + + l2Header, err := s.rpc.L2.HeaderByNumber(ctx, new(big.Int).SetUint64(currentBlockID)) + if err != nil { + return nil, err + } + if ts.BlockHash == l2Header.Hash() { + // To reduce the number of call contracts by bringing forward the termination condition judgement + if retries == 0 { + return nil, nil + } + l1Origin, err := s.rpc.L2.L1OriginByID(ctx, new(big.Int).SetUint64(currentBlockID)) + if err != nil { + if err.Error() == ethereum.NotFound.Error() { + log.Info( + "L1Origin not found in retrievePastBlock because the L2 EE is just synced through P2P", + "blockID", + currentBlockID, + ) + // Can't find l1Origin in L2 EE, so we call the contract to get block info + blockInfo, err := s.rpc.TaikoL1.GetBlock(&bind.CallOpts{Context: ctx}, currentBlockID) + if err != nil { + return nil, err + } + if blockInfo.ProposedIn != 0 { + l1HeaderToSet, err = s.rpc.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(blockInfo.ProposedIn)) + if err != nil { + return nil, err + } + } + } else { + return nil, err + } + } else { + l1HeaderToSet, err = s.rpc.L1.HeaderByNumber(ctx, l1Origin.L1BlockHeight) + if err != nil { + return nil, err + } + } + reorgCheckResult.IsReorged = retries > 0 + reorgCheckResult.L1CurrentToReset = l1HeaderToSet + reorgCheckResult.LastHandledBlockIDToReset = new(big.Int).SetUint64(currentBlockID) + } else { + reorgCheckResult, err = s.retrievePastBlock(ctx, blockID, retries+1, genesisL1Header) + if err != nil { + return nil, err + } + } + return reorgCheckResult, nil +} + +// checkReorg checks whether the L1 chain has been reorged, and resets the L1Current cursor if necessary. +func (s *Syncer) checkReorg( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, +) (*rpc.ReorgCheckResult, error) { + // If the L2 chain is at genesis, we don't need to check L1 reorg. + if s.state.GetL1Current().Number == s.state.GenesisL1Height { + return new(rpc.ReorgCheckResult), nil + } + + // 1. The latest verified block + reorgCheckResult, err := s.checkLastVerifiedBlockMismatch(ctx) + if err != nil { + return nil, fmt.Errorf("failed to check if last verified block in L2 EE has been reorged: %w", err) + } + + if reorgCheckResult == nil { + // 2. Parent block + reorgCheckResult, err = s.rpc.CheckL1Reorg( + ctx, + new(big.Int).Sub(event.BlockId, common.Big1), + ) + if err != nil { + return nil, fmt.Errorf("failed to check whether L1 chain has been reorged: %w", err) + } + } + + return reorgCheckResult, nil +} diff --git a/packages/taiko-client/driver/chain_syncer/blob/syncer_test.go b/packages/taiko-client/driver/chain_syncer/blob/syncer_test.go new file mode 100644 index 00000000000..cc11eb3ad11 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/blob/syncer_test.go @@ -0,0 +1,242 @@ +package blob + +import ( + "context" + "math/big" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" +) + +type BlobSyncerTestSuite struct { + testutils.ClientTestSuite + s *Syncer + p testutils.Proposer +} + +func (s *BlobSyncerTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + state2, err := state.New(context.Background(), s.RPCClient) + s.Nil(err) + + syncer, err := NewSyncer( + context.Background(), + s.RPCClient, + state2, + beaconsync.NewSyncProgressTracker(s.RPCClient.L2, 1*time.Hour), + 0, + nil, + ) + s.Nil(err) + s.s = syncer + + s.initProposer() +} +func (s *BlobSyncerTestSuite) TestCancelNewSyncer() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + syncer, err := NewSyncer( + ctx, + s.RPCClient, + s.s.state, + s.s.progressTracker, + 0, + nil, + ) + s.Nil(syncer) + s.NotNil(err) +} + +func (s *BlobSyncerTestSuite) TestProcessL1Blocks() { + s.Nil(s.s.ProcessL1Blocks(context.Background())) +} + +func (s *BlobSyncerTestSuite) TestProcessL1BlocksReorg() { + s.ProposeAndInsertEmptyBlocks(s.p, s.s) + s.Nil(s.s.ProcessL1Blocks(context.Background())) +} + +func (s *BlobSyncerTestSuite) TestOnBlockProposed() { + s.Nil(s.s.onBlockProposed( + context.Background(), + &bindings.TaikoL1ClientBlockProposed{BlockId: common.Big0}, + func() {}, + )) + s.NotNil(s.s.onBlockProposed( + context.Background(), + &bindings.TaikoL1ClientBlockProposed{BlockId: common.Big1}, + func() {}, + )) +} + +func (s *BlobSyncerTestSuite) TestInsertNewHead() { + parent, err := s.s.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l1Head, err := s.s.rpc.L1.BlockByNumber(context.Background(), nil) + s.Nil(err) + _, err = s.s.insertNewHead( + context.Background(), + &bindings.TaikoL1ClientBlockProposed{ + BlockId: common.Big1, + Meta: bindings.TaikoDataBlockMetadata{ + Id: 1, + L1Height: l1Head.NumberU64(), + L1Hash: l1Head.Hash(), + Coinbase: common.BytesToAddress(testutils.RandomBytes(1024)), + BlobHash: testutils.RandomHash(), + Difficulty: testutils.RandomHash(), + GasLimit: utils.RandUint32(nil), + Timestamp: uint64(time.Now().Unix()), + }, + }, + parent, + common.Big2, + []byte{}, + &rawdb.L1Origin{ + BlockID: common.Big1, + L1BlockHeight: common.Big1, + L1BlockHash: testutils.RandomHash(), + }, + ) + s.Nil(err) +} + +func (s *BlobSyncerTestSuite) TestTreasuryIncomeAllAnchors() { + treasury := common.HexToAddress(os.Getenv("TREASURY")) + s.NotZero(treasury.Big().Uint64()) + + balance, err := s.RPCClient.L2.BalanceAt(context.Background(), treasury, nil) + s.Nil(err) + + headBefore, err := s.RPCClient.L2.BlockNumber(context.Background()) + s.Nil(err) + + s.ProposeAndInsertEmptyBlocks(s.p, s.s) + + headAfter, err := s.RPCClient.L2.BlockNumber(context.Background()) + s.Nil(err) + + balanceAfter, err := s.RPCClient.L2.BalanceAt(context.Background(), treasury, nil) + s.Nil(err) + + s.Greater(headAfter, headBefore) + s.Zero(balanceAfter.Cmp(balance)) +} + +func (s *BlobSyncerTestSuite) TestTreasuryIncome() { + treasury := common.HexToAddress(os.Getenv("TREASURY")) + s.NotZero(treasury.Big().Uint64()) + + balance, err := s.RPCClient.L2.BalanceAt(context.Background(), treasury, nil) + s.Nil(err) + + headBefore, err := s.RPCClient.L2.BlockNumber(context.Background()) + s.Nil(err) + + s.ProposeAndInsertEmptyBlocks(s.p, s.s) + s.ProposeAndInsertValidBlock(s.p, s.s) + + headAfter, err := s.RPCClient.L2.BlockNumber(context.Background()) + s.Nil(err) + + balanceAfter, err := s.RPCClient.L2.BalanceAt(context.Background(), treasury, nil) + s.Nil(err) + + s.Greater(headAfter, headBefore) + s.True(balanceAfter.Cmp(balance) > 0) + + var hasNoneAnchorTxs bool + for i := headBefore + 1; i <= headAfter; i++ { + block, err := s.RPCClient.L2.BlockByNumber(context.Background(), new(big.Int).SetUint64(i)) + s.Nil(err) + s.GreaterOrEqual(block.Transactions().Len(), 1) + s.Greater(block.BaseFee().Uint64(), uint64(0)) + + for j, tx := range block.Transactions() { + if j == 0 { + continue + } + + hasNoneAnchorTxs = true + receipt, err := s.RPCClient.L2.TransactionReceipt(context.Background(), tx.Hash()) + s.Nil(err) + + fee := new(big.Int).Mul(block.BaseFee(), new(big.Int).SetUint64(receipt.GasUsed)) + + balance = new(big.Int).Add(balance, fee) + } + } + + s.True(hasNoneAnchorTxs) + s.Zero(balanceAfter.Cmp(balance)) +} + +func (s *BlobSyncerTestSuite) initProposer() { + prop := new(proposer.Proposer) + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.p = prop +} + +func TestBlobSyncerTestSuite(t *testing.T) { + suite.Run(t, new(BlobSyncerTestSuite)) +} diff --git a/packages/taiko-client/driver/chain_syncer/chain_syncer.go b/packages/taiko-client/driver/chain_syncer/chain_syncer.go new file mode 100644 index 00000000000..5a97e4362fe --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/chain_syncer.go @@ -0,0 +1,211 @@ +package chainsyncer + +import ( + "context" + "fmt" + "net/url" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/blob" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// L2ChainSyncer is responsible for keeping the L2 execution engine's local chain in sync with the one +// in TaikoL1 contract. +type L2ChainSyncer struct { + ctx context.Context + state *state.State // Driver's state + rpc *rpc.Client // L1/L2 RPC clients + + // Syncers + beaconSyncer *beaconsync.Syncer + blobSyncer *blob.Syncer + + // Monitors + progressTracker *beaconsync.SyncProgressTracker + + // Sync mode + syncMode string + + // If this flag is activated, will try P2P beacon sync if current node is behind of the protocol's + // the latest verified block head + p2pSync bool +} + +// New creates a new chain syncer instance. +func New( + ctx context.Context, + rpc *rpc.Client, + state *state.State, + p2pSync bool, + p2pSyncTimeout time.Duration, + maxRetrieveExponent uint64, + blobServerEndpoint *url.URL, + +) (*L2ChainSyncer, error) { + tracker := beaconsync.NewSyncProgressTracker(rpc.L2, p2pSyncTimeout) + go tracker.Track(ctx) + + syncMode, err := rpc.L2.GetSyncMode(ctx) + if err != nil { + return nil, err + } + beaconSyncer := beaconsync.NewSyncer(ctx, rpc, state, syncMode, tracker) + blobSyncer, err := blob.NewSyncer(ctx, rpc, state, tracker, maxRetrieveExponent, blobServerEndpoint) + if err != nil { + return nil, err + } + + return &L2ChainSyncer{ + ctx: ctx, + rpc: rpc, + state: state, + beaconSyncer: beaconSyncer, + blobSyncer: blobSyncer, + progressTracker: tracker, + syncMode: syncMode, + p2pSync: p2pSync, + }, nil +} + +// Sync performs a sync operation to L2 execution engine's local chain. +func (s *L2ChainSyncer) Sync() error { + blockID, needNewBeaconSyncTriggered, err := s.needNewBeaconSyncTriggered() + if err != nil { + return err + } + // If current L2 execution engine's chain is behind of the protocol's latest verified block head, and the + // `P2PSync` flag is set, try triggering a beacon sync in L2 execution engine to catch up the + // latest verified block head. + if needNewBeaconSyncTriggered { + if err := s.beaconSyncer.TriggerBeaconSync(blockID); err != nil { + return fmt.Errorf("trigger beacon sync error: %w", err) + } + + return nil + } + + // We have triggered at least a beacon sync in L2 execution engine, we should reset the L1Current + // cursor at first, before start inserting pending L2 blocks one by one. + if s.progressTracker.Triggered() { + log.Info( + "Switch to insert pending blocks one by one", + "p2pEnabled", s.p2pSync, + "p2pOutOfSync", s.progressTracker.OutOfSync(), + ) + + // Mark the beacon sync progress as finished. + s.progressTracker.MarkFinished() + + // Get the execution engine's chain head. + l2Head, err := s.rpc.L2.HeaderByNumber(s.ctx, nil) + if err != nil { + return err + } + + log.Info( + "L2 head information", + "number", l2Head.Number, + "hash", l2Head.Hash(), + "lastSyncedVerifiedBlockID", s.progressTracker.LastSyncedBlockID(), + "lastSyncedVerifiedBlockHash", s.progressTracker.LastSyncedBlockHash(), + ) + + // Reset the L1Current cursor. + if err := s.state.ResetL1Current(s.ctx, l2Head.Number); err != nil { + return err + } + + // Reset to the latest L2 execution engine's chain status. + s.progressTracker.UpdateMeta(l2Head.Number, l2Head.Hash()) + } + + // Insert the proposed block one by one. + return s.blobSyncer.ProcessL1Blocks(s.ctx) +} + +// AheadOfProtocolVerifiedHead checks whether the L2 chain is ahead of verified head in protocol. +func (s *L2ChainSyncer) AheadOfProtocolVerifiedHead(verifiedHeightToCompare uint64) bool { + log.Debug( + "Checking whether the execution engine is ahead of protocol's verified head", + "latestVerifiedBlock", verifiedHeightToCompare, + "executionEngineHead", s.state.GetL2Head().Number, + ) + if verifiedHeightToCompare > 0 { + // If latest verified head height is equal to L2 execution engine's synced head height minus one, + // we also mark the triggered P2P sync progress as finished to prevent a potential `InsertBlockWithoutSetHead` in + // execution engine, which may cause errors since we do not pass all transactions in ExecutePayload when calling + // `NewPayloadV1`. + verifiedHeightToCompare-- + } + + // If the L2 execution engine's chain is behind of the protocol's latest verified block head, + // we should keep the beacon sync. + if s.state.GetL2Head().Number.Uint64() < verifiedHeightToCompare { + return false + } + + if s.progressTracker.LastSyncedBlockID() != nil { + return s.state.GetL2Head().Number.Uint64() >= s.progressTracker.LastSyncedBlockID().Uint64() + } + + return true +} + +// needNewBeaconSyncTriggered checks whether the current L2 execution engine needs to trigger +// another new beacon sync, the following conditions should be met: +// 1. The `P2PSync` flag is set. +// 2. The protocol's latest verified block head is not zero. +// 3. The L2 execution engine's chain is behind of the protocol's latest verified block head. +// 4. The L2 execution engine's chain have met a sync timeout issue. +func (s *L2ChainSyncer) needNewBeaconSyncTriggered() (uint64, bool, error) { + // If the flag is not set or there was a finished beacon sync, we simply return false. + if !s.p2pSync || s.progressTracker.Finished() { + return 0, false, nil + } + + // For full sync mode, we will use the verified block head, + // And for snap sync mode, we will use the latest block head. + var ( + blockID uint64 + err error + ) + switch s.syncMode { + case downloader.SnapSync.String(): + if blockID, err = s.rpc.L2CheckPoint.BlockNumber(s.ctx); err != nil { + return 0, false, err + } + case downloader.FullSync.String(): + stateVars, err := s.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: s.ctx}) + if err != nil { + return 0, false, err + } + blockID = stateVars.B.LastVerifiedBlockId + default: + return 0, false, fmt.Errorf("invalid sync mode: %s", s.syncMode) + } + + // If the protocol's block head is zero, we simply return false. + if blockID == 0 { + return 0, false, nil + } + + return blockID, !s.AheadOfProtocolVerifiedHead(blockID) && + !s.progressTracker.OutOfSync(), nil +} + +// BeaconSyncer returns the inner beacon syncer. +func (s *L2ChainSyncer) BeaconSyncer() *beaconsync.Syncer { + return s.beaconSyncer +} + +// BlobSyncer returns the inner blob syncer. +func (s *L2ChainSyncer) BlobSyncer() *blob.Syncer { + return s.blobSyncer +} diff --git a/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go b/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go new file mode 100644 index 00000000000..3318783ff96 --- /dev/null +++ b/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go @@ -0,0 +1,161 @@ +package chainsyncer + +import ( + "bytes" + "context" + + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" +) + +type ChainSyncerTestSuite struct { + testutils.ClientTestSuite + s *L2ChainSyncer + snapshotID string + p testutils.Proposer +} + +func (s *ChainSyncerTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + state, err := state.New(context.Background(), s.RPCClient) + s.Nil(err) + + syncer, err := New( + context.Background(), + s.RPCClient, + state, + false, + 1*time.Hour, + 0, + nil, + ) + s.Nil(err) + s.s = syncer + + prop := new(proposer.Proposer) + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + ExtraData: "test", + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.p = prop +} + +func (s *ChainSyncerTestSuite) TestGetInnerSyncers() { + s.NotNil(s.s.BeaconSyncer()) + s.NotNil(s.s.BlobSyncer()) +} + +func (s *ChainSyncerTestSuite) TestSync() { + s.Nil(s.s.Sync()) +} + +func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead2() { + s.TakeSnapshot() + // propose a couple blocks + s.ProposeAndInsertEmptyBlocks(s.p, s.s.blobSyncer) + + // NOTE: need to prove the proposed blocks to be verified, writing helper function + // generate transactopts to interact with TaikoL1 contract with. + privKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + opts, err := bind.NewKeyedTransactorWithChainID(privKey, s.RPCClient.L1.ChainID) + s.Nil(err) + + head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Equal("test", string(bytes.TrimRight(l2Head.Extra, "\x00"))) + log.Info("L1HeaderByNumber head", "number", head.Number) + // (equiv to s.state.GetL2Head().Number) + log.Info("L2HeaderByNumber head", "number", l2Head.Number) + + // increase evm time to make blocks verifiable. + s.IncreaseTime(uint64((1024 * time.Hour).Seconds())) + + // interact with TaikoL1 contract to allow for verification of L2 blocks + tx, err := s.s.rpc.TaikoL1.VerifyBlocks(opts, uint64(3)) + s.Nil(err) + s.NotNil(tx) + + head2, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + l2Head2, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + log.Info("L1HeaderByNumber head2", "number", head2.Number) + log.Info("L2HeaderByNumber head", "number", l2Head2.Number) + + s.RevertSnapshot() +} + +func TestChainSyncerTestSuite(t *testing.T) { + suite.Run(t, new(ChainSyncerTestSuite)) +} + +func (s *ChainSyncerTestSuite) TakeSnapshot() { + // record snapshot state to revert to before changes + s.snapshotID = s.SetL1Snapshot() +} + +func (s *ChainSyncerTestSuite) RevertSnapshot() { + // revert to the snapshot state so protocol configs are unaffected + s.RevertL1Snapshot(s.snapshotID) + s.Nil(rpc.SetHead(context.Background(), s.RPCClient.L2, common.Big0)) +} + +func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead() { + s.True(s.s.AheadOfProtocolVerifiedHead(0)) +} diff --git a/packages/taiko-client/driver/config.go b/packages/taiko-client/driver/config.go new file mode 100644 index 00000000000..e385d758dd0 --- /dev/null +++ b/packages/taiko-client/driver/config.go @@ -0,0 +1,76 @@ +package driver + +import ( + "errors" + "fmt" + "net/url" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// Config contains the configurations to initialize a Taiko driver. +type Config struct { + *rpc.ClientConfig + P2PSync bool + P2PSyncTimeout time.Duration + RetryInterval time.Duration + MaxExponent uint64 + BlobServerEndpoint *url.URL +} + +// NewConfigFromCliContext creates a new config instance from +// the command line inputs. +func NewConfigFromCliContext(c *cli.Context) (*Config, error) { + jwtSecret, err := jwt.ParseSecretFromFile(c.String(flags.JWTSecret.Name)) + if err != nil { + return nil, fmt.Errorf("invalid JWT secret file: %w", err) + } + + var ( + p2pSync = c.Bool(flags.P2PSync.Name) + l2CheckPoint = c.String(flags.CheckPointSyncURL.Name) + ) + + if p2pSync && len(l2CheckPoint) == 0 { + return nil, errors.New("empty L2 check point URL") + } + + if !c.IsSet(flags.L1BeaconEndpoint.Name) { + return nil, errors.New("empty L1 beacon endpoint") + } + + var blobServerEndpoint *url.URL + if c.IsSet(flags.BlobServerEndpoint.Name) { + if blobServerEndpoint, err = url.Parse( + c.String(flags.BlobServerEndpoint.Name), + ); err != nil { + return nil, err + } + } + + var timeout = c.Duration(flags.RPCTimeout.Name) + return &Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: c.String(flags.L1WSEndpoint.Name), + L1BeaconEndpoint: c.String(flags.L1BeaconEndpoint.Name), + L2Endpoint: c.String(flags.L2WSEndpoint.Name), + L2CheckPoint: l2CheckPoint, + TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)), + TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)), + L2EngineEndpoint: c.String(flags.L2AuthEndpoint.Name), + JwtSecret: string(jwtSecret), + Timeout: timeout, + }, + RetryInterval: c.Duration(flags.BackOffRetryInterval.Name), + P2PSync: p2pSync, + P2PSyncTimeout: c.Duration(flags.P2PSyncTimeout.Name), + MaxExponent: c.Uint64(flags.MaxExponent.Name), + BlobServerEndpoint: blobServerEndpoint, + }, nil +} diff --git a/packages/taiko-client/driver/config_test.go b/packages/taiko-client/driver/config_test.go new file mode 100644 index 00000000000..45cff68059e --- /dev/null +++ b/packages/taiko-client/driver/config_test.go @@ -0,0 +1,98 @@ +package driver + +import ( + "context" + "os" + "time" + + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" +) + +var ( + l1Endpoint = os.Getenv("L1_NODE_WS_ENDPOINT") + l1BeaconEndpoint = os.Getenv("L1_NODE_HTTP_ENDPOINT") + l2Endpoint = os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT") + l2CheckPoint = os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT") + l2EngineEndpoint = os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT") + taikoL1 = os.Getenv("TAIKO_L1_ADDRESS") + taikoL2 = os.Getenv("TAIKO_L2_ADDRESS") +) + +func (s *DriverTestSuite) TestNewConfigFromCliContext() { + app := s.SetupApp() + + app.Action = func(ctx *cli.Context) error { + c, err := NewConfigFromCliContext(ctx) + s.Nil(err) + s.Equal(l1Endpoint, c.L1Endpoint) + s.Equal(l1BeaconEndpoint, c.L1BeaconEndpoint) + s.Equal(l2Endpoint, c.L2Endpoint) + s.Equal(l2EngineEndpoint, c.L2EngineEndpoint) + s.Equal(taikoL1, c.TaikoL1Address.String()) + s.Equal(taikoL2, c.TaikoL2Address.String()) + s.Equal(120*time.Second, c.P2PSyncTimeout) + s.NotEmpty(c.JwtSecret) + s.True(c.P2PSync) + s.Equal(l2CheckPoint, c.L2CheckPoint) + s.Nil(new(Driver).InitFromCli(context.Background(), ctx)) + + return err + } + + s.Nil(app.Run([]string{ + "TestNewConfigFromCliContext", + "--" + flags.L1WSEndpoint.Name, l1Endpoint, + "--" + flags.L1BeaconEndpoint.Name, l1BeaconEndpoint, + "--" + flags.L2WSEndpoint.Name, l2Endpoint, + "--" + flags.L2AuthEndpoint.Name, l2EngineEndpoint, + "--" + flags.TaikoL1Address.Name, taikoL1, + "--" + flags.TaikoL2Address.Name, taikoL2, + "--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"), + "--" + flags.P2PSyncTimeout.Name, "120s", + "--" + flags.RPCTimeout.Name, "5s", + "--" + flags.P2PSync.Name, + "--" + flags.CheckPointSyncURL.Name, l2CheckPoint, + })) +} + +func (s *DriverTestSuite) TestNewConfigFromCliContextJWTError() { + app := s.SetupApp() + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContext", + "--" + flags.JWTSecret.Name, "wrongsecretfile.txt", + }), "invalid JWT secret file") +} + +func (s *DriverTestSuite) TestNewConfigFromCliContextEmptyL2CheckPoint() { + app := s.SetupApp() + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContext", + "--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"), + "--" + flags.P2PSync.Name, + "--" + flags.L2WSEndpoint.Name, "", + }), "empty L2 check point URL") +} + +func (s *DriverTestSuite) SetupApp() *cli.App { + app := cli.NewApp() + app.Flags = []cli.Flag{ + &cli.StringFlag{Name: flags.L1WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L1BeaconEndpoint.Name}, + &cli.StringFlag{Name: flags.L2WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L2AuthEndpoint.Name}, + &cli.StringFlag{Name: flags.TaikoL1Address.Name}, + &cli.StringFlag{Name: flags.TaikoL2Address.Name}, + &cli.StringFlag{Name: flags.JWTSecret.Name}, + &cli.BoolFlag{Name: flags.P2PSync.Name}, + &cli.DurationFlag{Name: flags.P2PSyncTimeout.Name}, + &cli.DurationFlag{Name: flags.RPCTimeout.Name}, + &cli.StringFlag{Name: flags.CheckPointSyncURL.Name}, + } + app.Action = func(ctx *cli.Context) error { + _, err := NewConfigFromCliContext(ctx) + return err + } + return app +} diff --git a/packages/taiko-client/driver/driver.go b/packages/taiko-client/driver/driver.go new file mode 100644 index 00000000000..049b8c252e3 --- /dev/null +++ b/packages/taiko-client/driver/driver.go @@ -0,0 +1,259 @@ +package driver + +import ( + "context" + "sync" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" + + chainSyncer "github.com/taikoxyz/taiko-client/driver/chain_syncer" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +const ( + protocolStatusReportInterval = 30 * time.Second + exchangeTransitionConfigInterval = 1 * time.Minute +) + +// Driver keeps the L2 execution engine's local block chain in sync with the TaikoL1 +// contract. +type Driver struct { + *Config + rpc *rpc.Client + l2ChainSyncer *chainSyncer.L2ChainSyncer + state *state.State + + l1HeadCh chan *types.Header + l1HeadSub event.Subscription + + ctx context.Context + wg sync.WaitGroup +} + +// InitFromCli initializes the given driver instance based on the command line flags. +func (d *Driver) InitFromCli(ctx context.Context, c *cli.Context) error { + cfg, err := NewConfigFromCliContext(c) + if err != nil { + return err + } + + return d.InitFromConfig(ctx, cfg) +} + +// InitFromConfig initializes the driver instance based on the given configurations. +func (d *Driver) InitFromConfig(ctx context.Context, cfg *Config) (err error) { + d.l1HeadCh = make(chan *types.Header, 1024) + d.ctx = ctx + d.Config = cfg + + if d.rpc, err = rpc.NewClient(d.ctx, cfg.ClientConfig); err != nil { + return err + } + + if d.state, err = state.New(d.ctx, d.rpc); err != nil { + return err + } + + peers, err := d.rpc.L2.PeerCount(d.ctx) + if err != nil { + return err + } + + if cfg.P2PSync && peers == 0 { + log.Warn("P2P syncing verified blocks enabled, but no connected peer found in L2 execution engine") + } + + if d.l2ChainSyncer, err = chainSyncer.New( + d.ctx, + d.rpc, + d.state, + cfg.P2PSync, + cfg.P2PSyncTimeout, + cfg.MaxExponent, + cfg.BlobServerEndpoint, + ); err != nil { + return err + } + + d.l1HeadSub = d.state.SubL1HeadsFeed(d.l1HeadCh) + + return nil +} + +// Start starts the driver instance. +func (d *Driver) Start() error { + go d.eventLoop() + go d.reportProtocolStatus() + go d.exchangeTransitionConfigLoop() + + return nil +} + +// Close closes the driver instance. +func (d *Driver) Close(_ context.Context) { + d.l1HeadSub.Unsubscribe() + d.state.Close() + d.wg.Wait() +} + +// eventLoop starts the main loop of a L2 execution engine's driver. +func (d *Driver) eventLoop() { + d.wg.Add(1) + defer d.wg.Done() + + syncNotify := make(chan struct{}, 1) + // reqSync requests performing a synchronising operation, won't block + // if we are already synchronising. + reqSync := func() { + select { + case syncNotify <- struct{}{}: + default: + } + } + + // doSyncWithBackoff performs a synchronising operation with a backoff strategy. + doSyncWithBackoff := func() { + if err := backoff.Retry( + d.doSync, + backoff.WithContext(backoff.NewConstantBackOff(d.RetryInterval), d.ctx), + ); err != nil { + log.Error("Sync L2 execution engine's block chain error", "error", err) + } + } + + // Call doSync() right away to catch up with the latest known L1 head. + doSyncWithBackoff() + + for { + select { + case <-d.ctx.Done(): + return + case <-syncNotify: + doSyncWithBackoff() + case <-d.l1HeadCh: + reqSync() + } + } +} + +// doSync fetches all `BlockProposed` events emitted from local +// L1 sync cursor to the L1 head, and then applies all corresponding +// L2 blocks into node's local blockchain. +func (d *Driver) doSync() error { + // Check whether the application is closing. + if d.ctx.Err() != nil { + log.Warn("Driver context error", "error", d.ctx.Err()) + return nil + } + + if err := d.l2ChainSyncer.Sync(); err != nil { + log.Error("Process new L1 blocks error", "error", err) + return err + } + + return nil +} + +// ChainSyncer returns the driver's chain syncer, this method +// should only be used for testing. +func (d *Driver) ChainSyncer() *chainSyncer.L2ChainSyncer { + return d.l2ChainSyncer +} + +// reportProtocolStatus reports some protocol status intervally. +func (d *Driver) reportProtocolStatus() { + var ( + ticker = time.NewTicker(protocolStatusReportInterval) + maxNumBlocks uint64 + ) + d.wg.Add(1) + + defer func() { + ticker.Stop() + d.wg.Done() + }() + + if err := backoff.Retry( + func() error { + if d.ctx.Err() != nil { + return nil + } + configs, err := d.rpc.TaikoL1.GetConfig(&bind.CallOpts{Context: d.ctx}) + if err != nil { + return err + } + + maxNumBlocks = configs.BlockMaxProposals + return nil + }, + backoff.WithContext(backoff.NewConstantBackOff(d.RetryInterval), d.ctx), + ); err != nil { + log.Error("Failed to get protocol state variables", "error", err) + return + } + + for { + select { + case <-d.ctx.Done(): + return + case <-ticker.C: + vars, err := d.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: d.ctx}) + if err != nil { + log.Error("Failed to get protocol state variables", "error", err) + continue + } + + log.Info( + "📖 Protocol status", + "lastVerifiedBlockId", vars.B.LastVerifiedBlockId, + "pendingBlocks", vars.B.NumBlocks-vars.B.LastVerifiedBlockId-1, + "availableSlots", vars.B.LastVerifiedBlockId+maxNumBlocks-vars.B.NumBlocks, + ) + } + } +} + +// exchangeTransitionConfigLoop keeps exchanging transition configs with the +// L2 execution engine. +func (d *Driver) exchangeTransitionConfigLoop() { + ticker := time.NewTicker(exchangeTransitionConfigInterval) + d.wg.Add(1) + + defer func() { + ticker.Stop() + d.wg.Done() + }() + + for { + select { + case <-d.ctx.Done(): + return + case <-ticker.C: + tc, err := d.rpc.L2Engine.ExchangeTransitionConfiguration(d.ctx, &engine.TransitionConfigurationV1{ + TerminalTotalDifficulty: (*hexutil.Big)(common.Big0), + TerminalBlockHash: common.Hash{}, + TerminalBlockNumber: 0, + }) + if err != nil { + log.Error("Failed to exchange Transition Configuration", "error", err) + } else { + log.Debug("Exchanged transition config", "transitionConfig", tc) + } + } + } +} + +// Name returns the application name. +func (d *Driver) Name() string { + return "driver" +} diff --git a/packages/taiko-client/driver/driver_test.go b/packages/taiko-client/driver/driver_test.go new file mode 100644 index 00000000000..fe741b6dc6d --- /dev/null +++ b/packages/taiko-client/driver/driver_test.go @@ -0,0 +1,340 @@ +package driver + +import ( + "context" + "math/big" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" +) + +type DriverTestSuite struct { + testutils.ClientTestSuite + cancel context.CancelFunc + p *proposer.Proposer + d *Driver +} + +func (s *DriverTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + // InitFromConfig driver + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + d := new(Driver) + ctx, cancel := context.WithCancel(context.Background()) + s.Nil(d.InitFromConfig(ctx, &Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + JwtSecret: string(jwtSecret), + }, + })) + s.d = d + s.cancel = cancel + + // InitFromConfig proposer + s.InitProposer() +} + +func (s *DriverTestSuite) TestName() { + s.Equal("driver", s.d.Name()) +} + +func (s *DriverTestSuite) TestProcessL1Blocks() { + l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Nil(s.d.ChainSyncer().BlobSyncer().ProcessL1Blocks(context.Background())) + + // Propose a valid L2 block + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + + l2Head2, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Greater(l2Head2.Number.Uint64(), l2Head1.Number.Uint64()) + + // Empty blocks + s.ProposeAndInsertEmptyBlocks(s.p, s.d.ChainSyncer().BlobSyncer()) + s.Nil(err) + + l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Greater(l2Head3.Number.Uint64(), l2Head2.Number.Uint64()) + + for _, height := range []uint64{l2Head3.Number.Uint64(), l2Head3.Number.Uint64() - 1} { + header, err := s.d.rpc.L2.HeaderByNumber(context.Background(), new(big.Int).SetUint64(height)) + s.Nil(err) + + txCount, err := s.d.rpc.L2.TransactionCount(context.Background(), header.Hash()) + s.Nil(err) + s.Equal(uint(1), txCount) + + anchorTx, err := s.d.rpc.L2.TransactionInBlock(context.Background(), header.Hash(), 0) + s.Nil(err) + + method, err := encoding.TaikoL2ABI.MethodById(anchorTx.Data()) + s.Nil(err) + s.Equal("anchor", method.Name) + } +} + +func (s *DriverTestSuite) TestCheckL1ReorgToHigherFork() { + var ( + testnetL1SnapshotID = s.SetL1Snapshot() + ) + l1Head1, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + // Propose two L2 blocks + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + + l1Head2, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head2, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(l2Head2.Number.Uint64(), l2Head1.Number.Uint64()) + s.Greater(l1Head2.Number.Uint64(), l1Head1.Number.Uint64()) + + res, err := s.RPCClient.CheckL1Reorg( + context.Background(), + l2Head2.Number, + ) + s.Nil(err) + s.False(res.IsReorged) + + // Reorg back to l2Head1 + s.RevertL1Snapshot(testnetL1SnapshotID) + s.IncreaseTime(uint64((3 * time.Second).Seconds())) + s.InitProposer() + + // Because of evm_revert operation, the nonce of the proposer need to be adjusted. + // Propose ten blocks on another fork + for i := 0; i < 10; i++ { + s.ProposeInvalidTxListBytes(s.p) + } + + l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Greater(l1Head4.Number.Uint64(), l1Head2.Number.Uint64()) + + s.Nil(s.d.ChainSyncer().BlobSyncer().ProcessL1Blocks(context.Background())) + + l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Equal(l2Head1.Number.Uint64()+10, l2Head3.Number.Uint64()) + + parent, err := s.d.rpc.L2.HeaderByNumber(context.Background(), new(big.Int).SetUint64(l2Head1.Number.Uint64()+1)) + s.Nil(err) + s.Equal(parent.ParentHash, l2Head1.Hash()) + s.NotEqual(parent.Hash(), l2Head2.ParentHash) +} + +func (s *DriverTestSuite) TestCheckL1ReorgToLowerFork() { + var ( + testnetL1SnapshotID = s.SetL1Snapshot() + ) + l1Head1, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + // Propose two L2 blocks + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + time.Sleep(3 * time.Second) + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + + l1Head2, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head2, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(l2Head2.Number.Uint64(), l2Head1.Number.Uint64()) + s.Greater(l1Head2.Number.Uint64(), l1Head1.Number.Uint64()) + + res, err := s.RPCClient.CheckL1Reorg( + context.Background(), + l2Head2.Number, + ) + s.Nil(err) + s.False(res.IsReorged) + + // Reorg back to l2Head1 + s.RevertL1Snapshot(testnetL1SnapshotID) + s.InitProposer() + + l1Head3, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.GreaterOrEqual(l1Head3.Number.Uint64(), l1Head1.Number.Uint64()) + + // Propose one blocks on another fork + s.ProposeInvalidTxListBytes(s.p) + + l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Greater(l1Head4.Number.Uint64(), l1Head3.Number.Uint64()) + s.Less(l1Head4.Number.Uint64(), l1Head2.Number.Uint64()) + + s.Nil(s.d.ChainSyncer().BlobSyncer().ProcessL1Blocks(context.Background())) + + l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + parent, err := s.d.rpc.L2.HeaderByHash(context.Background(), l2Head3.ParentHash) + s.Nil(err) + s.Equal(l2Head3.Number.Uint64(), l2Head2.Number.Uint64()-1) + s.Equal(parent.Hash(), l2Head1.Hash()) +} + +func (s *DriverTestSuite) TestCheckL1ReorgToSameHeightFork() { + var ( + testnetL1SnapshotID = s.SetL1Snapshot() + ) + l1Head1, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + // Propose two L2 blocks + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + time.Sleep(3 * time.Second) + s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer()) + + l1Head2, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l2Head2, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(l2Head2.Number.Uint64(), l2Head1.Number.Uint64()) + s.Greater(l1Head2.Number.Uint64(), l1Head1.Number.Uint64()) + + res, err := s.RPCClient.CheckL1Reorg( + context.Background(), + l2Head2.Number, + ) + s.Nil(err) + s.False(res.IsReorged) + + // Reorg back to l2Head1 + s.RevertL1Snapshot(testnetL1SnapshotID) + s.InitProposer() + + l1Head3, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.GreaterOrEqual(l1Head3.Number.Uint64(), l1Head1.Number.Uint64()) + + // Propose two blocks on another fork + s.ProposeInvalidTxListBytes(s.p) + time.Sleep(3 * time.Second) + s.ProposeInvalidTxListBytes(s.p) + + l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + s.Greater(l1Head4.Number.Uint64(), l1Head3.Number.Uint64()) + + s.Nil(s.d.ChainSyncer().BlobSyncer().ProcessL1Blocks(context.Background())) + + l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + parent, err := s.d.rpc.L2.HeaderByHash(context.Background(), l2Head3.ParentHash) + s.Nil(err) + s.Equal(l2Head3.Number.Uint64(), l2Head2.Number.Uint64()) + s.NotEqual(l2Head3.Hash(), l2Head2.Hash()) + s.Equal(parent.ParentHash, l2Head1.Hash()) +} + +func (s *DriverTestSuite) TestDoSyncNoNewL2Blocks() { + s.Nil(s.d.l2ChainSyncer.Sync()) +} + +func (s *DriverTestSuite) TestStartClose() { + s.Nil(s.d.Start()) + s.cancel() + s.d.Close(s.d.ctx) +} + +func (s *DriverTestSuite) TestL1Current() { + // propose and insert a block + s.ProposeAndInsertEmptyBlocks(s.p, s.d.ChainSyncer().BlobSyncer()) + // reset L1 current with increased height + s.Nil(s.d.state.ResetL1Current(s.d.ctx, common.Big1)) +} + +func (s *DriverTestSuite) InitProposer() { + p := new(proposer.Proposer) + + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + s.Nil(p.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + s.p = p +} + +func TestDriverTestSuite(t *testing.T) { + suite.Run(t, new(DriverTestSuite)) +} diff --git a/packages/taiko-client/driver/signer/fixed_k_signer.go b/packages/taiko-client/driver/signer/fixed_k_signer.go new file mode 100644 index 00000000000..de50decaf46 --- /dev/null +++ b/packages/taiko-client/driver/signer/fixed_k_signer.go @@ -0,0 +1,87 @@ +package signer + +import ( + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var ( + // 32 zero bytes. + zero32 [32]byte +) + +// FixedKSigner is a ethereum ECDSA signer who always sign payload with the given K value. +// In theory K value is randomly selected in ECDSA algorithm's step 3: +// https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm, +// but here we use a fixed K value instead. +type FixedKSigner struct { + privKey *secp256k1.ModNScalar +} + +func NewFixedKSigner(privKey string) (*FixedKSigner, error) { + var priv btcec.PrivateKey + if overflow := priv.Key.SetByteSlice(hexutil.MustDecode(privKey)); overflow || priv.Key.IsZero() { + return nil, fmt.Errorf("invalid private key %s", privKey) + } + + return &FixedKSigner{privKey: &priv.Key}, nil +} + +// SignWithK signs the given hash using fixed K. +func (s *FixedKSigner) SignWithK(k *secp256k1.ModNScalar) func(hash []byte) ([]byte, bool) { + // k * G + var kG secp256k1.JacobianPoint + secp256k1.ScalarBaseMultNonConst(k, &kG) + kG.ToAffine() + + // r = kG.X mod N + // r != 0 + r, overflow := fieldToModNScalar(&kG.X) + pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.Y.IsOddBit()) + + kinv := new(secp256k1.ModNScalar).InverseValNonConst(k) + _s := new(secp256k1.ModNScalar).Mul2(s.privKey, &r) + + return func(hash []byte) ([]byte, bool) { + var e secp256k1.ModNScalar + e.SetByteSlice(hash) + // copy _s here to avoid modifying the original one. + _s := *_s + s := _s.Add(&e).Mul(kinv) + if s.IsZero() { + return nil, false + } + // copy pubKeyRecoveryCode here to avoid modifying the original one. + pubKeyRecoveryCode := pubKeyRecoveryCode + if s.IsOverHalfOrder() { + s.Negate() + + pubKeyRecoveryCode ^= 0x01 + } + + var sig [65]byte // r(32) + s(32) + v(1) + r.PutBytesUnchecked(sig[:32]) + s.PutBytesUnchecked(sig[32:64]) + sig[64] = pubKeyRecoveryCode + return sig[:], true + } +} + +// fieldToModNScalar converts a `secp256k1.FieldVal` to `secp256k1.ModNScalar`. +func fieldToModNScalar(v *secp256k1.FieldVal) (secp256k1.ModNScalar, uint32) { + var buf [32]byte + v.PutBytes(&buf) + var s secp256k1.ModNScalar + overflow := s.SetBytes(&buf) + // Clear buf here maybe for preventing memory theft (copy from source) + resetBuffer(&buf) + return s, overflow +} + +// resetBuffer resets the given buffer. +func resetBuffer(b *[32]byte) { + copy(b[:], zero32[:]) +} diff --git a/packages/taiko-client/driver/signer/fixed_k_signer_test.go b/packages/taiko-client/driver/signer/fixed_k_signer_test.go new file mode 100644 index 00000000000..a5a3bf7c038 --- /dev/null +++ b/packages/taiko-client/driver/signer/fixed_k_signer_test.go @@ -0,0 +1,46 @@ +package signer + +import ( + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +func TestSignWithK(t *testing.T) { + var priv btcec.PrivateKey + overflow := priv.Key.SetByteSlice( + hexutil.MustDecode("0x92954368afd3caa1f3ce3ead0069c1af414054aefe1ef9aeacc1bf426222ce38"), + ) + require.False(t, overflow || priv.Key.IsZero()) + + signer := FixedKSigner{privKey: &priv.Key} + + // K = 2, test case 1 + payload := hexutil.MustDecode("0x44943399d1507f3ce7525e9be2f987c3db9136dc759cb7f92f742154196868b9") + expected := testutils.SignatureFromRSV( + "0xc6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", + "0x38940d69b21d5b088beb706e9ebabe6422307e12863997a44239774467e240d5", + 1, + ) + + signed, ok := signer.SignWithK(new(secp256k1.ModNScalar).SetInt(2))(payload) + require.True(t, ok) + require.Equal(t, expected, signed) + + // K = 2, test case 2 + payload = hexutil.MustDecode("0x663d210fa6dba171546498489de1ba024b89db49e21662f91bf83cdffe788820") + expected = testutils.SignatureFromRSV( + "0xc6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5", + "0x5840695138a83611aa9dac67beb95aba7323429787a78df993f1c5c7f2c0ef7f", + 0, + ) + + signed, ok = signer.SignWithK(new(secp256k1.ModNScalar).SetInt(2))(payload) + require.True(t, ok) + require.Equal(t, expected, signed) +} diff --git a/packages/taiko-client/driver/state/l1_current.go b/packages/taiko-client/driver/state/l1_current.go new file mode 100644 index 00000000000..425ec1556d1 --- /dev/null +++ b/packages/taiko-client/driver/state/l1_current.go @@ -0,0 +1,61 @@ +package state + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// GetL1Current reads the L1 current cursor concurrent safely. +func (s *State) GetL1Current() *types.Header { + return s.l1Current.Load().(*types.Header) +} + +// SetL1Current sets the L1 current cursor concurrent safely. +func (s *State) SetL1Current(h *types.Header) { + if h == nil { + log.Warn("Empty l1 current cursor") + return + } + log.Debug("Set L1 current cursor", "number", h.Number) + s.l1Current.Store(h) +} + +// ResetL1Current resets the l1Current cursor to the L1 height which emitted a +// BlockProposed event with given blockID / blockHash. +func (s *State) ResetL1Current(ctx context.Context, blockID *big.Int) error { + if blockID == nil { + return errors.New("empty block ID") + } + + log.Info("Reset L1 current cursor", "blockID", blockID) + + // If blockID is zero, reset to genesis L1 height. + if blockID.Cmp(common.Big0) == 0 { + l1Current, err := s.rpc.L1.HeaderByNumber(ctx, s.GenesisL1Height) + if err != nil { + return err + } + s.SetL1Current(l1Current) + return nil + } + + // Fetch the block info from TaikoL1 contract, and set the L1 height. + blockInfo, err := s.rpc.GetL2BlockInfo(ctx, blockID) + if err != nil { + return err + } + l1Current, err := s.rpc.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(blockInfo.ProposedIn)) + if err != nil { + return err + } + s.SetL1Current(l1Current) + + log.Info("Reset L1 current cursor", "height", s.GetL1Current().Number, "hash", s.GetL1Current().Hash()) + + return nil +} diff --git a/packages/taiko-client/driver/state/l1_current_test.go b/packages/taiko-client/driver/state/l1_current_test.go new file mode 100644 index 00000000000..8ecd9a5c5c2 --- /dev/null +++ b/packages/taiko-client/driver/state/l1_current_test.go @@ -0,0 +1,37 @@ +package state + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +func (s *DriverStateTestSuite) TestGetL1Current() { + s.NotNil(s.s.GetL1Current()) +} + +func (s *DriverStateTestSuite) TestSetL1Current() { + h := &types.Header{ParentHash: testutils.RandomHash()} + s.s.SetL1Current(h) + s.Equal(h.Hash(), s.s.GetL1Current().Hash()) + + // should warn, but not panic + s.NotPanics(func() { s.s.SetL1Current(nil) }) +} + +func (s *DriverStateTestSuite) TestResetL1CurrentEmptyHeight() { + s.Nil(s.s.ResetL1Current(context.Background(), common.Big0)) +} + +func (s *DriverStateTestSuite) TestResetL1CurrentEmptyID() { + s.ErrorContains(s.s.ResetL1Current(context.Background(), common.Big1), "execution reverted") +} + +func (s *DriverStateTestSuite) TestResetL1CurrentCtxErr() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + s.ErrorContains(s.s.ResetL1Current(ctx, common.Big0), "context canceled") +} diff --git a/packages/taiko-client/driver/state/state.go b/packages/taiko-client/driver/state/state.go new file mode 100644 index 00000000000..9afd37e8cdb --- /dev/null +++ b/packages/taiko-client/driver/state/state.go @@ -0,0 +1,207 @@ +package state + +import ( + "context" + "math/big" + "sync" + "sync/atomic" + + "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" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// State contains all states which will be used by driver. +type State struct { + // Feeds + l1HeadsFeed event.Feed // L1 new heads notification feed + + l1Head atomic.Value // Latest known L1 head + l2Head atomic.Value // Current L2 execution engine's local chain head + l2HeadBlockID atomic.Value // Latest known L2 block ID in protocol + l1Current atomic.Value // Current L1 block sync cursor + + // Constants + GenesisL1Height *big.Int + + // RPC clients + rpc *rpc.Client + + wg sync.WaitGroup +} + +// New creates a new driver state instance. +func New(ctx context.Context, rpc *rpc.Client) (*State, error) { + s := &State{rpc: rpc} + + if err := s.init(ctx); err != nil { + return nil, err + } + + go s.eventLoop(ctx) + + return s, nil +} + +// Close closes all inner subscriptions. +func (s *State) Close() { + s.wg.Wait() +} + +// init fetches the latest status and initializes the state instance. +func (s *State) init(ctx context.Context) error { + stateVars, err := s.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: ctx}) + if err != nil { + return err + } + + log.Info("Genesis L1 height", "height", stateVars.A.GenesisHeight) + s.GenesisL1Height = new(big.Int).SetUint64(stateVars.A.GenesisHeight) + + // Set the L2 head's latest known L1 origin as current L1 sync cursor. + latestL2KnownL1Header, err := s.rpc.LatestL2KnownL1Header(ctx) + if err != nil { + return err + } + s.l1Current.Store(latestL2KnownL1Header) + + // L1 head + l1Head, err := s.rpc.L1.HeaderByNumber(ctx, nil) + if err != nil { + return err + } + s.setL1Head(l1Head) + + // L2 head + l2Head, err := s.rpc.L2.HeaderByNumber(ctx, nil) + if err != nil { + return err + } + + log.Info("L2 execution engine head", "height", l2Head.Number, "hash", l2Head.Hash()) + s.setL2Head(l2Head) + + s.setHeadBlockID(new(big.Int).SetUint64(stateVars.B.NumBlocks - 1)) + + return nil +} + +// eventLoop initializes and starts all subscriptions and callbacks in the given state instance. +func (s *State) eventLoop(ctx context.Context) { + s.wg.Add(1) + defer s.wg.Done() + + var ( + // Channels for subscriptions. + l1HeadCh = make(chan *types.Header, 10) + l2HeadCh = make(chan *types.Header, 10) + blockProposedCh = make(chan *bindings.TaikoL1ClientBlockProposed, 10) + transitionProvedCh = make(chan *bindings.TaikoL1ClientTransitionProved, 10) + blockVerifiedCh = make(chan *bindings.TaikoL1ClientBlockVerified, 10) + + // Subscriptions. + l1HeadSub = rpc.SubscribeChainHead(s.rpc.L1, l1HeadCh) + l2HeadSub = rpc.SubscribeChainHead(s.rpc.L2, l2HeadCh) + l2BlockVerifiedSub = rpc.SubscribeBlockVerified(s.rpc.TaikoL1, blockVerifiedCh) + l2BlockProposedSub = rpc.SubscribeBlockProposed(s.rpc.TaikoL1, blockProposedCh) + l2TransitionProvedSub = rpc.SubscribeTransitionProved(s.rpc.TaikoL1, transitionProvedCh) + ) + + defer func() { + l1HeadSub.Unsubscribe() + l2HeadSub.Unsubscribe() + l2BlockVerifiedSub.Unsubscribe() + l2BlockProposedSub.Unsubscribe() + l2TransitionProvedSub.Unsubscribe() + }() + + for { + select { + case <-ctx.Done(): + return + case e := <-blockProposedCh: + s.setHeadBlockID(e.BlockId) + case e := <-transitionProvedCh: + log.Info( + "✅ Transition proven", + "blockID", e.BlockId, + "parentHash", common.Hash(e.Tran.ParentHash), + "hash", common.Hash(e.Tran.BlockHash), + "stateRoot", common.Hash(e.Tran.StateRoot), + "prover", e.Prover, + ) + case e := <-blockVerifiedCh: + log.Info( + "📈 Block verified", + "blockID", e.BlockId, + "hash", common.Hash(e.BlockHash), + "stateRoot", common.Hash(e.StateRoot), + "prover", e.Prover, + ) + case newHead := <-l1HeadCh: + s.setL1Head(newHead) + s.l1HeadsFeed.Send(newHead) + case newHead := <-l2HeadCh: + s.setL2Head(newHead) + } + } +} + +// setL1Head sets the L1 head concurrent safely. +func (s *State) setL1Head(l1Head *types.Header) { + if l1Head == nil { + log.Warn("Empty new L1 head") + return + } + + log.Debug("New L1 head", "height", l1Head.Number, "hash", l1Head.Hash(), "timestamp", l1Head.Time) + metrics.DriverL1HeadHeightGauge.Set(float64(l1Head.Number.Int64())) + + s.l1Head.Store(l1Head) +} + +// GetL1Head reads the L1 head concurrent safely. +func (s *State) GetL1Head() *types.Header { + return s.l1Head.Load().(*types.Header) +} + +// setL2Head sets the L2 head concurrent safely. +func (s *State) setL2Head(l2Head *types.Header) { + if l2Head == nil { + log.Warn("Empty new L2 head") + return + } + + log.Debug("New L2 head", "height", l2Head.Number, "hash", l2Head.Hash(), "timestamp", l2Head.Time) + metrics.DriverL2HeadHeightGauge.Set(float64(l2Head.Number.Uint64())) + + s.l2Head.Store(l2Head) +} + +// GetL2Head reads the L2 head concurrent safely. +func (s *State) GetL2Head() *types.Header { + return s.l2Head.Load().(*types.Header) +} + +// setHeadBlockID sets the last pending block ID concurrent safely. +func (s *State) setHeadBlockID(id *big.Int) { + log.Debug("New head block ID", "ID", id) + metrics.DriverL2HeadIDGauge.Set(float64(id.Uint64())) + s.l2HeadBlockID.Store(id) +} + +// GetHeadBlockID reads the last pending block ID concurrent safely. +func (s *State) GetHeadBlockID() *big.Int { + return s.l2HeadBlockID.Load().(*big.Int) +} + +// SubL1HeadsFeed registers a subscription of new L1 heads. +func (s *State) SubL1HeadsFeed(ch chan *types.Header) event.Subscription { + return s.l1HeadsFeed.Subscribe(ch) +} diff --git a/packages/taiko-client/driver/state/state_test.go b/packages/taiko-client/driver/state/state_test.go new file mode 100644 index 00000000000..aa406606540 --- /dev/null +++ b/packages/taiko-client/driver/state/state_test.go @@ -0,0 +1,80 @@ +package state + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +type DriverStateTestSuite struct { + testutils.ClientTestSuite + ctx context.Context + cancel context.CancelFunc + s *State +} + +func (s *DriverStateTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + s.ctx, s.cancel = context.WithCancel(context.Background()) + state, err := New(s.ctx, s.RPCClient) + s.Nil(err) + s.s = state +} + +func (s *DriverStateTestSuite) TearDownTest() { + if s.ctx.Err() == nil { + s.cancel() + } +} + +func (s *DriverStateTestSuite) TestGetL1Head() { + l1Head := s.s.GetL1Head() + s.NotNil(l1Head) +} + +func (s *DriverStateTestSuite) TestGetHeadBlockID() { + s.Equal(uint64(0), s.s.GetHeadBlockID().Uint64()) +} + +func (s *DriverStateTestSuite) TestClose() { + s.cancel() + s.NotPanics(s.s.Close) +} + +func (s *DriverStateTestSuite) TestGetL2Head() { + testHeight := utils.RandUint64(nil) + + s.s.setL2Head(nil) + s.s.setL2Head(&types.Header{Number: new(big.Int).SetUint64(testHeight)}) + h := s.s.GetL2Head() + s.Equal(testHeight, h.Number.Uint64()) +} + +func (s *DriverStateTestSuite) TestSubL1HeadsFeed() { + s.NotNil(s.s.SubL1HeadsFeed(make(chan *types.Header))) +} + +func (s *DriverStateTestSuite) TestNewDriverContextErr() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + state, err := New(ctx, s.RPCClient) + s.Nil(state) + s.ErrorContains(err, "context canceled") +} + +func (s *DriverStateTestSuite) TestDriverInitContextErr() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err := s.s.init(ctx) + s.ErrorContains(err, "context canceled") +} + +func TestDriverStateTestSuite(t *testing.T) { + suite.Run(t, new(DriverStateTestSuite)) +} diff --git a/packages/taiko-client/driver/txlist_fetcher/blob.go b/packages/taiko-client/driver/txlist_fetcher/blob.go new file mode 100644 index 00000000000..dcedaadb4d7 --- /dev/null +++ b/packages/taiko-client/driver/txlist_fetcher/blob.go @@ -0,0 +1,67 @@ +package txlistdecoder + +import ( + "context" + "crypto/sha256" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/pkg" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// BlobFetcher is responsible for fetching the txList blob from the L1 block sidecar. +type BlobFetcher struct { + l1Beacon *rpc.BeaconClient + ds *rpc.BlobDataSource +} + +// NewBlobTxListFetcher creates a new BlobFetcher instance based on the given rpc client. +func NewBlobTxListFetcher(l1Beacon *rpc.BeaconClient, ds *rpc.BlobDataSource) *BlobFetcher { + return &BlobFetcher{l1Beacon, ds} +} + +// Fetch implements the TxListFetcher interface. +func (d *BlobFetcher) Fetch( + ctx context.Context, + _ *types.Transaction, + meta *bindings.TaikoDataBlockMetadata, +) ([]byte, error) { + if !meta.BlobUsed { + return nil, pkg.ErrBlobUsed + } + + // Fetch the L1 block sidecars. + sidecars, err := d.ds.GetBlobs(ctx, meta) + if err != nil { + return nil, err + } + + log.Info("Fetch sidecars", "blockNumber", meta.L1Height+1, "sidecars", len(sidecars)) + + // Compare the blob hash with the sidecar's kzg commitment. + for i, sidecar := range sidecars { + log.Info( + "Block sidecar", + "index", i, + "KzgCommitment", sidecar.KzgCommitment, + "blobHash", common.Bytes2Hex(meta.BlobHash[:]), + ) + + commitment := kzg4844.Commitment(common.FromHex(sidecar.KzgCommitment)) + if kzg4844.CalcBlobHashV1( + sha256.New(), + &commitment, + ) == common.BytesToHash(meta.BlobHash[:]) { + blob := eth.Blob(common.FromHex(sidecar.Blob)) + return blob.ToData() + } + } + + return nil, pkg.ErrSidecarNotFound +} diff --git a/packages/taiko-client/driver/txlist_fetcher/calldata.go b/packages/taiko-client/driver/txlist_fetcher/calldata.go new file mode 100644 index 00000000000..928fdc5b5fa --- /dev/null +++ b/packages/taiko-client/driver/txlist_fetcher/calldata.go @@ -0,0 +1,27 @@ +package txlistdecoder + +import ( + "context" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg" +) + +// CalldataFetcher is responsible for fetching the txList bytes from the transaction's calldata. +type CalldataFetcher struct{} + +// NewCalldataTxListFetcher creates a new CalldataFetcher instance. +func (d *CalldataFetcher) Fetch( + _ context.Context, + tx *types.Transaction, + meta *bindings.TaikoDataBlockMetadata, +) ([]byte, error) { + if meta.BlobUsed { + return nil, pkg.ErrBlobUsed + } + + return encoding.UnpackTxListBytes(tx.Data()) +} diff --git a/packages/taiko-client/driver/txlist_fetcher/interface.go b/packages/taiko-client/driver/txlist_fetcher/interface.go new file mode 100644 index 00000000000..8535c9f49de --- /dev/null +++ b/packages/taiko-client/driver/txlist_fetcher/interface.go @@ -0,0 +1,14 @@ +package txlistdecoder + +import ( + "context" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" +) + +// TxListFetcher is responsible for fetching the L2 txList bytes from L1 +type TxListFetcher interface { + Fetch(ctx context.Context, tx *types.Transaction, meta *bindings.TaikoDataBlockMetadata) ([]byte, error) +} diff --git a/packages/taiko-client/go.mod b/packages/taiko-client/go.mod new file mode 100644 index 00000000000..2d4e2d2f1aa --- /dev/null +++ b/packages/taiko-client/go.mod @@ -0,0 +1,257 @@ +module github.com/taikoxyz/taiko-client + +go 1.21 + +require ( + github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/cenkalti/backoff/v4 v4.1.3 + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 + github.com/ethereum-optimism/optimism v1.7.0 + github.com/ethereum/go-ethereum v1.13.14 + github.com/go-resty/resty/v2 v2.7.0 + github.com/holiman/uint256 v1.2.4 + github.com/joho/godotenv v1.5.1 + github.com/labstack/echo/v4 v4.11.1 + github.com/modern-go/reflect2 v1.0.2 + github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 + github.com/prometheus/client_golang v1.19.0 + github.com/prysmaticlabs/prysm/v4 v4.2.0 + github.com/stretchr/testify v1.9.0 + github.com/swaggo/swag v1.16.2 + github.com/urfave/cli/v2 v2.27.1 + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 + golang.org/x/sync v0.6.0 +) + +require ( + contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect + github.com/CloudyKit/jet/v6 v6.2.0 // indirect + github.com/DataDog/zstd v1.5.2 // indirect + github.com/Joker/jade v1.1.3 // indirect + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect + github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/btcsuite/btcd v0.24.0 // indirect + github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.11.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/containerd/cgroups v1.1.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/fjl/memsize v0.0.2 // indirect + github.com/flosch/pongo2/v4 v4.0.2 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect + github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/spec v0.20.9 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect + github.com/hashicorp/go-bexpr v0.1.11 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/iris-contrib/schema v0.0.6 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect + github.com/kataras/blocks v0.0.8 // indirect + github.com/kataras/golog v0.1.11 // indirect + github.com/kataras/iris/v12 v12.2.10 // indirect + github.com/kataras/pio v0.0.13 // indirect + github.com/kataras/sitemap v0.0.6 // indirect + github.com/kataras/tunnel v0.0.4 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/labstack/gommon v0.4.0 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.32.1 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect + github.com/libp2p/go-libp2p-mplex v0.9.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.10.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect + github.com/libp2p/go-nat v0.2.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-reuseport v0.4.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.1 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mailgun/raymond/v2 v2.0.48 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/microcosm-cc/bluemonday v1.0.26 // indirect + github.com/miekg/dns v1.1.56 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/pointerstructure v1.2.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.12.3 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/prom2json v1.3.0 // indirect + github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 // indirect + github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect + github.com/prysmaticlabs/gohashtree v0.0.3-alpha // indirect + github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect + github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rs/cors v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/schollz/closestmatch v2.1.0+incompatible // indirect + github.com/schollz/progressbar/v3 v3.3.4 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.10.0 // indirect + github.com/supranational/blst v0.3.11 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tdewolff/minify/v2 v2.20.14 // indirect + github.com/tdewolff/parse/v2 v2.7.8 // indirect + github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/wealdtech/go-bytesutil v1.1.1 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yosssi/ace v0.0.5 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect + google.golang.org/api v0.44.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.3 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apimachinery v0.20.0 // indirect + k8s.io/client-go v0.20.0 // indirect + k8s.io/klog/v2 v2.80.0 // indirect + k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect + lukechampine.com/blake3 v1.2.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.0.2 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace github.com/ethereum/go-ethereum v1.13.14 => github.com/taikoxyz/taiko-geth v0.0.0-20240417125434-12bb8478618f + +replace github.com/ethereum-optimism/optimism v1.7.0 => github.com/taikoxyz/optimism v0.0.0-20240421055139-477e311eb80b diff --git a/packages/taiko-client/go.sum b/packages/taiko-client/go.sum new file mode 100644 index 00000000000..26a4e6edd2b --- /dev/null +++ b/packages/taiko-client/go.sum @@ -0,0 +1,1690 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= +contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= +github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= +github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= +github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= +github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= +github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= +github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 h1:XJH0YfVFKbq782tlNThzN/Ud5qm/cx6LXOA/P6RkTxc= +github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= +github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= +github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +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= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= +github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 h1:PuHFhOUMnD62r80dN+Ik5qco2drekgsUSVdcHsvllec= +github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= +github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +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/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +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= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 h1:cNcG4c2n5xanQzp2hMyxDxPYVQmZ91y4WN6fJFlndLo= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018/go.mod h1:MIonLggsKgZLUSt414ExgwNtlOL5MuEoAJP514mwGe8= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= +github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= +github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= +github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 h1:Ep/joEub9YwcjRY6ND3+Y/w0ncE540RtGatVhtZL0/Q= +github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 h1:X2vfSnm1WC8HEo0MBHZg2TcuDUHJj6kd1TmEAQncnSA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.11 h1:6DqdA/KBjurGby9yTY0bmkathya0lfwF2SeuubCI7dY= +github.com/hashicorp/go-bexpr v0.1.11/go.mod h1:f03lAo0duBlDIUMGCuad8oLcgejw4m7U+N8T+6Kz1AE= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +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-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= +github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= +github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= +github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +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/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM= +github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg= +github.com/kataras/golog v0.1.11 h1:dGkcCVsIpqiAMWTlebn/ZULHxFvfG4K43LF1cNWSh20= +github.com/kataras/golog v0.1.11/go.mod h1:mAkt1vbPowFUuUGvexyQ5NFW6djEgGyxQBIARJ0AH4A= +github.com/kataras/iris/v12 v12.2.10 h1:rEJVM7qMoyhv8wpgkA1yGxibFcONE0jkJ70LFLibTAA= +github.com/kataras/iris/v12 v12.2.10/go.mod h1:z4+E+kLMqZ7U4WtDsYfFnG7BjMTXLkdzMAXLVMLnMNs= +github.com/kataras/pio v0.0.13 h1:x0rXVX0fviDTXOOLOmr4MUxOabu1InVSTu5itF8CXCM= +github.com/kataras/pio v0.0.13/go.mod h1:k3HNuSw+eJ8Pm2lA4lRhg3DiCjVgHlP8hmXApSej3oM= +github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= +github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= +github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= +github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= +github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +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-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.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= +github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8= +github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= +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.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= +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-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= +github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +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 v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mr-tron/base58 v1.1.2/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/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.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.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= +github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +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-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.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.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.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= +github.com/multiformats/go-varint v0.0.1/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= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +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.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= +github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= +github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +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.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/prom2json v1.3.0 h1:BlqrtbT9lLH3ZsOVhXPsHzFrApCTKRifB7gjJuypu6Y= +github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= +github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 h1:c3p3UzV4vFA7xaCDphnDWOjpxcadrQ26l5b+ypsvyxo= +github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= +github.com/prysmaticlabs/gohashtree v0.0.3-alpha h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY= +github.com/prysmaticlabs/gohashtree v0.0.3-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO/VN0s9k+RmLykho7AjDxblNYI5bYKed16NPU= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M= +github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h1:q9wE0ZZRdTUAAeyFP/w0SwBEnCqlVy2+on6X2/e+eAU= +github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= +github.com/prysmaticlabs/prysm/v4 v4.2.0 h1:87QoRT3Azs7c1Y6SnIq0+CNtQRbAt0sVKGj2OxRT1Rw= +github.com/prysmaticlabs/prysm/v4 v4.2.0/go.mod h1:PQrQtHJeeqTz4K3udN/EX1Gs2xhWR4j93gSj0OQZ1f4= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/schollz/progressbar/v3 v3.3.4 h1:nMinx+JaEm/zJz4cEyClQeAw5rsYSB5th3xv+5lV6Vg= +github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +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= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= +github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/taikoxyz/optimism v0.0.0-20240421055139-477e311eb80b h1:PkJ4rzgibmLZNIRCfDjTUtneXIvgBOUYCP+FEuLXMAo= +github.com/taikoxyz/optimism v0.0.0-20240421055139-477e311eb80b/go.mod h1:+M2UOTyG20iuKiQOi+Pzz3abOtTYbTnwah/CIp8o6Y8= +github.com/taikoxyz/taiko-geth v0.0.0-20240417125434-12bb8478618f h1:/LVWXZWuN+DTpkvI//rqbPOkpucr1dTal/OF6JVyxIs= +github.com/taikoxyz/taiko-geth v0.0.0-20240417125434-12bb8478618f/go.mod h1:nqByouVW0a0qx5KKgvYgoXba+pYEHznAAQp6LhZilgM= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tdewolff/minify/v2 v2.20.14 h1:sktSuVixRwk0ryQjqvKBu/uYS+MWmkwEFMEWtFZ+TdE= +github.com/tdewolff/minify/v2 v2.20.14/go.mod h1:qnIJbnG2dSzk7LIa/UUwgN2OjS8ir6RRlqc0T/1q2xY= +github.com/tdewolff/parse/v2 v2.7.8 h1:1cnVqa8L63xFkc2vfRsZTM6Qy35nJpTvQ2Uvdv3vbvs= +github.com/tdewolff/parse/v2 v2.7.8/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= +github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= +github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 h1:+LynomhWB+14Plp/bOONEAZCtvCZk4leRbTvNzNVkL0= +github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +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/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/wealdtech/go-bytesutil v1.1.1 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gqOy8JKVc= +github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= +github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +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.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-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= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.20.0 h1:WwrYoZNM1W1aQEbyl8HNG+oWGzLpZQBlcerS9BQw9yI= +k8s.io/api v0.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= +k8s.io/apimachinery v0.20.0 h1:jjzbTJRXk0unNS71L7h3lxGDH/2HPxMPaQY+MjECKL8= +k8s.io/apimachinery v0.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/client-go v0.20.0 h1:Xlax8PKbZsjX4gFvNtt4F5MoJ1V5prDvCuoq9B7iax0= +k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.80.0 h1:lyJt0TWMPaGoODa8B8bUuxgHS3W/m/bNr2cca3brA/g= +k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= +moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/packages/taiko-client/index.html b/packages/taiko-client/index.html new file mode 100644 index 00000000000..6a06a93af5b --- /dev/null +++ b/packages/taiko-client/index.html @@ -0,0 +1,29 @@ + + + + + + Prover Server API + + +
+ + + diff --git a/packages/taiko-client/integration_test/README.md b/packages/taiko-client/integration_test/README.md new file mode 100644 index 00000000000..c6335f54621 --- /dev/null +++ b/packages/taiko-client/integration_test/README.md @@ -0,0 +1,23 @@ +# How to debug test cases? +* start docker compose +``` +./internal/docker/start.sh +``` + +* deploy L1 contracts +``` +# replace $taiko-mono with the taiko-mono repo path. +TAIKO_MONO_DIR=$taiko-mono ./integration_test/deploy_l1_contract.sh +``` + +* expose environment variables into .env file. +``` +# replace $taiko-mono with the taiko-mono repo path. +TAIKO_MONO_DIR=$taiko-mono ./integration_test/test_env.sh +``` + +* copy the result of previous step and paste it into `Debug configurations` +> after debugging, don't forget stop docker compose! +``` +./internal/docker/stop.sh +``` \ No newline at end of file diff --git a/packages/taiko-client/integration_test/deploy_l1_contract.sh b/packages/taiko-client/integration_test/deploy_l1_contract.sh new file mode 100755 index 00000000000..694c5745277 --- /dev/null +++ b/packages/taiko-client/integration_test/deploy_l1_contract.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +source scripts/common.sh + +# load l1 chain deploy contracts environment variables +source integration_test/l1_env.sh + +# check taiko-mono dir path environment. +check_env "TAIKO_MONO_DIR" + +cd "$TAIKO_MONO_DIR"/packages/protocol && + forge script script/DeployOnL1.s.sol:DeployOnL1 \ + --fork-url "$L1_NODE_HTTP_ENDPOINT" \ + --broadcast \ + --ffi \ + -vvvvv \ + --evm-version cancun \ + --private-key "$PRIVATE_KEY" \ + --block-gas-limit 100000000 diff --git a/packages/taiko-client/integration_test/entrypoint.sh b/packages/taiko-client/integration_test/entrypoint.sh new file mode 100755 index 00000000000..abc478791c2 --- /dev/null +++ b/packages/taiko-client/integration_test/entrypoint.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -eou pipefail + +# load tool commands. +source scripts/common.sh + +# make sure all the commands are available. +check_command "cast" +check_command "forge" +check_command "docker" + +# start and stop docker compose +internal/docker/start.sh +trap "internal/docker/stop.sh" EXIT INT KILL ERR + +# deploy l1 contracts +integration_test/deploy_l1_contract.sh + +# load environment variables for integration test +source integration_test/test_env.sh + +# make sure environment variables are set +check_env "TAIKO_MONO_DIR" +check_env "L1_NODE_HTTP_ENDPOINT" +check_env "L1_NODE_WS_ENDPOINT" +check_env "L2_EXECUTION_ENGINE_HTTP_ENDPOINT" +check_env "L2_EXECUTION_ENGINE_WS_ENDPOINT" +check_env "L2_EXECUTION_ENGINE_AUTH_ENDPOINT" +check_env "TAIKO_L1_ADDRESS" +check_env "TAIKO_L2_ADDRESS" +check_env "TAIKO_TOKEN_ADDRESS" +check_env "ASSIGNMENT_HOOK_ADDRESS" +check_env "TIMELOCK_CONTROLLER" +check_env "ROLLUP_ADDRESS_MANAGER_CONTRACT_ADDRESS" +check_env "GUARDIAN_PROVER_CONTRACT_ADDRESS" +check_env "L1_CONTRACT_OWNER_PRIVATE_KEY" +check_env "L1_SECURITY_COUNCIL_PRIVATE_KEY" +check_env "L1_PROPOSER_PRIVATE_KEY" +check_env "L1_PROVER_PRIVATE_KEY" +check_env "TREASURY" +check_env "JWT_SECRET" +check_env "VERBOSITY" + +RUN_TESTS=${RUN_TESTS:-false} +PACKAGE=${PACKAGE:-...} + +if [ "$RUN_TESTS" == "true" ]; then + go test -v -p=1 ./"$PACKAGE" -coverprofile=coverage.out -covermode=atomic -timeout=700s +else + echo "💻 Local dev net started" +fi diff --git a/packages/taiko-client/integration_test/l1_env.sh b/packages/taiko-client/integration_test/l1_env.sh new file mode 100755 index 00000000000..12c2a25d3c3 --- /dev/null +++ b/packages/taiko-client/integration_test/l1_env.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +source internal/docker/docker_env.sh + +export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +export TAIKO_L2_ADDRESS=0x1670010000000000000000000000000000010001 +export L2_SIGNAL_SERVICE=0x1670010000000000000000000000000000010005 +export CONTRACT_OWNER=0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f +export TAIKO_TOKEN_PREMINT_RECIPIENT=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +export TAIKO_TOKEN_NAME="Taiko Token Test" +export TAIKO_TOKEN_SYMBOL="TTKOt" +export TIER_PROVIDER="devnet" +export PAUSE_TAIKO_L1="false" +export PAUSE_BRIDGE="false" +export TAIKO_TOKEN=0x0000000000000000000000000000000000000000 +export SHARED_ADDRESS_MANAGER=0x0000000000000000000000000000000000000000 +export PROPOSER=0x0000000000000000000000000000000000000000 +export PROPOSER_ONE=0x0000000000000000000000000000000000000000 + +GUARDIAN_PROVERS_ADDRESSES_LIST=( + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" + "0x90F79bf6EB2c4f870365E785982E1f101E93b906" + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" + "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f" + "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" +) +GUARDIAN_PROVERS_ADDRESSES=$(printf ",%s" "${GUARDIAN_PROVERS_ADDRESSES_LIST[@]}") +export GUARDIAN_PROVERS=${GUARDIAN_PROVERS_ADDRESSES:1} +export MIN_GUARDIANS=${#GUARDIAN_PROVERS_ADDRESSES_LIST[@]} + +# Get the hash of L2 genesis. +export L2_GENESIS_HASH=$( + curl \ + --silent \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":0,"method":"eth_getBlockByNumber","params":["0x0", false]}' \ + $L2_EXECUTION_ENGINE_HTTP_ENDPOINT | jq .result.hash | sed 's/\"//g' +) +echo "L2_GENESIS_HASH: $L2_GENESIS_HASH" diff --git a/packages/taiko-client/integration_test/test_env.sh b/packages/taiko-client/integration_test/test_env.sh new file mode 100755 index 00000000000..b106695fde2 --- /dev/null +++ b/packages/taiko-client/integration_test/test_env.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +source internal/docker/docker_env.sh +source scripts/common.sh + +# make sure environment variables are set. +check_env "TAIKO_MONO_DIR" + +# get deployed contract address. +DEPLOYMENT_JSON=$(cat "$TAIKO_MONO_DIR"/packages/protocol/deployments/deploy_l1.json) +export TAIKO_L1_ADDRESS=$(echo "$DEPLOYMENT_JSON" | jq '.taiko' | sed 's/\"//g') +export TAIKO_L2_ADDRESS=0x1670010000000000000000000000000000010001 +export TAIKO_TOKEN_ADDRESS=$(echo "$DEPLOYMENT_JSON" | jq '.taiko_token' | sed 's/\"//g') +export ASSIGNMENT_HOOK_ADDRESS=$(echo "$DEPLOYMENT_JSON" | jq '.assignment_hook' | sed 's/\"//g') +export TIMELOCK_CONTROLLER=$(echo "$DEPLOYMENT_JSON" | jq '.timelock_controller' | sed 's/\"//g') +export ROLLUP_ADDRESS_MANAGER_CONTRACT_ADDRESS=$(echo "$DEPLOYMENT_JSON" | jq '.rollup_address_manager' | sed 's/\"//g') +export GUARDIAN_PROVER_CONTRACT_ADDRESS=$(echo "$DEPLOYMENT_JSON" | jq '.guardian_prover' | sed 's/\"//g') +export L1_CONTRACT_OWNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +export L1_SECURITY_COUNCIL_PRIVATE_KEY=0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97 +export L1_PROPOSER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +export L2_SUGGESTED_FEE_RECIPIENT=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +export L1_PROVER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d +export TREASURY=0x1670010000000000000000000000000000010001 +export VERBOSITY=3 + +# show the integration test environment variables. +# L1_BEACON_HTTP_ENDPOINT=$L1_BEACON_HTTP_ENDPOINT +echo "RUN_TESTS=true +TAIKO_MONO_DIR=$TAIKO_MONO_DIR +L1_NODE_HTTP_ENDPOINT=$L1_NODE_HTTP_ENDPOINT +L1_NODE_WS_ENDPOINT=$L1_NODE_WS_ENDPOINT +L2_SUGGESTED_FEE_RECIPIENT=$L2_SUGGESTED_FEE_RECIPIENT +L2_EXECUTION_ENGINE_HTTP_ENDPOINT=$L2_EXECUTION_ENGINE_HTTP_ENDPOINT +L2_EXECUTION_ENGINE_WS_ENDPOINT=$L2_EXECUTION_ENGINE_WS_ENDPOINT +L2_EXECUTION_ENGINE_AUTH_ENDPOINT=$L2_EXECUTION_ENGINE_AUTH_ENDPOINT +TAIKO_L1_ADDRESS=$TAIKO_L1_ADDRESS +TAIKO_L2_ADDRESS=$TAIKO_L2_ADDRESS +TAIKO_TOKEN_ADDRESS=$TAIKO_TOKEN_ADDRESS +ASSIGNMENT_HOOK_ADDRESS=$ASSIGNMENT_HOOK_ADDRESS +TIMELOCK_CONTROLLER=$TIMELOCK_CONTROLLER +ROLLUP_ADDRESS_MANAGER_CONTRACT_ADDRESS=$ROLLUP_ADDRESS_MANAGER_CONTRACT_ADDRESS +GUARDIAN_PROVER_CONTRACT_ADDRESS=$GUARDIAN_PROVER_CONTRACT_ADDRESS +L1_CONTRACT_OWNER_PRIVATE_KEY=$L1_CONTRACT_OWNER_PRIVATE_KEY +L1_SECURITY_COUNCIL_PRIVATE_KEY=$L1_SECURITY_COUNCIL_PRIVATE_KEY +L1_PROPOSER_PRIVATE_KEY=$L1_PROPOSER_PRIVATE_KEY +L1_PROVER_PRIVATE_KEY=$L1_PROVER_PRIVATE_KEY +TREASURY=$TREASURY +JWT_SECRET=$JWT_SECRET +VERBOSITY=$VERBOSITY" > integration_test/.env diff --git a/packages/taiko-client/internal/docker/.gitignore b/packages/taiko-client/internal/docker/.gitignore new file mode 100644 index 00000000000..a3127c66cf1 --- /dev/null +++ b/packages/taiko-client/internal/docker/.gitignore @@ -0,0 +1 @@ +taikogeth/taiko-geth diff --git a/packages/taiko-client/internal/docker/docker_env.sh b/packages/taiko-client/internal/docker/docker_env.sh new file mode 100755 index 00000000000..ccaab9a033c --- /dev/null +++ b/packages/taiko-client/internal/docker/docker_env.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# check until L1 chain is ready +L1_PROBE_URL=ws://localhost:$(docker port l1_node | grep '0.0.0.0' | awk -F ':' '{print $2}') +until cast chain-id --rpc-url "$L1_PROBE_URL" 2> /dev/null; do + sleep 1 +done + +# check until L2 chain is ready +L2_PROBE_URL=ws://localhost:$(docker port l2_node | grep "0.0.0.0" | awk -F ':' 'NR==2 {print $2}') +until cast chain-id --rpc-url "$L2_PROBE_URL" 2> /dev/null; do + sleep 1 +done + +L1_NODE_PORT=$(docker port l1_node | grep '0.0.0.0' | awk -F ':' '{print $2}') +export L1_NODE_HTTP_ENDPOINT=http://localhost:$L1_NODE_PORT +export L1_NODE_WS_ENDPOINT=ws://localhost:$L1_NODE_PORT + +export L2_EXECUTION_ENGINE_HTTP_ENDPOINT=http://localhost:$(docker port l2_node | grep "0.0.0.0" | awk -F ':' 'NR==1 {print $2}') +export L2_EXECUTION_ENGINE_WS_ENDPOINT=ws://localhost:$(docker port l2_node | grep "0.0.0.0" | awk -F ':' 'NR==2 {print $2}') +export L2_EXECUTION_ENGINE_AUTH_ENDPOINT=http://localhost:$(docker port l2_node | grep "0.0.0.0" | awk -F ':' 'NR==3 {print $2}') +export JWT_SECRET=$DIR/nodes/jwt.hex + +echo -e "L1_NODE PORTS: \n$(docker port l1_node)" +echo -e "L2_NODE PORTS: \n$(docker port l2_node)" + +echo "L1_NODE_HTTP_ENDPOINT: $L1_NODE_HTTP_ENDPOINT" +echo "L1_NODE_WS_ENDPOINT: $L1_NODE_WS_ENDPOINT" +echo "L2_EXECUTION_ENGINE_HTTP_ENDPOINT: $L2_EXECUTION_ENGINE_HTTP_ENDPOINT" +echo "L2_EXECUTION_ENGINE_WS_ENDPOINT: $L2_EXECUTION_ENGINE_WS_ENDPOINT" +echo "L2_EXECUTION_ENGINE_AUTH_ENDPOINT: $L2_EXECUTION_ENGINE_AUTH_ENDPOINT" diff --git a/packages/taiko-client/internal/docker/nodes/docker-compose.yml b/packages/taiko-client/internal/docker/nodes/docker-compose.yml new file mode 100644 index 00000000000..bd0d48940fa --- /dev/null +++ b/packages/taiko-client/internal/docker/nodes/docker-compose.yml @@ -0,0 +1,67 @@ +services: + l1_node: + container_name: l1_node + image: ghcr.io/foundry-rs/foundry:nightly + restart: unless-stopped + platform: linux/amd64 + pull_policy: always + ports: + - "8545" + entrypoint: + - anvil + - --host + - "0.0.0.0" + - --hardfork + - cancun + + l2_execution_engine: + container_name: l2_node + image: us-docker.pkg.dev/evmchain/images/taiko-geth:taiko + restart: unless-stopped + pull_policy: always + volumes: + - .:/host + ports: + - "8545" + - "8546" + - "8551" + command: + - --nodiscover + - --gcmode + - archive + - --syncmode + - full + - --datadir + - /data/taiko-geth + - --networkid + - "167001" + - --metrics + - --metrics.expensive + - --metrics.addr + - "0.0.0.0" + - --http + - --http.addr + - "0.0.0.0" + - --http.vhosts + - "*" + - --http.corsdomain + - "*" + - --ws + - --ws.addr + - "0.0.0.0" + - --ws.origins + - "*" + - --authrpc.addr + - "0.0.0.0" + - --authrpc.port + - "8551" + - --authrpc.vhosts + - "*" + - --authrpc.jwtsecret + - /host/jwt.hex + - --allow-insecure-unlock + - --http.api + - admin,debug,eth,net,web3,txpool,miner,taiko + - --ws.api + - admin,debug,eth,net,web3,txpool,miner,taiko + - --taiko diff --git a/packages/taiko-client/internal/docker/nodes/jwt.hex b/packages/taiko-client/internal/docker/nodes/jwt.hex new file mode 100644 index 00000000000..e48067e7fd2 --- /dev/null +++ b/packages/taiko-client/internal/docker/nodes/jwt.hex @@ -0,0 +1 @@ +c49690b5a9bc72c7b451b48c5fee2b542e66559d840a133d090769abc56e39e7 diff --git a/packages/taiko-client/internal/docker/start.sh b/packages/taiko-client/internal/docker/start.sh new file mode 100755 index 00000000000..cde4a56a28c --- /dev/null +++ b/packages/taiko-client/internal/docker/start.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +source scripts/common.sh + +DOCKER_SERVICE_LIST=("l1_node" "l2_execution_engine") + +# start docker compose service list +echo "start docker compose service: ${DOCKER_SERVICE_LIST[*]}" + +compose_up "${DOCKER_SERVICE_LIST[@]}" + +# show all the running containers +echo +docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}\t{{.Status}}" diff --git a/packages/taiko-client/internal/docker/stop.sh b/packages/taiko-client/internal/docker/stop.sh new file mode 100755 index 00000000000..0a69ade3282 --- /dev/null +++ b/packages/taiko-client/internal/docker/stop.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +source scripts/common.sh + +DOCKER_SERVICE_LIST=("l1_node" "l2_execution_engine") + +echo "stop docker compose service: ${DOCKER_SERVICE_LIST[*]}" + +compose_down "${DOCKER_SERVICE_LIST[@]}" diff --git a/packages/taiko-client/internal/metrics/metrics.go b/packages/taiko-client/internal/metrics/metrics.go new file mode 100644 index 00000000000..61329df4e2a --- /dev/null +++ b/packages/taiko-client/internal/metrics/metrics.go @@ -0,0 +1,90 @@ +package metrics + +import ( + "context" + + opMetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/opio" + txmgrMetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "github.com/ethereum/go-ethereum/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" +) + +// Metrics +var ( + registry = opMetrics.NewRegistry() + factory = opMetrics.With(registry) + + // Driver + DriverL1HeadHeightGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "driver_l1Head_height"}) + DriverL2HeadHeightGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "driver_l2Head_height"}) + DriverL1CurrentHeightGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "driver_l1Current_height"}) + DriverL2HeadIDGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "driver_l2Head_id"}) + DriverL2VerifiedHeightGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "driver_l2Verified_id"}) + + // Proposer + ProposerProposeEpochCounter = factory.NewCounter(prometheus.CounterOpts{Name: "proposer_epoch"}) + ProposerProposedTxListsCounter = factory.NewCounter(prometheus.CounterOpts{Name: "proposer_proposed_txLists"}) + ProposerProposedTxsCounter = factory.NewCounter(prometheus.CounterOpts{Name: "proposer_proposed_txs"}) + + // Prover + ProverLatestVerifiedIDGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "prover_latestVerified_id"}) + ProverLatestProvenBlockIDGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "prover_latestProven_id"}) + ProverQueuedProofCounter = factory.NewCounter(prometheus.CounterOpts{Name: "prover_proof_all_queued"}) + ProverReceivedProofCounter = factory.NewCounter(prometheus.CounterOpts{Name: "prover_proof_all_received"}) + ProverSentProofCounter = factory.NewCounter(prometheus.CounterOpts{Name: "prover_proof_all_sent"}) + ProverProofsAssigned = factory.NewCounter(prometheus.CounterOpts{Name: "prover_proof_assigned"}) + ProverReceivedProposedBlockGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "prover_proposed_received"}) + ProverReceivedProvenBlockGauge = factory.NewGauge(prometheus.GaugeOpts{Name: "prover_proven_received"}) + ProverSubmissionAcceptedCounter = factory.NewCounter(prometheus.CounterOpts{ + Name: "prover_proof_submission_accepted", + }) + ProverSubmissionErrorCounter = factory.NewCounter(prometheus.CounterOpts{ + Name: "prover_proof_submission_error", + }) + ProverSgxProofGeneratedCounter = factory.NewCounter(prometheus.CounterOpts{ + Name: "prover_proof_sgx_generated", + }) + ProverSubmissionRevertedCounter = factory.NewCounter(prometheus.CounterOpts{ + Name: "prover_proof_submission_reverted", + }) + + // TxManager + TxMgrMetrics = txmgrMetrics.MakeTxMetrics("client", factory) +) + +// Serve starts the metrics server on the given address, will be closed when the given +// context is cancelled. +func Serve(ctx context.Context, c *cli.Context) error { + if !c.Bool(flags.MetricsEnabled.Name) { + return nil + } + + log.Info( + "Starting metrics server", + "host", c.String(flags.MetricsAddr.Name), + "port", c.Int(flags.MetricsPort.Name), + ) + + server, err := opMetrics.StartServer( + registry, + c.String(flags.MetricsAddr.Name), + c.Int(flags.MetricsPort.Name), + ) + if err != nil { + return err + } + + defer func() { + if err := server.Stop(ctx); err != nil { + log.Error("Failed to close metrics server", "error", err) + } + }() + + opio.BlockOnInterruptsContext(ctx) + + return nil +} diff --git a/packages/taiko-client/internal/testutils/helper.go b/packages/taiko-client/internal/testutils/helper.go new file mode 100644 index 00000000000..fffcb9dbfe6 --- /dev/null +++ b/packages/taiko-client/internal/testutils/helper.go @@ -0,0 +1,366 @@ +package testutils + +import ( + "context" + "crypto/ecdsa" + "crypto/rand" + "errors" + "fmt" + "math/big" + "net/http" + "net/url" + "os" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/go-resty/resty/v2" + "github.com/phayes/freeport" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/server" +) + +func (s *ClientTestSuite) ProposeInvalidTxListBytes(proposer Proposer) { + invalidTxListBytes := RandomBytes(256) + + for _, err := range proposer.ProposeTxLists(context.Background(), [][]byte{invalidTxListBytes}) { + s.Nil(err) + } +} + +func (s *ClientTestSuite) proposeEmptyBlockOp(ctx context.Context, proposer Proposer) { + emptyTxListBytes, err := rlp.EncodeToBytes(types.Transactions{}) + s.Nil(err) + for _, err := range proposer.ProposeTxLists(ctx, [][]byte{emptyTxListBytes}) { + s.Nil(err) + } +} + +func (s *ClientTestSuite) ProposeAndInsertEmptyBlocks( + proposer Proposer, + blobSyncer BlobSyncer, +) []*bindings.TaikoL1ClientBlockProposed { + var events []*bindings.TaikoL1ClientBlockProposed + + l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + sink := make(chan *bindings.TaikoL1ClientBlockProposed) + + sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + // RLP encoded empty list + var emptyTxs []types.Transaction + encoded, err := rlp.EncodeToBytes(emptyTxs) + s.Nil(err) + + for _, err := range proposer.ProposeTxLists(context.Background(), [][]byte{encoded}) { + s.Nil(err) + } + + s.ProposeInvalidTxListBytes(proposer) + + // Random bytes txList + s.proposeEmptyBlockOp(context.Background(), proposer) + + events = append(events, []*bindings.TaikoL1ClientBlockProposed{<-sink, <-sink, <-sink}...) + + _, isPending, err := s.RPCClient.L1.TransactionByHash(context.Background(), events[len(events)-1].Raw.TxHash) + s.Nil(err) + s.False(isPending) + + newL1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(newL1Head.Number.Uint64(), l1Head.Number.Uint64()) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.Nil(backoff.Retry(func() error { + return blobSyncer.ProcessL1Blocks(ctx) + }, backoff.NewExponentialBackOff())) + + s.Nil(s.RPCClient.WaitTillL2ExecutionEngineSynced(context.Background())) + + return events +} + +// ProposeAndInsertValidBlock proposes an valid tx list and then insert it +// into L2 execution engine's local chain. +func (s *ClientTestSuite) ProposeAndInsertValidBlock( + proposer Proposer, + blobSyncer BlobSyncer, +) *bindings.TaikoL1ClientBlockProposed { + l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + // Propose txs in L2 execution engine's mempool + sink := make(chan *bindings.TaikoL1ClientBlockProposed) + + sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + baseFeeInfo, err := s.RPCClient.TaikoL2.GetBasefee(nil, l1Head.Number.Uint64()+1, uint32(l2Head.GasUsed)) + s.Nil(err) + + nonce, err := s.RPCClient.L2.PendingNonceAt(context.Background(), s.TestAddr) + s.Nil(err) + + tx := types.NewTransaction( + nonce, + common.BytesToAddress(RandomBytes(32)), + common.Big1, + 100000, + new(big.Int).SetUint64(uint64(10*params.GWei)+baseFeeInfo.Basefee.Uint64()), + []byte{}, + ) + signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(s.RPCClient.L2.ChainID), s.TestAddrPrivKey) + s.Nil(err) + s.Nil(s.RPCClient.L2.SendTransaction(context.Background(), signedTx)) + + s.Nil(proposer.ProposeOp(context.Background())) + + event := <-sink + + _, isPending, err := s.RPCClient.L1.TransactionByHash(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.False(isPending) + + receipt, err := s.RPCClient.L1.TransactionReceipt(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.Equal(types.ReceiptStatusSuccessful, receipt.Status) + + newL1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(newL1Head.Number.Uint64(), l1Head.Number.Uint64()) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + s.Nil(backoff.Retry(func() error { + return blobSyncer.ProcessL1Blocks(ctx) + }, backoff.NewExponentialBackOff())) + + s.Nil(s.RPCClient.WaitTillL2ExecutionEngineSynced(context.Background())) + + _, err = s.RPCClient.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + return event +} + +func (s *ClientTestSuite) ProposeValidBlock( + proposer Proposer, +) *bindings.TaikoL1ClientBlockProposed { + l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + // Propose txs in L2 execution engine's mempool + sink := make(chan *bindings.TaikoL1ClientBlockProposed) + + sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + baseFeeInfo, err := s.RPCClient.TaikoL2.GetBasefee(nil, l1Head.Number.Uint64()+1, uint32(l2Head.GasUsed)) + s.Nil(err) + + nonce, err := s.RPCClient.L2.PendingNonceAt(context.Background(), s.TestAddr) + s.Nil(err) + + tx := types.NewTransaction( + nonce, + common.BytesToAddress(RandomBytes(32)), + common.Big1, + 100000, + new(big.Int).SetUint64(uint64(10*params.GWei)+baseFeeInfo.Basefee.Uint64()), + []byte{}, + ) + signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(s.RPCClient.L2.ChainID), s.TestAddrPrivKey) + s.Nil(err) + s.Nil(s.RPCClient.L2.SendTransaction(context.Background(), signedTx)) + + s.Nil(proposer.ProposeOp(context.Background())) + + event := <-sink + + _, isPending, err := s.RPCClient.L1.TransactionByHash(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.False(isPending) + + receipt, err := s.RPCClient.L1.TransactionReceipt(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.Equal(types.ReceiptStatusSuccessful, receipt.Status) + + newL1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + s.Greater(newL1Head.Number.Uint64(), l1Head.Number.Uint64()) + + return event +} + +// NewTestProverServer starts a new prover server that has channel listeners to respond and react +// to requests for capacity, which provers can call. +func (s *ClientTestSuite) NewTestProverServer( + proverPrivKey *ecdsa.PrivateKey, + url *url.URL, +) *server.ProverServer { + protocolConfig, err := s.RPCClient.TaikoL1.GetConfig(nil) + s.Nil(err) + + srv, err := server.New(&server.NewProverServerOpts{ + ProverPrivateKey: proverPrivKey, + MinOptimisticTierFee: common.Big1, + MinSgxTierFee: common.Big1, + MinSgxAndZkVMTierFee: common.Big1, + MinEthBalance: common.Big1, + MinTaikoTokenBalance: common.Big1, + MaxExpiry: 24 * time.Hour, + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + RPC: s.RPCClient, + ProtocolConfigs: &protocolConfig, + LivenessBond: protocolConfig.LivenessBond, + }) + s.Nil(err) + + go func() { + if err := srv.Start(fmt.Sprintf(":%v", url.Port())); !errors.Is(err, http.ErrServerClosed) { + log.Error("Failed to start prover server", "error", err) + } + }() + + // Wait till the server fully started. + s.Nil(backoff.Retry(func() error { + res, err := resty.New().R().Get(url.String() + "/healthz") + if err != nil { + return err + } + if !res.IsSuccess() { + return fmt.Errorf("invalid response status code: %d", res.StatusCode()) + } + + return nil + }, backoff.NewExponentialBackOff())) + + return srv +} + +// RandomHash generates a random blob of data and returns it as a hash. +func RandomHash() common.Hash { + var hash common.Hash + if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { + panic(err) + } + return hash +} + +// RandomBytes generates a random bytes. +func RandomBytes(size int) (b []byte) { + b = make([]byte, size) + if _, err := rand.Read(b); err != nil { + log.Crit("Generate random bytes error", "error", err) + } + return +} + +// RandomPort returns a local free random port. +func RandomPort() int { + port, err := freeport.GetFreePort() + if err != nil { + log.Crit("Failed to get local free random port", "error", err) + } + return port +} + +// LocalRandomProverEndpoint returns a local free random prover endpoint. +func LocalRandomProverEndpoint() *url.URL { + port := RandomPort() + + proverEndpoint, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) + if err != nil { + log.Crit("Failed to parse local prover endpoint", "error", err) + } + + return proverEndpoint +} + +// SignatureFromRSV creates the signature bytes from r,s,v. +func SignatureFromRSV(r, s string, v byte) []byte { + return append(append(hexutil.MustDecode(r), hexutil.MustDecode(s)...), v) +} + +// SendDynamicFeeTx sends a dynamic transaction, used for tests. +func SendDynamicFeeTx( + client *rpc.EthClient, + priv *ecdsa.PrivateKey, + to *common.Address, + value *big.Int, + data []byte, +) (*types.Transaction, error) { + head, err := client.HeaderByNumber(context.Background(), nil) + if err != nil { + return nil, err + } + + auth, err := bind.NewKeyedTransactorWithChainID(priv, client.ChainID) + if err != nil { + return nil, err + } + + nonce, err := client.PendingNonceAt(context.Background(), auth.From) + if err != nil { + return nil, err + } + + gasTipCap, err := client.SuggestGasTipCap(context.Background()) + if err != nil { + return nil, err + } + + tx, err := auth.Signer(auth.From, types.NewTx(&types.DynamicFeeTx{ + To: to, + Nonce: nonce, + Value: value, + GasTipCap: gasTipCap, + GasFeeCap: new(big.Int).Add( + gasTipCap, + new(big.Int).Mul(head.BaseFee, big.NewInt(2)), + ), + Gas: 2100_000, + Data: data, + })) + if err != nil { + return nil, err + } + if err = client.SendTransaction(context.Background(), tx); err != nil { + return nil, err + } + return tx, nil +} diff --git a/packages/taiko-client/internal/testutils/interfaces.go b/packages/taiko-client/internal/testutils/interfaces.go new file mode 100644 index 00000000000..88a5602ab58 --- /dev/null +++ b/packages/taiko-client/internal/testutils/interfaces.go @@ -0,0 +1,17 @@ +package testutils + +import ( + "context" + + "github.com/taikoxyz/taiko-client/cmd/utils" +) + +type BlobSyncer interface { + ProcessL1Blocks(ctx context.Context) error +} + +type Proposer interface { + utils.SubcommandApplication + ProposeOp(ctx context.Context) error + ProposeTxLists(ctx context.Context, txListsBytes [][]byte) []error +} diff --git a/packages/taiko-client/internal/testutils/suite.go b/packages/taiko-client/internal/testutils/suite.go new file mode 100644 index 00000000000..0e5e31fff81 --- /dev/null +++ b/packages/taiko-client/internal/testutils/suite.go @@ -0,0 +1,190 @@ +package testutils + +import ( + "context" + "crypto/ecdsa" + "math/big" + "net/url" + "os" + "strconv" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/server" +) + +type ClientTestSuite struct { + suite.Suite + testnetL1SnapshotID string + RPCClient *rpc.Client + TestAddrPrivKey *ecdsa.PrivateKey + TestAddr common.Address + ProverEndpoints []*url.URL + AddressManager *bindings.AddressManager + proverServer *server.ProverServer +} + +func (s *ClientTestSuite) SetupTest() { + utils.LoadEnv() + // Default logger + ver, err := strconv.Atoi(os.Getenv("VERBOSITY")) + s.Nil(err) + glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stdout, true)) + glogger.Verbosity(log.FromLegacyLevel(ver)) + log.SetDefault(log.NewLogger(glogger)) + + testAddrPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + s.TestAddrPrivKey = testAddrPrivKey + s.TestAddr = common.HexToAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266") + + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + rpcCli, err := rpc.NewClient(context.Background(), &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + GuardianProverAddress: common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + }) + s.Nil(err) + s.RPCClient = rpcCli + + s.Nil(s.RPCClient.WaitTillL2ExecutionEngineSynced(context.Background())) + + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + s.ProverEndpoints = []*url.URL{LocalRandomProverEndpoint()} + s.proverServer = s.NewTestProverServer(l1ProverPrivKey, s.ProverEndpoints[0]) + + balance, err := rpcCli.TaikoToken.BalanceOf(nil, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey)) + s.Nil(err) + + if balance.Cmp(common.Big0) == 0 { + ownerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_CONTRACT_OWNER_PRIVATE_KEY"))) + s.Nil(err) + + // Transfer some tokens to provers. + balance, err := rpcCli.TaikoToken.BalanceOf(nil, crypto.PubkeyToAddress(ownerPrivKey.PublicKey)) + s.Nil(err) + s.Greater(balance.Cmp(common.Big0), 0) + + opts, err := bind.NewKeyedTransactorWithChainID(ownerPrivKey, rpcCli.L1.ChainID) + s.Nil(err) + proverBalance := new(big.Int).Div(balance, common.Big2) + s.Greater(proverBalance.Cmp(common.Big0), 0) + + _, err = rpcCli.TaikoToken.Transfer(opts, crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey), proverBalance) + s.Nil(err) + + // Increase allowance for AssignmentHook and TaikoL1 + s.setAllowance(l1ProverPrivKey) + s.setAllowance(ownerPrivKey) + } + s.testnetL1SnapshotID = s.SetL1Snapshot() +} + +func (s *ClientTestSuite) setAllowance(key *ecdsa.PrivateKey) { + t, err := txmgr.NewSimpleTxManager( + "setAllowance", + log.Root(), + new(metrics.NoopTxMetrics), + txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(key)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + ) + s.Nil(err) + + decimal, err := s.RPCClient.TaikoToken.Decimals(nil) + s.Nil(err) + + var ( + bigInt = new(big.Int).Exp(big.NewInt(1_000_000_000), new(big.Int).SetUint64(uint64(decimal)), nil) + taikoTokenAddress = common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")) + ) + + data, err := encoding.TaikoTokenABI.Pack( + "approve", + common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + bigInt, + ) + s.Nil(err) + _, err = t.Send(context.Background(), txmgr.TxCandidate{ + TxData: data, + To: &taikoTokenAddress, + }) + s.Nil(err) + + data, err = encoding.TaikoTokenABI.Pack( + "approve", + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + bigInt, + ) + s.Nil(err) + _, err = t.Send(context.Background(), txmgr.TxCandidate{ + TxData: data, + To: &taikoTokenAddress, + }) + s.Nil(err) +} + +func (s *ClientTestSuite) TearDownTest() { + s.RevertL1Snapshot(s.testnetL1SnapshotID) + + s.Nil(rpc.SetHead(context.Background(), s.RPCClient.L2, common.Big0)) + s.Nil(s.proverServer.Shutdown(context.Background())) +} + +func (s *ClientTestSuite) SetL1Automine(automine bool) { + s.Nil(s.RPCClient.L1.CallContext(context.Background(), nil, "evm_setAutomine", automine)) +} + +func (s *ClientTestSuite) IncreaseTime(time uint64) { + var result uint64 + s.Nil(s.RPCClient.L1.CallContext(context.Background(), &result, "evm_increaseTime", time)) + s.NotNil(result) +} + +func (s *ClientTestSuite) SetL1Snapshot() string { + var snapshotID string + s.Nil(s.RPCClient.L1.CallContext(context.Background(), &snapshotID, "evm_snapshot")) + s.NotEmpty(snapshotID) + return snapshotID +} + +func (s *ClientTestSuite) RevertL1Snapshot(snapshotID string) { + var revertRes bool + s.Nil(s.RPCClient.L1.CallContext(context.Background(), &revertRes, "evm_revert", snapshotID)) + s.True(revertRes) +} diff --git a/packages/taiko-client/internal/utils/test_utils.go b/packages/taiko-client/internal/utils/test_utils.go new file mode 100644 index 00000000000..a1ca5db35fe --- /dev/null +++ b/packages/taiko-client/internal/utils/test_utils.go @@ -0,0 +1,16 @@ +package utils + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/assert" +) + +// MineL1Block mines a block on the L1 chain. +func MineL1Block(t *testing.T, l1Client *rpc.Client) { + var blockID string + assert.Nil(t, l1Client.CallContext(context.Background(), &blockID, "evm_mine")) + assert.NotEmpty(t, blockID) +} diff --git a/packages/taiko-client/internal/utils/util_test.go b/packages/taiko-client/internal/utils/util_test.go new file mode 100644 index 00000000000..3dae28bbedd --- /dev/null +++ b/packages/taiko-client/internal/utils/util_test.go @@ -0,0 +1,49 @@ +package utils_test + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +func TestEncodeDecodeBytes(t *testing.T) { + b := testutils.RandomBytes(1024) + + compressed, err := utils.Compress(b) + require.Nil(t, err) + require.NotEmpty(t, compressed) + + decompressed, err := utils.Decompress(compressed) + require.Nil(t, err) + + require.Equal(t, b, decompressed) +} + +func TestGWeiToWei(t *testing.T) { + wei, err := utils.GWeiToWei(1.0) + require.Nil(t, err) + + require.Equal(t, big.NewInt(params.GWei), wei) +} + +func TestEtherToWei(t *testing.T) { + wei, err := utils.EtherToWei(1.0) + require.Nil(t, err) + + require.Equal(t, big.NewInt(params.Ether), wei) +} + +func TestWeiToEther(t *testing.T) { + eth := utils.WeiToEther(big.NewInt(params.Ether)) + require.Equal(t, new(big.Float).SetUint64(1), eth) +} + +func TestWeiToGWei(t *testing.T) { + gwei := utils.WeiToGWei(big.NewInt(params.GWei)) + require.Equal(t, new(big.Float).SetUint64(1), gwei) +} diff --git a/packages/taiko-client/internal/utils/utils.go b/packages/taiko-client/internal/utils/utils.go new file mode 100644 index 00000000000..1eaea75dd87 --- /dev/null +++ b/packages/taiko-client/internal/utils/utils.go @@ -0,0 +1,162 @@ +package utils + +import ( + "bytes" + "compress/zlib" + "crypto/rand" + "errors" + "fmt" + "math" + + "io" + "math/big" + "os" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/joho/godotenv" + "github.com/modern-go/reflect2" + "golang.org/x/exp/constraints" +) + +// LoadEnv loads all the test environment variables. +func LoadEnv() { + currentPath, err := os.Getwd() + if err != nil { + log.Debug("Failed to get current path", "error", err) + } + path := strings.Split(currentPath, "/taiko-client") + if len(path) == 0 { + log.Debug("Not a taiko-client repo") + } + if godotenv.Load(fmt.Sprintf("%s/taiko-client/integration_test/.env", path[0])) != nil { + log.Debug("Failed to load test env", "current path", currentPath, "error", err) + } +} + +// RandUint64 returns a random uint64 number. +func RandUint64(max *big.Int) uint64 { + if max == nil { + max = new(big.Int) + max.SetUint64(math.MaxUint64) + } + num, _ := rand.Int(rand.Reader, max) + + return num.Uint64() +} + +// RandUint32 returns a random uint32 number. +func RandUint32(max *big.Int) uint32 { + if max == nil { + max = new(big.Int) + max.SetUint64(math.MaxUint32) + } + num, _ := rand.Int(rand.Reader, max) + return uint32(num.Uint64()) +} + +// IsNil checks if the interface is empty. +func IsNil(i interface{}) bool { + return reflect2.IsNil(i) +} + +// Min return the minimum value of two integers. +func Min[T constraints.Integer](a, b T) T { + if a < b { + return a + } + return b +} + +// Max return the maximum value of two integers. +func Max[T constraints.Integer](a, b T) T { + if a > b { + return a + } + return b +} + +// Compress compresses the given txList bytes using zlib. +func Compress(txList []byte) ([]byte, error) { + var b bytes.Buffer + w := zlib.NewWriter(&b) + defer w.Close() + + if _, err := w.Write(txList); err != nil { + return nil, err + } + + if err := w.Close(); err != nil { + return nil, err + } + + return b.Bytes(), nil +} + +// Decompress decompresses the given txList bytes using zlib. +func Decompress(compressedTxList []byte) ([]byte, error) { + r, err := zlib.NewReader(bytes.NewBuffer(compressedTxList)) + if err != nil { + return nil, err + } + defer r.Close() + + b, err := io.ReadAll(r) + if err != nil { + if !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) { + return nil, err + } + } + + return b, nil +} + +// GWeiToWei converts gwei value to wei value. +func GWeiToWei(gwei float64) (*big.Int, error) { + if math.IsNaN(gwei) || math.IsInf(gwei, 0) { + return nil, fmt.Errorf("invalid gwei value: %v", gwei) + } + + // convert float GWei value into integer Wei value + wei, _ := new(big.Float).Mul( + big.NewFloat(gwei), + big.NewFloat(params.GWei)). + Int(nil) + + if wei.Cmp(abi.MaxUint256) == 1 { + return nil, errors.New("gwei value larger than max uint256") + } + + return wei, nil +} + +// EtherToWei converts ether value to wei value. +func EtherToWei(ether float64) (*big.Int, error) { + if math.IsNaN(ether) || math.IsInf(ether, 0) { + return nil, fmt.Errorf("invalid ether value: %v", ether) + } + + // convert float GWei value into integer Wei value + wei, _ := new(big.Float).Mul( + big.NewFloat(ether), + big.NewFloat(params.Ether)). + Int(nil) + + if wei.Cmp(abi.MaxUint256) == 1 { + return nil, errors.New("ether value larger than max uint256") + } + + return wei, nil +} + +// WeiToEther converts wei value to ether value. +func WeiToEther(wei *big.Int) *big.Float { + return new(big.Float).Quo(new(big.Float).SetInt(wei), new(big.Float).SetInt(big.NewInt(params.Ether))) +} + +// WeiToGWei converts wei value to gwei value. +func WeiToGWei(wei *big.Int) *big.Float { + return new(big.Float).Quo(new(big.Float).SetInt(wei), new(big.Float).SetInt(big.NewInt(params.GWei))) +} diff --git a/packages/taiko-client/internal/version/version.go b/packages/taiko-client/internal/version/version.go new file mode 100644 index 00000000000..cc0463bea5e --- /dev/null +++ b/packages/taiko-client/internal/version/version.go @@ -0,0 +1,24 @@ +package version + +// Version info. +const Version = "0.18.0" // x-release-please-version + +var meta = "dev" + +// Git commit/date info, set via linker flags. +var ( + GitCommit = "" + GitDate = "" +) + +// CommitVersion returns a textual version string including Git commit/date information. +func CommitVersion() string { + vsn := Version + "-" + meta + if len(GitCommit) >= 8 { + vsn += "-" + GitCommit[:8] + } + if (meta != "stable") && (GitDate != "") { + vsn += "-" + GitDate + } + return vsn +} diff --git a/packages/taiko-client/pkg/chain_iterator/block_batch_iterator.go b/packages/taiko-client/pkg/chain_iterator/block_batch_iterator.go new file mode 100644 index 00000000000..e33c0939324 --- /dev/null +++ b/packages/taiko-client/pkg/chain_iterator/block_batch_iterator.go @@ -0,0 +1,283 @@ +package chainiterator + +import ( + "context" + "errors" + "fmt" + "io" + "math/big" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +const ( + DefaultBlocksReadPerEpoch = 1000 + DefaultRetryInterval = 12 * time.Second + DefaultBlockConfirmations = 0 +) + +var ( + errContinue = errors.New("continue") +) + +// OnBlocksFunc represents the callback function which will be called when a batch of blocks in chain are +// iterated. It returns true if it reorged, and false if not. +type OnBlocksFunc func( + ctx context.Context, + start, end *types.Header, + updateCurrentFunc UpdateCurrentFunc, + endIterFunc EndIterFunc, +) error + +// UpdateCurrentFunc updates the iterator.current cursor in the iterator. +type UpdateCurrentFunc func(*types.Header) + +// EndIterFunc ends the current iteration. +type EndIterFunc func() + +// BlockBatchIterator iterates the blocks in batches between the given start and end heights, +// with the awareness of reorganization. +type BlockBatchIterator struct { + ctx context.Context + client *rpc.EthClient + chainID *big.Int + blocksReadPerEpoch uint64 + startHeight uint64 + endHeight *uint64 + current *types.Header + onBlocks OnBlocksFunc + isEnd bool + reorgRewindDepth uint64 + retryInterval time.Duration + blockConfirmations *uint64 +} + +// BlockBatchIteratorConfig represents the configs of a block batch iterator. +type BlockBatchIteratorConfig struct { + Client *rpc.EthClient + MaxBlocksReadPerEpoch *uint64 + StartHeight *big.Int + EndHeight *big.Int + OnBlocks OnBlocksFunc + ReorgRewindDepth *uint64 + RetryInterval time.Duration + BlockConfirmations *uint64 +} + +// NewBlockBatchIterator creates a new block batch iterator instance. +func NewBlockBatchIterator(ctx context.Context, cfg *BlockBatchIteratorConfig) (*BlockBatchIterator, error) { + if cfg.Client == nil { + return nil, errors.New("invalid RPC client") + } + + if cfg.OnBlocks == nil { + return nil, errors.New("invalid callback") + } + + if cfg.StartHeight == nil { + return nil, errors.New("invalid start height") + } + + if cfg.EndHeight != nil && cfg.StartHeight.Cmp(cfg.EndHeight) > 0 { + return nil, fmt.Errorf("start height (%d) > end height (%d)", cfg.StartHeight, cfg.EndHeight) + } + + startHeader, err := cfg.Client.HeaderByNumber(ctx, cfg.StartHeight) + if err != nil { + return nil, fmt.Errorf("failed to get start header, height: %s, error: %w", cfg.StartHeight, err) + } + + if _, err = cfg.Client.HeaderByNumber(ctx, cfg.EndHeight); err != nil { + return nil, fmt.Errorf("failed to get end header, height: %s, error: %w", cfg.EndHeight, err) + } + + iterator := &BlockBatchIterator{ + ctx: ctx, + client: cfg.Client, + chainID: cfg.Client.ChainID, + startHeight: cfg.StartHeight.Uint64(), + onBlocks: cfg.OnBlocks, + current: startHeader, + blockConfirmations: cfg.BlockConfirmations, + } + + if cfg.MaxBlocksReadPerEpoch != nil { + iterator.blocksReadPerEpoch = *cfg.MaxBlocksReadPerEpoch + } else { + iterator.blocksReadPerEpoch = DefaultBlocksReadPerEpoch + } + + if cfg.RetryInterval == 0 { + iterator.retryInterval = DefaultRetryInterval + } else { + iterator.retryInterval = cfg.RetryInterval + } + + if cfg.EndHeight != nil { + endHeightUint64 := cfg.EndHeight.Uint64() + iterator.endHeight = &endHeightUint64 + } + + return iterator, nil +} + +// Iter iterates the given chain between the given start and end heights, +// will call the callback when a batch of blocks in chain are iterated. +func (i *BlockBatchIterator) Iter() error { + iterOp := func() error { + for { + if i.ctx.Err() != nil { + log.Warn( + "Block batch iterator closed", + "error", i.ctx.Err(), + "start", i.startHeight, + "end", i.endHeight, + "current", i.current.Number, + ) + break + } + if err := i.iter(); err != nil { + if errors.Is(err, io.EOF) { + break + } + if errors.Is(err, errContinue) { + continue + } + log.Error("Block batch iterator callback error", "error", err) + return err + } + } + return nil + } + + if err := backoff.Retry(iterOp, backoff.WithContext(backoff.NewConstantBackOff(i.retryInterval), i.ctx)); err != nil { + return err + } + + return i.ctx.Err() +} + +// iter is the internal implementation of Iter, which performs the iteration. +func (i *BlockBatchIterator) iter() (err error) { + if err := i.ensureCurrentNotReorged(); err != nil { + return fmt.Errorf("failed to check whether iterator.current cursor has been reorged: %w", err) + } + + var ( + endHeight uint64 + endHeader *types.Header + destHeight uint64 + isLastEpoch bool + blockConfirmations uint64 + ) + + if i.blockConfirmations == nil { + blockConfirmations = DefaultBlockConfirmations + } else { + blockConfirmations = *i.blockConfirmations + } + + if i.endHeight != nil { + destHeight = *i.endHeight + } else { + destHeight, err = i.client.BlockNumber(i.ctx) + if err != nil { + return err + } + if destHeight > blockConfirmations { + destHeight -= blockConfirmations + } else { + destHeight = 0 + } + } + + if i.current.Number.Uint64() >= destHeight { + return io.EOF + } + + endHeight = i.current.Number.Uint64() + i.blocksReadPerEpoch + + if endHeight >= destHeight { + endHeight = destHeight + isLastEpoch = true + } + + if endHeader, err = i.client.HeaderByNumber(i.ctx, new(big.Int).SetUint64(endHeight)); err != nil { + return err + } + + if err := i.onBlocks(i.ctx, i.current, endHeader, i.updateCurrent, i.end); err != nil { + return err + } + + if i.isEnd { + return io.EOF + } + + i.current = endHeader + + if !isLastEpoch && !i.isEnd { + return errContinue + } + + return io.EOF +} + +// updateCurrent updates the iterator's current cursor. +func (i *BlockBatchIterator) updateCurrent(current *types.Header) { + if current == nil { + log.Warn("Receive a nil header as iterator.current cursor") + return + } + + i.current = current +} + +// end ends the current iteration. +func (i *BlockBatchIterator) end() { + i.isEnd = true +} + +// ensureCurrentNotReorged checks if the iterator.current cursor was reorged, if was, will +// rewind back `ReorgRewindDepth` blocks. +// reorg is also detected on the iteration of the event later, by checking +// event.Raw.Removed, which will also call `i.rewindOnReorgDetected` to rewind back +func (i *BlockBatchIterator) ensureCurrentNotReorged() error { + current, err := i.client.HeaderByHash(i.ctx, i.current.Hash()) + if err != nil && !(err.Error() == ethereum.NotFound.Error()) { + return err + } + + // Not reorged + if current != nil { + return nil + } + + // reorged + return i.rewindOnReorgDetected() +} + +// rewindOnReorgDetected rewinds back `ReorgRewindDepth` blocks and sets i.current +// to a stable block, or 0 if it's less than `ReorgRewindDepth`. +func (i *BlockBatchIterator) rewindOnReorgDetected() error { + var newCurrentHeight uint64 + if i.current.Number.Uint64() <= i.reorgRewindDepth { + newCurrentHeight = 0 + } else { + newCurrentHeight = i.current.Number.Uint64() - i.reorgRewindDepth + } + + current, err := i.client.HeaderByNumber(i.ctx, new(big.Int).SetUint64(newCurrentHeight)) + if err != nil { + return err + } + + i.current = current + return nil +} diff --git a/packages/taiko-client/pkg/chain_iterator/block_batch_iterator_test.go b/packages/taiko-client/pkg/chain_iterator/block_batch_iterator_test.go new file mode 100644 index 00000000000..3a8f32b8c77 --- /dev/null +++ b/packages/taiko-client/pkg/chain_iterator/block_batch_iterator_test.go @@ -0,0 +1,268 @@ +package chainiterator + +import ( + "context" + "io" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +type BlockBatchIteratorTestSuite struct { + testutils.ClientTestSuite +} + +func (s *BlockBatchIteratorTestSuite) TestIter() { + var maxBlocksReadPerEpoch uint64 = 2 + + headHeight, err := s.RPCClient.L1.BlockNumber(context.Background()) + s.Nil(err) + s.Greater(headHeight, uint64(0)) + + lastEnd := common.Big0 + + iter, err := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + MaxBlocksReadPerEpoch: &maxBlocksReadPerEpoch, + StartHeight: common.Big0, + EndHeight: new(big.Int).SetUint64(headHeight), + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + _ EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + return nil + }, + }) + + s.Nil(err) + s.Nil(iter.Iter()) + s.Equal(headHeight, lastEnd.Uint64()) +} + +func (s *BlockBatchIteratorTestSuite) TestIterWithoutSpecifiedEndHeight() { + var maxBlocksReadPerEpoch uint64 = 2 + var blockConfirmations uint64 = 6 + + headHeight, err := s.RPCClient.L1.BlockNumber(context.Background()) + s.Nil(err) + s.Greater(headHeight, uint64(0)) + + lastEnd := common.Big0 + + iter, err := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + MaxBlocksReadPerEpoch: &maxBlocksReadPerEpoch, + StartHeight: common.Big0, + BlockConfirmations: &blockConfirmations, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + _ EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + return nil + }, + }) + + s.Nil(err) + s.Nil(iter.Iter()) + s.GreaterOrEqual(lastEnd.Uint64(), headHeight-blockConfirmations) +} + +func (s *BlockBatchIteratorTestSuite) TestIterWithLessThanConfirmations() { + var maxBlocksReadPerEpoch uint64 = 2 + + headHeight, err := s.RPCClient.L1.BlockNumber(context.Background()) + s.Nil(err) + s.Greater(headHeight, uint64(0)) + + lastEnd := headHeight + + var blockConfirmations = headHeight + 3 + + iter, err := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + MaxBlocksReadPerEpoch: &maxBlocksReadPerEpoch, + StartHeight: new(big.Int).SetUint64(headHeight), + BlockConfirmations: &blockConfirmations, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + _ EndIterFunc, + ) error { + s.Equal(lastEnd, start.Number.Uint64()) + lastEnd = end.Number.Uint64() + return nil + }, + }) + + s.Nil(err) + s.Equal(io.EOF, iter.iter()) + s.Equal(headHeight, lastEnd) +} + +func (s *BlockBatchIteratorTestSuite) TestIterEndFunc() { + var maxBlocksReadPerEpoch uint64 = 2 + + headHeight, err := s.RPCClient.L1.BlockNumber(context.Background()) + s.Nil(err) + s.Greater(headHeight, maxBlocksReadPerEpoch) + + lastEnd := common.Big0 + + iter, err := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + MaxBlocksReadPerEpoch: &maxBlocksReadPerEpoch, + StartHeight: common.Big0, + EndHeight: new(big.Int).SetUint64(headHeight), + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + }) + + s.Nil(err) + s.Nil(iter.Iter()) + s.Equal(lastEnd.Uint64(), maxBlocksReadPerEpoch) +} + +func (s *BlockBatchIteratorTestSuite) TestIterCtxCancel() { + lastEnd := common.Big0 + headHeight, err := s.RPCClient.L1.BlockNumber(context.Background()) + s.Nil(err) + ctx, cancel := context.WithCancel(context.Background()) + + itr, err := NewBlockBatchIterator(ctx, &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + MaxBlocksReadPerEpoch: nil, + RetryInterval: 5 * time.Second, + StartHeight: common.Big0, + EndHeight: new(big.Int).SetUint64(headHeight), + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + }) + + s.Nil(err) + cancel() + // should output a log.Warn and context cancel error + err8 := itr.Iter() + s.ErrorContains(err8, "context canceled") +} + +func (s *BlockBatchIteratorTestSuite) TestBlockBatchIteratorConfig() { + _, err := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: nil, + }) + s.ErrorContains(err, "invalid RPC client") + + _, err2 := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + OnBlocks: nil, + }) + s.ErrorContains(err2, "invalid callback") + + lastEnd := common.Big0 + _, err3 := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + StartHeight: nil, + }) + s.ErrorContains(err3, "invalid start height") + + _, err4 := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + StartHeight: common.Big2, + EndHeight: common.Big0, + }) + s.ErrorContains(err4, "start height (2) > end height (0)") + + _, err6 := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + StartHeight: big.NewInt(1000), // use very high number + EndHeight: big.NewInt(1000), + }) + s.ErrorContains(err6, "failed to get start header") + + _, err7 := NewBlockBatchIterator(context.Background(), &BlockBatchIteratorConfig{ + Client: s.RPCClient.L1, + OnBlocks: func( + _ context.Context, + start, end *types.Header, + _ UpdateCurrentFunc, + endIterFunc EndIterFunc, + ) error { + s.Equal(lastEnd.Uint64(), start.Number.Uint64()) + lastEnd = end.Number + endIterFunc() + return nil + }, + StartHeight: common.Big0, + EndHeight: big.NewInt(1000), // use very high number + }) + s.ErrorContains(err7, "failed to get end header") +} + +func TestBlockBatchIteratorTestSuite(t *testing.T) { + suite.Run(t, new(BlockBatchIteratorTestSuite)) +} diff --git a/packages/taiko-client/pkg/chain_iterator/event_iterator/block_proposed_iterator.go b/packages/taiko-client/pkg/chain_iterator/event_iterator/block_proposed_iterator.go new file mode 100644 index 00000000000..12ff6b82f18 --- /dev/null +++ b/packages/taiko-client/pkg/chain_iterator/event_iterator/block_proposed_iterator.go @@ -0,0 +1,144 @@ +package eventiterator + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" + chainIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// EndBlockProposedEventIterFunc ends the current iteration. +type EndBlockProposedEventIterFunc func() + +// OnBlockProposedEvent represents the callback function which will be called when a TaikoL1.BlockProposed event is +// iterated. +type OnBlockProposedEvent func( + context.Context, + *bindings.TaikoL1ClientBlockProposed, + EndBlockProposedEventIterFunc, +) error + +// BlockProposedIterator iterates the emitted TaikoL1.BlockProposed events in the chain, +// with the awareness of reorganization. +type BlockProposedIterator struct { + ctx context.Context + taikoL1 *bindings.TaikoL1Client + blockBatchIterator *chainIterator.BlockBatchIterator + filterQuery []*big.Int + isEnd bool +} + +// BlockProposedIteratorConfig represents the configs of a BlockProposed event iterator. +type BlockProposedIteratorConfig struct { + Client *rpc.EthClient + TaikoL1 *bindings.TaikoL1Client + MaxBlocksReadPerEpoch *uint64 + StartHeight *big.Int + EndHeight *big.Int + FilterQuery []*big.Int + OnBlockProposedEvent OnBlockProposedEvent + BlockConfirmations *uint64 +} + +// NewBlockProposedIterator creates a new instance of BlockProposed event iterator. +func NewBlockProposedIterator(ctx context.Context, cfg *BlockProposedIteratorConfig) (*BlockProposedIterator, error) { + if cfg.OnBlockProposedEvent == nil { + return nil, errors.New("invalid callback") + } + + iterator := &BlockProposedIterator{ + ctx: ctx, + taikoL1: cfg.TaikoL1, + filterQuery: cfg.FilterQuery, + } + + // Initialize the inner block iterator. + blockIterator, err := chainIterator.NewBlockBatchIterator(ctx, &chainIterator.BlockBatchIteratorConfig{ + Client: cfg.Client, + MaxBlocksReadPerEpoch: cfg.MaxBlocksReadPerEpoch, + StartHeight: cfg.StartHeight, + EndHeight: cfg.EndHeight, + BlockConfirmations: cfg.BlockConfirmations, + OnBlocks: assembleBlockProposedIteratorCallback( + cfg.Client, + cfg.TaikoL1, + cfg.FilterQuery, + cfg.OnBlockProposedEvent, + iterator, + ), + }) + if err != nil { + return nil, err + } + + iterator.blockBatchIterator = blockIterator + + return iterator, nil +} + +// Iter iterates the given chain between the given start and end heights, +// will call the callback when a BlockProposed event is iterated. +func (i *BlockProposedIterator) Iter() error { + return i.blockBatchIterator.Iter() +} + +// end ends the current iteration. +func (i *BlockProposedIterator) end() { + i.isEnd = true +} + +// assembleBlockProposedIteratorCallback assembles the callback which will be used +// by a event iterator's inner block iterator. +func assembleBlockProposedIteratorCallback( + client *rpc.EthClient, + taikoL1Client *bindings.TaikoL1Client, + filterQuery []*big.Int, + callback OnBlockProposedEvent, + eventIter *BlockProposedIterator, +) chainIterator.OnBlocksFunc { + return func( + ctx context.Context, + start, end *types.Header, + updateCurrentFunc chainIterator.UpdateCurrentFunc, + endFunc chainIterator.EndIterFunc, + ) error { + endHeight := end.Number.Uint64() + iter, err := taikoL1Client.FilterBlockProposed( + &bind.FilterOpts{Start: start.Number.Uint64(), End: &endHeight, Context: ctx}, + filterQuery, + nil, + ) + if err != nil { + return err + } + defer iter.Close() + + for iter.Next() { + event := iter.Event + + if err := callback(ctx, event, eventIter.end); err != nil { + return err + } + + if eventIter.isEnd { + endFunc() + return nil + } + + current, err := client.HeaderByHash(ctx, event.Raw.BlockHash) + if err != nil { + return err + } + + updateCurrentFunc(current) + } + + return nil + } +} diff --git a/packages/taiko-client/pkg/error.go b/packages/taiko-client/pkg/error.go new file mode 100644 index 00000000000..676e6d608a8 --- /dev/null +++ b/packages/taiko-client/pkg/error.go @@ -0,0 +1,12 @@ +package pkg + +import ( + "errors" +) + +var ( + ErrBlobUsed = errors.New("blob is used") + ErrBlobUnused = errors.New("blob is not used") + ErrSidecarNotFound = errors.New("sidecar not found") + ErrBeaconNotFound = errors.New("beacon client not found") +) diff --git a/packages/taiko-client/pkg/flags/config.go b/packages/taiko-client/pkg/flags/config.go new file mode 100644 index 00000000000..12375f89c55 --- /dev/null +++ b/packages/taiko-client/pkg/flags/config.go @@ -0,0 +1,31 @@ +package flags + +import ( + "crypto/ecdsa" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" +) + +// InitTxmgrConfigsFromCli initializes the transaction manager configs from the command line flags. +func InitTxmgrConfigsFromCli(l1Endpoint string, privateKey *ecdsa.PrivateKey, c *cli.Context) *txmgr.CLIConfig { + return &txmgr.CLIConfig{ + L1RPCURL: l1Endpoint, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(privateKey)), + NumConfirmations: c.Uint64(flags.NumConfirmations.Name), + SafeAbortNonceTooLowCount: c.Uint64(flags.SafeAbortNonceTooLowCount.Name), + FeeLimitMultiplier: c.Uint64(flags.FeeLimitMultiplier.Name), + FeeLimitThresholdGwei: c.Float64(flags.FeeLimitThreshold.Name), + MinBaseFeeGwei: c.Float64(flags.MinBaseFee.Name), + MinTipCapGwei: c.Float64(flags.MinTipCap.Name), + ResubmissionTimeout: c.Duration(flags.ResubmissionTimeout.Name), + NetworkTimeout: c.Duration(flags.RPCTimeout.Name), + ReceiptQueryInterval: c.Duration(flags.ReceiptQueryInterval.Name), + TxSendTimeout: c.Duration(flags.TxSendTimeout.Name), + TxNotInMempoolTimeout: c.Duration(flags.TxNotInMempoolTimeout.Name), + } +} diff --git a/packages/taiko-client/pkg/jwt/jwt.go b/packages/taiko-client/pkg/jwt/jwt.go new file mode 100644 index 00000000000..33ba0dacc66 --- /dev/null +++ b/packages/taiko-client/pkg/jwt/jwt.go @@ -0,0 +1,39 @@ +package jwt + +import ( + "encoding/hex" + "errors" + "fmt" + "strings" + + "github.com/prysmaticlabs/prysm/v4/io/file" +) + +// Taken from: https://github.com/prysmaticlabs/prysm/blob/v2.1.4/cmd/beacon-chain/execution/options.go#L43 +// Parses a JWT secret from a file path. This secret is required when connecting to execution nodes +// over HTTP, and must be the same one used in Prysm and the execution node server Prysm is connecting to. +// The engine API specification here https://github.com/ethereum/execution-apis/blob/main/src/engine/authentication.md +// Explains how we should validate this secret and the format of the file a user can specify. +// +// The secret must be stored as a hex-encoded string within a file in the filesystem. +func ParseSecretFromFile(jwtSecretFile string) ([]byte, error) { + if jwtSecretFile == "" { + return nil, nil + } + enc, err := file.ReadFileAsBytes(jwtSecretFile) + if err != nil { + return nil, err + } + strData := strings.TrimSpace(string(enc)) + if len(strData) == 0 { + return nil, fmt.Errorf("provided JWT secret in file %s cannot be empty", jwtSecretFile) + } + secret, err := hex.DecodeString(strings.TrimPrefix(strData, "0x")) + if err != nil { + return nil, err + } + if len(secret) < 32 { + return nil, errors.New("provided JWT secret should be a hex string of at least 32 bytes") + } + return secret, nil +} diff --git a/packages/taiko-client/pkg/jwt/jwt_test.go b/packages/taiko-client/pkg/jwt/jwt_test.go new file mode 100644 index 00000000000..43a5dec2b86 --- /dev/null +++ b/packages/taiko-client/pkg/jwt/jwt_test.go @@ -0,0 +1,41 @@ +package jwt + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseSecretFromFile(t *testing.T) { + _, err := ParseSecretFromFile(os.Getenv("JWT_SECRET")) + require.Nil(t, err) + + secret, err := ParseSecretFromFile("") + require.Nil(t, err) + require.Nil(t, secret) + + // File not exists + _, err = ParseSecretFromFile("TestParseSecretFromFile") + require.NotNil(t, err) + + // Empty file + file, err := os.CreateTemp("", "TestParseSecretFromFile") + require.Nil(t, err) + defer file.Close() + defer os.Remove(file.Name()) + + _, err = ParseSecretFromFile(file.Name()) + require.ErrorContains(t, err, "cannot be empty") + + file2, err := os.CreateTemp("", "test") + require.Nil(t, err) + defer file2.Close() + defer os.Remove(file2.Name()) + + _, err2 := file2.WriteString("0x10020FCb72e2765065") + require.Nil(t, err2) + + _, err3 := ParseSecretFromFile(file2.Name()) + require.ErrorContains(t, err3, "at least 32 bytes") +} diff --git a/packages/taiko-client/pkg/rpc/beaconclient.go b/packages/taiko-client/pkg/rpc/beaconclient.go new file mode 100644 index 00000000000..06e3b5ac600 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/beaconclient.go @@ -0,0 +1,109 @@ +package rpc + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/prysmaticlabs/prysm/v4/api/client" + "github.com/prysmaticlabs/prysm/v4/api/client/beacon" + "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/blob" +) + +var ( + // Request urls. + sidecarsRequestURL = "eth/v1/beacon/blob_sidecars/%d" + genesisRequestURL = "eth/v1/beacon/genesis" +) + +type ConfigSpec struct { + SecondsPerSlot string `json:"SECONDS_PER_SLOT"` +} + +type GenesisResponse struct { + Data struct { + GenesisTime string `json:"genesis_time"` + } `json:"data"` +} + +type BeaconClient struct { + *beacon.Client + + timeout time.Duration + genesisTime uint64 + secondsPerSlot uint64 +} + +// NewBeaconClient returns a new beacon client. +func NewBeaconClient(endpoint string, timeout time.Duration) (*BeaconClient, error) { + cli, err := beacon.NewClient(endpoint, client.WithTimeout(timeout)) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + // Get the genesis time. + var genesisDetail *GenesisResponse + resBytes, err := cli.Get(ctx, genesisRequestURL) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(resBytes, &genesisDetail); err != nil { + return nil, err + } + + genesisTime, err := strconv.Atoi(genesisDetail.Data.GenesisTime) + if err != nil { + return nil, err + } + + log.Info("L1 genesis time", "time", genesisTime) + + // Get the seconds per slot. + spec, err := cli.GetConfigSpec(ctx) + if err != nil { + return nil, err + } + + secondsPerSlot, err := strconv.Atoi(spec.Data.(map[string]interface{})["SECONDS_PER_SLOT"].(string)) + if err != nil { + return nil, err + } + + log.Info("L1 seconds per slot", "seconds", secondsPerSlot) + + return &BeaconClient{cli, timeout, uint64(genesisTime), uint64(secondsPerSlot)}, nil +} + +// GetBlobs returns the sidecars for a given slot. +func (c *BeaconClient) GetBlobs(ctx context.Context, time uint64) ([]*blob.Sidecar, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + slot, err := c.timeToSlot(time) + if err != nil { + return nil, err + } + + var sidecars *blob.SidecarsResponse + resBytes, err := c.Get(ctxWithTimeout, fmt.Sprintf(sidecarsRequestURL, slot)) + if err != nil { + return nil, err + } + + return sidecars.Data, json.Unmarshal(resBytes, &sidecars) +} + +// timeToSlot returns the slots of the given timestamp. +func (c *BeaconClient) timeToSlot(timestamp uint64) (uint64, error) { + if timestamp < c.genesisTime { + return 0, fmt.Errorf("provided timestamp (%v) precedes genesis time (%v)", timestamp, c.genesisTime) + } + return (timestamp - c.genesisTime) / c.secondsPerSlot, nil +} diff --git a/packages/taiko-client/pkg/rpc/blob_datasource.go b/packages/taiko-client/pkg/rpc/blob_datasource.go new file mode 100644 index 00000000000..0c7580d85fe --- /dev/null +++ b/packages/taiko-client/pkg/rpc/blob_datasource.go @@ -0,0 +1,111 @@ +package rpc + +import ( + "context" + "fmt" + "net/url" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" + "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/blob" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/pkg" +) + +type BlobDataSource struct { + ctx context.Context + client *Client + blobServerEndpoint *url.URL +} + +type BlobData struct { + BlobHash string `json:"blob_hash"` + KzgCommitment string `json:"kzg_commitment"` + Blob string `json:"blob"` +} + +type BlobDataSeq struct { + Data []*BlobData `json:"data"` +} + +func NewBlobDataSource( + ctx context.Context, + client *Client, + blobServerEndpoint *url.URL, +) *BlobDataSource { + return &BlobDataSource{ + ctx: ctx, + client: client, + blobServerEndpoint: blobServerEndpoint, + } +} + +// GetBlobs get blob sidecar by meta +func (ds *BlobDataSource) GetBlobs( + ctx context.Context, + meta *bindings.TaikoDataBlockMetadata, +) ([]*blob.Sidecar, error) { + if !meta.BlobUsed { + return nil, pkg.ErrBlobUnused + } + + var ( + sidecars []*blob.Sidecar + err error + ) + if ds.client.L1Beacon == nil { + sidecars, err = nil, pkg.ErrBeaconNotFound + } else { + sidecars, err = ds.client.L1Beacon.GetBlobs(ctx, meta.Timestamp) + } + if err != nil { + log.Info("Failed to get blobs from beacon, try to use blob server.", "error", err.Error()) + if ds.blobServerEndpoint == nil { + log.Info("No blob server endpoint set") + return nil, err + } + blobs, err := ds.getBlobFromServer(ctx, meta.BlobHash) + if err != nil { + return nil, err + } + sidecars = make([]*blob.Sidecar, len(blobs.Data)) + for index, value := range blobs.Data { + sidecars[index] = &blob.Sidecar{ + KzgCommitment: value.KzgCommitment, + Blob: value.Blob, + } + } + } + return sidecars, nil +} + +// getBlobFromServer get blob data from server path `/getBlob`. +func (ds *BlobDataSource) getBlobFromServer(ctx context.Context, blobHash common.Hash) (*BlobDataSeq, error) { + var ( + route = "/getBlob" + param = map[string]string{"blobHash": blobHash.String()} + ) + requestURL, err := url.JoinPath(ds.blobServerEndpoint.String(), route) + if err != nil { + return nil, err + } + resp, err := resty.New().R(). + SetResult(BlobDataSeq{}). + SetQueryParams(param). + SetContext(ctx). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "application/json"). + Get(requestURL) + if err != nil { + return nil, err + } + if !resp.IsSuccess() { + return nil, fmt.Errorf( + "unable to connect blob server endpoint, status code: %v", + resp.StatusCode(), + ) + } + return resp.Result().(*BlobDataSeq), nil +} diff --git a/packages/taiko-client/pkg/rpc/blob_tx.go b/packages/taiko-client/pkg/rpc/blob_tx.go new file mode 100644 index 00000000000..97c7f0119b0 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/blob_tx.go @@ -0,0 +1,137 @@ +package rpc + +import ( + "errors" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" +) + +var ( + ErrBlobInvalid = errors.New("invalid blob encoding") +) + +// TransactBlobTx creates, signs and then sends blob transactions. +func (c *EthClient) TransactBlobTx( + opts *bind.TransactOpts, + contract common.Address, + input []byte, + sidecar *types.BlobTxSidecar, +) (*types.Transaction, error) { + // Sign the transaction and schedule it for execution + if opts.Signer == nil { + return nil, errors.New("no signer to authorize the transaction with") + } + // Create blob tx + blobTx, err := c.CreateBlobTx(opts, contract, input, sidecar) + if err != nil { + return nil, err + } + signedTx, err := opts.Signer(opts.From, types.NewTx(blobTx)) + if err != nil { + return nil, err + } + if opts.NoSend { + return signedTx, nil + } + if err := c.SendTransaction(opts.Context, signedTx); err != nil { + return nil, err + } + return signedTx, nil +} + +// CreateBlobTx creates a blob transaction by given parameters. +func (c *EthClient) CreateBlobTx( + opts *bind.TransactOpts, + contract common.Address, + input []byte, + sidecar *types.BlobTxSidecar, +) (*types.BlobTx, error) { + // Fetch the nonce for the account + var ( + nonce *hexutil.Uint64 + gas *hexutil.Uint64 + ) + if opts.Nonce != nil { + curNonce := hexutil.Uint64(opts.Nonce.Uint64()) + nonce = &curNonce + } + + if input == nil { + input = []byte{} + } + + if opts.GasLimit != 0 { + gasVal := hexutil.Uint64(opts.GasLimit) + gas = &gasVal + } + + rawTx, err := c.FillTransaction(opts.Context, &TransactionArgs{ + From: &opts.From, + To: &contract, + Gas: gas, + GasPrice: (*hexutil.Big)(opts.GasPrice), + MaxFeePerGas: (*hexutil.Big)(opts.GasFeeCap), + MaxPriorityFeePerGas: (*hexutil.Big)(opts.GasTipCap), + Value: (*hexutil.Big)(opts.Value), + Nonce: nonce, + Data: (*hexutil.Bytes)(&input), + AccessList: nil, + ChainID: nil, + BlobFeeCap: nil, + BlobHashes: sidecar.BlobHashes(), + }) + if err != nil { + return nil, err + } + + blobFeeCap := rawTx.BlobGasFeeCap() + if blobFeeCap == nil || blobFeeCap.Uint64() < params.BlobTxMinBlobGasprice { + blobFeeCap = new(big.Int).SetUint64(uint64(params.BlobTxMinBlobGasprice)) + } + + return &types.BlobTx{ + ChainID: uint256.MustFromBig(rawTx.ChainId()), + Nonce: rawTx.Nonce(), + GasTipCap: uint256.MustFromBig(rawTx.GasTipCap()), + GasFeeCap: uint256.MustFromBig(rawTx.GasFeeCap()), + Gas: rawTx.Gas(), + To: *rawTx.To(), + Value: uint256.MustFromBig(rawTx.Value()), + Data: rawTx.Data(), + AccessList: rawTx.AccessList(), + BlobFeeCap: uint256.MustFromBig(blobFeeCap), + BlobHashes: sidecar.BlobHashes(), + Sidecar: sidecar, + }, nil +} + +// MakeSidecar makes a sidecar which only includes one blob with the given data. +func MakeSidecar(data []byte) (*types.BlobTxSidecar, error) { + var blob eth.Blob + if err := blob.FromData(data); err != nil { + return nil, err + } + + sideCar := &types.BlobTxSidecar{Blobs: []kzg4844.Blob{*blob.KZGBlob()}} + for _, blob := range sideCar.Blobs { + commitment, err := kzg4844.BlobToCommitment(blob) + if err != nil { + return nil, err + } + proof, err := kzg4844.ComputeBlobProof(blob, commitment) + if err != nil { + return nil, err + } + sideCar.Commitments = append(sideCar.Commitments, commitment) + sideCar.Proofs = append(sideCar.Proofs, proof) + } + return sideCar, nil +} diff --git a/packages/taiko-client/pkg/rpc/blob_tx_test.go b/packages/taiko-client/pkg/rpc/blob_tx_test.go new file mode 100644 index 00000000000..bcfb9103c2a --- /dev/null +++ b/packages/taiko-client/pkg/rpc/blob_tx_test.go @@ -0,0 +1,74 @@ +package rpc + +import ( + "context" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" + + "github.com/taikoxyz/taiko-client/internal/utils" +) + +func TestSendingBlobTx(t *testing.T) { + t.SkipNow() + // Load environment variables. + utils.LoadEnv() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + url := os.Getenv("L1_NODE_WS_ENDPOINT") + l1Client, err := NewEthClient(ctx, url, time.Second*20) + assert.NoError(t, err) + + priv := os.Getenv("L1_PROPOSER_PRIVATE_KEY") + sk, err := crypto.ToECDSA(common.FromHex(priv)) + assert.NoError(t, err) + + opts, err := bind.NewKeyedTransactorWithChainID(sk, l1Client.ChainID) + assert.NoError(t, err) + opts.Context = ctx + //opts.NoSend = true + + balance, err := l1Client.BalanceAt(ctx, opts.From, nil) + assert.NoError(t, err) + t.Logf("address: %s, balance: %s", opts.From.String(), balance.String()) + + data, dErr := os.ReadFile("./tx_blob.go") + assert.NoError(t, dErr) + //data := []byte{'s'} + sideCar, sErr := MakeSidecar(data) + assert.NoError(t, sErr) + + tx, err := l1Client.TransactBlobTx(opts, common.Address{}, nil, sideCar) + assert.NoError(t, err) + + receipt, err := bind.WaitMined(ctx, l1Client, tx) + assert.NoError(t, err) + assert.Equal(t, true, receipt.Status == types.ReceiptStatusSuccessful) + + t.Log("blob hash: ", tx.BlobHashes()[0].String()) + t.Log("block number: ", receipt.BlockNumber.Uint64()) + t.Log("tx hash: ", receipt.TxHash.String()) +} + +func TestMakeSideCar(t *testing.T) { + origin, err := os.ReadFile("./blob_tx.go") + assert.NoError(t, err) + + sideCar, mErr := MakeSidecar(origin) + assert.NoError(t, mErr) + + blob := eth.Blob(sideCar.Blobs[0]) + origin1, dErr := blob.ToData() + assert.NoError(t, dErr) + assert.Equal(t, hexutil.Bytes(origin), origin1) +} diff --git a/packages/taiko-client/pkg/rpc/client.go b/packages/taiko-client/pkg/rpc/client.go new file mode 100644 index 00000000000..4b431b4e2e8 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/client.go @@ -0,0 +1,154 @@ +package rpc + +import ( + "context" + "os" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" +) + +const ( + defaultTimeout = 1 * time.Minute +) + +// Client contains all L1/L2 RPC clients that a driver needs. +type Client struct { + // Geth ethclient clients + L1 *EthClient + L2 *EthClient + L2CheckPoint *EthClient + // Geth Engine API clients + L2Engine *EngineClient + // Beacon clients + L1Beacon *BeaconClient + // Protocol contracts clients + TaikoL1 *bindings.TaikoL1Client + TaikoL2 *bindings.TaikoL2Client + TaikoToken *bindings.TaikoToken + GuardianProver *bindings.GuardianProver +} + +// ClientConfig contains all configs which will be used to initializing an +// RPC client. If not providing L2EngineEndpoint or JwtSecret, then the L2Engine client +// won't be initialized. +type ClientConfig struct { + L1Endpoint string + L2Endpoint string + L1BeaconEndpoint string + L2CheckPoint string + TaikoL1Address common.Address + TaikoL2Address common.Address + TaikoTokenAddress common.Address + GuardianProverAddress common.Address + L2EngineEndpoint string + JwtSecret string + Timeout time.Duration +} + +// NewClient initializes all RPC clients used by Taiko client software. +func NewClient(ctx context.Context, cfg *ClientConfig) (*Client, error) { + var ( + l1Client *EthClient + l2Client *EthClient + l1BeaconClient *BeaconClient + l2CheckPoint *EthClient + err error + ) + + // Keep retrying to connect to the RPC endpoints until success or context is cancelled. + if err := backoff.Retry(func() error { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + if l1Client, err = NewEthClient(ctxWithTimeout, cfg.L1Endpoint, cfg.Timeout); err != nil { + log.Error("Failed to connect to L1 endpoint, retrying", "endpoint", cfg.L1Endpoint, "err", err) + return err + } + + if l2Client, err = NewEthClient(ctxWithTimeout, cfg.L2Endpoint, cfg.Timeout); err != nil { + log.Error("Failed to connect to L2 endpoint, retrying", "endpoint", cfg.L2Endpoint, "err", err) + return err + } + + // NOTE: when running tests, we do not have a L1 beacon endpoint. + if cfg.L1BeaconEndpoint != "" && os.Getenv("RUN_TESTS") == "" { + if l1BeaconClient, err = NewBeaconClient(cfg.L1BeaconEndpoint, defaultTimeout); err != nil { + log.Error("Failed to connect to L1 beacon endpoint, retrying", "endpoint", cfg.L1BeaconEndpoint, "err", err) + return err + } + } + + if cfg.L2CheckPoint != "" { + l2CheckPoint, err = NewEthClient(ctxWithTimeout, cfg.L2CheckPoint, cfg.Timeout) + if err != nil { + log.Error("Failed to connect to L2 checkpoint endpoint, retrying", "endpoint", cfg.L2CheckPoint, "err", err) + return err + } + } + + return nil + }, backoff.WithContext(backoff.NewExponentialBackOff(), ctx)); err != nil { + return nil, err + } + + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + taikoL1, err := bindings.NewTaikoL1Client(cfg.TaikoL1Address, l1Client) + if err != nil { + return nil, err + } + + taikoL2, err := bindings.NewTaikoL2Client(cfg.TaikoL2Address, l2Client) + if err != nil { + return nil, err + } + + var ( + taikoToken *bindings.TaikoToken + guardianProver *bindings.GuardianProver + ) + if cfg.TaikoTokenAddress.Hex() != ZeroAddress.Hex() { + if taikoToken, err = bindings.NewTaikoToken(cfg.TaikoTokenAddress, l1Client); err != nil { + return nil, err + } + } + if cfg.GuardianProverAddress.Hex() != ZeroAddress.Hex() { + if guardianProver, err = bindings.NewGuardianProver(cfg.GuardianProverAddress, l1Client); err != nil { + return nil, err + } + } + + // If not providing L2EngineEndpoint or JwtSecret, then the L2Engine client + // won't be initialized. + var l2AuthClient *EngineClient + if len(cfg.L2EngineEndpoint) != 0 && len(cfg.JwtSecret) != 0 { + l2AuthClient, err = NewJWTEngineClient(cfg.L2EngineEndpoint, cfg.JwtSecret) + if err != nil { + return nil, err + } + } + + client := &Client{ + L1: l1Client, + L1Beacon: l1BeaconClient, + L2: l2Client, + L2CheckPoint: l2CheckPoint, + L2Engine: l2AuthClient, + TaikoL1: taikoL1, + TaikoL2: taikoL2, + TaikoToken: taikoToken, + GuardianProver: guardianProver, + } + + if err := client.ensureGenesisMatched(ctxWithTimeout); err != nil { + return nil, err + } + + return client, nil +} diff --git a/packages/taiko-client/pkg/rpc/client_test.go b/packages/taiko-client/pkg/rpc/client_test.go new file mode 100644 index 00000000000..46b625d2a45 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/client_test.go @@ -0,0 +1,46 @@ +package rpc + +import ( + "context" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func newTestClient(t *testing.T) *Client { + client, err := NewClient(context.Background(), &ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: os.Getenv("JWT_SECRET"), + }) + + require.Nil(t, err) + require.NotNil(t, client) + + return client +} + +func newTestClientWithTimeout(t *testing.T) *Client { + client, err := NewClient(context.Background(), &ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: os.Getenv("JWT_SECRET"), + Timeout: 5 * time.Second, + }) + + require.Nil(t, err) + require.NotNil(t, client) + + return client +} diff --git a/packages/taiko-client/pkg/rpc/dial.go b/packages/taiko-client/pkg/rpc/dial.go new file mode 100644 index 00000000000..985ec0db5fb --- /dev/null +++ b/packages/taiko-client/pkg/rpc/dial.go @@ -0,0 +1,74 @@ +package rpc + +import ( + "context" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" +) + +// DialClientWithBackoff connects a ethereum RPC client at the given URL with +// a backoff strategy. Added a retry limit so it doesn't retry endlessly +func DialClientWithBackoff( + ctx context.Context, + url string, + retryInterval time.Duration, + maxRetrys uint64) (*ethclient.Client, error) { + var client *ethclient.Client + if err := backoff.Retry( + func() (err error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + client, err = ethclient.DialContext(ctxWithTimeout, url) + if err != nil { + log.Error("Dial ethclient error", "url", url, "error", err) + return err + } + + return nil + }, + backoff.WithMaxRetries(backoff.NewConstantBackOff(retryInterval), maxRetrys), + ); err != nil { + return nil, err + } + + return client, nil +} + +// DialEngineClientWithBackoff connects an ethereum engine RPC client at the +// given URL with a backoff strategy. Added a retry limit so it doesn't retry endlessly +func DialEngineClientWithBackoff( + ctx context.Context, + url string, + jwtSecret string, + retryInterval time.Duration, + maxRetry uint64, +) (*EngineClient, error) { + var engineClient *EngineClient + if err := backoff.Retry( + func() (err error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + jwtAuth := node.NewJWTAuth(StringToBytes32(jwtSecret)) + client, err := rpc.DialOptions(ctxWithTimeout, url, rpc.WithHTTPAuth(jwtAuth)) + if err != nil { + log.Error("Dial engine client error", "url", url, "error", err) + return err + } + + engineClient = &EngineClient{client} + return nil + }, + backoff.WithMaxRetries(backoff.NewConstantBackOff(retryInterval), maxRetry), + ); err != nil { + return nil, err + } + + return engineClient, nil +} diff --git a/packages/taiko-client/pkg/rpc/dial_test.go b/packages/taiko-client/pkg/rpc/dial_test.go new file mode 100644 index 00000000000..f8cdd7dbc62 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/dial_test.go @@ -0,0 +1,81 @@ +package rpc + +import ( + "context" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/pkg/jwt" +) + +func TestDialEngineClientWithBackoff(t *testing.T) { + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + + require.Nil(t, err) + require.NotEmpty(t, jwtSecret) + + client, err := DialEngineClientWithBackoff( + context.Background(), + os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + string(jwtSecret), + 12*time.Second, + 10, + ) + + require.Nil(t, err) + + var result engine.ExecutableData + err = client.CallContext(context.Background(), &result, "engine_getPayloadV1", engine.PayloadID{}) + + require.Equal(t, engine.UnsupportedFork.Error(), err.Error()) +} + +func TestDialClientWithBackoff(t *testing.T) { + client, err := DialClientWithBackoff( + context.Background(), + os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + 12*time.Second, + 10, + ) + require.Nil(t, err) + + genesis, err := client.HeaderByNumber(context.Background(), common.Big0) + require.Nil(t, err) + + require.Equal(t, common.Big0.Uint64(), genesis.Number.Uint64()) +} + +func TestDialClientWithBackoff_CtxError(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + _, err := DialClientWithBackoff( + ctx, + "invalid", + -1, + 10, + ) + require.NotNil(t, err) +} + +func TestDialEngineClientWithBackoff_CtxError(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + require.Nil(t, err) + require.NotEmpty(t, jwtSecret) + + _, err2 := DialEngineClientWithBackoff( + ctx, + "invalid", + string(jwtSecret), + -1, + 10, + ) + require.NotNil(t, err2) +} diff --git a/packages/taiko-client/pkg/rpc/engine.go b/packages/taiko-client/pkg/rpc/engine.go new file mode 100644 index 00000000000..e1ec3a5c841 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/engine.go @@ -0,0 +1,130 @@ +package rpc + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" +) + +// EngineClient represents a RPC client connecting to an Ethereum Engine API +// endpoint. +// ref: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md +type EngineClient struct { + *rpc.Client +} + +func NewJWTEngineClient(url, jwtSecret string) (*EngineClient, error) { + var jwt = StringToBytes32(jwtSecret) + if jwt == (common.Hash{}) || url == "" { + return nil, errors.New("url is empty or jwt secret is illegal") + } + authClient, err := rpc.DialOptions(context.Background(), url, rpc.WithHTTPAuth(node.NewJWTAuth(jwt))) + if err != nil { + return nil, err + } + + return &EngineClient{ + Client: authClient, + }, nil +} + +// ForkchoiceUpdate updates the forkchoice on the execution client. +func (c *EngineClient) ForkchoiceUpdate( + ctx context.Context, + fc *engine.ForkchoiceStateV1, + attributes *engine.PayloadAttributes, +) (*engine.ForkChoiceResponse, error) { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + var result *engine.ForkChoiceResponse + if err := c.Client.CallContext(timeoutCtx, &result, "engine_forkchoiceUpdatedV2", fc, attributes); err != nil { + return nil, err + } + + return result, nil +} + +// NewPayload executes a built block on the execution engine. +func (c *EngineClient) NewPayload( + ctx context.Context, + payload *engine.ExecutableData, +) (*engine.PayloadStatusV1, error) { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + var result *engine.PayloadStatusV1 + if err := c.Client.CallContext(timeoutCtx, &result, "engine_newPayloadV2", payload); err != nil { + return nil, err + } + + return result, nil +} + +// GetPayload gets the execution payload associated with the payload ID. +func (c *EngineClient) GetPayload( + ctx context.Context, + payloadID *engine.PayloadID, +) (*engine.ExecutableData, error) { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + var result *engine.ExecutionPayloadEnvelope + if err := c.Client.CallContext(timeoutCtx, &result, "engine_getPayloadV2", payloadID); err != nil { + return nil, err + } + + return result.ExecutionPayload, nil +} + +// ExchangeTransitionConfiguration exchanges transition configs with the L2 execution engine. +func (c *EngineClient) ExchangeTransitionConfiguration( + ctx context.Context, + cfg *engine.TransitionConfigurationV1, +) (*engine.TransitionConfigurationV1, error) { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + var result *engine.TransitionConfigurationV1 + if err := c.Client.CallContext(timeoutCtx, &result, "engine_exchangeTransitionConfigurationV1", cfg); err != nil { + return nil, err + } + + return result, nil +} + +// TxPoolContent fetches the transaction pool content from the L2 execution engine. +func (c *EngineClient) TxPoolContent( + ctx context.Context, + beneficiary common.Address, + baseFee *big.Int, + blockMaxGasLimit uint64, + maxBytesPerTxList uint64, + locals []string, + maxTransactionsLists uint64, +) ([]*miner.PreBuiltTxList, error) { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + var result []*miner.PreBuiltTxList + if err := c.CallContext( + timeoutCtx, + &result, + "taikoAuth_txPoolContent", + beneficiary, + baseFee, + blockMaxGasLimit, + maxBytesPerTxList, + locals, + maxTransactionsLists, + ); err != nil { + return nil, err + } + return result, nil +} diff --git a/packages/taiko-client/pkg/rpc/engine_test.go b/packages/taiko-client/pkg/rpc/engine_test.go new file mode 100644 index 00000000000..53740899141 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/engine_test.go @@ -0,0 +1,41 @@ +package rpc + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +func TestL2EngineForbidden(t *testing.T) { + c := newTestClient(t) + + _, err := c.L2Engine.ForkchoiceUpdate( + context.Background(), + &engine.ForkchoiceStateV1{}, + &engine.PayloadAttributes{}, + ) + require.ErrorContains(t, err, "Unauthorized") + + _, err = c.L2Engine.NewPayload( + context.Background(), + &engine.ExecutableData{}, + ) + require.ErrorContains(t, err, "Unauthorized") + + _, err = c.L2Engine.GetPayload( + context.Background(), + &engine.PayloadID{}, + ) + require.ErrorContains(t, err, "Unauthorized") + + _, err = c.L2Engine.ExchangeTransitionConfiguration(context.Background(), &engine.TransitionConfigurationV1{ + TerminalTotalDifficulty: (*hexutil.Big)(common.Big0), + TerminalBlockHash: common.Hash{}, + TerminalBlockNumber: 0, + }) + require.ErrorContains(t, err, "Unauthorized") +} diff --git a/packages/taiko-client/pkg/rpc/ethclient.go b/packages/taiko-client/pkg/rpc/ethclient.go new file mode 100644 index 00000000000..4b6c7b7e39e --- /dev/null +++ b/packages/taiko-client/pkg/rpc/ethclient.go @@ -0,0 +1,420 @@ +package rpc + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethclient/gethclient" + "github.com/ethereum/go-ethereum/rpc" +) + +type gethClient struct { + *gethclient.Client +} + +type ethClient struct { + *ethclient.Client +} + +// EthClient is a wrapper for go-ethereum eth client with a timeout attached. +type EthClient struct { + ChainID *big.Int + + *rpc.Client + *gethClient + *ethClient + + timeout time.Duration +} + +func NewEthClient(ctx context.Context, url string, timeout time.Duration) (*EthClient, error) { + var timeoutVal = defaultTimeout + if timeout != 0 { + timeoutVal = timeout + } + + client, err := rpc.DialContext(ctx, url) + if err != nil { + return nil, err + } + + ethClient := ðClient{ethclient.NewClient(client)} + // Get chainID. + chainID, err := ethClient.ChainID(ctx) + if err != nil { + return nil, err + } + + return &EthClient{ + ChainID: chainID, + Client: client, + gethClient: &gethClient{gethclient.New(client)}, + ethClient: ethClient, + timeout: timeoutVal, + }, nil +} + +// BlockByHash returns the given full block. +// +// Note that loading full blocks requires two requests. Use HeaderByHash +// if you don't need all transactions or uncle headers. +func (c *EthClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.BlockByHash(ctxWithTimeout, hash) +} + +// BlockByNumber returns a block from the current canonical chain. If number is nil, the +// latest known block is returned. +// +// Note that loading full blocks requires two requests. Use HeaderByNumber +// if you don't need all transactions or uncle headers. +func (c *EthClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.BlockByNumber(ctxWithTimeout, number) +} + +// BlockNumber returns the most recent block number +func (c *EthClient) BlockNumber(ctx context.Context) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.BlockNumber(ctxWithTimeout) +} + +// PeerCount returns the number of p2p peers as reported by the net_peerCount method. +func (c *EthClient) PeerCount(ctx context.Context) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PeerCount(ctxWithTimeout) +} + +// HeaderByHash returns the block header with the given hash. +func (c *EthClient) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.HeaderByHash(ctxWithTimeout, hash) +} + +// HeaderByNumber returns a block header from the current canonical chain. If number is +// nil, the latest known header is returned. +func (c *EthClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.HeaderByNumber(ctxWithTimeout, number) +} + +// TransactionByHash returns the transaction with the given hash. +func (c *EthClient) TransactionByHash( + ctx context.Context, + hash common.Hash, +) (tx *types.Transaction, isPending bool, err error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.TransactionByHash(ctxWithTimeout, hash) +} + +// TransactionSender returns the sender address of the given transaction. The transaction +// must be known to the remote node and included in the blockchain at the given block and +// index. The sender is the one derived by the protocol at the time of inclusion. +// +// There is a fast-path for transactions retrieved by TransactionByHash and +// TransactionInBlock. Getting their sender address can be done without an RPC interaction. +func (c *EthClient) TransactionSender( + ctx context.Context, + tx *types.Transaction, + block common.Hash, + index uint, +) (common.Address, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.TransactionSender(ctxWithTimeout, tx, block, index) +} + +// TransactionCount returns the total number of transactions in the given block. +func (c *EthClient) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.TransactionCount(ctxWithTimeout, blockHash) +} + +// TransactionInBlock returns a single transaction at index in the given block. +func (c *EthClient) TransactionInBlock( + ctx context.Context, + blockHash common.Hash, + index uint, +) (*types.Transaction, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.TransactionInBlock(ctxWithTimeout, blockHash, index) +} + +// SyncProgress retrieves the current progress of the sync algorithm. If there's +// no sync currently running, it returns nil. +func (c *EthClient) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.SyncProgress(ctxWithTimeout) +} + +// NetworkID returns the network ID for this client. +func (c *EthClient) NetworkID(ctx context.Context) (*big.Int, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.NetworkID(ctxWithTimeout) +} + +// BalanceAt returns the wei balance of the given account. +// The block number can be nil, in which case the balance is taken from the latest known block. +func (c *EthClient) BalanceAt( + ctx context.Context, + account common.Address, + blockNumber *big.Int, +) (*big.Int, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.BalanceAt(ctxWithTimeout, account, blockNumber) +} + +// StorageAt returns the value of key in the contract storage of the given account. +// The block number can be nil, in which case the value is taken from the latest known block. +func (c *EthClient) StorageAt( + ctx context.Context, + account common.Address, + key common.Hash, + blockNumber *big.Int, +) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.StorageAt(ctxWithTimeout, account, key, blockNumber) +} + +// CodeAt returns the contract code of the given account. +// The block number can be nil, in which case the code is taken from the latest known block. +func (c *EthClient) CodeAt( + ctx context.Context, + account common.Address, + blockNumber *big.Int, +) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.CodeAt(ctxWithTimeout, account, blockNumber) +} + +// NonceAt returns the account nonce of the given account. +// The block number can be nil, in which case the nonce is taken from the latest known block. +func (c *EthClient) NonceAt( + ctx context.Context, + account common.Address, + blockNumber *big.Int, +) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.NonceAt(ctxWithTimeout, account, blockNumber) +} + +// PendingBalanceAt returns the wei balance of the given account in the pending state. +func (c *EthClient) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingBalanceAt(ctxWithTimeout, account) +} + +// PendingStorageAt returns the value of key in the contract storage of the given account in the pending state. +func (c *EthClient) PendingStorageAt( + ctx context.Context, + account common.Address, + key common.Hash, +) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingStorageAt(ctxWithTimeout, account, key) +} + +// PendingCodeAt returns the contract code of the given account in the pending state. +func (c *EthClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingCodeAt(ctxWithTimeout, account) +} + +// PendingNonceAt returns the account nonce of the given account in the pending state. +// This is the nonce that should be used for the next transaction. +func (c *EthClient) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingNonceAt(ctxWithTimeout, account) +} + +// PendingTransactionCount returns the total number of transactions in the pending state. +func (c *EthClient) PendingTransactionCount(ctx context.Context) (uint, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingTransactionCount(ctxWithTimeout) +} + +// CallContract executes a message call transaction, which is directly executed in the VM +// of the node, but never mined into the blockchain. +// +// blockNumber selects the block height at which the call runs. It can be nil, in which +// case the code is taken from the latest known block. Note that state from very old +// blocks might not be available. +func (c *EthClient) CallContract( + ctx context.Context, + msg ethereum.CallMsg, + blockNumber *big.Int, +) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.CallContract(ctxWithTimeout, msg, blockNumber) +} + +// CallContractAtHash is almost the same as CallContract except that it selects +// the block by block hash instead of block height. +func (c *EthClient) CallContractAtHash( + ctx context.Context, + msg ethereum.CallMsg, + blockHash common.Hash, +) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.CallContractAtHash(ctxWithTimeout, msg, blockHash) +} + +// PendingCallContract executes a message call transaction using the EVM. +// The state seen by the contract call is the pending state. +func (c *EthClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.PendingCallContract(ctxWithTimeout, msg) +} + +// SuggestGasPrice retrieves the currently suggested gas price to allow a timely +// execution of a transaction. +func (c *EthClient) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.SuggestGasPrice(ctxWithTimeout) +} + +// SuggestGasTipCap retrieves the currently suggested gas tip cap after 1559 to +// allow a timely execution of a transaction. +func (c *EthClient) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.SuggestGasTipCap(ctxWithTimeout) +} + +// FeeHistory retrieves the fee market history. +func (c *EthClient) FeeHistory( + ctx context.Context, + blockCount uint64, + lastBlock *big.Int, + rewardPercentiles []float64, +) (*ethereum.FeeHistory, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.FeeHistory(ctxWithTimeout, blockCount, lastBlock, rewardPercentiles) +} + +// EstimateGas tries to estimate the gas needed to execute a specific transaction based on +// the current pending state of the backend blockchain. There is no guarantee that this is +// the true gas limit requirement as other transactions may be added or removed by miners, +// but it should provide a basis for setting a reasonable default. +func (c *EthClient) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.EstimateGas(ctxWithTimeout, msg) +} + +// SendTransaction injects a signed transaction into the pending pool for execution. +// +// If the transaction was a contract creation use the TransactionReceipt method to get the +// contract address after the transaction has been mined. +func (c *EthClient) SendTransaction(ctx context.Context, tx *types.Transaction) error { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + return c.ethClient.SendTransaction(ctxWithTimeout, tx) +} + +// TransactionArgs represents the arguments to construct a new transaction +// or a message call. +type TransactionArgs struct { + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` + Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` + + // We accept "data" and "input" for backwards-compatibility reasons. + // "input" is the newer name and should be preferred by clients. + // Issue detail: https://github.com/ethereum/go-ethereum/issues/15628 + Data *hexutil.Bytes `json:"data"` + Input *hexutil.Bytes `json:"input"` + + // Introduced by AccessListTxType transaction. + AccessList *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + + // Introduced by EIP-4844. + BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas"` + BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"` +} + +// SignTransactionResult represents a RLP encoded signed transaction. +type SignTransactionResult struct { + Raw hexutil.Bytes `json:"raw"` + Tx *types.Transaction `json:"tx"` +} + +// FillTransaction fill transaction. +func (c *EthClient) FillTransaction(ctx context.Context, args *TransactionArgs) (*types.Transaction, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, c.timeout) + defer cancel() + + var result SignTransactionResult + err := c.CallContext(ctxWithTimeout, &result, "eth_fillTransaction", *args) + if err != nil { + return nil, err + } + + return result.Tx, nil +} diff --git a/packages/taiko-client/pkg/rpc/ethclient_test.go b/packages/taiko-client/pkg/rpc/ethclient_test.go new file mode 100644 index 00000000000..3739482b63d --- /dev/null +++ b/packages/taiko-client/pkg/rpc/ethclient_test.go @@ -0,0 +1,170 @@ +package rpc + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestBlockByHash(t *testing.T) { + client := newTestClientWithTimeout(t) + + head, err := client.L1.HeaderByNumber(context.Background(), nil) + require.Nil(t, err) + + block, err := client.L1.BlockByHash(context.Background(), head.Hash()) + + require.Nil(t, err) + require.Equal(t, head.Hash(), block.Hash()) +} + +func TestBlockNumber(t *testing.T) { + client := newTestClientWithTimeout(t) + + head, err := client.L1.BlockNumber(context.Background()) + require.Nil(t, err) + require.Greater(t, head, uint64(0)) +} + +func TestPeerCount(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PeerCount(context.Background()) + require.NotNil(t, err) +} + +func TestTransactionByHash(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, _, err := client.L1.TransactionByHash(context.Background(), common.Hash{}) + require.NotNil(t, err) +} + +func TestTransactionSender(t *testing.T) { + client := newTestClientWithTimeout(t) + + block, err := client.L1.BlockByNumber(context.Background(), nil) + require.Nil(t, err) + require.NotZero(t, block.Transactions().Len()) +} + +func TestTransactionCount(t *testing.T) { + client := newTestClientWithTimeout(t) + + block, err := client.L1.BlockByNumber(context.Background(), nil) + require.Nil(t, err) + require.NotZero(t, block.Transactions().Len()) +} + +func TestTransactionInBlock(t *testing.T) { + client := newTestClientWithTimeout(t) + + block, err := client.L1.BlockByNumber(context.Background(), nil) + require.Nil(t, err) + require.NotZero(t, block.Transactions().Len()) + + _, err = client.L1.TransactionInBlock(context.Background(), block.Hash(), 0) + require.Nil(t, err) +} + +func TestNetworkID(t *testing.T) { + client := newTestClientWithTimeout(t) + + networkID, err := client.L1.NetworkID(context.Background()) + require.Nil(t, err) + require.NotEqual(t, common.Big0.Uint64(), networkID.Uint64()) +} + +func TestStorageAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.StorageAt(context.Background(), common.Address{}, common.Hash{}, nil) + require.Nil(t, err) +} + +func TestCodeAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.CodeAt(context.Background(), common.Address{}, nil) + require.Nil(t, err) +} + +func TestNonceAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.NonceAt(context.Background(), common.Address{}, nil) + require.Nil(t, err) +} + +func TestPendingBalanceAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PendingBalanceAt(context.Background(), common.Address{}) + require.Nil(t, err) +} + +func TestPendingStorageAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PendingStorageAt(context.Background(), common.Address{}, common.Hash{}) + require.Nil(t, err) +} + +func TestPendingCodeAt(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PendingCodeAt(context.Background(), common.Address{}) + require.Nil(t, err) +} + +func TestPendingTransactionCount(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PendingTransactionCount(context.Background()) + require.Nil(t, err) +} + +func TestCallContractAtHash(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.CallContractAtHash(context.Background(), ethereum.CallMsg{}, common.Hash{}) + require.NotNil(t, err) +} + +func TestPendingCallContract(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.PendingCallContract(context.Background(), ethereum.CallMsg{}) + require.Nil(t, err) +} + +func TestSuggestGasPrice(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.SuggestGasPrice(context.Background()) + require.Nil(t, err) +} + +func TestSuggestGasTipCap(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.SuggestGasTipCap(context.Background()) + require.Nil(t, err) +} + +func TestFeeHistory(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.FeeHistory(context.Background(), 1, nil, []float64{}) + require.Nil(t, err) +} + +func TestEstimateGas(t *testing.T) { + client := newTestClientWithTimeout(t) + + _, err := client.L1.EstimateGas(context.Background(), ethereum.CallMsg{}) + require.Nil(t, err) +} diff --git a/packages/taiko-client/pkg/rpc/fallback.go b/packages/taiko-client/pkg/rpc/fallback.go new file mode 100644 index 00000000000..6237f2105a0 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/fallback.go @@ -0,0 +1,29 @@ +package rpc + +import ( + "errors" + "math/big" + "strings" +) + +// Taken from: +// https://github.com/ethereum-optimism/optimism-legacy/blob/develop/bss-core/drivers/max_priority_fee_fallback.go +var ( + //lint:ignore ST1005 allow `errMaxPriorityFeePerGasNotFound` to be capitalized. + errMaxPriorityFeePerGasNotFound = errors.New( + "method eth_maxPriorityFeePerGas not found", + ) + + // FallbackGasTipCap is the default fallback gasTipCap used when we are + // unable to query an L1 backend for a suggested gasTipCap. + FallbackGasTipCap = big.NewInt(1500000000) +) + +// IsMaxPriorityFeePerGasNotFoundError returns true if the provided error +// signals that the backend does not support the eth_maxPriorityFeePerGas +// method. In this case, the caller should fallback to using the constant above. +func IsMaxPriorityFeePerGasNotFoundError(err error) bool { + return strings.Contains( + err.Error(), errMaxPriorityFeePerGasNotFound.Error(), + ) +} diff --git a/packages/taiko-client/pkg/rpc/fallback_test.go b/packages/taiko-client/pkg/rpc/fallback_test.go new file mode 100644 index 00000000000..a7d05649dc7 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/fallback_test.go @@ -0,0 +1,13 @@ +package rpc + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsMaxPriorityFeePerGasNotFoundError(t *testing.T) { + require.False(t, IsMaxPriorityFeePerGasNotFoundError(errors.New("test"))) + require.True(t, IsMaxPriorityFeePerGasNotFoundError(errMaxPriorityFeePerGasNotFound)) +} diff --git a/packages/taiko-client/pkg/rpc/methods.go b/packages/taiko-client/pkg/rpc/methods.go new file mode 100644 index 00000000000..b5af64a3484 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/methods.go @@ -0,0 +1,726 @@ +package rpc + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/miner" + "golang.org/x/sync/errgroup" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +var ( + // errSyncing is returned when the L2 execution engine is syncing. + errSyncing = errors.New("syncing") + errEmptyTiersList = errors.New("empty proof tiers list in protocol") + rpcPollingInterval = 3 * time.Second + defaultWaitTimeout = 3 * time.Minute +) + +// ensureGenesisMatched fetches the L2 genesis block from TaikoL1 contract, +// and checks whether the fetched genesis is same to the node local genesis. +func (c *Client) ensureGenesisMatched(ctx context.Context) error { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + stateVars, err := c.GetProtocolStateVariables(&bind.CallOpts{Context: ctxWithTimeout}) + if err != nil { + return err + } + + // Fetch the genesis `BlockVerified` event. + iter, err := c.TaikoL1.FilterBlockVerified( + &bind.FilterOpts{Start: stateVars.A.GenesisHeight, End: &stateVars.A.GenesisHeight, Context: ctxWithTimeout}, + []*big.Int{common.Big0}, + nil, + ) + if err != nil { + return err + } + + // Fetch the node's genesis block. + nodeGenesis, err := c.L2.HeaderByNumber(ctxWithTimeout, common.Big0) + if err != nil { + return err + } + + if iter.Next() { + l2GenesisHash := iter.Event.BlockHash + + log.Debug("Genesis hash", "node", nodeGenesis.Hash(), "TaikoL1", common.BytesToHash(l2GenesisHash[:])) + + // Node's genesis header and TaikoL1 contract's genesis header must match. + if common.BytesToHash(l2GenesisHash[:]) != nodeGenesis.Hash() { + return fmt.Errorf( + "genesis header hash mismatch, node: %s, TaikoL1 contract: %s", + nodeGenesis.Hash(), + common.BytesToHash(l2GenesisHash[:]), + ) + } + + return nil + } + + log.Warn("Genesis block not found in TaikoL1") + + return nil +} + +// WaitTillL2ExecutionEngineSynced keeps waiting until the L2 execution engine is fully synced. +func (c *Client) WaitTillL2ExecutionEngineSynced(ctx context.Context) error { + start := time.Now() + + return backoff.Retry( + func() error { + newCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + progress, err := c.L2ExecutionEngineSyncProgress(newCtx) + if err != nil { + log.Error("Fetch L2 execution engine sync progress error", "error", err) + return err + } + + if progress.isSyncing() { + log.Info( + "L2 execution engine is syncing", + "currentBlockID", progress.CurrentBlockID, + "highestBlockID", progress.HighestBlockID, + "progress", progress.SyncProgress, + "time", time.Since(start), + ) + return errSyncing + } + + return nil + }, + backoff.WithContext(backoff.NewExponentialBackOff(), ctx), + ) +} + +// LatestL2KnownL1Header fetches the L2 execution engine's latest known L1 header, +// if we can't find the L1Origin data, we will use the L1 genesis header instead. +func (c *Client) LatestL2KnownL1Header(ctx context.Context) (*types.Header, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + // Try to fetch the latest known L1 header from the L2 execution engine. + headL1Origin, err := c.L2.HeadL1Origin(ctxWithTimeout) + if err != nil { + switch err.Error() { + case ethereum.NotFound.Error(): + return c.GetGenesisL1Header(ctxWithTimeout) + default: + return nil, err + } + } + + if headL1Origin == nil { + return c.GetGenesisL1Header(ctxWithTimeout) + } + + // Fetch the L1 header from the L1 chain. + header, err := c.L1.HeaderByHash(ctxWithTimeout, headL1Origin.L1BlockHash) + if err != nil { + switch err.Error() { + case ethereum.NotFound.Error(): + log.Warn("Latest L2 known L1 header not found, use genesis instead", "hash", headL1Origin.L1BlockHash) + return c.GetGenesisL1Header(ctxWithTimeout) + default: + return nil, err + } + } + + log.Info("Latest L2 known L1 header", "height", header.Number, "hash", header.Hash()) + + return header, nil +} + +// GetGenesisL1Header fetches the L1 header that including L2 genesis block. +func (c *Client) GetGenesisL1Header(ctx context.Context) (*types.Header, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + stateVars, err := c.GetProtocolStateVariables(&bind.CallOpts{Context: ctxWithTimeout}) + if err != nil { + return nil, err + } + + return c.L1.HeaderByNumber(ctxWithTimeout, new(big.Int).SetUint64(stateVars.A.GenesisHeight)) +} + +// L2ParentByBlockID fetches the block header from L2 execution engine with the largest block id that +// smaller than the given `blockId`. +func (c *Client) L2ParentByBlockID(ctx context.Context, blockID *big.Int) (*types.Header, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + var ( + parentHash common.Hash + parentBlockID = new(big.Int).Sub(blockID, common.Big1) + ) + + log.Debug("Get parent block by block ID", "parentBlockID", parentBlockID) + + if parentBlockID.Cmp(common.Big0) == 0 { + return c.L2.HeaderByNumber(ctxWithTimeout, common.Big0) + } + + l1Origin, err := c.L2.L1OriginByID(ctxWithTimeout, parentBlockID) + if err != nil { + if err.Error() != ethereum.NotFound.Error() { + return nil, err + } + + // In some cases, the L1Origin data is not found in the L2 execution engine, we will try to fetch the parent + // by the parent block ID. + log.Warn("L1Origin not found, try to fetch parent by ID", "blockID", parentBlockID) + + parent, err := c.L2.BlockByNumber(ctxWithTimeout, parentBlockID) + if err != nil { + return nil, err + } + + parentHash = parent.Hash() + } else { + parentHash = l1Origin.L2BlockHash + } + + log.Debug("Parent block L1 origin", "l1Origin", l1Origin, "parentBlockID", parentBlockID) + + return c.L2.HeaderByHash(ctxWithTimeout, parentHash) +} + +func (c *Client) WaitL2Header(ctx context.Context, blockID *big.Int) (*types.Header, error) { + var ( + ctxWithTimeout = ctx + cancel context.CancelFunc + header *types.Header + err error + ) + + ticker := time.NewTicker(rpcPollingInterval) + defer ticker.Stop() + + if _, ok := ctx.Deadline(); !ok { + ctxWithTimeout, cancel = context.WithTimeout(ctx, defaultWaitTimeout) + defer cancel() + } + + log.Debug("Start fetching block header from L2 execution engine", "blockID", blockID) + + for ; true; <-ticker.C { + if ctxWithTimeout.Err() != nil { + return nil, ctxWithTimeout.Err() + } + + header, err = c.L2.HeaderByNumber(ctxWithTimeout, blockID) + if err != nil { + log.Debug( + "Fetch block header from L2 execution engine not found, keep retrying", + "blockID", blockID, + "error", err, + ) + continue + } + + if header == nil { + continue + } + + return header, nil + } + + return nil, fmt.Errorf("failed to fetch block header from L2 execution engine, blockID: %d", blockID) +} + +// GetPoolContent fetches the transactions list from L2 execution engine's transactions pool with given +// upper limit. +func (c *Client) GetPoolContent( + ctx context.Context, + beneficiary common.Address, + blockMaxGasLimit uint32, + maxBytesPerTxList uint64, + locals []common.Address, + maxTransactionsLists uint64, +) ([]*miner.PreBuiltTxList, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + l1Head, err := c.L1.HeaderByNumber(ctx, nil) + if err != nil { + return nil, err + } + + l2Head, err := c.L2.HeaderByNumber(ctx, nil) + if err != nil { + return nil, err + } + + baseFeeInfo, err := c.TaikoL2.GetBasefee( + &bind.CallOpts{Context: ctx}, + l1Head.Number.Uint64(), + uint32(l2Head.GasUsed), + ) + if err != nil { + return nil, err + } + + log.Info("Current base fee", "fee", utils.WeiToGWei(baseFeeInfo.Basefee)) + + var localsArg []string + for _, local := range locals { + localsArg = append(localsArg, local.Hex()) + } + + return c.L2Engine.TxPoolContent( + ctxWithTimeout, + beneficiary, + baseFeeInfo.Basefee, + uint64(blockMaxGasLimit), + maxBytesPerTxList, + localsArg, + maxTransactionsLists, + ) +} + +// L2AccountNonce fetches the nonce of the given L2 account at a specified height. +func (c *Client) L2AccountNonce( + ctx context.Context, + account common.Address, + height *big.Int, +) (uint64, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + var result hexutil.Uint64 + err := c.L2.CallContext(ctxWithTimeout, &result, "eth_getTransactionCount", account, hexutil.EncodeBig(height)) + return uint64(result), err +} + +// L2SyncProgress represents the sync progress of a L2 execution engine, `ethereum.SyncProgress` is used to check +// the sync progress of verified blocks, and block IDs are used to check the sync progress of pending blocks. +type L2SyncProgress struct { + *ethereum.SyncProgress + CurrentBlockID *big.Int + HighestBlockID *big.Int +} + +// isSyncing returns true if the L2 execution engine is syncing with L1. +func (p *L2SyncProgress) isSyncing() bool { + if p.SyncProgress == nil { + return false + } + + if p.CurrentBlockID == nil || p.HighestBlockID == nil { + return true + } + + return p.CurrentBlockID.Cmp(p.HighestBlockID) < 0 +} + +// L2ExecutionEngineSyncProgress fetches the sync progress of the given L2 execution engine. +func (c *Client) L2ExecutionEngineSyncProgress(ctx context.Context) (*L2SyncProgress, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + var ( + progress = new(L2SyncProgress) + err error + ) + g, ctx := errgroup.WithContext(ctxWithTimeout) + + g.Go(func() error { + progress.SyncProgress, err = c.L2.SyncProgress(ctx) + return err + }) + g.Go(func() error { + stateVars, err := c.GetProtocolStateVariables(&bind.CallOpts{Context: ctx}) + if err != nil { + return err + } + progress.HighestBlockID = new(big.Int).SetUint64(stateVars.B.NumBlocks - 1) + return nil + }) + g.Go(func() error { + headL1Origin, err := c.L2.HeadL1Origin(ctx) + if err != nil { + switch err.Error() { + case ethereum.NotFound.Error(): + // There is only genesis block in the L2 execution engine, or it has not started + // syncing the pending blocks yet. + progress.CurrentBlockID = common.Big0 + return nil + default: + return err + } + } + progress.CurrentBlockID = headL1Origin.BlockID + return nil + }) + + if err := g.Wait(); err != nil { + return nil, err + } + + return progress, nil +} + +// GetProtocolStateVariables gets the protocol states from TaikoL1 contract. +func (c *Client) GetProtocolStateVariables(opts *bind.CallOpts) (*struct { + A bindings.TaikoDataSlotA + B bindings.TaikoDataSlotB +}, error) { + if opts == nil { + opts = &bind.CallOpts{} + } + + var ctx = context.Background() + if opts.Context != nil { + ctx = opts.Context + } + ctxWithTimeout, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + opts.Context = ctxWithTimeout + + return GetProtocolStateVariables(c.TaikoL1, opts) +} + +// GetL2BlockInfo fetches the L2 block information from the protocol. +func (c *Client) GetL2BlockInfo(ctx context.Context, blockID *big.Int) (bindings.TaikoDataBlock, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + return c.TaikoL1.GetBlock(&bind.CallOpts{Context: ctxWithTimeout}, blockID.Uint64()) +} + +// GetTransition fetches the L2 block's corresponding transition state from the protocol. +func (c *Client) GetTransition( + ctx context.Context, + blockID *big.Int, + transactionID uint32, +) (bindings.TaikoDataTransitionState, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + return c.TaikoL1.GetTransition( + &bind.CallOpts{Context: ctxWithTimeout}, + blockID.Uint64(), + transactionID, + ) +} + +// ReorgCheckResult represents the information about whether the L1 block has been reorged +// and how to reset the L1 cursor. +type ReorgCheckResult struct { + IsReorged bool + L1CurrentToReset *types.Header + LastHandledBlockIDToReset *big.Int +} + +// CheckL1Reorg checks whether the L2 block's corresponding L1 block has been reorged or not. +// We will skip the reorg check if: +// 1. When the L2 chain has just finished a P2P sync, so there is no L1Origin information recorded in +// its local database, and we assume the last verified L2 block is old enough, so its corresponding +// L1 block should have also been finalized. +// +// Then we will check: +// 1. If the L2 block's corresponding L1 block which in L1Origin has been reorged +// 2. If the L1 information which in the given L2 block's anchor transaction has been reorged +// +// And if a reorg is detected, we return a new L1 block cursor which need to reset to. +func (c *Client) CheckL1Reorg(ctx context.Context, blockID *big.Int) (*ReorgCheckResult, error) { + var ( + result = new(ReorgCheckResult) + ctxWithTimeout, cancel = ctxWithTimeoutOrDefault(ctx, defaultTimeout) + ) + defer cancel() + + for { + // If we rollback to the genesis block, then there is no L1Origin information recorded in the L2 execution + // engine for that block, so we will query the protocol to use `GenesisHeight` value to reset the L1 cursor. + if blockID.Cmp(common.Big0) == 0 { + slotA, _, err := c.TaikoL1.GetStateVariables(&bind.CallOpts{Context: ctxWithTimeout}) + if err != nil { + return result, err + } + + if result.L1CurrentToReset, err = c.L1.HeaderByNumber( + ctxWithTimeout, + new(big.Int).SetUint64(slotA.GenesisHeight), + ); err != nil { + return nil, err + } + + return result, nil + } + + // 1. Check whether the L2 block's corresponding L1 block which in L1Origin has been reorged. + l1Origin, err := c.L2.L1OriginByID(ctxWithTimeout, blockID) + if err != nil { + // If the L2 EE is just synced through P2P, so there is no L1Origin information recorded in + // its local database, we skip this check. + if err.Error() == ethereum.NotFound.Error() { + log.Info("L1Origin not found, the L2 execution engine has just synced from P2P network", "blockID", blockID) + return result, nil + } + + return nil, err + } + + // Compare the L1 header hash in the L1Origin with the current L1 header hash in the L1 chain. + l1Header, err := c.L1.HeaderByNumber(ctxWithTimeout, l1Origin.L1BlockHeight) + if err != nil { + // We can not find the L1 header which in the L1Origin, which means that L1 block has been reorged. + if err.Error() == ethereum.NotFound.Error() { + result.IsReorged = true + blockID = new(big.Int).Sub(blockID, common.Big1) + continue + } + return nil, fmt.Errorf("failed to fetch L1 header (%d): %w", l1Origin.L1BlockHeight, err) + } + + if l1Header.Hash() != l1Origin.L1BlockHash { + log.Info( + "Reorg detected", + "blockID", blockID, + "l1Height", l1Origin.L1BlockHeight, + "l1HashOld", l1Origin.L1BlockHash, + "l1HashNew", l1Header.Hash(), + ) + blockID = new(big.Int).Sub(blockID, common.Big1) + result.IsReorged = true + continue + } + + // 2. Check whether the L1 information which in the given L2 block's anchor transaction has been reorged. + isSyncedL1SnippetInvalid, err := c.checkSyncedL1SnippetFromAnchor( + ctxWithTimeout, + blockID, + l1Origin.L1BlockHeight.Uint64(), + ) + if err != nil { + return nil, fmt.Errorf("failed to check L1 reorg from anchor transaction: %w", err) + } + if isSyncedL1SnippetInvalid { + blockID = new(big.Int).Sub(blockID, common.Big1) + result.IsReorged = true + continue + } + + result.L1CurrentToReset = l1Header + result.LastHandledBlockIDToReset = l1Origin.BlockID + break + } + + log.Debug( + "Check L1 reorg", + "isReorged", result.IsReorged, + "l1CurrentToResetNumber", result.L1CurrentToReset.Number, + "l1CurrentToResetHash", result.L1CurrentToReset.Hash(), + "blockIDToReset", result.LastHandledBlockIDToReset, + ) + + return result, nil +} + +// checkSyncedL1SnippetFromAnchor checks whether the L1 snippet synced from the anchor transaction is valid. +func (c *Client) checkSyncedL1SnippetFromAnchor( + ctx context.Context, + blockID *big.Int, + l1Height uint64, +) (bool, error) { + log.Info("Check synced L1 snippet from anchor", "blockID", blockID, "l1Height", l1Height) + block, err := c.L2.BlockByNumber(ctx, blockID) + if err != nil { + return false, err + } + parent, err := c.L2.BlockByHash(ctx, block.ParentHash()) + if err != nil { + return false, err + } + + l1BlockHash, l1StateRoot, l1HeightInAnchor, parentGasUsed, err := c.getSyncedL1SnippetFromAnchor( + block.Transactions()[0], + ) + if err != nil { + return false, err + } + + if l1HeightInAnchor+1 != l1Height { + log.Info( + "Reorg detected due to L1 height mismatch", + "blockID", blockID, + "l1HeightInAnchor", l1HeightInAnchor, + "l1Height", l1Height, + ) + return true, nil + } + + if parentGasUsed != uint32(parent.GasUsed()) { + log.Info( + "Reorg detected due to parent gas used mismatch", + "blockID", blockID, + "parentGasUsedInAnchor", parentGasUsed, + "parentGasUsed", parent.GasUsed(), + ) + return true, nil + } + + l1Header, err := c.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(l1HeightInAnchor)) + if err != nil { + return false, err + } + + if l1Header.Hash() != l1BlockHash { + log.Info( + "Reorg detected due to L1 block hash mismatch", + "blockID", blockID, + "l1BlockHashInAnchor", l1BlockHash, + "l1BlockHash", l1Header.Hash(), + ) + return true, nil + } + + if l1Header.Root != l1StateRoot { + log.Info( + "Reorg detected due to L1 state root mismatch", + "blockID", blockID, + "l1StateRootInAnchor", l1StateRoot, + "l1StateRoot", l1Header.Root, + ) + return true, nil + } + + return false, nil +} + +// getSyncedL1SnippetFromAnchor parses the anchor transaction calldata, and returns the synced L1 snippet, +func (c *Client) getSyncedL1SnippetFromAnchor( + tx *types.Transaction, +) ( + l1BlockHash common.Hash, + l1StateRoot common.Hash, + l1Height uint64, + parentGasUsed uint32, + err error, +) { + method, err := encoding.TaikoL2ABI.MethodById(tx.Data()) + if err != nil { + return common.Hash{}, common.Hash{}, 0, 0, err + } + + if method.Name != "anchor" { + return common.Hash{}, common.Hash{}, 0, 0, fmt.Errorf("invalid method name for anchor transaction: %s", method.Name) + } + + args := map[string]interface{}{} + + if err := method.Inputs.UnpackIntoMap(args, tx.Data()[4:]); err != nil { + return common.Hash{}, common.Hash{}, 0, 0, err + } + + l1BlockHash, ok := args["_l1BlockHash"].([32]byte) + if !ok { + return common.Hash{}, + common.Hash{}, + 0, + 0, + errors.New("failed to parse l1BlockHash from anchor transaction calldata") + } + l1StateRoot, ok = args["_l1StateRoot"].([32]byte) + if !ok { + return common.Hash{}, + common.Hash{}, + 0, + 0, + errors.New("failed to parse l1StateRoot from anchor transaction calldata") + } + l1Height, ok = args["_l1BlockId"].(uint64) + if !ok { + return common.Hash{}, + common.Hash{}, + 0, + 0, + errors.New("failed to parse l1Height from anchor transaction calldata") + } + parentGasUsed, ok = args["_parentGasUsed"].(uint32) + if !ok { + return common.Hash{}, + common.Hash{}, + 0, + 0, + errors.New("failed to parse parentGasUsed from anchor transaction calldata") + } + + return l1BlockHash, l1StateRoot, l1Height, parentGasUsed, nil +} + +// TierProviderTierWithID wraps protocol ITierProviderTier struct with an ID. +type TierProviderTierWithID struct { + ID uint16 + bindings.ITierProviderTier +} + +// GetTiers fetches all protocol supported tiers. +func (c *Client) GetTiers(ctx context.Context) ([]*TierProviderTierWithID, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + tierProviderAddress, err := c.TaikoL1.Resolve0(&bind.CallOpts{Context: ctx}, StringToBytes32("tier_provider"), false) + if err != nil { + return nil, err + } + + tierProvider, err := bindings.NewTierProvider(tierProviderAddress, c.L1) + if err != nil { + return nil, err + } + + ids, err := tierProvider.GetTierIds(&bind.CallOpts{Context: ctxWithTimeout}) + if err != nil { + return nil, err + } + if len(ids) == 0 { + return nil, errEmptyTiersList + } + + var tiers []*TierProviderTierWithID + for _, id := range ids { + tier, err := tierProvider.GetTier(&bind.CallOpts{Context: ctxWithTimeout}, id) + if err != nil { + return nil, err + } + tiers = append(tiers, &TierProviderTierWithID{ID: id, ITierProviderTier: tier}) + } + + return tiers, nil +} + +// GetTaikoDataSlotBByNumber fetches the state variables by block number. +func (c *Client) GetTaikoDataSlotBByNumber(ctx context.Context, number uint64) (*bindings.TaikoDataSlotB, error) { + iter, err := c.TaikoL1.FilterStateVariablesUpdated( + &bind.FilterOpts{Context: ctx, Start: number, End: &number}, + ) + if err != nil { + return nil, err + } + + for iter.Next() { + return &iter.Event.SlotB, nil + } + + return nil, fmt.Errorf("failed to get state variables by block number %d", number) +} diff --git a/packages/taiko-client/pkg/rpc/methods_test.go b/packages/taiko-client/pkg/rpc/methods_test.go new file mode 100644 index 00000000000..231e158878c --- /dev/null +++ b/packages/taiko-client/pkg/rpc/methods_test.go @@ -0,0 +1,126 @@ +package rpc + +import ( + "context" + "crypto/rand" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +var ( + testAddress = common.HexToAddress("0x98f86166571FE624778203d87A8eD6fd84695B79") +) + +func TestL2AccountNonce(t *testing.T) { + client := newTestClientWithTimeout(t) + + nonce, err := client.L2AccountNonce(context.Background(), testAddress, common.Big0) + + require.Nil(t, err) + require.Zero(t, nonce) +} + +func TestGetGenesisL1Header(t *testing.T) { + client := newTestClient(t) + + header, err := client.GetGenesisL1Header(context.Background()) + + require.Nil(t, err) + require.NotZero(t, header.Number.Uint64()) +} + +func TestLatestL2KnownL1Header(t *testing.T) { + client := newTestClient(t) + + header, err := client.LatestL2KnownL1Header(context.Background()) + + require.Nil(t, err) + require.NotZero(t, header.Number.Uint64()) +} + +func TestL2ParentByBlockId(t *testing.T) { + client := newTestClient(t) + + header, err := client.L2ParentByBlockID(context.Background(), common.Big1) + require.Nil(t, err) + require.Zero(t, header.Number.Uint64()) + + _, err = client.L2ParentByBlockID(context.Background(), common.Big2) + require.NotNil(t, err) +} + +func TestL2ExecutionEngineSyncProgress(t *testing.T) { + client := newTestClient(t) + + progress, err := client.L2ExecutionEngineSyncProgress(context.Background()) + require.Nil(t, err) + require.NotNil(t, progress) +} + +func TestGetProtocolStateVariables(t *testing.T) { + client := newTestClient(t) + _, err := client.GetProtocolStateVariables(nil) + require.Nil(t, err) +} + +func TestWaitTillL2ExecutionEngineSyncedNewClient(t *testing.T) { + client := newTestClient(t) + err := client.WaitTillL2ExecutionEngineSynced(context.Background()) + require.Nil(t, err) +} + +func TestGetSyncedL1SnippetFromAnchor(t *testing.T) { + client := newTestClient(t) + + l1BlockHash := randomHash() + l1StateRoot := randomHash() + l1Height := randomHash().Big().Uint64() + parentGasUsed := uint32(randomHash().Big().Uint64()) + + testAddrPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(encoding.GoldenTouchPrivKey)) + require.Nil(t, err) + + opts, err := bind.NewKeyedTransactorWithChainID(testAddrPrivKey, client.L2.ChainID) + require.Nil(t, err) + + opts.NoSend = true + opts.GasLimit = 1_000_000 + + tx, err := client.TaikoL2.Anchor(opts, l1BlockHash, l1StateRoot, l1Height, parentGasUsed) + require.Nil(t, err) + + syncedL1BlockHash, + syncedL1StateRoot, + syncedL1Height, + syncedParentGasUsed, + err := client.getSyncedL1SnippetFromAnchor(tx) + require.Nil(t, err) + require.Equal(t, l1BlockHash, syncedL1BlockHash) + require.Equal(t, l1StateRoot, syncedL1StateRoot) + require.Equal(t, l1Height, syncedL1Height) + require.Equal(t, parentGasUsed, syncedParentGasUsed) +} + +func TestWaitTillL2ExecutionEngineSyncedContextErr(t *testing.T) { + client := newTestClient(t) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err := client.WaitTillL2ExecutionEngineSynced(ctx) + require.ErrorContains(t, err, "context canceled") +} + +// randomHash generates a random blob of data and returns it as a hash. +func randomHash() common.Hash { + var hash common.Hash + if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil { + panic(err) + } + return hash +} diff --git a/packages/taiko-client/pkg/rpc/subscription.go b/packages/taiko-client/pkg/rpc/subscription.go new file mode 100644 index 00000000000..384ba8efa61 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/subscription.go @@ -0,0 +1,129 @@ +package rpc + +import ( + "context" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" +) + +// SubscribeEvent creates a event subscription, will retry if the established subscription failed. +func SubscribeEvent( + eventName string, + handler func(ctx context.Context) (event.Subscription, error), +) event.Subscription { + return event.ResubscribeErr( + backoff.DefaultMaxInterval, + func(ctx context.Context, err error) (event.Subscription, error) { + if err != nil { + log.Warn("Failed to subscribe protocol event, try resubscribing", "event", eventName, "error", err) + } + + return handler(ctx) + }, + ) +} + +// SubscribeBlockVerified subscribes the protocol's BlockVerified events. +func SubscribeBlockVerified( + taikoL1 *bindings.TaikoL1Client, + ch chan *bindings.TaikoL1ClientBlockVerified, +) event.Subscription { + return SubscribeEvent("BlockVerified", func(ctx context.Context) (event.Subscription, error) { + sub, err := taikoL1.WatchBlockVerified(nil, ch, nil, nil) + if err != nil { + log.Error("Create TaikoL1.BlockVerified subscription error", "error", err) + return nil, err + } + + defer sub.Unsubscribe() + + return waitSubErr(ctx, sub) + }) +} + +// SubscribeBlockProposed subscribes the protocol's BlockProposed events. +func SubscribeBlockProposed( + taikoL1 *bindings.TaikoL1Client, + ch chan *bindings.TaikoL1ClientBlockProposed, +) event.Subscription { + return SubscribeEvent("BlockProposed", func(ctx context.Context) (event.Subscription, error) { + sub, err := taikoL1.WatchBlockProposed(nil, ch, nil, nil) + if err != nil { + log.Error("Create TaikoL1.BlockProposed subscription error", "error", err) + return nil, err + } + + defer sub.Unsubscribe() + + return waitSubErr(ctx, sub) + }) +} + +// SubscribeTransitionProved subscribes the protocol's TransitionProved events. +func SubscribeTransitionProved( + taikoL1 *bindings.TaikoL1Client, + ch chan *bindings.TaikoL1ClientTransitionProved, +) event.Subscription { + return SubscribeEvent("TransitionProved", func(ctx context.Context) (event.Subscription, error) { + sub, err := taikoL1.WatchTransitionProved(nil, ch, nil) + if err != nil { + log.Error("Create TaikoL1.TransitionProved subscription error", "error", err) + return nil, err + } + + defer sub.Unsubscribe() + + return waitSubErr(ctx, sub) + }) +} + +// SubscribeTransitionContested subscribes the protocol's TransitionContested events. +func SubscribeTransitionContested( + taikoL1 *bindings.TaikoL1Client, + ch chan *bindings.TaikoL1ClientTransitionContested, +) event.Subscription { + return SubscribeEvent("TransitionContested", func(ctx context.Context) (event.Subscription, error) { + sub, err := taikoL1.WatchTransitionContested(nil, ch, nil) + if err != nil { + log.Error("Create TaikoL1.TransitionContested subscription error", "error", err) + return nil, err + } + + defer sub.Unsubscribe() + + return waitSubErr(ctx, sub) + }) +} + +// SubscribeChainHead subscribes the new chain heads. +func SubscribeChainHead( + client *EthClient, + ch chan *types.Header, +) event.Subscription { + return SubscribeEvent("ChainHead", func(ctx context.Context) (event.Subscription, error) { + sub, err := client.SubscribeNewHead(ctx, ch) + if err != nil { + log.Error("Create chain head subscription error", "error", err) + return nil, err + } + + defer sub.Unsubscribe() + + return waitSubErr(ctx, sub) + }) +} + +// waitSubErr keeps waiting until the given subscription failed. +func waitSubErr(ctx context.Context, sub event.Subscription) (event.Subscription, error) { + select { + case err := <-sub.Err(): + return sub, err + case <-ctx.Done(): + return sub, ctx.Err() + } +} diff --git a/packages/taiko-client/pkg/rpc/subscription_test.go b/packages/taiko-client/pkg/rpc/subscription_test.go new file mode 100644 index 00000000000..fefc2d02f9b --- /dev/null +++ b/packages/taiko-client/pkg/rpc/subscription_test.go @@ -0,0 +1,53 @@ +package rpc + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" +) + +func TestSubscribeEvent(t *testing.T) { + require.NotNil(t, SubscribeEvent("test", func(_ context.Context) (event.Subscription, error) { + return event.NewSubscription(func(_ <-chan struct{}) error { return nil }), nil + })) +} + +func TestSubscribeBlockVerified(t *testing.T) { + require.NotNil(t, SubscribeBlockVerified( + newTestClient(t).TaikoL1, + make(chan *bindings.TaikoL1ClientBlockVerified, 1024)), + ) +} + +func TestSubscribeBlockProposed(t *testing.T) { + require.NotNil(t, SubscribeBlockProposed( + newTestClient(t).TaikoL1, + make(chan *bindings.TaikoL1ClientBlockProposed, 1024)), + ) +} + +func TestSubscribeTransitionProved(t *testing.T) { + require.NotNil(t, SubscribeTransitionProved( + newTestClient(t).TaikoL1, + make(chan *bindings.TaikoL1ClientTransitionProved, 1024)), + ) +} + +func TestSubscribeTransitionContested(t *testing.T) { + require.NotNil(t, SubscribeTransitionContested( + newTestClient(t).TaikoL1, + make(chan *bindings.TaikoL1ClientTransitionContested, 1024)), + ) +} + +func TestSubscribeChainHead(t *testing.T) { + require.NotNil(t, SubscribeChainHead( + newTestClient(t).L1, + make(chan *types.Header, 1024)), + ) +} diff --git a/packages/taiko-client/pkg/rpc/utils.go b/packages/taiko-client/pkg/rpc/utils.go new file mode 100644 index 00000000000..cfb64e5824e --- /dev/null +++ b/packages/taiko-client/pkg/rpc/utils.go @@ -0,0 +1,346 @@ +package rpc + +import ( + "context" + "math/big" + "strconv" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/txpool" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +var ( + ZeroAddress common.Address + BlobBytes = params.BlobTxBytesPerFieldElement * params.BlobTxFieldElementsPerBlob + BlockMaxTxListBytes uint64 = (params.BlobTxBytesPerFieldElement - 1) * params.BlobTxFieldElementsPerBlob +) + +// GetProtocolStateVariables gets the protocol states from TaikoL1 contract. +func GetProtocolStateVariables( + taikoL1Client *bindings.TaikoL1Client, + opts *bind.CallOpts, +) (*struct { + A bindings.TaikoDataSlotA + B bindings.TaikoDataSlotB +}, error) { + slotA, slotB, err := taikoL1Client.GetStateVariables(opts) + if err != nil { + return nil, err + } + return &struct { + A bindings.TaikoDataSlotA + B bindings.TaikoDataSlotB + }{slotA, slotB}, nil +} + +// CheckProverBalance checks if the prover has the necessary allowance and +// balance for a prover to pay the liveness bond. +func CheckProverBalance( + ctx context.Context, + rpc *Client, + prover common.Address, + address common.Address, + bond *big.Int, +) (bool, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + // Check allowance on taiko token contract + allowance, err := rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctxWithTimeout}, prover, address) + if err != nil { + return false, err + } + + log.Info( + "Prover allowance for TaikoL1 contract", + "allowance", utils.WeiToEther(allowance), + "address", prover.Hex(), + "bond", utils.WeiToEther(bond), + ) + + // Check prover's taiko token balance + balance, err := rpc.TaikoToken.BalanceOf(&bind.CallOpts{Context: ctxWithTimeout}, prover) + if err != nil { + return false, err + } + + log.Info( + "Prover's wallet taiko token balance", + "balance", utils.WeiToEther(balance), + "address", prover.Hex(), + "bond", utils.WeiToEther(bond), + ) + + if bond.Cmp(allowance) > 0 || bond.Cmp(balance) > 0 { + log.Info( + "Assigned prover does not have required on-chain token balance or allowance", + "providedProver", prover.Hex(), + "taikoTokenBalance", utils.WeiToEther(balance), + "allowance", utils.WeiToEther(allowance), + "bond", utils.WeiToEther(bond), + ) + return false, nil + } + + return true, nil +} + +// BlockProofStatus represents the proving status of the given L2 block. +type BlockProofStatus struct { + IsSubmitted bool + Invalid bool + CurrentTransitionState *bindings.TaikoDataTransitionState + ParentHeader *types.Header +} + +// GetBlockProofStatus checks whether the L2 block still needs a new proof or a new contest. +// Here are the possible status: +// 1. No proof on chain at all. +// 2. A valid proof has been submitted. +// 3. An invalid proof has been submitted, and there is no valid contest. +// 4. An invalid proof has been submitted, and there is a valid contest. +func GetBlockProofStatus( + ctx context.Context, + cli *Client, + id *big.Int, + proverAddress common.Address, +) (*BlockProofStatus, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + // Get the local L2 parent header. + var ( + parent *types.Header + err error + ) + if id.Cmp(common.Big1) == 0 { + header, err := cli.L2.HeaderByNumber(ctxWithTimeout, common.Big0) + if err != nil { + return nil, err + } + + parent = header + } else { + if parent, err = cli.L2.HeaderByNumber(ctxWithTimeout, new(big.Int).Sub(id, common.Big1)); err != nil { + return nil, err + } + } + + // Get the transition state from TaikoL1 contract. + transition, err := cli.TaikoL1.GetTransition0( + &bind.CallOpts{Context: ctxWithTimeout}, + id.Uint64(), + parent.Hash(), + ) + if err != nil { + if !strings.Contains(encoding.TryParsingCustomError(err).Error(), "L1_TRANSITION_NOT_FOUND") { + return nil, encoding.TryParsingCustomError(err) + } + + // Status 1, no proof on chain at all. + return &BlockProofStatus{IsSubmitted: false, ParentHeader: parent}, nil + } + + header, err := cli.WaitL2Header(ctxWithTimeout, id) + if err != nil { + return nil, err + } + + if header.Hash() != transition.BlockHash || transition.StateRoot != header.Root { + log.Info( + "Different block hash or state root detected, try submitting a contest", + "localBlockHash", header.Hash(), + "protocolTransitionBlockHash", common.BytesToHash(transition.BlockHash[:]), + "localStateRoot", header.Root, + "protocolTransitionStateRoot", common.BytesToHash(transition.StateRoot[:]), + ) + return &BlockProofStatus{ + IsSubmitted: true, + Invalid: true, + CurrentTransitionState: &transition, + ParentHeader: parent, + }, nil + } + + if proverAddress == transition.Prover { + log.Info( + "📬 Block's proof has already been submitted by current prover", + "blockID", id, + "parent", parent.Hash().Hex(), + "hash", common.Bytes2Hex(transition.BlockHash[:]), + "stateRoot", common.Bytes2Hex(transition.StateRoot[:]), + "timestamp", transition.Timestamp, + "contester", transition.Contester, + ) + return &BlockProofStatus{ + IsSubmitted: true, + Invalid: transition.Contester != ZeroAddress, + ParentHeader: parent, + CurrentTransitionState: &transition, + }, nil + } + + log.Info( + "📬 Block's proof has already been submitted by another prover", + "blockID", id, + "prover", transition.Prover, + "parent", parent.Hash().Hex(), + "hash", common.Bytes2Hex(transition.BlockHash[:]), + "stateRoot", common.Bytes2Hex(transition.StateRoot[:]), + "timestamp", transition.Timestamp, + "contester", transition.Contester, + ) + + return &BlockProofStatus{ + IsSubmitted: true, + Invalid: transition.Contester != ZeroAddress, + ParentHeader: parent, + CurrentTransitionState: &transition, + }, nil +} + +type AccountPoolContent map[string]map[string]map[string]*types.Transaction +type AccountPoolContentFrom map[string]map[string]*types.Transaction + +// Content GetPendingTxs fetches the pending transactions from tx pool. +func Content(ctx context.Context, client *EthClient) (AccountPoolContent, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + var result AccountPoolContent + return result, client.CallContext(ctxWithTimeout, &result, "txpool_content") +} + +// ContentFrom fetches a given account's transactions list from a node's transactions pool. +func ContentFrom( + ctx context.Context, + rawRPC *EthClient, + address common.Address, +) (AccountPoolContentFrom, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + var result AccountPoolContentFrom + return result, rawRPC.CallContext( + ctxWithTimeout, + &result, + "txpool_contentFrom", + address, + ) +} + +// IncreaseGasTipCap tries to increase the given transaction's gasTipCap. +func IncreaseGasTipCap( + ctx context.Context, + cli *Client, + opts *bind.TransactOpts, + address common.Address, + txReplacementTipMultiplier *big.Int, + maxGasTipCap *big.Int, +) (*bind.TransactOpts, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + log.Info("Try replacing a transaction with same nonce", "sender", address, "nonce", opts.Nonce) + + originalTx, err := GetPendingTxByNonce(ctxWithTimeout, cli.L1, address, opts.Nonce.Uint64()) + if err != nil || originalTx == nil { + log.Warn( + "Original transaction not found", + "sender", address, + "nonce", opts.Nonce, + "error", err, + ) + + opts.GasTipCap = new(big.Int).Mul(opts.GasTipCap, txReplacementTipMultiplier) + } else { + log.Info( + "Original transaction to replace", + "sender", address, + "nonce", opts.Nonce, + "gasTipCap", originalTx.GasTipCap(), + "gasFeeCap", originalTx.GasFeeCap(), + ) + + opts.GasTipCap = new(big.Int).Mul(originalTx.GasTipCap(), txReplacementTipMultiplier) + } + + if maxGasTipCap != nil && opts.GasTipCap.Cmp(maxGasTipCap) > 0 { + log.Info( + "New gasTipCap exceeds limit, keep waiting", + "multiplier", txReplacementTipMultiplier, + "newGasTipCap", opts.GasTipCap, + "maxTipCap", maxGasTipCap, + ) + return nil, txpool.ErrReplaceUnderpriced + } + + return opts, nil +} + +// GetPendingTxByNonce tries to retrieve a pending transaction with a given nonce in a node's mempool. +func GetPendingTxByNonce( + ctx context.Context, + cli *EthClient, + address common.Address, + nonce uint64, +) (*types.Transaction, error) { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + content, err := ContentFrom(ctxWithTimeout, cli, address) + if err != nil { + return nil, err + } + + for _, txMap := range content { + for txNonce, tx := range txMap { + if txNonce == strconv.Itoa(int(nonce)) { + return tx, nil + } + } + } + + return nil, nil +} + +// SetHead makes a `debug_setHead` RPC call to set the chain's head, should only be used +// for testing purpose. +func SetHead(ctx context.Context, client *EthClient, headNum *big.Int) error { + ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout) + defer cancel() + + return client.SetHead(ctxWithTimeout, headNum) +} + +// StringToBytes32 converts the given string to [32]byte. +func StringToBytes32(str string) [32]byte { + var b [32]byte + copy(b[:], []byte(str)) + + return b +} + +// ctxWithTimeoutOrDefault sets a context timeout if the deadline has not passed or is not set, +// and otherwise returns the context as passed in. cancel func is always set to an empty function +// so is safe to defer the cancel. +func ctxWithTimeoutOrDefault(ctx context.Context, defaultTimeout time.Duration) (context.Context, context.CancelFunc) { + if utils.IsNil(ctx) { + return context.WithTimeout(context.Background(), defaultTimeout) + } + if _, ok := ctx.Deadline(); !ok { + return context.WithTimeout(ctx, defaultTimeout) + } + + return ctx, func() {} +} diff --git a/packages/taiko-client/pkg/rpc/utils_test.go b/packages/taiko-client/pkg/rpc/utils_test.go new file mode 100644 index 00000000000..bc5d84245b1 --- /dev/null +++ b/packages/taiko-client/pkg/rpc/utils_test.go @@ -0,0 +1,59 @@ +package rpc + +import ( + "context" + "math/big" + "os" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +func TestSetHead(t *testing.T) { + require.Nil(t, SetHead(context.Background(), newTestClient(t).L2, common.Big0)) +} + +func TestStringToBytes32(t *testing.T) { + require.Equal(t, [32]byte{}, StringToBytes32("")) + require.Equal(t, [32]byte{0x61, 0x62, 0x63}, StringToBytes32("abc")) +} + +func TestL1ContentFrom(t *testing.T) { + client := newTestClient(t) + l2Head, err := client.L2.HeaderByNumber(context.Background(), nil) + require.Nil(t, err) + + baseFeeInfo, err := client.TaikoL2.GetBasefee(nil, 0, uint32(l2Head.GasUsed)) + require.Nil(t, err) + + testAddrPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + require.Nil(t, err) + + testAddr := crypto.PubkeyToAddress(testAddrPrivKey.PublicKey) + + nonce, err := client.L2.PendingNonceAt(context.Background(), testAddr) + require.Nil(t, err) + + tx := types.NewTransaction( + nonce, + testAddr, + common.Big1, + 100000, + new(big.Int).SetUint64(uint64(10*params.GWei)+baseFeeInfo.Basefee.Uint64()), + []byte{}, + ) + signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(client.L2.ChainID), testAddrPrivKey) + require.Nil(t, err) + require.Nil(t, client.L2.SendTransaction(context.Background(), signedTx)) + + content, err := ContentFrom(context.Background(), client.L2, testAddr) + require.Nil(t, err) + + require.NotZero(t, len(content["pending"])) + require.Equal(t, signedTx.Nonce(), content["pending"][strconv.Itoa(int(signedTx.Nonce()))].Nonce()) +} diff --git a/packages/taiko-client/pkg/txlist_validator/tx_list_validator.go b/packages/taiko-client/pkg/txlist_validator/tx_list_validator.go new file mode 100644 index 00000000000..1d1801a7786 --- /dev/null +++ b/packages/taiko-client/pkg/txlist_validator/tx_list_validator.go @@ -0,0 +1,56 @@ +package txlistvalidator + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +// TxListValidator is responsible for validating the transactions list in a TaikoL1.proposeBlock transaction. +type TxListValidator struct { + blockMaxGasLimit uint64 + maxBytesPerTxList uint64 + chainID *big.Int +} + +// NewTxListValidator creates a new TxListValidator instance based on giving configurations. +func NewTxListValidator( + blockMaxGasLimit uint64, + maxBytesPerTxList uint64, + chainID *big.Int, +) *TxListValidator { + return &TxListValidator{ + blockMaxGasLimit: blockMaxGasLimit, + maxBytesPerTxList: maxBytesPerTxList, + chainID: chainID, + } +} + +// ValidateTxList checks whether the transactions list in the TaikoL1.proposeBlock transaction's +// input data is valid. +func (v *TxListValidator) ValidateTxList( + blockID *big.Int, + txListBytes []byte, + blobUsed bool, +) (isValid bool) { + // If the transaction list is empty, it's valid. + if len(txListBytes) == 0 { + return true + } + + if !blobUsed && (len(txListBytes) > int(v.maxBytesPerTxList)) { + log.Info("Transactions list binary too large", "length", len(txListBytes), "blockID", blockID) + return false + } + + var txs types.Transactions + if err := rlp.DecodeBytes(txListBytes, &txs); err != nil { + log.Info("Failed to decode transactions list bytes", "blockID", blockID, "error", err) + return false + } + + log.Info("Transaction list is valid", "blockID", blockID) + return true +} diff --git a/packages/taiko-client/pkg/txlist_validator/tx_list_validator_test.go b/packages/taiko-client/pkg/txlist_validator/tx_list_validator_test.go new file mode 100644 index 00000000000..f525bef46af --- /dev/null +++ b/packages/taiko-client/pkg/txlist_validator/tx_list_validator_test.go @@ -0,0 +1,111 @@ +package txlistvalidator + +import ( + "crypto/rand" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/require" +) + +var ( + maxBlocksGasLimit = uint64(50) + maxTxlistBytes = uint64(10000) + chainID = genesis.Config.ChainID + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + genesis = &core.Genesis{ + Config: params.AllEthashProtocolChanges, + Alloc: types.GenesisAlloc{testAddr: {Balance: big.NewInt(2e15)}}, + ExtraData: []byte("test genesis"), + Timestamp: 9000, + BaseFee: big.NewInt(params.InitialBaseFee), + } +) + +func TestIsTxListValid(t *testing.T) { + v := NewTxListValidator( + maxBlocksGasLimit, + maxTxlistBytes, + chainID, + ) + tests := []struct { + name string + blockID *big.Int + txListBytes []byte + isValid bool + }{ + { + "txListBytes binary too large", + chainID, + randBytes(maxTxlistBytes + 1), + false, + }, + { + "txListBytes not decodable to rlp", + chainID, + randBytes(0x1), + false, + }, + { + "success empty tx list", + chainID, + rlpEncodedTransactionBytes(0, true), + true, + }, + { + "success non-empty tx list", + chainID, + rlpEncodedTransactionBytes(1, true), + true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + isValid := v.ValidateTxList(tt.blockID, tt.txListBytes, false) + require.Equal(t, tt.isValid, isValid) + }) + } +} + +func rlpEncodedTransactionBytes(l int, signed bool) []byte { + txs := make(types.Transactions, 0) + for i := 0; i < l; i++ { + var tx *types.Transaction + if signed { + txData := &types.LegacyTx{ + Nonce: 1, + To: &testAddr, + GasPrice: common.Big256, + Value: common.Big1, + Gas: 10, + } + + tx = types.MustSignNewTx(testKey, types.LatestSigner(genesis.Config), txData) + } else { + tx = types.NewTransaction(1, testAddr, common.Big1, 10, new(big.Int).SetUint64(10*params.GWei), nil) + } + txs = append( + txs, + tx, + ) + } + b, _ := rlp.EncodeToBytes(txs) + return b +} + +func randBytes(l uint64) []byte { + b := make([]byte, l) + if _, err := rand.Read(b); err != nil { + log.Crit("Failed to generate random bytes", "error", err) + } + return b +} diff --git a/packages/taiko-client/proposer/config.go b/packages/taiko-client/proposer/config.go new file mode 100644 index 00000000000..673289f0e6c --- /dev/null +++ b/packages/taiko-client/proposer/config.go @@ -0,0 +1,136 @@ +package proposer + +import ( + "crypto/ecdsa" + "fmt" + "math/big" + "net/url" + "strings" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + + pkgFlags "github.com/taikoxyz/taiko-client/pkg/flags" +) + +// Config contains all configurations to initialize a Taiko proposer. +type Config struct { + *rpc.ClientConfig + AssignmentHookAddress common.Address + L1ProposerPrivKey *ecdsa.PrivateKey + L2SuggestedFeeRecipient common.Address + ExtraData string + ProposeInterval time.Duration + LocalAddresses []common.Address + LocalAddressesOnly bool + MinGasUsed uint64 + MinTxListBytes uint64 + MinProposingInternal time.Duration + MaxProposedTxListsPerEpoch uint64 + ProposeBlockTxGasLimit uint64 + ProverEndpoints []*url.URL + OptimisticTierFee *big.Int + SgxTierFee *big.Int + TierFeePriceBump *big.Int + MaxTierFeePriceBumps uint64 + IncludeParentMetaHash bool + BlobAllowed bool + TxmgrConfigs *txmgr.CLIConfig + L1BlockBuilderTip *big.Int +} + +// NewConfigFromCliContext initializes a Config instance from +// command line flags. +func NewConfigFromCliContext(c *cli.Context) (*Config, error) { + jwtSecret, err := jwt.ParseSecretFromFile(c.String(flags.JWTSecret.Name)) + if err != nil { + return nil, fmt.Errorf("invalid JWT secret file: %w", err) + } + + l1ProposerPrivKey, err := crypto.ToECDSA( + common.Hex2Bytes(c.String(flags.L1ProposerPrivKey.Name)), + ) + if err != nil { + return nil, fmt.Errorf("invalid L1 proposer private key: %w", err) + } + + l2SuggestedFeeRecipient := c.String(flags.L2SuggestedFeeRecipient.Name) + if !common.IsHexAddress(l2SuggestedFeeRecipient) { + return nil, fmt.Errorf("invalid L2 suggested fee recipient address: %s", l2SuggestedFeeRecipient) + } + + var localAddresses []common.Address + if c.IsSet(flags.TxPoolLocals.Name) { + for _, account := range strings.Split(c.String(flags.TxPoolLocals.Name), ",") { + if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) { + return nil, fmt.Errorf("invalid account in --txpool.locals: %s", trimmed) + } + localAddresses = append(localAddresses, common.HexToAddress(account)) + } + } + + var proverEndpoints []*url.URL + for _, e := range strings.Split(c.String(flags.ProverEndpoints.Name), ",") { + endpoint, err := url.Parse(e) + if err != nil { + return nil, err + } + proverEndpoints = append(proverEndpoints, endpoint) + } + + optimisticTierFee, err := utils.GWeiToWei(c.Float64(flags.OptimisticTierFee.Name)) + if err != nil { + return nil, err + } + + sgxTierFee, err := utils.GWeiToWei(c.Float64(flags.SgxTierFee.Name)) + if err != nil { + return nil, err + } + + return &Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: c.String(flags.L1WSEndpoint.Name), + L2Endpoint: c.String(flags.L2HTTPEndpoint.Name), + TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)), + TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)), + L2EngineEndpoint: c.String(flags.L2AuthEndpoint.Name), + JwtSecret: string(jwtSecret), + TaikoTokenAddress: common.HexToAddress(c.String(flags.TaikoTokenAddress.Name)), + Timeout: c.Duration(flags.RPCTimeout.Name), + }, + AssignmentHookAddress: common.HexToAddress(c.String(flags.AssignmentHookAddress.Name)), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(l2SuggestedFeeRecipient), + ExtraData: c.String(flags.ExtraData.Name), + ProposeInterval: c.Duration(flags.ProposeInterval.Name), + LocalAddresses: localAddresses, + LocalAddressesOnly: c.Bool(flags.TxPoolLocalsOnly.Name), + MinGasUsed: c.Uint64(flags.MinGasUsed.Name), + MinTxListBytes: c.Uint64(flags.MinTxListBytes.Name), + MinProposingInternal: c.Duration(flags.MinProposingInternal.Name), + MaxProposedTxListsPerEpoch: c.Uint64(flags.MaxProposedTxListsPerEpoch.Name), + ProposeBlockTxGasLimit: c.Uint64(flags.TxGasLimit.Name), + ProverEndpoints: proverEndpoints, + OptimisticTierFee: optimisticTierFee, + SgxTierFee: sgxTierFee, + TierFeePriceBump: new(big.Int).SetUint64(c.Uint64(flags.TierFeePriceBump.Name)), + MaxTierFeePriceBumps: c.Uint64(flags.MaxTierFeePriceBumps.Name), + IncludeParentMetaHash: c.Bool(flags.ProposeBlockIncludeParentMetaHash.Name), + BlobAllowed: c.Bool(flags.BlobAllowed.Name), + L1BlockBuilderTip: new(big.Int).SetUint64(c.Uint64(flags.L1BlockBuilderTip.Name)), + TxmgrConfigs: pkgFlags.InitTxmgrConfigsFromCli( + c.String(flags.L1WSEndpoint.Name), + l1ProposerPrivKey, + c, + ), + }, nil +} diff --git a/packages/taiko-client/proposer/config_test.go b/packages/taiko-client/proposer/config_test.go new file mode 100644 index 00000000000..59124c3f298 --- /dev/null +++ b/packages/taiko-client/proposer/config_test.go @@ -0,0 +1,154 @@ +package proposer + +import ( + "context" + "fmt" + "os" + "strings" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +var ( + l1Endpoint = os.Getenv("L1_NODE_WS_ENDPOINT") + l2Endpoint = os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT") + taikoL1 = os.Getenv("TAIKO_L1_ADDRESS") + taikoL2 = os.Getenv("TAIKO_L2_ADDRESS") + taikoToken = os.Getenv("TAIKO_TOKEN_ADDRESS") + proverEndpoints = "http://localhost:9876,http://localhost:1234" + tierFee = 100.0 + proposeInterval = "10s" + rpcTimeout = "5s" +) + +func (s *ProposerTestSuite) TestNewConfigFromCliContext() { + goldenTouchAddress, err := s.RPCClient.TaikoL2.GOLDENTOUCHADDRESS(nil) + s.Nil(err) + + app := s.SetupApp() + + app.Action = func(cliCtx *cli.Context) error { + c, err := NewConfigFromCliContext(cliCtx) + s.Nil(err) + s.Equal(l1Endpoint, c.L1Endpoint) + s.Equal(l2Endpoint, c.L2Endpoint) + s.Equal(taikoL1, c.TaikoL1Address.String()) + s.Equal(taikoL2, c.TaikoL2Address.String()) + s.Equal(taikoToken, c.TaikoTokenAddress.String()) + s.Equal(goldenTouchAddress, crypto.PubkeyToAddress(c.L1ProposerPrivKey.PublicKey)) + s.Equal(goldenTouchAddress, c.L2SuggestedFeeRecipient) + s.Equal(float64(10), c.ProposeInterval.Seconds()) + s.Equal(1, len(c.LocalAddresses)) + s.Equal(goldenTouchAddress, c.LocalAddresses[0]) + s.Equal(5*time.Second, c.Timeout) + tierFeeGWei, err := utils.GWeiToWei(tierFee) + s.Nil(err) + s.Equal(tierFeeGWei.Uint64(), c.OptimisticTierFee.Uint64()) + s.Equal(tierFeeGWei.Uint64(), c.SgxTierFee.Uint64()) + s.Equal(uint64(15), c.TierFeePriceBump.Uint64()) + s.Equal(uint64(5), c.MaxTierFeePriceBumps) + s.Equal(true, c.IncludeParentMetaHash) + + for i, e := range strings.Split(proverEndpoints, ",") { + s.Equal(c.ProverEndpoints[i].String(), e) + } + + s.Nil(new(Proposer).InitFromCli(context.Background(), cliCtx)) + return nil + } + + s.Nil(app.Run([]string{ + "TestNewConfigFromCliContext", + "--" + flags.L1WSEndpoint.Name, l1Endpoint, + "--" + flags.L2HTTPEndpoint.Name, l2Endpoint, + "--" + flags.TaikoL1Address.Name, taikoL1, + "--" + flags.TaikoL2Address.Name, taikoL2, + "--" + flags.TaikoTokenAddress.Name, taikoToken, + "--" + flags.L1ProposerPrivKey.Name, encoding.GoldenTouchPrivKey, + "--" + flags.L2SuggestedFeeRecipient.Name, goldenTouchAddress.Hex(), + "--" + flags.ProposeInterval.Name, proposeInterval, + "--" + flags.TxPoolLocals.Name, goldenTouchAddress.Hex(), + "--" + flags.RPCTimeout.Name, rpcTimeout, + "--" + flags.TxGasLimit.Name, "100000", + "--" + flags.ProverEndpoints.Name, proverEndpoints, + "--" + flags.OptimisticTierFee.Name, fmt.Sprint(tierFee), + "--" + flags.SgxTierFee.Name, fmt.Sprint(tierFee), + "--" + flags.TierFeePriceBump.Name, "15", + "--" + flags.MaxTierFeePriceBumps.Name, "5", + "--" + flags.ProposeBlockIncludeParentMetaHash.Name, "true", + })) +} + +func (s *ProposerTestSuite) TestNewConfigFromCliContextPrivKeyErr() { + app := s.SetupApp() + + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContextPrivKeyErr", + "--" + flags.L1ProposerPrivKey.Name, string(common.FromHex("0x")), + }), "invalid L1 proposer private key") +} + +func (s *ProposerTestSuite) TestNewConfigFromCliContextL2RecipErr() { + app := s.SetupApp() + + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContextL2RecipErr", + "--" + flags.L1ProposerPrivKey.Name, encoding.GoldenTouchPrivKey, + "--" + flags.ProposeInterval.Name, proposeInterval, + "--" + flags.MinProposingInternal.Name, proposeInterval, + "--" + flags.L2SuggestedFeeRecipient.Name, "notAnAddress", + }), "invalid L2 suggested fee recipient address") +} + +func (s *ProposerTestSuite) TestNewConfigFromCliContextTxPoolLocalsErr() { + goldenTouchAddress, err := s.RPCClient.TaikoL2.GOLDENTOUCHADDRESS(nil) + s.Nil(err) + + app := s.SetupApp() + + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContextTxPoolLocalsErr", + "--" + flags.L1ProposerPrivKey.Name, encoding.GoldenTouchPrivKey, + "--" + flags.ProposeInterval.Name, proposeInterval, + "--" + flags.MinProposingInternal.Name, proposeInterval, + "--" + flags.L2SuggestedFeeRecipient.Name, goldenTouchAddress.Hex(), + "--" + flags.TxPoolLocals.Name, "notAnAddress", + }), "invalid account in --txpool.locals") +} + +func (s *ProposerTestSuite) SetupApp() *cli.App { + app := cli.NewApp() + app.Flags = []cli.Flag{ + &cli.StringFlag{Name: flags.L1WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L2HTTPEndpoint.Name}, + &cli.StringFlag{Name: flags.TaikoL1Address.Name}, + &cli.StringFlag{Name: flags.TaikoL2Address.Name}, + &cli.StringFlag{Name: flags.TaikoTokenAddress.Name}, + &cli.StringFlag{Name: flags.L1ProposerPrivKey.Name}, + &cli.StringFlag{Name: flags.L2SuggestedFeeRecipient.Name}, + &cli.DurationFlag{Name: flags.MinProposingInternal.Name}, + &cli.DurationFlag{Name: flags.ProposeInterval.Name}, + &cli.StringFlag{Name: flags.TxPoolLocals.Name}, + &cli.StringFlag{Name: flags.ProverEndpoints.Name}, + &cli.Uint64Flag{Name: flags.OptimisticTierFee.Name}, + &cli.Uint64Flag{Name: flags.SgxTierFee.Name}, + &cli.DurationFlag{Name: flags.RPCTimeout.Name}, + &cli.Uint64Flag{Name: flags.TierFeePriceBump.Name}, + &cli.Uint64Flag{Name: flags.MaxTierFeePriceBumps.Name}, + &cli.BoolFlag{Name: flags.ProposeBlockIncludeParentMetaHash.Name}, + &cli.StringFlag{Name: flags.AssignmentHookAddress.Name}, + } + app.Flags = append(app.Flags, flags.TxmgrFlags...) + app.Action = func(ctx *cli.Context) error { + _, err := NewConfigFromCliContext(ctx) + return err + } + return app +} diff --git a/packages/taiko-client/proposer/proposer.go b/packages/taiko-client/proposer/proposer.go new file mode 100644 index 00000000000..cbbcbf6fd4f --- /dev/null +++ b/packages/taiko-client/proposer/proposer.go @@ -0,0 +1,445 @@ +package proposer + +import ( + "bytes" + "context" + "fmt" + "math/rand" + "strings" + "sync" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/sender" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "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/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/rpc" + selector "github.com/taikoxyz/taiko-client/proposer/prover_selector" + builder "github.com/taikoxyz/taiko-client/proposer/transaction_builder" +) + +var ( + proverAssignmentTimeout = 30 * time.Minute + requestProverServerTimeout = 12 * time.Second +) + +// Proposer keep proposing new transactions from L2 execution engine's tx pool at a fixed interval. +type Proposer struct { + // configurations + *Config + + // RPC clients + rpc *rpc.Client + + // Private keys and account addresses + proposerAddress common.Address + + proposingTimer *time.Timer + + tiers []*rpc.TierProviderTierWithID + tierFees []encoding.TierFee + + // Prover selector + proverSelector selector.ProverSelector + + // Transaction builder + txBuilder builder.ProposeBlockTransactionBuilder + + // Protocol configurations + protocolConfigs *bindings.TaikoDataConfig + + lastProposedAt time.Time + + txSender *sender.TxSender + + ctx context.Context + wg sync.WaitGroup +} + +// InitFromCli New initializes the given proposer instance based on the command line flags. +func (p *Proposer) InitFromCli(ctx context.Context, c *cli.Context) error { + cfg, err := NewConfigFromCliContext(c) + if err != nil { + return err + } + + return p.InitFromConfig(ctx, cfg) +} + +// InitFromConfig initializes the proposer instance based on the given configurations. +func (p *Proposer) InitFromConfig(ctx context.Context, cfg *Config) (err error) { + p.proposerAddress = crypto.PubkeyToAddress(cfg.L1ProposerPrivKey.PublicKey) + p.ctx = ctx + p.Config = cfg + p.lastProposedAt = time.Now() + + // RPC clients + if p.rpc, err = rpc.NewClient(p.ctx, cfg.ClientConfig); err != nil { + return fmt.Errorf("initialize rpc clients error: %w", err) + } + + // Protocol configs + protocolConfigs, err := p.rpc.TaikoL1.GetConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return fmt.Errorf("failed to get protocol configs: %w", err) + } + p.protocolConfigs = &protocolConfigs + + log.Info("Protocol configs", "configs", p.protocolConfigs) + + if p.tiers, err = p.rpc.GetTiers(ctx); err != nil { + return err + } + if err := p.initTierFees(); err != nil { + return err + } + + txmgr, err := txmgr.NewSimpleTxManager( + "proposer", + log.Root(), + &metrics.TxMgrMetrics, + *cfg.TxmgrConfigs, + ) + if err != nil { + return err + } + p.txSender = sender.NewTxSender(p.ctx, log.Root(), txmgr, p.Config.MaxProposedTxListsPerEpoch) + + if p.proverSelector, err = selector.NewETHFeeEOASelector( + &protocolConfigs, + p.rpc, + p.proposerAddress, + cfg.TaikoL1Address, + cfg.AssignmentHookAddress, + p.tierFees, + cfg.TierFeePriceBump, + cfg.ProverEndpoints, + cfg.MaxTierFeePriceBumps, + proverAssignmentTimeout, + requestProverServerTimeout, + ); err != nil { + return err + } + + if cfg.BlobAllowed { + p.txBuilder = builder.NewBlobTransactionBuilder( + p.rpc, + p.L1ProposerPrivKey, + p.proverSelector, + p.Config.L1BlockBuilderTip, + cfg.TaikoL1Address, + cfg.L2SuggestedFeeRecipient, + cfg.AssignmentHookAddress, + cfg.ProposeBlockTxGasLimit, + cfg.ExtraData, + ) + } else { + p.txBuilder = builder.NewCalldataTransactionBuilder( + p.rpc, + p.L1ProposerPrivKey, + p.proverSelector, + p.Config.L1BlockBuilderTip, + cfg.L2SuggestedFeeRecipient, + cfg.TaikoL1Address, + cfg.AssignmentHookAddress, + cfg.ProposeBlockTxGasLimit, + cfg.ExtraData, + ) + } + + return nil +} + +// Start starts the proposer's main loop. +func (p *Proposer) Start() error { + p.wg.Add(1) + go p.eventLoop() + return nil +} + +// eventLoop starts the main loop of Taiko proposer. +func (p *Proposer) eventLoop() { + defer func() { + p.proposingTimer.Stop() + p.wg.Done() + }() + + for { + p.updateProposingTicker() + + select { + case <-p.ctx.Done(): + return + // proposing interval timer has been reached + case <-p.proposingTimer.C: + metrics.ProposerProposeEpochCounter.Add(1) + + // Attempt a proposing operation + if err := p.ProposeOp(p.ctx); err != nil { + log.Error("Proposing operation error", "error", err) + continue + } + } + } +} + +// Close closes the proposer instance. +func (p *Proposer) Close(_ context.Context) { + p.wg.Wait() +} + +// fetchPoolContent fetches the transaction pool content from L2 execution engine. +func (p *Proposer) fetchPoolContent(filterPoolContent bool) ([]types.Transactions, error) { + // Fetch the pool content. + preBuiltTxList, err := p.rpc.GetPoolContent( + p.ctx, + p.proposerAddress, + p.protocolConfigs.BlockMaxGasLimit, + rpc.BlockMaxTxListBytes, + p.LocalAddresses, + p.MaxProposedTxListsPerEpoch, + ) + if err != nil { + return nil, fmt.Errorf("failed to fetch transaction pool content: %w", err) + } + + txLists := []types.Transactions{} + for i, txs := range preBuiltTxList { + // Filter the pool content if the filterPoolContent flag is set. + if txs.EstimatedGasUsed < p.MinGasUsed && txs.BytesLength < p.MinTxListBytes && filterPoolContent { + log.Info( + "Pool content skipped", + "index", i, + "estimatedGasUsed", txs.EstimatedGasUsed, + "minGasUsed", p.MinGasUsed, + "bytesLength", txs.BytesLength, + "minBytesLength", p.MinTxListBytes, + ) + break + } + txLists = append(txLists, txs.TxList) + } + // If the pool content is empty and the checkPoolContent flag is not set, return an empty list. + if !filterPoolContent && len(txLists) == 0 { + log.Info( + "Pool content is empty, proposing an empty block", + "lastProposedAt", p.lastProposedAt, + "minProposingInternal", p.MinProposingInternal, + ) + txLists = append(txLists, types.Transactions{}) + } + + // If LocalAddressesOnly is set, filter the transactions by the local addresses. + if p.LocalAddressesOnly { + var ( + localTxsLists []types.Transactions + signer = types.LatestSignerForChainID(p.rpc.L2.ChainID) + ) + for _, txs := range txLists { + var filtered types.Transactions + for _, tx := range txs { + sender, err := types.Sender(signer, tx) + if err != nil { + return nil, err + } + + for _, localAddress := range p.LocalAddresses { + if sender == localAddress { + filtered = append(filtered, tx) + } + } + } + + if filtered.Len() != 0 { + localTxsLists = append(localTxsLists, filtered) + } + } + txLists = localTxsLists + } + + log.Info("Transactions lists count", "count", len(txLists)) + + return txLists, nil +} + +// ProposeOp performs a proposing operation, fetching transactions +// from L2 execution engine's tx pool, splitting them by proposing constraints, +// and then proposing them to TaikoL1 contract. +func (p *Proposer) ProposeOp(ctx context.Context) error { + // Check if it's time to propose unfiltered pool content. + var ( + filterPoolContent = time.Now().Before(p.lastProposedAt.Add(p.MinProposingInternal)) + txListsBytes = make([][]byte, 0) + ) + + // Wait until L2 execution engine is synced at first. + if err := p.rpc.WaitTillL2ExecutionEngineSynced(ctx); err != nil { + return fmt.Errorf("failed to wait until L2 execution engine synced: %w", err) + } + + log.Info( + "Start fetching L2 execution engine's transaction pool content", + "filterPoolContent", filterPoolContent, + "lastProposedAt", p.lastProposedAt, + ) + + // Fetch the pool content with the given limits. + txLists, err := p.fetchPoolContent(filterPoolContent) + if err != nil { + return err + } + + // If the pool content is empty, return. + if len(txLists) == 0 { + return nil + } + + // Propose all L2 transactions lists. + for i, txs := range txLists { + if i >= int(p.MaxProposedTxListsPerEpoch) { + return nil + } + + txListBytes, err := rlp.EncodeToBytes(txs) + if err != nil { + return fmt.Errorf("failed to encode transactions: %w", err) + } + + txListsBytes = append(txListsBytes, txListBytes) + } + + for i, err := range p.ProposeTxLists(ctx, txListsBytes) { + if err != nil { + log.Error( + "Failed to send TaikoL1.proposeBlock transaction", + "index", i, + "error", err, + ) + continue + } + + metrics.ProposerProposedTxListsCounter.Add(1) + metrics.ProposerProposedTxsCounter.Add(float64(len(txLists[i]))) + + log.Info("📝 Propose transactions succeeded", "txs", len(txLists[i])) + p.lastProposedAt = time.Now() + } + + return nil +} + +// ProposeTxLists proposes the given transaction lists to TaikoL1 contract. +func (p *Proposer) ProposeTxLists(ctx context.Context, txListsBytes [][]byte) []error { + txCandidates := make([]txmgr.TxCandidate, 0) + + for i, txListBytes := range txListsBytes { + compressedTxListBytes, err := utils.Compress(txListBytes) + if err != nil { + log.Error("Failed to compress transactions list", "index", i, "error", err) + break + } + + candidate, err := p.txBuilder.Build( + ctx, + p.tierFees, + p.IncludeParentMetaHash, + compressedTxListBytes, + ) + if err != nil { + log.Error("Failed to build TaikoL1.proposeBlock transaction", "error", err) + break + } + + txCandidates = append(txCandidates, *candidate) + } + + if len(txCandidates) == 0 { + return []error{} + } + + // Send the transactions to the TaikoL1 contract, and if any of them fails, try + // to parse the custom error. + errors := p.txSender.SendAndWaitDetailed("proposeBlock", txCandidates...) + for i, err := range errors { + if err == nil { + continue + } + + // If a transaction is reverted on chain, the error string returned by txSender will like this: + // fmt.Errorf("%w purpose: %v hash: %v", ErrTransactionReverted, txPurpose, rcpt.Receipt.TxHash) + // Then we try parsing the custom error for more details in log. + if strings.Contains(err.Error(), "purpose: ") && strings.Contains(err.Error(), "hash: ") { + txHash := strings.Split(err.Error(), "hash: ")[1] + receipt, err := p.rpc.L1.TransactionReceipt(ctx, common.HexToHash(txHash)) + if err != nil { + log.Error("Failed to fetch receipt", "txHash", txHash, "error", err) + continue + } + errors[i] = encoding.TryParsingCustomErrorFromReceipt(ctx, p.rpc.L1, p.proposerAddress, receipt) + } + } + + return errors +} + +// updateProposingTicker updates the internal proposing timer. +func (p *Proposer) updateProposingTicker() { + if p.proposingTimer != nil { + p.proposingTimer.Stop() + } + + var duration time.Duration + if p.ProposeInterval != 0 { + duration = p.ProposeInterval + } else { + // Random number between 12 - 120 + randomSeconds := rand.Intn(120-11) + 12 // nolint: gosec + duration = time.Duration(randomSeconds) * time.Second + } + + p.proposingTimer = time.NewTimer(duration) +} + +// Name returns the application name. +func (p *Proposer) Name() string { + return "proposer" +} + +// initTierFees initializes the proving fees for every proof tier configured in the protocol for the proposer. +func (p *Proposer) initTierFees() error { + for _, tier := range p.tiers { + log.Info( + "Protocol tier", + "id", tier.ID, + "name", string(bytes.TrimRight(tier.VerifierName[:], "\x00")), + "validityBond", utils.WeiToEther(tier.ValidityBond), + "contestBond", utils.WeiToEther(tier.ContestBond), + "provingWindow", tier.ProvingWindow, + "cooldownWindow", tier.CooldownWindow, + ) + + switch tier.ID { + case encoding.TierOptimisticID: + p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: p.OptimisticTierFee}) + case encoding.TierSgxID: + p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: p.SgxTierFee}) + case encoding.TierGuardianID: + // Guardian prover should not charge any fee. + p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: common.Big0}) + default: + return fmt.Errorf("unknown tier: %d", tier.ID) + } + } + + return nil +} diff --git a/packages/taiko-client/proposer/proposer_test.go b/packages/taiko-client/proposer/proposer_test.go new file mode 100644 index 00000000000..1db83e8816a --- /dev/null +++ b/packages/taiko-client/proposer/proposer_test.go @@ -0,0 +1,382 @@ +package proposer + +import ( + "context" + "os" + "strings" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/blob" + "github.com/taikoxyz/taiko-client/driver/state" + txlistfetcher "github.com/taikoxyz/taiko-client/driver/txlist_fetcher" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + builder "github.com/taikoxyz/taiko-client/proposer/transaction_builder" +) + +type ProposerTestSuite struct { + testutils.ClientTestSuite + s *blob.Syncer + p *Proposer + cancel context.CancelFunc +} + +func (s *ProposerTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + state2, err := state.New(context.Background(), s.RPCClient) + s.Nil(err) + + syncer, err := blob.NewSyncer( + context.Background(), + s.RPCClient, + state2, + beaconsync.NewSyncProgressTracker(s.RPCClient.L2, 1*time.Hour), + 0, + nil, + ) + s.Nil(err) + s.s = syncer + + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + p := new(Proposer) + + ctx, cancel := context.WithCancel(context.Background()) + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + s.Nil(p.InitFromConfig(ctx, &Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + MinProposingInternal: 0, + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + TierFeePriceBump: common.Big2, + MaxTierFeePriceBumps: 3, + ExtraData: "test", + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.p = p + s.cancel = cancel +} + +func parseTxs(client *rpc.Client, event *bindings.TaikoL1ClientBlockProposed) (types.Transactions, error) { + tx, err := client.L1.TransactionInBlock(context.Background(), event.Raw.BlockHash, event.Raw.TxIndex) + if err != nil { + return nil, err + } + + // Decode transactions list. + var txListDecoder txlistfetcher.TxListFetcher + if event.Meta.BlobUsed { + txListDecoder = txlistfetcher.NewBlobTxListFetcher(client.L1Beacon, rpc.NewBlobDataSource( + context.Background(), + client, + nil, + )) + } else { + txListDecoder = new(txlistfetcher.CalldataFetcher) + } + txListBytes, err := txListDecoder.Fetch(context.Background(), tx, &event.Meta) + if err != nil { + return nil, err + } + + txListBytes, err = utils.Decompress(txListBytes) + if err != nil { + return nil, err + } + + var txs types.Transactions + return txs, rlp.DecodeBytes(txListBytes, &txs) +} + +func (s *ProposerTestSuite) getLatestProposedTxs( + n int, + timeout time.Duration, +) (<-chan []types.Transactions, error) { + sink := make(chan *bindings.TaikoL1ClientBlockProposed) + sub, err := s.p.rpc.TaikoL1.WatchBlockProposed(nil, sink, nil, nil) + if err != nil { + return nil, err + } + + var resCh = make(chan []types.Transactions, 1) + go func() { + defer sub.Unsubscribe() + + txLst := make([]types.Transactions, 0, n) + tick := time.After(timeout) + for len(txLst) < cap(txLst) { + select { + case event := <-sink: + txs, err := parseTxs(s.RPCClient, event) + if err != nil { + log.Error("failed to parse txs", "error", err) + } + txLst = append(txLst, txs) + case <-tick: + return + } + } + resCh <- txLst + }() + + return resCh, nil +} + +func (s *ProposerTestSuite) TestProposeOpNoEmptyBlock() { + defer s.Nil(s.s.ProcessL1Blocks(context.Background())) + + p := s.p + + batchSize := 100 + + var err error + for i := 0; i < batchSize; i++ { + to := common.BytesToAddress(testutils.RandomBytes(32)) + _, err = testutils.SendDynamicFeeTx(s.RPCClient.L2, s.TestAddrPrivKey, &to, nil, nil) + s.Nil(err) + } + + var preBuiltTxList []*miner.PreBuiltTxList + for i := 0; i < 3 && len(preBuiltTxList) == 0; i++ { + preBuiltTxList, err = s.RPCClient.GetPoolContent( + context.Background(), + p.proposerAddress, + p.protocolConfigs.BlockMaxGasLimit, + rpc.BlockMaxTxListBytes, + p.LocalAddresses, + p.MaxProposedTxListsPerEpoch, + ) + time.Sleep(time.Second) + } + s.Nil(err) + s.Equal(true, len(preBuiltTxList) > 0) + + txsCh, err := s.getLatestProposedTxs(len(preBuiltTxList), time.Minute) + s.Nil(err) + + var ( + blockMinGasLimit uint64 = math.MaxUint64 + blockMinTxListBytes uint64 = math.MaxUint64 + txLists = make([]types.Transactions, 0, len(preBuiltTxList)) + ) + for _, txs := range preBuiltTxList { + if txs.EstimatedGasUsed <= blockMinGasLimit { + blockMinGasLimit = txs.EstimatedGasUsed + } else { + break + } + if txs.BytesLength <= blockMinTxListBytes { + blockMinTxListBytes = txs.BytesLength + } else { + break + } + txLists = append(txLists, txs.TxList) + } + + // Start proposer + p.LocalAddressesOnly = false + p.MinGasUsed = blockMinGasLimit + p.MinTxListBytes = blockMinTxListBytes + p.ProposeInterval = time.Second + p.MinProposingInternal = time.Minute + s.Nil(p.ProposeOp(context.Background())) + + txs := <-txsCh + for i := 0; i < len(txLists); i++ { + s.Equal(txLists[i].Len(), txs[i].Len()) + } +} + +func (s *ProposerTestSuite) TestName() { + s.Equal("proposer", s.p.Name()) +} + +func (s *ProposerTestSuite) TestProposeOp() { + // Propose txs in L2 execution engine's mempool + sink := make(chan *bindings.TaikoL1ClientBlockProposed) + + sub, err := s.p.rpc.TaikoL1.WatchBlockProposed(nil, sink, nil, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + to := common.BytesToAddress(testutils.RandomBytes(32)) + _, err = testutils.SendDynamicFeeTx(s.p.rpc.L2, s.TestAddrPrivKey, &to, common.Big1, nil) + s.Nil(err) + + s.Nil(s.p.ProposeOp(context.Background())) + + event := <-sink + + s.Equal(event.Meta.Coinbase, s.p.L2SuggestedFeeRecipient) + + _, isPending, err := s.p.rpc.L1.TransactionByHash(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.False(isPending) + + receipt, err := s.p.rpc.L1.TransactionReceipt(context.Background(), event.Raw.TxHash) + s.Nil(err) + s.Equal(types.ReceiptStatusSuccessful, receipt.Status) +} + +func (s *ProposerTestSuite) TestProposeEmptyBlockOp() { + s.p.MinProposingInternal = 1 * time.Second + s.p.lastProposedAt = time.Now().Add(-10 * time.Second) + s.Nil(s.p.ProposeOp(context.Background())) +} + +func (s *ProposerTestSuite) TestAssignProverSuccessFirstRound() { + s.SetL1Automine(false) + defer s.SetL1Automine(true) + + _, _, fee, err := s.p.proverSelector.AssignProver(context.Background(), s.p.tierFees, testutils.RandomHash()) + + s.Nil(err) + s.Equal(fee.Uint64(), s.p.OptimisticTierFee.Uint64()) +} + +func (s *ProposerTestSuite) TestProposeTxLists() { + p := s.p + ctx := p.ctx + cfg := s.p.Config + + txBuilder := builder.NewBlobTransactionBuilder( + p.rpc, + p.L1ProposerPrivKey, + p.proverSelector, + p.Config.L1BlockBuilderTip, + cfg.TaikoL1Address, + cfg.L2SuggestedFeeRecipient, + cfg.AssignmentHookAddress, + cfg.ProposeBlockTxGasLimit, + cfg.ExtraData, + ) + + emptyTxListBytes, err := rlp.EncodeToBytes(types.Transactions{}) + s.Nil(err) + txListsBytes := [][]byte{emptyTxListBytes} + txCandidates := make([]txmgr.TxCandidate, len(txListsBytes)) + for i, txListBytes := range txListsBytes { + compressedTxListBytes, err := utils.Compress(txListBytes) + if err != nil { + log.Warn("Failed to compress transactions list", "index", i, "error", err) + break + } + + candidate, err := txBuilder.Build( + p.ctx, + p.tierFees, + p.IncludeParentMetaHash, + compressedTxListBytes, + ) + if err != nil { + log.Warn("Failed to build TaikoL1.proposeBlock transaction", "error", err) + break + } + + // trigger the error + candidate.Blobs = []*eth.Blob{} + candidate.GasLimit = 10000000 + + txCandidates[i] = *candidate + } + + // Send the transactions to the TaikoL1 contract, and if any of them fails, try + // to parse the custom error. + errors := p.txSender.SendAndWaitDetailed("proposeBlock", txCandidates...) + for i, err := range errors { + if err == nil { + continue + } + + // If a transaction is reverted on chain, the error string returned by txSender will like this: + // fmt.Errorf("%w purpose: %v hash: %v", ErrTransactionReverted, txPurpose, rcpt.Receipt.TxHash) + // Then we try parsing the custom error for more details in log. + if strings.Contains(err.Error(), "purpose: ") && strings.Contains(err.Error(), "hash: ") { + txHash := strings.Split(err.Error(), "hash: ")[1] + receipt, err := p.rpc.L1.TransactionReceipt(ctx, common.HexToHash(txHash)) + if err != nil { + log.Error("Failed to fetch receipt", "txHash", txHash, "error", err) + continue + } + errors[i] = encoding.TryParsingCustomErrorFromReceipt(ctx, p.rpc.L1, p.proposerAddress, receipt) + } + } + + // confirm errors handled + for _, err := range errors { + s.Equal("L1_BLOB_NOT_AVAILABLE", err.Error()) + } +} + +func (s *ProposerTestSuite) TestUpdateProposingTicker() { + s.p.ProposeInterval = 1 * time.Hour + s.NotPanics(s.p.updateProposingTicker) + + s.p.ProposeInterval = 0 + s.NotPanics(s.p.updateProposingTicker) +} + +func (s *ProposerTestSuite) TestStartClose() { + s.Nil(s.p.Start()) + s.cancel() + s.NotPanics(func() { s.p.Close(s.p.ctx) }) +} + +func TestProposerTestSuite(t *testing.T) { + suite.Run(t, new(ProposerTestSuite)) +} diff --git a/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector.go b/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector.go new file mode 100644 index 00000000000..cd3a02fe1a2 --- /dev/null +++ b/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector.go @@ -0,0 +1,283 @@ +package selector + +import ( + "context" + "errors" + "fmt" + "math/big" + "math/rand" + "net/url" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/prover/server" +) + +var ( + httpScheme = "http" + httpsScheme = "https" + errEmptyProverEndpoints = errors.New("empty prover endpoints") + errUnableToFindProver = errors.New("unable to find prover") +) + +// ETHFeeEOASelector is a prover selector implementation which use ETHs as prover fee and +// all provers selected must be EOA accounts. +type ETHFeeEOASelector struct { + protocolConfigs *bindings.TaikoDataConfig + rpc *rpc.Client + proposerAddress common.Address + taikoL1Address common.Address + assignmentHookAddress common.Address + tiersFee []encoding.TierFee + tierFeePriceBump *big.Int + proverEndpoints []*url.URL + maxTierFeePriceBumpIterations uint64 + proposalExpiry time.Duration + requestTimeout time.Duration +} + +// NewETHFeeEOASelector creates a new ETHFeeEOASelector instance. +func NewETHFeeEOASelector( + protocolConfigs *bindings.TaikoDataConfig, + rpc *rpc.Client, + proposerAddress common.Address, + taikoL1Address common.Address, + assignmentHookAddress common.Address, + tiersFee []encoding.TierFee, + tierFeePriceBump *big.Int, + proverEndpoints []*url.URL, + maxTierFeePriceBumpIterations uint64, + proposalExpiry time.Duration, + requestTimeout time.Duration, +) (*ETHFeeEOASelector, error) { + if len(proverEndpoints) == 0 { + return nil, errEmptyProverEndpoints + } + + for _, endpoint := range proverEndpoints { + if endpoint.Scheme != httpScheme && endpoint.Scheme != httpsScheme { + return nil, fmt.Errorf("invalid prover endpoint %s", endpoint) + } + } + + return ÐFeeEOASelector{ + protocolConfigs, + rpc, + proposerAddress, + taikoL1Address, + assignmentHookAddress, + tiersFee, + tierFeePriceBump, + proverEndpoints, + maxTierFeePriceBumpIterations, + proposalExpiry, + requestTimeout, + }, nil +} + +// ProverEndpoints returns all registered prover endpoints. +func (s *ETHFeeEOASelector) ProverEndpoints() []*url.URL { return s.proverEndpoints } + +// AssignProver tries to pick a prover through the registered prover endpoints. +func (s *ETHFeeEOASelector) AssignProver( + ctx context.Context, + tierFees []encoding.TierFee, + txListHash common.Hash, +) (*encoding.ProverAssignment, common.Address, *big.Int, error) { + var ( + expiry = uint64(time.Now().Add(s.proposalExpiry).Unix()) + fees = make([]encoding.TierFee, len(tierFees)) + big100 = new(big.Int).SetUint64(uint64(100)) + maxProverFee = common.Big0 + ) + + // Deep copy the tierFees slice. + for i, fee := range tierFees { + fees[i] = encoding.TierFee{Tier: fee.Tier, Fee: fee.Fee} + } + + // Iterate over each configured endpoint, and see if someone wants to accept this block. + // If it is denied, we continue on to the next endpoint. + // If we do not find a prover, we can increase the fee up to a point, or give up. + for i := 0; i < int(s.maxTierFeePriceBumpIterations); i++ { + // Bump tier fee on each failed loop. + cumulativeBumpPercent := new(big.Int).Mul(s.tierFeePriceBump, new(big.Int).SetUint64(uint64(i))) + for idx := range fees { + if i > 0 { + fee := new(big.Int).Mul(fees[idx].Fee, cumulativeBumpPercent) + fees[idx].Fee = fees[idx].Fee.Add(fees[idx].Fee, fee.Div(fee, big100)) + } + if fees[idx].Fee.Cmp(maxProverFee) > 0 { + maxProverFee = fees[idx].Fee + } + } + + // Try to assign a prover from all given endpoints. + for _, endpoint := range s.shuffleProverEndpoints() { + encodedAssignment, proverAddress, err := assignProver( + ctx, + s.protocolConfigs.ChainId, + endpoint, + expiry, + s.proposerAddress, + fees, + s.taikoL1Address, + s.assignmentHookAddress, + txListHash, + s.requestTimeout, + ) + if err != nil { + log.Warn("Failed to assign prover", "endpoint", endpoint, "error", err) + continue + } + + ok, err := rpc.CheckProverBalance( + ctx, + s.rpc, + proverAddress, + s.assignmentHookAddress, + s.protocolConfigs.LivenessBond, + ) + if err != nil { + log.Warn("Failed to check prover balance", "endpoint", endpoint, "error", err) + continue + } + if !ok { + continue + } + + return encodedAssignment, proverAddress, maxProverFee, nil + } + } + + return nil, common.Address{}, nil, errUnableToFindProver +} + +// shuffleProverEndpoints shuffles the current selector's prover endpoints. +func (s *ETHFeeEOASelector) shuffleProverEndpoints() []*url.URL { + // Clone the slice to avoid modifying the original proverEndpoints + shuffledEndpoints := make([]*url.URL, len(s.proverEndpoints)) + copy(shuffledEndpoints, s.proverEndpoints) + + rand.Shuffle(len(shuffledEndpoints), func(i, j int) { + shuffledEndpoints[i], shuffledEndpoints[j] = shuffledEndpoints[j], shuffledEndpoints[i] + }) + return shuffledEndpoints +} + +// assignProver tries to assign a proof generation task to the given prover by HTTP API. +func assignProver( + ctx context.Context, + chainID uint64, + endpoint *url.URL, + expiry uint64, + proposerAddress common.Address, + tierFees []encoding.TierFee, + taikoL1Address common.Address, + assignmentHookAddress common.Address, + txListHash common.Hash, + timeout time.Duration, +) (*encoding.ProverAssignment, common.Address, error) { + log.Info( + "Attempting to assign prover", + "endpoint", endpoint, + "expiry", expiry, + "txListHash", txListHash, + "tierFees", tierFees, + ) + + // Send the HTTP request + var ( + client = resty.New() + reqBody = &server.CreateAssignmentRequestBody{ + Proposer: proposerAddress, + FeeToken: rpc.ZeroAddress, + TierFees: tierFees, + Expiry: expiry, + BlobHash: txListHash, + } + result = server.ProposeBlockResponse{} + ) + requestURL, err := url.JoinPath(endpoint.String(), "/assignment") + if err != nil { + return nil, common.Address{}, err + } + + ctxTimeout, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + resp, err := client.R(). + SetContext(ctxTimeout). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "application/json"). + SetBody(reqBody). + SetResult(&result). + Post(requestURL) + if err != nil { + return nil, common.Address{}, err + } + if !resp.IsSuccess() { + return nil, common.Address{}, fmt.Errorf("unsuccessful response %d", resp.StatusCode()) + } + + // Ensure prover in response is the same as the one recovered + // from the signature + payload, err := encoding.EncodeProverAssignmentPayload( + chainID, + taikoL1Address, + assignmentHookAddress, + proposerAddress, + result.Prover, + txListHash, + common.Address{}, + expiry, + result.MaxBlockID, + result.MaxProposedIn, + tierFees, + ) + if err != nil { + return nil, common.Address{}, err + } + + pubKey, err := crypto.SigToPub(crypto.Keccak256Hash(payload).Bytes(), result.SignedPayload) + if err != nil { + return nil, common.Address{}, err + } + + if crypto.PubkeyToAddress(*pubKey).Hex() != result.Prover.Hex() { + return nil, common.Address{}, fmt.Errorf( + "assigned prover signature did not recover to provided prover address %s != %s", + crypto.PubkeyToAddress(*pubKey).Hex(), + result.Prover.Hex(), + ) + } + + log.Info( + "Prover assigned", + "address", result.Prover, + "endpoint", endpoint, + "tierFees", tierFees, + "maxBlockID", result.MaxBlockID, + "expiry", expiry, + ) + + // Convert signature to one solidity can recover by adding 27 to 65th byte + result.SignedPayload[64] = uint8(uint(result.SignedPayload[64])) + 27 + + return &encoding.ProverAssignment{ + FeeToken: common.Address{}, + TierFees: tierFees, + Expiry: reqBody.Expiry, + MaxBlockId: result.MaxBlockID, + MaxProposedIn: result.MaxProposedIn, + MetaHash: [32]byte{}, + Signature: result.SignedPayload, + }, result.Prover, nil +} diff --git a/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector_test.go b/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector_test.go new file mode 100644 index 00000000000..b108fd655ea --- /dev/null +++ b/packages/taiko-client/proposer/prover_selector/eth_fee_eoa_selector_test.go @@ -0,0 +1,69 @@ +package selector + +import ( + "context" + "net/url" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +type ProverSelectorTestSuite struct { + testutils.ClientTestSuite + s *ETHFeeEOASelector + proverAddress common.Address +} + +func (s *ProverSelectorTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + s.proverAddress = crypto.PubkeyToAddress(l1ProverPrivKey.PublicKey) + + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + protocolConfigs, err := s.RPCClient.TaikoL1.GetConfig(nil) + s.Nil(err) + + s.s, err = NewETHFeeEOASelector( + &protocolConfigs, + s.RPCClient, + crypto.PubkeyToAddress(l1ProposerPrivKey.PublicKey), + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + []encoding.TierFee{}, + common.Big2, + []*url.URL{s.ProverEndpoints[0]}, + 32, + 1*time.Minute, + 1*time.Minute, + ) + s.Nil(err) +} + +func (s *ProverSelectorTestSuite) TestProverEndpoints() { + s.Equal(1, len(s.s.ProverEndpoints())) +} + +func (s *ProverSelectorTestSuite) TestProverAssignProver() { + sig, _, fee, err := s.s.AssignProver(context.Background(), []encoding.TierFee{ + {Tier: encoding.TierOptimisticID, Fee: common.Big256}, + {Tier: encoding.TierSgxID, Fee: common.Big256}, + }, testutils.RandomHash()) + s.NotEmpty(sig) + s.Equal(fee.Cmp(common.Big32), 1) + s.Nil(err) +} + +func TestProverSelectorTestSuite(t *testing.T) { + suite.Run(t, new(ProverSelectorTestSuite)) +} diff --git a/packages/taiko-client/proposer/prover_selector/interface.go b/packages/taiko-client/proposer/prover_selector/interface.go new file mode 100644 index 00000000000..06c2450e1c7 --- /dev/null +++ b/packages/taiko-client/proposer/prover_selector/interface.go @@ -0,0 +1,20 @@ +package selector + +import ( + "context" + "math/big" + "net/url" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +type ProverSelector interface { + AssignProver( + ctx context.Context, + tierFees []encoding.TierFee, + txListHash common.Hash, + ) (assignment *encoding.ProverAssignment, assignedProver common.Address, fee *big.Int, err error) + ProverEndpoints() []*url.URL +} diff --git a/packages/taiko-client/proposer/transaction_builder/blob.go b/packages/taiko-client/proposer/transaction_builder/blob.go new file mode 100644 index 00000000000..db831b06d05 --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/blob.go @@ -0,0 +1,142 @@ +package builder + +import ( + "context" + "crypto/ecdsa" + "crypto/sha256" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" + selector "github.com/taikoxyz/taiko-client/proposer/prover_selector" +) + +// BlobTransactionBuilder is responsible for building a TaikoL1.proposeBlock transaction with txList +// bytes saved in blob. +type BlobTransactionBuilder struct { + rpc *rpc.Client + proposerPrivateKey *ecdsa.PrivateKey + proverSelector selector.ProverSelector + l1BlockBuilderTip *big.Int + taikoL1Address common.Address + l2SuggestedFeeRecipient common.Address + assignmentHookAddress common.Address + gasLimit uint64 + extraData string +} + +// NewBlobTransactionBuilder creates a new BlobTransactionBuilder instance based on giving configurations. +func NewBlobTransactionBuilder( + rpc *rpc.Client, + proposerPrivateKey *ecdsa.PrivateKey, + proverSelector selector.ProverSelector, + l1BlockBuilderTip *big.Int, + taikoL1Address common.Address, + l2SuggestedFeeRecipient common.Address, + assignmentHookAddress common.Address, + gasLimit uint64, + extraData string, +) *BlobTransactionBuilder { + return &BlobTransactionBuilder{ + rpc, + proposerPrivateKey, + proverSelector, + l1BlockBuilderTip, + taikoL1Address, + l2SuggestedFeeRecipient, + assignmentHookAddress, + gasLimit, + extraData, + } +} + +// Build implements the ProposeBlockTransactionBuilder interface. +func (b *BlobTransactionBuilder) Build( + ctx context.Context, + tierFees []encoding.TierFee, + includeParentMetaHash bool, + txListBytes []byte, +) (*txmgr.TxCandidate, error) { + // Make a sidecar then calculate the blob hash. + sideCar, err := rpc.MakeSidecar(txListBytes) + if err != nil { + return nil, err + } + + var blob = ð.Blob{} + if err := blob.FromData(txListBytes); err != nil { + return nil, err + } + + // Try to assign a prover. + assignment, assignedProver, maxFee, err := b.proverSelector.AssignProver( + ctx, + tierFees, + sideCar.BlobHashes()[0], + ) + if err != nil { + return nil, err + } + + // If the current proposer wants to include the parent meta hash, then fetch it from the protocol. + var parentMetaHash = [32]byte{} + if includeParentMetaHash { + if parentMetaHash, err = getParentMetaHash(ctx, b.rpc); err != nil { + return nil, err + } + } + + // Initially just use the AssignmentHook default. + hookInputData, err := encoding.EncodeAssignmentHookInput(&encoding.AssignmentHookInput{ + Assignment: assignment, + Tip: b.l1BlockBuilderTip, + }) + if err != nil { + return nil, err + } + + commitment, err := blob.ComputeKZGCommitment() + if err != nil { + return nil, err + } + blobHash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment) + + signature, err := crypto.Sign(blobHash[:], b.proposerPrivateKey) + if err != nil { + return nil, err + } + signature[64] = uint8(uint(signature[64])) + 27 + + // ABI encode the TaikoL1.proposeBlock parameters. + encodedParams, err := encoding.EncodeBlockParams(&encoding.BlockParams{ + AssignedProver: assignedProver, + ExtraData: rpc.StringToBytes32(b.extraData), + Coinbase: b.l2SuggestedFeeRecipient, + ParentMetaHash: parentMetaHash, + HookCalls: []encoding.HookCall{{Hook: b.assignmentHookAddress, Data: hookInputData}}, + Signature: signature, + }) + if err != nil { + return nil, err + } + + // Send the transaction to the L1 node. + data, err := encoding.TaikoL1ABI.Pack("proposeBlock", encodedParams, []byte{}) + if err != nil { + return nil, err + } + + return &txmgr.TxCandidate{ + TxData: data, + Blobs: []*eth.Blob{blob}, + To: &b.taikoL1Address, + GasLimit: b.gasLimit, + Value: maxFee, + }, nil +} diff --git a/packages/taiko-client/proposer/transaction_builder/calldata.go b/packages/taiko-client/proposer/transaction_builder/calldata.go new file mode 100644 index 00000000000..5af8300407d --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/calldata.go @@ -0,0 +1,122 @@ +package builder + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" + selector "github.com/taikoxyz/taiko-client/proposer/prover_selector" +) + +// CalldataTransactionBuilder is responsible for building a TaikoL1.proposeBlock transaction with txList +// bytes saved in calldata. +type CalldataTransactionBuilder struct { + rpc *rpc.Client + proposerPrivateKey *ecdsa.PrivateKey + proverSelector selector.ProverSelector + l1BlockBuilderTip *big.Int + l2SuggestedFeeRecipient common.Address + taikoL1Address common.Address + assignmentHookAddress common.Address + gasLimit uint64 + extraData string +} + +// NewCalldataTransactionBuilder creates a new CalldataTransactionBuilder instance based on giving configurations. +func NewCalldataTransactionBuilder( + rpc *rpc.Client, + proposerPrivateKey *ecdsa.PrivateKey, + proverSelector selector.ProverSelector, + l1BlockBuilderTip *big.Int, + l2SuggestedFeeRecipient common.Address, + taikoL1Address common.Address, + assignmentHookAddress common.Address, + gasLimit uint64, + extraData string, +) *CalldataTransactionBuilder { + return &CalldataTransactionBuilder{ + rpc, + proposerPrivateKey, + proverSelector, + l1BlockBuilderTip, + l2SuggestedFeeRecipient, + taikoL1Address, + assignmentHookAddress, + gasLimit, + extraData, + } +} + +// Build implements the ProposeBlockTransactionBuilder interface. +func (b *CalldataTransactionBuilder) Build( + ctx context.Context, + tierFees []encoding.TierFee, + includeParentMetaHash bool, + txListBytes []byte, +) (*txmgr.TxCandidate, error) { + // Try to assign a prover. + assignment, assignedProver, maxFee, err := b.proverSelector.AssignProver( + ctx, + tierFees, + crypto.Keccak256Hash(txListBytes), + ) + if err != nil { + return nil, err + } + + // If the current proposer wants to include the parent meta hash, then fetch it from the protocol. + var parentMetaHash = [32]byte{} + if includeParentMetaHash { + if parentMetaHash, err = getParentMetaHash(ctx, b.rpc); err != nil { + return nil, err + } + } + + // Initially just use the AssignmentHook default. + hookInputData, err := encoding.EncodeAssignmentHookInput(&encoding.AssignmentHookInput{ + Assignment: assignment, + Tip: b.l1BlockBuilderTip, + }) + if err != nil { + return nil, err + } + + signature, err := crypto.Sign(crypto.Keccak256(txListBytes), b.proposerPrivateKey) + if err != nil { + return nil, err + } + signature[64] = uint8(uint(signature[64])) + 27 + + // ABI encode the TaikoL1.proposeBlock parameters. + encodedParams, err := encoding.EncodeBlockParams(&encoding.BlockParams{ + AssignedProver: assignedProver, + Coinbase: b.l2SuggestedFeeRecipient, + ExtraData: rpc.StringToBytes32(b.extraData), + ParentMetaHash: parentMetaHash, + HookCalls: []encoding.HookCall{{Hook: b.assignmentHookAddress, Data: hookInputData}}, + Signature: signature, + }) + if err != nil { + return nil, err + } + + // Send the transaction to the L1 node. + data, err := encoding.TaikoL1ABI.Pack("proposeBlock", encodedParams, txListBytes) + if err != nil { + return nil, err + } + + return &txmgr.TxCandidate{ + TxData: data, + Blobs: nil, + To: &b.taikoL1Address, + GasLimit: b.gasLimit, + Value: maxFee, + }, nil +} diff --git a/packages/taiko-client/proposer/transaction_builder/calldata_test.go b/packages/taiko-client/proposer/transaction_builder/calldata_test.go new file mode 100644 index 00000000000..6b5e72c989e --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/calldata_test.go @@ -0,0 +1,19 @@ +package builder + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func (s *TransactionBuilderTestSuite) TestBuildCalldata() { + tx, err := s.calldataTxBuilder.Build(context.Background(), []encoding.TierFee{ + {Tier: encoding.TierOptimisticID, Fee: common.Big256}, + {Tier: encoding.TierSgxID, Fee: common.Big256}, + {Tier: encoding.TierSgxAndZkVMID, Fee: common.Big257}, + }, false, []byte{1}) + s.Nil(err) + s.Nil(tx.Blobs) +} diff --git a/packages/taiko-client/proposer/transaction_builder/common.go b/packages/taiko-client/proposer/transaction_builder/common.go new file mode 100644 index 00000000000..02340233683 --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/common.go @@ -0,0 +1,26 @@ +package builder + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// getParentMetaHash returns the meta hash of the parent block of the latest proposed block in protocol. +func getParentMetaHash(ctx context.Context, rpc *rpc.Client) (common.Hash, error) { + state, err := rpc.TaikoL1.State(&bind.CallOpts{Context: ctx}) + if err != nil { + return common.Hash{}, err + } + + parent, err := rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(state.SlotB.NumBlocks-1)) + if err != nil { + return common.Hash{}, err + } + + return parent.MetaHash, nil +} diff --git a/packages/taiko-client/proposer/transaction_builder/common_test.go b/packages/taiko-client/proposer/transaction_builder/common_test.go new file mode 100644 index 00000000000..034236d2db9 --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/common_test.go @@ -0,0 +1,80 @@ +package builder + +import ( + "context" + "net/url" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" + selector "github.com/taikoxyz/taiko-client/proposer/prover_selector" +) + +type TransactionBuilderTestSuite struct { + testutils.ClientTestSuite + calldataTxBuilder *CalldataTransactionBuilder + blobTxBuiler *BlobTransactionBuilder +} + +func (s *TransactionBuilderTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + protocolConfigs, err := s.RPCClient.TaikoL1.GetConfig(nil) + s.Nil(err) + + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + proverSelector, err := selector.NewETHFeeEOASelector( + &protocolConfigs, + s.RPCClient, + crypto.PubkeyToAddress(l1ProposerPrivKey.PublicKey), + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + []encoding.TierFee{}, + common.Big2, + []*url.URL{s.ProverEndpoints[0]}, + 32, + 1*time.Minute, + 1*time.Minute, + ) + s.Nil(err) + s.calldataTxBuilder = NewCalldataTransactionBuilder( + s.RPCClient, + l1ProposerPrivKey, + proverSelector, + common.Big0, + common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + 0, + "test", + ) + s.blobTxBuiler = NewBlobTransactionBuilder( + s.RPCClient, + l1ProposerPrivKey, + proverSelector, + common.Big0, + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + 0, + "test", + ) +} + +func (s *TransactionBuilderTestSuite) TestGetParentMetaHash() { + metahash, err := getParentMetaHash(context.Background(), s.RPCClient) + s.Nil(err) + s.NotEmpty(metahash) +} + +func TestTransactionBuilderTestSuite(t *testing.T) { + suite.Run(t, new(TransactionBuilderTestSuite)) +} diff --git a/packages/taiko-client/proposer/transaction_builder/interface.go b/packages/taiko-client/proposer/transaction_builder/interface.go new file mode 100644 index 00000000000..e9d26ed8eb8 --- /dev/null +++ b/packages/taiko-client/proposer/transaction_builder/interface.go @@ -0,0 +1,19 @@ +package builder + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +// ProposeBlockTransactionBuilder is an interface for building a TaikoL1.proposeBlock transaction. +type ProposeBlockTransactionBuilder interface { + Build( + ctx context.Context, + tierFees []encoding.TierFee, + includeParentMetaHash bool, + txListBytes []byte, + ) (*txmgr.TxCandidate, error) +} diff --git a/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator.go b/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator.go new file mode 100644 index 00000000000..54058f16e88 --- /dev/null +++ b/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator.go @@ -0,0 +1,77 @@ +package anchortxvalidator + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// AnchorTxValidator is responsible for validating the anchor transaction (TaikoL2.anchor) in +// each L2 block, which is always the first transaction. +type AnchorTxValidator struct { + taikoL2Address common.Address + goldenTouchAddress common.Address + chainID *big.Int + rpc *rpc.Client +} + +// New creates a new AnchorTxValidator instance. +func New(taikoL2Address common.Address, chainID *big.Int, rpc *rpc.Client) (*AnchorTxValidator, error) { + goldenTouchAddress, err := rpc.TaikoL2.GOLDENTOUCHADDRESS(nil) + if err != nil { + return nil, err + } + + return &AnchorTxValidator{taikoL2Address, goldenTouchAddress, chainID, rpc}, nil +} + +// ValidateAnchorTx checks whether the given transaction is a valid `TaikoL2.anchor` transaction. +func (v *AnchorTxValidator) ValidateAnchorTx(tx *types.Transaction) error { + if tx.To() == nil || *tx.To() != v.taikoL2Address { + return fmt.Errorf("invalid TaikoL2.anchor transaction to: %s, want: %s", tx.To(), v.taikoL2Address) + } + + sender, err := types.LatestSignerForChainID(v.chainID).Sender(tx) + if err != nil { + return fmt.Errorf("failed to get TaikoL2.anchor transaction sender: %w", err) + } + + if sender != v.goldenTouchAddress { + return fmt.Errorf("invalid TaikoL2.anchor transaction sender: %s", sender) + } + + method, err := encoding.TaikoL2ABI.MethodById(tx.Data()) + if err != nil || method.Name != "anchor" { + return fmt.Errorf("invalid TaikoL2.anchor transaction selector, error: %w", err) + } + + return nil +} + +// GetAndValidateAnchorTxReceipt gets and validates the `TaikoL2.anchor` transaction's receipt. +func (v *AnchorTxValidator) GetAndValidateAnchorTxReceipt( + ctx context.Context, + tx *types.Transaction, +) (*types.Receipt, error) { + receipt, err := v.rpc.L2.TransactionReceipt(ctx, tx.Hash()) + if err != nil { + return nil, fmt.Errorf("failed to get TaikoL2.anchor transaction receipt, error: %w", err) + } + + if receipt.Status != types.ReceiptStatusSuccessful { + return nil, fmt.Errorf("invalid TaikoL2.anchor transaction receipt status: %d", receipt.Status) + } + + if len(receipt.Logs) == 0 { + return nil, errors.New("no event found in TaikoL2.anchor transaction receipt") + } + + return receipt, nil +} diff --git a/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator_test.go b/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator_test.go new file mode 100644 index 00000000000..297554347c9 --- /dev/null +++ b/packages/taiko-client/prover/anchor_tx_validator/anchor_tx_validator_test.go @@ -0,0 +1,85 @@ +package anchortxvalidator + +import ( + "context" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +type AnchorTxValidatorTestSuite struct { + testutils.ClientTestSuite + v *AnchorTxValidator +} + +func (s *AnchorTxValidatorTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + validator, err := New(common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), s.RPCClient.L2.ChainID, s.RPCClient) + s.Nil(err) + s.v = validator +} + +func (s *AnchorTxValidatorTestSuite) TestValidateAnchorTx() { + wrongPrivKey, err := crypto.HexToECDSA("2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200") + s.Nil(err) + + // 0x92954368afd3caa1f3ce3ead0069c1af414054aefe1ef9aeacc1bf426222ce38 + goldenTouchPriKey, err := crypto.HexToECDSA(encoding.GoldenTouchPrivKey) + s.Nil(err) + + // invalid To + tx := types.NewTransaction( + 0, + common.BytesToAddress(testutils.RandomBytes(1024)), common.Big0, 0, common.Big0, []byte{}, + ) + s.ErrorContains(s.v.ValidateAnchorTx(tx), "invalid TaikoL2.anchor transaction to") + + // invalid sender + dynamicFeeTxTx := &types.DynamicFeeTx{ + ChainID: s.v.rpc.L2.ChainID, + Nonce: 0, + GasTipCap: common.Big1, + GasFeeCap: common.Big1, + Gas: 1, + To: &s.v.taikoL2Address, + Value: common.Big0, + Data: []byte{}, + AccessList: types.AccessList{}, + } + + signer := types.LatestSignerForChainID(s.v.rpc.L2.ChainID) + tx = types.MustSignNewTx(wrongPrivKey, signer, dynamicFeeTxTx) + + s.ErrorContains( + s.v.ValidateAnchorTx(tx), "invalid TaikoL2.anchor transaction sender", + ) + + // invalid method selector + tx = types.MustSignNewTx(goldenTouchPriKey, signer, dynamicFeeTxTx) + s.ErrorContains(s.v.ValidateAnchorTx(tx), "invalid TaikoL2.anchor transaction selector") +} + +func (s *AnchorTxValidatorTestSuite) TestGetAndValidateAnchorTxReceipt() { + tx := types.NewTransaction( + 100, + common.BytesToAddress(testutils.RandomBytes(32)), + common.Big1, + 100000, + common.Big1, + []byte{}, + ) + _, err := s.v.GetAndValidateAnchorTxReceipt(context.Background(), tx) + s.NotNil(err) +} + +func TestAnchorTxValidatorTestSuite(t *testing.T) { + suite.Run(t, new(AnchorTxValidatorTestSuite)) +} diff --git a/packages/taiko-client/prover/config.go b/packages/taiko-client/prover/config.go new file mode 100644 index 00000000000..fc3150a0fc2 --- /dev/null +++ b/packages/taiko-client/prover/config.go @@ -0,0 +1,214 @@ +package prover + +import ( + "crypto/ecdsa" + "errors" + "fmt" + "math/big" + "net/url" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/internal/utils" + + pkgFlags "github.com/taikoxyz/taiko-client/pkg/flags" +) + +// Config contains the configurations to initialize a Taiko prover. +type Config struct { + L1WsEndpoint string + L1HttpEndpoint string + L1BeaconEndpoint string + L2WsEndpoint string + L2HttpEndpoint string + TaikoL1Address common.Address + TaikoL2Address common.Address + TaikoTokenAddress common.Address + AssignmentHookAddress common.Address + L1ProverPrivKey *ecdsa.PrivateKey + StartingBlockID *big.Int + Dummy bool + GuardianProverAddress common.Address + GuardianProofSubmissionDelay time.Duration + Graffiti string + BackOffMaxRetries uint64 + BackOffRetryInterval time.Duration + ProveUnassignedBlocks bool + ContesterMode bool + EnableLivenessBondProof bool + RPCTimeout time.Duration + ProveBlockGasLimit uint64 + HTTPServerPort uint64 + Capacity uint64 + MinOptimisticTierFee *big.Int + MinSgxTierFee *big.Int + MinSgxAndZkVMTierFee *big.Int + MinEthBalance *big.Int + MinTaikoTokenBalance *big.Int + MaxExpiry time.Duration + MaxProposedIn uint64 + MaxBlockSlippage uint64 + Allowance *big.Int + GuardianProverHealthCheckServerEndpoint *url.URL + RaikoHostEndpoint string + RaikoL1Endpoint string + RaikoL1BeaconEndpoint string + RaikoL2Endpoint string + L1NodeVersion string + L2NodeVersion string + BlockConfirmations uint64 + TxmgrConfigs *txmgr.CLIConfig +} + +// NewConfigFromCliContext creates a new config instance from command line flags. +func NewConfigFromCliContext(c *cli.Context) (*Config, error) { + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(c.String(flags.L1ProverPrivKey.Name))) + if err != nil { + return nil, fmt.Errorf("invalid L1 prover private key: %w", err) + } + + if !c.IsSet(flags.L1BeaconEndpoint.Name) { + return nil, errors.New("empty L1 beacon endpoint") + } + + var startingBlockID *big.Int + if c.IsSet(flags.StartingBlockID.Name) { + startingBlockID = new(big.Int).SetUint64(c.Uint64(flags.StartingBlockID.Name)) + } + + var allowance = common.Big0 + if c.IsSet(flags.Allowance.Name) { + amt, err := utils.EtherToWei(c.Float64(flags.Allowance.Name)) + if err != nil { + return nil, fmt.Errorf("invalid setting allowance config value: %v", c.Float64(flags.Allowance.Name)) + } + + allowance = amt + } + + var guardianProverHealthCheckServerEndpoint *url.URL + if c.IsSet(flags.GuardianProverHealthCheckServerEndpoint.Name) { + if guardianProverHealthCheckServerEndpoint, err = url.Parse( + c.String(flags.GuardianProverHealthCheckServerEndpoint.Name), + ); err != nil { + return nil, err + } + } + + // If we are running a guardian prover, we need to prove unassigned blocks and run in contester mode by default. + if c.IsSet(flags.GuardianProver.Name) { + if err := c.Set(flags.ProveUnassignedBlocks.Name, "true"); err != nil { + return nil, err + } + if err := c.Set(flags.ContesterMode.Name, "true"); err != nil { + return nil, err + } + + // L1 and L2 node version flags are required only if guardian prover + if !c.IsSet(flags.L1NodeVersion.Name) { + return nil, errors.New("--prover.l1NodeVersion flag is required if guardian prover is set") + } + if !c.IsSet(flags.L2NodeVersion.Name) { + return nil, errors.New("--prover.l2NodeVersion flag is required if guardian prover is set") + } + } + + // If we are not running a guardian prover, a raiko host endpoint is required. + if !c.IsSet(flags.GuardianProver.Name) && !c.IsSet(flags.RaikoHostEndpoint.Name) { + return nil, errors.New("raiko host not provided") + } + + var ( + raikoL1Endpoint = c.String(flags.RaikoL1Endpoint.Name) + raikoL1BeaconEndpoint = c.String(flags.RaikoL1BeaconEndpoint.Name) + raikoL2Endpoint = c.String(flags.RaikoL2Endpoint.Name) + ) + if raikoL1Endpoint == "" { + raikoL1Endpoint = c.String(flags.L1HTTPEndpoint.Name) + } + if raikoL1BeaconEndpoint == "" { + raikoL1BeaconEndpoint = c.String(flags.L1BeaconEndpoint.Name) + } + if raikoL2Endpoint == "" { + raikoL2Endpoint = c.String(flags.L2HTTPEndpoint.Name) + } + + minOptimisticTierFee, err := utils.GWeiToWei(c.Float64(flags.MinOptimisticTierFee.Name)) + if err != nil { + return nil, err + } + + minSgxTierFee, err := utils.GWeiToWei(c.Float64(flags.MinSgxTierFee.Name)) + if err != nil { + return nil, err + } + + minSgxAndZkVMTierFee, err := utils.GWeiToWei(c.Float64(flags.MinSgxAndZkVMTierFee.Name)) + if err != nil { + return nil, err + } + + minEthBalance, err := utils.EtherToWei(c.Float64(flags.MinEthBalance.Name)) + if err != nil { + return nil, err + } + + minTaikoTokenBalance, err := utils.EtherToWei(c.Float64(flags.MinTaikoTokenBalance.Name)) + if err != nil { + return nil, err + } + + return &Config{ + L1WsEndpoint: c.String(flags.L1WSEndpoint.Name), + L1HttpEndpoint: c.String(flags.L1HTTPEndpoint.Name), + L1BeaconEndpoint: c.String(flags.L1BeaconEndpoint.Name), + L2WsEndpoint: c.String(flags.L2WSEndpoint.Name), + L2HttpEndpoint: c.String(flags.L2HTTPEndpoint.Name), + TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)), + TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)), + TaikoTokenAddress: common.HexToAddress(c.String(flags.TaikoTokenAddress.Name)), + AssignmentHookAddress: common.HexToAddress(c.String(flags.AssignmentHookAddress.Name)), + L1ProverPrivKey: l1ProverPrivKey, + RaikoHostEndpoint: c.String(flags.RaikoHostEndpoint.Name), + RaikoL1Endpoint: raikoL1Endpoint, + RaikoL1BeaconEndpoint: raikoL1BeaconEndpoint, + RaikoL2Endpoint: raikoL2Endpoint, + StartingBlockID: startingBlockID, + Dummy: c.Bool(flags.Dummy.Name), + GuardianProverAddress: common.HexToAddress(c.String(flags.GuardianProver.Name)), + GuardianProofSubmissionDelay: c.Duration(flags.GuardianProofSubmissionDelay.Name), + GuardianProverHealthCheckServerEndpoint: guardianProverHealthCheckServerEndpoint, + Graffiti: c.String(flags.Graffiti.Name), + BackOffMaxRetries: c.Uint64(flags.BackOffMaxRetries.Name), + BackOffRetryInterval: c.Duration(flags.BackOffRetryInterval.Name), + ProveUnassignedBlocks: c.Bool(flags.ProveUnassignedBlocks.Name), + ContesterMode: c.Bool(flags.ContesterMode.Name), + EnableLivenessBondProof: c.Bool(flags.EnableLivenessBondProof.Name), + RPCTimeout: c.Duration(flags.RPCTimeout.Name), + ProveBlockGasLimit: c.Uint64(flags.TxGasLimit.Name), + Capacity: c.Uint64(flags.ProverCapacity.Name), + HTTPServerPort: c.Uint64(flags.ProverHTTPServerPort.Name), + MinOptimisticTierFee: minOptimisticTierFee, + MinSgxTierFee: minSgxTierFee, + MinSgxAndZkVMTierFee: minSgxAndZkVMTierFee, + MinEthBalance: minEthBalance, + MinTaikoTokenBalance: minTaikoTokenBalance, + MaxExpiry: c.Duration(flags.MaxExpiry.Name), + MaxBlockSlippage: c.Uint64(flags.MaxAcceptableBlockSlippage.Name), + MaxProposedIn: c.Uint64(flags.MaxProposedIn.Name), + Allowance: allowance, + L1NodeVersion: c.String(flags.L1NodeVersion.Name), + L2NodeVersion: c.String(flags.L2NodeVersion.Name), + BlockConfirmations: c.Uint64(flags.BlockConfirmations.Name), + TxmgrConfigs: pkgFlags.InitTxmgrConfigsFromCli( + c.String(flags.L1HTTPEndpoint.Name), + l1ProverPrivKey, + c, + ), + }, nil +} diff --git a/packages/taiko-client/prover/config_test.go b/packages/taiko-client/prover/config_test.go new file mode 100644 index 00000000000..3d8da7f1d41 --- /dev/null +++ b/packages/taiko-client/prover/config_test.go @@ -0,0 +1,141 @@ +package prover + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/cmd/flags" + "github.com/taikoxyz/taiko-client/internal/utils" +) + +var ( + l1WsEndpoint = os.Getenv("L1_NODE_WS_ENDPOINT") + l1HttpEndpoint = os.Getenv("L1_NODE_HTTP_ENDPOINT") + l1BeaconEndpoint = os.Getenv("L1_NODE_HTTP_ENDPOINT") + l2WsEndpoint = os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT") + l2HttpEndpoint = os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT") + l1NodeVersion = "1.0.0" + l2NodeVersion = "0.1.0" + taikoL1 = os.Getenv("TAIKO_L1_ADDRESS") + taikoL2 = os.Getenv("TAIKO_L2_ADDRESS") + allowance = 10.0 + rpcTimeout = 5 * time.Second + minTierFee = 1024.0 +) + +func (s *ProverTestSuite) TestNewConfigFromCliContextGuardianProver() { + app := s.SetupApp() + app.Action = func(ctx *cli.Context) error { + c, err := NewConfigFromCliContext(ctx) + s.Nil(err) + s.Equal(l1WsEndpoint, c.L1WsEndpoint) + s.Equal(l1HttpEndpoint, c.L1HttpEndpoint) + s.Equal(l1BeaconEndpoint, c.L1BeaconEndpoint) + s.Equal(l2WsEndpoint, c.L2WsEndpoint) + s.Equal(l2HttpEndpoint, c.L2HttpEndpoint) + s.Equal(taikoL1, c.TaikoL1Address.String()) + s.Equal(taikoL2, c.TaikoL2Address.String()) + s.Equal( + crypto.PubkeyToAddress(s.p.cfg.L1ProverPrivKey.PublicKey), + crypto.PubkeyToAddress(c.L1ProverPrivKey.PublicKey), + ) + s.True(c.Dummy) + s.Equal("", c.Graffiti) + s.True(c.ProveUnassignedBlocks) + s.True(c.ContesterMode) + s.Equal(rpcTimeout, c.RPCTimeout) + s.Equal(uint64(8), c.Capacity) + tierFeeGWei, err := utils.GWeiToWei(minTierFee) + s.Nil(err) + s.Equal(tierFeeGWei.Uint64(), c.MinOptimisticTierFee.Uint64()) + s.Equal(tierFeeGWei.Uint64(), c.MinSgxTierFee.Uint64()) + s.Equal(c.L1NodeVersion, l1NodeVersion) + s.Equal(c.L2NodeVersion, l2NodeVersion) + s.Nil(new(Prover).InitFromCli(context.Background(), ctx)) + s.True(c.ProveUnassignedBlocks) + s.Equal(uint64(100), c.MaxProposedIn) + s.Equal(os.Getenv("ASSIGNMENT_HOOK_ADDRESS"), c.AssignmentHookAddress.String()) + allowanceWithDecimal, err := utils.EtherToWei(allowance) + s.Nil(err) + s.Equal(allowanceWithDecimal.Uint64(), c.Allowance.Uint64()) + + return err + } + + s.Nil(app.Run([]string{ + "TestNewConfigFromCliContextGuardianProver", + "--" + flags.L1WSEndpoint.Name, l1WsEndpoint, + "--" + flags.L1HTTPEndpoint.Name, l1HttpEndpoint, + "--" + flags.L1BeaconEndpoint.Name, l1BeaconEndpoint, + "--" + flags.L2WSEndpoint.Name, l2WsEndpoint, + "--" + flags.L2HTTPEndpoint.Name, l2HttpEndpoint, + "--" + flags.TaikoL1Address.Name, taikoL1, + "--" + flags.TaikoL2Address.Name, taikoL2, + "--" + flags.L1ProverPrivKey.Name, os.Getenv("L1_PROVER_PRIVATE_KEY"), + "--" + flags.StartingBlockID.Name, "0", + "--" + flags.RPCTimeout.Name, "5s", + "--" + flags.TxGasLimit.Name, "100000", + "--" + flags.Dummy.Name, + "--" + flags.MinOptimisticTierFee.Name, fmt.Sprint(minTierFee), + "--" + flags.MinSgxTierFee.Name, fmt.Sprint(minTierFee), + "--" + flags.ProverCapacity.Name, "8", + "--" + flags.GuardianProver.Name, os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS"), + "--" + flags.AssignmentHookAddress.Name, os.Getenv("ASSIGNMENT_HOOK_ADDRESS"), + "--" + flags.Graffiti.Name, "", + "--" + flags.ProveUnassignedBlocks.Name, + "--" + flags.MaxProposedIn.Name, "100", + "--" + flags.Allowance.Name, fmt.Sprint(allowance), + "--" + flags.L1NodeVersion.Name, l1NodeVersion, + "--" + flags.L2NodeVersion.Name, l2NodeVersion, + })) +} + +func (s *ProverTestSuite) TestNewConfigFromCliContextProverKeyError() { + app := s.SetupApp() + + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContext", + "--" + flags.L1ProverPrivKey.Name, "0x", + }), "invalid L1 prover private key") +} + +func (s *ProverTestSuite) SetupApp() *cli.App { + app := cli.NewApp() + app.Flags = []cli.Flag{ + &cli.StringFlag{Name: flags.L1WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L1HTTPEndpoint.Name}, + &cli.StringFlag{Name: flags.L1BeaconEndpoint.Name}, + &cli.StringFlag{Name: flags.L2WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L2HTTPEndpoint.Name}, + &cli.StringFlag{Name: flags.TaikoL1Address.Name}, + &cli.StringFlag{Name: flags.TaikoL2Address.Name}, + &cli.StringFlag{Name: flags.L1ProverPrivKey.Name}, + &cli.Uint64Flag{Name: flags.StartingBlockID.Name}, + &cli.BoolFlag{Name: flags.Dummy.Name}, + &cli.StringFlag{Name: flags.GuardianProver.Name}, + &cli.StringFlag{Name: flags.Graffiti.Name}, + &cli.BoolFlag{Name: flags.ProveUnassignedBlocks.Name}, + &cli.DurationFlag{Name: flags.RPCTimeout.Name}, + &cli.Uint64Flag{Name: flags.ProverCapacity.Name}, + &cli.Uint64Flag{Name: flags.MinOptimisticTierFee.Name}, + &cli.Uint64Flag{Name: flags.MinSgxTierFee.Name}, + &cli.Uint64Flag{Name: flags.MaxProposedIn.Name}, + &cli.StringFlag{Name: flags.AssignmentHookAddress.Name}, + &cli.StringFlag{Name: flags.Allowance.Name}, + &cli.StringFlag{Name: flags.ContesterMode.Name}, + &cli.StringFlag{Name: flags.L1NodeVersion.Name}, + &cli.StringFlag{Name: flags.L2NodeVersion.Name}, + } + app.Flags = append(app.Flags, flags.TxmgrFlags...) + app.Action = func(ctx *cli.Context) error { + _, err := NewConfigFromCliContext(ctx) + s.NotNil(err) + return err + } + return app +} diff --git a/packages/taiko-client/prover/event_handler/assignment_expired.go b/packages/taiko-client/prover/event_handler/assignment_expired.go new file mode 100644 index 00000000000..ddfac1aae9b --- /dev/null +++ b/packages/taiko-client/prover/event_handler/assignment_expired.go @@ -0,0 +1,83 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// AssignmentExpiredEventHandler is responsible for handling the expiration of proof assignments. +type AssignmentExpiredEventHandler struct { + rpc *rpc.Client + proverAddress common.Address + proofSubmissionCh chan<- *proofProducer.ProofRequestBody + proofContestCh chan<- *proofProducer.ContestRequestBody + contesterMode bool +} + +// NewAssignmentExpiredEventHandler creates a new AssignmentExpiredEventHandler instance. +func NewAssignmentExpiredEventHandler( + rpc *rpc.Client, + proverAddress common.Address, + proofSubmissionCh chan *proofProducer.ProofRequestBody, + proofContestCh chan *proofProducer.ContestRequestBody, + contesterMode bool, +) *AssignmentExpiredEventHandler { + return &AssignmentExpiredEventHandler{rpc, proverAddress, proofSubmissionCh, proofContestCh, contesterMode} +} + +// Handle implements the AssignmentExpiredHandler interface. +func (h *AssignmentExpiredEventHandler) Handle( + ctx context.Context, + e *bindings.TaikoL1ClientBlockProposed, +) error { + log.Info( + "Proof assignment window is expired", + "blockID", e.BlockId, + "assignedProver", e.AssignedProver, + "minTier", e.Meta.MinTier, + ) + + // Check if we still need to generate a new proof for that block. + proofStatus, err := rpc.GetBlockProofStatus(ctx, h.rpc, e.BlockId, h.proverAddress) + if err != nil { + return err + } + if !proofStatus.IsSubmitted { + go func() { + h.proofSubmissionCh <- &proofProducer.ProofRequestBody{Tier: e.Meta.MinTier, Event: e} + }() + return nil + } + // If there is already a proof submitted and there is no need to contest + // it, we skip proving this block here. + if !proofStatus.Invalid || !h.contesterMode { + return nil + } + + // If there is no contester, we submit a contest to protocol. + go func() { + if proofStatus.CurrentTransitionState.Contester == rpc.ZeroAddress { + h.proofContestCh <- &proofProducer.ContestRequestBody{ + BlockID: e.BlockId, + ProposedIn: new(big.Int).SetUint64(e.Raw.BlockNumber), + ParentHash: proofStatus.ParentHeader.Hash(), + Meta: &e.Meta, + Tier: proofStatus.CurrentTransitionState.Tier, + } + } else { + h.proofSubmissionCh <- &proofProducer.ProofRequestBody{ + Tier: proofStatus.CurrentTransitionState.Tier + 1, + Event: e, + } + } + }() + + return nil +} diff --git a/packages/taiko-client/prover/event_handler/block_proposed.go b/packages/taiko-client/prover/event_handler/block_proposed.go new file mode 100644 index 00000000000..7192be5a27b --- /dev/null +++ b/packages/taiko-client/prover/event_handler/block_proposed.go @@ -0,0 +1,415 @@ +package handler + +import ( + "context" + "crypto/rand" + "errors" + "fmt" + "math/big" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/internal/utils" + eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" + "github.com/taikoxyz/taiko-client/pkg/rpc" + guardianProverHeartbeater "github.com/taikoxyz/taiko-client/prover/guardian_prover_heartbeater" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + state "github.com/taikoxyz/taiko-client/prover/shared_state" +) + +var ( + errL1Reorged = errors.New("L1 reorged") + proofExpirationDelay = 6 * 12 * time.Second // 6 ethereum blocks + submissionDelayRandomBumpRange float64 = 20 +) + +// BlockProposedEventHandler is responsible for handling the BlockProposed event as a prover. +type BlockProposedEventHandler struct { + sharedState *state.SharedState + proverAddress common.Address + genesisHeightL1 uint64 + rpc *rpc.Client + proofGenerationCh chan<- *proofProducer.ProofWithHeader + assignmentExpiredCh chan<- *bindings.TaikoL1ClientBlockProposed + proofSubmissionCh chan<- *proofProducer.ProofRequestBody + proofContestCh chan<- *proofProducer.ContestRequestBody + backOffRetryInterval time.Duration + backOffMaxRetrys uint64 + contesterMode bool + proveUnassignedBlocks bool + tierToOverride uint16 + submissionDelay time.Duration +} + +// NewBlockProposedEventHandlerOps is the options for creating a new BlockProposedEventHandler. +type NewBlockProposedEventHandlerOps struct { + SharedState *state.SharedState + ProverAddress common.Address + GenesisHeightL1 uint64 + RPC *rpc.Client + ProofGenerationCh chan *proofProducer.ProofWithHeader + AssignmentExpiredCh chan *bindings.TaikoL1ClientBlockProposed + ProofSubmissionCh chan *proofProducer.ProofRequestBody + ProofContestCh chan *proofProducer.ContestRequestBody + BackOffRetryInterval time.Duration + BackOffMaxRetrys uint64 + ContesterMode bool + ProveUnassignedBlocks bool + SubmissionDelay time.Duration +} + +// NewBlockProposedEventHandler creates a new BlockProposedEventHandler instance. +func NewBlockProposedEventHandler(opts *NewBlockProposedEventHandlerOps) *BlockProposedEventHandler { + return &BlockProposedEventHandler{ + opts.SharedState, + opts.ProverAddress, + opts.GenesisHeightL1, + opts.RPC, + opts.ProofGenerationCh, + opts.AssignmentExpiredCh, + opts.ProofSubmissionCh, + opts.ProofContestCh, + opts.BackOffRetryInterval, + opts.BackOffMaxRetrys, + opts.ContesterMode, + opts.ProveUnassignedBlocks, + 0, + opts.SubmissionDelay, + } +} + +// Handle implements the BlockProposedHandler interface. +func (h *BlockProposedEventHandler) Handle( + ctx context.Context, + e *bindings.TaikoL1ClientBlockProposed, + end eventIterator.EndBlockProposedEventIterFunc, +) error { + // If there are newly generated proofs, we need to submit them as soon as possible, + // to avoid proof submission timeout. + if len(h.proofGenerationCh) > 0 { + log.Info("onBlockProposed callback early return", "proofGenerationChannelLength", len(h.proofGenerationCh)) + end() + return nil + } + + // Wait for the corresponding L2 block being mined in node. + if _, err := h.rpc.WaitL2Header(ctx, e.BlockId); err != nil { + return fmt.Errorf("failed to wait L2 header (eventID %d): %w", e.BlockId, err) + } + + // Check if the L1 chain has reorged at first. + if err := h.checkL1Reorg(ctx, e); err != nil { + if err.Error() == errL1Reorged.Error() { + end() + return nil + } + + return err + } + + // If the current block is handled, just skip it. + if e.BlockId.Uint64() <= h.sharedState.GetLastHandledBlockID() { + return nil + } + + log.Info( + "New BlockProposed event", + "l1Height", e.Raw.BlockNumber, + "l1Hash", e.Raw.BlockHash, + "blockID", e.BlockId, + "removed", e.Raw.Removed, + "assignedProver", e.AssignedProver, + "blobHash", common.Bytes2Hex(e.Meta.BlobHash[:]), + "livenessBond", utils.WeiToEther(e.LivenessBond), + "minTier", e.Meta.MinTier, + "blobUsed", e.Meta.BlobUsed, + ) + metrics.ProverReceivedProposedBlockGauge.Set(float64(e.BlockId.Uint64())) + + // Move l1Current cursor. + newL1Current, err := h.rpc.L1.HeaderByHash(ctx, e.Raw.BlockHash) + if err != nil { + return err + } + h.sharedState.SetL1Current(newL1Current) + h.sharedState.SetLastHandledBlockID(e.BlockId.Uint64()) + + // Try generating a proof for the proposed block with the given backoff policy. + go func() { + if err := backoff.Retry( + func() error { + if err := h.checkExpirationAndSubmitProof(ctx, e); err != nil { + log.Error( + "Failed to check proof status and submit proof", + "error", err, + "blockID", e.BlockId, + "minTier", e.Meta.MinTier, + "maxRetrys", h.backOffMaxRetrys, + ) + return err + } + return nil + }, + backoff.WithContext( + backoff.WithMaxRetries(backoff.NewConstantBackOff(h.backOffRetryInterval), h.backOffMaxRetrys), + ctx, + ), + ); err != nil { + log.Error("Handle new BlockProposed event error", "error", err) + } + }() + + return nil +} + +// checkL1Reorg checks whether the L1 chain has been reorged. +func (h *BlockProposedEventHandler) checkL1Reorg( + ctx context.Context, + e *bindings.TaikoL1ClientBlockProposed, +) error { + // Check whether the L2 EE's anchored L1 info, to see if the L1 chain has been reorged. + reorgCheckResult, err := h.rpc.CheckL1Reorg( + ctx, + new(big.Int).Sub(e.BlockId, common.Big1), + ) + if err != nil { + return fmt.Errorf("failed to check whether L1 chain was reorged from L2EE (eventID %d): %w", e.BlockId, err) + } + + if reorgCheckResult.IsReorged { + log.Info( + "Reset L1Current cursor due to reorg", + "l1CurrentHeightOld", h.sharedState.GetL1Current().Number, + "l1CurrentHeightNew", reorgCheckResult.L1CurrentToReset.Number, + "lastHandledBlockIDOld", h.sharedState.GetLastHandledBlockID(), + "lastHandledBlockIDNew", reorgCheckResult.LastHandledBlockIDToReset, + ) + h.sharedState.SetL1Current(reorgCheckResult.L1CurrentToReset) + if reorgCheckResult.LastHandledBlockIDToReset == nil { + h.sharedState.SetLastHandledBlockID(0) + } else { + h.sharedState.SetLastHandledBlockID(reorgCheckResult.LastHandledBlockIDToReset.Uint64()) + } + return errL1Reorged + } + + lastL1OriginHeader, err := h.rpc.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(e.Meta.L1Height)) + if err != nil { + return fmt.Errorf("failed to get L1 header, height %d: %w", e.Meta.L1Height, err) + } + + if lastL1OriginHeader.Hash() != e.Meta.L1Hash { + log.Warn( + "L1 block hash mismatch due to L1 reorg", + "height", e.Meta.L1Height, + "lastL1OriginHeader", lastL1OriginHeader.Hash(), + "l1HashInEvent", e.Meta.L1Hash, + ) + + return fmt.Errorf( + "L1 block hash mismatch due to L1 reorg: %s != %s", + lastL1OriginHeader.Hash(), + e.Meta.L1Hash, + ) + } + + return nil +} + +// getRandomBumpedSubmissionDelay returns a random bumped submission delay. +func (h *BlockProposedEventHandler) getRandomBumpedSubmissionDelay(expiredAt time.Time) (time.Duration, error) { + if h.submissionDelay == 0 { + return h.submissionDelay, nil + } + + randomBump, err := rand.Int( + rand.Reader, + new(big.Int).SetUint64(uint64(h.submissionDelay.Seconds()*submissionDelayRandomBumpRange/100)), + ) + if err != nil { + return 0, err + } + + delay := time.Duration(h.submissionDelay.Seconds()+float64(randomBump.Uint64())) * time.Second + + if time.Since(expiredAt) >= delay { + return 0, nil + } + + return delay - time.Since(expiredAt), nil +} + +// checkExpirationAndSubmitProof checks whether the proposed block's proving window is expired, +// and submits a new proof if necessary. +func (h *BlockProposedEventHandler) checkExpirationAndSubmitProof( + ctx context.Context, + e *bindings.TaikoL1ClientBlockProposed, +) error { + // Check whether the block has been verified. + isVerified, err := isBlockVerified(ctx, h.rpc, e.BlockId) + if err != nil { + return fmt.Errorf("failed to check if the current L2 block is verified: %w", err) + } + if isVerified { + log.Info("📋 Block has been verified", "blockID", e.BlockId) + return nil + } + + // Check whether the block's proof is still needed. + proofStatus, err := rpc.GetBlockProofStatus( + ctx, + h.rpc, + e.BlockId, + h.proverAddress, + ) + if err != nil { + return fmt.Errorf("failed to check whether the L2 block needs a new proof: %w", err) + } + + // If there is already a proof submitted on chain. + if proofStatus.IsSubmitted { + // If there is no need to contest the submitted proof, we skip proving this block here. + if !proofStatus.Invalid { + log.Info( + "A valid proof has been submitted, skip proving", + "blockID", e.BlockId, + "parent", proofStatus.ParentHeader.Hash(), + ) + return nil + } + + // If there is an invalid proof, but current prover is not in contest mode, we skip proving this block. + if !h.contesterMode { + log.Info( + "An invalid proof has been submitted, but current prover is not in contest mode, skip proving", + "blockID", e.BlockId, + "parent", proofStatus.ParentHeader.Hash(), + ) + return nil + } + + // The proof submitted to protocol is invalid. + h.proofContestCh <- &proofProducer.ContestRequestBody{ + BlockID: e.BlockId, + ProposedIn: new(big.Int).SetUint64(e.Raw.BlockNumber), + ParentHash: proofStatus.ParentHeader.Hash(), + Meta: &e.Meta, + Tier: e.Meta.MinTier, + } + return nil + } + + windowExpired, expiredAt, timeToExpire, err := isProvingWindowExpired(e, h.sharedState.GetTiers()) + if err != nil { + return fmt.Errorf("failed to check if the proving window is expired: %w", err) + } + + // If the proving window is not expired, we need to check if the current prover is the assigned prover, + // if no and the current prover wants to prove unassigned blocks, then we should wait for its expiration. + if !windowExpired && e.AssignedProver != h.proverAddress { + log.Info( + "Proposed block is not provable by current prover at the moment", + "blockID", e.BlockId, + "prover", e.AssignedProver, + "timeToExpire", timeToExpire, + ) + + if h.proveUnassignedBlocks { + log.Info( + "Add proposed block to wait for proof window expiration", + "blockID", e.BlockId, + "assignProver", e.AssignedProver, + "timeToExpire", timeToExpire, + ) + time.AfterFunc( + // Add another 60 seconds, to ensure one more L1 block will be mined before the proof submission + timeToExpire+proofExpirationDelay, + func() { h.assignmentExpiredCh <- e }, + ) + } + + return nil + } + + // The current prover is the assigned prover, or the proving window is expired, + // try to submit a proof for this proposed block. + tier := e.Meta.MinTier + + // Get a random bumped submission delay, if necessary. + submissionDelay, err := h.getRandomBumpedSubmissionDelay(expiredAt) + if err != nil { + return err + } + + if h.tierToOverride != 0 { + tier = h.tierToOverride + } + + log.Info( + "Proposed block is provable", + "blockID", e.BlockId, + "assignProver", e.AssignedProver, + "minTier", e.Meta.MinTier, + "submissionDelay", submissionDelay, + "tier", tier, + ) + + metrics.ProverProofsAssigned.Add(1) + + time.AfterFunc(submissionDelay, func() { + h.proofSubmissionCh <- &proofProducer.ProofRequestBody{Tier: tier, Event: e} + }) + + return nil +} + +// ========================= Guardian Prover ========================= + +// NewBlockProposedGuardianEventHandlerOps is the options for creating a new BlockProposedEventHandler. +type NewBlockProposedGuardianEventHandlerOps struct { + *NewBlockProposedEventHandlerOps + GuardianProverHeartbeater guardianProverHeartbeater.BlockSenderHeartbeater +} + +// BlockProposedGuaridanEventHandler is responsible for handling the BlockProposed event as a guardian prover. +type BlockProposedGuaridanEventHandler struct { + *BlockProposedEventHandler + GuardianProverHeartbeater guardianProverHeartbeater.BlockSenderHeartbeater +} + +// NewBlockProposedEventGuardianHandler creates a new BlockProposedEventHandler instance. +func NewBlockProposedEventGuardianHandler( + opts *NewBlockProposedGuardianEventHandlerOps, +) *BlockProposedGuaridanEventHandler { + blockProposedEventHandler := NewBlockProposedEventHandler(opts.NewBlockProposedEventHandlerOps) + // For guardian provers, we only send top tier proofs. + blockProposedEventHandler.tierToOverride = encoding.TierGuardianID + + return &BlockProposedGuaridanEventHandler{ + BlockProposedEventHandler: blockProposedEventHandler, + GuardianProverHeartbeater: opts.GuardianProverHeartbeater, + } +} + +// Handle implements the BlockProposedHandler interface. +func (h *BlockProposedGuaridanEventHandler) Handle( + ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + end eventIterator.EndBlockProposedEventIterFunc, +) error { + // If we are operating as a guardian prover, + // we should sign all seen proposed blocks as soon as possible. + go func() { + if err := h.GuardianProverHeartbeater.SignAndSendBlock(ctx, event.BlockId); err != nil { + log.Error("Guardian prover unable to sign block", "blockID", event.BlockId, "error", err) + } + }() + + return h.BlockProposedEventHandler.Handle(ctx, event, end) +} diff --git a/packages/taiko-client/prover/event_handler/block_proposed_test.go b/packages/taiko-client/prover/event_handler/block_proposed_test.go new file mode 100644 index 00000000000..f70fc1503b7 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/block_proposed_test.go @@ -0,0 +1,66 @@ +package handler + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + state "github.com/taikoxyz/taiko-client/prover/shared_state" +) + +func (s *EventHandlerTestSuite) TestBlockProposedHandle() { + opts := &NewBlockProposedEventHandlerOps{ + SharedState: &state.SharedState{}, + ProverAddress: common.Address{}, + GenesisHeightL1: 0, + RPC: s.RPCClient, + ProofGenerationCh: make(chan *proofProducer.ProofWithHeader), + AssignmentExpiredCh: make(chan *bindings.TaikoL1ClientBlockProposed), + ProofSubmissionCh: make(chan *proofProducer.ProofRequestBody), + ProofContestCh: make(chan *proofProducer.ContestRequestBody), + BackOffRetryInterval: 1 * time.Minute, + BackOffMaxRetrys: 5, + ContesterMode: true, + ProveUnassignedBlocks: true, + } + handler := NewBlockProposedEventHandler(opts) + e := s.ProposeAndInsertValidBlock(s.proposer, s.blobSyncer) + err := handler.Handle(context.Background(), e, func() {}) + s.Nil(err) +} + +func (s *EventHandlerTestSuite) TestGetRandomBumpedSubmissionDelay() { + opts := &NewBlockProposedEventHandlerOps{ + SharedState: &state.SharedState{}, + ProverAddress: common.Address{}, + GenesisHeightL1: 0, + RPC: s.RPCClient, + ProofGenerationCh: make(chan *proofProducer.ProofWithHeader), + AssignmentExpiredCh: make(chan *bindings.TaikoL1ClientBlockProposed), + ProofSubmissionCh: make(chan *proofProducer.ProofRequestBody), + ProofContestCh: make(chan *proofProducer.ContestRequestBody), + BackOffRetryInterval: 1 * time.Minute, + BackOffMaxRetrys: 5, + ContesterMode: true, + ProveUnassignedBlocks: true, + } + handler1 := NewBlockProposedEventHandler(opts) + + delay, err := handler1.getRandomBumpedSubmissionDelay(time.Now()) + s.Nil(err) + s.Zero(delay) + + opts.SubmissionDelay = 1 * time.Hour + handler2 := NewBlockProposedEventHandler(opts) + delay, err = handler2.getRandomBumpedSubmissionDelay(time.Now()) + s.Nil(err) + s.NotZero(delay) + s.Greater(delay.Seconds(), opts.SubmissionDelay.Seconds()) + s.Less( + delay.Seconds(), + opts.SubmissionDelay.Seconds()*(1+(submissionDelayRandomBumpRange/100)), + ) +} diff --git a/packages/taiko-client/prover/event_handler/block_verified.go b/packages/taiko-client/prover/event_handler/block_verified.go new file mode 100644 index 00000000000..7bb0c2ab7cf --- /dev/null +++ b/packages/taiko-client/prover/event_handler/block_verified.go @@ -0,0 +1,25 @@ +package handler + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/metrics" +) + +// BlockVerifiedEventHandler is responsible for handling the BlockVerified event. +type BlockVerifiedEventHandler struct{} + +// Handle handles the BlockVerified event. +func (h *BlockVerifiedEventHandler) Handle(e *bindings.TaikoL1ClientBlockVerified) { + metrics.ProverLatestVerifiedIDGauge.Set(float64(e.BlockId.Uint64())) + + log.Info( + "New verified block", + "blockID", e.BlockId, + "hash", common.BytesToHash(e.BlockHash[:]), + "stateRoot", common.BytesToHash(e.StateRoot[:]), + "prover", e.Prover, + ) +} diff --git a/packages/taiko-client/prover/event_handler/block_verified_test.go b/packages/taiko-client/prover/event_handler/block_verified_test.go new file mode 100644 index 00000000000..318569d3847 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/block_verified_test.go @@ -0,0 +1,22 @@ +package handler + +import ( + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +func (s *EventHandlerTestSuite) TestBlockVerifiedHandle() { + handler := &BlockVerifiedEventHandler{} + id := testutils.RandomHash().Big().Uint64() + s.NotPanics(func() { + handler.Handle(&bindings.TaikoL1ClientBlockVerified{ + BlockId: testutils.RandomHash().Big(), + Raw: types.Log{ + BlockHash: testutils.RandomHash(), + BlockNumber: id, + }, + }) + }) +} diff --git a/packages/taiko-client/prover/event_handler/interface.go b/packages/taiko-client/prover/event_handler/interface.go new file mode 100644 index 00000000000..06f42d36a95 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/interface.go @@ -0,0 +1,36 @@ +package handler + +import ( + "context" + + "github.com/taikoxyz/taiko-client/bindings" + eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" +) + +// BlockProposedHandler is the interface for handling `TaikoL1.BlockProposed` events. +type BlockProposedHandler interface { + Handle(ctx context.Context, + event *bindings.TaikoL1ClientBlockProposed, + end eventIterator.EndBlockProposedEventIterFunc, + ) error +} + +// TransitionContestedHandler is the interface for handling `TaikoL1.TransitionContested` events. +type TransitionContestedHandler interface { + Handle(ctx context.Context, event *bindings.TaikoL1ClientTransitionContested) error +} + +// TransitionProvedHandler is the interface for handling `TaikoL1.TransitionProved` events. +type TransitionProvedHandler interface { + Handle(ctx context.Context, event *bindings.TaikoL1ClientTransitionProved) error +} + +// BlockVerifiedHandler is the interface for handling `TaikoL1.BlockVerified` events. +type BlockVerifiedHandler interface { + Handle(e *bindings.TaikoL1ClientBlockVerified) +} + +// AssignmentExpiredHandler is the interface for handling the proof assignment expiration. +type AssignmentExpiredHandler interface { + Handle(ctx context.Context, event *bindings.TaikoL1ClientBlockProposed) error +} diff --git a/packages/taiko-client/prover/event_handler/transition_contested.go b/packages/taiko-client/prover/event_handler/transition_contested.go new file mode 100644 index 00000000000..5ead167697c --- /dev/null +++ b/packages/taiko-client/prover/event_handler/transition_contested.go @@ -0,0 +1,111 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// TransitionContestedEventHandler is responsible for handling the TransitionContested event. +type TransitionContestedEventHandler struct { + rpc *rpc.Client + proofSubmissionCh chan<- *proofProducer.ProofRequestBody + contesterMode bool +} + +// NewTransitionContestedEventHandler creates a new TransitionContestedEventHandler instance. +func NewTransitionContestedEventHandler( + rpc *rpc.Client, + proofSubmissionCh chan *proofProducer.ProofRequestBody, + contesterMode bool, +) *TransitionContestedEventHandler { + return &TransitionContestedEventHandler{rpc, proofSubmissionCh, contesterMode} +} + +// Handle implements the TransitionContestedHandler interface. +func (h *TransitionContestedEventHandler) Handle( + ctx context.Context, + e *bindings.TaikoL1ClientTransitionContested, +) error { + log.Info( + "🗡 Transition contested", + "blockID", e.BlockId, + "parentHash", common.Bytes2Hex(e.Tran.ParentHash[:]), + "hash", common.Bytes2Hex(e.Tran.BlockHash[:]), + "stateRoot", common.BytesToHash(e.Tran.StateRoot[:]), + "contester", e.Contester, + "bond", utils.WeiToEther(e.ContestBond), + ) + + // If this prover is not in contester mode, we simply output a log and return. + if !h.contesterMode { + return nil + } + + contestedTransition, err := h.rpc.TaikoL1.GetTransition0( + &bind.CallOpts{Context: ctx}, + e.BlockId.Uint64(), + e.Tran.ParentHash, + ) + if err != nil { + return err + } + + // Compare the contested transition to the block in local L2 canonical chain. + isValid, err := isValidProof( + ctx, + h.rpc, + e.BlockId, + e.Tran.ParentHash, + contestedTransition.BlockHash, + contestedTransition.StateRoot, + ) + if err != nil { + return err + } + if isValid { + log.Info( + "Contested transition is valid to local canonical chain, ignore the contest", + "blockID", e.BlockId, + "parentHash", common.Bytes2Hex(e.Tran.ParentHash[:]), + "hash", common.Bytes2Hex(contestedTransition.BlockHash[:]), + "stateRoot", common.BytesToHash(contestedTransition.StateRoot[:]), + "contester", e.Contester, + "bond", utils.WeiToEther(e.ContestBond), + ) + return nil + } + + // If the proof is invalid, we contest it. + blockInfo, err := h.rpc.GetL2BlockInfo(ctx, e.BlockId) + if err != nil { + return err + } + + blockProposedEvent, err := getBlockProposedEventFromBlockID( + ctx, + h.rpc, + e.BlockId, + new(big.Int).SetUint64(blockInfo.ProposedIn), + ) + if err != nil { + return err + } + + go func() { + h.proofSubmissionCh <- &proofProducer.ProofRequestBody{ + Tier: e.Tier + 1, // We need to send a higher tier proof to resolve the current contest. + Event: blockProposedEvent, + } + }() + + return nil +} diff --git a/packages/taiko-client/prover/event_handler/transition_proved.go b/packages/taiko-client/prover/event_handler/transition_proved.go new file mode 100644 index 00000000000..e75578a4595 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/transition_proved.go @@ -0,0 +1,92 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// TransitionProvedEventHandler is responsible for handling the TransitionProved event. +type TransitionProvedEventHandler struct { + rpc *rpc.Client + proofContestCh chan<- *proofProducer.ContestRequestBody + contesterMode bool +} + +// NewTransitionProvedEventHandler creates a new TransitionProvedEventHandler instance. +func NewTransitionProvedEventHandler( + rpc *rpc.Client, + proofContestCh chan *proofProducer.ContestRequestBody, + contesterMode bool, +) *TransitionProvedEventHandler { + return &TransitionProvedEventHandler{rpc, proofContestCh, contesterMode} +} + +// Handle implements the TransitionProvedHandler interface. +func (h *TransitionProvedEventHandler) Handle( + ctx context.Context, + e *bindings.TaikoL1ClientTransitionProved, +) error { + metrics.ProverReceivedProvenBlockGauge.Set(float64(e.BlockId.Uint64())) + + // If this prover is in contest mode, we check the validity of this proof and if it's invalid, + // contest it with a higher tier proof. + if !h.contesterMode { + return nil + } + + isValid, err := isValidProof( + ctx, + h.rpc, + e.BlockId, + e.Tran.ParentHash, + e.Tran.BlockHash, + e.Tran.StateRoot, + ) + if err != nil { + return err + } + // If the proof is valid, we simply return. + if isValid { + return nil + } + + // If the proof is invalid, we contest it. + blockInfo, err := h.rpc.GetL2BlockInfo(ctx, e.BlockId) + if err != nil { + return err + } + + meta, err := getMetadataFromBlockID(ctx, h.rpc, e.BlockId, new(big.Int).SetUint64(blockInfo.ProposedIn)) + if err != nil { + return err + } + + log.Info( + "Attempting to contest a proven transition", + "blockID", e.BlockId, + "l1Height", blockInfo.ProposedIn, + "tier", e.Tier, + "parentHash", common.Bytes2Hex(e.Tran.ParentHash[:]), + "blockHash", common.Bytes2Hex(e.Tran.BlockHash[:]), + "stateRoot", common.Bytes2Hex(e.Tran.StateRoot[:]), + ) + + go func() { + h.proofContestCh <- &proofProducer.ContestRequestBody{ + BlockID: e.BlockId, + ProposedIn: new(big.Int).SetUint64(blockInfo.ProposedIn), + ParentHash: e.Tran.ParentHash, + Meta: meta, + Tier: e.Tier, + } + }() + return nil +} diff --git a/packages/taiko-client/prover/event_handler/transition_proved_test.go b/packages/taiko-client/prover/event_handler/transition_proved_test.go new file mode 100644 index 00000000000..dd697715363 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/transition_proved_test.go @@ -0,0 +1,133 @@ +package handler + +import ( + "context" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/driver" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/blob" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +type EventHandlerTestSuite struct { + testutils.ClientTestSuite + d *driver.Driver + proposer *proposer.Proposer + blobSyncer *blob.Syncer +} + +func (s *EventHandlerTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + // Init driver + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + d := new(driver.Driver) + s.Nil(d.InitFromConfig(context.Background(), &driver.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + JwtSecret: string(jwtSecret), + }, + })) + s.d = d + + // Init calldata syncer + testState, err := state.New(context.Background(), s.RPCClient) + s.Nil(err) + s.Nil(testState.ResetL1Current(context.Background(), common.Big0)) + + tracker := beaconsync.NewSyncProgressTracker(s.RPCClient.L2, 30*time.Second) + s.blobSyncer, err = blob.NewSyncer( + context.Background(), + s.RPCClient, + testState, + tracker, + 0, + nil, + ) + s.Nil(err) + + // Init proposer + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + prop := new(proposer.Proposer) + + s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 1, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.proposer = prop +} + +func (s *EventHandlerTestSuite) TestTransitionProvedHandle() { + handler := NewTransitionProvedEventHandler( + s.RPCClient, + make(chan *proofProducer.ContestRequestBody), + true, + ) + e := s.ProposeAndInsertValidBlock(s.proposer, s.blobSyncer) + err := handler.Handle(context.Background(), &bindings.TaikoL1ClientTransitionProved{ + BlockId: e.BlockId, + Tier: e.Meta.MinTier, + }) + s.Nil(err) +} + +func TestTransitionProvedEventHandlerTestSuite(t *testing.T) { + suite.Run(t, new(EventHandlerTestSuite)) +} diff --git a/packages/taiko-client/prover/event_handler/util.go b/packages/taiko-client/prover/event_handler/util.go new file mode 100644 index 00000000000..b97a101879b --- /dev/null +++ b/packages/taiko-client/prover/event_handler/util.go @@ -0,0 +1,148 @@ +package handler + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +var ( + errTierNotFound = errors.New("tier not found") +) + +// isBlockVerified checks whether the given L2 block has been verified. +func isBlockVerified(ctx context.Context, rpc *rpc.Client, id *big.Int) (bool, error) { + stateVars, err := rpc.GetProtocolStateVariables(&bind.CallOpts{Context: ctx}) + if err != nil { + return false, err + } + + return id.Uint64() <= stateVars.B.LastVerifiedBlockId, nil +} + +// isValidProof checks if the given proof is a valid one, comparing to current L2 node canonical chain. +func isValidProof( + ctx context.Context, + rpc *rpc.Client, + blockID *big.Int, + parentHash common.Hash, + blockHash common.Hash, + stateRoot common.Hash, +) (bool, error) { + parent, err := rpc.L2ParentByBlockID(ctx, blockID) + if err != nil { + return false, err + } + + l2Header, err := rpc.L2.HeaderByNumber(ctx, blockID) + if err != nil { + return false, err + } + + return parent.Hash() == parentHash && + l2Header.Hash() == blockHash && + l2Header.Root == stateRoot, nil +} + +// getProvingWindow returns the provingWindow of the given proposed block. +func getProvingWindow( + e *bindings.TaikoL1ClientBlockProposed, + tiers []*rpc.TierProviderTierWithID, +) (time.Duration, error) { + for _, t := range tiers { + if e.Meta.MinTier == t.ID { + return time.Duration(t.ProvingWindow) * time.Minute, nil + } + } + + return 0, errTierNotFound +} + +// getBlockProposedEventFromBlockID fetches the BlockProposed event by the given block id. +func getBlockProposedEventFromBlockID( + ctx context.Context, + rpc *rpc.Client, + id *big.Int, + proposedIn *big.Int, +) (e *bindings.TaikoL1ClientBlockProposed, err error) { + callback := func( + _ context.Context, + event *bindings.TaikoL1ClientBlockProposed, + _ eventIterator.EndBlockProposedEventIterFunc, + ) error { + // Only filter for exact blockID we want. + if event.BlockId.Cmp(id) != 0 { + return nil + } + + e = event + + return nil + } + + iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{ + Client: rpc.L1, + TaikoL1: rpc.TaikoL1, + StartHeight: new(big.Int).Sub(proposedIn, common.Big1), + EndHeight: proposedIn, + OnBlockProposedEvent: callback, + }) + if err != nil { + log.Error("Failed to start event iterator", "event", "BlockProposed", "error", err) + return nil, err + } + + if err := iter.Iter(); err != nil { + return nil, err + } + + if e == nil { + return nil, fmt.Errorf("failed to find BlockProposed event for block %d", id) + } + + return e, nil +} + +// getMetadataFromBlockID fetches the block meta from the onchain event by the given block id. +func getMetadataFromBlockID( + ctx context.Context, + rpc *rpc.Client, + id *big.Int, + proposedIn *big.Int, +) (*bindings.TaikoDataBlockMetadata, error) { + e, err := getBlockProposedEventFromBlockID(ctx, rpc, id, proposedIn) + if err != nil { + return nil, err + } + return &e.Meta, nil +} + +// isProvingWindowExpired returns true as the first return parameter if the assigned prover +// proving window of the given proposed block is expired, and the second return parameter is the time +// remaining til proving window is expired. +func isProvingWindowExpired( + e *bindings.TaikoL1ClientBlockProposed, + tiers []*rpc.TierProviderTierWithID, +) (bool, time.Time, time.Duration, error) { + provingWindow, err := getProvingWindow(e, tiers) + if err != nil { + return false, time.Time{}, 0, fmt.Errorf("failed to get proving window: %w", err) + } + + var ( + now = uint64(time.Now().Unix()) + expiredAt = e.Meta.Timestamp + uint64(provingWindow.Seconds()) + ) + + return now > expiredAt, time.Unix(int64(expiredAt), 0), time.Duration(expiredAt-now) * time.Second, nil +} diff --git a/packages/taiko-client/prover/event_handler/util_test.go b/packages/taiko-client/prover/event_handler/util_test.go new file mode 100644 index 00000000000..3e34b5d35e5 --- /dev/null +++ b/packages/taiko-client/prover/event_handler/util_test.go @@ -0,0 +1,52 @@ +package handler + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +type ProverEventHandlerTestSuite struct { + testutils.ClientTestSuite +} + +func (s *ProverEventHandlerTestSuite) TestGetProvingWindowNotFound() { + _, err := getProvingWindow(&bindings.TaikoL1ClientBlockProposed{ + Meta: bindings.TaikoDataBlockMetadata{ + MinTier: encoding.TierGuardianID + 1, + }, + }, []*rpc.TierProviderTierWithID{}) + s.ErrorIs(err, errTierNotFound) +} + +func (s *ProverEventHandlerTestSuite) TestIsBlockVerified() { + _, slotB, err := s.RPCClient.TaikoL1.GetStateVariables(nil) + s.Nil(err) + + verified, err := isBlockVerified( + context.Background(), + s.RPCClient, + new(big.Int).SetUint64(slotB.LastVerifiedBlockId), + ) + s.Nil(err) + s.True(verified) + + verified, err = isBlockVerified( + context.Background(), + s.RPCClient, + new(big.Int).SetUint64(slotB.LastVerifiedBlockId+1), + ) + s.Nil(err) + s.False(verified) +} + +func TestProverEventHandlerTestSuite(t *testing.T) { + suite.Run(t, new(ProverEventHandlerTestSuite)) +} diff --git a/packages/taiko-client/prover/guardian.go b/packages/taiko-client/prover/guardian.go new file mode 100644 index 00000000000..c23b33e7802 --- /dev/null +++ b/packages/taiko-client/prover/guardian.go @@ -0,0 +1,58 @@ +package prover + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/log" + "golang.org/x/sync/errgroup" +) + +var ( + heartbeatInterval = 12 * time.Second +) + +// guardianProverHeartbeatLoop keeps sending heartbeats to the guardian prover health check server +// on an interval. +func (p *Prover) guardianProverHeartbeatLoop(ctx context.Context) { + p.wg.Add(1) + defer p.wg.Done() + + ticker := time.NewTicker(heartbeatInterval) + defer ticker.Stop() + + for { + select { + case <-p.ctx.Done(): + return + case <-ticker.C: + var ( + latestL1Block uint64 + latestL2Block uint64 + err error + g = new(errgroup.Group) + ) + + g.Go(func() error { + latestL1Block, err = p.rpc.L1.BlockNumber(ctx) + return err + }) + g.Go(func() error { + latestL2Block, err = p.rpc.L2.BlockNumber(ctx) + return err + }) + if err := g.Wait(); err != nil { + log.Error("Failed to get latest L1/L2 block number", "error", err) + continue + } + + if err := p.guardianProverHeartbeater.SendHeartbeat( + ctx, + latestL1Block, + latestL2Block, + ); err != nil { + log.Error("Failed to send guardian prover heartbeat", "error", err) + } + } + } +} diff --git a/packages/taiko-client/prover/guardian_prover_heartbeater/guardian_prover.go b/packages/taiko-client/prover/guardian_prover_heartbeater/guardian_prover.go new file mode 100644 index 00000000000..45a619c1a54 --- /dev/null +++ b/packages/taiko-client/prover/guardian_prover_heartbeater/guardian_prover.go @@ -0,0 +1,252 @@ +package guardianproverheartbeater + +import ( + "context" + "crypto/ecdsa" + "fmt" + "math/big" + "net/url" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// healthCheckReq is the request body sent to the health check server when a heartbeat is sent. +type healthCheckReq struct { + ProverAddress string `json:"prover"` + HeartBeatSignature []byte `json:"heartBeatSignature"` + LatestL1Block uint64 `json:"latestL1Block"` + LatestL2Block uint64 `json:"latestL2Block"` +} + +// signedBlockReq is the request body sent to the health check server when a block is signed. +type signedBlockReq struct { + BlockID uint64 `json:"blockID"` + BlockHash string `json:"blockHash"` + Signature []byte `json:"signature"` + Prover common.Address `json:"proverAddress"` +} + +// startupReq is the request body send to the health check server when the guardian prover starts up. +type startupReq struct { + ProverAddress string `json:"prover"` + GuardianVersion string `json:"guardianVersion"` + L1NodeVersion string `json:"l1NodeVersion"` + L2NodeVersion string `json:"l2NodeVersion"` + Revision string `json:"revision"` + Signature []byte `json:"signature"` +} + +// GuardianProverHeartBeater is responsible for signing and sending known blocks to the health check server. +type GuardianProverHeartBeater struct { + privateKey *ecdsa.PrivateKey + healthCheckServerEndpoint *url.URL + rpc *rpc.Client + proverAddress common.Address +} + +// New creates a new GuardianProverBlockSender instance. +func New( + privateKey *ecdsa.PrivateKey, + healthCheckServerEndpoint *url.URL, + rpc *rpc.Client, + proverAddress common.Address, +) *GuardianProverHeartBeater { + return &GuardianProverHeartBeater{ + privateKey: privateKey, + healthCheckServerEndpoint: healthCheckServerEndpoint, + rpc: rpc, + proverAddress: proverAddress, + } +} + +// post sends the given POST request to the health check server. +func (s *GuardianProverHeartBeater) post(ctx context.Context, route string, req interface{}) error { + resp, err := resty.New().R(). + SetContext(ctx). + SetHeader("Content-Type", "application/json"). + SetHeader("Accept", "application/json"). + SetBody(req). + Post(fmt.Sprintf("%v/%v", s.healthCheckServerEndpoint.String(), route)) + if err != nil { + return err + } + + if !resp.IsSuccess() { + return fmt.Errorf( + "unable to contact health check server endpoint, status code: %v", + resp.StatusCode(), + ) + } + + return nil +} + +// SignAndSendBlock signs the given block and sends it to the health check server. +func (s *GuardianProverHeartBeater) SignAndSendBlock(ctx context.Context, blockID *big.Int) error { + signed, header, err := s.signBlock(ctx, blockID) + if err != nil { + return nil + } + + if signed == nil { + return nil + } + + if err := s.sendSignedBlockReq(ctx, signed, header.Hash(), blockID); err != nil { + return err + } + + return nil +} + +// SendStartupMessage sends the startup message to the health check server. +func (s *GuardianProverHeartBeater) SendStartupMessage( + ctx context.Context, + revision string, + version string, + l1NodeVersion string, + l2NodeVersion string, +) error { + if s.healthCheckServerEndpoint == nil { + log.Warn("No health check server endpoint set, returning early") + return nil + } + + sig, err := crypto.Sign( + crypto.Keccak256Hash( + s.proverAddress.Bytes(), + []byte(revision), + []byte(version), + []byte(l1NodeVersion), + []byte(l2NodeVersion), + ).Bytes(), + s.privateKey) + if err != nil { + return err + } + + if err := s.post(ctx, "startup", &startupReq{ + Revision: revision, + GuardianVersion: version, + L1NodeVersion: l1NodeVersion, + L2NodeVersion: l2NodeVersion, + ProverAddress: s.proverAddress.Hex(), + Signature: sig, + }); err != nil { + return err + } + + log.Info( + "Guardian prover successfully sent the startup message", + "l1NodeVersion", l1NodeVersion, + "l2NodeVersion", l2NodeVersion, + ) + + return nil +} + +// sendSignedBlockReq is the actual method that sends the signed block to the health check server. +func (s *GuardianProverHeartBeater) sendSignedBlockReq( + ctx context.Context, + signed []byte, + hash common.Hash, + blockID *big.Int, +) error { + if s.healthCheckServerEndpoint == nil { + log.Info("No health check server endpoint set, returning early") + return nil + } + + req := &signedBlockReq{ + BlockID: blockID.Uint64(), + BlockHash: hash.Hex(), + Signature: signed, + Prover: s.proverAddress, + } + + if err := s.post(ctx, "signedBlock", req); err != nil { + return err + } + + log.Info("Guardian prover successfully signed block", "blockID", blockID.Uint64()) + + return nil +} + +// signBlock signs the given block and returns the signature and header. +func (s *GuardianProverHeartBeater) signBlock(ctx context.Context, blockID *big.Int) ([]byte, *types.Header, error) { + log.Info("Guardian prover signing block", "blockID", blockID.Uint64()) + + head, err := s.rpc.L2.BlockNumber(ctx) + if err != nil { + return nil, nil, err + } + + for head < blockID.Uint64() { + log.Info( + "Guardian prover block signing waiting for chain", + "latestBlock", head, + "eventBlockID", blockID.Uint64(), + ) + + if _, err := s.rpc.WaitL2Header(ctx, blockID); err != nil { + return nil, nil, err + } + + head, err = s.rpc.L2.BlockNumber(ctx) + if err != nil { + return nil, nil, err + } + } + + header, err := s.rpc.L2.HeaderByNumber(ctx, blockID) + if err != nil { + return nil, nil, err + } + + log.Info( + "Guardian prover block signing caught up", + "latestBlock", head, + "eventBlockID", blockID.Uint64(), + ) + + signed, err := crypto.Sign(header.Hash().Bytes(), s.privateKey) + if err != nil { + return nil, nil, err + } + + return signed, header, nil +} + +// SendHeartbeat sends a heartbeat to the health check server. +func (s *GuardianProverHeartBeater) SendHeartbeat( + ctx context.Context, + latestL1Block uint64, + latestL2Block uint64, +) error { + sig, err := crypto.Sign(crypto.Keccak256Hash([]byte("HEART_BEAT")).Bytes(), s.privateKey) + if err != nil { + return err + } + + req := &healthCheckReq{ + HeartBeatSignature: sig, + ProverAddress: s.proverAddress.Hex(), + LatestL1Block: latestL1Block, + LatestL2Block: latestL2Block, + } + + if err := s.post(ctx, "healthCheck", req); err != nil { + return err + } + + log.Info("Successfully sent heartbeat", "signature", common.Bytes2Hex(sig)) + + return nil +} diff --git a/packages/taiko-client/prover/guardian_prover_heartbeater/interface.go b/packages/taiko-client/prover/guardian_prover_heartbeater/interface.go new file mode 100644 index 00000000000..2f16670cf79 --- /dev/null +++ b/packages/taiko-client/prover/guardian_prover_heartbeater/interface.go @@ -0,0 +1,30 @@ +package guardianproverheartbeater + +import ( + "context" + "math/big" +) + +// BlockSigner defines an interface that communicates with a central Guardian Prover server, sending signed blocks. +type BlockSigner interface { + SignAndSendBlock(ctx context.Context, blockID *big.Int) error + SendStartupMessage( + ctx context.Context, + revision string, + version string, + l1NodeVersion string, + l2NodeVersion string, + ) error +} + +// Heartbeater defines an interface that communicates with a central Guardian Prover server, sending heartbeats. +type Heartbeater interface { + SendHeartbeat(ctx context.Context, latestL1Block uint64, latestL2Block uint64) error +} + +// BlockSenderHeartbeater defines an interface that communicates with a central Guardian Prover server, +// sending heartbeats and signed blocks (and in the future, contested blocks). +type BlockSenderHeartbeater interface { + BlockSigner + Heartbeater +} diff --git a/packages/taiko-client/prover/init.go b/packages/taiko-client/prover/init.go new file mode 100644 index 00000000000..45c8244b8eb --- /dev/null +++ b/packages/taiko-client/prover/init.go @@ -0,0 +1,245 @@ +package prover + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum" + "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/log" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/utils" + handler "github.com/taikoxyz/taiko-client/prover/event_handler" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + proofSubmitter "github.com/taikoxyz/taiko-client/prover/proof_submitter" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" +) + +// setApprovalAmount will set the allowance on the TaikoToken contract for the +// configured proverAddress as owner and the contract as spender, +// if `--prover.allowance` flag is provided for allowance. +func (p *Prover) setApprovalAmount(ctx context.Context, contract common.Address) error { + // Skip setting approval amount if `--prover.allowance` flag is not set. + if p.cfg.Allowance == nil || p.cfg.Allowance.Cmp(common.Big0) != 1 { + log.Info("Skipping setting approval, `--prover.allowance` flag not set") + return nil + } + + // Check the existing allowance for the contract. + allowance, err := p.rpc.TaikoToken.Allowance( + &bind.CallOpts{Context: ctx}, + p.ProverAddress(), + contract, + ) + if err != nil { + return err + } + + log.Info("Existing allowance for the contract", "allowance", utils.WeiToEther(allowance), "contract", contract) + + // If the existing allowance is greater or equal to the configured allowance, skip setting allowance. + if allowance.Cmp(p.cfg.Allowance) >= 0 { + log.Info( + "Skipping setting allowance, allowance already greater or equal", + "allowance", utils.WeiToEther(allowance), + "approvalAmount", p.cfg.Allowance, + "contract", contract, + ) + return nil + } + + log.Info("Approving the contract for taiko token", "allowance", p.cfg.Allowance, "contract", contract) + data, err := encoding.TaikoTokenABI.Pack("approve", contract, p.cfg.Allowance) + if err != nil { + return err + } + + receipt, err := p.txmgr.Send(ctx, txmgr.TxCandidate{ + TxData: data, + To: &p.cfg.TaikoTokenAddress, + }) + if err != nil { + return err + } + if receipt.Status != types.ReceiptStatusSuccessful { + return fmt.Errorf("failed to approve allowance for contract (%s): %s", contract, receipt.TxHash.Hex()) + } + + log.Info( + "Approved the contract for taiko token", + "txHash", receipt.TxHash.Hex(), + "contract", contract, + ) + + // Check the new allowance for the contract. + if allowance, err = p.rpc.TaikoToken.Allowance( + &bind.CallOpts{Context: ctx}, + p.ProverAddress(), + contract, + ); err != nil { + return err + } + + log.Info("New allowance for the contract", "allowance", utils.WeiToEther(allowance), "contract", contract) + + return nil +} + +// initProofSubmitters initializes the proof submitters from the given tiers in protocol. +func (p *Prover) initProofSubmitters( + txmgr *txmgr.SimpleTxManager, + txBuilder *transaction.ProveBlockTxBuilder, +) error { + for _, tier := range p.sharedState.GetTiers() { + var ( + producer proofProducer.ProofProducer + submitter proofSubmitter.Submitter + err error + ) + switch tier.ID { + case encoding.TierOptimisticID: + producer = &proofProducer.OptimisticProofProducer{} + case encoding.TierSgxID: + producer = &proofProducer.SGXProofProducer{ + RaikoHostEndpoint: p.cfg.RaikoHostEndpoint, + L1Endpoint: p.cfg.RaikoL1Endpoint, + L1BeaconEndpoint: p.cfg.RaikoL1BeaconEndpoint, + L2Endpoint: p.cfg.RaikoL2Endpoint, + Dummy: p.cfg.Dummy, + } + case encoding.TierGuardianID: + producer = proofProducer.NewGuardianProofProducer(p.cfg.EnableLivenessBondProof) + default: + return fmt.Errorf("unsupported tier: %d", tier.ID) + } + + if submitter, err = proofSubmitter.NewProofSubmitter( + p.rpc, + producer, + p.proofGenerationCh, + p.cfg.TaikoL2Address, + p.cfg.Graffiti, + p.cfg.ProveBlockGasLimit, + txmgr, + txBuilder, + ); err != nil { + return err + } + + p.proofSubmitters = append(p.proofSubmitters, submitter) + } + + return nil +} + +// initL1Current initializes prover's L1Current cursor. +func (p *Prover) initL1Current(startingBlockID *big.Int) error { + if err := p.rpc.WaitTillL2ExecutionEngineSynced(p.ctx); err != nil { + return err + } + + stateVars, err := p.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: p.ctx}) + if err != nil { + return err + } + p.genesisHeightL1 = stateVars.A.GenesisHeight + + if startingBlockID == nil { + if stateVars.B.LastVerifiedBlockId == 0 { + genesisL1Header, err := p.rpc.L1.HeaderByNumber(p.ctx, new(big.Int).SetUint64(stateVars.A.GenesisHeight)) + if err != nil { + return err + } + + p.sharedState.SetL1Current(genesisL1Header) + return nil + } + + startingBlockID = new(big.Int).SetUint64(stateVars.B.LastVerifiedBlockId) + } + + log.Info("Init L1Current cursor", "startingBlockID", startingBlockID) + + latestVerifiedHeaderL1Origin, err := p.rpc.L2.L1OriginByID(p.ctx, startingBlockID) + if err != nil { + if err.Error() == ethereum.NotFound.Error() { + log.Warn( + "Failed to find L1Origin for blockID, use latest L1 head instead", + "blockID", startingBlockID, + ) + l1Head, err := p.rpc.L1.HeaderByNumber(p.ctx, nil) + if err != nil { + return err + } + + p.sharedState.SetL1Current(l1Head) + return nil + } + return err + } + + l1Current, err := p.rpc.L1.HeaderByHash(p.ctx, latestVerifiedHeaderL1Origin.L1BlockHash) + if err != nil { + return err + } + p.sharedState.SetL1Current(l1Current) + + return nil +} + +// initEventHandlers initialize all event handlers which will be used by the current prover. +func (p *Prover) initEventHandlers() { + // ------- BlockProposed ------- + opts := &handler.NewBlockProposedEventHandlerOps{ + SharedState: p.sharedState, + ProverAddress: p.ProverAddress(), + GenesisHeightL1: p.genesisHeightL1, + RPC: p.rpc, + ProofGenerationCh: p.proofGenerationCh, + AssignmentExpiredCh: p.assignmentExpiredCh, + ProofSubmissionCh: p.proofSubmissionCh, + ProofContestCh: p.proofContestCh, + BackOffRetryInterval: p.cfg.BackOffRetryInterval, + BackOffMaxRetrys: p.cfg.BackOffMaxRetries, + ContesterMode: p.cfg.ContesterMode, + ProveUnassignedBlocks: p.cfg.ProveUnassignedBlocks, + } + if p.IsGuardianProver() { + opts.SubmissionDelay = p.cfg.GuardianProofSubmissionDelay + p.blockProposedHandler = handler.NewBlockProposedEventGuardianHandler( + &handler.NewBlockProposedGuardianEventHandlerOps{ + NewBlockProposedEventHandlerOps: opts, + GuardianProverHeartbeater: p.guardianProverHeartbeater, + }, + ) + } else { + p.blockProposedHandler = handler.NewBlockProposedEventHandler(opts) + } + // ------- TransitionProved ------- + p.transitionProvedHandler = handler.NewTransitionProvedEventHandler( + p.rpc, + p.proofContestCh, + p.cfg.ContesterMode, + ) + // ------- TransitionContested ------- + p.transitionContestedHandler = handler.NewTransitionContestedEventHandler( + p.rpc, + p.proofSubmissionCh, + p.cfg.ContesterMode, + ) + // ------- AssignmentExpired ------- + p.assignmentExpiredHandler = handler.NewAssignmentExpiredEventHandler( + p.rpc, + p.ProverAddress(), + p.proofSubmissionCh, + p.proofContestCh, + p.cfg.ContesterMode, + ) + // ------- BlockVerified ------- + p.blockVerifiedHandler = new(handler.BlockVerifiedEventHandler) +} diff --git a/packages/taiko-client/prover/init_test.go b/packages/taiko-client/prover/init_test.go new file mode 100644 index 00000000000..87169ebd15f --- /dev/null +++ b/packages/taiko-client/prover/init_test.go @@ -0,0 +1,44 @@ +package prover + +import ( + "context" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func (s *ProverTestSuite) TestSetApprovalAmount() { + data, err := encoding.TaikoTokenABI.Pack( + "approve", + s.p.cfg.AssignmentHookAddress, + common.Big0, + ) + s.Nil(err) + + _, err = s.p.txmgr.Send(context.Background(), txmgr.TxCandidate{ + TxData: data, + To: &s.p.cfg.TaikoTokenAddress, + }) + s.Nil(err) + + allowance, err := s.p.rpc.TaikoToken.Allowance(nil, s.p.ProverAddress(), s.p.cfg.AssignmentHookAddress) + s.Nil(err) + + s.Equal(0, allowance.Cmp(common.Big0)) + + // Max that can be approved + amt, ok := new(big.Int).SetString("58764887351446156758749765621197442946723800609510499661540524634076971270144", 10) + s.True(ok) + + s.p.cfg.Allowance = amt + + s.Nil(s.p.setApprovalAmount(context.Background(), s.p.cfg.AssignmentHookAddress)) + + allowance, err = s.p.rpc.TaikoToken.Allowance(nil, s.p.ProverAddress(), s.p.cfg.AssignmentHookAddress) + s.Nil(err) + + s.Equal(0, amt.Cmp(allowance)) +} diff --git a/packages/taiko-client/prover/proof_producer/dummy_producer.go b/packages/taiko-client/prover/proof_producer/dummy_producer.go new file mode 100644 index 00000000000..c5aedc04c48 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/dummy_producer.go @@ -0,0 +1,31 @@ +package producer + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" +) + +// DummyProofProducer always returns a dummy proof. +type DummyProofProducer struct{} + +// RequestProof returns a dummy proof to the result channel. +func (o *DummyProofProducer) RequestProof( + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, + tier uint16, +) (*ProofWithHeader, error) { + return &ProofWithHeader{ + BlockID: blockID, + Meta: meta, + Header: header, + Proof: bytes.Repeat([]byte{0xff}, 100), + Opts: opts, + Tier: tier, + }, nil +} diff --git a/packages/taiko-client/prover/proof_producer/dummy_producer_test.go b/packages/taiko-client/prover/proof_producer/dummy_producer_test.go new file mode 100644 index 00000000000..b52a47dabc3 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/dummy_producer_test.go @@ -0,0 +1,50 @@ +package producer + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" +) + +func TestDummyProducerRequestProof(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.BytesToAddress(randHash().Bytes()), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + producer = DummyProofProducer{} + tier uint16 = 1024 + blockID = common.Big32 + ) + res, err := producer.RequestProof( + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + tier, + ) + require.Nil(t, err) + + require.Equal(t, res.BlockID, blockID) + require.Equal(t, res.Header, header) + require.Equal(t, tier, res.Tier) + require.NotEmpty(t, res.Proof) +} diff --git a/packages/taiko-client/prover/proof_producer/guardian_producer.go b/packages/taiko-client/prover/proof_producer/guardian_producer.go new file mode 100644 index 00000000000..d638ef1da63 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/guardian_producer.go @@ -0,0 +1,60 @@ +package producer + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +// GuardianProofProducer always returns an optimistic (dummy) proof. +type GuardianProofProducer struct { + returnLivenessBond bool + DummyProofProducer +} + +func NewGuardianProofProducer(returnLivenessBond bool) *GuardianProofProducer { + return &GuardianProofProducer{ + returnLivenessBond: returnLivenessBond, + } +} + +// RequestProof implements the ProofProducer interface. +func (g *GuardianProofProducer) RequestProof( + _ context.Context, + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, +) (*ProofWithHeader, error) { + log.Info( + "Request guardian proof", + "blockID", blockID, + "coinbase", meta.Coinbase, + "height", header.Number, + "hash", header.Hash(), + ) + + if g.returnLivenessBond { + return &ProofWithHeader{ + BlockID: blockID, + Meta: meta, + Header: header, + Proof: crypto.Keccak256([]byte("RETURN_LIVENESS_BOND")), + Opts: opts, + Tier: g.Tier(), + }, nil + } + + return g.DummyProofProducer.RequestProof(opts, blockID, meta, header, g.Tier()) +} + +// Tier implements the ProofProducer interface. +func (g *GuardianProofProducer) Tier() uint16 { + return encoding.TierGuardianID +} diff --git a/packages/taiko-client/prover/proof_producer/guardian_producer_test.go b/packages/taiko-client/prover/proof_producer/guardian_producer_test.go new file mode 100644 index 00000000000..a6e6b6d8671 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/guardian_producer_test.go @@ -0,0 +1,90 @@ +package producer + +import ( + "context" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func TestGuardianProducerRequestProof(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.BytesToAddress(randHash().Bytes()), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + producer = NewGuardianProofProducer(false) + blockID = common.Big32 + ) + res, err := producer.RequestProof( + context.Background(), + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + ) + require.Nil(t, err) + + require.Equal(t, res.BlockID, blockID) + require.Equal(t, res.Header, header) + require.Equal(t, res.Tier, encoding.TierGuardianID) + require.NotEmpty(t, res.Proof) +} + +func TestGuardianProducerRequestProofReturnLivenessBond(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.BytesToAddress(randHash().Bytes()), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + producer = NewGuardianProofProducer(true) + blockID = common.Big32 + ) + res, err := producer.RequestProof( + context.Background(), + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + ) + require.Nil(t, err) + + require.Equal(t, res.BlockID, blockID) + require.Equal(t, res.Header, header) + require.Equal(t, res.Tier, encoding.TierGuardianID) + require.NotEmpty(t, res.Proof) + require.Equal(t, res.Proof, crypto.Keccak256([]byte("RETURN_LIVENESS_BOND"))) +} diff --git a/packages/taiko-client/prover/proof_producer/optimistic_producer.go b/packages/taiko-client/prover/proof_producer/optimistic_producer.go new file mode 100644 index 00000000000..93816f5da0b --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/optimistic_producer.go @@ -0,0 +1,39 @@ +package producer + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +// OptimisticProofProducer always returns an optimistic (dummy) proof. +type OptimisticProofProducer struct{ DummyProofProducer } + +// RequestProof implements the ProofProducer interface. +func (o *OptimisticProofProducer) RequestProof( + _ context.Context, + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, +) (*ProofWithHeader, error) { + log.Info( + "Request optimistic proof", + "blockID", blockID, + "coinbase", meta.Coinbase, + "height", header.Number, + "hash", header.Hash(), + ) + + return o.DummyProofProducer.RequestProof(opts, blockID, meta, header, o.Tier()) +} + +// Tier implements the ProofProducer interface. +func (o *OptimisticProofProducer) Tier() uint16 { + return encoding.TierOptimisticID +} diff --git a/packages/taiko-client/prover/proof_producer/optimistic_producer_test.go b/packages/taiko-client/prover/proof_producer/optimistic_producer_test.go new file mode 100644 index 00000000000..01106ddf518 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/optimistic_producer_test.go @@ -0,0 +1,93 @@ +package producer + +import ( + "context" + "crypto/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func TestOptimisticRequestProof(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.BytesToAddress(randHash().Bytes()), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + producer = &OptimisticProofProducer{} + blockID = common.Big32 + ) + res, err := producer.RequestProof( + context.Background(), + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + ) + require.Nil(t, err) + + require.Equal(t, res.BlockID, blockID) + require.Equal(t, res.Header, header) + require.Equal(t, res.Tier, encoding.TierOptimisticID) + require.NotEmpty(t, res.Proof) +} + +func TestProofCancel(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.HexToAddress("0x0000777735367b36bC9B61C50022d9D0700dB4Ec"), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + optimisticProofProducer = &OptimisticProofProducer{} + blockID = common.Big32 + ) + _, err := optimisticProofProducer.RequestProof( + context.Background(), + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + ) + require.Nil(t, err) +} + +func randHash() common.Hash { + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + log.Crit("Failed to generate random bytes", err) + } + return common.BytesToHash(b) +} diff --git a/packages/taiko-client/prover/proof_producer/proof_producer.go b/packages/taiko-client/prover/proof_producer/proof_producer.go new file mode 100644 index 00000000000..54e85b7259d --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/proof_producer.go @@ -0,0 +1,69 @@ +package producer + +import ( + "context" + "errors" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/bindings" +) + +var ( + proofPollingInterval = 10 * time.Second + errProofGenerating = errors.New("proof is generating") +) + +// ProofRequestBody represents a request body to generate a proof. +type ProofRequestBody struct { + Tier uint16 + Event *bindings.TaikoL1ClientBlockProposed +} + +// ContestRequestBody represents a request body to generate a proof for contesting. +type ContestRequestBody struct { + BlockID *big.Int + ProposedIn *big.Int + ParentHash common.Hash + Meta *bindings.TaikoDataBlockMetadata + Tier uint16 +} + +// ProofRequestOptions contains all options that need to be passed to a backend proof producer service. +type ProofRequestOptions struct { + BlockID *big.Int + ProverAddress common.Address + ProposeBlockTxHash common.Hash + TaikoL2 common.Address + MetaHash common.Hash + BlockHash common.Hash + ParentHash common.Hash + StateRoot common.Hash + EventL1Hash common.Hash + Graffiti string + GasUsed uint64 + ParentGasUsed uint64 +} + +type ProofWithHeader struct { + BlockID *big.Int + Meta *bindings.TaikoDataBlockMetadata + Header *types.Header + Proof []byte + Opts *ProofRequestOptions + Tier uint16 +} + +type ProofProducer interface { + RequestProof( + ctx context.Context, + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, + ) (*ProofWithHeader, error) + Tier() uint16 +} diff --git a/packages/taiko-client/prover/proof_producer/sgx_producer.go b/packages/taiko-client/prover/proof_producer/sgx_producer.go new file mode 100644 index 00000000000..f306a8dfab0 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/sgx_producer.go @@ -0,0 +1,214 @@ +package producer + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "math/big" + "net/http" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" +) + +// SGXProofProducer generates a SGX proof for the given block. +type SGXProofProducer struct { + RaikoHostEndpoint string // a proverd RPC endpoint + L1Endpoint string // a L1 node RPC endpoint + L1BeaconEndpoint string // a L1 beacon node RPC endpoint + L2Endpoint string // a L2 execution engine's RPC endpoint + Dummy bool + DummyProofProducer +} + +// SGXRequestProofBody represents the JSON body for requesting the proof. +type SGXRequestProofBody struct { + JsonRPC string `json:"jsonrpc"` //nolint:revive,stylecheck + ID *big.Int `json:"id"` + Method string `json:"method"` + Params []*SGXRequestProofBodyParam `json:"params"` +} + +// SGXRequestProofBodyParam represents the JSON body of RequestProofBody's `param` field. +type SGXRequestProofBodyParam struct { + Type string `json:"proof_type"` + Block *big.Int `json:"block_number"` + L2RPC string `json:"rpc"` + L1RPC string `json:"l1_rpc"` + L1BeaconRPC string `json:"beacon_rpc"` + Prover string `json:"prover"` + Graffiti string `json:"graffiti"` + ProofParam *ProofParam `json:"sgx"` +} + +// ProofParam represents the JSON body of SGXRequestProofBodyParam's `sgx` field. +type ProofParam struct { + Setup bool `json:"setup"` + Bootstrap bool `json:"bootstrap"` + Prove bool `json:"prove"` +} + +// SGXRequestProofBodyResponse represents the JSON body of the response of the proof requests. +type SGXRequestProofBodyResponse struct { + JsonRPC string `json:"jsonrpc"` //nolint:revive,stylecheck + ID *big.Int `json:"id"` + Result *RaikoHostOutput `json:"result"` + Error *struct { + Code *big.Int `json:"code"` + Message string `json:"message"` + } `json:"error,omitempty"` +} + +// RaikoHostOutput represents the JSON body of SGXRequestProofBodyResponse's `result` field. +type RaikoHostOutput struct { + Proof string `json:"proof"` +} + +// RequestProof implements the ProofProducer interface. +func (s *SGXProofProducer) RequestProof( + ctx context.Context, + opts *ProofRequestOptions, + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + header *types.Header, +) (*ProofWithHeader, error) { + log.Info( + "Request proof from raiko-host service", + "blockID", blockID, + "coinbase", meta.Coinbase, + "height", header.Number, + "hash", header.Hash(), + ) + + if s.Dummy { + return s.DummyProofProducer.RequestProof(opts, blockID, meta, header, s.Tier()) + } + + proof, err := s.callProverDaemon(ctx, opts) + if err != nil { + return nil, err + } + + metrics.ProverSgxProofGeneratedCounter.Add(1) + + return &ProofWithHeader{ + BlockID: blockID, + Header: header, + Meta: meta, + Proof: proof, + Opts: opts, + Tier: s.Tier(), + }, nil +} + +// callProverDaemon keeps polling the proverd service to get the requested proof. +func (s *SGXProofProducer) callProverDaemon(ctx context.Context, opts *ProofRequestOptions) ([]byte, error) { + var ( + proof []byte + start = time.Now() + ) + if err := backoff.Retry(func() error { + if ctx.Err() != nil { + return nil + } + output, err := s.requestProof(opts) + if err != nil { + log.Error("Failed to request proof", "height", opts.BlockID, "error", err, "endpoint", s.RaikoHostEndpoint) + return err + } + + if output == nil { + log.Info( + "Proof generating", + "height", opts.BlockID, + "time", time.Since(start), + "producer", "SGXProofProducer", + ) + return errProofGenerating + } + + log.Debug("Proof generation output", "output", output) + + proof = common.Hex2Bytes(output.Proof[2:]) + log.Info( + "Proof generated", + "height", opts.BlockID, + "time", time.Since(start), + "producer", "SGXProofProducer", + ) + return nil + }, backoff.WithContext(backoff.NewConstantBackOff(proofPollingInterval), ctx)); err != nil { + return nil, err + } + + return proof, nil +} + +// requestProof sends a RPC request to proverd to try to get the requested proof. +func (s *SGXProofProducer) requestProof(opts *ProofRequestOptions) (*RaikoHostOutput, error) { + reqBody := SGXRequestProofBody{ + JsonRPC: "2.0", + ID: common.Big1, + Method: "proof", + Params: []*SGXRequestProofBodyParam{{ + Type: "sgx", + Block: opts.BlockID, + L2RPC: s.L2Endpoint, + L1RPC: s.L1Endpoint, + L1BeaconRPC: s.L1BeaconEndpoint, + Prover: opts.ProverAddress.Hex()[2:], + Graffiti: opts.Graffiti, + ProofParam: &ProofParam{ + Setup: false, + Bootstrap: false, + Prove: true, + }, + }}, + } + + jsonValue, err := json.Marshal(reqBody) + if err != nil { + return nil, err + } + + res, err := http.Post(s.RaikoHostEndpoint, "application/json", bytes.NewBuffer(jsonValue)) + if err != nil { + return nil, err + } + + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to request proof, id: %d, statusCode: %d", opts.BlockID, res.StatusCode) + } + + resBytes, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + var output SGXRequestProofBodyResponse + if err := json.Unmarshal(resBytes, &output); err != nil { + return nil, err + } + + if output.Error != nil { + return nil, errors.New(output.Error.Message) + } + + return output.Result, nil +} + +// Tier implements the ProofProducer interface. +func (s *SGXProofProducer) Tier() uint16 { + return encoding.TierSgxID +} diff --git a/packages/taiko-client/prover/proof_producer/sgx_producer_test.go b/packages/taiko-client/prover/proof_producer/sgx_producer_test.go new file mode 100644 index 00000000000..795357d2c91 --- /dev/null +++ b/packages/taiko-client/prover/proof_producer/sgx_producer_test.go @@ -0,0 +1,51 @@ +package producer + +import ( + "context" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func TestSGXProducerRequestProof(t *testing.T) { + header := &types.Header{ + ParentHash: randHash(), + UncleHash: randHash(), + Coinbase: common.BytesToAddress(randHash().Bytes()), + Root: randHash(), + TxHash: randHash(), + ReceiptHash: randHash(), + Difficulty: common.Big0, + Number: common.Big256, + GasLimit: 1024, + GasUsed: 1024, + Time: uint64(time.Now().Unix()), + Extra: randHash().Bytes(), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + } + + var ( + producer = &SGXProofProducer{Dummy: true} + blockID = common.Big32 + ) + res, err := producer.RequestProof( + context.Background(), + &ProofRequestOptions{}, + blockID, + &bindings.TaikoDataBlockMetadata{}, + header, + ) + require.Nil(t, err) + + require.Equal(t, res.BlockID, blockID) + require.Equal(t, res.Header, header) + require.Equal(t, res.Tier, encoding.TierSgxID) + require.NotEmpty(t, res.Proof) +} diff --git a/packages/taiko-client/prover/proof_submitter/interface.go b/packages/taiko-client/prover/proof_submitter/interface.go new file mode 100644 index 00000000000..07a66ae2f4c --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/interface.go @@ -0,0 +1,31 @@ +package submitter + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// Submitter is the interface for submitting proofs of the L2 blocks. +type Submitter interface { + RequestProof(ctx context.Context, event *bindings.TaikoL1ClientBlockProposed) error + SubmitProof(ctx context.Context, proofWithHeader *proofProducer.ProofWithHeader) error + Producer() proofProducer.ProofProducer + Tier() uint16 +} + +// Contester is the interface for contesting proofs of the L2 blocks. +type Contester interface { + SubmitContest( + ctx context.Context, + blockID *big.Int, + proposedIn *big.Int, + parentHash common.Hash, + meta *bindings.TaikoDataBlockMetadata, + tier uint16, + ) error +} diff --git a/packages/taiko-client/prover/proof_submitter/proof_contester.go b/packages/taiko-client/prover/proof_submitter/proof_contester.go new file mode 100644 index 00000000000..b073b26ed99 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/proof_contester.go @@ -0,0 +1,124 @@ +package submitter + +import ( + "context" + "math/big" + "strings" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" +) + +var _ Contester = (*ProofContester)(nil) + +// ProofContester is responsible for contesting wrong L2 transitions. +type ProofContester struct { + rpc *rpc.Client + txBuilder *transaction.ProveBlockTxBuilder + sender *transaction.Sender + graffiti [32]byte +} + +// NewProofContester creates a new ProofContester instance. +func NewProofContester( + rpcClient *rpc.Client, + gasLimit uint64, + txmgr *txmgr.SimpleTxManager, + graffiti string, + builder *transaction.ProveBlockTxBuilder, +) *ProofContester { + return &ProofContester{ + rpc: rpcClient, + txBuilder: builder, + sender: transaction.NewSender(rpcClient, txmgr, gasLimit), + graffiti: rpc.StringToBytes32(graffiti), + } +} + +// SubmitContest submits a TaikoL1.proveBlock transaction to contest a L2 block transition. +func (c *ProofContester) SubmitContest( + ctx context.Context, + blockID *big.Int, + proposedIn *big.Int, + parentHash common.Hash, + meta *bindings.TaikoDataBlockMetadata, + tier uint16, +) error { + // Ensure the transition has not been contested yet. + transition, err := c.rpc.TaikoL1.GetTransition0( + &bind.CallOpts{Context: ctx}, + blockID.Uint64(), + parentHash, + ) + if err != nil { + if !strings.Contains(encoding.TryParsingCustomError(err).Error(), "L1_") { + log.Warn( + "Failed to get transition", + "blockID", blockID, + "parentHash", parentHash, + "error", encoding.TryParsingCustomError(err), + ) + return nil + } + return err + } + // If the transition has already been contested, return early. + if transition.Contester != (common.Address{}) { + log.Info( + "Transaction has already been contested", + "blockID", blockID, + "parentHash", parentHash, + "contester", transition.Contester, + ) + return nil + } + + // Send the contest transaction. + header, err := c.rpc.L2.HeaderByNumber(ctx, blockID) + if err != nil { + return err + } + + l1HeaderProposedIn, err := c.rpc.L1.HeaderByNumber(ctx, proposedIn) + if err != nil { + return err + } + + return c.sender.Send( + ctx, + &proofProducer.ProofWithHeader{ + BlockID: blockID, + Meta: meta, + Header: header, + Proof: []byte{}, + Opts: &proofProducer.ProofRequestOptions{ + EventL1Hash: l1HeaderProposedIn.Hash(), + StateRoot: header.Root, + }, + Tier: tier, + }, + c.txBuilder.Build( + blockID, + meta, + &bindings.TaikoDataTransition{ + ParentHash: header.ParentHash, + BlockHash: header.Hash(), + StateRoot: header.Root, + Graffiti: c.graffiti, + }, + &bindings.TaikoDataTierProof{ + Tier: transition.Tier, + Data: []byte{}, + }, + false, + ), + ) +} diff --git a/packages/taiko-client/prover/proof_submitter/proof_contester_test.go b/packages/taiko-client/prover/proof_submitter/proof_contester_test.go new file mode 100644 index 00000000000..a3a64f781e9 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/proof_contester_test.go @@ -0,0 +1,24 @@ +package submitter + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/testutils" +) + +func (s *ProofSubmitterTestSuite) TestSubmitContestNoTransition() { + s.NotNil( + s.contester.SubmitContest( + context.Background(), + common.Big256, + common.Big1, + testutils.RandomHash(), + &bindings.TaikoDataBlockMetadata{}, + encoding.TierOptimisticID, + ), + ) +} diff --git a/packages/taiko-client/prover/proof_submitter/proof_submitter.go b/packages/taiko-client/prover/proof_submitter/proof_submitter.go new file mode 100644 index 00000000000..c8b015d9f58 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/proof_submitter.go @@ -0,0 +1,197 @@ +package submitter + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/pkg/rpc" + validator "github.com/taikoxyz/taiko-client/prover/anchor_tx_validator" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" +) + +var _ Submitter = (*ProofSubmitter)(nil) + +// ProofSubmitter is responsible requesting proofs for the given L2 +// blocks, and submitting the generated proofs to the TaikoL1 smart contract. +type ProofSubmitter struct { + rpc *rpc.Client + proofProducer proofProducer.ProofProducer + resultCh chan *proofProducer.ProofWithHeader + anchorValidator *validator.AnchorTxValidator + txBuilder *transaction.ProveBlockTxBuilder + sender *transaction.Sender + proverAddress common.Address + taikoL2Address common.Address + graffiti [32]byte +} + +// NewProofSubmitter creates a new ProofSubmitter instance. +func NewProofSubmitter( + rpcClient *rpc.Client, + proofProducer proofProducer.ProofProducer, + resultCh chan *proofProducer.ProofWithHeader, + taikoL2Address common.Address, + graffiti string, + gasLimit uint64, + txmgr *txmgr.SimpleTxManager, + builder *transaction.ProveBlockTxBuilder, +) (*ProofSubmitter, error) { + anchorValidator, err := validator.New(taikoL2Address, rpcClient.L2.ChainID, rpcClient) + if err != nil { + return nil, err + } + + return &ProofSubmitter{ + rpc: rpcClient, + proofProducer: proofProducer, + resultCh: resultCh, + anchorValidator: anchorValidator, + txBuilder: builder, + sender: transaction.NewSender(rpcClient, txmgr, gasLimit), + proverAddress: txmgr.From(), + taikoL2Address: taikoL2Address, + graffiti: rpc.StringToBytes32(graffiti), + }, nil +} + +// RequestProof implements the Submitter interface. +func (s *ProofSubmitter) RequestProof(ctx context.Context, event *bindings.TaikoL1ClientBlockProposed) error { + header, err := s.rpc.WaitL2Header(ctx, event.BlockId) + if err != nil { + return fmt.Errorf("failed to fetch l2 Header, blockID: %d, error: %w", event.BlockId, err) + } + + if header.TxHash == types.EmptyTxsHash { + return errors.New("no transaction in block") + } + + parent, err := s.rpc.L2.BlockByHash(ctx, header.ParentHash) + if err != nil { + return fmt.Errorf("failed to get the L2 parent block by hash (%s): %w", header.ParentHash, err) + } + + blockInfo, err := s.rpc.GetL2BlockInfo(ctx, event.BlockId) + if err != nil { + return err + } + + // Request proof. + opts := &proofProducer.ProofRequestOptions{ + BlockID: header.Number, + ProverAddress: s.proverAddress, + ProposeBlockTxHash: event.Raw.TxHash, + TaikoL2: s.taikoL2Address, + MetaHash: blockInfo.MetaHash, + BlockHash: header.Hash(), + ParentHash: header.ParentHash, + StateRoot: header.Root, + EventL1Hash: event.Raw.BlockHash, + Graffiti: common.Bytes2Hex(s.graffiti[:]), + GasUsed: header.GasUsed, + ParentGasUsed: parent.GasUsed(), + } + + // Send the generated proof. + result, err := s.proofProducer.RequestProof( + ctx, + opts, + event.BlockId, + &event.Meta, + header, + ) + if err != nil { + return fmt.Errorf("failed to request proof (id: %d): %w", event.BlockId, err) + } + s.resultCh <- result + + metrics.ProverQueuedProofCounter.Add(1) + + return nil +} + +// SubmitProof implements the Submitter interface. +func (s *ProofSubmitter) SubmitProof( + ctx context.Context, + proofWithHeader *proofProducer.ProofWithHeader, +) (err error) { + log.Info( + "NewProofSubmitter block proof", + "blockID", proofWithHeader.BlockID, + "coinbase", proofWithHeader.Meta.Coinbase, + "parentHash", proofWithHeader.Header.ParentHash, + "hash", proofWithHeader.Opts.BlockHash, + "stateRoot", proofWithHeader.Opts.StateRoot, + "proof", common.Bytes2Hex(proofWithHeader.Proof), + "tier", proofWithHeader.Tier, + ) + + metrics.ProverReceivedProofCounter.Add(1) + + // Get the corresponding L2 block. + block, err := s.rpc.L2.BlockByHash(ctx, proofWithHeader.Header.Hash()) + if err != nil { + return fmt.Errorf("failed to get L2 block with given hash %s: %w", proofWithHeader.Header.Hash(), err) + } + + if block.Transactions().Len() == 0 { + return fmt.Errorf("invalid block without anchor transaction, blockID %s", proofWithHeader.BlockID) + } + + // Validate TaikoL2.anchor transaction inside the L2 block. + anchorTx := block.Transactions()[0] + if err = s.anchorValidator.ValidateAnchorTx(anchorTx); err != nil { + return fmt.Errorf("invalid anchor transaction: %w", err) + } + + // Build the TaikoL1.proveBlock transaction and send it to the L1 node. + if err = s.sender.Send( + ctx, + proofWithHeader, + s.txBuilder.Build( + proofWithHeader.BlockID, + proofWithHeader.Meta, + &bindings.TaikoDataTransition{ + ParentHash: proofWithHeader.Header.ParentHash, + BlockHash: proofWithHeader.Opts.BlockHash, + StateRoot: proofWithHeader.Opts.StateRoot, + Graffiti: s.graffiti, + }, + &bindings.TaikoDataTierProof{ + Tier: proofWithHeader.Tier, + Data: proofWithHeader.Proof, + }, + proofWithHeader.Tier == encoding.TierGuardianID, + ), + ); err != nil { + if err.Error() == transaction.ErrUnretryableSubmission.Error() { + return nil + } + metrics.ProverSubmissionErrorCounter.Add(1) + return err + } + + metrics.ProverSentProofCounter.Add(1) + metrics.ProverLatestProvenBlockIDGauge.Set(float64(proofWithHeader.BlockID.Uint64())) + + return nil +} + +// Producer returns the inner proof producer. +func (s *ProofSubmitter) Producer() proofProducer.ProofProducer { + return s.proofProducer +} + +// Tier returns the proof tier of the current proof submitter. +func (s *ProofSubmitter) Tier() uint16 { + return s.proofProducer.Tier() +} diff --git a/packages/taiko-client/prover/proof_submitter/proof_submitter_test.go b/packages/taiko-client/prover/proof_submitter/proof_submitter_test.go new file mode 100644 index 00000000000..f6d8413f800 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/proof_submitter_test.go @@ -0,0 +1,212 @@ +package submitter + +import ( + "bytes" + "context" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync" + "github.com/taikoxyz/taiko-client/driver/chain_syncer/blob" + "github.com/taikoxyz/taiko-client/driver/state" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" + producer "github.com/taikoxyz/taiko-client/prover/proof_producer" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" +) + +type ProofSubmitterTestSuite struct { + testutils.ClientTestSuite + submitter *ProofSubmitter + contester *ProofContester + blobSyncer *blob.Syncer + proposer *proposer.Proposer + proofCh chan *producer.ProofWithHeader +} + +func (s *ProofSubmitterTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + s.proofCh = make(chan *producer.ProofWithHeader, 1024) + + builder := transaction.NewProveBlockTxBuilder( + s.RPCClient, + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")), + ) + + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + txMgr, err := txmgr.NewSimpleTxManager( + "proofSubmitterTestSuite", + log.Root(), + new(metrics.NoopTxMetrics), + txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProverPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + ) + s.Nil(err) + + s.submitter, err = NewProofSubmitter( + s.RPCClient, + &producer.OptimisticProofProducer{}, + s.proofCh, + common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + "test", + 0, + txMgr, + builder, + ) + s.Nil(err) + s.contester = NewProofContester( + s.RPCClient, + 0, + txMgr, + "test", + builder, + ) + + // Init calldata syncer + testState, err := state.New(context.Background(), s.RPCClient) + s.Nil(err) + s.Nil(testState.ResetL1Current(context.Background(), common.Big0)) + + tracker := beaconsync.NewSyncProgressTracker(s.RPCClient.L2, 30*time.Second) + + s.blobSyncer, err = blob.NewSyncer( + context.Background(), + s.RPCClient, + testState, + tracker, + 0, + nil, + ) + s.Nil(err) + + // Init proposer + prop := new(proposer.Proposer) + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: s.ProverEndpoints, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.proposer = prop +} + +func (s *ProofSubmitterTestSuite) TestProofSubmitterRequestProofDeadlineExceeded() { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + s.ErrorContains( + s.submitter.RequestProof( + ctx, &bindings.TaikoL1ClientBlockProposed{BlockId: common.Big256}), "context deadline exceeded", + ) +} + +func (s *ProofSubmitterTestSuite) TestProofSubmitterSubmitProofMetadataNotFound() { + s.Error( + s.submitter.SubmitProof( + context.Background(), &producer.ProofWithHeader{ + BlockID: common.Big256, + Meta: &bindings.TaikoDataBlockMetadata{}, + Header: &types.Header{}, + Opts: &producer.ProofRequestOptions{}, + Proof: bytes.Repeat([]byte{0xff}, 100), + }, + ), + ) +} + +func (s *ProofSubmitterTestSuite) TestSubmitProofs() { + events := s.ProposeAndInsertEmptyBlocks(s.proposer, s.blobSyncer) + + for _, e := range events { + s.Nil(s.submitter.RequestProof(context.Background(), e)) + proofWithHeader := <-s.proofCh + s.Nil(s.submitter.SubmitProof(context.Background(), proofWithHeader)) + } +} + +func (s *ProofSubmitterTestSuite) TestGuardianSubmitProofs() { + events := s.ProposeAndInsertEmptyBlocks(s.proposer, s.blobSyncer) + + for _, e := range events { + s.Nil(s.submitter.RequestProof(context.Background(), e)) + proofWithHeader := <-s.proofCh + proofWithHeader.Tier = encoding.TierGuardianID + s.Nil(s.submitter.SubmitProof(context.Background(), proofWithHeader)) + } +} + +func (s *ProofSubmitterTestSuite) TestProofSubmitterRequestProofCancelled() { + ctx, cancel := context.WithCancel(context.Background()) + go func() { time.AfterFunc(2*time.Second, func() { cancel() }) }() + + s.ErrorContains( + s.submitter.RequestProof( + ctx, &bindings.TaikoL1ClientBlockProposed{BlockId: common.Big256}), "context canceled", + ) +} + +func TestProofSubmitterTestSuite(t *testing.T) { + suite.Run(t, new(ProofSubmitterTestSuite)) +} diff --git a/packages/taiko-client/prover/proof_submitter/transaction/builder.go b/packages/taiko-client/prover/proof_submitter/transaction/builder.go new file mode 100644 index 00000000000..13a2b388c92 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/transaction/builder.go @@ -0,0 +1,94 @@ +package transaction + +import ( + "errors" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +var ( + ErrUnretryableSubmission = errors.New("unretryable submission error") +) + +// TxBuilder will build a transaction with the given nonce. +type TxBuilder func(txOpts *bind.TransactOpts) (*txmgr.TxCandidate, error) + +// ProveBlockTxBuilder is responsible for building ProveBlock transactions. +type ProveBlockTxBuilder struct { + rpc *rpc.Client + taikoL1Address common.Address + guardianProverAddress common.Address +} + +// NewProveBlockTxBuilder creates a new ProveBlockTxBuilder instance. +func NewProveBlockTxBuilder( + rpc *rpc.Client, + taikoL1Address common.Address, + guardianProverAddress common.Address, +) *ProveBlockTxBuilder { + return &ProveBlockTxBuilder{rpc, taikoL1Address, guardianProverAddress} +} + +// Build creates a new TaikoL1.ProveBlock transaction with the given nonce. +func (a *ProveBlockTxBuilder) Build( + blockID *big.Int, + meta *bindings.TaikoDataBlockMetadata, + transition *bindings.TaikoDataTransition, + tierProof *bindings.TaikoDataTierProof, + guardian bool, +) TxBuilder { + return func(txOpts *bind.TransactOpts) (*txmgr.TxCandidate, error) { + var ( + data []byte + to common.Address + err error + ) + + log.Info( + "Build proof submission transaction", + "blockID", blockID, + "gasLimit", txOpts.GasLimit, + "guardian", guardian, + ) + + if !guardian { + to = a.taikoL1Address + + input, err := encoding.EncodeProveBlockInput(meta, transition, tierProof) + if err != nil { + return nil, err + } + if data, err = encoding.TaikoL1ABI.Pack("proveBlock", blockID.Uint64(), input); err != nil { + if isSubmitProofTxErrorRetryable(err, blockID) { + return nil, err + } + return nil, ErrUnretryableSubmission + } + } else { + to = a.guardianProverAddress + + if data, err = encoding.GuardianProverABI.Pack("approve", *meta, *transition, *tierProof); err != nil { + if isSubmitProofTxErrorRetryable(err, blockID) { + return nil, err + } + return nil, ErrUnretryableSubmission + } + } + + return &txmgr.TxCandidate{ + TxData: data, + To: &to, + Blobs: nil, + GasLimit: txOpts.GasLimit, + Value: txOpts.Value, + }, nil + } +} diff --git a/packages/taiko-client/prover/proof_submitter/transaction/builder_test.go b/packages/taiko-client/prover/proof_submitter/transaction/builder_test.go new file mode 100644 index 00000000000..389504209fd --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/transaction/builder_test.go @@ -0,0 +1,19 @@ +package transaction + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings" +) + +func (s *TransactionTestSuite) TestBuildTxs() { + _, err := s.builder.Build( + common.Big256, + &bindings.TaikoDataBlockMetadata{}, + &bindings.TaikoDataTransition{}, + &bindings.TaikoDataTierProof{}, + false, + )(&bind.TransactOpts{Nonce: common.Big0, GasLimit: 0, GasTipCap: common.Big0}) + s.Nil(err) +} diff --git a/packages/taiko-client/prover/proof_submitter/transaction/sender.go b/packages/taiko-client/prover/proof_submitter/transaction/sender.go new file mode 100644 index 00000000000..d1b7c96f23d --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/transaction/sender.go @@ -0,0 +1,163 @@ +package transaction + +import ( + "context" + "fmt" + "math/big" + "strings" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/pkg/rpc" + producer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// Sender is responsible for sending proof submission transactions with a backoff policy. +type Sender struct { + rpc *rpc.Client + txmgr *txmgr.SimpleTxManager + gasLimit uint64 +} + +// NewSender creates a new Sener instance. +func NewSender( + cli *rpc.Client, + txmgr *txmgr.SimpleTxManager, + gasLimit uint64, +) *Sender { + return &Sender{ + rpc: cli, + txmgr: txmgr, + gasLimit: gasLimit, + } +} + +// Send sends the given proof to the TaikoL1 smart contract with a backoff policy. +func (s *Sender) Send( + ctx context.Context, + proofWithHeader *producer.ProofWithHeader, + buildTx TxBuilder, +) error { + // Check if the proof has already been submitted. + proofStatus, err := rpc.GetBlockProofStatus(ctx, s.rpc, proofWithHeader.BlockID, proofWithHeader.Opts.ProverAddress) + if err != nil { + return err + } + if proofStatus.IsSubmitted && !proofStatus.Invalid { + return fmt.Errorf("a valid proof for block %d is already submitted", proofWithHeader.BlockID) + } + + // Check if this proof is still needed to be submitted. + ok, err := s.validateProof(ctx, proofWithHeader) + if err != nil || !ok { + return err + } + + // Assemble the TaikoL1.proveBlock transaction. + txCandidate, err := buildTx(&bind.TransactOpts{GasLimit: s.gasLimit}) + if err != nil { + return err + } + + // Send the transaction. + receipt, err := s.txmgr.Send(ctx, *txCandidate) + if err != nil { + return err + } + + if receipt.Status != types.ReceiptStatusSuccessful { + log.Error( + "Failed to submit proof", + "blockID", proofWithHeader.BlockID, + "tier", proofWithHeader.Tier, + "txHash", receipt.TxHash, + "error", encoding.TryParsingCustomErrorFromReceipt(ctx, s.rpc.L1, s.txmgr.From(), receipt), + ) + metrics.ProverSubmissionRevertedCounter.Add(1) + return ErrUnretryableSubmission + } + + log.Info( + "💰 Your block proof was accepted", + "blockID", proofWithHeader.BlockID, + "parentHash", proofWithHeader.Header.ParentHash, + "hash", proofWithHeader.Header.Hash(), + "stateRoot", proofWithHeader.Opts.StateRoot, + "txHash", receipt.TxHash, + "tier", proofWithHeader.Tier, + "isContest", len(proofWithHeader.Proof) == 0, + ) + + metrics.ProverSubmissionAcceptedCounter.Add(1) + + return nil +} + +// validateProof checks if the proof's corresponding L1 block is still in the canonical chain and if the +// latest verified head is not ahead of this block proof. +func (s *Sender) validateProof(ctx context.Context, proofWithHeader *producer.ProofWithHeader) (bool, error) { + // 1. Check if the corresponding L1 block is still in the canonical chain. + l1Header, err := s.rpc.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(proofWithHeader.Meta.L1Height+1)) + if err != nil { + log.Warn( + "Failed to fetch L1 block", + "blockID", proofWithHeader.BlockID, + "l1Height", proofWithHeader.Meta.L1Height+1, + "error", err, + ) + return false, err + } + if l1Header.Hash() != proofWithHeader.Opts.EventL1Hash { + log.Warn( + "Reorg detected, skip the current proof submission", + "blockID", proofWithHeader.BlockID, + "l1Height", proofWithHeader.Meta.L1Height+1, + "l1HashOld", proofWithHeader.Opts.EventL1Hash, + "l1HashNew", l1Header.Hash(), + ) + return false, nil + } + + // 2. Check if latest verified head is ahead of this block proof. + stateVars, err := s.rpc.GetProtocolStateVariables(&bind.CallOpts{Context: ctx}) + if err != nil { + log.Warn( + "Failed to fetch state variables", + "blockID", proofWithHeader.BlockID, + "error", err, + ) + return false, err + } + latestVerifiedID := stateVars.B.LastVerifiedBlockId + if new(big.Int).SetUint64(latestVerifiedID).Cmp(proofWithHeader.BlockID) >= 0 { + log.Info( + "Block is already verified, skip current proof submission", + "blockID", proofWithHeader.BlockID.Uint64(), + "latestVerifiedID", latestVerifiedID, + ) + return false, nil + } + + return true, nil +} + +// isSubmitProofTxErrorRetryable checks whether the error returned by a proof submission transaction +// is retryable. +func isSubmitProofTxErrorRetryable(err error, blockID *big.Int) bool { + if !strings.HasPrefix(err.Error(), "L1_") { + return true + } + + if strings.HasPrefix(err.Error(), "L1_NOT_ASSIGNED_PROVER") || + strings.HasPrefix(err.Error(), "L1_INVALID_PAUSE_STATUS") { + return true + } + + log.Warn("🤷 Unretryable proof submission error", "error", err, "blockID", blockID) + return false +} diff --git a/packages/taiko-client/prover/proof_submitter/transaction/sender_test.go b/packages/taiko-client/prover/proof_submitter/transaction/sender_test.go new file mode 100644 index 00000000000..d3f9db5ee13 --- /dev/null +++ b/packages/taiko-client/prover/proof_submitter/transaction/sender_test.go @@ -0,0 +1,100 @@ +package transaction + +import ( + "context" + "errors" + "math/big" + "os" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "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/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/internal/testutils" + producer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +var ( + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) +) + +type TransactionTestSuite struct { + testutils.ClientTestSuite + sender *Sender + builder *ProveBlockTxBuilder +} + +func (s *TransactionTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + s.builder = NewProveBlockTxBuilder( + s.RPCClient, + common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")), + ) + + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + txmgr, err := txmgr.NewSimpleTxManager( + "transactionTestSuite", + log.Root(), + new(metrics.NoopTxMetrics), + txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProverPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + ) + s.Nil(err) + + s.sender = NewSender(s.RPCClient, txmgr, 0) +} + +func (s *TransactionTestSuite) TestIsSubmitProofTxErrorRetryable() { + s.True(isSubmitProofTxErrorRetryable(errors.New(testAddr.String()), common.Big0)) + s.False(isSubmitProofTxErrorRetryable(errors.New("L1_NOT_SPECIAL_PROVER"), common.Big0)) + s.False(isSubmitProofTxErrorRetryable(errors.New("L1_DUP_PROVERS"), common.Big0)) + s.False(isSubmitProofTxErrorRetryable(errors.New("L1_"+testAddr.String()), common.Big0)) +} + +func (s *TransactionTestSuite) TestSendTxWithBackoff() { + l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil) + s.Nil(err) + l1HeadChild, err := s.RPCClient.L1.HeaderByNumber(context.Background(), new(big.Int).Sub(l1Head.Number, common.Big1)) + s.Nil(err) + meta := &bindings.TaikoDataBlockMetadata{L1Height: l1HeadChild.Number.Uint64(), L1Hash: l1HeadChild.Hash()} + s.NotNil(s.sender.Send( + context.Background(), + &producer.ProofWithHeader{ + Meta: meta, + BlockID: common.Big1, + Header: &types.Header{}, + Opts: &producer.ProofRequestOptions{EventL1Hash: l1Head.Hash()}, + }, + func(*bind.TransactOpts) (*txmgr.TxCandidate, error) { return nil, errors.New("L1_TEST") }, + )) +} + +func TestTxSenderTestSuite(t *testing.T) { + suite.Run(t, new(TransactionTestSuite)) +} diff --git a/packages/taiko-client/prover/prover.go b/packages/taiko-client/prover/prover.go new file mode 100644 index 00000000000..8c06b739846 --- /dev/null +++ b/packages/taiko-client/prover/prover.go @@ -0,0 +1,474 @@ +package prover + +import ( + "context" + "errors" + "fmt" + "math/big" + "net/http" + "strings" + "sync" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/metrics" + "github.com/taikoxyz/taiko-client/internal/version" + eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator" + "github.com/taikoxyz/taiko-client/pkg/rpc" + handler "github.com/taikoxyz/taiko-client/prover/event_handler" + guardianProverHeartbeater "github.com/taikoxyz/taiko-client/prover/guardian_prover_heartbeater" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" + proofSubmitter "github.com/taikoxyz/taiko-client/prover/proof_submitter" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" + "github.com/taikoxyz/taiko-client/prover/server" + state "github.com/taikoxyz/taiko-client/prover/shared_state" +) + +// Prover keeps trying to prove newly proposed blocks. +type Prover struct { + // Configurations + cfg *Config + backoff backoff.BackOffContext + + // Clients + rpc *rpc.Client + + // Guardian prover related + server *server.ProverServer + guardianProverHeartbeater guardianProverHeartbeater.BlockSenderHeartbeater + + // Contract configurations + protocolConfig *bindings.TaikoDataConfig + + // States + sharedState *state.SharedState + genesisHeightL1 uint64 + + // Event handlers + blockProposedHandler handler.BlockProposedHandler + blockVerifiedHandler handler.BlockVerifiedHandler + transitionContestedHandler handler.TransitionContestedHandler + transitionProvedHandler handler.TransitionProvedHandler + assignmentExpiredHandler handler.AssignmentExpiredHandler + + // Proof submitters + proofSubmitters []proofSubmitter.Submitter + proofContester proofSubmitter.Contester + + assignmentExpiredCh chan *bindings.TaikoL1ClientBlockProposed + proveNotify chan struct{} + + // Proof related channels + proofSubmissionCh chan *proofProducer.ProofRequestBody + proofContestCh chan *proofProducer.ContestRequestBody + proofGenerationCh chan *proofProducer.ProofWithHeader + + // Transactions manager + txmgr *txmgr.SimpleTxManager + + ctx context.Context + wg sync.WaitGroup +} + +// InitFromCli initializes the given prover instance based on the command line flags. +func (p *Prover) InitFromCli(ctx context.Context, c *cli.Context) error { + cfg, err := NewConfigFromCliContext(c) + if err != nil { + return err + } + + return InitFromConfig(ctx, p, cfg) +} + +// InitFromConfig initializes the prover instance based on the given configurations. +func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { + p.cfg = cfg + p.ctx = ctx + // Initialize state which will be shared by event handlers. + p.sharedState = state.New() + p.backoff = backoff.WithContext( + backoff.WithMaxRetries( + backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval), + p.cfg.BackOffMaxRetries, + ), + p.ctx, + ) + + // Clients + if p.rpc, err = rpc.NewClient(p.ctx, &rpc.ClientConfig{ + L1Endpoint: cfg.L1WsEndpoint, + L2Endpoint: cfg.L2WsEndpoint, + TaikoL1Address: cfg.TaikoL1Address, + TaikoL2Address: cfg.TaikoL2Address, + TaikoTokenAddress: cfg.TaikoTokenAddress, + GuardianProverAddress: cfg.GuardianProverAddress, + Timeout: cfg.RPCTimeout, + }); err != nil { + return err + } + + // Configs + protocolConfigs, err := p.rpc.TaikoL1.GetConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return fmt.Errorf("failed to get protocol configs: %w", err) + } + p.protocolConfig = &protocolConfigs + + log.Info("Protocol configs", "configs", p.protocolConfig) + + chBufferSize := p.protocolConfig.BlockMaxProposals + p.proofGenerationCh = make(chan *proofProducer.ProofWithHeader, chBufferSize) + p.assignmentExpiredCh = make(chan *bindings.TaikoL1ClientBlockProposed, chBufferSize) + p.proofSubmissionCh = make(chan *proofProducer.ProofRequestBody, p.cfg.Capacity) + p.proofContestCh = make(chan *proofProducer.ContestRequestBody, p.cfg.Capacity) + p.proveNotify = make(chan struct{}, 1) + + if err := p.initL1Current(cfg.StartingBlockID); err != nil { + return fmt.Errorf("initialize L1 current cursor error: %w", err) + } + + // Protocol proof tiers + tiers, err := p.rpc.GetTiers(ctx) + if err != nil { + return err + } + p.sharedState.SetTiers(tiers) + + txBuilder := transaction.NewProveBlockTxBuilder(p.rpc, p.cfg.TaikoL1Address, p.cfg.GuardianProverAddress) + + if p.txmgr, err = txmgr.NewSimpleTxManager( + "prover", + log.Root(), + &metrics.TxMgrMetrics, + *cfg.TxmgrConfigs, + ); err != nil { + return err + } + + // Proof submitters + if err := p.initProofSubmitters(p.txmgr, txBuilder); err != nil { + return err + } + + // Proof contester + p.proofContester = proofSubmitter.NewProofContester( + p.rpc, + p.cfg.ProveBlockGasLimit, + p.txmgr, + p.cfg.Graffiti, + txBuilder, + ) + + // Prover server + if p.server, err = server.New(&server.NewProverServerOpts{ + ProverPrivateKey: p.cfg.L1ProverPrivKey, + MinOptimisticTierFee: p.cfg.MinOptimisticTierFee, + MinSgxTierFee: p.cfg.MinSgxTierFee, + MinSgxAndZkVMTierFee: p.cfg.MinSgxAndZkVMTierFee, + MinEthBalance: p.cfg.MinEthBalance, + MinTaikoTokenBalance: p.cfg.MinTaikoTokenBalance, + MaxExpiry: p.cfg.MaxExpiry, + MaxBlockSlippage: p.cfg.MaxBlockSlippage, + TaikoL1Address: p.cfg.TaikoL1Address, + AssignmentHookAddress: p.cfg.AssignmentHookAddress, + RPC: p.rpc, + ProtocolConfigs: &protocolConfigs, + LivenessBond: protocolConfigs.LivenessBond, + }); err != nil { + return err + } + + // Guardian prover heartbeat sender + if p.IsGuardianProver() && p.cfg.GuardianProverHealthCheckServerEndpoint != nil { + // Check guardian prover contract address is correct. + if _, err := p.rpc.GuardianProver.MinGuardians(&bind.CallOpts{Context: ctx}); err != nil { + return fmt.Errorf("failed to get MinGuardians from guardian prover contract: %w", err) + } + + p.guardianProverHeartbeater = guardianProverHeartbeater.New( + p.cfg.L1ProverPrivKey, + p.cfg.GuardianProverHealthCheckServerEndpoint, + p.rpc, + p.ProverAddress(), + ) + } + + // Initialize event handlers. + p.initEventHandlers() + + return nil +} + +// Start starts the main loop of the L2 block prover. +func (p *Prover) Start() error { + // 1. Set approval amount for the contracts. + for _, contract := range []common.Address{p.cfg.TaikoL1Address, p.cfg.AssignmentHookAddress} { + if err := p.setApprovalAmount(p.ctx, contract); err != nil { + log.Crit("Failed to set approval amount", "contract", contract, "error", err) + } + } + + // 2. Start the prover server. + go func() { + if err := p.server.Start(fmt.Sprintf(":%v", p.cfg.HTTPServerPort)); !errors.Is(err, http.ErrServerClosed) { + log.Crit("Failed to start http server", "error", err) + } + }() + + // 3. Start the guardian prover heartbeat sender if the current prover is a guardian prover. + if p.IsGuardianProver() && p.cfg.GuardianProverHealthCheckServerEndpoint != nil { + // Send the startup message to the guardian prover health check server. + if err := p.guardianProverHeartbeater.SendStartupMessage( + p.ctx, + version.CommitVersion(), + version.CommitVersion(), + p.cfg.L1NodeVersion, + p.cfg.L2NodeVersion, + ); err != nil { + log.Error("Failed to send guardian prover startup message", "error", err) + } + + // Start the guardian prover heartbeat loop. + go p.guardianProverHeartbeatLoop(p.ctx) + } + + // 4. Start the main event loop of the prover. + go p.eventLoop() + + return nil +} + +// eventLoop starts the main loop of Taiko prover. +func (p *Prover) eventLoop() { + p.wg.Add(1) + defer p.wg.Done() + + // reqProving requests performing a proving operation, won't block + // if we are already proving. + reqProving := func() { + select { + case p.proveNotify <- struct{}{}: + default: + } + } + // Call reqProving() right away to catch up with the latest state. + reqProving() + + // If there is too many (TaikoData.Config.blockMaxProposals) pending blocks in TaikoL1 contract, there will be no new + // BlockProposed event temporarily, so except the BlockProposed subscription, we need another trigger to start + // fetching the proposed blocks. + forceProvingTicker := time.NewTicker(15 * time.Second) + defer forceProvingTicker.Stop() + + // Channels + chBufferSize := p.protocolConfig.BlockMaxProposals + blockProposedCh := make(chan *bindings.TaikoL1ClientBlockProposed, chBufferSize) + blockVerifiedCh := make(chan *bindings.TaikoL1ClientBlockVerified, chBufferSize) + transitionProvedCh := make(chan *bindings.TaikoL1ClientTransitionProved, chBufferSize) + transitionContestedCh := make(chan *bindings.TaikoL1ClientTransitionContested, chBufferSize) + // Subscriptions + blockProposedSub := rpc.SubscribeBlockProposed(p.rpc.TaikoL1, blockProposedCh) + blockVerifiedSub := rpc.SubscribeBlockVerified(p.rpc.TaikoL1, blockVerifiedCh) + transitionProvedSub := rpc.SubscribeTransitionProved(p.rpc.TaikoL1, transitionProvedCh) + transitionContestedSub := rpc.SubscribeTransitionContested(p.rpc.TaikoL1, transitionContestedCh) + defer func() { + blockProposedSub.Unsubscribe() + blockVerifiedSub.Unsubscribe() + transitionProvedSub.Unsubscribe() + transitionContestedSub.Unsubscribe() + }() + + for { + select { + case <-p.ctx.Done(): + return + case req := <-p.proofContestCh: + p.withRetry(func() error { return p.contestProofOp(req) }) + case proofWithHeader := <-p.proofGenerationCh: + p.withRetry(func() error { return p.submitProofOp(proofWithHeader) }) + case req := <-p.proofSubmissionCh: + p.withRetry(func() error { return p.requestProofOp(req.Event, req.Tier) }) + case <-p.proveNotify: + if err := p.proveOp(); err != nil { + log.Error("Prove new blocks error", "error", err) + } + case e := <-blockVerifiedCh: + p.blockVerifiedHandler.Handle(e) + case e := <-transitionProvedCh: + p.withRetry(func() error { return p.transitionProvedHandler.Handle(p.ctx, e) }) + case e := <-transitionContestedCh: + p.withRetry(func() error { return p.transitionContestedHandler.Handle(p.ctx, e) }) + case e := <-p.assignmentExpiredCh: + p.withRetry(func() error { return p.assignmentExpiredHandler.Handle(p.ctx, e) }) + case <-blockProposedCh: + reqProving() + case <-forceProvingTicker.C: + reqProving() + } + } +} + +// Close closes the prover instance. +func (p *Prover) Close(ctx context.Context) { + if err := p.server.Shutdown(ctx); err != nil { + log.Error("Failed to shut down prover server", "error", err) + } + p.wg.Wait() +} + +// proveOp iterates through BlockProposed events. +func (p *Prover) proveOp() error { + iter, err := eventIterator.NewBlockProposedIterator(p.ctx, &eventIterator.BlockProposedIteratorConfig{ + Client: p.rpc.L1, + TaikoL1: p.rpc.TaikoL1, + StartHeight: new(big.Int).SetUint64(p.sharedState.GetL1Current().Number.Uint64()), + OnBlockProposedEvent: p.blockProposedHandler.Handle, + BlockConfirmations: &p.cfg.BlockConfirmations, + }) + if err != nil { + log.Error("Failed to start event iterator", "event", "BlockProposed", "error", err) + return err + } + + return iter.Iter() +} + +// contestProofOp performs a proof contest operation. +func (p *Prover) contestProofOp(req *proofProducer.ContestRequestBody) error { + if err := p.proofContester.SubmitContest( + p.ctx, + req.BlockID, + req.ProposedIn, + req.ParentHash, + req.Meta, + req.Tier, + ); err != nil { + if strings.Contains(err.Error(), vm.ErrExecutionReverted.Error()) { + log.Error( + "Proof contest submission reverted", + "blockID", req.BlockID, + "minTier", req.Meta.MinTier, + "error", err, + ) + return nil + } + log.Error( + "Request new proof contest error", + "blockID", req.BlockID, + "minTier", req.Meta.MinTier, + "error", err, + ) + return err + } + + return nil +} + +// requestProofOp requests a new proof generation operation. +func (p *Prover) requestProofOp(e *bindings.TaikoL1ClientBlockProposed, minTier uint16) error { + if p.IsGuardianProver() { + minTier = encoding.TierGuardianID + } + if submitter := p.selectSubmitter(minTier); submitter != nil { + if err := submitter.RequestProof(p.ctx, e); err != nil { + log.Error("Request new proof error", "blockID", e.BlockId, "minTier", e.Meta.MinTier, "error", err) + return err + } + + return nil + } + + log.Error("Failed to find proof submitter", "blockID", e.BlockId, "minTier", minTier) + return nil +} + +// submitProofOp performs a proof submission operation. +func (p *Prover) submitProofOp(proofWithHeader *proofProducer.ProofWithHeader) error { + submitter := p.getSubmitterByTier(proofWithHeader.Tier) + if submitter == nil { + return nil + } + + if err := submitter.SubmitProof(p.ctx, proofWithHeader); err != nil { + if strings.Contains(err.Error(), vm.ErrExecutionReverted.Error()) { + log.Error( + "Proof submission reverted", + "blockID", proofWithHeader.BlockID, + "minTier", proofWithHeader.Meta.MinTier, + "error", err, + ) + return nil + } + log.Error( + "Submit proof error", + "blockID", proofWithHeader.BlockID, + "minTier", proofWithHeader.Meta.MinTier, + "error", err, + ) + return err + } + + return nil +} + +// Name returns the application name. +func (p *Prover) Name() string { + return "prover" +} + +// selectSubmitter returns the proof submitter with the given minTier. +func (p *Prover) selectSubmitter(minTier uint16) proofSubmitter.Submitter { + for _, s := range p.proofSubmitters { + if s.Tier() >= minTier { + log.Debug("Proof submitter selected", "tier", s.Tier(), "minTier", minTier) + return s + } + } + + log.Warn("No proof producer / submitter found for the given minTier", "minTier", minTier) + + return nil +} + +// getSubmitterByTier returns the proof submitter with the given tier. +func (p *Prover) getSubmitterByTier(tier uint16) proofSubmitter.Submitter { + for _, s := range p.proofSubmitters { + if s.Tier() == tier { + return s + } + } + + log.Warn("No proof producer / submitter found for the given tier", "tier", tier) + + return nil +} + +// IsGuardianProver returns true if the current prover is a guardian prover. +func (p *Prover) IsGuardianProver() bool { + return p.cfg.GuardianProverAddress != common.Address{} +} + +// ProverAddress returns the current prover account address. +func (p *Prover) ProverAddress() common.Address { + return p.txmgr.From() +} + +// withRetry retries the given function with prover backoff policy. +func (p *Prover) withRetry(f func() error) { + p.wg.Add(1) + go func() { + defer p.wg.Done() + if err := backoff.Retry(f, p.backoff); err != nil { + log.Error("Operation failed", "error", err) + } + }() +} diff --git a/packages/taiko-client/prover/prover_test.go b/packages/taiko-client/prover/prover_test.go new file mode 100644 index 00000000000..10f5f05a2fc --- /dev/null +++ b/packages/taiko-client/prover/prover_test.go @@ -0,0 +1,548 @@ +package prover + +import ( + "context" + "crypto/ecdsa" + "math/big" + "net/url" + "os" + "strconv" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "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/crypto" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/driver" + "github.com/taikoxyz/taiko-client/internal/testutils" + "github.com/taikoxyz/taiko-client/pkg/jwt" + "github.com/taikoxyz/taiko-client/pkg/rpc" + "github.com/taikoxyz/taiko-client/proposer" + guardianProverHeartbeater "github.com/taikoxyz/taiko-client/prover/guardian_prover_heartbeater" + producer "github.com/taikoxyz/taiko-client/prover/proof_producer" + "github.com/taikoxyz/taiko-client/prover/proof_submitter/transaction" +) + +type ProverTestSuite struct { + testutils.ClientTestSuite + p *Prover + cancel context.CancelFunc + d *driver.Driver + proposer *proposer.Proposer +} + +func (s *ProverTestSuite) SetupTest() { + s.ClientTestSuite.SetupTest() + + // Init prover + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + ctx, cancel := context.WithCancel(context.Background()) + proverServerURL := s.initProver(ctx, l1ProverPrivKey) + s.cancel = cancel + + // Init driver + jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET")) + s.Nil(err) + s.NotEmpty(jwtSecret) + + d := new(driver.Driver) + s.Nil(d.InitFromConfig(context.Background(), &driver.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + JwtSecret: string(jwtSecret), + }, + })) + s.d = d + + // Init proposer + l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY"))) + s.Nil(err) + + prop := new(proposer.Proposer) + + s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{ + ClientConfig: &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: string(jwtSecret), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + }, + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: 1024 * time.Hour, + MaxProposedTxListsPerEpoch: 1, + ProverEndpoints: []*url.URL{proverServerURL}, + OptimisticTierFee: common.Big256, + SgxTierFee: common.Big256, + MaxTierFeePriceBumps: 3, + TierFeePriceBump: common.Big2, + L1BlockBuilderTip: common.Big0, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProposerPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + + s.proposer = prop +} + +func (s *ProverTestSuite) TestName() { + s.Equal("prover", s.p.Name()) +} + +func (s *ProverTestSuite) TestInitError() { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + p := new(Prover) + + s.NotNil(InitFromConfig(ctx, p, &Config{ + L1WsEndpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L1HttpEndpoint: os.Getenv("L1_NODE_HTTP_ENDPOINT"), + L2WsEndpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2HttpEndpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_CONTRACT_ADDRESS")), + L1ProverPrivKey: l1ProverPrivKey, + Dummy: true, + ProveUnassignedBlocks: true, + RPCTimeout: 10 * time.Minute, + BackOffRetryInterval: 3 * time.Second, + BackOffMaxRetries: 12, + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(l1ProverPrivKey)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) +} + +func (s *ProverTestSuite) TestOnBlockProposed() { + // Init prover + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + s.p.cfg.L1ProverPrivKey = l1ProverPrivKey + // Valid block + e := s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + s.Nil(s.p.blockProposedHandler.Handle(context.Background(), e, func() {})) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + + // Empty blocks + for _, e = range s.ProposeAndInsertEmptyBlocks( + s.proposer, + s.d.ChainSyncer().BlobSyncer(), + ) { + s.Nil(s.p.blockProposedHandler.Handle(context.Background(), e, func() {})) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + } +} + +func (s *ProverTestSuite) TestOnBlockVerifiedEmptyBlockHash() { + s.NotPanics(func() { + s.p.blockVerifiedHandler.Handle(&bindings.TaikoL1ClientBlockVerified{ + BlockId: common.Big1, + BlockHash: common.Hash{}, + }) + }) +} + +func (s *ProverTestSuite) TestSubmitProofOp() { + s.NotPanics(func() { + s.p.withRetry(func() error { + return s.p.submitProofOp(&producer.ProofWithHeader{ + BlockID: common.Big1, + Meta: &bindings.TaikoDataBlockMetadata{}, + Header: &types.Header{}, + Proof: []byte{}, + Tier: encoding.TierOptimisticID, + Opts: &producer.ProofRequestOptions{}, + }) + }) + }) + s.NotPanics(func() { + s.p.withRetry(func() error { + return s.p.submitProofOp(&producer.ProofWithHeader{ + BlockID: common.Big1, + Meta: &bindings.TaikoDataBlockMetadata{}, + Header: &types.Header{}, + Proof: []byte{}, + Tier: encoding.TierOptimisticID, + Opts: &producer.ProofRequestOptions{}, + }) + }) + }) +} + +func (s *ProverTestSuite) TestOnBlockVerified() { + id := testutils.RandomHash().Big().Uint64() + s.NotPanics(func() { + s.p.blockVerifiedHandler.Handle(&bindings.TaikoL1ClientBlockVerified{ + BlockId: testutils.RandomHash().Big(), + Raw: types.Log{ + BlockHash: testutils.RandomHash(), + BlockNumber: id, + }, + }) + }) +} + +func (s *ProverTestSuite) TestContestWrongBlocks() { + s.T().Skip() + s.p.cfg.ContesterMode = false + s.p.initEventHandlers() + e := s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + s.Nil(s.p.transitionProvedHandler.Handle(context.Background(), &bindings.TaikoL1ClientTransitionProved{ + BlockId: e.BlockId, + Tier: e.Meta.MinTier, + })) + s.p.cfg.ContesterMode = true + s.p.initEventHandlers() + + // Submit a wrong proof at first. + sink := make(chan *bindings.TaikoL1ClientTransitionProved) + header, err := s.p.rpc.L2.HeaderByNumber(context.Background(), e.BlockId) + s.Nil(err) + + sub, err := s.p.rpc.TaikoL1.WatchTransitionProved(nil, sink, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + s.Nil(s.p.proveOp()) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + proofWithHeader := <-s.p.proofGenerationCh + proofWithHeader.Opts.BlockHash = testutils.RandomHash() + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), proofWithHeader)) + + event := <-sink + s.Equal(header.Number.Uint64(), event.BlockId.Uint64()) + s.Equal(common.BytesToHash(proofWithHeader.Opts.BlockHash[:]), common.BytesToHash(event.Tran.BlockHash[:])) + s.NotEqual(header.Hash(), common.BytesToHash(event.Tran.BlockHash[:])) + s.Equal(header.ParentHash, common.BytesToHash(event.Tran.ParentHash[:])) + + // Contest the transition. + contestedSink := make(chan *bindings.TaikoL1ClientTransitionContested) + contestedSub, err := s.p.rpc.TaikoL1.WatchTransitionContested(nil, contestedSink, nil) + s.Nil(err) + defer func() { + contestedSub.Unsubscribe() + close(contestedSink) + }() + + contesterKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_CONTRACT_OWNER_PRIVATE_KEY"))) + s.Nil(err) + s.NotNil(s.initProver( + context.Background(), + contesterKey, + )) + s.p.cfg.ContesterMode = true + s.p.initEventHandlers() + + s.Greater(header.Number.Uint64(), uint64(0)) + s.Nil(s.p.transitionProvedHandler.Handle(context.Background(), event)) + contestReq := <-s.p.proofContestCh + s.Nil(s.p.contestProofOp(contestReq)) + + contestedEvent := <-contestedSink + s.Equal(header.Number.Uint64(), contestedEvent.BlockId.Uint64()) + s.Equal(header.Hash(), common.BytesToHash(contestedEvent.Tran.BlockHash[:])) + s.Equal(header.ParentHash, common.BytesToHash(contestedEvent.Tran.ParentHash[:])) + + s.Nil(s.p.transitionContestedHandler.Handle(context.Background(), contestedEvent)) + + s.p.cfg.GuardianProverAddress = common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")) + s.True(s.p.IsGuardianProver()) + + txBuilder := transaction.NewProveBlockTxBuilder(s.p.rpc, s.p.cfg.TaikoL1Address, s.p.cfg.GuardianProverAddress) + s.p.proofSubmitters = nil + s.Nil(s.p.initProofSubmitters(s.p.txmgr, txBuilder)) + + s.p.rpc.GuardianProver, err = bindings.NewGuardianProver(s.p.cfg.GuardianProverAddress, s.p.rpc.L1) + s.Nil(err) + + approvedSink := make(chan *bindings.GuardianProverGuardianApproval) + approvedSub, err := s.p.rpc.GuardianProver.WatchGuardianApproval( + nil, approvedSink, []common.Address{}, [](*big.Int){}, []([32]byte){}, + ) + s.Nil(err) + defer func() { + approvedSub.Unsubscribe() + close(approvedSink) + }() + req = <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(encoding.TierGuardianID).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + approvedEvent := <-approvedSink + + s.Equal(header.Number.Uint64(), approvedEvent.BlockId.Uint64()) +} + +func (s *ProverTestSuite) TestProveExpiredUnassignedBlock() { + e := s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + sink := make(chan *bindings.TaikoL1ClientTransitionProved) + + header, err := s.p.rpc.L2.HeaderByNumber(context.Background(), e.BlockId) + s.Nil(err) + + sub, err := s.p.rpc.TaikoL1.WatchTransitionProved(nil, sink, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + e.AssignedProver = common.BytesToAddress(testutils.RandomHash().Bytes()) + s.p.cfg.GuardianProverAddress = common.Address{} + s.Nil(s.p.assignmentExpiredHandler.Handle(context.Background(), e)) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + + event := <-sink + s.Equal(header.Number.Uint64(), event.BlockId.Uint64()) + s.Equal(header.Hash(), common.BytesToHash(event.Tran.BlockHash[:])) + s.Equal(header.ParentHash, common.BytesToHash(event.Tran.ParentHash[:])) +} + +func (s *ProverTestSuite) TestSelectSubmitter() { + submitter := s.p.selectSubmitter(encoding.TierGuardianID - 1) + s.NotNil(submitter) + s.Equal(encoding.TierGuardianID, submitter.Tier()) +} + +func (s *ProverTestSuite) TestSelectSubmitterNotFound() { + submitter := s.p.selectSubmitter(encoding.TierGuardianID + 1) + s.Nil(submitter) +} + +func (s *ProverTestSuite) TestGetSubmitterByTier() { + submitter := s.p.getSubmitterByTier(encoding.TierGuardianID) + s.NotNil(submitter) + s.Equal(encoding.TierGuardianID, submitter.Tier()) + s.Nil(s.p.getSubmitterByTier(encoding.TierGuardianID + 1)) +} + +func (s *ProverTestSuite) TestProveOp() { + e := s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + sink := make(chan *bindings.TaikoL1ClientTransitionProved) + + header, err := s.p.rpc.L2.HeaderByNumber(context.Background(), e.BlockId) + s.Nil(err) + + sub, err := s.p.rpc.TaikoL1.WatchTransitionProved(nil, sink, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + s.Nil(s.p.proveOp()) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + + event := <-sink + s.Equal(header.Number.Uint64(), event.BlockId.Uint64()) + s.Equal(header.Hash(), common.BytesToHash(event.Tran.BlockHash[:])) + s.Equal(header.ParentHash, common.BytesToHash(event.Tran.ParentHash[:])) +} + +func (s *ProverTestSuite) TestGetBlockProofStatus() { + parent, err := s.p.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + e := s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + + // No proof submitted + status, err := rpc.GetBlockProofStatus(context.Background(), s.p.rpc, e.BlockId, s.p.ProverAddress()) + s.Nil(err) + s.False(status.IsSubmitted) + + // Valid proof submitted + sink := make(chan *bindings.TaikoL1ClientTransitionProved) + + sub, err := s.p.rpc.TaikoL1.WatchTransitionProved(nil, sink, nil) + s.Nil(err) + defer func() { + sub.Unsubscribe() + close(sink) + }() + + s.Nil(s.p.proveOp()) + req := <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + + status, err = rpc.GetBlockProofStatus(context.Background(), s.p.rpc, e.BlockId, s.p.ProverAddress()) + s.Nil(err) + + s.True(status.IsSubmitted) + s.False(status.Invalid) + s.Equal(parent.Hash(), status.ParentHeader.Hash()) + s.Equal(s.p.ProverAddress(), status.CurrentTransitionState.Prover) + + // Invalid proof submitted + parent, err = s.p.rpc.L2.HeaderByNumber(context.Background(), nil) + s.Nil(err) + + e = s.ProposeAndInsertValidBlock(s.proposer, s.d.ChainSyncer().BlobSyncer()) + + status, err = rpc.GetBlockProofStatus(context.Background(), s.p.rpc, e.BlockId, s.p.ProverAddress()) + s.Nil(err) + s.False(status.IsSubmitted) + + s.Nil(s.p.proveOp()) + req = <-s.p.proofSubmissionCh + s.Nil(s.p.requestProofOp(req.Event, req.Tier)) + + proofWithHeader := <-s.p.proofGenerationCh + proofWithHeader.Opts.BlockHash = testutils.RandomHash() + s.Nil(s.p.selectSubmitter(e.Meta.MinTier).SubmitProof(context.Background(), proofWithHeader)) + + status, err = rpc.GetBlockProofStatus(context.Background(), s.p.rpc, e.BlockId, s.p.ProverAddress()) + s.Nil(err) + s.True(status.IsSubmitted) + s.True(status.Invalid) + s.Equal(parent.Hash(), status.ParentHeader.Hash()) + s.Equal(s.p.ProverAddress(), status.CurrentTransitionState.Prover) + s.Equal(proofWithHeader.Opts.BlockHash, common.BytesToHash(status.CurrentTransitionState.BlockHash[:])) +} + +func (s *ProverTestSuite) TestSetApprovalAlreadySetHigher() { + originalAllowance, err := s.p.rpc.TaikoToken.Allowance(&bind.CallOpts{}, s.p.ProverAddress(), s.p.cfg.TaikoL1Address) + s.Nil(err) + + amt := common.Big1 + s.p.cfg.Allowance = amt + + s.Nil(s.p.setApprovalAmount(context.Background(), s.p.cfg.TaikoL1Address)) + + allowance, err := s.p.rpc.TaikoToken.Allowance(&bind.CallOpts{}, s.p.ProverAddress(), s.p.cfg.TaikoL1Address) + s.Nil(err) + + s.Equal(0, allowance.Cmp(originalAllowance)) +} + +func (s *ProverTestSuite) TearDownTest() { + if s.p.ctx.Err() == nil { + s.cancel() + } +} + +func TestProverTestSuite(t *testing.T) { + suite.Run(t, new(ProverTestSuite)) +} + +func (s *ProverTestSuite) initProver( + ctx context.Context, + key *ecdsa.PrivateKey, +) *url.URL { + proverServerURL := testutils.LocalRandomProverEndpoint() + port, err := strconv.Atoi(proverServerURL.Port()) + s.Nil(err) + + decimal, err := s.RPCClient.TaikoToken.Decimals(nil) + s.Nil(err) + + p := new(Prover) + s.Nil(InitFromConfig(ctx, p, &Config{ + L1WsEndpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L1HttpEndpoint: os.Getenv("L1_NODE_HTTP_ENDPOINT"), + L2WsEndpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + L2HttpEndpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + L1ProverPrivKey: key, + Dummy: true, + ProveUnassignedBlocks: true, + Capacity: 1024, + MinOptimisticTierFee: common.Big1, + MinSgxTierFee: common.Big1, + HTTPServerPort: uint64(port), + Allowance: new(big.Int).Exp(big.NewInt(1_000_000_100), new(big.Int).SetUint64(uint64(decimal)), nil), + RPCTimeout: 3 * time.Second, + BackOffRetryInterval: 3 * time.Second, + BackOffMaxRetries: 12, + L1NodeVersion: "1.0.0", + L2NodeVersion: "0.1.0", + TxmgrConfigs: &txmgr.CLIConfig{ + L1RPCURL: os.Getenv("L1_NODE_WS_ENDPOINT"), + NumConfirmations: 0, + SafeAbortNonceTooLowCount: txmgr.DefaultBatcherFlagValues.SafeAbortNonceTooLowCount, + PrivateKey: common.Bytes2Hex(crypto.FromECDSA(key)), + FeeLimitMultiplier: txmgr.DefaultBatcherFlagValues.FeeLimitMultiplier, + FeeLimitThresholdGwei: txmgr.DefaultBatcherFlagValues.FeeLimitThresholdGwei, + MinBaseFeeGwei: txmgr.DefaultBatcherFlagValues.MinBaseFeeGwei, + MinTipCapGwei: txmgr.DefaultBatcherFlagValues.MinTipCapGwei, + ResubmissionTimeout: txmgr.DefaultBatcherFlagValues.ResubmissionTimeout, + ReceiptQueryInterval: 1 * time.Second, + NetworkTimeout: txmgr.DefaultBatcherFlagValues.NetworkTimeout, + TxSendTimeout: txmgr.DefaultBatcherFlagValues.TxSendTimeout, + TxNotInMempoolTimeout: txmgr.DefaultBatcherFlagValues.TxNotInMempoolTimeout, + }, + })) + p.server = s.NewTestProverServer( + key, + proverServerURL, + ) + + p.guardianProverHeartbeater = guardianProverHeartbeater.New( + key, + p.cfg.GuardianProverHealthCheckServerEndpoint, + p.rpc, + p.ProverAddress(), + ) + s.p = p + + return proverServerURL +} diff --git a/packages/taiko-client/prover/server/api.go b/packages/taiko-client/prover/server/api.go new file mode 100644 index 00000000000..be35869ac7e --- /dev/null +++ b/packages/taiko-client/prover/server/api.go @@ -0,0 +1,285 @@ +package server + +import ( + "context" + "math/big" + "net/http" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/labstack/echo/v4" + + "github.com/taikoxyz/taiko-client/bindings/encoding" + "github.com/taikoxyz/taiko-client/internal/utils" + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +const ( + rpcTimeout = 1 * time.Minute +) + +// @title Taiko Prover Server API +// @version 1.0 +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url https://community.taiko.xyz/ +// @contact.email info@taiko.xyz + +// @license.name MIT +// @license.url https://github.com/taikoxyz/taiko-client/blob/main/LICENSE.md + +// CreateAssignmentRequestBody represents a request body when handling assignment creation request. +type CreateAssignmentRequestBody struct { + Proposer common.Address `json:"proposer"` + FeeToken common.Address `json:"feeToken"` + TierFees []encoding.TierFee `json:"tierFees"` + Expiry uint64 `json:"expiry"` + BlobHash common.Hash `json:"blobHash"` +} + +// Status represents the current prover server status. +type Status struct { + MinOptimisticTierFee uint64 `json:"minOptimisticTierFee"` + MinSgxTierFee uint64 `json:"minSgxTierFee"` + MinSgxAndZkVMTierFee uint64 `json:"minSgxAndZkVMTierFee"` + MaxExpiry uint64 `json:"maxExpiry"` + Prover string `json:"prover"` +} + +// GetStatus handles a query to the current prover server status. +// +// @Summary Get current prover server status +// @ID get-status +// @Accept json +// @Produce json +// @Success 200 {object} Status +// @Router /status [get] +func (s *ProverServer) GetStatus(c echo.Context) error { + return c.JSON(http.StatusOK, &Status{ + MinOptimisticTierFee: s.minOptimisticTierFee.Uint64(), + MinSgxTierFee: s.minSgxTierFee.Uint64(), + MinSgxAndZkVMTierFee: s.minSgxAndZkVMTierFee.Uint64(), + MaxExpiry: uint64(s.maxExpiry.Seconds()), + Prover: s.proverAddress.Hex(), + }) +} + +// ProposeBlockResponse represents the JSON response which will be returned by +// the ProposeBlock request handler. +type ProposeBlockResponse struct { + SignedPayload []byte `json:"signedPayload"` + Prover common.Address `json:"prover"` + MaxBlockID uint64 `json:"maxBlockID"` + MaxProposedIn uint64 `json:"maxProposedIn"` +} + +// CreateAssignment handles a block proof assignment request, decides if this prover wants to +// handle this block, and if so, returns a signed payload the proposer +// can submit onchain. +// +// @Summary Try to accept a block proof assignment +// @Param body body server.CreateAssignmentRequestBody true "assignment request body" +// @Accept json +// @Produce json +// @Success 200 {object} ProposeBlockResponse +// @Failure 422 {string} string "empty blob hash" +// @Failure 422 {string} string "only receive ETH" +// @Failure 422 {string} string "insufficient prover balance" +// @Failure 422 {string} string "proof fee too low" +// @Failure 422 {string} string "expiry too long" +// @Failure 422 {string} string "prover does not have capacity" +// @Router /assignment [post] +func (s *ProverServer) CreateAssignment(c echo.Context) error { + req := new(CreateAssignmentRequestBody) + if err := c.Bind(req); err != nil { + return c.JSON(http.StatusUnprocessableEntity, err) + } + + log.Info( + "Proof assignment request body", + "feeToken", req.FeeToken, + "expiry", req.Expiry, + "tierFees", req.TierFees, + "blobHash", req.BlobHash, + "currentUsedCapacity", len(s.proofSubmissionCh), + ) + + // 1. Check if the request body is valid. + if req.BlobHash == (common.Hash{}) { + log.Warn("Empty blob hash", "prover", s.proverAddress) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "empty blob hash") + } + if req.FeeToken != (common.Address{}) { + log.Warn("Only receive ETH", "prover", s.proverAddress) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "only receive ETH") + } + + // 2. Check if the prover has the required minimum on-chain ETH and Taiko token balance. + ok, err := s.checkMinEthAndToken(c.Request().Context()) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) + } + + if !ok { + return echo.NewHTTPError(http.StatusUnprocessableEntity, "insufficient prover balance") + } + + // 3. Check if the prover's token balance is enough to cover the bonds. + if ok, err = rpc.CheckProverBalance( + c.Request().Context(), + s.rpc, + s.proverAddress, + s.assignmentHookAddress, + s.livenessBond, + ); err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) + } + if !ok { + log.Warn( + "Insufficient prover token balance, please get more tokens or wait for verification of the blocks you proved", + "prover", s.proverAddress, + ) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "insufficient prover balance") + } + + // 4. Check if the proof fee meets prover's minimum requirement for each tier. + for _, tier := range req.TierFees { + if tier.Tier == encoding.TierGuardianID { + continue + } + + var minTierFee *big.Int + switch tier.Tier { + case encoding.TierOptimisticID: + minTierFee = s.minOptimisticTierFee + case encoding.TierSgxID: + minTierFee = s.minSgxTierFee + case encoding.TierSgxAndZkVMID: + minTierFee = s.minSgxAndZkVMTierFee + default: + log.Warn("Unknown tier", "tier", tier.Tier, "fee", tier.Fee, "proposerIP", c.RealIP()) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "unknown tier") + } + + if tier.Fee.Cmp(minTierFee) < 0 { + log.Warn( + "Proof fee too low", + "tier", tier.Tier, + "fee", tier.Fee, + "minTierFee", minTierFee, + "proposerIP", c.RealIP(), + ) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "proof fee too low") + } + } + + // 5. Check if the expiry is too long. + if req.Expiry > uint64(time.Now().Add(s.maxExpiry).Unix()) { + log.Warn( + "Expiry too long", + "requestExpiry", req.Expiry, + "srvMaxExpiry", s.maxExpiry, + "proposerIP", c.RealIP(), + ) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "expiry too long") + } + + // 6. Check if the prover has any capacity now. + if s.proofSubmissionCh != nil && len(s.proofSubmissionCh) == cap(s.proofSubmissionCh) { + log.Warn("Prover does not have capacity", "capacity", cap(s.proofSubmissionCh)) + return echo.NewHTTPError(http.StatusUnprocessableEntity, "prover does not have capacity") + } + + // 7. Encode and sign the prover assignment payload. + l1Head, err := s.rpc.L1.BlockNumber(c.Request().Context()) + if err != nil { + log.Error("Failed to get L1 block head", "error", err) + return echo.NewHTTPError(http.StatusUnprocessableEntity, err) + } + encoded, err := encoding.EncodeProverAssignmentPayload( + s.protocolConfigs.ChainId, + s.taikoL1Address, + s.assignmentHookAddress, + req.Proposer, + s.proverAddress, + req.BlobHash, + req.FeeToken, + req.Expiry, + l1Head+s.maxSlippage, + s.maxProposedIn, + req.TierFees, + ) + if err != nil { + log.Error("Failed to encode proverAssignment payload data", "error", err) + return echo.NewHTTPError(http.StatusUnprocessableEntity, err) + } + + signed, err := crypto.Sign(crypto.Keccak256Hash(encoded).Bytes(), s.proverPrivateKey) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) + } + + // 8. Return the signed payload. + return c.JSON(http.StatusOK, &ProposeBlockResponse{ + SignedPayload: signed, + Prover: s.proverAddress, + MaxBlockID: l1Head + s.maxSlippage, + MaxProposedIn: s.maxProposedIn, + }) +} + +// checkMinEthAndToken checks if the prover has the required minimum on-chain ETH and Taiko token balance. +func (s *ProverServer) checkMinEthAndToken(ctx context.Context) (bool, error) { + ctx, cancel := context.WithTimeout(ctx, rpcTimeout) + defer cancel() + + // 1. Check prover's ETH balance. + ethBalance, err := s.rpc.L1.BalanceAt(ctx, s.proverAddress, nil) + if err != nil { + return false, err + } + + log.Info( + "Prover's ETH balance", + "balance", utils.WeiToEther(ethBalance), + "address", s.proverAddress.Hex(), + ) + + if ethBalance.Cmp(s.minEthBalance) <= 0 { + log.Warn( + "Prover does not have required minimum on-chain ETH balance", + "providedProver", s.proverAddress.Hex(), + "ethBalance", utils.WeiToEther(ethBalance), + "minEthBalance", utils.WeiToEther(s.minEthBalance), + ) + return false, nil + } + + // 2. Check prover's Taiko token balance. + balance, err := s.rpc.TaikoToken.BalanceOf(&bind.CallOpts{Context: ctx}, s.proverAddress) + if err != nil { + return false, err + } + + log.Info( + "Prover's Taiko token balance", + "balance", utils.WeiToEther(balance), + "address", s.proverAddress.Hex(), + ) + + if balance.Cmp(s.minTaikoTokenBalance) <= 0 { + log.Warn( + "Prover does not have required on-chain Taiko token balance", + "providedProver", s.proverAddress.Hex(), + "taikoTokenBalance", utils.WeiToEther(balance), + "minTaikoTokenBalance", utils.WeiToEther(s.minTaikoTokenBalance), + ) + return false, nil + } + + return true, nil +} diff --git a/packages/taiko-client/prover/server/api_test.go b/packages/taiko-client/prover/server/api_test.go new file mode 100644 index 00000000000..ce0cb85ff7f --- /dev/null +++ b/packages/taiko-client/prover/server/api_test.go @@ -0,0 +1,50 @@ +package server + +import ( + "encoding/json" + "io" + "net/http" + "strings" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/taikoxyz/taiko-client/bindings/encoding" +) + +func (s *ProverServerTestSuite) TestGetStatusSuccess() { + res := s.sendReq("/status") + s.Equal(http.StatusOK, res.StatusCode) + + status := new(Status) + + defer res.Body.Close() + b, err := io.ReadAll(res.Body) + s.Nil(err) + s.Nil(json.Unmarshal(b, &status)) + + s.Equal(s.s.minOptimisticTierFee.Uint64(), status.MinOptimisticTierFee) + s.Equal(s.s.minSgxTierFee.Uint64(), status.MinSgxTierFee) + s.Equal(uint64(s.s.maxExpiry.Seconds()), status.MaxExpiry) + s.NotEmpty(status.Prover) +} + +func (s *ProverServerTestSuite) TestProposeBlockSuccess() { + data, err := json.Marshal(CreateAssignmentRequestBody{ + FeeToken: (common.Address{}), + TierFees: []encoding.TierFee{ + {Tier: encoding.TierOptimisticID, Fee: common.Big256}, + {Tier: encoding.TierSgxID, Fee: common.Big256}, + }, + Expiry: uint64(time.Now().Add(time.Minute).Unix()), + BlobHash: common.BigToHash(common.Big1), + }) + s.Nil(err) + res, err := http.Post(s.testServer.URL+"/assignment", "application/json", strings.NewReader(string(data))) + s.Nil(err) + s.Equal(http.StatusOK, res.StatusCode) + defer res.Body.Close() + b, err := io.ReadAll(res.Body) + s.Nil(err) + s.Contains(string(b), "signedPayload") +} diff --git a/packages/taiko-client/prover/server/server.go b/packages/taiko-client/prover/server/server.go new file mode 100644 index 00000000000..5114633c863 --- /dev/null +++ b/packages/taiko-client/prover/server/server.go @@ -0,0 +1,146 @@ +package server + +import ( + "context" + "crypto/ecdsa" + "math/big" + "net/http" + "os" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + + "github.com/taikoxyz/taiko-client/bindings" + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +// @title Taiko Prover Server API +// @version 1.0 +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url https://community.taiko.xyz/ +// @contact.email info@taiko.xyz + +// @license.name MIT +// @license.url https://github.com/taikoxyz/taiko-client/blob/main/LICENSE.md + +// ProverServer represents a prover server instance. +type ProverServer struct { + echo *echo.Echo + proverPrivateKey *ecdsa.PrivateKey + proverAddress common.Address + minOptimisticTierFee *big.Int + minSgxTierFee *big.Int + minSgxAndZkVMTierFee *big.Int + minEthBalance *big.Int + minTaikoTokenBalance *big.Int + maxExpiry time.Duration + maxSlippage uint64 + maxProposedIn uint64 + taikoL1Address common.Address + assignmentHookAddress common.Address + proofSubmissionCh chan<- proofProducer.ProofRequestBody + rpc *rpc.Client + protocolConfigs *bindings.TaikoDataConfig + livenessBond *big.Int +} + +// NewProverServerOpts contains all configurations for creating a prover server instance. +type NewProverServerOpts struct { + ProverPrivateKey *ecdsa.PrivateKey + MinOptimisticTierFee *big.Int + MinSgxTierFee *big.Int + MinSgxAndZkVMTierFee *big.Int + MinEthBalance *big.Int + MinTaikoTokenBalance *big.Int + MaxExpiry time.Duration + MaxBlockSlippage uint64 + MaxProposedIn uint64 + TaikoL1Address common.Address + AssignmentHookAddress common.Address + ProofSubmissionCh chan<- proofProducer.ProofRequestBody + RPC *rpc.Client + ProtocolConfigs *bindings.TaikoDataConfig + LivenessBond *big.Int +} + +// New creates a new prover server instance. +func New(opts *NewProverServerOpts) (*ProverServer, error) { + srv := &ProverServer{ + proverPrivateKey: opts.ProverPrivateKey, + proverAddress: crypto.PubkeyToAddress(opts.ProverPrivateKey.PublicKey), + echo: echo.New(), + minOptimisticTierFee: opts.MinOptimisticTierFee, + minSgxTierFee: opts.MinSgxTierFee, + minSgxAndZkVMTierFee: opts.MinSgxAndZkVMTierFee, + minEthBalance: opts.MinEthBalance, + minTaikoTokenBalance: opts.MinTaikoTokenBalance, + maxExpiry: opts.MaxExpiry, + maxProposedIn: opts.MaxProposedIn, + maxSlippage: opts.MaxBlockSlippage, + taikoL1Address: opts.TaikoL1Address, + assignmentHookAddress: opts.AssignmentHookAddress, + proofSubmissionCh: opts.ProofSubmissionCh, + rpc: opts.RPC, + protocolConfigs: opts.ProtocolConfigs, + livenessBond: opts.LivenessBond, + } + + srv.echo.HideBanner = true + srv.configureMiddleware() + srv.configureRoutes() + + return srv, nil +} + +// Start starts the HTTP server. +func (s *ProverServer) Start(address string) error { + return s.echo.Start(address) +} + +// Shutdown shuts down the HTTP server. +func (s *ProverServer) Shutdown(ctx context.Context) error { + return s.echo.Shutdown(ctx) +} + +// Health endpoints for probes. +func (s *ProverServer) Health(c echo.Context) error { + return c.NoContent(http.StatusOK) +} + +// LogSkipper implements the `middleware.Skipper` interface. +func LogSkipper(c echo.Context) bool { + switch c.Request().URL.Path { + case "/healthz": + return true + default: + return true + } +} + +// configureMiddleware configures the server middlewares. +func (s *ProverServer) configureMiddleware() { + s.echo.Use(middleware.RequestID()) + + s.echo.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ + Skipper: LogSkipper, + Format: `{"time":"${time_rfc3339_nano}","level":"INFO","message":{"id":"${id}","remote_ip":"${remote_ip}",` + + `"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` + + `"response_status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}",` + + `"bytes_in":${bytes_in},"bytes_out":${bytes_out}}}` + "\n", + Output: os.Stdout, + })) +} + +// configureRoutes contains all routes which will be used by prover server. +func (s *ProverServer) configureRoutes() { + s.echo.GET("/", s.Health) + s.echo.GET("/healthz", s.Health) + s.echo.GET("/status", s.GetStatus) + s.echo.POST("/assignment", s.CreateAssignment) +} diff --git a/packages/taiko-client/prover/server/server_test.go b/packages/taiko-client/prover/server/server_test.go new file mode 100644 index 00000000000..99b94282fb5 --- /dev/null +++ b/packages/taiko-client/prover/server/server_test.go @@ -0,0 +1,127 @@ +package server + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "os" + "testing" + "time" + + "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/go-resty/resty/v2" + "github.com/phayes/freeport" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/pkg/rpc" + proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" +) + +type ProverServerTestSuite struct { + suite.Suite + s *ProverServer + testServer *httptest.Server +} + +func (s *ProverServerTestSuite) SetupTest() { + l1ProverPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + + rpcClient, err := rpc.NewClient(context.Background(), &rpc.ClientConfig{ + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN_ADDRESS")), + L2EngineEndpoint: os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT"), + JwtSecret: os.Getenv("JWT_SECRET"), + Timeout: 5 * time.Second, + }) + s.Nil(err) + + configs, err := rpcClient.TaikoL1.GetConfig(nil) + s.Nil(err) + + p, err := New(&NewProverServerOpts{ + ProverPrivateKey: l1ProverPrivKey, + MinOptimisticTierFee: common.Big1, + MinSgxTierFee: common.Big1, + MinSgxAndZkVMTierFee: common.Big1, + MinEthBalance: common.Big1, + MinTaikoTokenBalance: common.Big1, + MaxExpiry: time.Hour, + ProofSubmissionCh: make(chan<- proofProducer.ProofRequestBody, 1024), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + AssignmentHookAddress: common.HexToAddress(os.Getenv("ASSIGNMENT_HOOK_ADDRESS")), + RPC: rpcClient, + ProtocolConfigs: &configs, + LivenessBond: common.Big0, + }) + s.Nil(err) + + p.echo.HideBanner = true + p.configureMiddleware() + p.configureRoutes() + s.s = p + s.testServer = httptest.NewServer(p.echo) +} + +func (s *ProverServerTestSuite) TestHealth() { + resp := s.sendReq("/healthz") + defer resp.Body.Close() + s.Equal(http.StatusOK, resp.StatusCode) +} + +func (s *ProverServerTestSuite) TestRoot() { + resp := s.sendReq("/") + defer resp.Body.Close() + s.Equal(http.StatusOK, resp.StatusCode) +} + +func (s *ProverServerTestSuite) TestStartShutdown() { + port, err := freeport.GetFreePort() + s.Nil(err) + + url, err := url.Parse(fmt.Sprintf("http://localhost:%v", port)) + s.Nil(err) + + go func() { + if err := s.s.Start(fmt.Sprintf(":%v", port)); err != nil { + log.Error("Failed to start prover server", "error", err) + } + }() + + // Wait till the server fully started. + s.Nil(backoff.Retry(func() error { + res, err := resty.New().R().Get(url.String() + "/healthz") + if err != nil { + return err + } + if !res.IsSuccess() { + return fmt.Errorf("invalid response status code: %d", res.StatusCode()) + } + + return nil + }, backoff.NewExponentialBackOff())) + + s.Nil(s.s.Shutdown(context.Background())) +} + +func (s *ProverServerTestSuite) TearDownTest() { + s.testServer.Close() +} + +func TestProverServerTestSuite(t *testing.T) { + suite.Run(t, new(ProverServerTestSuite)) +} + +func (s *ProverServerTestSuite) sendReq(path string) *http.Response { + res, err := http.Get(s.testServer.URL + path) + s.Nil(err) + return res +} diff --git a/packages/taiko-client/prover/shared_state/state.go b/packages/taiko-client/prover/shared_state/state.go new file mode 100644 index 00000000000..e0a4e6edc0d --- /dev/null +++ b/packages/taiko-client/prover/shared_state/state.go @@ -0,0 +1,54 @@ +package state + +import ( + "sync/atomic" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +// SharedState represents the internal state of a prover. +type SharedState struct { + lastHandledBlockID atomic.Uint64 + l1Current atomic.Value + tiers []*rpc.TierProviderTierWithID +} + +// New creates a new prover shared state instance. +func New() *SharedState { + return &SharedState{} +} + +// GetLastHandledBlockID returns the last handled block ID. +func (s *SharedState) GetLastHandledBlockID() uint64 { + return s.lastHandledBlockID.Load() +} + +// SetLastHandledBlockID sets the last handled block ID. +func (s *SharedState) SetLastHandledBlockID(blockID uint64) { + s.lastHandledBlockID.Store(blockID) +} + +// GetL1Current returns the current L1 header cursor. +func (s *SharedState) GetL1Current() *types.Header { + if val := s.l1Current.Load(); val != nil { + return val.(*types.Header) + } + return nil +} + +// SetL1Current sets the current L1 header cursor. +func (s *SharedState) SetL1Current(header *types.Header) { + s.l1Current.Store(header) +} + +// GetTiers returns the current proof tiers. +func (s *SharedState) GetTiers() []*rpc.TierProviderTierWithID { + return s.tiers +} + +// SetTiers sets the current proof tiers. +func (s *SharedState) SetTiers(tiers []*rpc.TierProviderTierWithID) { + s.tiers = tiers +} diff --git a/packages/taiko-client/prover/shared_state/state_test.go b/packages/taiko-client/prover/shared_state/state_test.go new file mode 100644 index 00000000000..bcd3a604068 --- /dev/null +++ b/packages/taiko-client/prover/shared_state/state_test.go @@ -0,0 +1,44 @@ +package state + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/suite" + + "github.com/taikoxyz/taiko-client/pkg/rpc" +) + +type ProverSharedStateTestSuite struct { + suite.Suite + state *SharedState +} + +func (s *ProverSharedStateTestSuite) SetupTest() { + s.state = New() +} + +func (s *ProverSharedStateTestSuite) TestLastHandledBlockID() { + newLastHandledBlockID := uint64(1024) + s.NotEqual(newLastHandledBlockID, s.state.GetLastHandledBlockID()) + s.state.SetLastHandledBlockID(newLastHandledBlockID) + s.Equal(newLastHandledBlockID, s.state.GetLastHandledBlockID()) +} + +func (s *ProverSharedStateTestSuite) TestL1Current() { + newL1Current := &types.Header{Number: common.Big256} + s.NotEqual(newL1Current, s.state.GetL1Current()) + s.state.SetL1Current(newL1Current) + s.Equal(newL1Current.Hash(), s.state.GetL1Current().Hash()) +} + +func (s *ProverSharedStateTestSuite) TestTiers() { + s.Empty(s.state.GetTiers()) + s.state.SetTiers([]*rpc.TierProviderTierWithID{{ID: 1}}) + s.Equal(1, len(s.state.GetTiers())) +} + +func TestProverSharedStateTestSuite(t *testing.T) { + suite.Run(t, new(ProverSharedStateTestSuite)) +} diff --git a/packages/taiko-client/release-please-config.json b/packages/taiko-client/release-please-config.json new file mode 100644 index 00000000000..21692e34a5a --- /dev/null +++ b/packages/taiko-client/release-please-config.json @@ -0,0 +1,11 @@ +{ + "release-type": "go", + "packages": { + ".": { + "extra-files": [ + "version/version.go" + ] + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} diff --git a/packages/taiko-client/scripts/common.sh b/packages/taiko-client/scripts/common.sh new file mode 100644 index 00000000000..79a317cfd2d --- /dev/null +++ b/packages/taiko-client/scripts/common.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +RED='\033[1;31m' +NC='\033[0m' # No Color + +COMPOSE="docker compose -f internal/docker/nodes/docker-compose.yml" + +print_error() { + local msg="$1" + echo -e "${RED}$msg${NC}" +} + +check_env() { + local name="$1" + local value="${!name}" + + if [ -z "$value" ]; then + print_error "$name not set in env" + exit 1 + fi +} + +check_command() { + if ! command -v "$1" &> /dev/null; then + print_error "$1 could not be found" + exit + fi +} + +compose_down() { + local services=("$@") + echo + echo "stopping services..." + $COMPOSE down "${services[@]}" #--remove-orphans + echo "done" +} + +compose_up() { + local services=("$@") + echo + echo "launching services..." + $COMPOSE up --quiet-pull "${services[@]}" -d --wait + echo "done" +} diff --git a/packages/taiko-client/scripts/gen_bindings.sh b/packages/taiko-client/scripts/gen_bindings.sh new file mode 100755 index 00000000000..7e6d516a0a4 --- /dev/null +++ b/packages/taiko-client/scripts/gen_bindings.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# Generate go contract bindings. +# ref: https://geth.ethereum.org/docs/dapp/native-bindings + +set -eou pipefail + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" + +echo "" +echo "TAIKO_MONO_DIR: ${TAIKO_MONO_DIR}" +echo "TAIKO_GETH_DIR: ${TAIKO_GETH_DIR}" +echo "" + +cd ${TAIKO_GETH_DIR} && + make all && + cd - + +cd ${TAIKO_MONO_DIR}/packages/protocol && + pnpm clean && + pnpm compile && + cd - + +ABIGEN_BIN=$TAIKO_GETH_DIR/build/bin/abigen + +echo "" +echo "Start generating go contract bindings..." +echo "" + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/TaikoL1.sol/TaikoL1.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type TaikoL1Client --pkg bindings --out $DIR/../bindings/gen_taiko_l1.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/LibProving.sol/LibProving.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type LibProving --pkg bindings --out $DIR/../bindings/gen_lib_proving.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/LibProposing.sol/LibProposing.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type LibProposing --pkg bindings --out $DIR/../bindings/gen_lib_proposing.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/LibUtils.sol/LibUtils.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type LibUtils --pkg bindings --out $DIR/../bindings/gen_lib_utils.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/LibVerifying.sol/LibVerifying.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type LibVerifying --pkg bindings --out $DIR/../bindings/gen_lib_verifying.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/TaikoL2.sol/TaikoL2.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type TaikoL2Client --pkg bindings --out $DIR/../bindings/gen_taiko_l2.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/TaikoToken.sol/TaikoToken.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type TaikoToken --pkg bindings --out $DIR/../bindings/gen_taiko_token.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/AddressManager.sol/AddressManager.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type AddressManager --pkg bindings --out $DIR/../bindings/gen_address_manager.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/GuardianProver.sol/GuardianProver.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type GuardianProver --pkg bindings --out $DIR/../bindings/gen_guardian_prover.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/AssignmentHook.sol/AssignmentHook.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type AssignmentHook --pkg bindings --out $DIR/../bindings/gen_assignment_hook.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/DevnetTierProvider.sol/DevnetTierProvider.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type TierProvider --pkg bindings --out $DIR/../bindings/gen_tier_provider.go + +cat ${TAIKO_MONO_DIR}/packages/protocol/out/SgxVerifier.sol/SgxVerifier.json | + jq .abi | + ${ABIGEN_BIN} --abi - --type SgxVerifier --pkg bindings --out $DIR/../bindings/gen_sgx_verifier.go + +git -C ${TAIKO_MONO_DIR} log --format="%H" -n 1 >./bindings/.githead + +echo "🍻 Go contract bindings generated!" diff --git a/packages/taiko-client/scripts/gen_swagger_json.sh b/packages/taiko-client/scripts/gen_swagger_json.sh new file mode 100755 index 00000000000..59dce311dbd --- /dev/null +++ b/packages/taiko-client/scripts/gen_swagger_json.sh @@ -0,0 +1,3 @@ +#/bin/sh + +swag init -g api.go -d prover/server --pd