diff --git a/.github/workflows/eventindexer.yml b/.github/workflows/eventindexer.yml
new file mode 100644
index 00000000000..5141adaaf69
--- /dev/null
+++ b/.github/workflows/eventindexer.yml
@@ -0,0 +1,99 @@
+name: Eventindexer
+
+on:
+ push:
+ branches: [main, alpha-2]
+ paths:
+ - "packages/eventindexer/**"
+ pull_request:
+ paths:
+ - "packages/eventindexer/**"
+
+jobs:
+ lint:
+ name: lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/setup-go@v3
+ with:
+ go-version: 1.19
+ - uses: actions/checkout@v3
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
+ version: latest
+
+ # Optional: working directory, useful for monorepos
+ working-directory: ./packages/eventindexer
+ args: --config=.golangci.yml
+
+ test:
+ runs-on: ubuntu-latest
+ needs: lint
+ steps:
+ - name: Cancel Previous Runs
+ uses: styfle/cancel-workflow-action@0.11.0
+ with:
+ access_token: ${{ github.token }}
+
+ - uses: actions/checkout@v3
+ - uses: actions/setup-go@v3
+ with:
+ go-version: ">=1.19.0"
+
+ - name: eventindexer - Unit Tests
+ working-directory: ./packages/eventindexer
+ run: go test `go list ./... | grep -v ./contracts | grep -v ./mock | grep -v ./cmd` -coverprofile=coverage.txt -covermode=atomic
+
+ - name: eventindexer - Upload coverage to Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ files: ./packages/eventindexer/coverage.txt
+ flags: eventindexer
+
+ push-docker-image:
+ # only push docker image on PR merge to main
+ if: ${{ github.event }} == 'push'
+ name: Build and push docker image
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Login to GCR
+ uses: docker/login-action@v2
+ with:
+ registry: gcr.io
+ username: _json_key
+ password: ${{ secrets.GCR_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: |
+ gcr.io/evmchain/eventindexer
+ 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
+ push: true
+ context: .
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ build-args: |
+ PACKAGE=eventindexer
\ No newline at end of file
diff --git a/.github/workflows/relayer.yml b/.github/workflows/relayer.yml
index 47d340b27e9..7b9ade79fd3 100644
--- a/.github/workflows/relayer.yml
+++ b/.github/workflows/relayer.yml
@@ -92,6 +92,8 @@ jobs:
with:
platforms: linux/amd64
push: true
- context: packages/relayer
+ context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+ build-args: |
+ PACKAGE=relayer
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000000..547fe6bfc51
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,27 @@
+FROM golang:1.19.3 as builder
+
+ARG PACKAGE=eventindexer
+
+RUN apt install git curl
+
+RUN mkdir /taiko-mono
+
+WORKDIR /taiko-mono
+
+COPY . .
+
+RUN go mod download
+
+WORKDIR /taiko-mono/packages/$PACKAGE
+
+RUN CGO_ENABLED=0 GOOS=linux go build -o /taiko-mono/packages/$PACKAGE/bin/${PACKAGE} /taiko-mono/packages/$PACKAGE/cmd/main.go
+
+FROM alpine:latest
+
+ARG PACKAGE
+
+RUN apk add --no-cache ca-certificates
+
+COPY --from=builder /taiko-mono/packages/$PACKAGE/bin/$PACKAGE /usr/local/bin/
+
+ENTRYPOINT ["$PACKAGE"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 4424a477c0d..e8d6d6e930c 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,7 @@ taiko-mono
├── packages
│ ├── branding: Taiko branding materials
│ ├── bridge-ui: Taiko Bridge frontend UI
+│ ├── eventindexer: Event indexer
│ ├── protocol: Taiko ZK-Rollup L2 Protocol and Taiko Bridge smart contracts
│ ├── relayer: Bridge relayer (backend)
│ ├── status-page: Taiko Protocol status page
diff --git a/packages/eventindexer/.default.env b/packages/eventindexer/.default.env
new file mode 100644
index 00000000000..9bd08910b28
--- /dev/null
+++ b/packages/eventindexer/.default.env
@@ -0,0 +1,13 @@
+HTTP_PORT=4101
+PROMETHEUS_HTTP_PORT=6061
+MYSQL_USER=root
+MYSQL_PASSWORD=root
+MYSQL_DATABASE=eventindexer
+MYSQL_HOST=localhost:3306
+MYSQL_MAX_IDLE_CONNS=50
+MYSQL_MAX_OPEN_CONNS=3000
+MYSQL_CONN_MAX_LIFETIME_IN_MS=100000
+L1_TAIKO_ADDRESS=0x7B3AF414448ba906f02a1CA307C56c4ADFF27ce7
+L1_RPC_URL=wss://l1ws.a2.taiko.xyz
+CORS_ORIGINS=*
+BLOCK_BATCH_SIZE=10
\ No newline at end of file
diff --git a/packages/eventindexer/.gitignore b/packages/eventindexer/.gitignore
new file mode 100644
index 00000000000..eeedab188e5
--- /dev/null
+++ b/packages/eventindexer/.gitignore
@@ -0,0 +1,46 @@
+.netrc
+.env
+.test.env
+main
+coverage.txt
+
+# Local .terraform directories
+.terraform
+
+# .tfstate files
+*.tfstate
+*.tfstate.*
+
+# Crash log files
+crash.log
+
+# Exclude all .tfvars files, which are likely to contain sentitive data, such as
+# password, private keys, and other secrets. These should not be part of version
+# control as they are data points which are potentially sensitive and subject
+# to change depending on the environment.
+#
+*.tfvars
+
+# Ignore override files as they are usually used to override resources locally and so
+# are not checked in
+override.tf
+override.tf.json
+*_override.tf
+*_override.tf.json
+
+# Include override files you do wish to add to version control using negated pattern
+#
+# !example_override.tf
+
+# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
+# example: *tfplan*
+
+# Ignore CLI configuration files
+.terraformrc
+terraform.rc
+
+.idea
+
+Bridge.json
+TaikoL2.json
+IHeaderSync.json
\ No newline at end of file
diff --git a/packages/eventindexer/.golangci.yml b/packages/eventindexer/.golangci.yml
new file mode 100644
index 00000000000..6d47927d8d6
--- /dev/null
+++ b/packages/eventindexer/.golangci.yml
@@ -0,0 +1,42 @@
+# See: https://golangci-lint.run/usage/configuration/
+#
+# Note: for VSCode, you must have the following settings to use this configuration:
+#
+# "go.lintTool": "golangci-lint",
+# "go.lintFlags": [
+# "--fast",
+# "--config=${workspaceFolder}/.golangci.yml"
+# ],
+
+output:
+ format: colored-line-number
+
+linters:
+ enable:
+ - errcheck
+ - funlen
+ - gocognit
+ - gocritic
+ - gofmt
+ - golint
+ - gosec
+ - gosimple
+ - lll
+ - unused
+ - whitespace
+ - wsl
+
+linters-settings:
+ funlen:
+ lines: 137
+ statements: 54
+ gocognit:
+ min-complexity: 43
+
+issues:
+ exclude-rules:
+ # Exclude some linters from running on tests files.
+ - path: _test\.go
+ linters:
+ - funlen
+
diff --git a/packages/eventindexer/README.md b/packages/eventindexer/README.md
index e6071803220..34ea0ee5318 100644
--- a/packages/eventindexer/README.md
+++ b/packages/eventindexer/README.md
@@ -9,4 +9,4 @@ Catches events, stores them in the database to be queried via API.
run `cp .default.env .env`, and add your own private key as `RELAYER_ECDSA_KEY` in `.env`. You need to be running a MySQL instance, and replace all the `MYSQL_` env vars with yours.
-Run `go run cmd/main.go --help` to see a list of possible configuration flags, or `go run cmd/main.go` to run with defaults, which will process messages from L1 to L2, and from L2 to L1, and start indexing blocks from 0.
\ No newline at end of file
+Run `go run cmd/main.go --help` to see a list of possible configuration flags, or `go run cmd/main.go` to run with defaults, which will process messages from L1 to L2, and from L2 to L1, and start indexing blocks from 0.
diff --git a/packages/eventindexer/TaikoL1.json b/packages/eventindexer/TaikoL1.json
new file mode 100644
index 00000000000..f04a963da2d
--- /dev/null
+++ b/packages/eventindexer/TaikoL1.json
@@ -0,0 +1,1134 @@
+[
+ {
+ "inputs": [],
+ "name": "L1_0_FEE_BASE",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_0_FEE_BASE",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ALREADY_PROVEN",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_CALLDATA",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_DEST",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_GAS_LIMIT",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_ADDR",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_DATA",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_LOGS",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_PROOF",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_STATUS",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_RECEIPT_TOPICS",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_SIG_R",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_SIG_S",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_TX_PROOF",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ANCHOR_TYPE",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_BLOCK_NUMBER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_BLOCK_NUMBER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_CANNOT_BE_FIRST_PROVER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_COMMITTED",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_CONFLICT_PROOF",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_CONTRACT_NOT_ALLOWED",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_DUP_PROVERS",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_EXTRA_DATA",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_GAS_LIMIT",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ID",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ID",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_INPUT_SIZE",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_INVALID_CONFIG",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_INVALID_CONFIG",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_INVALID_PARAM",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_METADATA_FIELD",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_META_MISMATCH",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_NOT_COMMITTED",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_NOT_ORACLE_PROVER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_PROOF_LENGTH",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_PROVER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_SOLO_PROPOSER",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_TOO_MANY_BLOCKS",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_TX_LIST",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "L1_ZKP",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RESOLVER_DENIED",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "RESOLVER_INVALID_ADDR",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "commitSlot",
+ "type": "uint64"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "commitHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "BlockCommitted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "l1Height",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l1Hash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "beneficiary",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "txListHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "mixHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes",
+ "name": "extraData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint64",
+ "name": "gasLimit",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "timestamp",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "commitHeight",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "commitSlot",
+ "type": "uint64"
+ }
+ ],
+ "indexed": false,
+ "internalType": "struct TaikoData.BlockMetadata",
+ "name": "meta",
+ "type": "tuple"
+ }
+ ],
+ "name": "BlockProposed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "parentHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "prover",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "provenAt",
+ "type": "uint64"
+ }
+ ],
+ "name": "BlockProven",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "BlockVerified",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "srcHeight",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "srcHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "HeaderSynced",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint8",
+ "name": "version",
+ "type": "uint8"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "addressManager",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint64",
+ "name": "commitSlot",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "commitBlock",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getBlockFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getConfig",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxNumBlocks",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "blockHashHistory",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxVerificationsPerTx",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "commitConfirmations",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "blockMaxGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxTransactionsPerBlock",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxBytesPerTxList",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "minTxGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "anchorTxGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "slotSmoothingFactor",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "rewardBurnBips",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "proposerDepositPctg",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "feeBaseMAF",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "blockTimeMAF",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "proofTimeMAF",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint64",
+ "name": "rewardMultiplierPctg",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "feeGracePeriodPctg",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "feeMaxPeriodPctg",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "blockTimeCap",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "proofTimeCap",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "bootstrapDiscountHalvingPeriod",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bool",
+ "name": "enableTokenomics",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "enablePublicInputsCheck",
+ "type": "bool"
+ },
+ {
+ "internalType": "bool",
+ "name": "enableAnchorValidation",
+ "type": "bool"
+ }
+ ],
+ "internalType": "struct TaikoData.Config",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "parentHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getForkChoice",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bytes32",
+ "name": "blockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "prover",
+ "type": "address"
+ },
+ {
+ "internalType": "uint64",
+ "name": "provenAt",
+ "type": "uint64"
+ }
+ ],
+ "internalType": "struct TaikoData.ForkChoice",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getLatestSyncedHeader",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint64",
+ "name": "provenAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "proposedAt",
+ "type": "uint64"
+ }
+ ],
+ "name": "getProofReward",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "reward",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "id",
+ "type": "uint256"
+ }
+ ],
+ "name": "getProposedBlock",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "bytes32",
+ "name": "metaHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "deposit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "proposer",
+ "type": "address"
+ },
+ {
+ "internalType": "uint64",
+ "name": "proposedAt",
+ "type": "uint64"
+ }
+ ],
+ "internalType": "struct TaikoData.ProposedBlock",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "addr",
+ "type": "address"
+ }
+ ],
+ "name": "getRewardBalance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getStateVariables",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "feeBase",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint64",
+ "name": "genesisHeight",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "genesisTimestamp",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "nextBlockId",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "lastProposedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "avgBlockTime",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "latestVerifiedHeight",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "latestVerifiedId",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "avgProofTime",
+ "type": "uint64"
+ }
+ ],
+ "internalType": "struct LibUtils.StateVariables",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "number",
+ "type": "uint256"
+ }
+ ],
+ "name": "getSyncedHeader",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_addressManager",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "_genesisBlockHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_feeBase",
+ "type": "uint256"
+ }
+ ],
+ "name": "init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "commitSlot",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "commitHeight",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "isCommitValid",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes[]",
+ "name": "inputs",
+ "type": "bytes[]"
+ }
+ ],
+ "name": "proposeBlock",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "blockId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes[]",
+ "name": "inputs",
+ "type": "bytes[]"
+ }
+ ],
+ "name": "proveBlock",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "blockId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes[]",
+ "name": "inputs",
+ "type": "bytes[]"
+ }
+ ],
+ "name": "proveBlockInvalid",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "bool",
+ "name": "allowZeroAddress",
+ "type": "bool"
+ }
+ ],
+ "name": "resolve",
+ "outputs": [
+ {
+ "internalType": "address payable",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "bool",
+ "name": "allowZeroAddress",
+ "type": "bool"
+ }
+ ],
+ "name": "resolve",
+ "outputs": [
+ {
+ "internalType": "address payable",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "hash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint8",
+ "name": "k",
+ "type": "uint8"
+ }
+ ],
+ "name": "signWithGoldenTouch",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "r",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "s",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "state",
+ "outputs": [
+ {
+ "internalType": "uint64",
+ "name": "genesisHeight",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "genesisTimestamp",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "__reservedA1",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "__reservedA2",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "feeBase",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint64",
+ "name": "nextBlockId",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "lastProposedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "avgBlockTime",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "__avgGasLimit",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "latestVerifiedHeight",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "latestVerifiedId",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "avgProofTime",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "__reservedC1",
+ "type": "uint64"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "maxBlocks",
+ "type": "uint256"
+ }
+ ],
+ "name": "verifyBlocks",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "withdrawBalance",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/packages/eventindexer/abigen.sh b/packages/eventindexer/abigen.sh
new file mode 100755
index 00000000000..a048a6c1d36
--- /dev/null
+++ b/packages/eventindexer/abigen.sh
@@ -0,0 +1,22 @@
+#/bin/sh
+
+if [ ! -d "../protocol/artifacts" ]; then
+ echo "ABI not generated in protocol package yet. Please run npm install && npx hardhat compile in ../protocol"
+ exit 1
+fi
+
+paths=("L1/TaikoL1.sol")
+
+names=("TaikoL1")
+
+for (( i = 0; i < ${#paths[@]}; ++i ));
+do
+ jq .abi ../protocol/artifacts/contracts/${paths[i]}/${names[i]}.json > ${names[i]}.json
+ lower=$(echo "${names[i]}" | tr '[:upper:]' '[:lower:]')
+ abigen --abi ${names[i]}.json \
+ --pkg $lower \
+ --type ${names[i]} \
+ --out contracts/$lower/${names[i]}.go
+done
+
+exit 0
diff --git a/packages/eventindexer/block.go b/packages/eventindexer/block.go
new file mode 100644
index 00000000000..cb8e724e835
--- /dev/null
+++ b/packages/eventindexer/block.go
@@ -0,0 +1,30 @@
+package eventindexer
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+)
+
+// Block is a database model representing simple header types
+// to keep track of our most recently processed block number and hash.
+type Block struct {
+ ID int `json:"id"`
+ Height uint64 `json:"blockHeight" gorm:"column:block_height"`
+ Hash string `json:"hash"`
+ ChainID int64 `json:"chainID"`
+}
+
+// SaveBlockOpts is required to store a new block
+type SaveBlockOpts struct {
+ Height uint64
+ Hash common.Hash
+ ChainID *big.Int
+}
+
+// BlockRepository defines methods necessary for interacting with
+// the block store.
+type BlockRepository interface {
+ Save(opts SaveBlockOpts) error
+ GetLatestBlockProcessed(chainID *big.Int) (*Block, error)
+}
diff --git a/packages/eventindexer/caller.go b/packages/eventindexer/caller.go
new file mode 100644
index 00000000000..59846dfc657
--- /dev/null
+++ b/packages/eventindexer/caller.go
@@ -0,0 +1,7 @@
+package eventindexer
+
+import "context"
+
+type Caller interface {
+ CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
+}
diff --git a/packages/eventindexer/cli/cli.go b/packages/eventindexer/cli/cli.go
new file mode 100644
index 00000000000..fe92e3b7b39
--- /dev/null
+++ b/packages/eventindexer/cli/cli.go
@@ -0,0 +1,246 @@
+package cli
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/labstack/echo/v4"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/ethclient"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/joho/godotenv"
+ "github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/db"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/http"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/indexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/repo"
+
+ "gorm.io/driver/mysql"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+)
+
+var (
+ envVars = []string{
+ "HTTP_PORT",
+ "L1_TAIKO_ADDRESS",
+ "L1_RPC_URL",
+ "MYSQL_USER",
+ "MYSQL_DATABASE",
+ "MYSQL_HOST",
+ "PROMETHEUS_HTTP_PORT",
+ }
+
+ defaultBlockBatchSize = 2
+ defaultSubscriptionBackoff = 600 * time.Second
+)
+
+func Run(
+ mode eventindexer.Mode,
+ watchMode eventindexer.WatchMode,
+) {
+ if err := loadAndValidateEnv(); err != nil {
+ log.Fatal(err)
+ }
+
+ log.SetFormatter(&log.JSONFormatter{})
+
+ db, err := openDBConnection(eventindexer.DBConnectionOpts{
+ Name: os.Getenv("MYSQL_USER"),
+ Password: os.Getenv("MYSQL_PASSWORD"),
+ Database: os.Getenv("MYSQL_DATABASE"),
+ Host: os.Getenv("MYSQL_HOST"),
+ OpenFunc: func(dsn string) (eventindexer.DB, error) {
+ gormDB, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
+ Logger: logger.Default.LogMode(logger.Silent),
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return db.New(gormDB), nil
+ },
+ })
+
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ l1EthClient, err := ethclient.Dial(os.Getenv("L1_RPC_URL"))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ srv, err := newHTTPServer(db, l1EthClient)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ forever := make(chan struct{})
+
+ go func() {
+ if err := srv.Start(fmt.Sprintf(":%v", os.Getenv("HTTP_PORT"))); err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ eventRepository, err := repo.NewEventRepository(db)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ blockRepository, err := repo.NewBlockRepository(db)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ blockBatchSize, err := strconv.Atoi(os.Getenv("BLOCK_BATCH_SIZE"))
+ if err != nil || blockBatchSize <= 0 {
+ blockBatchSize = defaultBlockBatchSize
+ }
+
+ var subscriptionBackoff time.Duration
+
+ subscriptionBackoffInSeconds, err := strconv.Atoi(os.Getenv("SUBSCRIPTION_BACKOFF_IN_SECONDS"))
+ if err != nil || subscriptionBackoffInSeconds <= 0 {
+ subscriptionBackoff = defaultSubscriptionBackoff
+ } else {
+ subscriptionBackoff = time.Duration(subscriptionBackoffInSeconds) * time.Second
+ }
+
+ l1RpcClient, err := rpc.DialContext(context.Background(), os.Getenv("L1_RPC_URL"))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ i, err := indexer.NewService(indexer.NewServiceOpts{
+ EventRepo: eventRepository,
+ BlockRepo: blockRepository,
+ EthClient: l1EthClient,
+ RPCClient: l1RpcClient,
+ SrcTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")),
+ BlockBatchSize: uint64(blockBatchSize),
+ SubscriptionBackoff: subscriptionBackoff,
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ go func() {
+ if err := i.FilterThenSubscribe(context.Background(), mode, watchMode); err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ <-forever
+}
+
+func openDBConnection(opts eventindexer.DBConnectionOpts) (eventindexer.DB, error) {
+ dsn := ""
+ if opts.Password == "" {
+ dsn = fmt.Sprintf(
+ "%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local",
+ opts.Name,
+ opts.Host,
+ opts.Database,
+ )
+ } else {
+ dsn = fmt.Sprintf(
+ "%v:%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local",
+ opts.Name,
+ opts.Password,
+ opts.Host,
+ opts.Database,
+ )
+ }
+
+ db, err := opts.OpenFunc(dsn)
+ if err != nil {
+ return nil, err
+ }
+
+ sqlDB, err := db.DB()
+ if err != nil {
+ return nil, err
+ }
+
+ var (
+ defaultMaxIdleConns = 50
+ defaultMaxOpenConns = 200
+ defaultConnMaxLifetime = 10 * time.Second
+ )
+
+ maxIdleConns, err := strconv.Atoi(os.Getenv("MYSQL_MAX_IDLE_CONNS"))
+ if err != nil || maxIdleConns <= 0 {
+ maxIdleConns = defaultMaxIdleConns
+ }
+
+ maxOpenConns, err := strconv.Atoi(os.Getenv("MYSQL_MAX_OPEN_CONNS"))
+ if err != nil || maxOpenConns <= 0 {
+ maxOpenConns = defaultMaxOpenConns
+ }
+
+ var maxLifetime time.Duration
+
+ connMaxLifetime, err := strconv.Atoi(os.Getenv("MYSQL_CONN_MAX_LIFETIME_IN_MS"))
+ if err != nil || connMaxLifetime <= 0 {
+ maxLifetime = defaultConnMaxLifetime
+ } else {
+ maxLifetime = time.Duration(connMaxLifetime)
+ }
+
+ // SetMaxOpenConns sets the maximum number of open connections to the database.
+ sqlDB.SetMaxOpenConns(maxOpenConns)
+
+ // SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
+ sqlDB.SetMaxIdleConns(maxIdleConns)
+
+ // SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
+ sqlDB.SetConnMaxLifetime(maxLifetime)
+
+ return db, nil
+}
+
+func loadAndValidateEnv() error {
+ _ = godotenv.Load()
+
+ missing := make([]string, 0)
+
+ for _, v := range envVars {
+ e := os.Getenv(v)
+ if e == "" {
+ missing = append(missing, v)
+ }
+ }
+
+ if len(missing) == 0 {
+ return nil
+ }
+
+ return errors.Errorf("Missing env vars: %v", missing)
+}
+
+func newHTTPServer(db eventindexer.DB, l1EthClient *ethclient.Client) (*http.Server, error) {
+ eventRepo, err := repo.NewEventRepository(db)
+ if err != nil {
+ return nil, err
+ }
+
+ srv, err := http.NewServer(http.NewServerOpts{
+ EventRepo: eventRepo,
+ Echo: echo.New(),
+ CorsOrigins: strings.Split(os.Getenv("CORS_ORIGINS"), ","),
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return srv, nil
+}
diff --git a/packages/eventindexer/cmd/main.go b/packages/eventindexer/cmd/main.go
new file mode 100644
index 00000000000..96f89836c04
--- /dev/null
+++ b/packages/eventindexer/cmd/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+ "flag"
+
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/cli"
+)
+
+func main() {
+ modePtr := flag.String("mode", string(eventindexer.SyncMode), `mode to run in.
+ options:
+ sync: continue syncing from previous block
+ resync: restart syncing from block 0
+ fromBlock: restart syncing from specified block number
+ `)
+
+ watchModePtr := flag.String("watch-mode", string(eventindexer.FilterAndSubscribeWatchMode), `watch mode to run in.
+ options:
+ filter: only filter previous messages
+ subscribe: only subscribe to new messages
+ filter-and-subscribe: catch up on all previous messages, then subscribe to new messages
+ `)
+
+ flag.Parse()
+
+ cli.Run(
+ eventindexer.Mode(*modePtr),
+ eventindexer.WatchMode(*watchModePtr),
+ )
+}
diff --git a/packages/eventindexer/contracts/taikol1/TaikoL1.go b/packages/eventindexer/contracts/taikol1/TaikoL1.go
new file mode 100644
index 00000000000..536a40aa63a
--- /dev/null
+++ b/packages/eventindexer/contracts/taikol1/TaikoL1.go
@@ -0,0 +1,2031 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package taikol1
+
+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
+)
+
+// LibUtilsStateVariables is an auto generated low-level Go binding around an user-defined struct.
+type LibUtilsStateVariables struct {
+ FeeBase *big.Int
+ GenesisHeight uint64
+ GenesisTimestamp uint64
+ NextBlockId uint64
+ LastProposedAt uint64
+ AvgBlockTime uint64
+ LatestVerifiedHeight uint64
+ LatestVerifiedId uint64
+ AvgProofTime uint64
+}
+
+// TaikoDataBlockMetadata is an auto generated low-level Go binding around an user-defined struct.
+type TaikoDataBlockMetadata struct {
+ Id *big.Int
+ L1Height *big.Int
+ L1Hash [32]byte
+ Beneficiary common.Address
+ TxListHash [32]byte
+ MixHash [32]byte
+ ExtraData []byte
+ GasLimit uint64
+ Timestamp uint64
+ CommitHeight uint64
+ CommitSlot uint64
+}
+
+// TaikoDataConfig is an auto generated low-level Go binding around an user-defined struct.
+type TaikoDataConfig struct {
+ ChainId *big.Int
+ MaxNumBlocks *big.Int
+ BlockHashHistory *big.Int
+ MaxVerificationsPerTx *big.Int
+ CommitConfirmations *big.Int
+ BlockMaxGasLimit *big.Int
+ MaxTransactionsPerBlock *big.Int
+ MaxBytesPerTxList *big.Int
+ MinTxGasLimit *big.Int
+ AnchorTxGasLimit *big.Int
+ SlotSmoothingFactor *big.Int
+ RewardBurnBips *big.Int
+ ProposerDepositPctg *big.Int
+ FeeBaseMAF *big.Int
+ BlockTimeMAF *big.Int
+ ProofTimeMAF *big.Int
+ RewardMultiplierPctg uint64
+ FeeGracePeriodPctg uint64
+ FeeMaxPeriodPctg uint64
+ BlockTimeCap uint64
+ ProofTimeCap uint64
+ BootstrapDiscountHalvingPeriod uint64
+ EnableTokenomics bool
+ EnablePublicInputsCheck bool
+ EnableAnchorValidation bool
+}
+
+// TaikoDataForkChoice is an auto generated low-level Go binding around an user-defined struct.
+type TaikoDataForkChoice struct {
+ BlockHash [32]byte
+ Prover common.Address
+ ProvenAt uint64
+}
+
+// TaikoDataProposedBlock is an auto generated low-level Go binding around an user-defined struct.
+type TaikoDataProposedBlock struct {
+ MetaHash [32]byte
+ Deposit *big.Int
+ Proposer common.Address
+ ProposedAt uint64
+}
+
+// TaikoL1MetaData contains all meta data concerning the TaikoL1 contract.
+var TaikoL1MetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[],\"name\":\"L1_0_FEE_BASE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_0_FEE_BASE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_CALLDATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_DEST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_ADDR\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_LOGS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_STATUS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_TOPICS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_R\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_S\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TX_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TYPE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CANNOT_BE_FIRST_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONFLICT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONTRACT_NOT_ALLOWED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_DUP_PROVERS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EXTRA_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INPUT_SIZE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_METADATA_FIELD\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_META_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROOF_LENGTH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SOLO_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ZKP\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"BlockCommitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"commitBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockHashHistory\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slotSmoothingFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeBaseMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"rewardMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"}],\"name\":\"getForkChoice\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ForkChoice\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"name\":\"getProofReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getProposedBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ProposedBlock\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getRewardBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"feeBase\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"}],\"internalType\":\"structLibUtils.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_feeBase\",\"type\":\"uint256\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"commitSlot\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitHeight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"isCommitValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proposeBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlockInvalid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"k\",\"type\":\"uint8\"}],\"name\":\"signWithGoldenTouch\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"r\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA1\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA2\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeBase\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__avgGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedC1\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxBlocks\",\"type\":\"uint256\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+}
+
+// TaikoL1ABI is the input ABI used to generate the binding from.
+// Deprecated: Use TaikoL1MetaData.ABI instead.
+var TaikoL1ABI = TaikoL1MetaData.ABI
+
+// TaikoL1 is an auto generated Go binding around an Ethereum contract.
+type TaikoL1 struct {
+ TaikoL1Caller // Read-only binding to the contract
+ TaikoL1Transactor // Write-only binding to the contract
+ TaikoL1Filterer // Log filterer for contract events
+}
+
+// TaikoL1Caller is an auto generated read-only Go binding around an Ethereum contract.
+type TaikoL1Caller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TaikoL1Transactor is an auto generated write-only Go binding around an Ethereum contract.
+type TaikoL1Transactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TaikoL1Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type TaikoL1Filterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// TaikoL1Session is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type TaikoL1Session struct {
+ Contract *TaikoL1 // 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
+}
+
+// TaikoL1CallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type TaikoL1CallerSession struct {
+ Contract *TaikoL1Caller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// TaikoL1TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type TaikoL1TransactorSession struct {
+ Contract *TaikoL1Transactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// TaikoL1Raw is an auto generated low-level Go binding around an Ethereum contract.
+type TaikoL1Raw struct {
+ Contract *TaikoL1 // Generic contract binding to access the raw methods on
+}
+
+// TaikoL1CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type TaikoL1CallerRaw struct {
+ Contract *TaikoL1Caller // Generic read-only contract binding to access the raw methods on
+}
+
+// TaikoL1TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type TaikoL1TransactorRaw struct {
+ Contract *TaikoL1Transactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewTaikoL1 creates a new instance of TaikoL1, bound to a specific deployed contract.
+func NewTaikoL1(address common.Address, backend bind.ContractBackend) (*TaikoL1, error) {
+ contract, err := bindTaikoL1(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1{TaikoL1Caller: TaikoL1Caller{contract: contract}, TaikoL1Transactor: TaikoL1Transactor{contract: contract}, TaikoL1Filterer: TaikoL1Filterer{contract: contract}}, nil
+}
+
+// NewTaikoL1Caller creates a new read-only instance of TaikoL1, bound to a specific deployed contract.
+func NewTaikoL1Caller(address common.Address, caller bind.ContractCaller) (*TaikoL1Caller, error) {
+ contract, err := bindTaikoL1(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1Caller{contract: contract}, nil
+}
+
+// NewTaikoL1Transactor creates a new write-only instance of TaikoL1, bound to a specific deployed contract.
+func NewTaikoL1Transactor(address common.Address, transactor bind.ContractTransactor) (*TaikoL1Transactor, error) {
+ contract, err := bindTaikoL1(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1Transactor{contract: contract}, nil
+}
+
+// NewTaikoL1Filterer creates a new log filterer instance of TaikoL1, bound to a specific deployed contract.
+func NewTaikoL1Filterer(address common.Address, filterer bind.ContractFilterer) (*TaikoL1Filterer, error) {
+ contract, err := bindTaikoL1(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1Filterer{contract: contract}, nil
+}
+
+// bindTaikoL1 binds a generic wrapper to an already deployed contract.
+func bindTaikoL1(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := TaikoL1MetaData.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 (_TaikoL1 *TaikoL1Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _TaikoL1.Contract.TaikoL1Caller.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 (_TaikoL1 *TaikoL1Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TaikoL1.Contract.TaikoL1Transactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TaikoL1 *TaikoL1Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TaikoL1.Contract.TaikoL1Transactor.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 (_TaikoL1 *TaikoL1CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _TaikoL1.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 (_TaikoL1 *TaikoL1TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TaikoL1.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_TaikoL1 *TaikoL1TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _TaikoL1.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 (_TaikoL1 *TaikoL1Caller) AddressManager(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _TaikoL1.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 (_TaikoL1 *TaikoL1Session) AddressManager() (common.Address, error) {
+ return _TaikoL1.Contract.AddressManager(&_TaikoL1.CallOpts)
+}
+
+// AddressManager is a free data retrieval call binding the contract method 0x3ab76e9f.
+//
+// Solidity: function addressManager() view returns(address)
+func (_TaikoL1 *TaikoL1CallerSession) AddressManager() (common.Address, error) {
+ return _TaikoL1.Contract.AddressManager(&_TaikoL1.CallOpts)
+}
+
+// GetBlockFee is a free data retrieval call binding the contract method 0x7baf0bc7.
+//
+// Solidity: function getBlockFee() view returns(uint256)
+func (_TaikoL1 *TaikoL1Caller) GetBlockFee(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getBlockFee")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+// GetBlockFee is a free data retrieval call binding the contract method 0x7baf0bc7.
+//
+// Solidity: function getBlockFee() view returns(uint256)
+func (_TaikoL1 *TaikoL1Session) GetBlockFee() (*big.Int, error) {
+ return _TaikoL1.Contract.GetBlockFee(&_TaikoL1.CallOpts)
+}
+
+// GetBlockFee is a free data retrieval call binding the contract method 0x7baf0bc7.
+//
+// Solidity: function getBlockFee() view returns(uint256)
+func (_TaikoL1 *TaikoL1CallerSession) GetBlockFee() (*big.Int, error) {
+ return _TaikoL1.Contract.GetBlockFee(&_TaikoL1.CallOpts)
+}
+
+// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4.
+//
+// Solidity: function getConfig() pure returns((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint64,uint64,uint64,uint64,uint64,uint64,bool,bool,bool))
+func (_TaikoL1 *TaikoL1Caller) GetConfig(opts *bind.CallOpts) (TaikoDataConfig, error) {
+ var out []interface{}
+ err := _TaikoL1.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() pure returns((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint64,uint64,uint64,uint64,uint64,uint64,bool,bool,bool))
+func (_TaikoL1 *TaikoL1Session) GetConfig() (TaikoDataConfig, error) {
+ return _TaikoL1.Contract.GetConfig(&_TaikoL1.CallOpts)
+}
+
+// GetConfig is a free data retrieval call binding the contract method 0xc3f909d4.
+//
+// Solidity: function getConfig() pure returns((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint64,uint64,uint64,uint64,uint64,uint64,bool,bool,bool))
+func (_TaikoL1 *TaikoL1CallerSession) GetConfig() (TaikoDataConfig, error) {
+ return _TaikoL1.Contract.GetConfig(&_TaikoL1.CallOpts)
+}
+
+// GetForkChoice is a free data retrieval call binding the contract method 0xe00ea1e1.
+//
+// Solidity: function getForkChoice(uint256 id, bytes32 parentHash) view returns((bytes32,address,uint64))
+func (_TaikoL1 *TaikoL1Caller) GetForkChoice(opts *bind.CallOpts, id *big.Int, parentHash [32]byte) (TaikoDataForkChoice, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getForkChoice", id, parentHash)
+
+ if err != nil {
+ return *new(TaikoDataForkChoice), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(TaikoDataForkChoice)).(*TaikoDataForkChoice)
+
+ return out0, err
+
+}
+
+// GetForkChoice is a free data retrieval call binding the contract method 0xe00ea1e1.
+//
+// Solidity: function getForkChoice(uint256 id, bytes32 parentHash) view returns((bytes32,address,uint64))
+func (_TaikoL1 *TaikoL1Session) GetForkChoice(id *big.Int, parentHash [32]byte) (TaikoDataForkChoice, error) {
+ return _TaikoL1.Contract.GetForkChoice(&_TaikoL1.CallOpts, id, parentHash)
+}
+
+// GetForkChoice is a free data retrieval call binding the contract method 0xe00ea1e1.
+//
+// Solidity: function getForkChoice(uint256 id, bytes32 parentHash) view returns((bytes32,address,uint64))
+func (_TaikoL1 *TaikoL1CallerSession) GetForkChoice(id *big.Int, parentHash [32]byte) (TaikoDataForkChoice, error) {
+ return _TaikoL1.Contract.GetForkChoice(&_TaikoL1.CallOpts, id, parentHash)
+}
+
+// GetLatestSyncedHeader is a free data retrieval call binding the contract method 0x5155ce9f.
+//
+// Solidity: function getLatestSyncedHeader() view returns(bytes32)
+func (_TaikoL1 *TaikoL1Caller) GetLatestSyncedHeader(opts *bind.CallOpts) ([32]byte, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getLatestSyncedHeader")
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+// GetLatestSyncedHeader is a free data retrieval call binding the contract method 0x5155ce9f.
+//
+// Solidity: function getLatestSyncedHeader() view returns(bytes32)
+func (_TaikoL1 *TaikoL1Session) GetLatestSyncedHeader() ([32]byte, error) {
+ return _TaikoL1.Contract.GetLatestSyncedHeader(&_TaikoL1.CallOpts)
+}
+
+// GetLatestSyncedHeader is a free data retrieval call binding the contract method 0x5155ce9f.
+//
+// Solidity: function getLatestSyncedHeader() view returns(bytes32)
+func (_TaikoL1 *TaikoL1CallerSession) GetLatestSyncedHeader() ([32]byte, error) {
+ return _TaikoL1.Contract.GetLatestSyncedHeader(&_TaikoL1.CallOpts)
+}
+
+// GetProofReward is a free data retrieval call binding the contract method 0x4ee56f9e.
+//
+// Solidity: function getProofReward(uint64 provenAt, uint64 proposedAt) view returns(uint256 reward)
+func (_TaikoL1 *TaikoL1Caller) GetProofReward(opts *bind.CallOpts, provenAt uint64, proposedAt uint64) (*big.Int, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getProofReward", provenAt, proposedAt)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+// GetProofReward is a free data retrieval call binding the contract method 0x4ee56f9e.
+//
+// Solidity: function getProofReward(uint64 provenAt, uint64 proposedAt) view returns(uint256 reward)
+func (_TaikoL1 *TaikoL1Session) GetProofReward(provenAt uint64, proposedAt uint64) (*big.Int, error) {
+ return _TaikoL1.Contract.GetProofReward(&_TaikoL1.CallOpts, provenAt, proposedAt)
+}
+
+// GetProofReward is a free data retrieval call binding the contract method 0x4ee56f9e.
+//
+// Solidity: function getProofReward(uint64 provenAt, uint64 proposedAt) view returns(uint256 reward)
+func (_TaikoL1 *TaikoL1CallerSession) GetProofReward(provenAt uint64, proposedAt uint64) (*big.Int, error) {
+ return _TaikoL1.Contract.GetProofReward(&_TaikoL1.CallOpts, provenAt, proposedAt)
+}
+
+// GetProposedBlock is a free data retrieval call binding the contract method 0x8972b10c.
+//
+// Solidity: function getProposedBlock(uint256 id) view returns((bytes32,uint256,address,uint64))
+func (_TaikoL1 *TaikoL1Caller) GetProposedBlock(opts *bind.CallOpts, id *big.Int) (TaikoDataProposedBlock, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getProposedBlock", id)
+
+ if err != nil {
+ return *new(TaikoDataProposedBlock), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(TaikoDataProposedBlock)).(*TaikoDataProposedBlock)
+
+ return out0, err
+
+}
+
+// GetProposedBlock is a free data retrieval call binding the contract method 0x8972b10c.
+//
+// Solidity: function getProposedBlock(uint256 id) view returns((bytes32,uint256,address,uint64))
+func (_TaikoL1 *TaikoL1Session) GetProposedBlock(id *big.Int) (TaikoDataProposedBlock, error) {
+ return _TaikoL1.Contract.GetProposedBlock(&_TaikoL1.CallOpts, id)
+}
+
+// GetProposedBlock is a free data retrieval call binding the contract method 0x8972b10c.
+//
+// Solidity: function getProposedBlock(uint256 id) view returns((bytes32,uint256,address,uint64))
+func (_TaikoL1 *TaikoL1CallerSession) GetProposedBlock(id *big.Int) (TaikoDataProposedBlock, error) {
+ return _TaikoL1.Contract.GetProposedBlock(&_TaikoL1.CallOpts, id)
+}
+
+// GetRewardBalance is a free data retrieval call binding the contract method 0xd5a849e9.
+//
+// Solidity: function getRewardBalance(address addr) view returns(uint256)
+func (_TaikoL1 *TaikoL1Caller) GetRewardBalance(opts *bind.CallOpts, addr common.Address) (*big.Int, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getRewardBalance", addr)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+// GetRewardBalance is a free data retrieval call binding the contract method 0xd5a849e9.
+//
+// Solidity: function getRewardBalance(address addr) view returns(uint256)
+func (_TaikoL1 *TaikoL1Session) GetRewardBalance(addr common.Address) (*big.Int, error) {
+ return _TaikoL1.Contract.GetRewardBalance(&_TaikoL1.CallOpts, addr)
+}
+
+// GetRewardBalance is a free data retrieval call binding the contract method 0xd5a849e9.
+//
+// Solidity: function getRewardBalance(address addr) view returns(uint256)
+func (_TaikoL1 *TaikoL1CallerSession) GetRewardBalance(addr common.Address) (*big.Int, error) {
+ return _TaikoL1.Contract.GetRewardBalance(&_TaikoL1.CallOpts, addr)
+}
+
+// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5.
+//
+// Solidity: function getStateVariables() view returns((uint256,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64))
+func (_TaikoL1 *TaikoL1Caller) GetStateVariables(opts *bind.CallOpts) (LibUtilsStateVariables, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getStateVariables")
+
+ if err != nil {
+ return *new(LibUtilsStateVariables), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(LibUtilsStateVariables)).(*LibUtilsStateVariables)
+
+ return out0, err
+
+}
+
+// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5.
+//
+// Solidity: function getStateVariables() view returns((uint256,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64))
+func (_TaikoL1 *TaikoL1Session) GetStateVariables() (LibUtilsStateVariables, error) {
+ return _TaikoL1.Contract.GetStateVariables(&_TaikoL1.CallOpts)
+}
+
+// GetStateVariables is a free data retrieval call binding the contract method 0xdde89cf5.
+//
+// Solidity: function getStateVariables() view returns((uint256,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64))
+func (_TaikoL1 *TaikoL1CallerSession) GetStateVariables() (LibUtilsStateVariables, error) {
+ return _TaikoL1.Contract.GetStateVariables(&_TaikoL1.CallOpts)
+}
+
+// GetSyncedHeader is a free data retrieval call binding the contract method 0x25bf86f2.
+//
+// Solidity: function getSyncedHeader(uint256 number) view returns(bytes32)
+func (_TaikoL1 *TaikoL1Caller) GetSyncedHeader(opts *bind.CallOpts, number *big.Int) ([32]byte, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "getSyncedHeader", number)
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+// GetSyncedHeader is a free data retrieval call binding the contract method 0x25bf86f2.
+//
+// Solidity: function getSyncedHeader(uint256 number) view returns(bytes32)
+func (_TaikoL1 *TaikoL1Session) GetSyncedHeader(number *big.Int) ([32]byte, error) {
+ return _TaikoL1.Contract.GetSyncedHeader(&_TaikoL1.CallOpts, number)
+}
+
+// GetSyncedHeader is a free data retrieval call binding the contract method 0x25bf86f2.
+//
+// Solidity: function getSyncedHeader(uint256 number) view returns(bytes32)
+func (_TaikoL1 *TaikoL1CallerSession) GetSyncedHeader(number *big.Int) ([32]byte, error) {
+ return _TaikoL1.Contract.GetSyncedHeader(&_TaikoL1.CallOpts, number)
+}
+
+// IsCommitValid is a free data retrieval call binding the contract method 0x340d9599.
+//
+// Solidity: function isCommitValid(uint256 commitSlot, uint256 commitHeight, bytes32 commitHash) view returns(bool)
+func (_TaikoL1 *TaikoL1Caller) IsCommitValid(opts *bind.CallOpts, commitSlot *big.Int, commitHeight *big.Int, commitHash [32]byte) (bool, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "isCommitValid", commitSlot, commitHeight, commitHash)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+// IsCommitValid is a free data retrieval call binding the contract method 0x340d9599.
+//
+// Solidity: function isCommitValid(uint256 commitSlot, uint256 commitHeight, bytes32 commitHash) view returns(bool)
+func (_TaikoL1 *TaikoL1Session) IsCommitValid(commitSlot *big.Int, commitHeight *big.Int, commitHash [32]byte) (bool, error) {
+ return _TaikoL1.Contract.IsCommitValid(&_TaikoL1.CallOpts, commitSlot, commitHeight, commitHash)
+}
+
+// IsCommitValid is a free data retrieval call binding the contract method 0x340d9599.
+//
+// Solidity: function isCommitValid(uint256 commitSlot, uint256 commitHeight, bytes32 commitHash) view returns(bool)
+func (_TaikoL1 *TaikoL1CallerSession) IsCommitValid(commitSlot *big.Int, commitHeight *big.Int, commitHash [32]byte) (bool, error) {
+ return _TaikoL1.Contract.IsCommitValid(&_TaikoL1.CallOpts, commitSlot, commitHeight, commitHash)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
+//
+// Solidity: function owner() view returns(address)
+func (_TaikoL1 *TaikoL1Caller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _TaikoL1.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 (_TaikoL1 *TaikoL1Session) Owner() (common.Address, error) {
+ return _TaikoL1.Contract.Owner(&_TaikoL1.CallOpts)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
+//
+// Solidity: function owner() view returns(address)
+func (_TaikoL1 *TaikoL1CallerSession) Owner() (common.Address, error) {
+ return _TaikoL1.Contract.Owner(&_TaikoL1.CallOpts)
+}
+
+// Resolve is a free data retrieval call binding the contract method 0x0ca4dffd.
+//
+// Solidity: function resolve(string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1Caller) Resolve(opts *bind.CallOpts, name string, allowZeroAddress bool) (common.Address, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "resolve", 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 0x0ca4dffd.
+//
+// Solidity: function resolve(string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1Session) Resolve(name string, allowZeroAddress bool) (common.Address, error) {
+ return _TaikoL1.Contract.Resolve(&_TaikoL1.CallOpts, name, allowZeroAddress)
+}
+
+// Resolve is a free data retrieval call binding the contract method 0x0ca4dffd.
+//
+// Solidity: function resolve(string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1CallerSession) Resolve(name string, allowZeroAddress bool) (common.Address, error) {
+ return _TaikoL1.Contract.Resolve(&_TaikoL1.CallOpts, name, allowZeroAddress)
+}
+
+// Resolve0 is a free data retrieval call binding the contract method 0x1be2bfa7.
+//
+// Solidity: function resolve(uint256 chainId, string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1Caller) Resolve0(opts *bind.CallOpts, chainId *big.Int, name string, allowZeroAddress bool) (common.Address, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "resolve0", chainId, 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 0x1be2bfa7.
+//
+// Solidity: function resolve(uint256 chainId, string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1Session) Resolve0(chainId *big.Int, name string, allowZeroAddress bool) (common.Address, error) {
+ return _TaikoL1.Contract.Resolve0(&_TaikoL1.CallOpts, chainId, name, allowZeroAddress)
+}
+
+// Resolve0 is a free data retrieval call binding the contract method 0x1be2bfa7.
+//
+// Solidity: function resolve(uint256 chainId, string name, bool allowZeroAddress) view returns(address)
+func (_TaikoL1 *TaikoL1CallerSession) Resolve0(chainId *big.Int, name string, allowZeroAddress bool) (common.Address, error) {
+ return _TaikoL1.Contract.Resolve0(&_TaikoL1.CallOpts, chainId, name, allowZeroAddress)
+}
+
+// SignWithGoldenTouch is a free data retrieval call binding the contract method 0xdadec12a.
+//
+// Solidity: function signWithGoldenTouch(bytes32 hash, uint8 k) view returns(uint8 v, uint256 r, uint256 s)
+func (_TaikoL1 *TaikoL1Caller) SignWithGoldenTouch(opts *bind.CallOpts, hash [32]byte, k uint8) (struct {
+ V uint8
+ R *big.Int
+ S *big.Int
+}, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "signWithGoldenTouch", hash, k)
+
+ outstruct := new(struct {
+ V uint8
+ R *big.Int
+ S *big.Int
+ })
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.V = *abi.ConvertType(out[0], new(uint8)).(*uint8)
+ outstruct.R = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+ outstruct.S = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
+
+ return *outstruct, err
+
+}
+
+// SignWithGoldenTouch is a free data retrieval call binding the contract method 0xdadec12a.
+//
+// Solidity: function signWithGoldenTouch(bytes32 hash, uint8 k) view returns(uint8 v, uint256 r, uint256 s)
+func (_TaikoL1 *TaikoL1Session) SignWithGoldenTouch(hash [32]byte, k uint8) (struct {
+ V uint8
+ R *big.Int
+ S *big.Int
+}, error) {
+ return _TaikoL1.Contract.SignWithGoldenTouch(&_TaikoL1.CallOpts, hash, k)
+}
+
+// SignWithGoldenTouch is a free data retrieval call binding the contract method 0xdadec12a.
+//
+// Solidity: function signWithGoldenTouch(bytes32 hash, uint8 k) view returns(uint8 v, uint256 r, uint256 s)
+func (_TaikoL1 *TaikoL1CallerSession) SignWithGoldenTouch(hash [32]byte, k uint8) (struct {
+ V uint8
+ R *big.Int
+ S *big.Int
+}, error) {
+ return _TaikoL1.Contract.SignWithGoldenTouch(&_TaikoL1.CallOpts, hash, k)
+}
+
+// State is a free data retrieval call binding the contract method 0xc19d93fb.
+//
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 latestVerifiedId, uint64 avgProofTime, uint64 __reservedC1)
+func (_TaikoL1 *TaikoL1Caller) State(opts *bind.CallOpts) (struct {
+ GenesisHeight uint64
+ GenesisTimestamp uint64
+ ReservedA1 uint64
+ ReservedA2 uint64
+ FeeBase *big.Int
+ NextBlockId uint64
+ LastProposedAt uint64
+ AvgBlockTime uint64
+ AvgGasLimit uint64
+ LatestVerifiedHeight uint64
+ LatestVerifiedId uint64
+ AvgProofTime uint64
+ ReservedC1 uint64
+}, error) {
+ var out []interface{}
+ err := _TaikoL1.contract.Call(opts, &out, "state")
+
+ outstruct := new(struct {
+ GenesisHeight uint64
+ GenesisTimestamp uint64
+ ReservedA1 uint64
+ ReservedA2 uint64
+ FeeBase *big.Int
+ NextBlockId uint64
+ LastProposedAt uint64
+ AvgBlockTime uint64
+ AvgGasLimit uint64
+ LatestVerifiedHeight uint64
+ LatestVerifiedId uint64
+ AvgProofTime uint64
+ ReservedC1 uint64
+ })
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.GenesisHeight = *abi.ConvertType(out[0], new(uint64)).(*uint64)
+ outstruct.GenesisTimestamp = *abi.ConvertType(out[1], new(uint64)).(*uint64)
+ outstruct.ReservedA1 = *abi.ConvertType(out[2], new(uint64)).(*uint64)
+ outstruct.ReservedA2 = *abi.ConvertType(out[3], new(uint64)).(*uint64)
+ outstruct.FeeBase = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
+ outstruct.NextBlockId = *abi.ConvertType(out[5], new(uint64)).(*uint64)
+ outstruct.LastProposedAt = *abi.ConvertType(out[6], new(uint64)).(*uint64)
+ outstruct.AvgBlockTime = *abi.ConvertType(out[7], new(uint64)).(*uint64)
+ outstruct.AvgGasLimit = *abi.ConvertType(out[8], new(uint64)).(*uint64)
+ outstruct.LatestVerifiedHeight = *abi.ConvertType(out[9], new(uint64)).(*uint64)
+ outstruct.LatestVerifiedId = *abi.ConvertType(out[10], new(uint64)).(*uint64)
+ outstruct.AvgProofTime = *abi.ConvertType(out[11], new(uint64)).(*uint64)
+ outstruct.ReservedC1 = *abi.ConvertType(out[12], new(uint64)).(*uint64)
+
+ return *outstruct, err
+
+}
+
+// State is a free data retrieval call binding the contract method 0xc19d93fb.
+//
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 latestVerifiedId, uint64 avgProofTime, uint64 __reservedC1)
+func (_TaikoL1 *TaikoL1Session) State() (struct {
+ GenesisHeight uint64
+ GenesisTimestamp uint64
+ ReservedA1 uint64
+ ReservedA2 uint64
+ FeeBase *big.Int
+ NextBlockId uint64
+ LastProposedAt uint64
+ AvgBlockTime uint64
+ AvgGasLimit uint64
+ LatestVerifiedHeight uint64
+ LatestVerifiedId uint64
+ AvgProofTime uint64
+ ReservedC1 uint64
+}, error) {
+ return _TaikoL1.Contract.State(&_TaikoL1.CallOpts)
+}
+
+// State is a free data retrieval call binding the contract method 0xc19d93fb.
+//
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 latestVerifiedId, uint64 avgProofTime, uint64 __reservedC1)
+func (_TaikoL1 *TaikoL1CallerSession) State() (struct {
+ GenesisHeight uint64
+ GenesisTimestamp uint64
+ ReservedA1 uint64
+ ReservedA2 uint64
+ FeeBase *big.Int
+ NextBlockId uint64
+ LastProposedAt uint64
+ AvgBlockTime uint64
+ AvgGasLimit uint64
+ LatestVerifiedHeight uint64
+ LatestVerifiedId uint64
+ AvgProofTime uint64
+ ReservedC1 uint64
+}, error) {
+ return _TaikoL1.Contract.State(&_TaikoL1.CallOpts)
+}
+
+// CommitBlock is a paid mutator transaction binding the contract method 0x7e7a262c.
+//
+// Solidity: function commitBlock(uint64 commitSlot, bytes32 commitHash) returns()
+func (_TaikoL1 *TaikoL1Transactor) CommitBlock(opts *bind.TransactOpts, commitSlot uint64, commitHash [32]byte) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "commitBlock", commitSlot, commitHash)
+}
+
+// CommitBlock is a paid mutator transaction binding the contract method 0x7e7a262c.
+//
+// Solidity: function commitBlock(uint64 commitSlot, bytes32 commitHash) returns()
+func (_TaikoL1 *TaikoL1Session) CommitBlock(commitSlot uint64, commitHash [32]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.CommitBlock(&_TaikoL1.TransactOpts, commitSlot, commitHash)
+}
+
+// CommitBlock is a paid mutator transaction binding the contract method 0x7e7a262c.
+//
+// Solidity: function commitBlock(uint64 commitSlot, bytes32 commitHash) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) CommitBlock(commitSlot uint64, commitHash [32]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.CommitBlock(&_TaikoL1.TransactOpts, commitSlot, commitHash)
+}
+
+// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
+//
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
+func (_TaikoL1 *TaikoL1Transactor) Init(opts *bind.TransactOpts, _addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "init", _addressManager, _genesisBlockHash, _feeBase)
+}
+
+// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
+//
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
+func (_TaikoL1 *TaikoL1Session) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _feeBase)
+}
+
+// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
+//
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _feeBase)
+}
+
+// ProposeBlock is a paid mutator transaction binding the contract method 0xa043dbdf.
+//
+// Solidity: function proposeBlock(bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Transactor) ProposeBlock(opts *bind.TransactOpts, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "proposeBlock", inputs)
+}
+
+// ProposeBlock is a paid mutator transaction binding the contract method 0xa043dbdf.
+//
+// Solidity: function proposeBlock(bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Session) ProposeBlock(inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProposeBlock(&_TaikoL1.TransactOpts, inputs)
+}
+
+// ProposeBlock is a paid mutator transaction binding the contract method 0xa043dbdf.
+//
+// Solidity: function proposeBlock(bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) ProposeBlock(inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProposeBlock(&_TaikoL1.TransactOpts, inputs)
+}
+
+// ProveBlock is a paid mutator transaction binding the contract method 0x8ed7b3be.
+//
+// Solidity: function proveBlock(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Transactor) ProveBlock(opts *bind.TransactOpts, blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "proveBlock", blockId, inputs)
+}
+
+// ProveBlock is a paid mutator transaction binding the contract method 0x8ed7b3be.
+//
+// Solidity: function proveBlock(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Session) ProveBlock(blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProveBlock(&_TaikoL1.TransactOpts, blockId, inputs)
+}
+
+// ProveBlock is a paid mutator transaction binding the contract method 0x8ed7b3be.
+//
+// Solidity: function proveBlock(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) ProveBlock(blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProveBlock(&_TaikoL1.TransactOpts, blockId, inputs)
+}
+
+// ProveBlockInvalid is a paid mutator transaction binding the contract method 0xa279cec7.
+//
+// Solidity: function proveBlockInvalid(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Transactor) ProveBlockInvalid(opts *bind.TransactOpts, blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "proveBlockInvalid", blockId, inputs)
+}
+
+// ProveBlockInvalid is a paid mutator transaction binding the contract method 0xa279cec7.
+//
+// Solidity: function proveBlockInvalid(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1Session) ProveBlockInvalid(blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProveBlockInvalid(&_TaikoL1.TransactOpts, blockId, inputs)
+}
+
+// ProveBlockInvalid is a paid mutator transaction binding the contract method 0xa279cec7.
+//
+// Solidity: function proveBlockInvalid(uint256 blockId, bytes[] inputs) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) ProveBlockInvalid(blockId *big.Int, inputs [][]byte) (*types.Transaction, error) {
+ return _TaikoL1.Contract.ProveBlockInvalid(&_TaikoL1.TransactOpts, blockId, inputs)
+}
+
+// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6.
+//
+// Solidity: function renounceOwnership() returns()
+func (_TaikoL1 *TaikoL1Transactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "renounceOwnership")
+}
+
+// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6.
+//
+// Solidity: function renounceOwnership() returns()
+func (_TaikoL1 *TaikoL1Session) RenounceOwnership() (*types.Transaction, error) {
+ return _TaikoL1.Contract.RenounceOwnership(&_TaikoL1.TransactOpts)
+}
+
+// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6.
+//
+// Solidity: function renounceOwnership() returns()
+func (_TaikoL1 *TaikoL1TransactorSession) RenounceOwnership() (*types.Transaction, error) {
+ return _TaikoL1.Contract.RenounceOwnership(&_TaikoL1.TransactOpts)
+}
+
+// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b.
+//
+// Solidity: function transferOwnership(address newOwner) returns()
+func (_TaikoL1 *TaikoL1Transactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "transferOwnership", newOwner)
+}
+
+// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b.
+//
+// Solidity: function transferOwnership(address newOwner) returns()
+func (_TaikoL1 *TaikoL1Session) TransferOwnership(newOwner common.Address) (*types.Transaction, error) {
+ return _TaikoL1.Contract.TransferOwnership(&_TaikoL1.TransactOpts, newOwner)
+}
+
+// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b.
+//
+// Solidity: function transferOwnership(address newOwner) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) {
+ return _TaikoL1.Contract.TransferOwnership(&_TaikoL1.TransactOpts, newOwner)
+}
+
+// VerifyBlocks is a paid mutator transaction binding the contract method 0x2fb5ae0a.
+//
+// Solidity: function verifyBlocks(uint256 maxBlocks) returns()
+func (_TaikoL1 *TaikoL1Transactor) VerifyBlocks(opts *bind.TransactOpts, maxBlocks *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "verifyBlocks", maxBlocks)
+}
+
+// VerifyBlocks is a paid mutator transaction binding the contract method 0x2fb5ae0a.
+//
+// Solidity: function verifyBlocks(uint256 maxBlocks) returns()
+func (_TaikoL1 *TaikoL1Session) VerifyBlocks(maxBlocks *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.VerifyBlocks(&_TaikoL1.TransactOpts, maxBlocks)
+}
+
+// VerifyBlocks is a paid mutator transaction binding the contract method 0x2fb5ae0a.
+//
+// Solidity: function verifyBlocks(uint256 maxBlocks) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) VerifyBlocks(maxBlocks *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.VerifyBlocks(&_TaikoL1.TransactOpts, maxBlocks)
+}
+
+// WithdrawBalance is a paid mutator transaction binding the contract method 0x5fd8c710.
+//
+// Solidity: function withdrawBalance() returns()
+func (_TaikoL1 *TaikoL1Transactor) WithdrawBalance(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "withdrawBalance")
+}
+
+// WithdrawBalance is a paid mutator transaction binding the contract method 0x5fd8c710.
+//
+// Solidity: function withdrawBalance() returns()
+func (_TaikoL1 *TaikoL1Session) WithdrawBalance() (*types.Transaction, error) {
+ return _TaikoL1.Contract.WithdrawBalance(&_TaikoL1.TransactOpts)
+}
+
+// WithdrawBalance is a paid mutator transaction binding the contract method 0x5fd8c710.
+//
+// Solidity: function withdrawBalance() returns()
+func (_TaikoL1 *TaikoL1TransactorSession) WithdrawBalance() (*types.Transaction, error) {
+ return _TaikoL1.Contract.WithdrawBalance(&_TaikoL1.TransactOpts)
+}
+
+// TaikoL1BlockCommittedIterator is returned from FilterBlockCommitted and is used to iterate over the raw logs and unpacked data for BlockCommitted events raised by the TaikoL1 contract.
+type TaikoL1BlockCommittedIterator struct {
+ Event *TaikoL1BlockCommitted // 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 *TaikoL1BlockCommittedIterator) 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(TaikoL1BlockCommitted)
+ 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(TaikoL1BlockCommitted)
+ 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 *TaikoL1BlockCommittedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1BlockCommittedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1BlockCommitted represents a BlockCommitted event raised by the TaikoL1 contract.
+type TaikoL1BlockCommitted struct {
+ CommitSlot uint64
+ CommitHash [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterBlockCommitted is a free log retrieval operation binding the contract event 0x51264991e22d808f3bcbb1cbffa82b752eae327c24055259a5c455c0aa5b7136.
+//
+// Solidity: event BlockCommitted(uint64 commitSlot, bytes32 commitHash)
+func (_TaikoL1 *TaikoL1Filterer) FilterBlockCommitted(opts *bind.FilterOpts) (*TaikoL1BlockCommittedIterator, error) {
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "BlockCommitted")
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1BlockCommittedIterator{contract: _TaikoL1.contract, event: "BlockCommitted", logs: logs, sub: sub}, nil
+}
+
+// WatchBlockCommitted is a free log subscription operation binding the contract event 0x51264991e22d808f3bcbb1cbffa82b752eae327c24055259a5c455c0aa5b7136.
+//
+// Solidity: event BlockCommitted(uint64 commitSlot, bytes32 commitHash)
+func (_TaikoL1 *TaikoL1Filterer) WatchBlockCommitted(opts *bind.WatchOpts, sink chan<- *TaikoL1BlockCommitted) (event.Subscription, error) {
+
+ logs, sub, err := _TaikoL1.contract.WatchLogs(opts, "BlockCommitted")
+ 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(TaikoL1BlockCommitted)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockCommitted", 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
+}
+
+// ParseBlockCommitted is a log parse operation binding the contract event 0x51264991e22d808f3bcbb1cbffa82b752eae327c24055259a5c455c0aa5b7136.
+//
+// Solidity: event BlockCommitted(uint64 commitSlot, bytes32 commitHash)
+func (_TaikoL1 *TaikoL1Filterer) ParseBlockCommitted(log types.Log) (*TaikoL1BlockCommitted, error) {
+ event := new(TaikoL1BlockCommitted)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockCommitted", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1BlockProposedIterator is returned from FilterBlockProposed and is used to iterate over the raw logs and unpacked data for BlockProposed events raised by the TaikoL1 contract.
+type TaikoL1BlockProposedIterator struct {
+ Event *TaikoL1BlockProposed // 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 *TaikoL1BlockProposedIterator) 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(TaikoL1BlockProposed)
+ 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(TaikoL1BlockProposed)
+ 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 *TaikoL1BlockProposedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1BlockProposedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1BlockProposed represents a BlockProposed event raised by the TaikoL1 contract.
+type TaikoL1BlockProposed struct {
+ Id *big.Int
+ Meta TaikoDataBlockMetadata
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterBlockProposed is a free log retrieval operation binding the contract event 0x344fc5d5f80c4a29bd7e06ad7c28a0c8c9c08d682129da3a31936d5982e4f044.
+//
+// Solidity: event BlockProposed(uint256 indexed id, (uint256,uint256,bytes32,address,bytes32,bytes32,bytes,uint64,uint64,uint64,uint64) meta)
+func (_TaikoL1 *TaikoL1Filterer) FilterBlockProposed(opts *bind.FilterOpts, id []*big.Int) (*TaikoL1BlockProposedIterator, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "BlockProposed", idRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1BlockProposedIterator{contract: _TaikoL1.contract, event: "BlockProposed", logs: logs, sub: sub}, nil
+}
+
+// WatchBlockProposed is a free log subscription operation binding the contract event 0x344fc5d5f80c4a29bd7e06ad7c28a0c8c9c08d682129da3a31936d5982e4f044.
+//
+// Solidity: event BlockProposed(uint256 indexed id, (uint256,uint256,bytes32,address,bytes32,bytes32,bytes,uint64,uint64,uint64,uint64) meta)
+func (_TaikoL1 *TaikoL1Filterer) WatchBlockProposed(opts *bind.WatchOpts, sink chan<- *TaikoL1BlockProposed, id []*big.Int) (event.Subscription, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.WatchLogs(opts, "BlockProposed", idRule)
+ 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(TaikoL1BlockProposed)
+ if err := _TaikoL1.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 0x344fc5d5f80c4a29bd7e06ad7c28a0c8c9c08d682129da3a31936d5982e4f044.
+//
+// Solidity: event BlockProposed(uint256 indexed id, (uint256,uint256,bytes32,address,bytes32,bytes32,bytes,uint64,uint64,uint64,uint64) meta)
+func (_TaikoL1 *TaikoL1Filterer) ParseBlockProposed(log types.Log) (*TaikoL1BlockProposed, error) {
+ event := new(TaikoL1BlockProposed)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockProposed", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1BlockProvenIterator is returned from FilterBlockProven and is used to iterate over the raw logs and unpacked data for BlockProven events raised by the TaikoL1 contract.
+type TaikoL1BlockProvenIterator struct {
+ Event *TaikoL1BlockProven // 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 *TaikoL1BlockProvenIterator) 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(TaikoL1BlockProven)
+ 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(TaikoL1BlockProven)
+ 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 *TaikoL1BlockProvenIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1BlockProvenIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1BlockProven represents a BlockProven event raised by the TaikoL1 contract.
+type TaikoL1BlockProven struct {
+ Id *big.Int
+ ParentHash [32]byte
+ BlockHash [32]byte
+ Prover common.Address
+ ProvenAt uint64
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterBlockProven is a free log retrieval operation binding the contract event 0x45848a3b2a67571e5876283456675aa3e05880e4f5a73447bd86cef5a181db38.
+//
+// Solidity: event BlockProven(uint256 indexed id, bytes32 parentHash, bytes32 blockHash, address prover, uint64 provenAt)
+func (_TaikoL1 *TaikoL1Filterer) FilterBlockProven(opts *bind.FilterOpts, id []*big.Int) (*TaikoL1BlockProvenIterator, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "BlockProven", idRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1BlockProvenIterator{contract: _TaikoL1.contract, event: "BlockProven", logs: logs, sub: sub}, nil
+}
+
+// WatchBlockProven is a free log subscription operation binding the contract event 0x45848a3b2a67571e5876283456675aa3e05880e4f5a73447bd86cef5a181db38.
+//
+// Solidity: event BlockProven(uint256 indexed id, bytes32 parentHash, bytes32 blockHash, address prover, uint64 provenAt)
+func (_TaikoL1 *TaikoL1Filterer) WatchBlockProven(opts *bind.WatchOpts, sink chan<- *TaikoL1BlockProven, id []*big.Int) (event.Subscription, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.WatchLogs(opts, "BlockProven", idRule)
+ 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(TaikoL1BlockProven)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockProven", 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
+}
+
+// ParseBlockProven is a log parse operation binding the contract event 0x45848a3b2a67571e5876283456675aa3e05880e4f5a73447bd86cef5a181db38.
+//
+// Solidity: event BlockProven(uint256 indexed id, bytes32 parentHash, bytes32 blockHash, address prover, uint64 provenAt)
+func (_TaikoL1 *TaikoL1Filterer) ParseBlockProven(log types.Log) (*TaikoL1BlockProven, error) {
+ event := new(TaikoL1BlockProven)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockProven", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1BlockVerifiedIterator is returned from FilterBlockVerified and is used to iterate over the raw logs and unpacked data for BlockVerified events raised by the TaikoL1 contract.
+type TaikoL1BlockVerifiedIterator struct {
+ Event *TaikoL1BlockVerified // 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 *TaikoL1BlockVerifiedIterator) 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(TaikoL1BlockVerified)
+ 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(TaikoL1BlockVerified)
+ 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 *TaikoL1BlockVerifiedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1BlockVerifiedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1BlockVerified represents a BlockVerified event raised by the TaikoL1 contract.
+type TaikoL1BlockVerified struct {
+ Id *big.Int
+ BlockHash [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterBlockVerified is a free log retrieval operation binding the contract event 0x68b82650828a9621868d09dc161400acbe189fa002e3fb7cf9dea5c2c6f928ee.
+//
+// Solidity: event BlockVerified(uint256 indexed id, bytes32 blockHash)
+func (_TaikoL1 *TaikoL1Filterer) FilterBlockVerified(opts *bind.FilterOpts, id []*big.Int) (*TaikoL1BlockVerifiedIterator, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "BlockVerified", idRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1BlockVerifiedIterator{contract: _TaikoL1.contract, event: "BlockVerified", logs: logs, sub: sub}, nil
+}
+
+// WatchBlockVerified is a free log subscription operation binding the contract event 0x68b82650828a9621868d09dc161400acbe189fa002e3fb7cf9dea5c2c6f928ee.
+//
+// Solidity: event BlockVerified(uint256 indexed id, bytes32 blockHash)
+func (_TaikoL1 *TaikoL1Filterer) WatchBlockVerified(opts *bind.WatchOpts, sink chan<- *TaikoL1BlockVerified, id []*big.Int) (event.Subscription, error) {
+
+ var idRule []interface{}
+ for _, idItem := range id {
+ idRule = append(idRule, idItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.WatchLogs(opts, "BlockVerified", idRule)
+ 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(TaikoL1BlockVerified)
+ if err := _TaikoL1.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 0x68b82650828a9621868d09dc161400acbe189fa002e3fb7cf9dea5c2c6f928ee.
+//
+// Solidity: event BlockVerified(uint256 indexed id, bytes32 blockHash)
+func (_TaikoL1 *TaikoL1Filterer) ParseBlockVerified(log types.Log) (*TaikoL1BlockVerified, error) {
+ event := new(TaikoL1BlockVerified)
+ if err := _TaikoL1.contract.UnpackLog(event, "BlockVerified", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1HeaderSyncedIterator is returned from FilterHeaderSynced and is used to iterate over the raw logs and unpacked data for HeaderSynced events raised by the TaikoL1 contract.
+type TaikoL1HeaderSyncedIterator struct {
+ Event *TaikoL1HeaderSynced // 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 *TaikoL1HeaderSyncedIterator) 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(TaikoL1HeaderSynced)
+ 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(TaikoL1HeaderSynced)
+ 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 *TaikoL1HeaderSyncedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1HeaderSyncedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1HeaderSynced represents a HeaderSynced event raised by the TaikoL1 contract.
+type TaikoL1HeaderSynced struct {
+ SrcHeight *big.Int
+ SrcHash [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterHeaderSynced is a free log retrieval operation binding the contract event 0x58313b60ec6c5bfc381e52f0de3ede0faac3cdffea26f7d6bcc3d09b61018691.
+//
+// Solidity: event HeaderSynced(uint256 indexed srcHeight, bytes32 srcHash)
+func (_TaikoL1 *TaikoL1Filterer) FilterHeaderSynced(opts *bind.FilterOpts, srcHeight []*big.Int) (*TaikoL1HeaderSyncedIterator, error) {
+
+ var srcHeightRule []interface{}
+ for _, srcHeightItem := range srcHeight {
+ srcHeightRule = append(srcHeightRule, srcHeightItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "HeaderSynced", srcHeightRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1HeaderSyncedIterator{contract: _TaikoL1.contract, event: "HeaderSynced", logs: logs, sub: sub}, nil
+}
+
+// WatchHeaderSynced is a free log subscription operation binding the contract event 0x58313b60ec6c5bfc381e52f0de3ede0faac3cdffea26f7d6bcc3d09b61018691.
+//
+// Solidity: event HeaderSynced(uint256 indexed srcHeight, bytes32 srcHash)
+func (_TaikoL1 *TaikoL1Filterer) WatchHeaderSynced(opts *bind.WatchOpts, sink chan<- *TaikoL1HeaderSynced, srcHeight []*big.Int) (event.Subscription, error) {
+
+ var srcHeightRule []interface{}
+ for _, srcHeightItem := range srcHeight {
+ srcHeightRule = append(srcHeightRule, srcHeightItem)
+ }
+
+ logs, sub, err := _TaikoL1.contract.WatchLogs(opts, "HeaderSynced", srcHeightRule)
+ 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(TaikoL1HeaderSynced)
+ if err := _TaikoL1.contract.UnpackLog(event, "HeaderSynced", 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
+}
+
+// ParseHeaderSynced is a log parse operation binding the contract event 0x58313b60ec6c5bfc381e52f0de3ede0faac3cdffea26f7d6bcc3d09b61018691.
+//
+// Solidity: event HeaderSynced(uint256 indexed srcHeight, bytes32 srcHash)
+func (_TaikoL1 *TaikoL1Filterer) ParseHeaderSynced(log types.Log) (*TaikoL1HeaderSynced, error) {
+ event := new(TaikoL1HeaderSynced)
+ if err := _TaikoL1.contract.UnpackLog(event, "HeaderSynced", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1InitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TaikoL1 contract.
+type TaikoL1InitializedIterator struct {
+ Event *TaikoL1Initialized // 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 *TaikoL1InitializedIterator) 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(TaikoL1Initialized)
+ 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(TaikoL1Initialized)
+ 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 *TaikoL1InitializedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1InitializedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1Initialized represents a Initialized event raised by the TaikoL1 contract.
+type TaikoL1Initialized 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 (_TaikoL1 *TaikoL1Filterer) FilterInitialized(opts *bind.FilterOpts) (*TaikoL1InitializedIterator, error) {
+
+ logs, sub, err := _TaikoL1.contract.FilterLogs(opts, "Initialized")
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1InitializedIterator{contract: _TaikoL1.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 (_TaikoL1 *TaikoL1Filterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TaikoL1Initialized) (event.Subscription, error) {
+
+ logs, sub, err := _TaikoL1.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(TaikoL1Initialized)
+ if err := _TaikoL1.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 (_TaikoL1 *TaikoL1Filterer) ParseInitialized(log types.Log) (*TaikoL1Initialized, error) {
+ event := new(TaikoL1Initialized)
+ if err := _TaikoL1.contract.UnpackLog(event, "Initialized", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+// TaikoL1OwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TaikoL1 contract.
+type TaikoL1OwnershipTransferredIterator struct {
+ Event *TaikoL1OwnershipTransferred // 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 *TaikoL1OwnershipTransferredIterator) 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(TaikoL1OwnershipTransferred)
+ 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(TaikoL1OwnershipTransferred)
+ 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 *TaikoL1OwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *TaikoL1OwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// TaikoL1OwnershipTransferred represents a OwnershipTransferred event raised by the TaikoL1 contract.
+type TaikoL1OwnershipTransferred 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 (_TaikoL1 *TaikoL1Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TaikoL1OwnershipTransferredIterator, 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 := _TaikoL1.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule)
+ if err != nil {
+ return nil, err
+ }
+ return &TaikoL1OwnershipTransferredIterator{contract: _TaikoL1.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 (_TaikoL1 *TaikoL1Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TaikoL1OwnershipTransferred, 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 := _TaikoL1.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(TaikoL1OwnershipTransferred)
+ if err := _TaikoL1.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 (_TaikoL1 *TaikoL1Filterer) ParseOwnershipTransferred(log types.Log) (*TaikoL1OwnershipTransferred, error) {
+ event := new(TaikoL1OwnershipTransferred)
+ if err := _TaikoL1.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
diff --git a/packages/eventindexer/db.go b/packages/eventindexer/db.go
new file mode 100644
index 00000000000..531c2b6f3ca
--- /dev/null
+++ b/packages/eventindexer/db.go
@@ -0,0 +1,25 @@
+package eventindexer
+
+import (
+ "database/sql"
+
+ "github.com/cyberhorsey/errors"
+ "gorm.io/gorm"
+)
+
+var (
+ ErrNoDB = errors.Validation.NewWithKeyAndDetail("ERR_NO_DB", "DB is required")
+)
+
+type DBConnectionOpts struct {
+ Name string
+ Password string
+ Host string
+ Database string
+ OpenFunc func(dsn string) (DB, error)
+}
+
+type DB interface {
+ DB() (*sql.DB, error)
+ GormDB() *gorm.DB
+}
diff --git a/packages/eventindexer/db/db.go b/packages/eventindexer/db/db.go
new file mode 100644
index 00000000000..4f557011cfc
--- /dev/null
+++ b/packages/eventindexer/db/db.go
@@ -0,0 +1,25 @@
+package db
+
+import (
+ "database/sql"
+
+ "gorm.io/gorm"
+)
+
+type DB struct {
+ gormdb *gorm.DB
+}
+
+func (db *DB) DB() (*sql.DB, error) {
+ return db.gormdb.DB()
+}
+
+func (db *DB) GormDB() *gorm.DB {
+ return db.gormdb
+}
+
+func New(gormdb *gorm.DB) *DB {
+ return &DB{
+ gormdb: gormdb,
+ }
+}
diff --git a/packages/eventindexer/errors.go b/packages/eventindexer/errors.go
new file mode 100644
index 00000000000..3d9ff825457
--- /dev/null
+++ b/packages/eventindexer/errors.go
@@ -0,0 +1,15 @@
+package eventindexer
+
+import "github.com/cyberhorsey/errors"
+
+var (
+ ErrNoEthClient = errors.Validation.NewWithKeyAndDetail("ERR_NO_ETH_CLIENT", "EthClient is required")
+ ErrNoEventRepository = errors.Validation.NewWithKeyAndDetail("ERR_NO_EVENT_REPOSITORY", "EventRepository is required")
+ ErrNoBlockRepository = errors.Validation.NewWithKeyAndDetail(
+ "ERR_NO_BLOCK_REPOSITORY",
+ "BlockRepository is required",
+ )
+ ErrNoCORSOrigins = errors.Validation.NewWithKeyAndDetail("ERR_NO_CORS_ORIGINS", "CORS Origins are required")
+ ErrNoRPCClient = errors.Validation.NewWithKeyAndDetail("ERR_NO_RPC_CLIENT", "RPCClient is required")
+ ErrInvalidMode = errors.Validation.NewWithKeyAndDetail("ERR_INVALID_MODE", "Mode not supported")
+)
diff --git a/packages/eventindexer/event.go b/packages/eventindexer/event.go
new file mode 100644
index 00000000000..1e0b67bfb6c
--- /dev/null
+++ b/packages/eventindexer/event.go
@@ -0,0 +1,46 @@
+package eventindexer
+
+import (
+ "context"
+ "math/big"
+
+ "gorm.io/datatypes"
+)
+
+var (
+ EventNameBlockProven = "BlockProven"
+)
+
+// Event represents a stored EVM event. The fields will be serialized
+// into the Data field to be unmarshalled into a concrete struct
+// dependant on the name of the event
+type Event struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ Data datatypes.JSON `json:"data"`
+ ChainID int64 `json:"chainID"`
+ Event string `json:"event"`
+ Address string `json:"address"`
+}
+
+// SaveEventOpts
+type SaveEventOpts struct {
+ Name string
+ Data string
+ ChainID *big.Int
+ Event string
+ Address string
+}
+
+type UniqueProversResponse struct {
+ Address string `json:"address"`
+ Count int `json:"count"`
+}
+
+// EventRepository is used to interact with events in the store
+type EventRepository interface {
+ Save(ctx context.Context, opts SaveEventOpts) (*Event, error)
+ FindUniqueProvers(
+ ctx context.Context,
+ ) ([]UniqueProversResponse, error)
+}
diff --git a/packages/eventindexer/flags.go b/packages/eventindexer/flags.go
new file mode 100644
index 00000000000..523f62f7dcc
--- /dev/null
+++ b/packages/eventindexer/flags.go
@@ -0,0 +1,20 @@
+package eventindexer
+
+type Mode string
+
+var (
+ SyncMode Mode = "sync"
+ ResyncMode Mode = "resync"
+ Modes = []Mode{SyncMode, ResyncMode}
+)
+
+type WatchMode string
+
+var (
+ FilterWatchMode WatchMode = "filter"
+ SubscribeWatchMode WatchMode = "subscribe"
+ FilterAndSubscribeWatchMode WatchMode = "filter-and-subscribe"
+ WatchModes = []WatchMode{FilterWatchMode, SubscribeWatchMode}
+)
+
+type HTTPOnly bool
diff --git a/packages/eventindexer/http/errors.go b/packages/eventindexer/http/errors.go
new file mode 100644
index 00000000000..438fea9c9d9
--- /dev/null
+++ b/packages/eventindexer/http/errors.go
@@ -0,0 +1,14 @@
+package http
+
+import "github.com/cyberhorsey/errors"
+
+var (
+ ErrNoHTTPFramework = errors.Validation.NewWithKeyAndDetail(
+ "ERR_NO_HTTP_ENGINE",
+ "HTTP framework required",
+ )
+ ErrNoRewarder = errors.Validation.NewWithKeyAndDetail(
+ "ERR_NO_REWARDER",
+ "Rewarder is required",
+ )
+)
diff --git a/packages/eventindexer/http/get_unique_provers.go b/packages/eventindexer/http/get_unique_provers.go
new file mode 100644
index 00000000000..649cb1e2bca
--- /dev/null
+++ b/packages/eventindexer/http/get_unique_provers.go
@@ -0,0 +1,28 @@
+package http
+
+import (
+ "net/http"
+
+ "github.com/cyberhorsey/webutils"
+ "github.com/labstack/echo/v4"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+)
+
+type uniqueProversResp struct {
+ Provers []eventindexer.UniqueProversResponse `json:"provers"`
+ UniqueProvers int `json:"uniqueProvers"`
+}
+
+func (srv *Server) GetUniqueProvers(c echo.Context) error {
+ provers, err := srv.eventRepo.FindUniqueProvers(
+ c.Request().Context(),
+ )
+ if err != nil {
+ return webutils.LogAndRenderErrors(c, http.StatusUnprocessableEntity, err)
+ }
+
+ return c.JSON(http.StatusOK, &uniqueProversResp{
+ Provers: provers,
+ UniqueProvers: len(provers),
+ })
+}
diff --git a/packages/eventindexer/http/routes.go b/packages/eventindexer/http/routes.go
new file mode 100644
index 00000000000..7e45ea41127
--- /dev/null
+++ b/packages/eventindexer/http/routes.go
@@ -0,0 +1,8 @@
+package http
+
+func (srv *Server) configureRoutes() {
+ srv.echo.GET("/healthz", srv.Health)
+ srv.echo.GET("/", srv.Health)
+
+ srv.echo.GET("/uniqueProvers", srv.GetUniqueProvers)
+}
diff --git a/packages/eventindexer/http/server.go b/packages/eventindexer/http/server.go
new file mode 100644
index 00000000000..5234f4dddd7
--- /dev/null
+++ b/packages/eventindexer/http/server.go
@@ -0,0 +1,126 @@
+package http
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "os"
+
+ "github.com/labstack/echo/v4/middleware"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+
+ echoprom "github.com/labstack/echo-contrib/prometheus"
+ echo "github.com/labstack/echo/v4"
+)
+
+type Server struct {
+ echo *echo.Echo
+ eventRepo eventindexer.EventRepository
+}
+
+type NewServerOpts struct {
+ Echo *echo.Echo
+ EventRepo eventindexer.EventRepository
+ CorsOrigins []string
+}
+
+func (opts NewServerOpts) Validate() error {
+ if opts.Echo == nil {
+ return ErrNoHTTPFramework
+ }
+
+ if opts.EventRepo == nil {
+ return eventindexer.ErrNoEventRepository
+ }
+
+ if opts.CorsOrigins == nil {
+ return eventindexer.ErrNoCORSOrigins
+ }
+
+ return nil
+}
+
+func NewServer(opts NewServerOpts) (*Server, error) {
+ if err := opts.Validate(); err != nil {
+ return nil, err
+ }
+
+ srv := &Server{
+ echo: opts.Echo,
+ eventRepo: opts.EventRepo,
+ }
+
+ corsOrigins := opts.CorsOrigins
+ if corsOrigins == nil {
+ corsOrigins = []string{"*"}
+ }
+
+ srv.configureMiddleware(corsOrigins)
+ srv.configureRoutes()
+
+ return srv, nil
+}
+
+// Start starts the HTTP server
+func (srv *Server) Start(address string) error {
+ return srv.echo.Start(address)
+}
+
+// Shutdown shuts down the HTTP server
+func (srv *Server) Shutdown(ctx context.Context) error {
+ return srv.echo.Shutdown(ctx)
+}
+
+// ServeHTTP implements the `http.Handler` interface which serves HTTP requests
+func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ srv.echo.ServeHTTP(w, r)
+}
+
+// Health endpoints for probes
+func (srv *Server) Health(c echo.Context) error {
+ return c.NoContent(http.StatusOK)
+}
+
+func LogSkipper(c echo.Context) bool {
+ switch c.Request().URL.Path {
+ case "/healthz":
+ return true
+ case "/metrics":
+ return true
+ default:
+ return false
+ }
+}
+
+func (srv *Server) configureMiddleware(corsOrigins []string) {
+ srv.echo.Use(middleware.RequestID())
+
+ srv.echo.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
+ Skipper: LogSkipper,
+ Format: `{"time":"${time_rfc3339_nano}","level":"INFO","message":{"id":"${id}","remote_ip":"${remote_ip}",` + //nolint:lll
+ `"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` + //nolint:lll
+ `"response_status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}",` +
+ `"bytes_in":${bytes_in},"bytes_out":${bytes_out}}}` + "\n",
+ Output: os.Stdout,
+ }))
+
+ srv.echo.Use(middleware.CORSWithConfig(middleware.CORSConfig{
+ AllowOrigins: corsOrigins,
+ AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
+ AllowMethods: []string{http.MethodGet, http.MethodHead},
+ }))
+
+ srv.configureAndStartPrometheus()
+}
+
+func (srv *Server) configureAndStartPrometheus() {
+ // Enable metrics middleware
+ p := echoprom.NewPrometheus("echo", nil)
+ p.Use(srv.echo)
+ e := echo.New()
+ p.SetMetricsPath(e)
+
+ go func() {
+ _ = e.Start(fmt.Sprintf(":%v", os.Getenv("PROMETHEUS_HTTP_PORT")))
+ }()
+}
diff --git a/packages/eventindexer/indexer/filter_then_subscribe.go b/packages/eventindexer/indexer/filter_then_subscribe.go
new file mode 100644
index 00000000000..5afcbca1897
--- /dev/null
+++ b/packages/eventindexer/indexer/filter_then_subscribe.go
@@ -0,0 +1,112 @@
+package indexer
+
+import (
+ "context"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+)
+
+func (svc *Service) FilterThenSubscribe(
+ ctx context.Context,
+ mode eventindexer.Mode,
+ watchMode eventindexer.WatchMode,
+) error {
+ chainID, err := svc.ethClient.ChainID(ctx)
+ if err != nil {
+ return errors.Wrap(err, "svc.ethClient.ChainID()")
+ }
+
+ if watchMode == eventindexer.SubscribeWatchMode {
+ return svc.subscribe(ctx, chainID)
+ }
+
+ if err := svc.setInitialProcessingBlockByMode(ctx, mode, chainID); err != nil {
+ return errors.Wrap(err, "svc.setInitialProcessingBlockByMode")
+ }
+
+ header, err := svc.ethClient.HeaderByNumber(ctx, nil)
+ if err != nil {
+ return errors.Wrap(err, "svc.ethClient.HeaderByNumber")
+ }
+
+ if svc.processingBlockHeight == header.Number.Uint64() {
+ log.Infof("chain ID %v caught up, subscribing to new incoming events", chainID.Uint64())
+ return svc.subscribe(ctx, chainID)
+ }
+
+ log.Infof("chain ID %v getting events between %v and %v in batches of %v",
+ chainID.Uint64(),
+ svc.processingBlockHeight,
+ header.Number.Int64(),
+ svc.blockBatchSize,
+ )
+
+ for i := svc.processingBlockHeight; i < header.Number.Uint64(); i += svc.blockBatchSize {
+ end := svc.processingBlockHeight + svc.blockBatchSize
+ // if the end of the batch is greater than the latest block number, set end
+ // to the latest block number
+ if end > header.Number.Uint64() {
+ end = header.Number.Uint64()
+ }
+
+ filterOpts := &bind.FilterOpts{
+ Start: svc.processingBlockHeight,
+ End: &end,
+ Context: ctx,
+ }
+
+ blockProvenEvents, err := svc.taikol1.FilterBlockProven(filterOpts, nil)
+ if err != nil {
+ return errors.Wrap(err, "svc.taikol1.FilterBlockProven")
+ }
+
+ err = svc.saveBlockProvenEvents(ctx, chainID, blockProvenEvents)
+ if err != nil {
+ return errors.Wrap(err, "svc.saveBlockProvenEvents")
+ }
+
+ header, err := svc.ethClient.HeaderByNumber(ctx, big.NewInt(int64(end)))
+ if err != nil {
+ return errors.Wrap(err, "svc.ethClient.HeaderByNumber")
+ }
+
+ log.Infof("setting last processed block to height: %v, hash: %v", end, header.Hash().Hex())
+
+ if err := svc.blockRepo.Save(eventindexer.SaveBlockOpts{
+ Height: uint64(end),
+ Hash: header.Hash(),
+ ChainID: chainID,
+ }); err != nil {
+ return errors.Wrap(err, "svc.blockRepo.Save")
+ }
+
+ eventindexer.BlocksProcessed.Inc()
+
+ svc.processingBlockHeight = uint64(end)
+ }
+
+ log.Infof(
+ "chain id %v indexer fully caught up, checking latest block number to see if it's advanced",
+ chainID.Uint64(),
+ )
+
+ latestBlock, err := svc.ethClient.HeaderByNumber(ctx, nil)
+ if err != nil {
+ return errors.Wrap(err, "svc.ethclient.HeaderByNumber")
+ }
+
+ if svc.processingBlockHeight < latestBlock.Number.Uint64() {
+ return svc.FilterThenSubscribe(ctx, eventindexer.SyncMode, watchMode)
+ }
+
+ // we are caught up and specified not to subscribe, we can return now
+ if watchMode == eventindexer.FilterWatchMode {
+ return nil
+ }
+
+ return svc.subscribe(ctx, chainID)
+}
diff --git a/packages/eventindexer/indexer/save_block_proven_event.go b/packages/eventindexer/indexer/save_block_proven_event.go
new file mode 100644
index 00000000000..8342fdaf3a0
--- /dev/null
+++ b/packages/eventindexer/indexer/save_block_proven_event.go
@@ -0,0 +1,65 @@
+package indexer
+
+import (
+ "context"
+ "encoding/json"
+ "math/big"
+
+ "github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/contracts/taikol1"
+)
+
+func (svc *Service) saveBlockProvenEvents(
+ ctx context.Context,
+ chainID *big.Int,
+ events *taikol1.TaikoL1BlockProvenIterator,
+) error {
+ if !events.Next() || events.Event == nil {
+ log.Infof("no blockProven events")
+ return nil
+ }
+
+ for {
+ event := events.Event
+
+ if event.Raw.Removed {
+ continue
+ }
+
+ log.Infof("blockProven by: %v", event.Prover.Hex())
+
+ if err := svc.saveBlockProvenEvent(ctx, chainID, event); err != nil {
+ return errors.Wrap(err, "svc.saveBlockProvenEvent")
+ }
+
+ if !events.Next() {
+ return nil
+ }
+ }
+}
+
+func (svc *Service) saveBlockProvenEvent(
+ ctx context.Context,
+ chainID *big.Int,
+ event *taikol1.TaikoL1BlockProven,
+) error {
+ marshaled, err := json.Marshal(event)
+ if err != nil {
+ return errors.Wrap(err, "json.Marshal(event)")
+ }
+
+ _, err = svc.eventRepo.Save(ctx, eventindexer.SaveEventOpts{
+ Name: eventindexer.EventNameBlockProven,
+ Data: string(marshaled),
+ ChainID: chainID,
+ Event: eventindexer.EventNameBlockProven,
+ Address: event.Prover.Hex(),
+ })
+ if err != nil {
+ return errors.Wrap(err, "svc.eventRepo.Save")
+ }
+
+ return nil
+}
diff --git a/packages/eventindexer/indexer/service.go b/packages/eventindexer/indexer/service.go
new file mode 100644
index 00000000000..eb9b66c1d18
--- /dev/null
+++ b/packages/eventindexer/indexer/service.go
@@ -0,0 +1,78 @@
+package indexer
+
+import (
+ "context"
+ "math/big"
+ "time"
+
+ "github.com/cyberhorsey/errors"
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethclient"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/contracts/taikol1"
+)
+
+var (
+ ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000")
+)
+
+type ethClient interface {
+ ChainID(ctx context.Context) (*big.Int, error)
+ HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
+ SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error)
+}
+
+type Service struct {
+ eventRepo eventindexer.EventRepository
+ blockRepo eventindexer.BlockRepository
+ ethClient ethClient
+
+ processingBlockHeight uint64
+
+ blockBatchSize uint64
+ subscriptionBackoff time.Duration
+
+ taikol1 *taikol1.TaikoL1
+}
+
+type NewServiceOpts struct {
+ EventRepo eventindexer.EventRepository
+ BlockRepo eventindexer.BlockRepository
+ EthClient *ethclient.Client
+ RPCClient *rpc.Client
+ SrcTaikoAddress common.Address
+ BlockBatchSize uint64
+ SubscriptionBackoff time.Duration
+}
+
+func NewService(opts NewServiceOpts) (*Service, error) {
+ if opts.EventRepo == nil {
+ return nil, eventindexer.ErrNoEventRepository
+ }
+
+ if opts.EthClient == nil {
+ return nil, eventindexer.ErrNoEthClient
+ }
+
+ if opts.RPCClient == nil {
+ return nil, eventindexer.ErrNoRPCClient
+ }
+
+ taikoL1, err := taikol1.NewTaikoL1(opts.SrcTaikoAddress, opts.EthClient)
+ if err != nil {
+ return nil, errors.Wrap(err, "contracts.NewTaikoL1")
+ }
+
+ return &Service{
+ eventRepo: opts.EventRepo,
+ blockRepo: opts.BlockRepo,
+ ethClient: opts.EthClient,
+ taikol1: taikoL1,
+
+ blockBatchSize: opts.BlockBatchSize,
+ subscriptionBackoff: opts.SubscriptionBackoff,
+ }, nil
+}
diff --git a/packages/eventindexer/indexer/set_initial_processing_block_height.go b/packages/eventindexer/indexer/set_initial_processing_block_height.go
new file mode 100644
index 00000000000..9a8fda94513
--- /dev/null
+++ b/packages/eventindexer/indexer/set_initial_processing_block_height.go
@@ -0,0 +1,45 @@
+package indexer
+
+import (
+ "context"
+ "math/big"
+
+ "github.com/pkg/errors"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+)
+
+func (svc *Service) setInitialProcessingBlockByMode(
+ ctx context.Context,
+ mode eventindexer.Mode,
+ chainID *big.Int,
+) error {
+ stateVars, err := svc.taikol1.GetStateVariables(nil)
+ if err != nil {
+ return errors.Wrap(err, "svc.taikoL1.GetStateVariables")
+ }
+
+ startingBlock := stateVars.GenesisHeight
+
+ switch mode {
+ case eventindexer.SyncMode:
+ latestProcessedBlock, err := svc.blockRepo.GetLatestBlockProcessed(
+ chainID,
+ )
+ if err != nil {
+ return errors.Wrap(err, "svc.blockRepo.GetLatestBlock()")
+ }
+
+ if latestProcessedBlock.Height != 0 {
+ startingBlock = latestProcessedBlock.Height
+ }
+
+ svc.processingBlockHeight = startingBlock
+
+ return nil
+ case eventindexer.ResyncMode:
+ svc.processingBlockHeight = startingBlock
+ return nil
+ default:
+ return eventindexer.ErrInvalidMode
+ }
+}
diff --git a/packages/eventindexer/indexer/subscribe.go b/packages/eventindexer/indexer/subscribe.go
new file mode 100644
index 00000000000..6662233da43
--- /dev/null
+++ b/packages/eventindexer/indexer/subscribe.go
@@ -0,0 +1,87 @@
+package indexer
+
+import (
+ "context"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer/contracts/taikol1"
+)
+
+// subscribe subscribes to latest events
+func (svc *Service) subscribe(ctx context.Context, chainID *big.Int) error {
+ log.Info("subscribing to new events")
+
+ errChan := make(chan error)
+
+ go svc.subscribeBlockProven(ctx, chainID, errChan)
+
+ // nolint: gosimple
+ for {
+ select {
+ case <-ctx.Done():
+ log.Info("context finished")
+ return nil
+ case err := <-errChan:
+ eventindexer.ErrorsEncounteredDuringSubscription.Inc()
+
+ return errors.Wrap(err, "errChan")
+ }
+ }
+}
+
+func (svc *Service) subscribeBlockProven(ctx context.Context, chainID *big.Int, errChan chan error) {
+ sink := make(chan *taikol1.TaikoL1BlockProven)
+
+ sub := event.ResubscribeErr(svc.subscriptionBackoff, func(ctx context.Context, err error) (event.Subscription, error) {
+ if err != nil {
+ log.Errorf("svc.taikoL1.WatchBlockProven: %v", err)
+ }
+ log.Info("resubscribing to BlockProven events")
+
+ return svc.taikol1.WatchBlockProven(&bind.WatchOpts{
+ Context: ctx,
+ }, sink, nil)
+ })
+
+ defer sub.Unsubscribe()
+
+ for {
+ select {
+ case <-ctx.Done():
+ log.Info("context finished")
+ return
+ case err := <-sub.Err():
+ errChan <- errors.Wrap(err, "sub.Err()")
+ case event := <-sink:
+ log.Infof("blockProvenEvent from subscription for prover %v", event.Prover.Hex())
+
+ if err := svc.saveBlockProvenEvent(ctx, chainID, event); err != nil {
+ log.Errorf("svc.subscribe, svc.saveBlockProvenEvent: %v", err)
+ }
+
+ block, err := svc.blockRepo.GetLatestBlockProcessed(chainID)
+ if err != nil {
+ log.Errorf("svc.subscribe, blockRepo.GetLatestBlockProcessed: %v", err)
+ continue
+ }
+
+ if block.Height < event.Raw.BlockNumber {
+ err = svc.blockRepo.Save(eventindexer.SaveBlockOpts{
+ Height: event.Raw.BlockNumber,
+ Hash: event.Raw.BlockHash,
+ ChainID: chainID,
+ })
+ if err != nil {
+ log.Errorf("svc.subscribe, svc.blockRepo.Save: %v", err)
+ }
+
+ eventindexer.BlocksProcessed.Inc()
+ }
+ }
+ }
+}
diff --git a/packages/eventindexer/migrations/1666650599_create_events_table.sql b/packages/eventindexer/migrations/1666650599_create_events_table.sql
new file mode 100644
index 00000000000..324204d6757
--- /dev/null
+++ b/packages/eventindexer/migrations/1666650599_create_events_table.sql
@@ -0,0 +1,18 @@
+-- +goose Up
+-- +goose StatementBegin
+CREATE TABLE IF NOT EXISTS events (
+ id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ name VARCHAR(255) NOT NULL,
+ event VARCHAR(255) NOT NULL DEFAULT "",
+ chain_id int NOT NULL,
+ data JSON NOT NULL,
+ address VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+
+-- +goose StatementEnd
+-- +goose Down
+-- +goose StatementBegin
+DROP TABLE events;
+-- +goose StatementEnd
diff --git a/packages/eventindexer/migrations/1666650700_create_processed_blocks_table.sql b/packages/eventindexer/migrations/1666650700_create_processed_blocks_table.sql
new file mode 100644
index 00000000000..4c8726067d6
--- /dev/null
+++ b/packages/eventindexer/migrations/1666650700_create_processed_blocks_table.sql
@@ -0,0 +1,17 @@
+-- +goose Up
+-- +goose StatementBegin
+CREATE TABLE IF NOT EXISTS processed_blocks (
+ id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ block_height int NOT NULL,
+ hash VARCHAR(255) NOT NULL UNIQUE,
+ chain_id int NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+
+-- +goose StatementEnd
+-- +goose Down
+-- +goose StatementBegin
+DROP TABLE processed_blocks;
+-- +goose StatementEnd
+
diff --git a/packages/eventindexer/package.json b/packages/eventindexer/package.json
new file mode 100644
index 00000000000..5f0c53747e9
--- /dev/null
+++ b/packages/eventindexer/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@taiko/eventindexer",
+ "version": "0.1.0",
+ "private": true
+}
diff --git a/packages/eventindexer/prometheus.go b/packages/eventindexer/prometheus.go
new file mode 100644
index 00000000000..b12557a2fcb
--- /dev/null
+++ b/packages/eventindexer/prometheus.go
@@ -0,0 +1,25 @@
+package eventindexer
+
+import (
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+)
+
+var (
+ EventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "events_processed_ops_total",
+ Help: "The total number of processed events",
+ })
+ BlocksProcessed = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "blocks_processed_ops_total",
+ Help: "The total number of processed blocks",
+ })
+ BlocksScannedError = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "blocks_scanned_error_ops_total",
+ Help: "The total number of scanned block errors.",
+ })
+ ErrorsEncounteredDuringSubscription = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "errors_encountered_during_subscription_opts_total",
+ Help: "The total number of errors that occured during active subscription",
+ })
+)
diff --git a/packages/eventindexer/repo/block.go b/packages/eventindexer/repo/block.go
new file mode 100644
index 00000000000..159700dd609
--- /dev/null
+++ b/packages/eventindexer/repo/block.go
@@ -0,0 +1,62 @@
+package repo
+
+import (
+ "math/big"
+
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "gorm.io/gorm"
+)
+
+type BlockRepository struct {
+ db eventindexer.DB
+}
+
+func NewBlockRepository(db eventindexer.DB) (*BlockRepository, error) {
+ if db == nil {
+ return nil, eventindexer.ErrNoDB
+ }
+
+ return &BlockRepository{
+ db: db,
+ }, nil
+}
+
+func (r *BlockRepository) startQuery() *gorm.DB {
+ return r.db.GormDB().Table("processed_blocks")
+}
+
+func (r *BlockRepository) Save(opts eventindexer.SaveBlockOpts) error {
+ exists := &eventindexer.Block{}
+ _ = r.startQuery().Where("block_height = ?", opts.Height).Where("chain_id = ?", opts.ChainID.Int64()).First(exists)
+ // block procesed already
+ if exists.Height == opts.Height {
+ return nil
+ }
+
+ b := &eventindexer.Block{
+ Height: opts.Height,
+ Hash: opts.Hash.String(),
+ ChainID: opts.ChainID.Int64(),
+ }
+ if err := r.startQuery().Create(b).Error; err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (r *BlockRepository) GetLatestBlockProcessed(chainID *big.Int) (*eventindexer.Block, error) {
+ b := &eventindexer.Block{}
+ if err := r.
+ startQuery().
+ Raw(`SELECT id, block_height, hash, chain_id
+ FROM processed_blocks
+ WHERE block_height =
+ ( SELECT MAX(block_height) from processed_blocks
+ WHERE chain_id = ? )`, chainID.Int64()).
+ FirstOrInit(b).Error; err != nil {
+ return nil, err
+ }
+
+ return b, nil
+}
diff --git a/packages/eventindexer/repo/event.go b/packages/eventindexer/repo/event.go
new file mode 100644
index 00000000000..c2a93c14572
--- /dev/null
+++ b/packages/eventindexer/repo/event.go
@@ -0,0 +1,53 @@
+package repo
+
+import (
+ "context"
+
+ "github.com/pkg/errors"
+ "github.com/taikoxyz/taiko-mono/packages/eventindexer"
+ "gorm.io/datatypes"
+)
+
+type EventRepository struct {
+ db eventindexer.DB
+}
+
+func NewEventRepository(db eventindexer.DB) (*EventRepository, error) {
+ if db == nil {
+ return nil, eventindexer.ErrNoDB
+ }
+
+ return &EventRepository{
+ db: db,
+ }, nil
+}
+
+func (r *EventRepository) Save(ctx context.Context, opts eventindexer.SaveEventOpts) (*eventindexer.Event, error) {
+ e := &eventindexer.Event{
+ Data: datatypes.JSON(opts.Data),
+ ChainID: opts.ChainID.Int64(),
+ Name: opts.Name,
+ Event: opts.Event,
+ Address: opts.Address,
+ }
+
+ if err := r.db.GormDB().Create(e).Error; err != nil {
+ return nil, errors.Wrap(err, "r.db.Create")
+ }
+
+ return e, nil
+}
+
+func (r *EventRepository) FindUniqueProvers(
+ ctx context.Context,
+) ([]eventindexer.UniqueProversResponse, error) {
+ addrs := make([]eventindexer.UniqueProversResponse, 0)
+
+ if err := r.db.GormDB().
+ Raw("SELECT address, count(*) AS count FROM events GROUP BY address").
+ FirstOrInit(&addrs).Error; err != nil {
+ return nil, errors.Wrap(err, "r.db.FirstOrInit")
+ }
+
+ return addrs, nil
+}
diff --git a/packages/relayer/Dockerfile b/packages/relayer/Dockerfile
deleted file mode 100644
index 67b8ab73d45..00000000000
--- a/packages/relayer/Dockerfile
+++ /dev/null
@@ -1,19 +0,0 @@
-FROM golang:1.19.3 as builder
-
-RUN apt install git curl
-
-RUN git clone --depth 1 https://github.com/taikoxyz/taiko-mono /taiko-mono
-
-WORKDIR /taiko-mono/packages/relayer
-
-RUN go mod download
-
-RUN CGO_ENABLED=0 GOOS=linux go build -o ./bin/relayer cmd/main.go
-
-FROM alpine:latest
-
-RUN apk add --no-cache ca-certificates
-
-COPY --from=builder /taiko-mono/packages/relayer/bin/relayer /usr/local/bin/
-
-ENTRYPOINT ["relayer"]
\ No newline at end of file
diff --git a/packages/status-page/.default.env b/packages/status-page/.default.env
index 1facacb4ff8..871254df358 100644
--- a/packages/status-page/.default.env
+++ b/packages/status-page/.default.env
@@ -6,4 +6,5 @@ VITE_TAIKO_L1_ADDRESS="0x7B3AF414448ba906f02a1CA307C56c4ADFF27ce7"
VITE_L1_EXPLORER_URL="https://l1explorer.a1.taiko.xyz"
VITE_L2_EXPLORER_URL="https://l2explorer.a1.taiko.xyz"
VITE_FEE_TOKEN_SYMBOL="TKO";
-VITE_ORACLE_PROVER_ADDRESS="0x1567CDAb5F7a69154e61A16D8Ff5eE6A3e991b39"
\ No newline at end of file
+VITE_ORACLE_PROVER_ADDRESS="0x1567CDAb5F7a69154e61A16D8Ff5eE6A3e991b39"
+VITE_EVENT_INDEXER_API_URL="http://localhost:4100"
\ No newline at end of file
diff --git a/packages/status-page/src/App.svelte b/packages/status-page/src/App.svelte
index ae84186310a..0bba71fdce1 100644
--- a/packages/status-page/src/App.svelte
+++ b/packages/status-page/src/App.svelte
@@ -29,6 +29,7 @@
oracleProverAddress:
import.meta.env.ORACLE_PROVER_ADDRESS ||
"0x1567CDAb5F7a69154e61A16D8Ff5eE6A3e991b39",
+ eventIndexerApiUrl: import.meta.env.VITE_EVENT_INDEXER_API_URL,
},
userData: {},
}),
diff --git a/packages/status-page/src/components/DetailsModal.svelte b/packages/status-page/src/components/DetailsModal.svelte
new file mode 100644
index 00000000000..a7ea557e7f7
--- /dev/null
+++ b/packages/status-page/src/components/DetailsModal.svelte
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/packages/status-page/src/components/StatusIndicator.svelte b/packages/status-page/src/components/StatusIndicator.svelte
index f6c2393d44a..e0861151180 100644
--- a/packages/status-page/src/components/StatusIndicator.svelte
+++ b/packages/status-page/src/components/StatusIndicator.svelte
@@ -7,6 +7,7 @@
import { fade } from "svelte/transition";
import Tooltip from "./Tooltip.svelte";
import TooltipModal from "./TooltipModal.svelte";
+ import DetailsModal from "./DetailsModal.svelte";
export let provider: ethers.providers.JsonRpcProvider;
export let contractAddress: string;
@@ -40,6 +41,8 @@
let tooltipOpen: boolean = false;
+ let detailsOpen: boolean = false;
+
onMount(async () => {
try {
if (status) {
diff --git a/packages/status-page/src/pages/home/Home.svelte b/packages/status-page/src/pages/home/Home.svelte
index 16aeb97532e..26292b87ad1 100644
--- a/packages/status-page/src/pages/home/Home.svelte
+++ b/packages/status-page/src/pages/home/Home.svelte
@@ -1,5 +1,5 @@