Compare commits

..

41 Commits

Author SHA1 Message Date
Péter Garamvölgyi
61c44037e9 add 30 batch per tx limit 2023-05-31 20:38:30 +02:00
Richord
e53c7bca99 Add metric to track batch payload size and number of oversized batches (#500)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-05-24 09:08:39 -07:00
Lawliet-Chan
01a8f32363 feat(roller&coordinator): fetch traces from local l2geth node on roller (#452)
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-24 22:00:18 +08:00
HAOYUatHZ
7c05b5a20e ci(github): add conventionalcommits requirement into pull_request_template.md (#511) 2023-05-24 14:50:55 +08:00
HAOYUatHZ
029cb72333 build(github): fix ready_for_review trigger (#512) 2023-05-23 10:13:52 +08:00
Orest Tarasiuk
be3534baf1 (docs) Update README.md: Fix contracts links (#510) 2023-05-23 09:27:18 +08:00
Orest Tarasiuk
02429a9ad3 (docs) Update README.md for contracts 2023-05-22 17:48:55 +02:00
HAOYUatHZ
412ec4eeb7 docs: reorganize docs (#490)
Co-authored-by: Orest Tarasiuk <830847+OrestTa@users.noreply.github.com>
2023-05-22 17:44:25 +02:00
HAOYUatHZ
e838a88e61 docs(roller): add basic doc for roller (#448)
Co-authored-by: Jerry Ho <a29988122@gmail.com>
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: maskpp <maskpp266@gmail.com>
Co-authored-by: colinlyguo <colinlyguo@scroll.io>
Co-authored-by: Orest Tarasiuk <830847+OrestTa@users.noreply.github.com>
2023-05-22 17:40:15 +02:00
Xi Lin
3bc8a3f5c6 feat(contracts): revert subsequent batches (#509)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-22 09:41:40 +02:00
Ahmed Castro
0e09160a08 build(contracts): add package.json for npm library (#485)
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-22 15:07:51 +08:00
Lawliet-Chan
bd9d2e784c feat(version&Roller): add Halo2 version into Roller (#494)
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
2023-05-22 14:57:10 +08:00
Haichen Shen
af94da625c fix(ci): Disable github actions on draft prs (#508)
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
2023-05-22 08:50:38 +08:00
Haichen Shen
348b58ceb4 fix(contracts): disallow committing a batch twice (#505) 2023-05-21 15:00:05 -07:00
Xi Lin
f705ae7c0f feat(contracts): implement new rollup design (#464)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: maskpp <maskpp266@gmail.com>
Co-authored-by: Lawliet-Chan <1576710154@qq.com>
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
Co-authored-by: Orest Tarasiuk <830847+OrestTa@users.noreply.github.com>
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-05-21 11:29:16 -07:00
Xi Lin
29f358e838 feat(contracts): add a non-upgradeable version of IScrollStandardERC20 (#501)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-05-21 15:16:52 +08:00
Haichen Shen
aa03ad953d fix(contracts): update the l1 data fee calculation (#498) 2023-05-20 00:32:05 -07:00
Haichen Shen
dfc443a257 feat(contracts): Remove whitelist from ScrollMessengerBase (#499) 2023-05-20 00:15:41 -07:00
Xi Lin
2e0039ab25 feat(contracts): remove relay fee in L2ScrollMessenger (#493)
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-05-19 23:12:42 -07:00
Xi Lin
09378804b7 bugfix(contracts): fix wrong _oldFeeVault (#497)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-05-19 10:32:40 -07:00
HAOYUatHZ
80c946dabe build: rearrange docker build orders (#495) 2023-05-19 11:34:54 +08:00
HAOYUatHZ
58b70639b2 refactor(bridge-history-api): rename CreatedTime to CreatedAt (#492) 2023-05-19 11:22:09 +08:00
Lawliet-Chan
5788dd6207 fix(libzkp): fix makefile script (#491)
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
2023-05-18 17:56:11 +08:00
Orest Tarasiuk
50479d430c Update README.md: Fix contract docs relative paths 2023-05-17 18:33:18 +02:00
colin
b2b19dd2d3 feat(tests): add Docker-based local testing solution for M1/M2 silicon (#469)
Co-authored-by: maskpp <maskpp266@gmail.com>
Co-authored-by: Orest Tarasiuk <830847+OrestTa@users.noreply.github.com>
Co-authored-by: Xi Lin <zimpha@gmail.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-05-17 18:29:51 +02:00
ChuhanJin
0a7a7ad98b refactor(bridge-history-api): update bridge-history api (#478)
Co-authored-by: vincent <419436363@qq.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-17 22:37:16 +08:00
Haichen Shen
f6f11be0cf feat(contracts): remove unnecessary todos (#483)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-17 13:56:10 +08:00
Lawliet-Chan
f2c8b733c3 fix(libzkp):fix libzkp.so path (#486)
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-17 13:27:42 +08:00
Max Wolff
1e07c7c032 Feat/withdraw trie test (#479)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
2023-05-16 15:42:37 -07:00
Xi Lin
aea91291b2 feat(contracts): gateway to add enforced transaction (#400)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-05-16 15:13:09 -07:00
Nazarii Denha
02d0ff2219 Fix race condition in TestWorkerPool (#482)
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-05-16 13:19:06 +02:00
maskpp
a70c317b92 refactor(API): refactor SubmitProof (#318)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: Lawliet-Chan <1576710154@qq.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-05-16 09:22:45 +08:00
Orest Tarasiuk
046463e4e8 chore(github): make PR template copy explicit (#476) 2023-05-15 12:03:27 +02:00
Lawliet-Chan
929c8bf609 feat(libzkp): upgrade zkevm to v0.3 (#458)
Co-authored-by: xinran chen <lawliet@xinran-m1x.local>
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
2023-05-15 15:18:22 +08:00
maskpp
2cec2a3da2 feat(l2geth): bump l2geth version to scroll-v3.1.12 (#477) 2023-05-15 10:47:09 +08:00
Max Wolff
646ecb0124 feat(contracts): Intrinsic Gas Check (#465)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-05-12 10:57:58 -07:00
Xi Lin
26b65473cf feat(contracts): fixes according to Zellic contract audits (#441)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-05-12 09:10:53 -07:00
colin
db906f8c8a test: add more tests (#466) 2023-05-12 20:28:21 +08:00
maskpp
83c954bd26 fix(watcher): fix l1 baseFee (#475) 2023-05-12 17:39:14 +08:00
maskpp
97553ecebd refactor(test): simplify bridge tests (#472)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
2023-05-12 14:15:02 +08:00
HAOYUatHZ
ae02b32874 build(CI): fix bridge-history-api github CI (#474) 2023-05-12 11:44:27 +08:00
171 changed files with 2333320 additions and 45385 deletions

View File

@@ -1,7 +1,34 @@
1. Purpose or design rationale of this PR
## 1. Purpose or design rationale of this PR
...
2. Does this PR involve a new deployment, and involve a new git tag & docker image tag? If so, has `tag` in `common/version.go` been updated?
## 2. PR title
Your PR title must follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) (as we are doing squash merge for each PR), so it must start with one of the following [types](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#type):
- [ ] build: Changes that affect the build system or external dependencies (example scopes: yarn, eslint, typescript)
- [ ] ci: Changes to our CI configuration files and scripts (example scopes: vercel, github, cypress)
- [ ] docs: Documentation-only changes
- [ ] feat: A new feature
- [ ] fix: A bug fix
- [ ] perf: A code change that improves performance
- [ ] refactor: A code change that doesn't fix a bug, or add a feature, or improves performance
- [ ] style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- [ ] test: Adding missing tests or correcting existing tests
3. Is this PR a breaking change? If so, have it been attached a `breaking-change` label?
## 3. Deployment tag versioning
Has `tag` in `common/version.go` been updated?
- [ ] This PR doesn't involve a new deployment, git tag, docker image tag
- [ ] Yes
## 4. Breaking change label
Does this PR have the `breaking-change` label?
- [ ] This PR is not a breaking change
- [ ] Yes

View File

@@ -11,11 +11,11 @@ on:
- 'bridge/**'
- '.github/workflows/bridge.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'bridge/**'
- '.github/workflows/bridge.yml'
@@ -26,6 +26,7 @@ defaults:
jobs:
check:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -48,6 +49,7 @@ jobs:
make mock_abi
make lint
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -67,6 +69,7 @@ jobs:
exit 1
fi
# docker-build:
# if: github.event.pull_request.draft == false
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code

View File

@@ -11,11 +11,11 @@ on:
- 'bridge-history-api/**'
- '.github/workflows/bridge_history_api.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'bridge-history-api/**'
- '.github/workflows/bridge_history_api.yml'
@@ -25,20 +25,22 @@ defaults:
working-directory: 'bridge-history-api'
jobs:
check:
# runs-on: ubuntu-latest
# steps:
# - name: Install Go
# uses: actions/setup-go@v2
# with:
# go-version: 1.20.x
# - name: Checkout code
# uses: actions/checkout@v2
# - name: Lint
# run: |
# rm -rf $HOME/.cache/golangci-lint
# make lint
# check:
# if: github.event.pull_request.draft == false
# runs-on: ubuntu-latest
# steps:
# - name: Install Go
# uses: actions/setup-go@v2
# with:
# go-version: 1.20.x
# - name: Checkout code
# uses: actions/checkout@v2
# - name: Lint
# run: |
# rm -rf $HOME/.cache/golangci-lint
# make lint
test:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -52,6 +54,7 @@ jobs:
go get ./...
make test
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -70,4 +73,4 @@ jobs:
if [ -n "$(git status --porcelain)" ]; then
exit 1
fi

View File

@@ -11,11 +11,11 @@ on:
- 'common/**'
- '.github/workflows/common.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'common/**'
- '.github/workflows/common.yml'
@@ -26,6 +26,7 @@ defaults:
jobs:
check:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions-rs/toolchain@v1
@@ -45,9 +46,10 @@ jobs:
workspaces: "common/libzkp/impl -> target"
- name: Lint
run: |
rm -rf $HOME/.cache/golangci-lint
rm -rf $HOME/.cache/golangci-lint
make lint
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go

View File

@@ -2,10 +2,20 @@ name: Contracts
on:
push:
branches:
- main
- staging
- develop
- alpha
paths:
- 'contracts/**'
- '.github/workflows/contracts.yaml'
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'contracts/**'
- '.github/workflows/contracts.yaml'
@@ -16,6 +26,7 @@ defaults:
jobs:
foundry:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
@@ -28,7 +39,7 @@ jobs:
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Setup LCOV
uses: hrishikesh-kadam/setup-lcov@v1
@@ -84,6 +95,7 @@ jobs:
update-comment: true
hardhat:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:

View File

@@ -11,11 +11,11 @@ on:
- 'coordinator/**'
- '.github/workflows/coordinator.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'coordinator/**'
- '.github/workflows/coordinator.yml'
@@ -26,6 +26,7 @@ defaults:
jobs:
check:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions-rs/toolchain@v1
@@ -44,6 +45,7 @@ jobs:
rm -rf $HOME/.cache/golangci-lint
make lint
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -63,6 +65,7 @@ jobs:
exit 1
fi
# docker-build:
# if: github.event.pull_request.draft == false
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code

View File

@@ -11,11 +11,11 @@ on:
- 'database/**'
- '.github/workflows/database.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'database/**'
- '.github/workflows/database.yml'
@@ -26,6 +26,7 @@ defaults:
jobs:
check:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -36,9 +37,10 @@ jobs:
uses: actions/checkout@v2
- name: Lint
run: |
rm -rf $HOME/.cache/golangci-lint
rm -rf $HOME/.cache/golangci-lint
make lint
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go

View File

@@ -18,15 +18,6 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push coordinator docker
uses: docker/build-push-action@v2
with:
context: .
file: ./build/dockerfiles/coordinator.Dockerfile
push: true
tags: scrolltech/coordinator:${{github.ref_name}}
# cache-from: type=gha,scope=${{ github.workflow }}
# cache-to: type=gha,scope=${{ github.workflow }}
- name: Build and push event_watcher docker
uses: docker/build-push-action@v2
with:
@@ -81,3 +72,12 @@ jobs:
tags: scrolltech/bridgehistoryapi-server:${{github.ref_name}}
# cache-from: type=gha,scope=${{ github.workflow }}
# cache-to: type=gha,scope=${{ github.workflow }}
- name: Build and push coordinator docker
uses: docker/build-push-action@v2
with:
context: .
file: ./build/dockerfiles/coordinator.Dockerfile
push: true
tags: scrolltech/coordinator:${{github.ref_name}}
# cache-from: type=gha,scope=${{ github.workflow }}
# cache-to: type=gha,scope=${{ github.workflow }}

View File

@@ -11,11 +11,11 @@ on:
- 'roller/**'
- '.github/workflows/roller.yml'
pull_request:
branches:
- main
- staging
- develop
- alpha
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- 'roller/**'
- '.github/workflows/roller.yml'
@@ -26,6 +26,7 @@ defaults:
jobs:
test:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions-rs/toolchain@v1
@@ -48,6 +49,7 @@ jobs:
make roller
go test -tags="mock_prover" -v ./...
check:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go
@@ -61,6 +63,7 @@ jobs:
rm -rf $HOME/.cache/golangci-lint
make lint
goimports-lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Install Go

2
Jenkinsfile vendored
View File

@@ -96,4 +96,4 @@ pipeline {
slackSend(message: "${JOB_BASE_NAME} ${GIT_COMMIT} #${BUILD_NUMBER} deploy ${currentBuild.result}")
}
}
}
}

View File

@@ -1,4 +1,4 @@
.PHONY: check update dev_docker clean
.PHONY: check update dev_docker build_test_docker run_test_docker clean
ZKP_VERSION=release-1220
@@ -17,12 +17,14 @@ lint: ## The code's format and security checks.
update: ## update dependencies
go work sync
cd $(PWD)/bridge/ && go get -u github.com/scroll-tech/go-ethereum@scroll && go mod tidy
cd $(PWD)/common/ && go get -u github.com/scroll-tech/go-ethereum@scroll && go mod tidy
cd $(PWD)/coordinator/ && go get -u github.com/scroll-tech/go-ethereum@scroll && go mod tidy
cd $(PWD)/database/ && go get -u github.com/scroll-tech/go-ethereum@scroll && go mod tidy
cd $(PWD)/roller/ && go get -u github.com/scroll-tech/go-ethereum@scroll && go mod tidy
cd $(PWD)/bridge/ && go get -u github.com/scroll-tech/go-ethereum@scroll-v3.1.12 && go mod tidy
cd $(PWD)/bridge-history-api/ && go get -u github.com/ethereum/go-ethereum@latest && go mod tidy
cd $(PWD)/common/ && go get -u github.com/scroll-tech/go-ethereum@scroll-v3.1.12 && go mod tidy
cd $(PWD)/coordinator/ && go get -u github.com/scroll-tech/go-ethereum@scroll-v3.1.12 && go mod tidy
cd $(PWD)/database/ && go get -u github.com/scroll-tech/go-ethereum@scroll-v3.1.12 && go mod tidy
cd $(PWD)/roller/ && go get -u github.com/scroll-tech/go-ethereum@scroll-v3.1.12 && go mod tidy
goimports -local $(PWD)/bridge/ -w .
goimports -local $(PWD)/bridge-history-api/ -w .
goimports -local $(PWD)/common/ -w .
goimports -local $(PWD)/coordinator/ -w .
goimports -local $(PWD)/database/ -w .
@@ -32,6 +34,13 @@ dev_docker: ## build docker images for development/testing usages
docker build -t scroll_l1geth ./common/docker/l1geth/
docker build -t scroll_l2geth ./common/docker/l2geth/
build_test_docker: ## build Docker image for local testing on M1/M2 Silicon Mac
docker build -t scroll_test_image -f ./build/dockerfiles/local_testing.Dockerfile $$(mktemp -d)
run_test_docker: ## run Docker image for local testing on M1/M2 Silicon Mac
docker run -it --rm --name scroll_test_container --network=host -v /var/run/docker.sock:/var/run/docker.sock -v $(PWD):/go/src/app scroll_test_image
test_zkp: ## Test zkp prove and verify, roller/prover generates the proof and coordinator/verifier verifies it
mkdir -p test_params
wget https://circuit-release.s3.us-west-2.amazonaws.com/circuit-release/${ZKP_VERSION}/test_params/params19 -O ./test_params/params19

View File

@@ -3,10 +3,66 @@
[![Contracts](https://github.com/scroll-tech/scroll/actions/workflows/contracts.yaml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/contracts.yaml) [![Bridge](https://github.com/scroll-tech/scroll/actions/workflows/bridge.yml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/bridge.yml) [![Coordinator](https://github.com/scroll-tech/scroll/actions/workflows/coordinator.yml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/coordinator.yml) [![Database](https://github.com/scroll-tech/scroll/actions/workflows/database.yml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/database.yml) [![Common](https://github.com/scroll-tech/scroll/actions/workflows/common.yml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/common.yml) [![Roller](https://github.com/scroll-tech/scroll/actions/workflows/roller.yml/badge.svg)](https://github.com/scroll-tech/scroll/actions/workflows/roller.yml)
## Prerequisites
+ go1.18
+ rust (for version, see [rust-toolchain](./common/libzkp/impl/rust-toolchain))
+ hardhat / foundry
+ Go 1.18
+ Rust (for version, see [rust-toolchain](./common/libzkp/impl/rust-toolchain))
+ Hardhat / Foundry
+ Docker
---
To run the tests, it is essential to first pull or build the required Docker images. Execute the following commands in the root directory of the repository to do this:
For a more comprehensive doc, see [`docs/`](./docs).
```bash
docker pull postgres
make dev_docker
```
## Testing Bridge & Coordinator
### For Non-Apple Silicon (M1/M2) Macs
Run the tests using the following commands:
```bash
go test -v -race -covermode=atomic scroll-tech/bridge/...
go test -tags="mock_verifier" -v -race -covermode=atomic scroll-tech/coordinator/...
go test -v -race -covermode=atomic scroll-tech/database/...
go test -v -race -covermode=atomic scroll-tech/common/...
```
### For Apple Silicon (M1/M2) Macs
To run tests on Apple Silicon Macs, build and execute the Docker image as outlined below:
#### Build a Docker Image for Testing
Use the following command to build a Docker image:
```bash
make build_test_docker
```
This command builds a Docker image named `scroll_test_image` using the Dockerfile found at `./build/dockerfiles/local_test.Dockerfile`.
#### Run Docker Image
After the image is built, run a Docker container from it:
```bash
make run_test_docker
```
This command runs a Docker container named `scroll_test_container` from the `scroll_test_image` image. The container uses the host network and has access to the Docker socket and the current directory.
Once the Docker container is running, execute the tests using the following commands:
```bash
go test -v -race -covermode=atomic scroll-tech/bridge/...
go test -tags="mock_verifier" -v -race -covermode=atomic scroll-tech/coordinator/...
go test -v -race -covermode=atomic scroll-tech/database/...
go test -v -race -covermode=atomic scroll-tech/common/...
```
## Testing Contracts
You can find the unit tests in [`<REPO_DIR>/contracts/src/test/`](/contracts/src/test/), and integration tests in [`<REPO_DIR>/contracts/integration-test/`](/contracts/integration-test/).
For more details on contracts, see [`/contracts`](/contracts).

View File

@@ -190,15 +190,21 @@ func (c *CrossMsgFetcher) fetchMissingLatestHeaders() {
log.Crit("Can not get safe number during reorg, quit the process", "err", err)
}
// clear all our saved data, because no data is safe now
c.reorgHandling(c.ctx, int64(num), c.db)
c.cachedHeaders = c.cachedHeaders[:0]
err = c.reorgHandling(c.ctx, int64(num), c.db)
// if handling success then we can update the cachedHeaders
if err == nil {
c.cachedHeaders = c.cachedHeaders[:0]
}
c.mu.Unlock()
c.reorgEndCh <- struct{}{}
return
}
c.reorgHandling(c.ctx, c.cachedHeaders[index].Number.Int64(), c.db)
c.cachedHeaders = c.cachedHeaders[:index+1]
c.cachedHeaders = MergeAddIntoHeaderList(c.cachedHeaders, validHeaders, int(c.config.Confirmation))
err = c.reorgHandling(c.ctx, c.cachedHeaders[index].Number.Int64(), c.db)
// if handling success then we can update the cachedHeaders
if err == nil {
c.cachedHeaders = c.cachedHeaders[:index+1]
c.cachedHeaders = MergeAddIntoHeaderList(c.cachedHeaders, validHeaders, int(c.config.Confirmation))
}
c.mu.Unlock()
c.reorgEndCh <- struct{}{}
}

View File

@@ -65,7 +65,7 @@ func GetLatestL2ProcessedHeight(db db.OrmFactory) (int64, error) {
log.Error("failed to get L2 cross message processed height", "err", err)
return 0, err
}
relayedHeight, err := db.GetLatestRelayedHeightFromL2()
relayedHeight, err := db.GetLatestRelayedHeightOnL2()
if err != nil {
log.Error("failed to get L2 relayed message processed height", "err", err)
return 0, err
@@ -111,24 +111,26 @@ func L1FetchAndSaveEvents(ctx context.Context, client *ethclient.Client, databas
}
err = database.BatchInsertL1CrossMsgDBTx(dbTx, depositL1CrossMsgs)
if err != nil {
log.Error("l1FetchAndSaveEvents: Failed to insert cross msg event logs", "err", err)
return err
dbTx.Rollback()
log.Crit("l1FetchAndSaveEvents: Failed to insert cross msg event logs", "err", err)
}
err = database.BatchInsertRelayedMsgDBTx(dbTx, relayedMsg)
if err != nil {
log.Error("l1FetchAndSaveEvents: Failed to insert relayed message event logs", "err", err)
return err
dbTx.Rollback()
log.Crit("l1FetchAndSaveEvents: Failed to insert relayed message event logs", "err", err)
}
err = updateL1CrossMsgMsgHash(ctx, dbTx, database, msgHashes)
if err != nil {
log.Error("l1FetchAndSaveEvents: Failed to update msgHash in L1 cross msg", "err", err)
return err
dbTx.Rollback()
log.Crit("l1FetchAndSaveEvents: Failed to update msgHash in L1 cross msg", "err", err)
}
err = dbTx.Commit()
if err != nil {
// if we can not insert into DB, there must something wrong, need a on-call member handle the dababase manually
log.Crit("l1FetchAndSaveEvents: Failed to commit db transaction", "err", err)
dbTx.Rollback()
log.Error("l1FetchAndSaveEvents: Failed to commit db transaction", "err", err)
return err
}
return nil
@@ -167,34 +169,36 @@ func L2FetchAndSaveEvents(ctx context.Context, client *ethclient.Client, databas
}
err = database.BatchInsertL2CrossMsgDBTx(dbTx, depositL2CrossMsgs)
if err != nil {
log.Error("l2FetchAndSaveEvents: Failed to insert cross msg event logs", "err", err)
return err
dbTx.Rollback()
log.Crit("l2FetchAndSaveEvents: Failed to insert cross msg event logs", "err", err)
}
err = database.BatchInsertRelayedMsgDBTx(dbTx, relayedMsg)
if err != nil {
log.Error("l2FetchAndSaveEvents: Failed to insert relayed message event logs", "err", err)
return err
dbTx.Rollback()
log.Crit("l2FetchAndSaveEvents: Failed to insert relayed message event logs", "err", err)
}
err = updateL2CrossMsgMsgHash(ctx, dbTx, database, msgHashes)
if err != nil {
log.Error("l2FetchAndSaveEvents: Failed to update msgHash in L2 cross msg", "err", err)
return err
dbTx.Rollback()
log.Crit("l2FetchAndSaveEvents: Failed to update msgHash in L2 cross msg", "err", err)
}
err = dbTx.Commit()
if err != nil {
// if we can not insert into DB, there must something wrong, need a on-call member handle the dababase manually
log.Crit("l2FetchAndSaveEvents: Failed to commit db transaction", "err", err)
dbTx.Rollback()
log.Error("l2FetchAndSaveEvents: Failed to commit db transaction", "err", err)
return err
}
return nil
}
func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrapper, []*orm.RelayedMsg, error) {
func parseBackendL1EventLogs(logs []types.Log) ([]*orm.CrossMsg, []msgHashWrapper, []*orm.RelayedMsg, error) {
// Need use contract abi to parse event Log
// Can only be tested after we have our contracts set up
var l1CrossMsg []*orm.L1CrossMsg
var l1CrossMsg []*orm.CrossMsg
var relayedMsgs []*orm.RelayedMsg
var msgHashes []msgHashWrapper
for _, vlog := range logs {
@@ -206,7 +210,7 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
log.Warn("Failed to unpack DepositETH event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
l1CrossMsg = append(l1CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -214,21 +218,6 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
Asset: int(orm.ETH),
Layer1Hash: vlog.TxHash.Hex(),
})
case backendabi.L1DepositWETHSig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L1WETHGatewayABI, &event, "DepositERC20", vlog)
if err != nil {
log.Warn("Failed to unpack DepositWETH event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
Amount: event.Amount.String(),
Asset: int(orm.WETH),
Layer1Hash: vlog.TxHash.Hex(),
})
case backendabi.L1DepositERC20Sig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L1StandardERC20GatewayABI, &event, "DepositERC20", vlog)
@@ -236,24 +225,7 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
log.Warn("Failed to unpack DepositERC20 event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
Amount: event.Amount.String(),
Asset: int(orm.ERC20),
Layer1Hash: vlog.TxHash.Hex(),
Layer1Token: event.L1Token.Hex(),
Layer2Token: event.L2Token.Hex(),
})
case backendabi.L1DepositCustomERC20Sig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L1CustomERC20GatewayABI, &event, "DepositERC20", vlog)
if err != nil {
log.Warn("Failed to unpack DepositCustomERC20 event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
l1CrossMsg = append(l1CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -270,7 +242,7 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
log.Warn("Failed to unpack DepositERC721 event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
l1CrossMsg = append(l1CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -287,7 +259,7 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
log.Warn("Failed to unpack DepositERC1155 event", "err", err)
return l1CrossMsg, msgHashes, relayedMsgs, err
}
l1CrossMsg = append(l1CrossMsg, &orm.L1CrossMsg{
l1CrossMsg = append(l1CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -328,11 +300,11 @@ func parseBackendL1EventLogs(logs []types.Log) ([]*orm.L1CrossMsg, []msgHashWrap
return l1CrossMsg, msgHashes, relayedMsgs, nil
}
func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrapper, []*orm.RelayedMsg, error) {
func parseBackendL2EventLogs(logs []types.Log) ([]*orm.CrossMsg, []msgHashWrapper, []*orm.RelayedMsg, error) {
// Need use contract abi to parse event Log
// Can only be tested after we have our contracts set up
var l2CrossMsg []*orm.L2CrossMsg
var l2CrossMsg []*orm.CrossMsg
var relayedMsgs []*orm.RelayedMsg
var msgHashes []msgHashWrapper
for _, vlog := range logs {
@@ -344,7 +316,7 @@ func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrap
log.Warn("Failed to unpack WithdrawETH event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
l2CrossMsg = append(l2CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -352,21 +324,6 @@ func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrap
Asset: int(orm.ETH),
Layer2Hash: vlog.TxHash.Hex(),
})
case backendabi.L2WithdrawWETHSig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L2WETHGatewayABI, &event, "WithdrawERC20", vlog)
if err != nil {
log.Warn("Failed to unpack WithdrawWETH event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
Amount: event.Amount.String(),
Asset: int(orm.WETH),
Layer2Hash: vlog.TxHash.Hex(),
})
case backendabi.L2WithdrawERC20Sig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L2StandardERC20GatewayABI, &event, "WithdrawERC20", vlog)
@@ -374,24 +331,7 @@ func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrap
log.Warn("Failed to unpack WithdrawERC20 event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
Amount: event.Amount.String(),
Asset: int(orm.ERC20),
Layer2Hash: vlog.TxHash.Hex(),
Layer1Token: event.L1Token.Hex(),
Layer2Token: event.L2Token.Hex(),
})
case backendabi.L2WithdrawCustomERC20Sig:
event := backendabi.ERC20MessageEvent{}
err := utils.UnpackLog(backendabi.L2CustomERC20GatewayABI, &event, "WithdrawERC20", vlog)
if err != nil {
log.Warn("Failed to unpack DepositCustomERC20 event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
l2CrossMsg = append(l2CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -408,7 +348,7 @@ func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrap
log.Warn("Failed to unpack WithdrawERC721 event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
l2CrossMsg = append(l2CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),
@@ -425,7 +365,7 @@ func parseBackendL2EventLogs(logs []types.Log) ([]*orm.L2CrossMsg, []msgHashWrap
log.Warn("Failed to unpack WithdrawERC1155 event", "err", err)
return l2CrossMsg, msgHashes, relayedMsgs, err
}
l2CrossMsg = append(l2CrossMsg, &orm.L2CrossMsg{
l2CrossMsg = append(l2CrossMsg, &orm.CrossMsg{
Height: vlog.BlockNumber,
Sender: event.From.String(),
Target: event.To.String(),

View File

@@ -10,7 +10,7 @@ import (
"bridge-history-api/db"
)
type ReorgHandling func(ctx context.Context, reorgHeight int64, db db.OrmFactory)
type ReorgHandling func(ctx context.Context, reorgHeight int64, db db.OrmFactory) error
func reverseArray(arr []*types.Header) []*types.Header {
for i := 0; i < len(arr)/2; i++ {
@@ -54,40 +54,51 @@ func BackwardFindReorgBlock(ctx context.Context, headers []*types.Header, client
return -1, false, nil
}
func L1ReorgHandling(ctx context.Context, reorgHeight int64, db db.OrmFactory) {
func L1ReorgHandling(ctx context.Context, reorgHeight int64, db db.OrmFactory) error {
dbTx, err := db.Beginx()
if err != nil {
log.Crit("begin db tx failed", "err", err)
}
err = db.DeleteL1CrossMsgAfterHeightDBTx(dbTx, reorgHeight)
if err != nil {
dbTx.Rollback()
log.Crit("delete l1 cross msg from height", "height", reorgHeight, "err", err)
}
err = db.DeleteL1RelayedHashFromHeightDBTx(dbTx, reorgHeight)
err = db.DeleteL1RelayedHashAfterHeightDBTx(dbTx, reorgHeight)
if err != nil {
dbTx.Rollback()
log.Crit("delete l1 relayed hash from height", "height", reorgHeight, "err", err)
}
err = dbTx.Commit()
if err != nil {
log.Crit("commit tx failed", "err", err)
dbTx.Rollback()
log.Error("commit tx failed", "err", err)
return err
}
return nil
}
func L2ReorgHandling(ctx context.Context, reorgHeight int64, db db.OrmFactory) {
func L2ReorgHandling(ctx context.Context, reorgHeight int64, db db.OrmFactory) error {
dbTx, err := db.Beginx()
if err != nil {
dbTx.Rollback()
log.Crit("begin db tx failed", "err", err)
}
err = db.DeleteL2CrossMsgFromHeightDBTx(dbTx, reorgHeight)
if err != nil {
dbTx.Rollback()
log.Crit("delete l2 cross msg from height", "height", reorgHeight, "err", err)
}
err = db.DeleteL2RelayedHashFromHeightDBTx(dbTx, reorgHeight)
err = db.DeleteL2RelayedHashAfterHeightDBTx(dbTx, reorgHeight)
if err != nil {
dbTx.Rollback()
log.Crit("delete l2 relayed hash from height", "height", reorgHeight, "err", err)
}
err = dbTx.Commit()
if err != nil {
log.Crit("commit tx failed", "err", err)
dbTx.Rollback()
log.Error("commit tx failed", "err", err)
return err
}
return nil
}

View File

@@ -0,0 +1,72 @@
-- +goose Up
-- +goose StatementBegin
create table cross_message
(
id BIGSERIAL PRIMARY KEY,
msg_hash VARCHAR NOT NULL DEFAULT '',
height BIGINT NOT NULL,
sender VARCHAR NOT NULL,
target VARCHAR NOT NULL,
amount VARCHAR NOT NULL,
layer1_hash VARCHAR NOT NULL DEFAULT '',
layer2_hash VARCHAR NOT NULL DEFAULT '',
layer1_token VARCHAR NOT NULL DEFAULT '',
layer2_token VARCHAR NOT NULL DEFAULT '',
token_id BIGINT NOT NULL DEFAULT 0,
asset SMALLINT NOT NULL,
msg_type SMALLINT NOT NULL,
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP(0) DEFAULT NULL
);
comment
on column cross_message.asset is 'ETH, ERC20, ERC721, ERC1155';
comment
on column cross_message.msg_type is 'unknown, l1msg, l2msg';
comment
on column cross_message.is_deleted is 'NotDeleted false, Deleted true';
CREATE INDEX valid_l1_msg_index ON cross_message (layer1_hash, is_deleted);
CREATE INDEX valid_l2_msg_index ON cross_message (layer2_hash, is_deleted);
CREATE INDEX valid_height_index ON cross_message (height, msg_type, is_deleted);
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_timestamp BEFORE UPDATE
ON cross_message FOR EACH ROW EXECUTE PROCEDURE
update_timestamp();
CREATE OR REPLACE FUNCTION delete_at_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.is_deleted AND OLD.is_deleted != NEW.is_deleted THEN
UPDATE cross_message SET delete_at = NOW() WHERE id = NEW.id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER delete_at_trigger
AFTER UPDATE ON cross_message
FOR EACH ROW
EXECUTE FUNCTION delete_at_trigger();
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop table if exists cross_message;
-- +goose StatementEnd

View File

@@ -1,47 +0,0 @@
-- +goose Up
-- +goose StatementBegin
create table l1_cross_message
(
msg_hash VARCHAR DEFAULT '',
height BIGINT NOT NULL,
sender VARCHAR NOT NULL,
target VARCHAR NOT NULL,
amount VARCHAR NOT NULL,
layer1_hash VARCHAR NOT NULL,
layer2_hash VARCHAR DEFAULT '',
layer1_token VARCHAR DEFAULT '',
layer2_token VARCHAR DEFAULT '',
token_id BIGINT DEFAULT 0,
asset SMALLINT DEFAULT 1,
created_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
comment
on column l1_cross_message.asset is 'ETH, ERC20, ERC721, ERC1155, WETH';
create unique index l1_cross_message_hash_uindex
on l1_cross_message (layer1_hash);
create index l1_cross_message_height_index
on l1_cross_message (height);
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_timestamp BEFORE UPDATE
ON l1_cross_message FOR EACH ROW EXECUTE PROCEDURE
update_timestamp();
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop table if exists l1_cross_message;
-- +goose StatementEnd

View File

@@ -1,46 +0,0 @@
-- +goose Up
-- +goose StatementBegin
create table l2_cross_message
(
msg_hash VARCHAR DEFAULT '',
height BIGINT NOT NULL,
sender VARCHAR NOT NULL,
target VARCHAR NOT NULL,
amount VARCHAR NOT NULL,
layer1_hash VARCHAR DEFAULT '',
layer2_hash VARCHAR NOT NULL,
layer1_token VARCHAR DEFAULT '',
layer2_token VARCHAR DEFAULT '',
token_id BIGINT DEFAULT 0,
asset SMALLINT DEFAULT 1,
created_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
comment
on column l2_cross_message.asset is 'ETH, ERC20, ERC721, ERC1155, WETH';
create unique index l2_cross_message_hash_uindex
on l2_cross_message (layer2_hash);
create index l2_cross_message_height_index
on l2_cross_message (height);
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_timestamp BEFORE UPDATE
ON l2_cross_message FOR EACH ROW EXECUTE PROCEDURE
update_timestamp();
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop table if exists l2_cross_message;
-- +goose StatementEnd

View File

@@ -0,0 +1,55 @@
-- +goose Up
-- +goose StatementBegin
create table relayed_msg
(
id BIGSERIAL PRIMARY KEY,
msg_hash VARCHAR NOT NULL,
height BIGINT NOT NULL,
layer1_hash VARCHAR NOT NULL DEFAULT '',
layer2_hash VARCHAR NOT NULL DEFAULT '',
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP(0) DEFAULT NULL
);
comment
on column relayed_msg.is_deleted is 'NotDeleted, Deleted';
create unique index relayed_msg_hash_uindex
on relayed_msg (msg_hash);
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_timestamp BEFORE UPDATE
ON relayed_msg FOR EACH ROW EXECUTE PROCEDURE
update_timestamp();
CREATE OR REPLACE FUNCTION delete_at_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.is_deleted AND OLD.is_deleted != NEW.is_deleted THEN
UPDATE relayed_msg SET delete_at = NOW() WHERE id = NEW.id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER delete_at_trigger
AFTER UPDATE ON relayed_msg
FOR EACH ROW
EXECUTE FUNCTION delete_at_trigger();
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop table if exists relayed_msg;
-- +goose StatementEnd

View File

@@ -1,34 +0,0 @@
-- +goose Up
-- +goose StatementBegin
create table relayed_msg
(
msg_hash VARCHAR NOT NULL,
height BIGINT NOT NULL,
layer1_hash VARCHAR DEFAULT '',
layer2_hash VARCHAR DEFAULT '',
created_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
create unique index relayed_msg_hash_uindex
on relayed_msg (msg_hash);
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_timestamp BEFORE UPDATE
ON relayed_msg FOR EACH ROW EXECUTE PROCEDURE
update_timestamp();
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop table if exists relayed_msg;
-- +goose StatementEnd

View File

@@ -9,6 +9,7 @@ import (
)
type AssetType int
type MsgType int
func (a AssetType) String() string {
switch a {
@@ -20,8 +21,6 @@ func (a AssetType) String() string {
return "ERC1155"
case ERC721:
return "ERC721"
case WETH:
return "WETH"
}
return "Unknown Asset Type"
}
@@ -31,11 +30,17 @@ const (
ERC20
ERC721
ERC1155
WETH
)
// L1CrossMsg represents a cross message from layer 1 to layer 2
type L1CrossMsg struct {
const (
UnknownMsg MsgType = iota
Layer1Msg
Layer2Msg
)
// CrossMsg represents a cross message from layer 1 to layer 2
type CrossMsg struct {
ID uint64 `json:"id" db:"id"`
MsgHash string `json:"msg_hash" db:"msg_hash"`
Height uint64 `json:"height" db:"height"`
Sender string `json:"sender" db:"sender"`
@@ -46,26 +51,12 @@ type L1CrossMsg struct {
Layer1Token string `json:"layer1_token" db:"layer1_token"`
Layer2Token string `json:"layer2_token" db:"layer2_token"`
TokenID uint64 `json:"token_id" db:"token_id"`
CreatedTime *time.Time `json:"created_time" db:"created_time"`
Asset int `json:"asset" db:"asset"`
UpdatedTime *time.Time `json:"updated_time" db:"updated_time"`
}
// L2CrossMsg represents a cross message from layer 2 to layer 1
type L2CrossMsg struct {
MsgHash string `json:"msg_hash" db:"msg_hash"`
Height uint64 `json:"height" db:"height"`
Sender string `json:"sender" db:"sender"`
Target string `json:"target" db:"target"`
Amount string `json:"value" db:"amount"`
Layer1Hash string `json:"layer1_hash" db:"layer1_hash"`
Layer2Hash string `json:"layer2_hash" db:"layer2_hash"`
Layer1Token string `json:"layer1_token" db:"layer1_token"`
Layer2Token string `json:"layer2_token" db:"layer2_token"`
TokenID uint64 `json:"token_id" db:"token_id"`
CreatedTime *time.Time `json:"created_time" db:"created_time"`
Asset int `json:"asset" db:"asset"`
UpdatedTime *time.Time `json:"updated_time" db:"updated_time"`
MsgType int `json:"msg_type" db:"msg_type"`
IsDeleted bool `json:"is_deleted" db:"is_deleted"`
CreatedAt *time.Time `json:"created_at" db:"created_at"`
UpdatedAt *time.Time `json:"updated_at" db:"updated_at"`
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"`
}
type RelayedMsg struct {
@@ -77,27 +68,25 @@ type RelayedMsg struct {
// L1CrossMsgOrm provides operations on l1_cross_message table
type L1CrossMsgOrm interface {
GetL1CrossMsgByHash(l1Hash common.Hash) (*L1CrossMsg, error)
GetL1CrossMsgsByAddress(sender common.Address) ([]*L1CrossMsg, error)
BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L1CrossMsg) error
GetL1CrossMsgByHash(l1Hash common.Hash) (*CrossMsg, error)
GetL1CrossMsgsByAddress(sender common.Address) ([]*CrossMsg, error)
BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*CrossMsg) error
// UpdateL1CrossMsgHash invoked when SentMessage event is received
UpdateL1CrossMsgHashDBTx(ctx context.Context, dbTx *sqlx.Tx, l1Hash, msgHash common.Hash) error
UpdateL1CrossMsgHash(ctx context.Context, l1Hash, msgHash common.Hash) error
GetLatestL1ProcessedHeight() (int64, error)
DeleteL1CrossMsgAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error
GetL1CrossMsgsByAddressWithOffset(sender common.Address, offset int64, limit int64) ([]*L1CrossMsg, error)
}
// L2CrossMsgOrm provides operations on l2_cross_message table
type L2CrossMsgOrm interface {
GetL2CrossMsgByHash(l2Hash common.Hash) (*L2CrossMsg, error)
GetL2CrossMsgByAddress(sender common.Address) ([]*L2CrossMsg, error)
BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L2CrossMsg) error
GetL2CrossMsgByHash(l2Hash common.Hash) (*CrossMsg, error)
GetL2CrossMsgByAddress(sender common.Address) ([]*CrossMsg, error)
BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*CrossMsg) error
// UpdateL2CrossMsgHash invoked when SentMessage event is received
UpdateL2CrossMsgHashDBTx(ctx context.Context, dbTx *sqlx.Tx, l2Hash, msgHash common.Hash) error
UpdateL2CrossMsgHash(ctx context.Context, l2Hash, msgHash common.Hash) error
GetLatestL2ProcessedHeight() (int64, error)
GetL2CrossMsgsByAddressWithOffset(sender common.Address, offset int64, limit int64) ([]*L2CrossMsg, error)
DeleteL2CrossMsgFromHeightDBTx(dbTx *sqlx.Tx, height int64) error
}
@@ -105,7 +94,7 @@ type RelayedMsgOrm interface {
BatchInsertRelayedMsgDBTx(dbTx *sqlx.Tx, messages []*RelayedMsg) error
GetRelayedMsgByHash(msg_hash string) (*RelayedMsg, error)
GetLatestRelayedHeightOnL1() (int64, error)
GetLatestRelayedHeightFromL2() (int64, error)
DeleteL1RelayedHashFromHeightDBTx(dbTx *sqlx.Tx, height int64) error
DeleteL2RelayedHashFromHeightDBTx(dbTx *sqlx.Tx, height int64) error
GetLatestRelayedHeightOnL2() (int64, error)
DeleteL1RelayedHashAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error
DeleteL2RelayedHashAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error
}

View File

@@ -19,9 +19,9 @@ func NewL1CrossMsgOrm(db *sqlx.DB) L1CrossMsgOrm {
return &l1CrossMsgOrm{db: db}
}
func (l *l1CrossMsgOrm) GetL1CrossMsgByHash(l1Hash common.Hash) (*L1CrossMsg, error) {
result := &L1CrossMsg{}
row := l.db.QueryRowx(`SELECT * FROM l1_cross_message WHERE layer1_hash = $1;`, l1Hash.String())
func (l *l1CrossMsgOrm) GetL1CrossMsgByHash(l1Hash common.Hash) (*CrossMsg, error) {
result := &CrossMsg{}
row := l.db.QueryRowx(`SELECT * FROM cross_message WHERE layer1_hash = $1 AND msg_type = $2 AND NOT is_deleted;`, l1Hash.String(), Layer1Msg)
if err := row.StructScan(result); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
@@ -31,33 +31,14 @@ func (l *l1CrossMsgOrm) GetL1CrossMsgByHash(l1Hash common.Hash) (*L1CrossMsg, er
return result, nil
}
func (l *l1CrossMsgOrm) GetL1CrossMsgsByAddressWithOffset(sender common.Address, offset int64, limit int64) ([]*L1CrossMsg, error) {
para := sender.String()
var results []*L1CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM l1_cross_message WHERE sender = $1 ORDER BY height DESC LIMIT $2 OFFSET $3;`, para, limit, offset)
for rows.Next() {
msg := &L1CrossMsg{}
if err = rows.StructScan(msg); err != nil {
break
}
results = append(results, msg)
}
if len(results) == 0 && errors.Is(err, sql.ErrNoRows) {
} else if err != nil {
return nil, err
}
return results, nil
}
// GetL1CrossMsgsByAddress returns all layer1 cross messages under given address
// Warning: return empty slice if no data found
func (l *l1CrossMsgOrm) GetL1CrossMsgsByAddress(sender common.Address) ([]*L1CrossMsg, error) {
para := sender.String()
var results []*L1CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM l1_cross_message WHERE sender = $1;`, para)
func (l *l1CrossMsgOrm) GetL1CrossMsgsByAddress(sender common.Address) ([]*CrossMsg, error) {
var results []*CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM cross_message WHERE sender = $1 AND msg_type = 1 AND NOT is_deleted;`, sender.String(), Layer1Msg)
for rows.Next() {
msg := &L1CrossMsg{}
msg := &CrossMsg{}
if err = rows.StructScan(msg); err != nil {
break
}
@@ -70,7 +51,7 @@ func (l *l1CrossMsgOrm) GetL1CrossMsgsByAddress(sender common.Address) ([]*L1Cro
return results, nil
}
func (l *l1CrossMsgOrm) BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L1CrossMsg) error {
func (l *l1CrossMsgOrm) BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*CrossMsg) error {
if len(messages) == 0 {
return nil
}
@@ -87,9 +68,10 @@ func (l *l1CrossMsgOrm) BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L1C
"layer1_token": msg.Layer1Token,
"layer2_token": msg.Layer2Token,
"token_id": msg.TokenID,
"msg_type": Layer1Msg,
}
_, err := dbTx.NamedExec(`insert into l1_cross_message(height, sender, target, asset, layer1_hash, layer1_token, layer2_token, token_id, amount) values(:height, :sender, :target, :asset, :layer1_hash, :layer1_token, :layer2_token, :token_id, :amount);`, messageMaps[i])
_, err = dbTx.NamedExec(`insert into cross_message(height, sender, target, asset, layer1_hash, layer1_token, layer2_token, token_id, amount, msg_type) select :height, :sender, :target, :asset, :layer1_hash, :layer1_token, :layer2_token, :token_id, :amount, :msg_type WHERE NOT EXISTS (SELECT 1 FROM cross_message WHERE layer1_hash = :layer1_hash AND NOT is_deleted);`, messageMaps[i])
if err != nil {
log.Error("BatchInsertL1CrossMsgDBTx: failed to insert l1 cross msgs", "l1hashes", msg.Layer1Hash, "heights", msg.Height, "err", err)
break
@@ -98,8 +80,9 @@ func (l *l1CrossMsgOrm) BatchInsertL1CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L1C
return err
}
// UpdateL1CrossMsgHashDBTx update l1 cross msg hash in db, no need to check msg_type since layer1_hash wont be empty if its layer1 msg
func (l *l1CrossMsgOrm) UpdateL1CrossMsgHashDBTx(ctx context.Context, dbTx *sqlx.Tx, l1Hash, msgHash common.Hash) error {
if _, err := dbTx.ExecContext(ctx, l.db.Rebind("update public.l1_cross_message set msg_hash = ? where layer1_hash = ?;"), msgHash.String(), l1Hash.String()); err != nil {
if _, err := dbTx.ExecContext(ctx, l.db.Rebind("update public.cross_message set msg_hash = ? where layer1_hash = ? AND NOT is_deleted;"), msgHash.String(), l1Hash.String()); err != nil {
return err
}
return nil
@@ -107,7 +90,7 @@ func (l *l1CrossMsgOrm) UpdateL1CrossMsgHashDBTx(ctx context.Context, dbTx *sqlx
}
func (l *l1CrossMsgOrm) UpdateL1CrossMsgHash(ctx context.Context, l1Hash, msgHash common.Hash) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update public.l1_cross_message set msg_hash = ? where layer1_hash = ?;"), msgHash.String(), l1Hash.String()); err != nil {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update public.l1_cross_message set msg_hash = ? where layer1_hash = ? AND NOT is_deleted;"), msgHash.String(), l1Hash.String()); err != nil {
return err
}
return nil
@@ -115,7 +98,7 @@ func (l *l1CrossMsgOrm) UpdateL1CrossMsgHash(ctx context.Context, l1Hash, msgHas
}
func (l *l1CrossMsgOrm) GetLatestL1ProcessedHeight() (int64, error) {
row := l.db.QueryRowx(`SELECT MAX(height) FROM l1_cross_message;`)
row := l.db.QueryRowx(`SELECT height FROM cross_message WHERE msg_type = $1 AND NOT is_deleted ORDER BY id DESC LIMIT 1;`, Layer1Msg)
var result sql.NullInt64
if err := row.Scan(&result); err != nil {
if err == sql.ErrNoRows || !result.Valid {
@@ -130,7 +113,7 @@ func (l *l1CrossMsgOrm) GetLatestL1ProcessedHeight() (int64, error) {
}
func (l *l1CrossMsgOrm) DeleteL1CrossMsgAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error {
if _, err := l.db.Exec(`DELETE FROM l1_cross_message WHERE height > $1;`, height); err != nil {
if _, err := l.db.Exec(`UPDATE cross_message SET is_deleted = true WHERE height > $1 AND msg_type = $2;`, height, Layer1Msg); err != nil {
return err
}
return nil

View File

@@ -19,9 +19,9 @@ func NewL2CrossMsgOrm(db *sqlx.DB) L2CrossMsgOrm {
return &l2CrossMsgOrm{db: db}
}
func (l *l2CrossMsgOrm) GetL2CrossMsgByHash(l2Hash common.Hash) (*L2CrossMsg, error) {
result := &L2CrossMsg{}
row := l.db.QueryRowx(`SELECT * FROM l2_cross_message WHERE layer2_hash = $1;`, l2Hash.String())
func (l *l2CrossMsgOrm) GetL2CrossMsgByHash(l2Hash common.Hash) (*CrossMsg, error) {
result := &CrossMsg{}
row := l.db.QueryRowx(`SELECT * FROM l2_cross_message WHERE layer2_hash = $1 AND NOT is_deleted;`, l2Hash.String())
if err := row.StructScan(result); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
@@ -31,33 +31,14 @@ func (l *l2CrossMsgOrm) GetL2CrossMsgByHash(l2Hash common.Hash) (*L2CrossMsg, er
return result, nil
}
func (l *l2CrossMsgOrm) GetL2CrossMsgsByAddressWithOffset(sender common.Address, offset int64, limit int64) ([]*L2CrossMsg, error) {
para := sender.String()
var results []*L2CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM l2_cross_message WHERE sender = $1 ORDER BY height DESC LIMIT $2 OFFSET $3;`, para, limit, offset)
for rows.Next() {
msg := &L2CrossMsg{}
if err = rows.StructScan(msg); err != nil {
break
}
results = append(results, msg)
}
if len(results) == 0 && errors.Is(err, sql.ErrNoRows) {
} else if err != nil {
return nil, err
}
return results, nil
}
// GetL2CrossMsgsByAddress returns all layer2 cross messages under given address
// Warning: return empty slice if no data found
func (l *l2CrossMsgOrm) GetL2CrossMsgByAddress(sender common.Address) ([]*L2CrossMsg, error) {
para := sender.String()
var results []*L2CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM l2_cross_message WHERE sender = $1;`, para)
func (l *l2CrossMsgOrm) GetL2CrossMsgByAddress(sender common.Address) ([]*CrossMsg, error) {
var results []*CrossMsg
rows, err := l.db.Queryx(`SELECT * FROM cross_message WHERE sender = $1 AND msg_type = $2 AND NOT is_deleted;`, sender.String(), Layer2Msg)
for rows.Next() {
msg := &L2CrossMsg{}
msg := &CrossMsg{}
if err = rows.StructScan(msg); err != nil {
break
}
@@ -73,7 +54,7 @@ func (l *l2CrossMsgOrm) GetL2CrossMsgByAddress(sender common.Address) ([]*L2Cros
}
func (l *l2CrossMsgOrm) DeleteL2CrossMsgFromHeightDBTx(dbTx *sqlx.Tx, height int64) error {
_, err := dbTx.Exec(`delete from l2_cross_message where height > $1;`, height)
_, err := dbTx.Exec(`UPDATE cross_message SET is_deleted = true where height > $1 AND msg_type = $2 ;`, height, Layer2Msg)
if err != nil {
log.Error("DeleteL1CrossMsgAfterHeightDBTx: failed to delete", "height", height, "err", err)
return err
@@ -81,7 +62,7 @@ func (l *l2CrossMsgOrm) DeleteL2CrossMsgFromHeightDBTx(dbTx *sqlx.Tx, height int
return nil
}
func (l *l2CrossMsgOrm) BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L2CrossMsg) error {
func (l *l2CrossMsgOrm) BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*CrossMsg) error {
if len(messages) == 0 {
return nil
}
@@ -100,9 +81,10 @@ func (l *l2CrossMsgOrm) BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L2C
"layer2_token": msg.Layer2Token,
"token_id": msg.TokenID,
"amount": msg.Amount,
"msg_type": Layer2Msg,
}
_, err := dbTx.NamedExec(`insert into l2_cross_message(height, sender, target, asset, layer2_hash, layer1_token, layer2_token, token_id, amount) values(:height, :sender, :target, :asset, :layer2_hash, :layer1_token, :layer2_token, :token_id, :amount);`, messageMaps[i])
_, err = dbTx.NamedExec(`insert into cross_message(height, sender, target, asset, layer2_hash, layer1_token, layer2_token, token_id, amount, msg_type) select :height, :sender, :target, :asset, :layer2_hash, :layer1_token, :layer2_token, :token_id, :amount, :msg_type WHERE NOT EXISTS (SELECT 1 FROM cross_message WHERE layer2_hash = :layer2_hash AND NOT is_deleted);`, messageMaps[i])
if err != nil {
log.Error("BatchInsertL2CrossMsgDBTx: failed to insert l2 cross msgs", "layer2hash", msg.Layer2Hash, "heights", msg.Height, "err", err)
break
@@ -112,21 +94,21 @@ func (l *l2CrossMsgOrm) BatchInsertL2CrossMsgDBTx(dbTx *sqlx.Tx, messages []*L2C
}
func (l *l2CrossMsgOrm) UpdateL2CrossMsgHashDBTx(ctx context.Context, dbTx *sqlx.Tx, l2Hash, msgHash common.Hash) error {
if _, err := dbTx.ExecContext(ctx, l.db.Rebind("update public.l2_cross_message set msg_hash = ? where layer2_hash = ?;"), msgHash.String(), l2Hash.String()); err != nil {
if _, err := dbTx.ExecContext(ctx, l.db.Rebind("update public.cross_message set msg_hash = ? where layer2_hash = ? AND NOT is_deleted;"), msgHash.String(), l2Hash.String()); err != nil {
return err
}
return nil
}
func (l *l2CrossMsgOrm) UpdateL2CrossMsgHash(ctx context.Context, l2Hash, msgHash common.Hash) error {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update public.l2_cross_message set msg_hash = ? where layer2_hash = ?;"), msgHash.String(), l2Hash.String()); err != nil {
if _, err := l.db.ExecContext(ctx, l.db.Rebind("update public.cross_message set msg_hash = ? where layer2_hash = ? AND NOT is_deleted;"), msgHash.String(), l2Hash.String()); err != nil {
return err
}
return nil
}
func (l *l2CrossMsgOrm) GetLatestL2ProcessedHeight() (int64, error) {
row := l.db.QueryRowx(`SELECT MAX(height) FROM l2_cross_message WHERE layer2_hash IS NOT NULL;`)
row := l.db.QueryRowx(`SELECT height FROM cross_message WHERE msg_type = $1 AND NOT is_deleted ORDER BY id DESC LIMIT 1;`, Layer2Msg)
var result sql.NullInt64
if err := row.Scan(&result); err != nil {
if err == sql.ErrNoRows || !result.Valid {

View File

@@ -32,7 +32,7 @@ func (l *relayedMsgOrm) BatchInsertRelayedMsgDBTx(dbTx *sqlx.Tx, messages []*Rel
"layer2_hash": msg.Layer2Hash,
}
_, err := dbTx.NamedExec(`insert into relayed_msg(msg_hash, height, layer1_hash, layer2_hash) values(:msg_hash, :height, :layer1_hash, :layer2_hash);`, messageMaps[i])
_, err = dbTx.NamedExec(`insert into relayed_msg(msg_hash, height, layer1_hash, layer2_hash) values(:msg_hash, :height, :layer1_hash, :layer2_hash);`, messageMaps[i])
if err != nil && !strings.Contains(err.Error(), "pq: duplicate key value violates unique constraint \"relayed_msg_hash_uindex") {
log.Error("BatchInsertRelayedMsgDBTx: failed to insert l1 cross msgs", "msg_Hashe", msg.MsgHash, "height", msg.Height, "err", err)
break
@@ -43,7 +43,7 @@ func (l *relayedMsgOrm) BatchInsertRelayedMsgDBTx(dbTx *sqlx.Tx, messages []*Rel
func (l *relayedMsgOrm) GetRelayedMsgByHash(msg_hash string) (*RelayedMsg, error) {
result := &RelayedMsg{}
row := l.db.QueryRowx(`SELECT msg_hash, height, layer1_hash, layer2_hash FROM relayed_msg WHERE msg_hash = $1;`, msg_hash)
row := l.db.QueryRowx(`SELECT msg_hash, height, layer1_hash, layer2_hash FROM relayed_msg WHERE msg_hash = $1 AND NOT is_deleted;`, msg_hash)
if err := row.StructScan(result); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
@@ -54,7 +54,7 @@ func (l *relayedMsgOrm) GetRelayedMsgByHash(msg_hash string) (*RelayedMsg, error
}
func (l *relayedMsgOrm) GetLatestRelayedHeightOnL1() (int64, error) {
row := l.db.QueryRow(`SELECT MAX(height) FROM relayed_msg WHERE layer1_hash != '';`)
row := l.db.QueryRow(`SELECT height FROM relayed_msg WHERE layer1_hash != '' AND NOT is_deleted ORDER BY height DESC LIMIT 1;`)
var result sql.NullInt64
if err := row.Scan(&result); err != nil {
if err == sql.ErrNoRows || !result.Valid {
@@ -68,8 +68,8 @@ func (l *relayedMsgOrm) GetLatestRelayedHeightOnL1() (int64, error) {
return 0, nil
}
func (l *relayedMsgOrm) GetLatestRelayedHeightFromL2() (int64, error) {
row := l.db.QueryRow(`SELECT MAX(height) FROM relayed_msg WHERE layer2_hash != '';`)
func (l *relayedMsgOrm) GetLatestRelayedHeightOnL2() (int64, error) {
row := l.db.QueryRow(`SELECT height FROM relayed_msg WHERE layer2_hash != '' AND NOT is_deleted ORDER BY height DESC LIMIT 1;`)
var result sql.NullInt64
if err := row.Scan(&result); err != nil {
if err == sql.ErrNoRows || !result.Valid {
@@ -83,12 +83,12 @@ func (l *relayedMsgOrm) GetLatestRelayedHeightFromL2() (int64, error) {
return 0, nil
}
func (l *relayedMsgOrm) DeleteL1RelayedHashFromHeightDBTx(dbTx *sqlx.Tx, height int64) error {
_, err := dbTx.Exec(`DELETE FROM relayed_msg WHERE height > $1 AND layer1_hash != '';`, height)
func (l *relayedMsgOrm) DeleteL1RelayedHashAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error {
_, err := dbTx.Exec(`UPDATE relayed_msg SET is_deleted = true WHERE height > $1 AND layer1_hash != '';`, height)
return err
}
func (l *relayedMsgOrm) DeleteL2RelayedHashFromHeightDBTx(dbTx *sqlx.Tx, height int64) error {
_, err := dbTx.Exec(`DELETE FROM relayed_msg WHERE height > $1 AND layer2_hash != '';`, height)
func (l *relayedMsgOrm) DeleteL2RelayedHashAfterHeightDBTx(dbTx *sqlx.Tx, height int64) error {
_, err := dbTx.Exec(`UPDATE relayed_msg SET is_deleted = true WHERE height > $1 AND layer2_hash != '';`, height)
return err
}

View File

@@ -1,6 +1,9 @@
package db
import (
"database/sql"
"errors"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq" //nolint:golint
@@ -13,6 +16,7 @@ type OrmFactory interface {
orm.L1CrossMsgOrm
orm.L2CrossMsgOrm
orm.RelayedMsgOrm
GetCrossMsgsByAddressWithOffset(sender string, offset int64, limit int64) ([]*orm.CrossMsg, error)
GetDB() *sqlx.DB
Beginx() (*sqlx.Tx, error)
Close() error
@@ -54,3 +58,24 @@ func (o *ormFactory) GetDB() *sqlx.DB {
func (o *ormFactory) Beginx() (*sqlx.Tx, error) {
return o.DB.Beginx()
}
func (o *ormFactory) GetCrossMsgsByAddressWithOffset(sender string, offset int64, limit int64) ([]*orm.CrossMsg, error) {
para := sender
var results []*orm.CrossMsg
rows, err := o.DB.Queryx(`SELECT * FROM cross_message WHERE sender = $1 AND NOT is_deleted ORDER BY id DESC LIMIT $2 OFFSET $3;`, para, limit, offset)
if err != nil || rows == nil {
return nil, err
}
for rows.Next() {
msg := &orm.CrossMsg{}
if err = rows.StructScan(msg); err != nil {
break
}
results = append(results, msg)
}
if len(results) == 0 && errors.Is(err, sql.ErrNoRows) {
} else if err != nil {
return nil, err
}
return results, nil
}

View File

@@ -3,7 +3,7 @@ module bridge-history-api
go 1.20
require (
github.com/ethereum/go-ethereum v1.11.4
github.com/ethereum/go-ethereum v1.11.6
github.com/jmoiron/sqlx v1.3.5
github.com/kataras/iris/v12 v12.2.0
github.com/lib/pq v1.10.7
@@ -28,7 +28,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/btcsuite/btcd v0.20.1-beta // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
@@ -37,7 +37,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/docker/docker v20.10.21+incompatible // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
@@ -56,19 +56,19 @@ require (
github.com/gobwas/ws v1.1.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/graph-gophers/graphql-go v1.3.0 // indirect
github.com/hashicorp/go-bexpr v0.1.10 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/holiman/uint256 v1.2.2 // indirect
github.com/huin/goupnp v1.0.3 // indirect
github.com/influxdata/influxdb v1.8.3 // indirect
github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
github.com/iris-contrib/schema v0.0.6 // indirect
@@ -127,17 +127,18 @@ require (
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yosssi/ace v0.0.5 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
google.golang.org/protobuf v1.29.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@@ -1,41 +1,19 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME=
github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc=
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk=
github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0=
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM=
@@ -44,31 +22,22 @@ github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNu
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
@@ -76,17 +45,12 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
@@ -109,29 +73,25 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog=
github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
@@ -141,8 +101,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum/go-ethereum v1.11.4 h1:KG81SnUHXWk8LJB3mBcHg/E2yLvXoiPmRMCIRxgx3cE=
github.com/ethereum/go-ethereum v1.11.4/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo=
github.com/ethereum/go-ethereum v1.11.6 h1:2VF8Mf7XiSUfmoNOy3D+ocfl9Qu8baQBrCNbo2CXQ8E=
github.com/ethereum/go-ethereum v1.11.6/go.mod h1:+a8pUj1tOyJ2RinsNQD4326YS+leSoKGiG/uVVb0x6Y=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
@@ -150,7 +110,6 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlK
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
@@ -167,27 +126,18 @@ github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnR
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -202,26 +152,17 @@ github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -236,15 +177,12 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -255,16 +193,9 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
@@ -277,36 +208,26 @@ github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLt
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk=
github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8=
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k=
github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=
github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk=
github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE=
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs=
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM=
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
@@ -326,14 +247,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4=
github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I=
@@ -355,21 +270,14 @@ github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIR
github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA=
github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -382,7 +290,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
@@ -395,14 +302,12 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
@@ -415,13 +320,10 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
@@ -446,8 +348,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0 h1:xdnzwFETV++jNc4W1mw//qFyJGb2ABOombmZJQS4+Qo=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI=
@@ -478,52 +378,34 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pressly/goose/v3 v3.7.0 h1:jblaZul15uCIEKHRu5KUdA+5wDA7E60JC0TOthdrtf8=
github.com/pressly/goose/v3 v3.7.0/go.mod h1:N5gqPdIzdxf3BiPWdmoPreIwHStkxsvKWE5xjUvfYNk=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
@@ -538,24 +420,19 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo
github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -564,10 +441,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -586,7 +461,6 @@ github.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZy
github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
@@ -610,14 +484,12 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
@@ -636,18 +508,9 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -657,36 +520,15 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -696,19 +538,13 @@ golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -721,13 +557,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -739,29 +571,18 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -790,12 +611,11 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -803,40 +623,20 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -851,48 +651,17 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -908,7 +677,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0=
google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -922,6 +690,8 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -938,10 +708,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
modernc.org/cc/v3 v3.36.1 h1:CICrjwr/1M4+6OQ4HJZ/AHxjcwe67r5vPUF518MkO8A=
modernc.org/ccgo/v3 v3.16.8 h1:G0QNlTqI5uVgczBWfGKs7B++EPwCfXPWGD2MdeKloDs=
@@ -953,5 +720,3 @@ modernc.org/sqlite v1.18.1 h1:ko32eKt3jf7eqIkCgPAeHMBXw3riNSLhl2f3loEF7o8=
modernc.org/strutil v1.1.2 h1:iFBDH6j1Z0bN/Q9udJnnFoFpENA4252qe/7/5woE5MI=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@@ -1,13 +1,13 @@
package service
import (
"sort"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"bridge-history-api/db"
"bridge-history-api/db/orm"
)
type Finalized struct {
@@ -27,7 +27,7 @@ type TxHistoryInfo struct {
BlockNumber uint64 `json:"blockNumber"`
BlockTimestamp *time.Time `json:"blockTimestamp"` // useless
FinalizeTx *Finalized `json:"finalizeTx"`
CreatedTime *time.Time `json:"createdTime"`
CreatedAt *time.Time `json:"createdTime"`
}
// HistoryService example service.
@@ -71,53 +71,24 @@ func updateCrossTxHash(msgHash string, txInfo *TxHistoryInfo, db db.OrmFactory)
func (h *historyBackend) GetTxsByAddress(address common.Address, offset int64, limit int64) ([]*TxHistoryInfo, error) {
txHistories := make([]*TxHistoryInfo, 0)
result, err := h.db.GetL1CrossMsgsByAddressWithOffset(address, offset, limit)
result, err := h.db.GetCrossMsgsByAddressWithOffset(address.String(), offset, limit)
if err != nil {
return nil, err
}
if len(result) > 0 {
for _, r := range result {
txHistory := &TxHistoryInfo{
Hash: r.Layer1Hash,
Amount: r.Amount,
To: r.Target,
IsL1: true,
BlockNumber: r.Height,
CreatedTime: r.CreatedTime,
FinalizeTx: &Finalized{
Hash: "",
},
}
// update relayed info into results
updateCrossTxHash(r.MsgHash, txHistory, h.db)
txHistories = append(txHistories, txHistory)
for _, msg := range result {
txHistory := &TxHistoryInfo{
Hash: msg.MsgHash,
Amount: msg.Amount,
To: msg.Target,
IsL1: msg.MsgType == int(orm.Layer1Msg),
BlockNumber: msg.Height,
CreatedAt: msg.CreatedAt,
FinalizeTx: &Finalized{
Hash: "",
},
}
}
l2Result, err := h.db.GetL2CrossMsgsByAddressWithOffset(address, offset, limit)
if err != nil {
return nil, err
}
if len(l2Result) > 0 {
for _, r := range l2Result {
txHistory := &TxHistoryInfo{
Hash: r.Layer2Hash,
Amount: r.Amount,
To: r.Target,
IsL1: false,
BlockNumber: r.Height,
CreatedTime: r.CreatedTime,
FinalizeTx: &Finalized{
Hash: "",
},
}
updateCrossTxHash(r.MsgHash, txHistory, h.db)
txHistories = append(txHistories, txHistory)
}
}
if len(txHistories) > 0 {
sort.Slice(txHistories, func(i, j int) bool {
return txHistories[i].CreatedTime.Second() > txHistories[j].CreatedTime.Second()
})
updateCrossTxHash(msg.MsgHash, txHistory, h.db)
txHistories = append(txHistories, txHistory)
}
return txHistories, nil
}
@@ -136,7 +107,7 @@ func (h *historyBackend) GetTxsByHashes(hashes []string) ([]*TxHistoryInfo, erro
To: l1result.Target,
IsL1: true,
BlockNumber: l1result.Height,
CreatedTime: l1result.CreatedTime,
CreatedAt: l1result.CreatedAt,
FinalizeTx: &Finalized{
Hash: "",
},
@@ -156,7 +127,7 @@ func (h *historyBackend) GetTxsByHashes(hashes []string) ([]*TxHistoryInfo, erro
To: l2result.Target,
IsL1: false,
BlockNumber: l2result.Height,
CreatedTime: l2result.CreatedTime,
CreatedAt: l2result.CreatedAt,
FinalizeTx: &Finalized{
Hash: "",
},

View File

@@ -31,7 +31,7 @@
"1212121212121212121212121212121212121212121212121212121212121212"
],
"gas_oracle_sender_private_keys": [
"1212121212121212121212121212121212121212121212121212121212121212"
"1313131313131313131313131313131313131313131313131313131313131313"
]
}
},
@@ -66,10 +66,10 @@
"1212121212121212121212121212121212121212121212121212121212121212"
],
"gas_oracle_sender_private_keys": [
"1212121212121212121212121212121212121212121212121212121212121212"
"1313131313131313131313131313131313131313131313131313131313131313"
],
"rollup_sender_private_keys": [
"1212121212121212121212121212121212121212121212121212121212121212"
"1414141414141414141414141414141414141414141414141414141414141414"
]
},
"batch_proposer_config": {

View File

@@ -13,7 +13,7 @@ import (
func TestConfig(t *testing.T) {
t.Run("Success Case", func(t *testing.T) {
cfg, err := NewConfig("../config.json")
assert.NoError(t, err, "failed to load config")
assert.NoError(t, err)
assert.Len(t, cfg.L1Config.RelayerConfig.MessageSenderPrivateKeys, 1)
assert.Len(t, cfg.L2Config.RelayerConfig.MessageSenderPrivateKeys, 1)
@@ -23,7 +23,11 @@ func TestConfig(t *testing.T) {
assert.NoError(t, err)
tmpJSON := fmt.Sprintf("/tmp/%d_bridge_config.json", time.Now().Nanosecond())
defer func() { _ = os.Remove(tmpJSON) }()
defer func() {
if _, err = os.Stat(tmpJSON); err == nil {
assert.NoError(t, os.Remove(tmpJSON))
}
}()
assert.NoError(t, os.WriteFile(tmpJSON, data, 0644))
@@ -42,14 +46,17 @@ func TestConfig(t *testing.T) {
t.Run("Invalid JSON Content", func(t *testing.T) {
// Create a temporary file with invalid JSON content
tempFile, err := os.CreateTemp("", "invalid_json_config.json")
tmpFile, err := os.CreateTemp("", "invalid_json_config.json")
assert.NoError(t, err)
defer os.Remove(tempFile.Name())
defer func() {
assert.NoError(t, tmpFile.Close())
assert.NoError(t, os.Remove(tmpFile.Name()))
}()
_, err = tempFile.WriteString("{ invalid_json: ")
_, err = tmpFile.WriteString("{ invalid_json: ")
assert.NoError(t, err)
_, err = NewConfig(tempFile.Name())
_, err = NewConfig(tmpFile.Name())
assert.Error(t, err)
})
}

View File

@@ -6,7 +6,7 @@ require (
github.com/agiledragon/gomonkey/v2 v2.9.0
github.com/orcaman/concurrent-map v1.0.0
github.com/orcaman/concurrent-map/v2 v2.0.1
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61
github.com/smartystreets/goconvey v1.8.0
github.com/stretchr/testify v1.8.2
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa
@@ -16,17 +16,21 @@ require (
require (
github.com/btcsuite/btcd v0.20.1-beta // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/ethereum/go-ethereum v1.11.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/iden3/go-iden3-crypto v0.0.14 // indirect
github.com/huin/goupnp v1.0.3 // indirect
github.com/iden3/go-iden3-crypto v0.0.15 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -36,16 +40,17 @@ require (
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/scroll-tech/zktrie v0.5.2 // indirect
github.com/scroll-tech/zktrie v0.5.3 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/smartystreets/assertions v1.13.1 // indirect
github.com/status-im/keycard-go v0.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/time v0.3.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect

View File

@@ -13,8 +13,10 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -22,8 +24,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/ethereum/go-ethereum v1.11.4 h1:KG81SnUHXWk8LJB3mBcHg/E2yLvXoiPmRMCIRxgx3cE=
github.com/ethereum/go-ethereum v1.11.4/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
@@ -46,9 +46,12 @@ github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZ
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
github.com/iden3/go-iden3-crypto v0.0.14 h1:HQnFchY735JRNQxof6n/Vbyon4owj4+Ku+LNAamWV6c=
github.com/iden3/go-iden3-crypto v0.0.14/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4=
github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -56,11 +59,15 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
@@ -76,6 +83,7 @@ github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HD
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=
github.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -87,15 +95,16 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04 h1:PpI31kaBVm6+7sZtyK03Ex0QIg3P821Ktae0FHFh7IM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04/go.mod h1:jH8c08L9K8Hieaf0r/ur2P/cpesn4dFhmLm2Mmoi8kI=
github.com/scroll-tech/zktrie v0.5.2 h1:U34jPXMLGOlRHfdvYp5VVgOcC0RuPeJmcS3bWotCWiY=
github.com/scroll-tech/zktrie v0.5.2/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61 h1:4fslVpNOPLeJPYX3tivrVWgqNvChPs7/y9OqWvQSNCw=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61/go.mod h1:45PZqlQCqV0dU4o4+SE8LoJLEvXkK5j45ligvbih9QY=
github.com/scroll-tech/zktrie v0.5.3 h1:jjzQchGU6XPL5s1C5bwwivSadefSRuYASE9OL7UKAdE=
github.com/scroll-tech/zktrie v0.5.3/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -105,6 +114,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/smartystreets/goconvey v1.8.0 h1:Oi49ha/2MURE0WexF052Z0m+BNSGirfjg5RL+JXWq3w=
github.com/smartystreets/goconvey v1.8.0/go.mod h1:EdX8jtrTIj26jmjCOVNMVSIYAtgexqXKHOXW2Dx9JLg=
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -118,6 +128,7 @@ github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7Am
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q=
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
@@ -126,23 +137,27 @@ github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPR
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=

View File

@@ -12,14 +12,13 @@ import (
"github.com/stretchr/testify/assert"
"scroll-tech/database"
"scroll-tech/database/migrate"
"scroll-tech/common/types"
"scroll-tech/common/utils"
"scroll-tech/bridge/sender"
"scroll-tech/database"
)
var (

View File

@@ -11,7 +11,9 @@ import (
"golang.org/x/sync/errgroup"
"github.com/agiledragon/gomonkey/v2"
cmap "github.com/orcaman/concurrent-map"
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto"
@@ -63,7 +65,8 @@ func TestSender(t *testing.T) {
t.Run("test pending limit", testPendLimit)
t.Run("test min gas limit", testMinGasLimit)
t.Run("test resubmit transaction", func(t *testing.T) { testResubmitTransaction(t) })
t.Run("test resubmit transaction", testResubmitTransaction)
t.Run("test check pending transaction", testCheckPendingTransaction)
t.Run("test 1 account sender", func(t *testing.T) { testBatchSender(t, 1) })
t.Run("test 3 account sender", func(t *testing.T) { testBatchSender(t, 3) })
@@ -152,6 +155,95 @@ func testResubmitTransaction(t *testing.T) {
}
}
func testCheckPendingTransaction(t *testing.T) {
for _, txType := range txTypes {
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
cfgCopy.TxType = txType
s, err := NewSender(context.Background(), &cfgCopy, privateKeys)
assert.NoError(t, err)
header := &types.Header{Number: big.NewInt(100), BaseFee: big.NewInt(100)}
confirmed := uint64(100)
receipt := &types.Receipt{Status: types.ReceiptStatusSuccessful, BlockNumber: big.NewInt(90)}
auth := s.auths.getAccount()
tx := types.NewTransaction(auth.Nonce.Uint64(), common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil)
testCases := []struct {
name string
receipt *types.Receipt
receiptErr error
resubmitErr error
expectedCount int
expectedFound bool
}{
{
name: "Normal case, transaction receipt exists and successful",
receipt: receipt,
receiptErr: nil,
resubmitErr: nil,
expectedCount: 0,
expectedFound: false,
},
{
name: "Resubmit case, resubmitTransaction error (not nonce) case",
receipt: receipt,
receiptErr: errors.New("receipt error"),
resubmitErr: errors.New("resubmit error"),
expectedCount: 1,
expectedFound: true,
},
{
name: "Resubmit case, resubmitTransaction success case",
receipt: receipt,
receiptErr: errors.New("receipt error"),
resubmitErr: nil,
expectedCount: 1,
expectedFound: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var c *ethclient.Client
patchGuard := gomonkey.ApplyMethodFunc(c, "TransactionReceipt", func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
return tc.receipt, tc.receiptErr
})
patchGuard.ApplyPrivateMethod(s, "resubmitTransaction",
func(feeData *FeeData, auth *bind.TransactOpts, tx *types.Transaction) (*types.Transaction, error) {
return tx, tc.resubmitErr
},
)
pendingTx := &PendingTransaction{id: "abc", tx: tx, submitAt: header.Number.Uint64() - s.config.EscalateBlocks - 1}
s.pendingTxs.Set(pendingTx.id, pendingTx)
s.checkPendingTransaction(header, confirmed)
if tc.receiptErr == nil {
expectedConfirmation := &Confirmation{
ID: pendingTx.id,
IsSuccessful: tc.receipt.Status == types.ReceiptStatusSuccessful,
TxHash: pendingTx.tx.Hash(),
}
actualConfirmation := <-s.confirmCh
assert.Equal(t, expectedConfirmation, actualConfirmation)
}
if tc.expectedFound && tc.resubmitErr == nil {
actualPendingTx, found := s.pendingTxs.Get(pendingTx.id)
assert.Equal(t, true, found)
assert.Equal(t, header.Number.Uint64(), actualPendingTx.submitAt)
}
_, found := s.pendingTxs.Get(pendingTx.id)
assert.Equal(t, tc.expectedFound, found)
assert.Equal(t, tc.expectedCount, s.pendingTxs.Count())
patchGuard.Reset()
})
}
s.Stop()
}
}
func testBatchSender(t *testing.T, batchSize int) {
for _, txType := range txTypes {
for len(privateKeys) < batchSize {

View File

@@ -2,31 +2,23 @@ package tests
import (
"context"
"crypto/ecdsa"
"math/big"
"testing"
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/ethclient"
"github.com/scroll-tech/go-ethereum/rpc"
"github.com/stretchr/testify/assert"
"scroll-tech/bridge/config"
bcmd "scroll-tech/bridge/cmd"
"scroll-tech/bridge/mock_bridge"
"scroll-tech/common/docker"
)
var (
// config
cfg *config.Config
// private key
privateKey *ecdsa.PrivateKey
base *docker.App
base *docker.App
bridgeApp *bcmd.MockApp
// clients
l1Client *ethclient.Client
@@ -51,99 +43,32 @@ var (
func TestMain(m *testing.M) {
base = docker.NewDockerApp()
bridgeApp = bcmd.NewBridgeApp(base, "../config.json")
m.Run()
bridgeApp.Free()
base.Free()
}
func setupEnv(t *testing.T) {
var err error
privateKey, err = crypto.ToECDSA(common.FromHex("1212121212121212121212121212121212121212121212121212121212121212"))
assert.NoError(t, err)
messagePrivateKey, err := crypto.ToECDSA(common.FromHex("1212121212121212121212121212121212121212121212121212121212121213"))
assert.NoError(t, err)
rollupPrivateKey, err := crypto.ToECDSA(common.FromHex("1212121212121212121212121212121212121212121212121212121212121214"))
assert.NoError(t, err)
gasOraclePrivateKey, err := crypto.ToECDSA(common.FromHex("1212121212121212121212121212121212121212121212121212121212121215"))
assert.NoError(t, err)
// Load config.
cfg, err = config.NewConfig("../config.json")
assert.NoError(t, err)
cfg.L1Config.Confirmations = rpc.LatestBlockNumber
cfg.L1Config.RelayerConfig.MessageSenderPrivateKeys = []*ecdsa.PrivateKey{messagePrivateKey}
cfg.L1Config.RelayerConfig.RollupSenderPrivateKeys = []*ecdsa.PrivateKey{rollupPrivateKey}
cfg.L1Config.RelayerConfig.GasOracleSenderPrivateKeys = []*ecdsa.PrivateKey{gasOraclePrivateKey}
cfg.L2Config.Confirmations = rpc.LatestBlockNumber
cfg.L2Config.RelayerConfig.MessageSenderPrivateKeys = []*ecdsa.PrivateKey{messagePrivateKey}
cfg.L2Config.RelayerConfig.RollupSenderPrivateKeys = []*ecdsa.PrivateKey{rollupPrivateKey}
cfg.L2Config.RelayerConfig.GasOracleSenderPrivateKeys = []*ecdsa.PrivateKey{gasOraclePrivateKey}
base.RunImages(t)
// Create l1geth container.
cfg.L2Config.RelayerConfig.SenderConfig.Endpoint = base.L1gethImg.Endpoint()
cfg.L1Config.Endpoint = base.L1gethImg.Endpoint()
// Create l2geth container.
cfg.L1Config.RelayerConfig.SenderConfig.Endpoint = base.L2gethImg.Endpoint()
cfg.L2Config.Endpoint = base.L2gethImg.Endpoint()
// Create db container.
cfg.DBConfig = base.DBConfig
// Create l1geth and l2geth client.
l1Client, err = ethclient.Dial(cfg.L1Config.Endpoint)
var err error
l1Client, err = base.L1Client()
assert.NoError(t, err)
l2Client, err = ethclient.Dial(cfg.L2Config.Endpoint)
l2Client, err = base.L2Client()
assert.NoError(t, err)
// Create l1 and l2 auth
l1Auth = prepareAuth(t, l1Client, privateKey)
l2Auth = prepareAuth(t, l2Client, privateKey)
l1Cfg, l2Cfg := bridgeApp.Config.L1Config, bridgeApp.Config.L2Config
l1Cfg.Confirmations = 0
l1Cfg.RelayerConfig.SenderConfig.Confirmations = 0
l2Cfg.Confirmations = 0
l2Cfg.RelayerConfig.SenderConfig.Confirmations = 0
// send some balance to message and rollup sender
transferEther(t, l1Auth, l1Client, messagePrivateKey)
transferEther(t, l1Auth, l1Client, rollupPrivateKey)
transferEther(t, l1Auth, l1Client, gasOraclePrivateKey)
transferEther(t, l2Auth, l2Client, messagePrivateKey)
transferEther(t, l2Auth, l2Client, rollupPrivateKey)
transferEther(t, l2Auth, l2Client, gasOraclePrivateKey)
}
func transferEther(t *testing.T, auth *bind.TransactOpts, client *ethclient.Client, privateKey *ecdsa.PrivateKey) {
targetAddress := crypto.PubkeyToAddress(privateKey.PublicKey)
gasPrice, err := client.SuggestGasPrice(context.Background())
assert.NoError(t, err)
gasPrice.Mul(gasPrice, big.NewInt(2))
// Get pending nonce
nonce, err := client.PendingNonceAt(context.Background(), auth.From)
l1Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.MessageSenderPrivateKeys[0], base.L1gethImg.ChainID())
assert.NoError(t, err)
// 200 ether should be enough
value, ok := big.NewInt(0).SetString("0xad78ebc5ac6200000", 0)
assert.Equal(t, ok, true)
tx := types.NewTx(&types.LegacyTx{
Nonce: nonce,
To: &targetAddress,
Value: value,
Gas: 500000,
GasPrice: gasPrice,
})
signedTx, err := auth.Signer(auth.From, tx)
l2Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L1Config.RelayerConfig.MessageSenderPrivateKeys[0], base.L2gethImg.ChainID())
assert.NoError(t, err)
err = client.SendTransaction(context.Background(), signedTx)
assert.NoError(t, err)
receipt, err := bind.WaitMined(context.Background(), client, signedTx)
assert.NoError(t, err)
if receipt.Status != types.ReceiptStatusSuccessful {
t.Fatalf("Call failed")
}
}
func prepareContracts(t *testing.T) {
@@ -168,27 +93,18 @@ func prepareContracts(t *testing.T) {
l2MessengerAddress, err = bind.WaitDeployed(context.Background(), l2Client, tx)
assert.NoError(t, err)
cfg.L1Config.L1MessengerAddress = l1MessengerAddress
cfg.L1Config.L1MessageQueueAddress = l1MessengerAddress
cfg.L1Config.ScrollChainContractAddress = scrollChainAddress
cfg.L1Config.RelayerConfig.MessengerContractAddress = l2MessengerAddress
cfg.L1Config.RelayerConfig.GasPriceOracleContractAddress = l1MessengerAddress
l1Config, l2Config := bridgeApp.Config.L1Config, bridgeApp.Config.L2Config
l1Config.L1MessengerAddress = l1MessengerAddress
l1Config.L1MessageQueueAddress = l1MessengerAddress
l1Config.ScrollChainContractAddress = scrollChainAddress
l1Config.RelayerConfig.MessengerContractAddress = l2MessengerAddress
l1Config.RelayerConfig.GasPriceOracleContractAddress = l1MessengerAddress
cfg.L2Config.L2MessengerAddress = l2MessengerAddress
cfg.L2Config.L2MessageQueueAddress = l2MessengerAddress
cfg.L2Config.RelayerConfig.MessengerContractAddress = l1MessengerAddress
cfg.L2Config.RelayerConfig.RollupContractAddress = scrollChainAddress
cfg.L2Config.RelayerConfig.GasPriceOracleContractAddress = l2MessengerAddress
}
func prepareAuth(t *testing.T, client *ethclient.Client, privateKey *ecdsa.PrivateKey) *bind.TransactOpts {
chainID, err := client.ChainID(context.Background())
assert.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
assert.NoError(t, err)
auth.Value = big.NewInt(0) // in wei
assert.NoError(t, err)
return auth
l2Config.L2MessengerAddress = l2MessengerAddress
l2Config.L2MessageQueueAddress = l2MessengerAddress
l2Config.RelayerConfig.MessengerContractAddress = l1MessengerAddress
l2Config.RelayerConfig.RollupContractAddress = scrollChainAddress
l2Config.RelayerConfig.GasPriceOracleContractAddress = l2MessengerAddress
}
func TestFunction(t *testing.T) {

View File

@@ -20,14 +20,14 @@ import (
func testImportL1GasPrice(t *testing.T) {
// Create db handler and reset db.
db, err := database.NewOrmFactory(cfg.DBConfig)
db, err := database.NewOrmFactory(base.DBConfig)
assert.NoError(t, err)
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
defer db.Close()
prepareContracts(t)
l1Cfg := cfg.L1Config
l1Cfg := bridgeApp.Config.L1Config
// Create L1Relayer
l1Relayer, err := relayer.NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig)
@@ -70,14 +70,14 @@ func testImportL1GasPrice(t *testing.T) {
func testImportL2GasPrice(t *testing.T) {
// Create db handler and reset db.
db, err := database.NewOrmFactory(cfg.DBConfig)
db, err := database.NewOrmFactory(base.DBConfig)
assert.NoError(t, err)
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
defer db.Close()
prepareContracts(t)
l2Cfg := cfg.L2Config
l2Cfg := bridgeApp.Config.L2Config
// Create L2Relayer
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig)
@@ -104,7 +104,7 @@ func testImportL2GasPrice(t *testing.T) {
}
batchData := types.NewBatchData(parentBatch, []*types.WrappedBlock{
traces[0],
}, cfg.L2Config.BatchProposerConfig.PublicInputConfig)
}, l2Cfg.BatchProposerConfig.PublicInputConfig)
// add fake batch
dbTx, err := db.Beginx()

View File

@@ -22,15 +22,15 @@ import (
func testRelayL1MessageSucceed(t *testing.T) {
// Create db handler and reset db.
db, err := database.NewOrmFactory(cfg.DBConfig)
db, err := database.NewOrmFactory(base.DBConfig)
assert.NoError(t, err)
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
defer db.Close()
prepareContracts(t)
l1Cfg := cfg.L1Config
l2Cfg := cfg.L2Config
l1Cfg := bridgeApp.Config.L1Config
l2Cfg := bridgeApp.Config.L2Config
// Create L1Relayer
l1Relayer, err := relayer.NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig)

View File

@@ -22,14 +22,14 @@ import (
func testRelayL2MessageSucceed(t *testing.T) {
// Create db handler and reset db.
db, err := database.NewOrmFactory(cfg.DBConfig)
db, err := database.NewOrmFactory(base.DBConfig)
assert.NoError(t, err)
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
defer db.Close()
prepareContracts(t)
l2Cfg := cfg.L2Config
l2Cfg := bridgeApp.Config.L2Config
// Create L2Watcher
confirmations := rpc.LatestBlockNumber
@@ -40,7 +40,7 @@ func testRelayL2MessageSucceed(t *testing.T) {
assert.NoError(t, err)
// Create L1Watcher
l1Cfg := cfg.L1Config
l1Cfg := bridgeApp.Config.L1Config
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, 0, confirmations, l1Cfg.L1MessengerAddress, l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db)
// send message through l2 messenger contract
@@ -85,7 +85,7 @@ func testRelayL2MessageSucceed(t *testing.T) {
}
batchData := types.NewBatchData(parentBatch, []*types.WrappedBlock{
traces[0],
}, cfg.L2Config.BatchProposerConfig.PublicInputConfig)
}, l2Cfg.BatchProposerConfig.PublicInputConfig)
batchHash := batchData.Hash().String()
// add fake batch

View File

@@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/assert"
"scroll-tech/common/types"
"scroll-tech/common/utils"
"scroll-tech/bridge/relayer"
"scroll-tech/bridge/watcher"
@@ -21,7 +22,7 @@ import (
func testCommitBatchAndFinalizeBatch(t *testing.T) {
// Create db handler and reset db.
db, err := database.NewOrmFactory(cfg.DBConfig)
db, err := database.NewOrmFactory(base.DBConfig)
assert.NoError(t, err)
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
defer db.Close()
@@ -29,12 +30,12 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
prepareContracts(t)
// Create L2Relayer
l2Cfg := cfg.L2Config
l2Cfg := bridgeApp.Config.L2Config
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig)
assert.NoError(t, err)
// Create L1Watcher
l1Cfg := cfg.L1Config
l1Cfg := bridgeApp.Config.L1Config
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, 0, l1Cfg.Confirmations, l1Cfg.L1MessengerAddress, l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db)
// add some blocks to db
@@ -63,7 +64,7 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
batchData := types.NewBatchData(parentBatch, []*types.WrappedBlock{
wrappedBlocks[0],
wrappedBlocks[1],
}, cfg.L2Config.BatchProposerConfig.PublicInputConfig)
}, l2Cfg.BatchProposerConfig.PublicInputConfig)
batchHash := batchData.Hash().String()
@@ -80,7 +81,7 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
assert.NoError(t, dbTx.Commit())
// process pending batch and check status
l2Relayer.SendCommitTx([]*types.BatchData{batchData})
assert.NoError(t, l2Relayer.SendCommitTx([]*types.BatchData{batchData}))
status, err := db.GetRollupStatus(batchHash)
assert.NoError(t, err)
@@ -97,9 +98,11 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
// fetch rollup events
err = l1Watcher.FetchContractEvent()
assert.NoError(t, err)
status, err = db.GetRollupStatus(batchHash)
assert.NoError(t, err)
assert.Equal(t, types.RollupCommitted, status)
ok := utils.TryTimes(20, func() bool {
status, err = db.GetRollupStatus(batchHash)
return err == nil && status == types.RollupCommitted
})
assert.True(t, ok)
// add dummy proof
tProof := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
@@ -112,9 +115,12 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
// process committed batch and check status
l2Relayer.ProcessCommittedBatches()
status, err = db.GetRollupStatus(batchHash)
assert.NoError(t, err)
assert.Equal(t, types.RollupFinalizing, status)
ok = utils.TryTimes(20, func() bool {
status, err = db.GetRollupStatus(batchHash)
return err == nil && status == types.RollupFinalizing
})
assert.True(t, ok)
finalizeTxHash, err := db.GetFinalizeTxHash(batchHash)
assert.NoError(t, err)
assert.Equal(t, true, finalizeTxHash.Valid)

View File

@@ -25,9 +25,11 @@ var (
bridgeL2BatchesTxsOverThresholdTotalCounter = geth_metrics.NewRegisteredCounter("bridge/l2/batches/txs/over/threshold/total", metrics.ScrollRegistry)
bridgeL2BatchesBlocksCreatedTotalCounter = geth_metrics.NewRegisteredCounter("bridge/l2/batches/blocks/created/total", metrics.ScrollRegistry)
bridgeL2BatchesCommitsSentTotalCounter = geth_metrics.NewRegisteredCounter("bridge/l2/batches/commits/sent/total", metrics.ScrollRegistry)
bridgeL2BatchesOversizedTotalCounter = geth_metrics.NewRegisteredCounter("bridge/l2/batches/oversized/total", metrics.ScrollRegistry)
bridgeL2BatchesTxsCreatedPerBatchGauge = geth_metrics.NewRegisteredGauge("bridge/l2/batches/txs/created/per/batch", metrics.ScrollRegistry)
bridgeL2BatchesGasCreatedPerBatchGauge = geth_metrics.NewRegisteredGauge("bridge/l2/batches/gas/created/per/batch", metrics.ScrollRegistry)
bridgeL2BatchesTxsCreatedPerBatchGauge = geth_metrics.NewRegisteredGauge("bridge/l2/batches/txs/created/per/batch", metrics.ScrollRegistry)
bridgeL2BatchesGasCreatedPerBatchGauge = geth_metrics.NewRegisteredGauge("bridge/l2/batches/gas/created/per/batch", metrics.ScrollRegistry)
bridgeL2BatchesPayloadSizePerBatchGauge = geth_metrics.NewRegisteredGauge("bridge/l2/batches/payload/size/per/batch", metrics.ScrollRegistry)
)
// AddBatchInfoToDB inserts the batch information to the BlockBatch table and updates the batch_hash
@@ -229,7 +231,10 @@ func (p *BatchProposer) TryCommitBatches() {
index := 0
commit := false
calldataByteLen := uint64(0)
for ; index < len(p.batchDataBuffer); index++ {
// allow at most 30 batches to be committed in a single transaction
// note: we need a more fine-tuned approach, the batch proposer
// must break up a transaction if we run into "exceeds block gas limit"
for ; index < len(p.batchDataBuffer) && index < 30; index++ {
calldataByteLen += bridgeabi.GetBatchCalldataLength(&p.batchDataBuffer[index].Batch)
if calldataByteLen > p.commitCalldataSizeLimit {
commit = true
@@ -297,7 +302,9 @@ func (p *BatchProposer) proposeBatch(blocks []*types.BlockInfo) bool {
}
bridgeL2BatchesTxsCreatedPerBatchGauge.Update(int64(blocks[0].TxNum))
bridgeL2BatchesGasCreatedPerBatchGauge.Update(int64(blocks[0].GasUsed))
bridgeL2BatchesPayloadSizePerBatchGauge.Update(int64(firstSize))
bridgeL2BatchesBlocksCreatedTotalCounter.Inc(1)
bridgeL2BatchesOversizedTotalCounter.Inc(1)
return true
}
@@ -309,6 +316,7 @@ func (p *BatchProposer) proposeBatch(blocks []*types.BlockInfo) bool {
} else {
bridgeL2BatchesTxsCreatedPerBatchGauge.Update(int64(blocks[0].TxNum))
bridgeL2BatchesGasCreatedPerBatchGauge.Update(int64(blocks[0].GasUsed))
bridgeL2BatchesPayloadSizePerBatchGauge.Update(int64(firstSize))
bridgeL2BatchesBlocksCreatedTotalCounter.Inc(1)
}
return true
@@ -322,6 +330,7 @@ func (p *BatchProposer) proposeBatch(blocks []*types.BlockInfo) bool {
} else {
bridgeL2BatchesTxsCreatedPerBatchGauge.Update(int64(blocks[0].TxNum))
bridgeL2BatchesGasCreatedPerBatchGauge.Update(int64(blocks[0].GasUsed))
bridgeL2BatchesPayloadSizePerBatchGauge.Update(int64(firstSize))
bridgeL2BatchesBlocksCreatedTotalCounter.Inc(1)
}
return true
@@ -359,6 +368,7 @@ func (p *BatchProposer) proposeBatch(blocks []*types.BlockInfo) bool {
} else {
bridgeL2BatchesTxsCreatedPerBatchGauge.Update(int64(txNum))
bridgeL2BatchesGasCreatedPerBatchGauge.Update(int64(gasUsed))
bridgeL2BatchesPayloadSizePerBatchGauge.Update(int64(payloadSize))
bridgeL2BatchesBlocksCreatedTotalCounter.Inc(int64(len(blocks)))
}

View File

@@ -140,10 +140,14 @@ func (w *L1WatcherClient) FetchBlockHeader(blockHeight uint64) error {
log.Warn("Failed to get block", "height", height, "err", err)
break
}
var baseFee uint64
if block.BaseFee != nil {
baseFee = block.BaseFee.Uint64()
}
blocks = append(blocks, &types.L1BlockInfo{
Number: uint64(height),
Hash: block.Hash().String(),
BaseFee: block.BaseFee.Uint64(),
BaseFee: baseFee,
})
}

View File

@@ -0,0 +1,11 @@
# Start from the latest golang base image
FROM golang:1.18
# Install Docker
RUN apt-get update && apt-get install -y docker.io
# Set the working directory
WORKDIR /go/src/app
# This container will be executable
ENTRYPOINT [ "/bin/bash" ]

View File

@@ -3,7 +3,7 @@ set -uex
profile_name=$1
exclude_dirs=("scroll-tech/bridge/cmd" "scroll-tech/bridge/tests" "scroll-tech/bridge/mock_bridge" "scroll-tech/coordinator/cmd")
exclude_dirs=("scroll-tech/bridge/cmd" "scroll-tech/bridge/tests" "scroll-tech/bridge/mock_bridge" "scroll-tech/coordinator/cmd" "scroll-tech/coordinator/verifier")
all_packages=$(go list ./... | grep -v "^scroll-tech/${profile_name}$")
coverpkg="scroll-tech/${profile_name}"

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
FROM scrolltech/l2geth:scroll-v3.1.4
FROM scrolltech/l2geth:scroll-v3.1.12
RUN mkdir -p /l2geth/keystore

File diff suppressed because one or more lines are too long

View File

@@ -10,10 +10,9 @@ require (
github.com/mattn/go-isatty v0.0.18
github.com/modern-go/reflect2 v1.0.2
github.com/orcaman/concurrent-map v1.0.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61
github.com/stretchr/testify v1.8.2
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa
gotest.tools v2.2.0+incompatible
)
require (
@@ -29,8 +28,8 @@ require (
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/ethereum/go-ethereum v1.11.4 // indirect
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/go-kit/kit v0.9.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
@@ -48,11 +47,13 @@ require (
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/huin/goupnp v1.0.3 // indirect
github.com/iden3/go-iden3-crypto v0.0.14 // indirect
github.com/iden3/go-iden3-crypto v0.0.15 // indirect
github.com/influxdata/influxdb v1.8.3 // indirect
github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-sqlite3 v1.14.14 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -74,7 +75,7 @@ require (
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/scroll-tech/zktrie v0.5.2 // indirect
github.com/scroll-tech/zktrie v0.5.3 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/status-im/keycard-go v0.2.0 // indirect
@@ -84,11 +85,11 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.8.0 // indirect

View File

@@ -62,6 +62,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
@@ -90,14 +91,13 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum/go-ethereum v1.11.4 h1:KG81SnUHXWk8LJB3mBcHg/E2yLvXoiPmRMCIRxgx3cE=
github.com/ethereum/go-ethereum v1.11.4/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
@@ -194,8 +194,8 @@ github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iden3/go-iden3-crypto v0.0.14 h1:HQnFchY735JRNQxof6n/Vbyon4owj4+Ku+LNAamWV6c=
github.com/iden3/go-iden3-crypto v0.0.14/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4=
github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8=
@@ -224,6 +224,7 @@ github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@@ -239,9 +240,11 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
@@ -323,6 +326,7 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -349,16 +353,17 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04 h1:PpI31kaBVm6+7sZtyK03Ex0QIg3P821Ktae0FHFh7IM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230321020420-127af384ed04/go.mod h1:jH8c08L9K8Hieaf0r/ur2P/cpesn4dFhmLm2Mmoi8kI=
github.com/scroll-tech/zktrie v0.5.2 h1:U34jPXMLGOlRHfdvYp5VVgOcC0RuPeJmcS3bWotCWiY=
github.com/scroll-tech/zktrie v0.5.2/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61 h1:4fslVpNOPLeJPYX3tivrVWgqNvChPs7/y9OqWvQSNCw=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230508165858-27a3830afa61/go.mod h1:45PZqlQCqV0dU4o4+SE8LoJLEvXkK5j45ligvbih9QY=
github.com/scroll-tech/zktrie v0.5.3 h1:jjzQchGU6XPL5s1C5bwwivSadefSRuYASE9OL7UKAdE=
github.com/scroll-tech/zktrie v0.5.3/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@@ -426,8 +431,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -479,8 +484,8 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -534,10 +539,11 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -655,8 +661,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=

View File

@@ -241,6 +241,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
[[package]]
name = "base64ct"
version = "1.0.1"
@@ -301,9 +307,9 @@ dependencies = [
[[package]]
name = "blake2b_simd"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127"
checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc"
dependencies = [
"arrayref",
"arrayvec 0.7.2",
@@ -339,7 +345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"block-padding 0.2.1",
"generic-array 0.14.5",
"generic-array 0.14.6",
]
[[package]]
@@ -348,7 +354,7 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
]
[[package]]
@@ -402,7 +408,7 @@ checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "bus-mapping"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"eth-types",
"ethers-core",
@@ -423,6 +429,7 @@ dependencies = [
"pallet-evm-precompile-curve25519",
"pallet-evm-precompile-modexp",
"pallet-evm-precompile-simple",
"poseidon-circuit",
"primitive-types 0.12.1",
"rand 0.8.5",
"serde",
@@ -457,9 +464,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.2.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
dependencies = [
"serde",
]
@@ -532,7 +539,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
]
[[package]]
@@ -621,7 +628,7 @@ dependencies = [
"bech32",
"blake2",
"digest 0.10.3",
"generic-array 0.14.5",
"generic-array 0.14.6",
"hex",
"ripemd",
"serde",
@@ -639,9 +646,9 @@ checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b"
[[package]]
name = "convert_case"
@@ -669,8 +676,9 @@ dependencies = [
[[package]]
name = "cranelift-entity"
version = "0.92.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "0.93.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cf583f7b093f291005f9fb1323e2c37f6ee4c7909e39ce016b2e8360d461705"
dependencies = [
"serde",
]
@@ -741,7 +749,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
"rand_core 0.6.3",
"subtle",
"zeroize",
@@ -753,7 +761,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
"typenum",
]
@@ -763,7 +771,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
"subtle",
]
@@ -773,7 +781,7 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
"subtle",
]
@@ -922,7 +930,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.5",
"generic-array 0.14.6",
]
[[package]]
@@ -1053,7 +1061,7 @@ dependencies = [
"der",
"digest 0.10.3",
"ff",
"generic-array 0.14.5",
"generic-array 0.14.6",
"group",
"pkcs8",
"rand_core 0.6.3",
@@ -1136,11 +1144,10 @@ dependencies = [
[[package]]
name = "eth-types"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"ethers-core",
"ethers-signers",
"halo2-mpt-circuits",
"halo2_proofs",
"hex",
"itertools",
@@ -1148,6 +1155,7 @@ dependencies = [
"libsecp256k1",
"num",
"num-bigint",
"poseidon-circuit",
"regex",
"serde",
"serde_json",
@@ -1212,7 +1220,7 @@ checksum = "6a89fb87a9e103f71b903b80b670200b54cc67a07578f070681f1fffb7396fb7"
dependencies = [
"bytes",
"ethereum-types 0.14.1",
"hash-db",
"hash-db 0.15.2",
"hash256-std-hasher",
"parity-scale-codec",
"rlp",
@@ -1265,7 +1273,7 @@ dependencies = [
"elliptic-curve",
"ethabi",
"fastrlp",
"generic-array 0.14.5",
"generic-array 0.14.6",
"hex",
"k256",
"proc-macro2",
@@ -1395,13 +1403,27 @@ dependencies = [
"sha3 0.10.1",
]
[[package]]
name = "expander"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f360349150728553f92e4c997a16af8915f418d3a0f21b440d34c5632f16ed84"
dependencies = [
"blake2",
"fs-err",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "external-tracer"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"eth-types",
"geth-utils",
"log",
"serde",
"serde_json",
]
@@ -1506,7 +1528,7 @@ dependencies = [
[[package]]
name = "fp-evm"
version = "3.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"evm",
"frame-support",
@@ -1531,9 +1553,10 @@ dependencies = [
[[package]]
name = "frame-support"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"bitflags",
"environmental",
"frame-metadata",
"frame-support-procedural",
"impl-trait-for-tuples",
@@ -1563,7 +1586,7 @@ dependencies = [
[[package]]
name = "frame-support-procedural"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"Inflector",
"cfg-expr",
@@ -1578,7 +1601,7 @@ dependencies = [
[[package]]
name = "frame-support-procedural-tools"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"frame-support-procedural-tools-derive",
"proc-macro-crate",
@@ -1590,13 +1613,19 @@ dependencies = [
[[package]]
name = "frame-support-procedural-tools-derive"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "fs-err"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
[[package]]
name = "funty"
version = "2.0.0"
@@ -1711,7 +1740,7 @@ dependencies = [
[[package]]
name = "gadgets"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"digest 0.7.6",
"eth-types",
@@ -1740,9 +1769,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.14.5"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
"typenum",
"version_check",
@@ -1751,7 +1780,7 @@ dependencies = [
[[package]]
name = "geth-utils"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"env_logger",
"gobuild",
@@ -1877,7 +1906,7 @@ dependencies = [
[[package]]
name = "halo2-mpt-circuits"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/mpt-circuit.git?branch=scroll-dev-0216#051b5efc54512d1422eba35338364473fe3a65c0"
source = "git+https://github.com/scroll-tech/mpt-circuit.git?branch=goerli-0215-dual-hash#ae8acdf37eafbbb5b6dffcb9e977dab465970c83"
dependencies = [
"halo2_proofs",
"hex",
@@ -1979,7 +2008,7 @@ dependencies = [
[[package]]
name = "halo2_proofs"
version = "0.2.0"
source = "git+https://github.com/scroll-tech/halo2.git?branch=scroll-dev-0220#49f4c58908095b46b4f0983404c12106b725df4e"
source = "git+https://github.com/scroll-tech/halo2.git?branch=scroll-dev-0220#5689a747c6acf9f7316b73dbe5ce4a1b3628c60c"
dependencies = [
"ark-std",
"blake2b_simd",
@@ -2050,6 +2079,12 @@ version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a"
[[package]]
name = "hash-db"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4"
[[package]]
name = "hash256-std-hasher"
version = "0.15.2"
@@ -2073,6 +2108,9 @@ name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash 0.8.3",
]
[[package]]
name = "hashers"
@@ -2140,7 +2178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
dependencies = [
"digest 0.9.0",
"generic-array 0.14.5",
"generic-array 0.14.6",
"hmac 0.8.1",
]
@@ -2437,7 +2475,7 @@ checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
[[package]]
name = "keccak256"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"env_logger",
"eth-types",
@@ -2613,12 +2651,11 @@ dependencies = [
[[package]]
name = "memory-db"
version = "0.31.0"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66"
checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe"
dependencies = [
"hash-db",
"hashbrown 0.12.3",
"hash-db 0.16.0",
]
[[package]]
@@ -2678,7 +2715,7 @@ dependencies = [
[[package]]
name = "mock"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"eth-types",
"ethers-core",
@@ -2693,13 +2730,12 @@ dependencies = [
[[package]]
name = "mpt-zktrie"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"bus-mapping",
"eth-types",
"halo2-mpt-circuits",
"halo2_proofs",
"hex",
"lazy_static",
"log",
"num-bigint",
@@ -2857,7 +2893,7 @@ checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "pallet-evm-precompile-blake2"
version = "2.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"fp-evm",
]
@@ -2865,7 +2901,7 @@ dependencies = [
[[package]]
name = "pallet-evm-precompile-bn128"
version = "2.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"fp-evm",
"sp-core",
@@ -2875,7 +2911,7 @@ dependencies = [
[[package]]
name = "pallet-evm-precompile-curve25519"
version = "1.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"curve25519-dalek 4.0.0-pre.1",
"fp-evm",
@@ -2884,7 +2920,7 @@ dependencies = [
[[package]]
name = "pallet-evm-precompile-modexp"
version = "2.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"fp-evm",
"num",
@@ -2893,7 +2929,7 @@ dependencies = [
[[package]]
name = "pallet-evm-precompile-simple"
version = "2.0.0-dev"
source = "git+https://github.com/paritytech/frontier?rev=73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca#73e6223e8bc26bf8e57cd9b212f1bc2fd288c5ca"
source = "git+https://github.com/paritytech/frontier?rev=76ad4c8f#76ad4c8fe970e15fafcdd931fa00d8af237ec513"
dependencies = [
"fp-evm",
"ripemd",
@@ -3216,7 +3252,7 @@ dependencies = [
[[package]]
name = "poseidon-circuit"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/poseidon-circuit.git?branch=scroll-dev-0215#1eea94a77a2252f2e8ca4eb5b98b66934b32623e"
source = "git+https://github.com/scroll-tech/poseidon-circuit.git?branch=scroll-dev-0215#b5e9b1440de088648a8661ccefbd28f7ebb3f252"
dependencies = [
"bitvec 1.0.1",
"halo2_proofs",
@@ -3515,11 +3551,11 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "reqwest"
version = "0.11.11"
version = "0.11.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92"
checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949"
dependencies = [
"base64 0.13.0",
"base64 0.21.0",
"bytes",
"encoding_rs",
"futures-core",
@@ -3531,9 +3567,9 @@ dependencies = [
"hyper-rustls",
"ipnet",
"js-sys",
"lazy_static",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls",
@@ -3818,7 +3854,7 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
dependencies = [
"base16ct",
"der",
"generic-array 0.14.5",
"generic-array 0.14.6",
"pkcs8",
"subtle",
"zeroize",
@@ -4109,9 +4145,9 @@ dependencies = [
[[package]]
name = "sp-api"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"hash-db",
"hash-db 0.16.0",
"log",
"parity-scale-codec",
"sp-api-proc-macro",
@@ -4127,9 +4163,11 @@ dependencies = [
[[package]]
name = "sp-api-proc-macro"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"Inflector",
"blake2",
"expander",
"proc-macro-crate",
"proc-macro2",
"quote",
@@ -4139,7 +4177,7 @@ dependencies = [
[[package]]
name = "sp-application-crypto"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -4152,7 +4190,7 @@ dependencies = [
[[package]]
name = "sp-arithmetic"
version = "6.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"integer-sqrt",
"num-traits",
@@ -4166,7 +4204,7 @@ dependencies = [
[[package]]
name = "sp-core"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"array-bytes",
"base58 0.2.0",
@@ -4176,7 +4214,7 @@ dependencies = [
"dyn-clonable",
"ed25519-zebra",
"futures",
"hash-db",
"hash-db 0.16.0",
"hash256-std-hasher",
"impl-serde 0.4.0",
"lazy_static",
@@ -4209,9 +4247,9 @@ dependencies = [
[[package]]
name = "sp-core-hashing"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"blake2",
"blake2b_simd",
"byteorder",
"digest 0.10.3",
"sha2 0.10.2",
@@ -4223,7 +4261,7 @@ dependencies = [
[[package]]
name = "sp-core-hashing-proc-macro"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"proc-macro2",
"quote",
@@ -4234,7 +4272,7 @@ dependencies = [
[[package]]
name = "sp-debug-derive"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"proc-macro2",
"quote",
@@ -4244,7 +4282,7 @@ dependencies = [
[[package]]
name = "sp-externalities"
version = "0.13.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"environmental",
"parity-scale-codec",
@@ -4255,7 +4293,7 @@ dependencies = [
[[package]]
name = "sp-inherents"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"async-trait",
"impl-trait-for-tuples",
@@ -4270,7 +4308,7 @@ dependencies = [
[[package]]
name = "sp-io"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"bytes",
"ed25519",
@@ -4295,9 +4333,8 @@ dependencies = [
[[package]]
name = "sp-keystore"
version = "0.13.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"async-trait",
"futures",
"merlin",
"parity-scale-codec",
@@ -4311,7 +4348,7 @@ dependencies = [
[[package]]
name = "sp-panic-handler"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"backtrace",
"lazy_static",
@@ -4321,7 +4358,7 @@ dependencies = [
[[package]]
name = "sp-runtime"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"either",
"hash256-std-hasher",
@@ -4343,7 +4380,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"bytes",
"impl-trait-for-tuples",
@@ -4361,7 +4398,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface-proc-macro"
version = "6.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"Inflector",
"proc-macro-crate",
@@ -4373,7 +4410,7 @@ dependencies = [
[[package]]
name = "sp-staking"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -4385,9 +4422,9 @@ dependencies = [
[[package]]
name = "sp-state-machine"
version = "0.13.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"hash-db",
"hash-db 0.16.0",
"log",
"parity-scale-codec",
"parking_lot 0.12.1",
@@ -4405,12 +4442,12 @@ dependencies = [
[[package]]
name = "sp-std"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
[[package]]
name = "sp-storage"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"impl-serde 0.4.0",
"parity-scale-codec",
@@ -4423,7 +4460,7 @@ dependencies = [
[[package]]
name = "sp-tracing"
version = "6.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"parity-scale-codec",
"sp-std",
@@ -4435,11 +4472,11 @@ dependencies = [
[[package]]
name = "sp-trie"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"ahash 0.8.3",
"hash-db",
"hashbrown 0.12.3",
"hash-db 0.16.0",
"hashbrown 0.13.2",
"lazy_static",
"memory-db",
"nohash-hasher",
@@ -4458,7 +4495,7 @@ dependencies = [
[[package]]
name = "sp-version"
version = "5.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"impl-serde 0.4.0",
"parity-scale-codec",
@@ -4475,7 +4512,7 @@ dependencies = [
[[package]]
name = "sp-version-proc-macro"
version = "4.0.0-dev"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"parity-scale-codec",
"proc-macro2",
@@ -4486,7 +4523,7 @@ dependencies = [
[[package]]
name = "sp-wasm-interface"
version = "7.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"anyhow",
"impl-trait-for-tuples",
@@ -4500,7 +4537,7 @@ dependencies = [
[[package]]
name = "sp-weights"
version = "4.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#d97a18851f9da0b1c299daa8fb18022794065779"
source = "git+https://github.com/paritytech/substrate?branch=master#8f0b0f69e79c0dcf1487b9858792439c35a1d4cd"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -4844,9 +4881,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.35"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if 1.0.0",
"pin-project-lite",
@@ -4856,9 +4893,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
version = "0.1.22"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
@@ -4930,12 +4967,12 @@ dependencies = [
[[package]]
name = "trie-db"
version = "0.24.0"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "004e1e8f92535694b4cb1444dc5a8073ecf0815e3357f729638b9f8fc4062908"
checksum = "634d75c77ea43f2ad8ea9d9c58de49dfc9c3995bdef32b503df7883ff054e7f1"
dependencies = [
"hash-db",
"hashbrown 0.12.3",
"hash-db 0.16.0",
"hashbrown 0.13.2",
"log",
"rustc-hex",
"smallvec",
@@ -4943,11 +4980,11 @@ dependencies = [
[[package]]
name = "trie-root"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a36c5ca3911ed3c9a5416ee6c679042064b93fc637ded67e25f92e68d783891"
checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b"
dependencies = [
"hash-db",
"hash-db 0.16.0",
]
[[package]]
@@ -4956,7 +4993,7 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1631b201eb031b563d2e85ca18ec8092508e262a3196ce9bd10a67ec87b9f5c"
dependencies = [
"hash-db",
"hash-db 0.15.2",
"rlp",
]
@@ -5001,7 +5038,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 1.0.0",
"digest 0.10.3",
"rand 0.8.5",
"rand 0.7.3",
"static_assertions",
]
@@ -5013,8 +5050,8 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "types"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/scroll-zkevm?branch=goerli-0215#1f7a3c7da2370860087555a11346bd5d96f609fd"
version = "0.3.0"
source = "git+https://github.com/scroll-tech/scroll-zkevm?rev=78ab7a7#78ab7a770f7753fa88c8aab4969296f06e1c811a"
dependencies = [
"base64 0.13.0",
"blake2",
@@ -5330,9 +5367,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.96.0"
version = "0.100.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adde01ade41ab9a5d10ec8ed0bb954238cf8625b5cd5a13093d6de2ad9c2be1a"
checksum = "64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4"
dependencies = [
"indexmap",
"url",
@@ -5340,8 +5377,9 @@ dependencies = [
[[package]]
name = "wasmtime"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6e89f9819523447330ffd70367ef4a18d8c832e24e8150fe054d1d912841632"
dependencies = [
"anyhow",
"bincode",
@@ -5364,16 +5402,18 @@ dependencies = [
[[package]]
name = "wasmtime-asm-macros"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd3a5e46c198032da934469f3a6e48649d1f9142438e4fd4617b68a35644b8a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "wasmtime-environ"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a6db9fc52985ba06ca601f2ff0ff1f526c5d724c7ac267b47326304b0c97883"
dependencies = [
"anyhow",
"cranelift-entity",
@@ -5390,8 +5430,9 @@ dependencies = [
[[package]]
name = "wasmtime-jit"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b77e3a52cd84d0f7f18554afa8060cfe564ccac61e3b0802d3fd4084772fa5f6"
dependencies = [
"addr2line 0.17.0",
"anyhow",
@@ -5412,16 +5453,18 @@ dependencies = [
[[package]]
name = "wasmtime-jit-debug"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0245e8a9347017c7185a72e215218a802ff561545c242953c11ba00fccc930f"
dependencies = [
"once_cell",
]
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67d412e9340ab1c83867051d8d1d7c90aa8c9afc91da086088068e2734e25064"
dependencies = [
"cfg-if 1.0.0",
"libc",
@@ -5430,8 +5473,9 @@ dependencies = [
[[package]]
name = "wasmtime-runtime"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d594e791b5fdd4dbaf8cf7ae62f2e4ff85018ce90f483ca6f42947688e48827d"
dependencies = [
"anyhow",
"cc",
@@ -5453,8 +5497,9 @@ dependencies = [
[[package]]
name = "wasmtime-types"
version = "5.0.0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6688d6f96d4dbc1f89fab626c56c1778936d122b5f4ae7a57c2eb42b8d982e2"
dependencies = [
"cranelift-entity",
"serde",
@@ -5681,8 +5726,8 @@ dependencies = [
[[package]]
name = "zkevm"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/scroll-zkevm?branch=goerli-0215#1f7a3c7da2370860087555a11346bd5d96f609fd"
version = "0.3.0"
source = "git+https://github.com/scroll-tech/scroll-zkevm?rev=78ab7a7#78ab7a770f7753fa88c8aab4969296f06e1c811a"
dependencies = [
"anyhow",
"blake2",
@@ -5719,7 +5764,7 @@ dependencies = [
[[package]]
name = "zkevm-circuits"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=goerli-0215#3395fe1abfb39000da19631af27508e33437295d"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=v0.3#c1c400436fd60b2e80e223e4c10cbff38d41e307"
dependencies = [
"array-init",
"bus-mapping",
@@ -5759,6 +5804,7 @@ name = "zkp"
version = "0.1.0"
dependencies = [
"env_logger",
"halo2_proofs",
"libc",
"log",
"once_cell",
@@ -5772,7 +5818,7 @@ dependencies = [
[[package]]
name = "zktrie"
version = "0.1.2"
source = "git+https://github.com/lispc/zktrie?branch=scroll-dev-0215#0bd8820fea4fea1ad10371ae9cae49622bd5413b"
source = "git+https://github.com/scroll-tech/zktrie.git?branch=scroll-dev-0226#1a5562f663a81ff903383db69dc6c9404b63e69d"
dependencies = [
"gobuild",
]

View File

@@ -11,12 +11,11 @@ crate-type = ["cdylib"]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-0220" }
[patch."https://github.com/privacy-scaling-explorations/poseidon.git"]
poseidon = { git = "https://github.com/scroll-tech/poseidon.git", branch = "scroll-dev-0220" }
[patch."https://github.com/scroll-tech/zktrie.git"]
zktrie = { git = "https://github.com/lispc/zktrie", branch = "scroll-dev-0215" }
[dependencies]
zkevm = { git = "https://github.com/scroll-tech/scroll-zkevm", branch="goerli-0215" }
types = { git = "https://github.com/scroll-tech/scroll-zkevm", branch="goerli-0215" }
zkevm = { git = "https://github.com/scroll-tech/scroll-zkevm", rev="78ab7a7" }
types = { git = "https://github.com/scroll-tech/scroll-zkevm", rev="78ab7a7" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2022_09_10" }
log = "0.4"
env_logger = "0.9.0"

View File

@@ -1,4 +1,5 @@
use crate::utils::{c_char_to_str, c_char_to_vec, vec_to_c_char};
use halo2_proofs::SerdeFormat;
use libc::c_char;
use std::cell::OnceCell;
use std::panic;
@@ -17,8 +18,8 @@ pub unsafe extern "C" fn init_prover(params_path: *const c_char, seed_path: *con
let params_path = c_char_to_str(params_path);
let seed_path = c_char_to_str(seed_path);
let params = load_params(params_path, *DEGREE).unwrap();
let agg_params = load_params(params_path, *AGG_DEGREE).unwrap();
let params = load_params(params_path, *DEGREE, SerdeFormat::RawBytesUnchecked).unwrap();
let agg_params = load_params(params_path, *AGG_DEGREE, SerdeFormat::RawBytesUnchecked).unwrap();
let seed = load_seed(seed_path).unwrap();
let p = Prover::from_params_and_seed(params, agg_params, seed);
PROVER.set(p).unwrap();

View File

@@ -1,4 +1,5 @@
use crate::utils::{c_char_to_str, c_char_to_vec};
use halo2_proofs::SerdeFormat;
use libc::c_char;
use std::fs::File;
use std::io::Read;
@@ -21,8 +22,8 @@ pub unsafe extern "C" fn init_verifier(params_path: *const c_char, agg_vk_path:
let mut agg_vk = vec![];
f.read_to_end(&mut agg_vk).unwrap();
let params = load_params(params_path, *DEGREE).unwrap();
let agg_params = load_params(params_path, *AGG_DEGREE).unwrap();
let params = load_params(params_path, *DEGREE, SerdeFormat::RawBytesUnchecked).unwrap();
let agg_params = load_params(params_path, *AGG_DEGREE, SerdeFormat::RawBytesUnchecked).unwrap();
let v = Box::new(Verifier::from_params(params, agg_params, Some(agg_vk)));
VERIFIER = Some(Box::leak(v))

View File

@@ -1,10 +1,12 @@
package types
import (
"encoding/json"
"math/big"
"os"
"testing"
"gotest.tools/assert"
"github.com/stretchr/testify/assert"
"github.com/scroll-tech/go-ethereum/common"
geth_types "github.com/scroll-tech/go-ethereum/core/types"
@@ -89,3 +91,53 @@ func TestNewGenesisBatch(t *testing.T) {
"wrong genesis batch hash",
)
}
func TestNewBatchData(t *testing.T) {
templateBlockTrace, err := os.ReadFile("../testdata/blockTrace_02.json")
assert.NoError(t, err)
wrappedBlock := &WrappedBlock{}
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock))
parentBatch := &BlockBatch{
Index: 1,
Hash: "0x0000000000000000000000000000000000000000",
StateRoot: "0x0000000000000000000000000000000000000000",
}
batchData1 := NewBatchData(parentBatch, []*WrappedBlock{wrappedBlock}, nil)
assert.NotNil(t, batchData1)
assert.NotNil(t, batchData1.Batch)
assert.Equal(t, "0xac4487c0d8f429dafda3c68cbb8983ac08af83c03c83c365d7df02864f80af37", batchData1.Hash().Hex())
templateBlockTrace, err = os.ReadFile("../testdata/blockTrace_03.json")
assert.NoError(t, err)
wrappedBlock2 := &WrappedBlock{}
assert.NoError(t, json.Unmarshal(templateBlockTrace, wrappedBlock2))
parentBatch2 := &BlockBatch{
Index: batchData1.Batch.BatchIndex,
Hash: batchData1.Hash().Hex(),
StateRoot: batchData1.Batch.NewStateRoot.Hex(),
}
batchData2 := NewBatchData(parentBatch2, []*WrappedBlock{wrappedBlock2}, nil)
assert.NotNil(t, batchData2)
assert.NotNil(t, batchData2.Batch)
assert.Equal(t, "0x8f1447573740b3e75b979879866b8ad02eecf88e1946275eb8cf14ab95876efc", batchData2.Hash().Hex())
}
func TestBatchDataTimestamp(t *testing.T) {
// Test case 1: when the batch data contains no blocks.
assert.Equal(t, uint64(0), (&BatchData{}).Timestamp())
// Test case 2: when the batch data contains blocks.
batchData := &BatchData{
Batch: abi.IScrollChainBatch{
Blocks: []abi.IScrollChainBlockContext{
{Timestamp: 123456789},
{Timestamp: 234567891},
},
},
}
assert.Equal(t, uint64(123456789), batchData.Timestamp())
}

92
common/types/db_test.go Normal file
View File

@@ -0,0 +1,92 @@
package types
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRollerProveStatus(t *testing.T) {
tests := []struct {
name string
s RollerProveStatus
want string
}{
{
"RollerAssigned",
RollerAssigned,
"RollerAssigned",
},
{
"RollerProofValid",
RollerProofValid,
"RollerProofValid",
},
{
"RollerProofInvalid",
RollerProofInvalid,
"RollerProofInvalid",
},
{
"Bad Value",
RollerProveStatus(999), // Invalid value.
"Bad Value: 999",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.s.String())
})
}
}
func TestProvingStatus(t *testing.T) {
tests := []struct {
name string
s ProvingStatus
want string
}{
{
"ProvingTaskUnassigned",
ProvingTaskUnassigned,
"unassigned",
},
{
"ProvingTaskSkipped",
ProvingTaskSkipped,
"skipped",
},
{
"ProvingTaskAssigned",
ProvingTaskAssigned,
"assigned",
},
{
"ProvingTaskProved",
ProvingTaskProved,
"proved",
},
{
"ProvingTaskVerified",
ProvingTaskVerified,
"verified",
},
{
"ProvingTaskFailed",
ProvingTaskFailed,
"failed",
},
{
"Undefined",
ProvingStatus(999), // Invalid value.
"undefined",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.s.String())
})
}
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/common/hexutil"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/rlp"
)
@@ -203,9 +202,9 @@ func (a *ProofMsg) PublicKey() (string, error) {
type TaskMsg struct {
ID string `json:"id"`
Type ProveType `json:"type,omitempty"`
// Only basic rollers need traces, aggregator rollers don't!
Traces []*types.BlockTrace `json:"blockTraces,omitempty"`
// Only aggregator rollers need proofs to aggregate, basic rollers don't!
// For decentralization, basic rollers will get block hashes from the coordinator. So that they can refer to the block hashes and fetch traces locally. Only applicable for basic rollers.
BlockHashes []common.Hash `json:"block_hashes,omitempty"`
// Only applicable for aggregator rollers.
SubProofs [][]byte `json:"sub_proofs,omitempty"`
}

View File

@@ -1,6 +1,7 @@
package message
import (
"encoding/hex"
"testing"
"time"
@@ -15,13 +16,15 @@ func TestAuthMessageSignAndVerify(t *testing.T) {
authMsg := &AuthMsg{
Identity: &Identity{
Name: "testRoller",
Name: "testName",
Timestamp: uint32(time.Now().Unix()),
Version: "testVersion",
Token: "testToken",
},
}
assert.NoError(t, authMsg.SignWithKey(privkey))
// check public key.
// Check public key.
pk, err := authMsg.PublicKey()
assert.NoError(t, err)
assert.Equal(t, common.Bytes2Hex(crypto.CompressPubkey(&privkey.PublicKey)), pk)
@@ -36,3 +39,120 @@ func TestAuthMessageSignAndVerify(t *testing.T) {
pubkey := crypto.CompressPubkey(&privkey.PublicKey)
assert.Equal(t, pub, common.Bytes2Hex(pubkey))
}
func TestGenerateToken(t *testing.T) {
token, err := GenerateToken()
assert.NoError(t, err)
assert.Equal(t, 32, len(token))
}
func TestIdentityHash(t *testing.T) {
identity := &Identity{
Name: "testName",
RollerType: BasicProve,
Timestamp: uint32(1622428800),
Version: "testVersion",
Token: "testToken",
}
hash, err := identity.Hash()
assert.NoError(t, err)
expectedHash := "b3f152958dc881446fc131a250526139d909710c6b91b4d3281ceded28ce2e32"
assert.Equal(t, expectedHash, hex.EncodeToString(hash))
}
func TestProofMessageSignVerifyPublicKey(t *testing.T) {
privkey, err := crypto.GenerateKey()
assert.NoError(t, err)
proofMsg := &ProofMsg{
ProofDetail: &ProofDetail{
ID: "testID",
Type: BasicProve,
Status: StatusOk,
Proof: &AggProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Vk: []byte("testVk"),
BlockCount: 1,
},
Error: "testError",
},
}
assert.NoError(t, proofMsg.Sign(privkey))
// Test when publicKey is not set.
ok, err := proofMsg.Verify()
assert.NoError(t, err)
assert.Equal(t, true, ok)
// Test when publicKey is already set.
ok, err = proofMsg.Verify()
assert.NoError(t, err)
assert.Equal(t, true, ok)
}
func TestProofDetailHash(t *testing.T) {
proofDetail := &ProofDetail{
ID: "testID",
Type: BasicProve,
Status: StatusOk,
Proof: &AggProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Vk: []byte("testVk"),
BlockCount: 1,
},
Error: "testError",
}
hash, err := proofDetail.Hash()
assert.NoError(t, err)
expectedHash := "fdfaae752d6fd72a7fdd2ad034ef504d3acda9e691a799323cfa6e371684ba2b"
assert.Equal(t, expectedHash, hex.EncodeToString(hash))
}
func TestProveTypeString(t *testing.T) {
basicProve := ProveType(0)
assert.Equal(t, "Basic Prove", basicProve.String())
aggregatorProve := ProveType(1)
assert.Equal(t, "Aggregator Prove", aggregatorProve.String())
illegalProve := ProveType(3)
assert.Equal(t, "Illegal Prove type", illegalProve.String())
}
func TestProofMsgPublicKey(t *testing.T) {
privkey, err := crypto.GenerateKey()
assert.NoError(t, err)
proofMsg := &ProofMsg{
ProofDetail: &ProofDetail{
ID: "testID",
Type: BasicProve,
Status: StatusOk,
Proof: &AggProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Vk: []byte("testVk"),
BlockCount: 1,
},
Error: "testError",
},
}
assert.NoError(t, proofMsg.Sign(privkey))
// Test when publicKey is not set.
pk, err := proofMsg.PublicKey()
assert.NoError(t, err)
assert.Equal(t, common.Bytes2Hex(crypto.CompressPubkey(&privkey.PublicKey)), pk)
// Test when publicKey is already set.
proofMsg.publicKey = common.Bytes2Hex(crypto.CompressPubkey(&privkey.PublicKey))
pk, err = proofMsg.PublicKey()
assert.NoError(t, err)
assert.Equal(t, common.Bytes2Hex(crypto.CompressPubkey(&privkey.PublicKey)), pk)
}

View File

@@ -22,14 +22,35 @@ func TestWorkerPool(t *testing.T) {
atomic.AddInt32(&cnt, -1)
}
go vwp.AddTask(task)
go vwp.AddTask(task)
go vwp.AddTask(task)
vwp.AddTask(task)
vwp.AddTask(task)
time.Sleep(600 * time.Millisecond)
as.Equal(int32(1), atomic.LoadInt32(&cnt))
vwp.AddTask(task)
vwp.Stop()
as.Equal(int32(0), atomic.LoadInt32(&cnt))
}
func TestWorkerPoolMaxWorkers(t *testing.T) {
as := assert.New(t)
vwp := workerpool.NewWorkerPool(2)
vwp.Run()
var cnt int32 = 3
task := func() {
time.Sleep(500 * time.Millisecond)
atomic.AddInt32(&cnt, -1)
}
time1 := time.Now()
vwp.AddTask(task)
vwp.AddTask(task)
vwp.AddTask(task)
vwp.Stop()
time2 := time.Now()
as.Greater(time2.Sub(time1), time.Second*1)
}

View File

@@ -5,15 +5,15 @@ import (
"runtime/debug"
)
var tag = "v3.0.15"
var tag = "v3.1.1"
var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
for _, setting := range info.Settings {
if setting.Key == "vcs.revision" {
value := setting.Value
if len(value) >= 8 {
return value[:8]
if len(value) >= 7 {
return value[:7]
}
return value
}

View File

@@ -13,6 +13,16 @@
"singleQuote": false,
"bracketSpacing": false
}
}
},
{
"files": "scripts/**/*.sol",
"options": {
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false
}
}
]
}

View File

@@ -1,5 +1,8 @@
# Scroll Contracts
Note: For more comprehensive documentation, see [`./docs/`](./docs).
## Directory Structure
```
@@ -21,7 +24,9 @@ remappings.txt - "foundry dependency mappings"
...
```
## Dependency
## Dependencies
### Foundry
@@ -37,12 +42,14 @@ Then, run `foundryup` in a new terminal session or after reloading your `PATH`.
Other ways to install Foundry can be found [here](https://github.com/foundry-rs/foundry#installation).
### Hardhat
```
yarn install
```
## Build
+ Run `git submodule update --init --recursive` to initialise git submodules.
@@ -53,6 +60,7 @@ yarn install
+ Run `forge test -vvv` to run foundry units tests. It will compile all contracts before running the unit tests.
+ Run `npx hardhat test` to run integration tests. It may not compile all contracts before running, it's better to run `npx hardhat compile` first.
## TODO
- [ ] unit tests

View File

@@ -215,10 +215,10 @@ function renounceOwnership() external nonpayable
### replayMessage
```solidity
function replayMessage(address _from, address _to, uint256 _value, uint256 _queueIndex, bytes _message, uint32 _oldGasLimit, uint32 _newGasLimit, address _refundAddress) external payable
function replayMessage(address _from, address _to, uint256 _value, uint256 _queueIndex, bytes _message, uint32 _newGasLimit, address _refundAddress) external payable
```
Replay an exsisting message.
Replay an existing message.
@@ -231,7 +231,6 @@ Replay an exsisting message.
| _value | uint256 | undefined |
| _queueIndex | uint256 | undefined |
| _message | bytes | undefined |
| _oldGasLimit | uint32 | undefined |
| _newGasLimit | uint32 | undefined |
| _refundAddress | address | undefined |
@@ -339,39 +338,6 @@ Update fee vault contract.
|---|---|---|
| _newFeeVault | address | The address of new fee vault contract. |
### updateWhitelist
```solidity
function updateWhitelist(address _newWhitelist) external nonpayable
```
Update whitelist contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newWhitelist | address | The address of new whitelist contract. |
### whitelist
```solidity
function whitelist() external view returns (address)
```
The whitelist contract to track the sender who can call `sendMessage` in ScrollMessenger.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### xDomainMessageSender
```solidity
@@ -512,22 +478,5 @@ Emitted when owner updates fee vault contract.
| _oldFeeVault | address | undefined |
| _newFeeVault | address | undefined |
### UpdateWhitelist
```solidity
event UpdateWhitelist(address _oldWhitelist, address _newWhitelist)
```
Emitted when owner updates whitelist contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldWhitelist | address | undefined |
| _newWhitelist | address | undefined |

View File

@@ -284,7 +284,7 @@ function retryMessageWithProof(address _from, address _to, uint256 _value, uint2
### sendMessage
```solidity
function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit, address _refundAddress) external payable
function sendMessage(address _to, uint256 _value, bytes _message, uint256 _gasLimit, address) external payable
```
Send cross chain message from L1 to L2 or L2 to L1.
@@ -299,7 +299,7 @@ Send cross chain message from L1 to L2 or L2 to L1.
| _value | uint256 | undefined |
| _message | bytes | undefined |
| _gasLimit | uint256 | undefined |
| _refundAddress | address | undefined |
| _4 | address | undefined |
### sendMessage
@@ -374,23 +374,7 @@ Update fee vault contract.
function updateMaxFailedExecutionTimes(uint256 _maxFailedExecutionTimes) external nonpayable
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| _maxFailedExecutionTimes | uint256 | undefined |
### updateWhitelist
```solidity
function updateWhitelist(address _newWhitelist) external nonpayable
```
Update whitelist contract.
Update max failed execution times.
*This function can only called by contract owner.*
@@ -398,7 +382,7 @@ Update whitelist contract.
| Name | Type | Description |
|---|---|---|
| _newWhitelist | address | The address of new whitelist contract. |
| _maxFailedExecutionTimes | uint256 | The new max failed execution times. |
### verifyMessageExecutionStatus
@@ -448,23 +432,6 @@ Check whether the l1 message is included in the corresponding L1 block.
|---|---|---|
| _0 | bool | bool Return true is the message is included in L1, otherwise return false. |
### whitelist
```solidity
function whitelist() external view returns (address)
```
The whitelist contract to track the sender who can call `sendMessage` in ScrollMessenger.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### xDomainMessageSender
```solidity
@@ -621,22 +588,5 @@ Emitted when the maximum number of times each message can fail in L2 is updated.
|---|---|---|
| maxFailedExecutionTimes | uint256 | The new maximum number of times each message can fail in L2. |
### UpdateWhitelist
```solidity
event UpdateWhitelist(address _oldWhitelist, address _newWhitelist)
```
Emitted when owner updates whitelist contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldWhitelist | address | undefined |
| _newWhitelist | address | undefined |

View File

@@ -26,4 +26,6 @@ gas_price = 0 # the gas price (i
block_base_fee_per_gas = 0 # the base fee (in wei) in tests
block_coinbase = '0x0000000000000000000000000000000000000000' # the address of `block.coinbase` in tests
block_timestamp = 0 # the value of `block.timestamp` in tests
block_difficulty = 0 # the value of `block.difficulty` in tests
block_difficulty = 0 # the value of `block.difficulty` in tests
gas_reports = ["L2GasPriceOracle"]

View File

@@ -0,0 +1,324 @@
/* eslint-disable node/no-unpublished-import */
/* eslint-disable node/no-missing-import */
import { expect } from "chai";
import { BigNumberish, BytesLike, constants, utils } from "ethers";
import { ethers } from "hardhat";
import { EnforcedTxGateway, L1MessageQueue, L2GasPriceOracle, MockCaller } from "../typechain";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
describe("EnforcedTxGateway.spec", async () => {
let deployer: SignerWithAddress;
let feeVault: SignerWithAddress;
let signer: SignerWithAddress;
let caller: MockCaller;
let gateway: EnforcedTxGateway;
let oracle: L2GasPriceOracle;
let queue: L1MessageQueue;
beforeEach(async () => {
[deployer, feeVault, signer] = await ethers.getSigners();
const L1MessageQueue = await ethers.getContractFactory("L1MessageQueue", deployer);
queue = await L1MessageQueue.deploy();
await queue.deployed();
const L2GasPriceOracle = await ethers.getContractFactory("L2GasPriceOracle", deployer);
oracle = await L2GasPriceOracle.deploy();
const EnforcedTxGateway = await ethers.getContractFactory("EnforcedTxGateway", deployer);
gateway = await EnforcedTxGateway.deploy();
await gateway.deployed();
const MockCaller = await ethers.getContractFactory("MockCaller", deployer);
caller = await MockCaller.deploy();
await caller.deployed();
await queue.initialize(constants.AddressZero, constants.AddressZero, gateway.address, oracle.address, 10000000);
await gateway.initialize(queue.address, feeVault.address);
await oracle.initialize(21000, 0, 8, 16);
const Whitelist = await ethers.getContractFactory("Whitelist", deployer);
const whitelist = await Whitelist.deploy(deployer.address);
await whitelist.deployed();
await whitelist.updateWhitelistStatus([deployer.address], true);
await oracle.updateWhitelist(whitelist.address);
await oracle.setL2BaseFee(1);
});
context("auth", async () => {
it("should initialize correctly", async () => {
expect(await gateway.owner()).to.eq(deployer.address);
expect(await gateway.messageQueue()).to.eq(queue.address);
expect(await gateway.feeVault()).to.eq(feeVault.address);
expect(await gateway.paused()).to.eq(false);
});
it("should revert, when initialize again", async () => {
await expect(gateway.initialize(constants.AddressZero, constants.AddressZero)).to.revertedWith(
"Initializable: contract is already initialized"
);
});
context("#updateFeeVault", async () => {
it("should revert, when non-owner call", async () => {
await expect(gateway.connect(signer).updateFeeVault(constants.AddressZero)).to.revertedWith(
"Ownable: caller is not the owner"
);
});
it("should succeed", async () => {
expect(await gateway.feeVault()).to.eq(feeVault.address);
await expect(gateway.updateFeeVault(deployer.address))
.to.emit(gateway, "UpdateFeeVault")
.withArgs(feeVault.address, deployer.address);
expect(await gateway.feeVault()).to.eq(deployer.address);
});
});
context("#setPaused", async () => {
it("should revert, when non-owner call", async () => {
await expect(gateway.connect(signer).setPaused(false)).to.revertedWith("Ownable: caller is not the owner");
});
it("should succeed", async () => {
expect(await gateway.paused()).to.eq(false);
await expect(gateway.setPaused(true)).to.emit(gateway, "Paused").withArgs(deployer.address);
expect(await gateway.paused()).to.eq(true);
await expect(gateway.setPaused(false)).to.emit(gateway, "Unpaused").withArgs(deployer.address);
expect(await gateway.paused()).to.eq(false);
});
});
});
context("#sendTransaction, by EOA", async () => {
it("should revert, when contract is paused", async () => {
await gateway.setPaused(true);
await expect(
gateway.connect(signer)["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 0, "0x")
).to.revertedWith("Pausable: paused");
});
it("should revert, when call is not EOA", async () => {
const tx = await gateway.populateTransaction["sendTransaction(address,uint256,uint256,bytes)"](
signer.address,
0,
0,
"0x"
);
await expect(caller.callTarget(gateway.address, tx.data!)).to.revertedWith(
"Only EOA senders are allowed to send enforced transaction"
);
});
it("should revert, when insufficient value for fee", async () => {
const fee = await queue.estimateCrossDomainMessageFee(1000000);
await expect(
gateway
.connect(signer)
["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee.sub(1) })
).to.revertedWith("Insufficient value for fee");
});
it("should revert, when failed to deduct the fee", async () => {
await gateway.updateFeeVault(gateway.address);
const fee = await queue.estimateCrossDomainMessageFee(1000000);
await expect(
gateway
.connect(signer)
["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee })
).to.revertedWith("Failed to deduct the fee");
});
it("should succeed, no refund", async () => {
const fee = await queue.estimateCrossDomainMessageFee(1000000);
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
await expect(
gateway
.connect(signer)
["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee })
)
.to.emit(queue, "QueueTransaction")
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
expect(feeVaultBalanceAfter.sub(feeVaultBalanceBefore)).to.eq(fee);
});
it("should succeed, with refund", async () => {
const fee = await queue.estimateCrossDomainMessageFee(1000000);
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
const signerBalanceBefore = await ethers.provider.getBalance(signer.address);
const tx = await gateway
.connect(signer)
["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee.add(100) });
await expect(tx)
.to.emit(queue, "QueueTransaction")
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
const receipt = await tx.wait();
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
const signerBalanceAfter = await ethers.provider.getBalance(signer.address);
expect(feeVaultBalanceAfter.sub(feeVaultBalanceBefore)).to.eq(fee);
expect(signerBalanceBefore.sub(signerBalanceAfter)).to.eq(
receipt.gasUsed.mul(receipt.effectiveGasPrice).add(fee)
);
});
});
context("#sendTransaction, with signatures", async () => {
const getSignature = async (
signer: SignerWithAddress,
target: string,
value: BigNumberish,
gasLimit: BigNumberish,
data: BytesLike
): Promise<string> => {
const queueIndex = await queue.nextCrossDomainMessageIndex();
const txHash = await queue.computeTransactionHash(signer.address, queueIndex, value, target, gasLimit, data);
return await signer.signMessage(utils.arrayify(txHash));
};
it("should revert, when contract is paused", async () => {
await gateway.setPaused(true);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
signer.address,
0,
0,
"0x",
"0x",
constants.AddressZero
)
).to.revertedWith("Pausable: paused");
});
it("should revert, when signature is wrong", async () => {
const signature = await signer.signMessage("0x00");
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
signer.address,
0,
0,
"0x",
signature,
constants.AddressZero
)
).to.revertedWith("Incorrect signature");
});
it("should revert, when insufficient value for fee", async () => {
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x");
const fee = await queue.estimateCrossDomainMessageFee(1000000);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
signer.address,
0,
1000000,
"0x",
signature,
signer.address,
{ value: fee.sub(1) }
)
).to.revertedWith("Insufficient value for fee");
});
it("should revert, when failed to deduct the fee", async () => {
await gateway.updateFeeVault(gateway.address);
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x");
const fee = await queue.estimateCrossDomainMessageFee(1000000);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
signer.address,
0,
1000000,
"0x",
signature,
signer.address,
{ value: fee }
)
).to.revertedWith("Failed to deduct the fee");
});
it("should succeed, no refund", async () => {
const signature = await getSignature(signer, deployer.address, 0, 1000000, "0x");
const fee = await queue.estimateCrossDomainMessageFee(1000000);
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
deployer.address,
0,
1000000,
"0x",
signature,
signer.address,
{ value: fee }
)
)
.to.emit(queue, "QueueTransaction")
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
expect(feeVaultBalanceAfter.sub(feeVaultBalanceBefore)).to.eq(fee);
});
it("should succeed, with refund", async () => {
const signature = await getSignature(signer, deployer.address, 0, 1000000, "0x");
const fee = await queue.estimateCrossDomainMessageFee(1000000);
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
const signerBalanceBefore = await ethers.provider.getBalance(signer.address);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
deployer.address,
0,
1000000,
"0x",
signature,
signer.address,
{ value: fee.add(100) }
)
)
.to.emit(queue, "QueueTransaction")
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
const signerBalanceAfter = await ethers.provider.getBalance(signer.address);
expect(feeVaultBalanceAfter.sub(feeVaultBalanceBefore)).to.eq(fee);
expect(signerBalanceAfter.sub(signerBalanceBefore)).to.eq(100);
});
it("should revert, when refund failed", async () => {
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x");
const fee = await queue.estimateCrossDomainMessageFee(1000000);
await expect(
gateway
.connect(deployer)
["sendTransaction(address,address,uint256,uint256,bytes,bytes,address)"](
signer.address,
signer.address,
0,
1000000,
"0x",
signature,
gateway.address,
{ value: fee.add(100) }
)
).to.revertedWith("Failed to refund the fee");
});
});
});

View File

@@ -2,37 +2,103 @@
/* eslint-disable node/no-missing-import */
import { expect } from "chai";
import { BigNumber, constants } from "ethers";
import { concat, hexlify, keccak256, randomBytes, RLP } from "ethers/lib/utils";
import { concat, getAddress, hexlify, keccak256, randomBytes, RLP } from "ethers/lib/utils";
import { ethers } from "hardhat";
import { L1MessageQueue } from "../typechain";
import { L1MessageQueue, L2GasPriceOracle } from "../typechain";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
describe("L1MessageQueue", async () => {
let deployer: SignerWithAddress;
let scrollChain: SignerWithAddress;
let messenger: SignerWithAddress;
let gateway: SignerWithAddress;
let signer: SignerWithAddress;
let oracle: L2GasPriceOracle;
let queue: L1MessageQueue;
beforeEach(async () => {
const [deployer] = await ethers.getSigners();
[deployer, scrollChain, messenger, gateway, signer] = await ethers.getSigners();
const L1MessageQueue = await ethers.getContractFactory("L1MessageQueue", deployer);
queue = await L1MessageQueue.deploy();
await queue.deployed();
await queue.initialize(constants.AddressZero, constants.AddressZero);
const L2GasPriceOracle = await ethers.getContractFactory("L2GasPriceOracle", deployer);
oracle = await L2GasPriceOracle.deploy();
await oracle.initialize(21000, 0, 8, 16);
await queue.initialize(messenger.address, scrollChain.address, gateway.address, oracle.address, 10000000);
});
it("should succeed", async () => {
const sender = hexlify(randomBytes(20));
const target = hexlify(randomBytes(20));
const transactionType = "0x7E";
context("auth", async () => {
it("should initialize correctly", async () => {
expect(await queue.owner()).to.eq(deployer.address);
expect(await queue.messenger()).to.eq(messenger.address);
expect(await queue.scrollChain()).to.eq(scrollChain.address);
expect(await queue.enforcedTxGateway()).to.eq(gateway.address);
expect(await queue.gasOracle()).to.eq(oracle.address);
expect(await queue.maxGasLimit()).to.eq(10000000);
});
for (const nonce of [
BigNumber.from(0),
BigNumber.from(1),
BigNumber.from(127),
BigNumber.from(128),
BigNumber.from(22334455),
constants.MaxUint256,
]) {
for (const value of [
it("should revert, when initialize again", async () => {
await expect(
queue.initialize(constants.AddressZero, constants.AddressZero, constants.AddressZero, constants.AddressZero, 0)
).to.revertedWith("Initializable: contract is already initialized");
});
context("#updateGasOracle", async () => {
it("should revert, when non-owner call", async () => {
await expect(queue.connect(signer).updateGasOracle(constants.AddressZero)).to.revertedWith(
"Ownable: caller is not the owner"
);
});
it("should succeed", async () => {
expect(await queue.gasOracle()).to.eq(oracle.address);
await expect(queue.updateGasOracle(deployer.address))
.to.emit(queue, "UpdateGasOracle")
.withArgs(oracle.address, deployer.address);
expect(await queue.gasOracle()).to.eq(deployer.address);
});
});
context("#updateEnforcedTxGateway", async () => {
it("should revert, when non-owner call", async () => {
await expect(queue.connect(signer).updateEnforcedTxGateway(constants.AddressZero)).to.revertedWith(
"Ownable: caller is not the owner"
);
});
it("should succeed", async () => {
expect(await queue.enforcedTxGateway()).to.eq(gateway.address);
await expect(queue.updateEnforcedTxGateway(deployer.address))
.to.emit(queue, "UpdateEnforcedTxGateway")
.withArgs(gateway.address, deployer.address);
expect(await queue.enforcedTxGateway()).to.eq(deployer.address);
});
});
context("#updateMaxGasLimit", async () => {
it("should revert, when non-owner call", async () => {
await expect(queue.connect(signer).updateMaxGasLimit(0)).to.revertedWith("Ownable: caller is not the owner");
});
it("should succeed", async () => {
expect(await queue.maxGasLimit()).to.eq(10000000);
await expect(queue.updateMaxGasLimit(0)).to.emit(queue, "UpdateMaxGasLimit").withArgs(10000000, 0);
expect(await queue.maxGasLimit()).to.eq(0);
});
});
});
context("#computeTransactionHash", async () => {
it("should succeed", async () => {
const sender = hexlify(randomBytes(20));
const target = hexlify(randomBytes(20));
const transactionType = "0x7E";
for (const nonce of [
BigNumber.from(0),
BigNumber.from(1),
BigNumber.from(127),
@@ -40,7 +106,7 @@ describe("L1MessageQueue", async () => {
BigNumber.from(22334455),
constants.MaxUint256,
]) {
for (const gasLimit of [
for (const value of [
BigNumber.from(0),
BigNumber.from(1),
BigNumber.from(127),
@@ -48,23 +114,164 @@ describe("L1MessageQueue", async () => {
BigNumber.from(22334455),
constants.MaxUint256,
]) {
for (const dataLen of [0, 1, 2, 3, 4, 55, 56, 100]) {
const data = randomBytes(dataLen);
const transactionPayload = RLP.encode([
nonce.toHexString(),
gasLimit.toHexString(),
target,
value.toHexString(),
data,
sender,
]);
const payload = concat([transactionType, transactionPayload]);
const expectedHash = keccak256(payload);
const computedHash = await queue.computeTransactionHash(sender, nonce, value, target, gasLimit, data);
expect(expectedHash).to.eq(computedHash);
for (const gasLimit of [
BigNumber.from(0),
BigNumber.from(1),
BigNumber.from(127),
BigNumber.from(128),
BigNumber.from(22334455),
constants.MaxUint256,
]) {
for (const dataLen of [0, 1, 2, 3, 4, 55, 56, 100]) {
const data = randomBytes(dataLen);
const transactionPayload = RLP.encode([
nonce.toHexString(),
gasLimit.toHexString(),
target,
value.toHexString(),
data,
sender,
]);
const payload = concat([transactionType, transactionPayload]);
const expectedHash = keccak256(payload);
const computedHash = await queue.computeTransactionHash(sender, nonce, value, target, gasLimit, data);
expect(expectedHash).to.eq(computedHash);
}
}
}
}
}
});
});
context("#appendCrossDomainMessage", async () => {
it("should revert, when non-messenger call", async () => {
await expect(queue.connect(signer).appendCrossDomainMessage(constants.AddressZero, 0, "0x")).to.revertedWith(
"Only callable by the L1ScrollMessenger"
);
});
it("should revert, when exceed maxGasLimit", async () => {
await expect(
queue.connect(messenger).appendCrossDomainMessage(constants.AddressZero, 10000001, "0x")
).to.revertedWith("Gas limit must not exceed maxGasLimit");
});
it("should revert, when below intrinsic gas", async () => {
await expect(queue.connect(messenger).appendCrossDomainMessage(constants.AddressZero, 0, "0x")).to.revertedWith(
"Insufficient gas limit, must be above intrinsic gas"
);
});
it("should succeed", async () => {
expect(await queue.nextCrossDomainMessageIndex()).to.eq(constants.Zero);
const sender = getAddress(
BigNumber.from(messenger.address)
.add("0x1111000000000000000000000000000000001111")
.mod(BigNumber.from(2).pow(160))
.toHexString()
.slice(2)
.padStart(40, "0")
);
const hash = await queue.computeTransactionHash(sender, 0, 0, signer.address, 100000, "0x01");
await expect(queue.connect(messenger).appendCrossDomainMessage(signer.address, 100000, "0x01"))
.to.emit(queue, "QueueTransaction")
.withArgs(sender, signer.address, 0, 0, 100000, "0x01");
expect(await queue.nextCrossDomainMessageIndex()).to.eq(constants.One);
expect(await queue.getCrossDomainMessage(0)).to.eq(hash);
});
});
context("#appendEnforcedTransaction", async () => {
it("should revert, when non-gateway call", async () => {
await expect(
queue.connect(signer).appendEnforcedTransaction(signer.address, constants.AddressZero, 0, 0, "0x")
).to.revertedWith("Only callable by the EnforcedTxGateway");
});
it("should revert, when sender is not EOA", async () => {
await expect(
queue.connect(gateway).appendEnforcedTransaction(queue.address, constants.AddressZero, 0, 0, "0x")
).to.revertedWith("only EOA");
});
it("should revert, when exceed maxGasLimit", async () => {
await expect(
queue.connect(gateway).appendEnforcedTransaction(signer.address, constants.AddressZero, 0, 10000001, "0x")
).to.revertedWith("Gas limit must not exceed maxGasLimit");
});
it("should revert, when below intrinsic gas", async () => {
await expect(
queue.connect(gateway).appendEnforcedTransaction(signer.address, constants.AddressZero, 0, 0, "0x")
).to.revertedWith("Insufficient gas limit, must be above intrinsic gas");
});
it("should succeed", async () => {
expect(await queue.nextCrossDomainMessageIndex()).to.eq(constants.Zero);
const sender = signer.address;
const hash = await queue.computeTransactionHash(sender, 0, 200, signer.address, 100000, "0x01");
await expect(
queue.connect(gateway).appendEnforcedTransaction(signer.address, signer.address, 200, 100000, "0x01")
)
.to.emit(queue, "QueueTransaction")
.withArgs(sender, signer.address, 200, 0, 100000, "0x01");
expect(await queue.nextCrossDomainMessageIndex()).to.eq(constants.One);
expect(await queue.getCrossDomainMessage(0)).to.eq(hash);
});
});
context("#popCrossDomainMessage", async () => {
it("should revert, when non-scrollChain call", async () => {
await expect(queue.connect(signer).popCrossDomainMessage(0, 0, 0)).to.revertedWith(
"Only callable by the ScrollChain"
);
});
it("should revert, when pop too many messages", async () => {
await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 257, 0)).to.revertedWith(
"pop too many messages"
);
});
it("should revert, when start index mismatch", async () => {
await expect(queue.connect(scrollChain).popCrossDomainMessage(1, 256, 0)).to.revertedWith("start index mismatch");
});
it("should succeed", async () => {
// append 100 messages
for (let i = 0; i < 100; i++) {
await queue.connect(messenger).appendCrossDomainMessage(constants.AddressZero, 1000000, "0x");
}
// pop 50 messages with no skip
await expect(queue.connect(scrollChain).popCrossDomainMessage(0, 50, 0))
.to.emit(queue, "DequeueTransaction")
.withArgs(0, 50, 0);
for (let i = 0; i < 50; i++) {
expect(await queue.getCrossDomainMessage(i)).to.eq(constants.HashZero);
}
expect(await queue.pendingQueueIndex()).to.eq(50);
// pop 10 messages all skip
await expect(queue.connect(scrollChain).popCrossDomainMessage(50, 10, 1023))
.to.emit(queue, "DequeueTransaction")
.withArgs(50, 10, 1023);
expect(await queue.pendingQueueIndex()).to.eq(60);
for (let i = 50; i < 60; i++) {
expect(BigNumber.from(await queue.getCrossDomainMessage(i))).to.gt(constants.Zero);
}
// pop 20 messages, skip first 5
await expect(queue.connect(scrollChain).popCrossDomainMessage(60, 20, 31))
.to.emit(queue, "DequeueTransaction")
.withArgs(60, 20, 31);
expect(await queue.pendingQueueIndex()).to.eq(80);
for (let i = 60; i < 65; i++) {
expect(BigNumber.from(await queue.getCrossDomainMessage(i))).to.gt(constants.Zero);
}
for (let i = 65; i < 80; i++) {
expect(await queue.getCrossDomainMessage(i)).to.eq(constants.HashZero);
}
});
});
});

View File

@@ -24,14 +24,22 @@ describe("ScrollChain", async () => {
signer: deployer,
libraries: { RollupVerifier: verifier.address },
});
chain = await ScrollChain.deploy(0, 25, "0xb5baa665b2664c3bfed7eb46e00ebc110ecf2ebd257854a9bf2b9dbc9b2c08f6");
chain = await ScrollChain.deploy(0);
await chain.deployed();
await chain.initialize(queue.address);
await chain.initialize(queue.address, constants.AddressZero, 44);
await chain.updateSequencer(deployer.address, true);
await queue.initialize(constants.AddressZero, constants.AddressZero);
await queue.initialize(
constants.AddressZero,
chain.address,
constants.AddressZero,
constants.AddressZero,
10000000
);
});
// @note skip this benchmark tests
/*
it("should succeed", async () => {
await chain.importGenesisBatch({
blocks: [
@@ -105,4 +113,5 @@ describe("ScrollChain", async () => {
}
}
});
*/
});

View File

@@ -1,207 +1,216 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import { Script } from "forge-std/Script.sol";
import { console } from "forge-std/console.sol";
import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import { L1CustomERC20Gateway } from "../../src/L1/gateways/L1CustomERC20Gateway.sol";
import { L1ERC1155Gateway } from "../../src/L1/gateways/L1ERC1155Gateway.sol";
import { L1ERC721Gateway } from "../../src/L1/gateways/L1ERC721Gateway.sol";
import { L1ETHGateway } from "../../src/L1/gateways/L1ETHGateway.sol";
import { L1GatewayRouter } from "../../src/L1/gateways/L1GatewayRouter.sol";
import { L1ScrollMessenger } from "../../src/L1/L1ScrollMessenger.sol";
import { L1StandardERC20Gateway } from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import { L1WETHGateway } from "../../src/L1/gateways/L1WETHGateway.sol";
import { RollupVerifier } from "../../src/libraries/verifier/RollupVerifier.sol";
import { L1MessageQueue } from "../../src/L1/rollup/L1MessageQueue.sol";
import { L2GasPriceOracle } from "../../src/L1/rollup/L2GasPriceOracle.sol";
import { ScrollChain } from "../../src/L1/rollup/ScrollChain.sol";
import { Whitelist } from "../../src/L2/predeploys/Whitelist.sol";
import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol";
import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol";
import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol";
import {L1ETHGateway} from "../../src/L1/gateways/L1ETHGateway.sol";
import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol";
import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol";
import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol";
import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol";
import {RollupVerifier} from "../../src/libraries/verifier/RollupVerifier.sol";
import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol";
import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol";
import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol";
import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol";
contract DeployL1BridgeContracts is Script {
uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY");
uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY");
uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2");
uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2");
uint256 MAX_TX_IN_ONE_BATCH = vm.envOr("MAX_TX_IN_ONE_BATCH", uint256(44));
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
bytes32 PADDING_TX_HASH =
vm.envOr("PADDING_TX_HASH", bytes32(0x0000000000000000000000000000000000000000000000000000000000000000));
ProxyAdmin proxyAdmin;
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
function run() external {
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
ProxyAdmin proxyAdmin;
// note: the RollupVerifier library is deployed implicitly
function run() external {
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
deployProxyAdmin();
deployL1Whitelist();
deployL1MessageQueue();
deployL2GasPriceOracle();
deployScrollChain();
deployL1ETHGateway();
deployL1WETHGateway();
deployL1StandardERC20Gateway();
deployL1GatewayRouter();
deployL1ScrollMessenger();
deployEnforcedTxGateway();
deployL1CustomERC20Gateway();
deployL1ERC721Gateway();
deployL1ERC1155Gateway();
// note: the RollupVerifier library is deployed implicitly
vm.stopBroadcast();
}
deployProxyAdmin();
deployL1Whitelist();
deployL1MessageQueue();
deployL2GasPriceOracle();
deployScrollChain();
deployL1ETHGateway();
deployL1WETHGateway();
deployL1StandardERC20Gateway();
deployL1GatewayRouter();
deployL1ScrollMessenger();
deployL1CustomERC20Gateway();
deployL1ERC721Gateway();
deployL1ERC1155Gateway();
function deployProxyAdmin() internal {
proxyAdmin = new ProxyAdmin();
vm.stopBroadcast();
}
logAddress("L1_PROXY_ADMIN_ADDR", address(proxyAdmin));
}
function deployProxyAdmin() internal {
proxyAdmin = new ProxyAdmin();
function deployL1Whitelist() internal {
address owner = vm.addr(L1_DEPLOYER_PRIVATE_KEY);
Whitelist whitelist = new Whitelist(owner);
logAddress("L1_PROXY_ADMIN_ADDR", address(proxyAdmin));
}
logAddress("L1_WHITELIST_ADDR", address(whitelist));
}
function deployL1Whitelist() internal {
address owner = vm.addr(L1_DEPLOYER_PRIVATE_KEY);
Whitelist whitelist = new Whitelist(owner);
function deployScrollChain() internal {
ScrollChain impl = new ScrollChain(CHAIN_ID_L2);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_WHITELIST_ADDR", address(whitelist));
}
logAddress("L1_ZK_ROLLUP_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ZK_ROLLUP_PROXY_ADDR", address(proxy));
}
function deployScrollChain() internal {
ScrollChain impl = new ScrollChain(CHAIN_ID_L2, MAX_TX_IN_ONE_BATCH, PADDING_TX_HASH);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1MessageQueue() internal {
L1MessageQueue impl = new L1MessageQueue();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_MESSAGE_QUEUE_PROXY_ADDR", address(proxy));
}
logAddress("L1_ZK_ROLLUP_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ZK_ROLLUP_PROXY_ADDR", address(proxy));
}
function deployL2GasPriceOracle() internal {
L2GasPriceOracle impl = new L2GasPriceOracle();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_GAS_PRICE_ORACLE_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR", address(proxy));
}
function deployL1MessageQueue() internal {
L1MessageQueue impl = new L1MessageQueue();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_MESSAGE_QUEUE_PROXY_ADDR", address(proxy));
}
function deployL1StandardERC20Gateway() internal {
L1StandardERC20Gateway impl = new L1StandardERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2GasPriceOracle() internal {
L2GasPriceOracle impl = new L2GasPriceOracle();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_GAS_PRICE_ORACLE_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR", address(proxy));
}
logAddress("L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1StandardERC20Gateway() internal {
L1StandardERC20Gateway impl = new L1StandardERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1ETHGateway() internal {
L1ETHGateway impl = new L1ETHGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ETH_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1ETHGateway() internal {
L1ETHGateway impl = new L1ETHGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1WETHGateway() internal {
L1WETHGateway impl = new L1WETHGateway(L1_WETH_ADDR, L2_WETH_ADDR);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ETH_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_WETH_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1WETHGateway() internal {
L1WETHGateway impl = new L1WETHGateway(L1_WETH_ADDR, L2_WETH_ADDR);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1GatewayRouter() internal {
L1GatewayRouter impl = new L1GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_WETH_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_GATEWAY_ROUTER_PROXY_ADDR", address(proxy));
}
function deployL1GatewayRouter() internal {
L1GatewayRouter impl = new L1GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1ScrollMessenger() internal {
L1ScrollMessenger impl = new L1ScrollMessenger();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_GATEWAY_ROUTER_PROXY_ADDR", address(proxy));
}
logAddress("L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_SCROLL_MESSENGER_PROXY_ADDR", address(proxy));
}
function deployL1ScrollMessenger() internal {
L1ScrollMessenger impl = new L1ScrollMessenger();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployEnforcedTxGateway() internal {
EnforcedTxGateway impl = new EnforcedTxGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_SCROLL_MESSENGER_PROXY_ADDR", address(proxy));
}
logAddress("ENFORCED_TX_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("ENFORCED_TX_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1CustomERC20Gateway() internal {
L1CustomERC20Gateway impl = new L1CustomERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1CustomERC20Gateway() internal {
L1CustomERC20Gateway impl = new L1CustomERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1ERC721Gateway() internal {
L1ERC721Gateway impl = new L1ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1ERC721Gateway() internal {
L1ERC721Gateway impl = new L1ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ERC721_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ERC721_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1ERC1155Gateway() internal {
L1ERC1155Gateway impl = new L1ERC1155Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL1ERC1155Gateway() internal {
L1ERC1155Gateway impl = new L1ERC1155Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ERC1155_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_ERC1155_GATEWAY_PROXY_ADDR", address(proxy));
}
function logAddress(string memory name, address addr) internal view {
console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr)))));
}
function logAddress(string memory name, address addr) internal view {
console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr)))));
}
}

View File

@@ -1,246 +1,246 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import { Script } from "forge-std/Script.sol";
import { console } from "forge-std/console.sol";
import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import { L2CustomERC20Gateway } from "../../src/L2/gateways/L2CustomERC20Gateway.sol";
import { L2ERC1155Gateway } from "../../src/L2/gateways/L2ERC1155Gateway.sol";
import { L2ERC721Gateway } from "../../src/L2/gateways/L2ERC721Gateway.sol";
import { L2ETHGateway } from "../../src/L2/gateways/L2ETHGateway.sol";
import { L2GatewayRouter } from "../../src/L2/gateways/L2GatewayRouter.sol";
import { L2ScrollMessenger } from "../../src/L2/L2ScrollMessenger.sol";
import { L2StandardERC20Gateway } from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import { L2WETHGateway } from "../../src/L2/gateways/L2WETHGateway.sol";
import { L1BlockContainer } from "../../src/L2/predeploys/L1BlockContainer.sol";
import { L1GasPriceOracle } from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import { L2MessageQueue } from "../../src/L2/predeploys/L2MessageQueue.sol";
import { L2TxFeeVault } from "../../src/L2/predeploys/L2TxFeeVault.sol";
import { Whitelist } from "../../src/L2/predeploys/Whitelist.sol";
import { ScrollStandardERC20 } from "../../src/libraries/token/ScrollStandardERC20.sol";
import { ScrollStandardERC20Factory } from "../../src/libraries/token/ScrollStandardERC20Factory.sol";
import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol";
import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol";
import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol";
import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol";
import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol";
import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol";
import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol";
import {L1BlockContainer} from "../../src/L2/predeploys/L1BlockContainer.sol";
import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol";
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol";
import {ScrollStandardERC20} from "../../src/libraries/token/ScrollStandardERC20.sol";
import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStandardERC20Factory.sol";
contract DeployL2BridgeContracts is Script {
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
address L1_TX_FEE_RECIPIENT_ADDR = vm.envAddress("L1_TX_FEE_RECIPIENT_ADDR");
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
address L1_TX_FEE_RECIPIENT_ADDR = vm.envAddress("L1_TX_FEE_RECIPIENT_ADDR");
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
L1GasPriceOracle oracle;
L1BlockContainer container;
L2MessageQueue queue;
ProxyAdmin proxyAdmin;
L1GasPriceOracle oracle;
L1BlockContainer container;
L2MessageQueue queue;
ProxyAdmin proxyAdmin;
// predeploy contracts
address L1_BLOCK_CONTAINER_PREDEPLOY_ADDR = vm.envOr("L1_BLOCK_CONTAINER_PREDEPLOY_ADDR", address(0));
address L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR = vm.envOr("L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR", address(0));
address L2_MESSAGE_QUEUE_PREDEPLOY_ADDR = vm.envOr("L2_MESSAGE_QUEUE_PREDEPLOY_ADDR", address(0));
address L2_TX_FEE_VAULT_PREDEPLOY_ADDR = vm.envOr("L2_TX_FEE_VAULT_PREDEPLOY_ADDR", address(0));
address L2_WHITELIST_PREDEPLOY_ADDR = vm.envOr("L2_WHITELIST_PREDEPLOY_ADDR", address(0));
// predeploy contracts
address L1_BLOCK_CONTAINER_PREDEPLOY_ADDR = vm.envOr("L1_BLOCK_CONTAINER_PREDEPLOY_ADDR", address(0));
address L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR = vm.envOr("L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR", address(0));
address L2_MESSAGE_QUEUE_PREDEPLOY_ADDR = vm.envOr("L2_MESSAGE_QUEUE_PREDEPLOY_ADDR", address(0));
address L2_TX_FEE_VAULT_PREDEPLOY_ADDR = vm.envOr("L2_TX_FEE_VAULT_PREDEPLOY_ADDR", address(0));
address L2_WHITELIST_PREDEPLOY_ADDR = vm.envOr("L2_WHITELIST_PREDEPLOY_ADDR", address(0));
function run() external {
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
function run() external {
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
// predeploys
deployL1GasPriceOracle();
deployL1BlockContainer();
deployL2MessageQueue();
deployTxFeeVault();
deployL2Whitelist();
// predeploys
deployL1GasPriceOracle();
deployL1BlockContainer();
deployL2MessageQueue();
deployTxFeeVault();
deployL2Whitelist();
// upgradable
deployProxyAdmin();
deployL2ScrollMessenger();
deployL2ETHGateway();
deployL2WETHGateway();
deployL2StandardERC20Gateway();
deployL2GatewayRouter();
deployScrollStandardERC20Factory();
deployL2CustomERC20Gateway();
deployL2ERC721Gateway();
deployL2ERC1155Gateway();
// upgradable
deployProxyAdmin();
deployL2ScrollMessenger();
deployL2ETHGateway();
deployL2WETHGateway();
deployL2StandardERC20Gateway();
deployL2GatewayRouter();
deployScrollStandardERC20Factory();
deployL2CustomERC20Gateway();
deployL2ERC721Gateway();
deployL2ERC1155Gateway();
vm.stopBroadcast();
}
function deployL1GasPriceOracle() internal {
if (L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR != address(0)) {
oracle = L1GasPriceOracle(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR);
logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR));
return;
vm.stopBroadcast();
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
oracle = new L1GasPriceOracle(owner);
function deployL1GasPriceOracle() internal {
if (L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR != address(0)) {
oracle = L1GasPriceOracle(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR);
logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(L1_GAS_PRICE_ORACLE_PREDEPLOY_ADDR));
return;
}
logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(oracle));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
oracle = new L1GasPriceOracle(owner);
function deployL1BlockContainer() internal {
if (L1_BLOCK_CONTAINER_PREDEPLOY_ADDR != address(0)) {
container = L1BlockContainer(L1_BLOCK_CONTAINER_PREDEPLOY_ADDR);
logAddress("L1_BLOCK_CONTAINER_ADDR", address(L1_BLOCK_CONTAINER_PREDEPLOY_ADDR));
return;
logAddress("L1_GAS_PRICE_ORACLE_ADDR", address(oracle));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
container = new L1BlockContainer(owner);
function deployL1BlockContainer() internal {
if (L1_BLOCK_CONTAINER_PREDEPLOY_ADDR != address(0)) {
container = L1BlockContainer(L1_BLOCK_CONTAINER_PREDEPLOY_ADDR);
logAddress("L1_BLOCK_CONTAINER_ADDR", address(L1_BLOCK_CONTAINER_PREDEPLOY_ADDR));
return;
}
logAddress("L1_BLOCK_CONTAINER_ADDR", address(container));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
container = new L1BlockContainer(owner);
function deployL2MessageQueue() internal {
if (L2_MESSAGE_QUEUE_PREDEPLOY_ADDR != address(0)) {
queue = L2MessageQueue(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR);
logAddress("L2_MESSAGE_QUEUE_ADDR", address(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR));
return;
logAddress("L1_BLOCK_CONTAINER_ADDR", address(container));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
queue = new L2MessageQueue(owner);
function deployL2MessageQueue() internal {
if (L2_MESSAGE_QUEUE_PREDEPLOY_ADDR != address(0)) {
queue = L2MessageQueue(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR);
logAddress("L2_MESSAGE_QUEUE_ADDR", address(L2_MESSAGE_QUEUE_PREDEPLOY_ADDR));
return;
}
logAddress("L2_MESSAGE_QUEUE_ADDR", address(queue));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
queue = new L2MessageQueue(owner);
function deployTxFeeVault() internal {
if (L2_TX_FEE_VAULT_PREDEPLOY_ADDR != address(0)) {
logAddress("L2_TX_FEE_VAULT_ADDR", address(L2_TX_FEE_VAULT_PREDEPLOY_ADDR));
return;
logAddress("L2_MESSAGE_QUEUE_ADDR", address(queue));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
L2TxFeeVault feeVault = new L2TxFeeVault(address(owner), L1_TX_FEE_RECIPIENT_ADDR);
function deployTxFeeVault() internal {
if (L2_TX_FEE_VAULT_PREDEPLOY_ADDR != address(0)) {
logAddress("L2_TX_FEE_VAULT_ADDR", address(L2_TX_FEE_VAULT_PREDEPLOY_ADDR));
return;
}
logAddress("L2_TX_FEE_VAULT_ADDR", address(feeVault));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
L2TxFeeVault feeVault = new L2TxFeeVault(address(owner), L1_TX_FEE_RECIPIENT_ADDR);
function deployL2Whitelist() internal {
if (L2_WHITELIST_PREDEPLOY_ADDR != address(0)) {
logAddress("L2_WHITELIST_ADDR", address(L2_WHITELIST_PREDEPLOY_ADDR));
return;
logAddress("L2_TX_FEE_VAULT_ADDR", address(feeVault));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
Whitelist whitelist = new Whitelist(owner);
function deployL2Whitelist() internal {
if (L2_WHITELIST_PREDEPLOY_ADDR != address(0)) {
logAddress("L2_WHITELIST_ADDR", address(L2_WHITELIST_PREDEPLOY_ADDR));
return;
}
logAddress("L2_WHITELIST_ADDR", address(whitelist));
}
address owner = vm.addr(L2_DEPLOYER_PRIVATE_KEY);
Whitelist whitelist = new Whitelist(owner);
function deployProxyAdmin() internal {
proxyAdmin = new ProxyAdmin();
logAddress("L2_WHITELIST_ADDR", address(whitelist));
}
logAddress("L2_PROXY_ADMIN_ADDR", address(proxyAdmin));
}
function deployProxyAdmin() internal {
proxyAdmin = new ProxyAdmin();
function deployL2ScrollMessenger() internal {
L2ScrollMessenger impl = new L2ScrollMessenger(address(container), address(oracle), address(queue));
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_PROXY_ADMIN_ADDR", address(proxyAdmin));
}
logAddress("L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_SCROLL_MESSENGER_PROXY_ADDR", address(proxy));
}
function deployL2ScrollMessenger() internal {
L2ScrollMessenger impl = new L2ScrollMessenger(address(container), address(oracle), address(queue));
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2StandardERC20Gateway() internal {
L2StandardERC20Gateway impl = new L2StandardERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_SCROLL_MESSENGER_PROXY_ADDR", address(proxy));
}
logAddress("L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2StandardERC20Gateway() internal {
L2StandardERC20Gateway impl = new L2StandardERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2ETHGateway() internal {
L2ETHGateway impl = new L2ETHGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L2_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ETH_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2ETHGateway() internal {
L2ETHGateway impl = new L2ETHGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2WETHGateway() internal {
L2WETHGateway impl = new L2WETHGateway(L2_WETH_ADDR, L1_WETH_ADDR);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_ETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ETH_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L2_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_WETH_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2WETHGateway() internal {
L2WETHGateway impl = new L2WETHGateway(L2_WETH_ADDR, L1_WETH_ADDR);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2GatewayRouter() internal {
L2GatewayRouter impl = new L2GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_WETH_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_WETH_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L2_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_GATEWAY_ROUTER_PROXY_ADDR", address(proxy));
}
function deployL2GatewayRouter() internal {
L2GatewayRouter impl = new L2GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployScrollStandardERC20Factory() internal {
ScrollStandardERC20 tokenImpl = new ScrollStandardERC20();
ScrollStandardERC20Factory scrollStandardERC20Factory = new ScrollStandardERC20Factory(address(tokenImpl));
logAddress("L2_GATEWAY_ROUTER_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_GATEWAY_ROUTER_PROXY_ADDR", address(proxy));
}
logAddress("L2_SCROLL_STANDARD_ERC20_ADDR", address(tokenImpl));
logAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR", address(scrollStandardERC20Factory));
}
function deployScrollStandardERC20Factory() internal {
ScrollStandardERC20 tokenImpl = new ScrollStandardERC20();
ScrollStandardERC20Factory scrollStandardERC20Factory = new ScrollStandardERC20Factory(address(tokenImpl));
function deployL2CustomERC20Gateway() internal {
L2CustomERC20Gateway impl = new L2CustomERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_SCROLL_STANDARD_ERC20_ADDR", address(tokenImpl));
logAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR", address(scrollStandardERC20Factory));
}
logAddress("L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2CustomERC20Gateway() internal {
L2CustomERC20Gateway impl = new L2CustomERC20Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2ERC721Gateway() internal {
L2ERC721Gateway impl = new L2ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ERC721_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2ERC721Gateway() internal {
L2ERC721Gateway impl = new L2ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function deployL2ERC1155Gateway() internal {
L2ERC1155Gateway impl = new L2ERC1155Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ERC721_GATEWAY_PROXY_ADDR", address(proxy));
}
logAddress("L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ERC1155_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2ERC1155Gateway() internal {
L2ERC1155Gateway impl = new L2ERC1155Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
function logAddress(string memory name, address addr) internal view {
console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr)))));
}
logAddress("L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_ERC1155_GATEWAY_PROXY_ADDR", address(proxy));
}
function logAddress(string memory name, address addr) internal view {
console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr)))));
}
}

View File

@@ -1,126 +1,138 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import { Script } from "forge-std/Script.sol";
import {Script} from "forge-std/Script.sol";
import { L1CustomERC20Gateway } from "../../src/L1/gateways/L1CustomERC20Gateway.sol";
import { L1ERC1155Gateway } from "../../src/L1/gateways/L1ERC1155Gateway.sol";
import { L1ERC721Gateway } from "../../src/L1/gateways/L1ERC721Gateway.sol";
import { L1ETHGateway } from "../../src/L1/gateways/L1ETHGateway.sol";
import { L1GatewayRouter } from "../../src/L1/gateways/L1GatewayRouter.sol";
import { L1ScrollMessenger } from "../../src/L1/L1ScrollMessenger.sol";
import { L1StandardERC20Gateway } from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import { L1WETHGateway } from "../../src/L1/gateways/L1WETHGateway.sol";
import { ScrollChain } from "../../src/L1/rollup/ScrollChain.sol";
import { L1MessageQueue } from "../../src/L1/rollup/L1MessageQueue.sol";
import { L2GasPriceOracle } from "../../src/L1/rollup/L2GasPriceOracle.sol";
import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol";
import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol";
import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol";
import {L1ETHGateway} from "../../src/L1/gateways/L1ETHGateway.sol";
import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol";
import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol";
import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol";
import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol";
import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol";
import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol";
import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol";
contract InitializeL1BridgeContracts is Script {
uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY");
uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY");
uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2");
address L1_ROLLUP_OPERATOR_ADDR = vm.envAddress("L1_ROLLUP_OPERATOR_ADDR");
uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2");
uint256 MAX_L2_TX_IN_CHUNK = vm.envOr("MAX_L2_TX_IN_CHUNK", uint256(44));
address L1_ROLLUP_OPERATOR_ADDR = vm.envAddress("L1_ROLLUP_OPERATOR_ADDR");
address L1_FEE_VAULT_ADDR = vm.envAddress("L1_FEE_VAULT_ADDR");
address L1_FEE_VAULT_ADDR = vm.envAddress("L1_FEE_VAULT_ADDR");
address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR");
address L1_ZK_ROLLUP_PROXY_ADDR = vm.envAddress("L1_ZK_ROLLUP_PROXY_ADDR");
address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR");
address L2_GAS_PRICE_ORACLE_PROXY_ADDR = vm.envAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR");
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR");
address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR");
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR");
address L1_ZK_ROLLUP_PROXY_ADDR = vm.envAddress("L1_ZK_ROLLUP_PROXY_ADDR");
address L1_ROLLUP_VERIFIER_ADDR = vm.envAddress("L1_ROLLUP_VERIFIER_ADDR");
address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR");
address L2_GAS_PRICE_ORACLE_PROXY_ADDR = vm.envAddress("L2_GAS_PRICE_ORACLE_PROXY_ADDR");
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR");
address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR");
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("ENFORCED_TX_GATEWAY_PROXY_ADDR");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR");
address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR");
address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
function run() external {
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
function run() external {
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
// initialize ScrollChain
ScrollChain(L1_ZK_ROLLUP_PROXY_ADDR).initialize(L1_MESSAGE_QUEUE_PROXY_ADDR);
ScrollChain(L1_ZK_ROLLUP_PROXY_ADDR).updateSequencer(L1_ROLLUP_OPERATOR_ADDR, true);
// initialize ScrollChain
ScrollChain(L1_ZK_ROLLUP_PROXY_ADDR).initialize(L1_MESSAGE_QUEUE_PROXY_ADDR, L1_ROLLUP_VERIFIER_ADDR, MAX_L2_TX_IN_CHUNK);
ScrollChain(L1_ZK_ROLLUP_PROXY_ADDR).updateSequencer(L1_ROLLUP_OPERATOR_ADDR, true);
// initialize L2GasPriceOracle
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize();
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
// initialize L2GasPriceOracle
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize(0, 0, 0, 0);
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
// initialize L1MessageQueue
L1MessageQueue(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_GAS_PRICE_ORACLE_PROXY_ADDR
);
// initialize L1MessageQueue
L1MessageQueue(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L1_ZK_ROLLUP_PROXY_ADDR,
ENFORCED_TX_GATEWAY_PROXY_ADDR,
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
10000000
);
// initialize L1ScrollMessenger
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L2_SCROLL_MESSENGER_PROXY_ADDR,
L1_FEE_VAULT_ADDR,
L1_ZK_ROLLUP_PROXY_ADDR,
L1_MESSAGE_QUEUE_PROXY_ADDR
);
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).updateWhitelist(L1_WHITELIST_ADDR);
// initialize L1ScrollMessenger
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L2_SCROLL_MESSENGER_PROXY_ADDR,
L1_FEE_VAULT_ADDR,
L1_ZK_ROLLUP_PROXY_ADDR,
L1_MESSAGE_QUEUE_PROXY_ADDR
);
// initialize L1GatewayRouter
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize(
L1_ETH_GATEWAY_PROXY_ADDR,
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
// initialize EnforcedTxGateway
EnforcedTxGateway(payable(ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize(
L2_SCROLL_MESSENGER_PROXY_ADDR,
L1_FEE_VAULT_ADDR
);
// initialize L1CustomERC20Gateway
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1GatewayRouter
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize(
L1_ETH_GATEWAY_PROXY_ADDR,
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
// initialize L1ERC1155Gateway
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L2_ERC1155_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1CustomERC20Gateway
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ERC721Gateway
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
L2_ERC721_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ERC1155Gateway
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L2_ERC1155_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ETHGateway
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ERC721Gateway
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
L2_ERC721_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1StandardERC20Gateway
L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
// initialize L1ETHGateway
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1WETHGateway
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
L2_WETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1StandardERC20Gateway
L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
vm.stopBroadcast();
}
// initialize L1WETHGateway
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
L2_WETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
vm.stopBroadcast();
}
}

View File

@@ -1,126 +1,125 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import { Script } from "forge-std/Script.sol";
import {Script} from "forge-std/Script.sol";
import { L2ScrollMessenger } from "../../src/L2/L2ScrollMessenger.sol";
import { L2CustomERC20Gateway } from "../../src/L2/gateways/L2CustomERC20Gateway.sol";
import { L2ERC1155Gateway } from "../../src/L2/gateways/L2ERC1155Gateway.sol";
import { L2ERC721Gateway } from "../../src/L2/gateways/L2ERC721Gateway.sol";
import { L2ETHGateway } from "../../src/L2/gateways/L2ETHGateway.sol";
import { L2GatewayRouter } from "../../src/L2/gateways/L2GatewayRouter.sol";
import { L2StandardERC20Gateway } from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import { L2WETHGateway } from "../../src/L2/gateways/L2WETHGateway.sol";
import { L2MessageQueue } from "../../src/L2/predeploys/L2MessageQueue.sol";
import { L2TxFeeVault } from "../../src/L2/predeploys/L2TxFeeVault.sol";
import { L1BlockContainer } from "../../src/L2/predeploys/L1BlockContainer.sol";
import { L1GasPriceOracle } from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import { Whitelist } from "../../src/L2/predeploys/Whitelist.sol";
import { ScrollStandardERC20Factory } from "../../src/libraries/token/ScrollStandardERC20Factory.sol";
import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol";
import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol";
import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol";
import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol";
import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol";
import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol";
import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol";
import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol";
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
import {L1BlockContainer} from "../../src/L2/predeploys/L1BlockContainer.sol";
import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol";
import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStandardERC20Factory.sol";
contract InitializeL2BridgeContracts is Script {
uint256 deployerPrivateKey = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
uint256 deployerPrivateKey = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR");
address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR");
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR");
address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR");
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L2_TX_FEE_VAULT_ADDR = vm.envAddress("L2_TX_FEE_VAULT_ADDR");
address L1_BLOCK_CONTAINER_ADDR = vm.envAddress("L1_BLOCK_CONTAINER_ADDR");
address L1_GAS_PRICE_ORACLE_ADDR = vm.envAddress("L1_GAS_PRICE_ORACLE_ADDR");
address L2_WHITELIST_ADDR = vm.envAddress("L2_WHITELIST_ADDR");
address L2_MESSAGE_QUEUE_ADDR = vm.envAddress("L2_MESSAGE_QUEUE_ADDR");
address L2_TX_FEE_VAULT_ADDR = vm.envAddress("L2_TX_FEE_VAULT_ADDR");
address L1_BLOCK_CONTAINER_ADDR = vm.envAddress("L1_BLOCK_CONTAINER_ADDR");
address L1_GAS_PRICE_ORACLE_ADDR = vm.envAddress("L1_GAS_PRICE_ORACLE_ADDR");
address L2_WHITELIST_ADDR = vm.envAddress("L2_WHITELIST_ADDR");
address L2_MESSAGE_QUEUE_ADDR = vm.envAddress("L2_MESSAGE_QUEUE_ADDR");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR");
address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR");
address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
function run() external {
vm.startBroadcast(deployerPrivateKey);
function run() external {
vm.startBroadcast(deployerPrivateKey);
// initialize L2MessageQueue
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).initialize();
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).updateMessenger(L2_SCROLL_MESSENGER_PROXY_ADDR);
// initialize L2MessageQueue
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).initialize();
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).updateMessenger(L2_SCROLL_MESSENGER_PROXY_ADDR);
// initialize L2TxFeeVault
L2TxFeeVault(payable(L2_TX_FEE_VAULT_ADDR)).updateMessenger(L2_SCROLL_MESSENGER_PROXY_ADDR);
// initialize L2TxFeeVault
L2TxFeeVault(payable(L2_TX_FEE_VAULT_ADDR)).updateMessenger(L2_SCROLL_MESSENGER_PROXY_ADDR);
// initialize L1BlockContainer
L1BlockContainer(L1_BLOCK_CONTAINER_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L1BlockContainer
L1BlockContainer(L1_BLOCK_CONTAINER_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L1GasPriceOracle
L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L1GasPriceOracle
L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L2ScrollMessenger
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_TX_FEE_VAULT_ADDR
);
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L2ScrollMessenger
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_TX_FEE_VAULT_ADDR
);
// initialize L2GatewayRouter
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
// initialize L2GatewayRouter
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
// initialize L2CustomERC20Gateway
L2CustomERC20Gateway(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2CustomERC20Gateway
L2CustomERC20Gateway(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC1155Gateway
L2ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L1_ERC1155_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC1155Gateway
L2ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L1_ERC1155_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC721Gateway
L2ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR).initialize(
L1_ERC721_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC721Gateway
L2ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR).initialize(
L1_ERC721_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ETHGateway
L2ETHGateway(L2_ETH_GATEWAY_PROXY_ADDR).initialize(
L1_ETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ETHGateway
L2ETHGateway(L2_ETH_GATEWAY_PROXY_ADDR).initialize(
L1_ETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2StandardERC20Gateway
L2StandardERC20Gateway(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
// initialize L2StandardERC20Gateway
L2StandardERC20Gateway(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
// initialize L2WETHGateway
L2WETHGateway(payable(L2_WETH_GATEWAY_PROXY_ADDR)).initialize(
L1_WETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2WETHGateway
L2WETHGateway(payable(L2_WETH_GATEWAY_PROXY_ADDR)).initialize(
L1_WETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize ScrollStandardERC20Factory
ScrollStandardERC20Factory(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR).transferOwnership(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
// initialize ScrollStandardERC20Factory
ScrollStandardERC20Factory(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR).transferOwnership(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
vm.stopBroadcast();
}
vm.stopBroadcast();
}
}

View File

@@ -18,7 +18,7 @@ async function main() {
const ScrollChain = await ethers.getContractAt("ScrollChain", addressFile.get("ScrollChain.proxy"), deployer);
if ((await ScrollChain.owner()) === constants.AddressZero) {
const tx = await ScrollChain.initialize(L1_MESSAGE_QUEUE);
const tx = await ScrollChain.initialize(L1_MESSAGE_QUEUE, constants.AddressZero);
console.log("initialize ScrollChain, hash:", tx.hash);
const receipt = await tx.wait();
console.log(`✅ Done, gas used: ${receipt.gasUsed}`);

View File

@@ -10,8 +10,8 @@ interface IL1ScrollMessenger is IScrollMessenger {
***********/
struct L2MessageProof {
// The hash of the batch where the message belongs to.
bytes32 batchHash;
// The index of the batch where the message belongs to.
uint256 batchIndex;
// Concatenation of merkle proof for withdraw merkle trie.
bytes merkleProof;
}
@@ -36,13 +36,12 @@ interface IL1ScrollMessenger is IScrollMessenger {
L2MessageProof memory proof
) external;
/// @notice Replay an exsisting message.
/// @notice Replay an existing message.
/// @param from The address of the sender of the message.
/// @param to The address of the recipient of the message.
/// @param value The msg.value passed to the message call.
/// @param queueIndex The queue index for the message to replay.
/// @param message The content of the message.
/// @param oldGasLimit Original gas limit used to send the message.
/// @param newGasLimit New gas limit to be used for this message.
/// @param refundAddress The address of account who will receive the refunded fee.
function replayMessage(
@@ -51,7 +50,6 @@ interface IL1ScrollMessenger is IScrollMessenger {
uint256 value,
uint256 queueIndex,
bytes memory message,
uint32 oldGasLimit,
uint32 newGasLimit,
address refundAddress
) external payable;

View File

@@ -125,7 +125,7 @@ contract L1ScrollMessenger is PausableUpgradeable, ScrollMessengerBase, IL1Scrol
uint256 _nonce,
bytes memory _message,
L2MessageProof memory _proof
) external override whenNotPaused onlyWhitelistedSender(msg.sender) {
) external override whenNotPaused {
require(
xDomainMessageSender == ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER,
"Message is already in execution"
@@ -136,15 +136,15 @@ contract L1ScrollMessenger is PausableUpgradeable, ScrollMessengerBase, IL1Scrol
{
address _rollup = rollup;
require(IScrollChain(_rollup).isBatchFinalized(_proof.batchHash), "Batch is not finalized");
bytes32 _messageRoot = IScrollChain(_rollup).getL2MessageRoot(_proof.batchHash);
require(IScrollChain(_rollup).isBatchFinalized(_proof.batchIndex), "Batch is not finalized");
bytes32 _messageRoot = IScrollChain(_rollup).withdrawRoots(_proof.batchIndex);
require(
WithdrawTrieVerifier.verifyMerkleProof(_messageRoot, _xDomainCalldataHash, _nonce, _proof.merkleProof),
"Invalid proof"
);
}
// @todo check more `_to` address to avoid attack.
// @note check more `_to` address to avoid attack in the future when we add more gateways.
require(_to != messageQueue, "Forbid to call message queue");
require(_to != address(this), "Forbid to call self");
@@ -174,7 +174,6 @@ contract L1ScrollMessenger is PausableUpgradeable, ScrollMessengerBase, IL1Scrol
uint256 _value,
uint256 _queueIndex,
bytes memory _message,
uint32 _oldGasLimit,
uint32 _newGasLimit,
address _refundAddress
) external payable override whenNotPaused {
@@ -185,22 +184,9 @@ contract L1ScrollMessenger is PausableUpgradeable, ScrollMessengerBase, IL1Scrol
address _messageQueue = messageQueue;
address _counterpart = counterpart;
bytes memory _xDomainCalldata = _encodeXDomainCalldata(_from, _to, _value, _queueIndex, _message);
bytes32 _xDomainCalldataHash = keccak256(_xDomainCalldata);
// compute the expected transaction hash
bytes32 _computedTransactionHash = IL1MessageQueue(_messageQueue).computeTransactionHash(
AddressAliasHelper.applyL1ToL2Alias(address(this)),
_queueIndex,
0,
_counterpart,
_oldGasLimit,
_xDomainCalldata
);
// check the provided message matching with enqueued one.
require(
_computedTransactionHash == IL1MessageQueue(_messageQueue).getCrossDomainMessage(_queueIndex),
"Provided message has not been enqueued"
);
require(isL1MessageSent[_xDomainCalldataHash], "Provided message has not been enqueued");
// compute and deduct the messaging fee to fee vault.
uint256 _fee = IL1MessageQueue(_messageQueue).estimateCrossDomainMessageFee(_newGasLimit);

View File

@@ -0,0 +1,168 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {IL1MessageQueue} from "../rollup/IL1MessageQueue.sol";
contract EnforcedTxGateway is OwnableUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable {
/**********
* Events *
**********/
/// @notice Emitted when owner updates fee vault contract.
/// @param _oldFeeVault The address of old fee vault contract.
/// @param _newFeeVault The address of new fee vault contract.
event UpdateFeeVault(address _oldFeeVault, address _newFeeVault);
/*************
* Variables *
*************/
/// @notice The address of L1MessageQueue contract.
address public messageQueue;
/// @notice The address of fee vault contract.
address public feeVault;
/***************
* Constructor *
***************/
function initialize(address _queue, address _feeVault) external initializer {
OwnableUpgradeable.__Ownable_init();
ReentrancyGuardUpgradeable.__ReentrancyGuard_init();
PausableUpgradeable.__Pausable_init();
messageQueue = _queue;
feeVault = _feeVault;
}
/*****************************
* Public Mutating Functions *
*****************************/
/// @notice Add an enforced transaction to L2.
/// @dev The caller should be EOA only.
/// @param _target The address of target contract to call in L2.
/// @param _value The value passed
/// @param _gasLimit The maximum gas should be used for this transaction in L2.
/// @param _data The calldata passed to target contract.
function sendTransaction(
address _target,
uint256 _value,
uint256 _gasLimit,
bytes calldata _data
) external payable whenNotPaused {
require(msg.sender == tx.origin, "Only EOA senders are allowed to send enforced transaction");
_sendTransaction(msg.sender, _target, _value, _gasLimit, _data, msg.sender);
}
/// @notice Add an enforced transaction to L2.
/// @dev The `_sender` should be EOA and match with the signature.
/// @param _sender The address of sender who will initiate this transaction in L2.
/// @param _target The address of target contract to call in L2.
/// @param _value The value passed
/// @param _gasLimit The maximum gas should be used for this transaction in L2.
/// @param _data The calldata passed to target contract.
/// @param _signature The signature for the transaction.
/// @param _refundAddress The address to refund exceeded fee.
function sendTransaction(
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes calldata _data,
bytes memory _signature,
address _refundAddress
) external payable whenNotPaused {
address _messageQueue = messageQueue;
uint256 _queueIndex = IL1MessageQueue(messageQueue).nextCrossDomainMessageIndex();
bytes32 _txHash = IL1MessageQueue(_messageQueue).computeTransactionHash(
_sender,
_queueIndex,
_value,
_target,
_gasLimit,
_data
);
bytes32 _signHash = ECDSAUpgradeable.toEthSignedMessageHash(_txHash);
address _signer = ECDSAUpgradeable.recover(_signHash, _signature);
// no need to check `_signer != address(0)`, since it is checked in `recover`.
require(_signer == _sender, "Incorrect signature");
_sendTransaction(_sender, _target, _value, _gasLimit, _data, _refundAddress);
}
/************************
* Restricted Functions *
************************/
/// @notice Update the address of fee vault.
/// @param _newFeeVault The address to update.
function updateFeeVault(address _newFeeVault) external onlyOwner {
address _oldFeeVault = feeVault;
feeVault = _newFeeVault;
emit UpdateFeeVault(_oldFeeVault, _newFeeVault);
}
/// @notice Pause or unpause this contract.
/// @param _status Pause this contract if it is true, otherwise unpause this contract.
function setPaused(bool _status) external onlyOwner {
if (_status) {
_pause();
} else {
_unpause();
}
}
/**********************
* Internal Functions *
**********************/
/// @dev Internal function to charge fee and add enforced transaction.
/// @param _sender The address of sender who will initiate this transaction in L2.
/// @param _target The address of target contract to call in L2.
/// @param _value The value passed
/// @param _gasLimit The maximum gas should be used for this transaction in L2.
/// @param _data The calldata passed to target contract.
/// @param _refundAddress The address to refund exceeded fee.
function _sendTransaction(
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes calldata _data,
address _refundAddress
) internal nonReentrant {
address _messageQueue = messageQueue;
// charge fee
uint256 _fee = IL1MessageQueue(_messageQueue).estimateCrossDomainMessageFee(_gasLimit);
require(msg.value >= _fee, "Insufficient value for fee");
if (_fee > 0) {
(bool _success, ) = feeVault.call{value: _fee}("");
require(_success, "Failed to deduct the fee");
}
// append transaction
IL1MessageQueue(messageQueue).appendEnforcedTransaction(_sender, _target, _value, _gasLimit, _data);
// refund fee to `_refundAddress`
unchecked {
uint256 _refund = msg.value - _fee;
if (_refund > 0) {
(bool _success, ) = _refundAddress.call{value: _refund}("");
require(_success, "Failed to refund the fee");
}
}
}
}

View File

@@ -77,8 +77,9 @@ contract L1CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L1ERC20G
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == 0, "nonzero msg.value");
require(_l2Token != address(0), "token address cannot be 0");
require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch");
// @note can possible trigger reentrant call to this contract or messenger,
@@ -98,7 +99,7 @@ contract L1CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L1ERC20G
/// @param _l1Token The address of ERC20 token in layer 1.
/// @param _l2Token The address of corresponding ERC20 token in layer 2.
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "map to zero address");
require(_l2Token != address(0), "token address cannot be 0");
tokenMapping[_l1Token] = _l2Token;

View File

@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {ERC1155HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {IL2ERC1155Gateway} from "../../L2/gateways/IL2ERC1155Gateway.sol";
import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol";
@@ -19,7 +19,6 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// NFT will be transfer to the recipient directly.
///
/// This will be changed if we have more specific scenarios.
// @todo Current implementation doesn't support calling from `L1GatewayRouter`.
contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC1155Gateway {
/**********
* Events *
@@ -46,6 +45,9 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
/// @param _messenger The address of L1ScrollMessenger.
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC1155HolderUpgradeable.__ERC1155Holder_init();
ERC1155ReceiverUpgradeable.__ERC1155Receiver_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
}
@@ -103,7 +105,8 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
address _to,
uint256 _tokenId,
uint256 _amount
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l2Token != address(0), "token address cannot be 0");
require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch");
IERC1155Upgradeable(_l1Token).safeTransferFrom(address(this), _to, _tokenId, _amount, "");
@@ -119,7 +122,8 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
address _to,
uint256[] calldata _tokenIds,
uint256[] calldata _amounts
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l2Token != address(0), "token address cannot be 0");
require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch");
IERC1155Upgradeable(_l1Token).safeBatchTransferFrom(address(this), _to, _tokenIds, _amounts, "");
@@ -135,7 +139,7 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
/// @param _l1Token The address of ERC1155 token in layer 1.
/// @param _l1Token The address of corresponding ERC1155 token in layer 2.
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "map to zero address");
require(_l2Token != address(0), "token address cannot be 0");
tokenMapping[_l1Token] = _l2Token;
@@ -162,7 +166,7 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
require(_amount > 0, "deposit zero amount");
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "token not supported");
require(_l2Token != address(0), "no corresponding l2 token");
// 1. transfer token to this contract
IERC1155Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _tokenId, _amount, "");
@@ -205,7 +209,7 @@ contract L1ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
}
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "token not supported");
require(_l2Token != address(0), "no corresponding l2 token");
// 1. transfer token to this contract
IERC1155Upgradeable(_token).safeBatchTransferFrom(msg.sender, address(this), _tokenIds, _amounts, "");

View File

@@ -19,7 +19,6 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// NFT will be transfer to the recipient directly.
///
/// This will be changed if we have more specific scenarios.
// @todo Current implementation doesn't support calling from `L1GatewayRouter`.
contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC721Gateway {
/**********
* Events *
@@ -46,6 +45,8 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
/// @param _messenger The address of L1ScrollMessenger.
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC721HolderUpgradeable.__ERC721Holder_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
}
@@ -98,7 +99,8 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
address _from,
address _to,
uint256 _tokenId
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l2Token != address(0), "token address cannot be 0");
require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch");
IERC721Upgradeable(_l1Token).safeTransferFrom(address(this), _to, _tokenId);
@@ -113,7 +115,8 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
address _from,
address _to,
uint256[] calldata _tokenIds
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l2Token != address(0), "token address cannot be 0");
require(_l2Token == tokenMapping[_l1Token], "l2 token mismatch");
for (uint256 i = 0; i < _tokenIds.length; i++) {
@@ -131,7 +134,7 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
/// @param _l1Token The address of ERC721 token in layer 1.
/// @param _l1Token The address of corresponding ERC721 token in layer 2.
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "map to zero address");
require(_l2Token != address(0), "token address cannot be 0");
tokenMapping[_l1Token] = _l2Token;
@@ -154,7 +157,7 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
uint256 _gasLimit
) internal nonReentrant {
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "token not supported");
require(_l2Token != address(0), "no corresponding l2 token");
// 1. transfer token to this contract
IERC721Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _tokenId);
@@ -189,7 +192,7 @@ contract L1ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
require(_tokenIds.length > 0, "no token to deposit");
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "token not supported");
require(_l2Token != address(0), "no corresponding l2 token");
// 1. transfer token to this contract
for (uint256 i = 0; i < _tokenIds.length; i++) {

View File

@@ -67,8 +67,10 @@ contract L1ETHGateway is Initializable, ScrollGatewayBase, IL1ETHGateway {
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
// @note can possible trigger reentrant call to this contract or messenger,
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == _amount, "msg.value mismatch");
// @note can possible trigger reentrant call to messenger,
// but it seems not a big problem.
// solhint-disable-next-line avoid-low-level-calls
(bool _success, ) = _to.call{value: _amount}("");

View File

@@ -31,8 +31,6 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
// solhint-disable-next-line var-name-mixedcase
mapping(address => address) public ERC20Gateway;
// @todo: add ERC721/ERC1155 Gateway mapping.
/***************
* Constructor *
***************/

View File

@@ -92,10 +92,12 @@ contract L1StandardERC20Gateway is Initializable, ScrollGatewayBase, L1ERC20Gate
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == 0, "nonzero msg.value");
require(_l2Token != address(0), "token address cannot be 0");
require(getL2ERC20Address(_l1Token) == _l2Token, "l2 token mismatch");
// @note can possible trigger reentrant call to this contract or messenger,
// @note can possible trigger reentrant call to messenger,
// but it seems not a big problem.
IERC20(_l1Token).safeTransfer(_to, _amount);

View File

@@ -82,7 +82,7 @@ contract L1WETHGateway is Initializable, ScrollGatewayBase, L1ERC20Gateway {
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(_l1Token == WETH, "l1 token not WETH");
require(_l2Token == l2WETH, "l2 token not WETH");
require(_amount == msg.value, "msg.value mismatch");

View File

@@ -9,7 +9,7 @@ interface IL1MessageQueue {
/// @notice Emitted when a new L1 => L2 transaction is appended to the queue.
/// @param sender The address of account who initiates the transaction.
/// @param target The address of account who will recieve the transaction.
/// @param target The address of account who will receive the transaction.
/// @param value The value passed with the transaction.
/// @param queueIndex The index of this transaction in the queue.
/// @param gasLimit Gas limit required to complete the message relay on L2.
@@ -23,10 +23,19 @@ interface IL1MessageQueue {
bytes data
);
/// @notice Emitted when some L1 => L2 transactions are included in L1.
/// @param startIndex The start index of messages popped.
/// @param count The number of messages popped.
/// @param skippedBitmap A bitmap indicates whether a message is skipped.
event DequeueTransaction(uint256 startIndex, uint256 count, uint256 skippedBitmap);
/*************************
* Public View Functions *
*************************/
/// @notice The start index of all pending inclusion messages.
function pendingQueueIndex() external view returns (uint256);
/// @notice Return the index of next appended message.
/// @dev Also the total number of appended messages.
function nextCrossDomainMessageIndex() external view returns (uint256);
@@ -39,6 +48,10 @@ interface IL1MessageQueue {
/// @param gasLimit Gas limit required to complete the message relay on L2.
function estimateCrossDomainMessageFee(uint256 gasLimit) external view returns (uint256);
/// @notice Return the amount of intrinsic gas fee should pay for cross domain message.
/// @param _calldata The calldata of L1-initiated transaction.
function calculateIntrinsicGasFee(bytes memory _calldata) external view returns (uint256);
/// @notice Return the hash of a L1 message.
/// @param sender The address of sender.
/// @param queueIndex The queue index of this message.
@@ -83,4 +96,18 @@ interface IL1MessageQueue {
uint256 gasLimit,
bytes calldata data
) external;
/// @notice Pop finalized messages from queue.
///
/// @dev We can pop at most 256 messages each time. And if the message is not skipped,
/// the corresponding entry will be cleared.
///
/// @param startIndex The start index to pop.
/// @param count The number of messages to pop.
/// @param skippedBitmap A bitmap indicates whether a message is skipped.
function popCrossDomainMessage(
uint256 startIndex,
uint256 count,
uint256 skippedBitmap
) external;
}

View File

@@ -6,4 +6,8 @@ interface IL2GasPriceOracle {
/// @notice Estimate fee for cross chain message call.
/// @param _gasLimit Gas limit required to complete the message relay on L2.
function estimateCrossDomainMessageFee(uint256 _gasLimit) external view returns (uint256);
/// @notice Estimate intrinsic gas fee for cross chain message call.
/// @param _message The message to be relayed on L2.
function calculateIntrinsicGasFee(bytes memory _message) external view returns (uint256);
}

View File

@@ -7,98 +7,74 @@ interface IScrollChain {
* Events *
**********/
/// @notice Emitted when a new batch is commited.
/// @param batchHash The hash of the batch
/// @notice Emitted when a new batch is committed.
/// @param batchHash The hash of the batch.
event CommitBatch(bytes32 indexed batchHash);
/// @notice Emitted when a batch is reverted.
/// @param batchHash The identification of the batch.
/// @notice revert a pending batch.
/// @param batchHash The hash of the batch
event RevertBatch(bytes32 indexed batchHash);
/// @notice Emitted when a batch is finalized.
/// @param batchHash The hash of the batch
event FinalizeBatch(bytes32 indexed batchHash);
/***********
* Structs *
***********/
struct BlockContext {
// The hash of this block.
bytes32 blockHash;
// The parent hash of this block.
bytes32 parentHash;
// The height of this block.
uint64 blockNumber;
// The timestamp of this block.
uint64 timestamp;
// The base fee of this block.
// Currently, it is not used, because we disable EIP-1559.
// We keep it for future proof.
uint256 baseFee;
// The gas limit of this block.
uint64 gasLimit;
// The number of transactions in this block, both L1 & L2 txs.
uint16 numTransactions;
// The number of l1 messages in this block.
uint16 numL1Messages;
}
struct Batch {
// The list of blocks in this batch
BlockContext[] blocks; // MAX_NUM_BLOCKS = 100, about 5 min
// The state root of previous batch.
// The first batch will use 0x0 for prevStateRoot
bytes32 prevStateRoot;
// The state root of the last block in this batch.
bytes32 newStateRoot;
// The withdraw trie root of the last block in this batch.
bytes32 withdrawTrieRoot;
// The index of the batch.
uint64 batchIndex;
// The parent batch hash.
bytes32 parentBatchHash;
// Concatenated raw data of RLP encoded L2 txs
bytes l2Transactions;
}
/// @param stateRoot The state root in layer 2 after this batch.
/// @param withdrawRoot The merkle root in layer2 after this batch.
event FinalizeBatch(bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot);
/*************************
* Public View Functions *
*************************/
/// @notice Return whether the batch is finalized by batch hash.
/// @param batchHash The hash of the batch to query.
function isBatchFinalized(bytes32 batchHash) external view returns (bool);
/// @notice Return the batch hash of a committed batch.
/// @param batchIndex The index of the batch.
function committedBatches(uint256 batchIndex) external view returns (bytes32);
/// @notice Return the merkle root of L2 message tree.
/// @param batchHash The hash of the batch to query.
function getL2MessageRoot(bytes32 batchHash) external view returns (bytes32);
/// @notice Return the state root of a committed batch.
/// @param batchIndex The index of the batch.
function finalizedStateRoots(uint256 batchIndex) external view returns (bytes32);
/// @notice Return the message root of a committed batch.
/// @param batchIndex The index of the batch.
function withdrawRoots(uint256 batchIndex) external view returns (bytes32);
/// @notice Return whether the batch is finalized by batch index.
/// @param batchIndex The index of the batch.
function isBatchFinalized(uint256 batchIndex) external view returns (bool);
/*****************************
* Public Mutating Functions *
*****************************/
/// @notice commit a batch in layer 1
/// @param batch The layer2 batch to commit.
function commitBatch(Batch memory batch) external;
/// @notice Commit a batch of transactions on layer 1.
///
/// @param version The version of current batch.
/// @param parentBatchHeader The header of parent batch, see the comments of `BatchHeaderV0Codec`.
/// @param chunks The list of encoded chunks, see the comments of `ChunkCodec`.
/// @param skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
function commitBatch(
uint8 version,
bytes calldata parentBatchHeader,
bytes[] memory chunks,
bytes calldata skippedL1MessageBitmap
) external;
/// @notice commit a list of batches in layer 1
/// @param batches The list of layer2 batches to commit.
function commitBatches(Batch[] memory batches) external;
/// @notice revert a pending batch.
/// @notice Revert a pending batch.
/// @dev one can only revert unfinalized batches.
/// @param batchId The identification of the batch.
function revertBatch(bytes32 batchId) external;
/// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch`.
/// @param count The number of subsequent batches to revert, including current batch.
function revertBatch(bytes calldata batchHeader, uint256 count) external;
/// @notice finalize commited batch in layer 1
/// @dev will add more parameters if needed.
/// @param batchId The identification of the commited batch.
/// @param proof The corresponding proof of the commited batch.
/// @param instances Instance used to verify, generated from batch.
/// @notice Finalize a committed batch on layer 1.
/// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch.
/// @param prevStateRoot The state root of parent batch.
/// @param postStateRoot The state root of current batch.
/// @param withdrawRoot The withdraw trie root of current batch.
/// @param aggrProof The aggregation proof for current batch.
function finalizeBatchWithProof(
bytes32 batchId,
uint256[] memory proof,
uint256[] memory instances
bytes calldata batchHeader,
bytes32 prevStateRoot,
bytes32 postStateRoot,
bytes32 withdrawRoot,
bytes calldata aggrProof
) external;
}

View File

@@ -22,6 +22,16 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
/// @param _newGasOracle The address of new gas oracle contract.
event UpdateGasOracle(address _oldGasOracle, address _newGasOracle);
/// @notice Emitted when owner updates EnforcedTxGateway contract.
/// @param _oldGateway The address of old EnforcedTxGateway contract.
/// @param _newGateway The address of new EnforcedTxGateway contract.
event UpdateEnforcedTxGateway(address _oldGateway, address _newGateway);
/// @notice Emitted when owner updates max gas limit.
/// @param _oldMaxGasLimit The old max gas limit.
/// @param _newMaxGasLimit The new max gas limit.
event UpdateMaxGasLimit(uint256 _oldMaxGasLimit, uint256 _newMaxGasLimit);
/*************
* Variables *
*************/
@@ -29,21 +39,42 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
/// @notice The address of L1ScrollMessenger contract.
address public messenger;
/// @notice The address of ScrollChain contract.
address public scrollChain;
/// @notice The address EnforcedTxGateway contract.
address public enforcedTxGateway;
/// @notice The address of GasOracle contract.
address public gasOracle;
/// @notice The list of queued cross domain messages.
bytes32[] public messageQueue;
/// @inheritdoc IL1MessageQueue
uint256 public pendingQueueIndex;
/// @notice The max gas limit of L1 transactions.
uint256 public maxGasLimit;
/***************
* Constructor *
***************/
function initialize(address _messenger, address _gasOracle) external initializer {
function initialize(
address _messenger,
address _scrollChain,
address _enforcedTxGateway,
address _gasOracle,
uint256 _maxGasLimit
) external initializer {
OwnableUpgradeable.__Ownable_init();
messenger = _messenger;
scrollChain = _scrollChain;
enforcedTxGateway = _enforcedTxGateway;
gasOracle = _gasOracle;
maxGasLimit = _maxGasLimit;
}
/*************************
@@ -67,6 +98,13 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
return IL2GasPriceOracle(_oracle).estimateCrossDomainMessageFee(_gasLimit);
}
/// @inheritdoc IL1MessageQueue
function calculateIntrinsicGasFee(bytes memory _calldata) public view override returns (uint256) {
address _oracle = gasOracle;
if (_oracle == address(0)) return 0;
return IL2GasPriceOracle(_oracle).calculateIntrinsicGasFee(_calldata);
}
/// @inheritdoc IL1MessageQueue
function computeTransactionHash(
address _sender,
@@ -204,26 +242,55 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
) external override {
require(msg.sender == messenger, "Only callable by the L1ScrollMessenger");
// validate gas limit
_validateGasLimit(_gasLimit, _data);
// do address alias to avoid replay attack in L2.
address _sender = AddressAliasHelper.applyL1ToL2Alias(msg.sender);
// compute transaction hash
uint256 _queueIndex = messageQueue.length;
bytes32 _hash = computeTransactionHash(_sender, _queueIndex, 0, _target, _gasLimit, _data);
messageQueue.push(_hash);
emit QueueTransaction(_sender, _target, 0, _queueIndex, _gasLimit, _data);
_queueTransaction(_sender, _target, 0, _gasLimit, _data);
}
/// @inheritdoc IL1MessageQueue
function appendEnforcedTransaction(
address,
address,
uint256,
uint256,
bytes calldata
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes calldata _data
) external override {
// @todo
require(msg.sender == enforcedTxGateway, "Only callable by the EnforcedTxGateway");
// We will check it in EnforcedTxGateway, just in case.
require(_sender.code.length == 0, "only EOA");
// validate gas limit
_validateGasLimit(_gasLimit, _data);
_queueTransaction(_sender, _target, _value, _gasLimit, _data);
}
/// @inheritdoc IL1MessageQueue
function popCrossDomainMessage(
uint256 _startIndex,
uint256 _count,
uint256 _skippedBitmap
) external {
require(msg.sender == scrollChain, "Only callable by the ScrollChain");
require(_count <= 256, "pop too many messages");
require(pendingQueueIndex == _startIndex, "start index mismatch");
unchecked {
for (uint256 i = 0; i < _count; i++) {
if ((_skippedBitmap >> i) & 1 == 0) {
messageQueue[_startIndex + i] = bytes32(0);
}
}
pendingQueueIndex = _startIndex + _count;
}
emit DequeueTransaction(_startIndex, _count, _skippedBitmap);
}
/************************
@@ -239,4 +306,57 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
emit UpdateGasOracle(_oldGasOracle, _newGasOracle);
}
/// @notice Update the address of EnforcedTxGateway.
/// @dev This function can only called by contract owner.
/// @param _newGateway The address to update.
function updateEnforcedTxGateway(address _newGateway) external onlyOwner {
address _oldGateway = enforcedTxGateway;
enforcedTxGateway = _newGateway;
emit UpdateEnforcedTxGateway(_oldGateway, _newGateway);
}
/// @notice Update the max gas limit.
/// @dev This function can only called by contract owner.
/// @param _newMaxGasLimit The new max gas limit.
function updateMaxGasLimit(uint256 _newMaxGasLimit) external onlyOwner {
uint256 _oldMaxGasLimit = maxGasLimit;
maxGasLimit = _newMaxGasLimit;
emit UpdateMaxGasLimit(_oldMaxGasLimit, _newMaxGasLimit);
}
/**********************
* Internal Functions *
**********************/
/// @dev Internal function to queue a L1 transaction.
/// @param _sender The address of sender who will initiate this transaction in L2.
/// @param _target The address of target contract to call in L2.
/// @param _value The value passed
/// @param _gasLimit The maximum gas should be used for this transaction in L2.
/// @param _data The calldata passed to target contract.
function _queueTransaction(
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes calldata _data
) internal {
// compute transaction hash
uint256 _queueIndex = messageQueue.length;
bytes32 _hash = computeTransactionHash(_sender, _queueIndex, _value, _target, _gasLimit, _data);
messageQueue.push(_hash);
// emit event
emit QueueTransaction(_sender, _target, _value, _queueIndex, _gasLimit, _data);
}
function _validateGasLimit(uint256 _gasLimit, bytes memory _calldata) internal view {
require(_gasLimit <= maxGasLimit, "Gas limit must not exceed maxGasLimit");
// check if the gas limit is above intrinsic gas
uint256 intrinsicGas = calculateIntrinsicGasFee(_calldata);
require(_gasLimit >= intrinsicGas, "Insufficient gas limit, must be above intrinsic gas");
}
}

View File

@@ -22,6 +22,13 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
/// @param l2BaseFee The current l2 base fee updated.
event L2BaseFeeUpdated(uint256 l2BaseFee);
/// @notice Emitted when intrinsic params are updated.
/// @param txGas The intrinsic gas for transaction.
/// @param txGasContractCreation The intrinsic gas for contract creation.
/// @param zeroGas The intrinsic gas for each zero byte.
/// @param nonZeroGas The intrinsic gas for each nonzero byte.
event IntrinsicParamsUpdated(uint256 txGas, uint256 txGasContractCreation, uint256 zeroGas, uint256 nonZeroGas);
/*************
* Variables *
*************/
@@ -32,18 +39,60 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
/// @notice The address of whitelist contract.
IWhitelist public whitelist;
struct IntrinsicParams {
uint64 txGas;
uint64 txGasContractCreation;
uint64 zeroGas;
uint64 nonZeroGas;
}
/// @notice The intrinsic params for transaction.
IntrinsicParams public intrinsicParams;
/***************
* Constructor *
***************/
function initialize() external initializer {
function initialize(
uint64 _txGas,
uint64 _txGasContractCreation,
uint64 _zeroGas,
uint64 _nonZeroGas
) external initializer {
OwnableUpgradeable.__Ownable_init();
intrinsicParams = IntrinsicParams({
txGas: _txGas,
txGasContractCreation: _txGasContractCreation,
zeroGas: _zeroGas,
nonZeroGas: _nonZeroGas
});
}
/*************************
* Public View Functions *
*************************/
/// @inheritdoc IL2GasPriceOracle
function calculateIntrinsicGasFee(bytes memory _message) external view override returns (uint256) {
// @note currently we don't support contract deployment via L1 messages.
uint256 _txGas = uint256(intrinsicParams.txGas);
uint256 _zeroGas = uint256(intrinsicParams.zeroGas);
uint256 _nonZeroGas = uint256(intrinsicParams.nonZeroGas);
uint256 gas = _txGas;
if (_message.length > 0) {
uint256 nz = 0;
for (uint256 i = 0; i < _message.length; i++) {
if (_message[i] != 0) {
nz++;
}
}
gas += nz * _nonZeroGas + (_message.length - nz) * _zeroGas;
}
return uint256(gas);
}
/// @inheritdoc IL2GasPriceOracle
function estimateCrossDomainMessageFee(uint256 _gasLimit) external view override returns (uint256) {
return _gasLimit * l2BaseFee;
@@ -53,6 +102,29 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
* Public Mutating Functions *
*****************************/
/// @notice Allows the owner to update parameters for intrinsic gas calculation.
/// @param _txGas The intrinsic gas for transaction.
/// @param _txGasContractCreation The intrinsic gas for contract creation.
/// @param _zeroGas The intrinsic gas for each zero byte.
/// @param _nonZeroGas The intrinsic gas for each nonzero byte.
function setIntrinsicParams(
uint64 _txGas,
uint64 _txGasContractCreation,
uint64 _zeroGas,
uint64 _nonZeroGas
) public {
require(whitelist.isSenderAllowed(msg.sender), "Not whitelisted sender");
intrinsicParams = IntrinsicParams({
txGas: _txGas,
txGasContractCreation: _txGasContractCreation,
zeroGas: _zeroGas,
nonZeroGas: _nonZeroGas
});
emit IntrinsicParamsUpdated(_txGas, _txGasContractCreation, _zeroGas, _nonZeroGas);
}
/// @notice Allows the owner to modify the l2 base fee.
/// @param _l2BaseFee The new l2 base fee.
function setL2BaseFee(uint256 _l2BaseFee) external {

View File

@@ -6,17 +6,14 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
import {IL1MessageQueue} from "./IL1MessageQueue.sol";
import {IScrollChain} from "./IScrollChain.sol";
import {RollupVerifier} from "../../libraries/verifier/RollupVerifier.sol";
import {BatchHeaderV0Codec} from "../../libraries/codec/BatchHeaderV0Codec.sol";
import {ChunkCodec} from "../../libraries/codec/ChunkCodec.sol";
import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol";
// solhint-disable reason-string
/// @title ScrollChain
/// @notice This contract maintains essential data for scroll rollup, including:
///
/// 1. a list of pending messages, which will be relayed to layer 2;
/// 2. the block tree generated by layer 2 and it's status.
///
/// @dev the message queue is not used yet, the offline relayer only use events in `L1ScrollMessenger`.
/// @notice This contract maintains data for the Scroll rollup.
contract ScrollChain is OwnableUpgradeable, IScrollChain {
/**********
* Events *
@@ -27,68 +24,57 @@ contract ScrollChain is OwnableUpgradeable, IScrollChain {
/// @param status The status of the account updated.
event UpdateSequencer(address indexed account, bool status);
/// @notice Emitted when the address of rollup verifier is updated.
/// @param oldVerifier The address of old rollup verifier.
/// @param newVerifier The address of new rollup verifier.
event UpdateVerifier(address oldVerifier, address newVerifier);
/// @notice Emitted when the value of `maxNumL2TxInChunk` is updated.
/// @param oldMaxNumL2TxInChunk The old value of `maxNumL2TxInChunk`.
/// @param newMaxNumL2TxInChunk The new value of `maxNumL2TxInChunk`.
event UpdateMaxNumL2TxInChunk(uint256 oldMaxNumL2TxInChunk, uint256 newMaxNumL2TxInChunk);
/*************
* Constants *
*************/
/// @dev The maximum number of transaction in on batch.
uint256 public immutable maxNumTxInBatch;
/// @dev The hash used for padding public inputs.
bytes32 public immutable paddingTxHash;
/// @notice The chain id of the corresponding layer 2 chain.
uint256 public immutable layer2ChainId;
/***********
* Structs *
***********/
// subject to change
struct BatchStored {
// The state root of the last block in this batch.
bytes32 newStateRoot;
// The withdraw trie root of the last block in this batch.
bytes32 withdrawTrieRoot;
// The parent batch hash.
bytes32 parentBatchHash;
// The index of the batch.
uint64 batchIndex;
// The timestamp of the last block in this batch.
uint64 timestamp;
// The number of transactions in this batch, both L1 & L2 txs.
uint64 numTransactions;
// The total number of L1 messages included after this batch.
uint64 totalL1Messages;
// Whether the batch is finalized.
bool finalized;
}
/*************
* Variables *
*************/
/// @notice The maximum number of transactions allowed in each chunk.
uint256 public maxNumL2TxInChunk;
/// @notice The address of L1MessageQueue.
address public messageQueue;
/// @notice The address of RollupVerifier.
address public verifier;
/// @notice Whether an account is a sequencer.
mapping(address => bool) public isSequencer;
/// @notice The latest finalized batch hash.
bytes32 public lastFinalizedBatchHash;
/// @notice The latest finalized batch index.
uint256 public lastFinalizedBatchIndex;
/// @notice Mapping from batch id to batch struct.
mapping(bytes32 => BatchStored) public batches;
/// @inheritdoc IScrollChain
mapping(uint256 => bytes32) public override committedBatches;
/// @notice Mapping from batch index to finalized batch hash.
mapping(uint256 => bytes32) public finalizedBatches;
/// @inheritdoc IScrollChain
mapping(uint256 => bytes32) public override finalizedStateRoots;
/// @inheritdoc IScrollChain
mapping(uint256 => bytes32) public override withdrawRoots;
/**********************
* Function Modifiers *
**********************/
modifier OnlySequencer() {
// @todo In the decentralize mode, it should be only called by a list of validator.
// @note In the decentralized mode, it should be only called by a list of validator.
require(isSequencer[msg.sender], "caller not sequencer");
_;
}
@@ -97,20 +83,23 @@ contract ScrollChain is OwnableUpgradeable, IScrollChain {
* Constructor *
***************/
constructor(
uint256 _chainId,
uint256 _maxNumTxInBatch,
bytes32 _paddingTxHash
) {
constructor(uint256 _chainId) {
layer2ChainId = _chainId;
maxNumTxInBatch = _maxNumTxInBatch;
paddingTxHash = _paddingTxHash;
}
function initialize(address _messageQueue) public initializer {
function initialize(
address _messageQueue,
address _verifier,
uint256 _maxNumL2TxInChunk
) public initializer {
OwnableUpgradeable.__Ownable_init();
messageQueue = _messageQueue;
verifier = _verifier;
maxNumL2TxInChunk = _maxNumL2TxInChunk;
emit UpdateVerifier(address(0), _verifier);
emit UpdateMaxNumL2TxInChunk(0, _maxNumL2TxInChunk);
}
/*************************
@@ -118,17 +107,8 @@ contract ScrollChain is OwnableUpgradeable, IScrollChain {
*************************/
/// @inheritdoc IScrollChain
function isBatchFinalized(bytes32 _batchHash) external view override returns (bool) {
BatchStored storage _batch = batches[_batchHash];
if (_batch.newStateRoot == bytes32(0)) {
return false;
}
return batches[lastFinalizedBatchHash].batchIndex >= _batch.batchIndex;
}
/// @inheritdoc IScrollChain
function getL2MessageRoot(bytes32 _batchHash) external view override returns (bytes32) {
return batches[_batchHash].withdrawTrieRoot;
function isBatchFinalized(uint256 _batchIndex) external view override returns (bool) {
return _batchIndex <= lastFinalizedBatchIndex;
}
/*****************************
@@ -136,80 +116,223 @@ contract ScrollChain is OwnableUpgradeable, IScrollChain {
*****************************/
/// @notice Import layer 2 genesis block
function importGenesisBatch(Batch memory _genesisBatch) external {
require(lastFinalizedBatchHash == bytes32(0), "Genesis batch imported");
require(_genesisBatch.blocks.length == 1, "Not exact one block in genesis");
require(_genesisBatch.prevStateRoot == bytes32(0), "Nonzero prevStateRoot");
/// @dev Although `_withdrawRoot` is always zero, we add this parameter for the convenience of unit testing.
function importGenesisBatch(
bytes calldata _batchHeader,
bytes32 _stateRoot,
bytes32 _withdrawRoot
) external {
// check genesis batch header length
require(_stateRoot != bytes32(0), "zero state root");
BlockContext memory _genesisBlock = _genesisBatch.blocks[0];
// check whether the genesis batch is imported
require(finalizedStateRoots[0] == bytes32(0), "Genesis batch imported");
require(_genesisBlock.blockHash != bytes32(0), "Block hash is zero");
require(_genesisBlock.blockNumber == 0, "Block is not genesis");
require(_genesisBlock.parentHash == bytes32(0), "Parent hash not empty");
(uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader);
bytes32 _batchHash = _commitBatch(_genesisBatch);
lastFinalizedBatchHash = _batchHash;
finalizedBatches[0] = _batchHash;
batches[_batchHash].finalized = true;
emit FinalizeBatch(_batchHash);
}
/// @inheritdoc IScrollChain
function commitBatch(Batch memory _batch) public override OnlySequencer {
_commitBatch(_batch);
}
/// @inheritdoc IScrollChain
function commitBatches(Batch[] memory _batches) public override OnlySequencer {
for (uint256 i = 0; i < _batches.length; i++) {
_commitBatch(_batches[i]);
// check all fields except `dataHash` and `lastBlockHash` are zero
unchecked {
uint256 sum = BatchHeaderV0Codec.version(memPtr) +
BatchHeaderV0Codec.batchIndex(memPtr) +
BatchHeaderV0Codec.l1MessagePopped(memPtr) +
BatchHeaderV0Codec.totalL1MessagePopped(memPtr);
require(sum == 0, "not all fields are zero");
}
require(BatchHeaderV0Codec.dataHash(memPtr) != bytes32(0), "zero data hash");
require(BatchHeaderV0Codec.parentBatchHash(memPtr) == bytes32(0), "nonzero parent batch hash");
committedBatches[0] = _batchHash;
finalizedStateRoots[0] = _stateRoot;
withdrawRoots[0] = _withdrawRoot;
emit CommitBatch(_batchHash);
emit FinalizeBatch(_batchHash, _stateRoot, _withdrawRoot);
}
/// @inheritdoc IScrollChain
function revertBatch(bytes32 _batchHash) external override OnlySequencer {
BatchStored storage _batch = batches[_batchHash];
function commitBatch(
uint8 _version,
bytes calldata _parentBatchHeader,
bytes[] memory _chunks,
bytes calldata _skippedL1MessageBitmap
) external override OnlySequencer {
require(_version == 0, "invalid version");
require(_batch.newStateRoot != bytes32(0), "No such batch");
require(!_batch.finalized, "Unable to revert finalized batch");
// check whether the batch is empty
uint256 _chunksLength = _chunks.length;
require(_chunksLength > 0, "batch is empty");
// delete committed batch
delete batches[_batchHash];
// The overall memory layout in this function is organized as follows
// +---------------------+-------------------+------------------+
// | parent batch header | chunk data hashes | new batch header |
// +---------------------+-------------------+------------------+
// ^ ^ ^
// batchPtr dataPtr newBatchPtr (re-use var batchPtr)
//
// 1. We copy the parent batch header from calldata to memory starting at batchPtr
// 2. We store `_chunksLength` number of Keccak hashes starting at `dataPtr`. Each Keccak
// hash corresponds to the data hash of a chunk. So we reserve the memory region from
// `dataPtr` to `dataPtr + _chunkLength * 32` for the chunk data hashes.
// 3. The memory starting at `newBatchPtr` is used to store the new batch header and compute
// the batch hash.
emit RevertBatch(_batchHash);
// the variable `batchPtr` will be reused later for the current batch
(uint256 batchPtr, bytes32 _parentBatchHash) = _loadBatchHeader(_parentBatchHeader);
uint256 _batchIndex = BatchHeaderV0Codec.batchIndex(batchPtr);
uint256 _totalL1MessagesPoppedOverall = BatchHeaderV0Codec.totalL1MessagePopped(batchPtr);
require(committedBatches[_batchIndex] == _parentBatchHash, "incorrect parent batch hash");
require(committedBatches[_batchIndex + 1] == 0, "batch already committed");
// load `dataPtr` and reserve the memory region for chunk data hashes
uint256 dataPtr;
assembly {
dataPtr := mload(0x40)
mstore(0x40, add(dataPtr, mul(_chunksLength, 32)))
}
// compute the data hash for each chunk
uint256 _totalL1MessagesPoppedInBatch;
for (uint256 i = 0; i < _chunksLength; i++) {
uint256 _totalNumL1MessagesInChunk = _commitChunk(
dataPtr,
_chunks[i],
_totalL1MessagesPoppedInBatch,
_totalL1MessagesPoppedOverall,
_skippedL1MessageBitmap
);
unchecked {
_totalL1MessagesPoppedInBatch += _totalNumL1MessagesInChunk;
_totalL1MessagesPoppedOverall += _totalNumL1MessagesInChunk;
dataPtr += 32;
}
}
// check the length of bitmap
unchecked {
require(
((_totalL1MessagesPoppedInBatch + 255) / 256) * 32 == _skippedL1MessageBitmap.length,
"wrong bitmap length"
);
}
// compute the data hash for current batch
bytes32 _dataHash;
assembly {
let dataLen := mul(_chunksLength, 0x20)
_dataHash := keccak256(sub(dataPtr, dataLen), dataLen)
batchPtr := mload(0x40) // reset batchPtr
_batchIndex := add(_batchIndex, 1) // increase batch index
}
// store entries, the order matters
BatchHeaderV0Codec.storeVersion(batchPtr, _version);
BatchHeaderV0Codec.storeBatchIndex(batchPtr, _batchIndex);
BatchHeaderV0Codec.storeL1MessagePopped(batchPtr, _totalL1MessagesPoppedInBatch);
BatchHeaderV0Codec.storeTotalL1MessagePopped(batchPtr, _totalL1MessagesPoppedOverall);
BatchHeaderV0Codec.storeDataHash(batchPtr, _dataHash);
BatchHeaderV0Codec.storeParentBatchHash(batchPtr, _parentBatchHash);
BatchHeaderV0Codec.storeSkippedBitmap(batchPtr, _skippedL1MessageBitmap);
// compute batch hash
bytes32 _batchHash = BatchHeaderV0Codec.computeBatchHash(batchPtr, 89 + _skippedL1MessageBitmap.length);
committedBatches[_batchIndex] = _batchHash;
emit CommitBatch(_batchHash);
}
/// @inheritdoc IScrollChain
function revertBatch(bytes calldata _batchHeader, uint256 _count) external onlyOwner {
require(_count > 0, "count must be nonzero");
(uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader);
// check batch hash
uint256 _batchIndex = BatchHeaderV0Codec.batchIndex(memPtr);
require(committedBatches[_batchIndex] == _batchHash, "incorrect batch hash");
// check finalization
require(_batchIndex > lastFinalizedBatchIndex, "can only revert unfinalized batch");
while (_count > 0) {
committedBatches[_batchIndex] = bytes32(0);
unchecked {
_batchIndex += 1;
_count -= 1;
}
emit RevertBatch(_batchHash);
_batchHash = committedBatches[_batchIndex];
if (_batchHash == bytes32(0)) break;
}
}
/// @inheritdoc IScrollChain
function finalizeBatchWithProof(
bytes32 _batchHash,
uint256[] memory _proof,
uint256[] memory _instances
bytes calldata _batchHeader,
bytes32 _prevStateRoot,
bytes32 _postStateRoot,
bytes32 _withdrawRoot,
bytes calldata _aggrProof
) external override OnlySequencer {
BatchStored storage _batch = batches[_batchHash];
require(_batch.newStateRoot != bytes32(0), "No such batch");
require(!_batch.finalized, "Batch is already finalized");
require(_prevStateRoot != bytes32(0), "previous state root is zero");
require(_postStateRoot != bytes32(0), "new state root is zero");
// @note skip parent check for now, since we may not prove blocks in order.
// bytes32 _parentHash = _block.header.parentHash;
// require(lastFinalizedBlockHash == _parentHash, "parent not latest finalized");
// this check below is not needed, just incase
// require(blocks[_parentHash].verified, "parent not verified");
// compute batch hash and verify
(uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader);
// @todo add verification logic
RollupVerifier.verify(_proof, _instances);
bytes32 _dataHash = BatchHeaderV0Codec.dataHash(memPtr);
uint256 _batchIndex = BatchHeaderV0Codec.batchIndex(memPtr);
require(committedBatches[_batchIndex] == _batchHash, "incorrect batch hash");
uint256 _batchIndex = _batch.batchIndex;
finalizedBatches[_batchIndex] = _batchHash;
_batch.finalized = true;
// verify previous state root.
require(finalizedStateRoots[_batchIndex - 1] == _prevStateRoot, "incorrect previous state root");
BatchStored storage _finalizedBatch = batches[lastFinalizedBatchHash];
if (_batchIndex > _finalizedBatch.batchIndex) {
lastFinalizedBatchHash = _batchHash;
// avoid duplicated verification
require(finalizedStateRoots[_batchIndex] == bytes32(0), "batch already verified");
// compute public input hash
bytes32 _publicInputHash = keccak256(abi.encode(_prevStateRoot, _postStateRoot, _withdrawRoot, _dataHash));
// verify batch
IRollupVerifier(verifier).verifyAggregateProof(_aggrProof, _publicInputHash);
// check and update lastFinalizedBatchIndex
unchecked {
require(lastFinalizedBatchIndex + 1 == _batchIndex, "incorrect batch index");
lastFinalizedBatchIndex = _batchIndex;
}
emit FinalizeBatch(_batchHash);
// record state root and withdraw root
finalizedStateRoots[_batchIndex] = _postStateRoot;
withdrawRoots[_batchIndex] = _withdrawRoot;
// Pop finalized and non-skipped message from L1MessageQueue.
uint256 _l1MessagePopped = BatchHeaderV0Codec.l1MessagePopped(memPtr);
if (_l1MessagePopped > 0) {
IL1MessageQueue _queue = IL1MessageQueue(messageQueue);
unchecked {
uint256 _startIndex = BatchHeaderV0Codec.totalL1MessagePopped(memPtr) - _l1MessagePopped;
for (uint256 i = 0; i < _l1MessagePopped; i += 256) {
uint256 _count = 256;
if (_l1MessagePopped - i < _count) {
_count = _l1MessagePopped - i;
}
uint256 _skippedBitmap = BatchHeaderV0Codec.skippedBitmap(memPtr, i / 256);
_queue.popCrossDomainMessage(_startIndex, _count, _skippedBitmap);
_startIndex += 256;
}
}
}
emit FinalizeBatch(_batchHash, _postStateRoot, _withdrawRoot);
}
/************************
@@ -226,197 +349,173 @@ contract ScrollChain is OwnableUpgradeable, IScrollChain {
emit UpdateSequencer(_account, _status);
}
/// @notice Update the address verifier contract.
/// @param _newVerifier The address of new verifier contract.
function updateVerifier(address _newVerifier) external onlyOwner {
address _oldVerifier = verifier;
verifier = _newVerifier;
emit UpdateVerifier(_oldVerifier, _newVerifier);
}
/// @notice Update the value of `maxNumL2TxInChunk`.
/// @param _maxNumL2TxInChunk The new value of `maxNumL2TxInChunk`.
function updateMaxNumL2TxInChunk(uint256 _maxNumL2TxInChunk) external onlyOwner {
uint256 _oldMaxNumL2TxInChunk = maxNumL2TxInChunk;
maxNumL2TxInChunk = _maxNumL2TxInChunk;
emit UpdateMaxNumL2TxInChunk(_oldMaxNumL2TxInChunk, _maxNumL2TxInChunk);
}
/**********************
* Internal Functions *
**********************/
/// @dev Internal function to commit a batch.
/// @param _batch The batch to commit.
function _commitBatch(Batch memory _batch) internal returns (bytes32) {
// check whether the batch is empty
require(_batch.blocks.length > 0, "Batch is empty");
/// @dev Internal function to load batch header from calldata to memory.
/// @param _batchHeader The batch header in calldata.
/// @return memPtr The start memory offset of loaded batch header.
/// @return _batchHash The hash of the loaded batch header.
function _loadBatchHeader(bytes calldata _batchHeader) internal pure returns (uint256 memPtr, bytes32 _batchHash) {
// load to memory
uint256 _length;
(memPtr, _length) = BatchHeaderV0Codec.loadAndValidate(_batchHeader);
BatchStored storage _parentBatch = batches[_batch.parentBatchHash];
require(
_parentBatch.newStateRoot == _batch.prevStateRoot,
"prevStateRoot is different from newStateRoot in the parent batch"
);
uint64 accTotalL1Messages = _parentBatch.totalL1Messages;
bytes32 publicInputHash;
uint64 numTransactionsInBatch;
uint64 lastBlockTimestamp;
(publicInputHash, numTransactionsInBatch, accTotalL1Messages, lastBlockTimestamp) = _computePublicInputHash(
accTotalL1Messages,
_batch
);
BatchStored storage _batchInStorage = batches[publicInputHash];
require(_batchInStorage.newStateRoot == bytes32(0), "Batch already commited");
_batchInStorage.newStateRoot = _batch.newStateRoot;
_batchInStorage.withdrawTrieRoot = _batch.withdrawTrieRoot;
_batchInStorage.batchIndex = _batch.batchIndex;
_batchInStorage.parentBatchHash = _batch.parentBatchHash;
_batchInStorage.timestamp = lastBlockTimestamp;
_batchInStorage.numTransactions = numTransactionsInBatch;
_batchInStorage.totalL1Messages = accTotalL1Messages;
emit CommitBatch(publicInputHash);
return publicInputHash;
// compute batch hash
_batchHash = BatchHeaderV0Codec.computeBatchHash(memPtr, _length);
}
/// @dev Internal function to compute the public input hash.
/// @param accTotalL1Messages The number of total L1 messages in previous batch.
/// @param batch The batch to compute.
function _computePublicInputHash(uint64 accTotalL1Messages, Batch memory batch)
internal
view
returns (
bytes32,
uint64,
uint64,
uint64
)
{
uint256 publicInputsPtr;
// 1. append prevStateRoot, newStateRoot and withdrawTrieRoot to public inputs
{
bytes32 prevStateRoot = batch.prevStateRoot;
bytes32 newStateRoot = batch.newStateRoot;
bytes32 withdrawTrieRoot = batch.withdrawTrieRoot;
// number of bytes in public inputs: 32 * 3 + 124 * blocks + 32 * MAX_NUM_TXS
uint256 publicInputsSize = 32 * 3 + batch.blocks.length * 124 + 32 * maxNumTxInBatch;
assembly {
publicInputsPtr := mload(0x40)
mstore(0x40, add(publicInputsPtr, publicInputsSize))
mstore(publicInputsPtr, prevStateRoot)
publicInputsPtr := add(publicInputsPtr, 0x20)
mstore(publicInputsPtr, newStateRoot)
publicInputsPtr := add(publicInputsPtr, 0x20)
mstore(publicInputsPtr, withdrawTrieRoot)
publicInputsPtr := add(publicInputsPtr, 0x20)
/// @dev Internal function to commit a chunk.
/// @param memPtr The start memory offset to store list of `dataHash`.
/// @param _chunk The encoded chunk to commit.
/// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch.
/// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch.
/// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
/// @return _totalNumL1MessagesInChunk The total number of L1 message popped in current chunk
function _commitChunk(
uint256 memPtr,
bytes memory _chunk,
uint256 _totalL1MessagesPoppedInBatch,
uint256 _totalL1MessagesPoppedOverall,
bytes calldata _skippedL1MessageBitmap
) internal view returns (uint256 _totalNumL1MessagesInChunk) {
uint256 chunkPtr;
uint256 dataPtr;
uint256 blockPtr;
assembly {
dataPtr := mload(0x40)
chunkPtr := add(_chunk, 0x20) // skip chunkLength
blockPtr := add(chunkPtr, 1) // skip numBlocks
}
uint256 _numBlocks = ChunkCodec.validateChunkLength(chunkPtr, _chunk.length);
// concatenate block contexts
for (uint256 i = 0; i < _numBlocks; i++) {
dataPtr = ChunkCodec.copyBlockContext(chunkPtr, dataPtr, i);
}
// concatenate tx hashes
uint256 l2TxPtr = ChunkCodec.l2TxPtr(chunkPtr, _numBlocks);
// avoid stack too deep on forge coverage
uint256 _totalTransactionsInChunk;
while (_numBlocks > 0) {
// concatenate l1 message hashes
uint256 _numL1MessagesInBlock = ChunkCodec.numL1Messages(blockPtr);
dataPtr = _loadL1MessageHashes(
dataPtr,
_numL1MessagesInBlock,
_totalL1MessagesPoppedInBatch,
_totalL1MessagesPoppedOverall,
_skippedL1MessageBitmap
);
// concatenate l2 transaction hashes
uint256 _numTransactionsInBlock = ChunkCodec.numTransactions(blockPtr);
for (uint256 j = _numL1MessagesInBlock; j < _numTransactionsInBlock; j++) {
bytes32 txHash;
(txHash, l2TxPtr) = ChunkCodec.loadL2TxHash(l2TxPtr);
assembly {
mstore(dataPtr, txHash)
dataPtr := add(dataPtr, 0x20)
}
}
unchecked {
_totalTransactionsInChunk += _numTransactionsInBlock;
_totalNumL1MessagesInChunk += _numL1MessagesInBlock;
_totalL1MessagesPoppedInBatch += _numL1MessagesInBlock;
_totalL1MessagesPoppedOverall += _numL1MessagesInBlock;
_numBlocks -= 1;
blockPtr += ChunkCodec.BLOCK_CONTEXT_LENGTH;
}
}
uint64 numTransactionsInBatch;
BlockContext memory _block;
// 2. append block information to public inputs.
for (uint256 i = 0; i < batch.blocks.length; i++) {
// validate blocks, we won't check first block against previous batch.
{
BlockContext memory _currentBlock = batch.blocks[i];
if (i > 0) {
require(_block.blockHash == _currentBlock.parentHash, "Parent hash mismatch");
require(_block.blockNumber + 1 == _currentBlock.blockNumber, "Block number mismatch");
}
_block = _currentBlock;
}
// check the number of L2 transactions in the chunk
require(
_totalTransactionsInChunk - _totalNumL1MessagesInChunk <= maxNumL2TxInChunk,
"too many L2 txs in one chunk"
);
// append blockHash and parentHash to public inputs
{
bytes32 blockHash = _block.blockHash;
bytes32 parentHash = _block.parentHash;
assembly {
mstore(publicInputsPtr, blockHash)
publicInputsPtr := add(publicInputsPtr, 0x20)
mstore(publicInputsPtr, parentHash)
publicInputsPtr := add(publicInputsPtr, 0x20)
}
}
// append blockNumber and blockTimestamp to public inputs
{
uint256 blockNumber = _block.blockNumber;
uint256 blockTimestamp = _block.timestamp;
assembly {
mstore(publicInputsPtr, shl(192, blockNumber))
publicInputsPtr := add(publicInputsPtr, 0x8)
mstore(publicInputsPtr, shl(192, blockTimestamp))
publicInputsPtr := add(publicInputsPtr, 0x8)
}
}
// append baseFee to public inputs
{
uint256 baseFee = _block.baseFee;
assembly {
mstore(publicInputsPtr, baseFee)
publicInputsPtr := add(publicInputsPtr, 0x20)
}
}
uint64 numTransactionsInBlock = _block.numTransactions;
// gasLimit, numTransactions and numL1Messages to public inputs
{
uint256 gasLimit = _block.gasLimit;
uint256 numL1MessagesInBlock = _block.numL1Messages;
assembly {
mstore(publicInputsPtr, shl(192, gasLimit))
publicInputsPtr := add(publicInputsPtr, 0x8)
mstore(publicInputsPtr, shl(240, numTransactionsInBlock))
publicInputsPtr := add(publicInputsPtr, 0x2)
mstore(publicInputsPtr, shl(240, numL1MessagesInBlock))
publicInputsPtr := add(publicInputsPtr, 0x2)
}
}
numTransactionsInBatch += numTransactionsInBlock;
}
require(numTransactionsInBatch <= maxNumTxInBatch, "Too many transactions in batch");
// check chunk has correct length
require(l2TxPtr - chunkPtr == _chunk.length, "incomplete l2 transaction data");
// 3. append transaction hash to public inputs.
address _messageQueue = messageQueue;
uint256 _l2TxnPtr;
{
bytes memory l2Transactions = batch.l2Transactions;
assembly {
_l2TxnPtr := add(l2Transactions, 0x20)
}
// compute data hash and store to memory
assembly {
let startPtr := mload(0x40)
let dataHash := keccak256(startPtr, sub(dataPtr, startPtr))
mstore(memPtr, dataHash)
}
for (uint256 i = 0; i < batch.blocks.length; i++) {
uint256 numL1MessagesInBlock = batch.blocks[i].numL1Messages;
while (numL1MessagesInBlock > 0) {
bytes32 hash = IL1MessageQueue(_messageQueue).getCrossDomainMessage(uint64(accTotalL1Messages));
assembly {
mstore(publicInputsPtr, hash)
publicInputsPtr := add(publicInputsPtr, 0x20)
return _totalNumL1MessagesInChunk;
}
/// @dev Internal function to load L1 message hashes from the message queue.
/// @param _ptr The memory offset to store the transaction hash.
/// @param _numL1Messages The number of L1 messages to load.
/// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch.
/// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch.
/// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
/// @return uint256 The new memory offset after loading.
function _loadL1MessageHashes(
uint256 _ptr,
uint256 _numL1Messages,
uint256 _totalL1MessagesPoppedInBatch,
uint256 _totalL1MessagesPoppedOverall,
bytes calldata _skippedL1MessageBitmap
) internal view returns (uint256) {
if (_numL1Messages == 0) return _ptr;
IL1MessageQueue _messageQueue = IL1MessageQueue(messageQueue);
unchecked {
uint256 _bitmap;
for (uint256 i = 0; i < _numL1Messages; i++) {
uint256 quo = _totalL1MessagesPoppedInBatch >> 8;
uint256 rem = _totalL1MessagesPoppedInBatch & 0xff;
// load bitmap every 256 bits
if (i == 0 || rem == 0) {
assembly {
_bitmap := calldataload(add(_skippedL1MessageBitmap.offset, mul(0x20, quo)))
}
}
unchecked {
accTotalL1Messages += 1;
numL1MessagesInBlock -= 1;
}
}
numL1MessagesInBlock = batch.blocks[i].numL1Messages;
uint256 numTransactionsInBlock = batch.blocks[i].numTransactions;
for (uint256 j = numL1MessagesInBlock; j < numTransactionsInBlock; ++j) {
bytes32 hash;
assembly {
let txPayloadLength := shr(224, mload(_l2TxnPtr))
_l2TxnPtr := add(_l2TxnPtr, 4)
_l2TxnPtr := add(_l2TxnPtr, txPayloadLength)
hash := keccak256(sub(_l2TxnPtr, txPayloadLength), txPayloadLength)
mstore(publicInputsPtr, hash)
publicInputsPtr := add(publicInputsPtr, 0x20)
if (((_bitmap >> rem) & 1) == 0) {
// message not skipped
bytes32 _hash = _messageQueue.getCrossDomainMessage(_totalL1MessagesPoppedOverall);
assembly {
mstore(_ptr, _hash)
_ptr := add(_ptr, 0x20)
}
}
_totalL1MessagesPoppedInBatch += 1;
_totalL1MessagesPoppedOverall += 1;
}
}
// 4. append padding transaction to public inputs.
bytes32 txHashPadding = paddingTxHash;
for (uint256 i = numTransactionsInBatch; i < maxNumTxInBatch; i++) {
assembly {
mstore(publicInputsPtr, txHashPadding)
publicInputsPtr := add(publicInputsPtr, 0x20)
}
}
// 5. compute public input hash
bytes32 publicInputHash;
{
uint256 publicInputsSize = 32 * 3 + batch.blocks.length * 124 + 32 * maxNumTxInBatch;
assembly {
publicInputHash := keccak256(sub(publicInputsPtr, publicInputsSize), publicInputsSize)
}
}
return (publicInputHash, numTransactionsInBatch, accTotalL1Messages, _block.timestamp);
return _ptr;
}
}

View File

@@ -38,22 +38,22 @@ contract ScrollChainCommitmentVerifier {
}
/// @notice Verifies a batch inclusion proof.
/// @param batchHash The hash of the batch.
/// @param batchIndex The index of the batch.
/// @param account The address of the contract in L2.
/// @param storageKey The storage key inside the contract in L2.
/// @param proof The rlp encoding result of eth_getProof.
/// @return storageValue The value of `storageKey`.
function verifyStateCommitment(
bytes32 batchHash,
uint256 batchIndex,
address account,
bytes32 storageKey,
bytes calldata proof
) external view returns (bytes32 storageValue) {
require(ScrollChain(rollup).isBatchFinalized(batchHash), "Batch not finalized");
require(ScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized");
bytes32 computedStateRoot;
(computedStateRoot, storageValue) = ZkTrieVerifier.verifyZkTrieProof(poseidon, account, storageKey, proof);
(bytes32 expectedStateRoot, , , , , , , ) = ScrollChain(rollup).batches(batchHash);
bytes32 expectedStateRoot = ScrollChain(rollup).finalizedStateRoots(batchIndex);
require(computedStateRoot == expectedStateRoot, "Invalid inclusion proof");
}
}

View File

@@ -37,8 +37,6 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
* Constants *
*************/
uint256 private constant MIN_GAS_LIMIT = 21000;
/// @notice The contract contains the list of L1 blocks.
address public immutable blockContainer;
@@ -194,7 +192,7 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
bytes memory _message,
uint256 _gasLimit
) external payable override whenNotPaused {
_sendMessage(_to, _value, _message, _gasLimit, tx.origin);
_sendMessage(_to, _value, _message, _gasLimit);
}
/// @inheritdoc IScrollMessenger
@@ -203,9 +201,9 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
uint256 _value,
bytes calldata _message,
uint256 _gasLimit,
address _refundAddress
address
) external payable override whenNotPaused {
_sendMessage(_to, _value, _message, _gasLimit, _refundAddress);
_sendMessage(_to, _value, _message, _gasLimit);
}
/// @inheritdoc IL2ScrollMessenger
@@ -266,6 +264,9 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
}
}
/// @notice Update max failed execution times.
/// @dev This function can only called by contract owner.
/// @param _maxFailedExecutionTimes The new max failed execution times.
function updateMaxFailedExecutionTimes(uint256 _maxFailedExecutionTimes) external onlyOwner {
maxFailedExecutionTimes = _maxFailedExecutionTimes;
@@ -276,25 +277,18 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
* Internal Functions *
**********************/
/// @dev Internal function to send cross domain message.
/// @param _to The address of account who receive the message.
/// @param _value The amount of ether passed when call target contract.
/// @param _message The content of the message.
/// @param _gasLimit Optional gas limit to complete the message relay on corresponding chain.
function _sendMessage(
address _to,
uint256 _value,
bytes memory _message,
uint256 _gasLimit,
address _refundAddress
uint256 _gasLimit
) internal nonReentrant {
// by pass fee vault relay
if (feeVault != msg.sender) {
require(_gasLimit >= MIN_GAS_LIMIT, "gas limit too small");
}
// compute and deduct the messaging fee to fee vault.
uint256 _fee = _gasLimit * IL1GasPriceOracle(gasOracle).l1BaseFee();
require(msg.value >= _value + _fee, "Insufficient msg.value");
if (_fee > 0) {
(bool _success, ) = feeVault.call{value: _fee}("");
require(_success, "Failed to deduct the fee");
}
require(msg.value == _value, "msg.value mismatch");
uint256 _nonce = L2MessageQueue(messageQueue).nextMessageIndex();
bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(msg.sender, _to, _value, _nonce, _message));
@@ -306,17 +300,14 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
L2MessageQueue(messageQueue).appendMessage(_xDomainCalldataHash);
emit SentMessage(msg.sender, _to, _value, _nonce, _gasLimit, _message);
// refund fee to tx.origin
unchecked {
uint256 _refund = msg.value - _fee - _value;
if (_refund > 0) {
(bool _success, ) = _refundAddress.call{value: _refund}("");
require(_success, "Failed to refund the fee");
}
}
}
/// @dev Internal function to execute a L1 => L2 message.
/// @param _from The address of the sender of the message.
/// @param _to The address of the recipient of the message.
/// @param _value The msg.value passed to the message call.
/// @param _message The content of the message.
/// @param _xDomainCalldataHash The hash of the message.
function _executeMessage(
address _from,
address _to,
@@ -324,7 +315,7 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
bytes memory _message,
bytes32 _xDomainCalldataHash
) internal {
// @todo check more `_to` address to avoid attack.
// @note check more `_to` address to avoid attack in the future when we add more gateways.
require(_to != messageQueue, "Forbid to call message queue");
require(_to != address(this), "Forbid to call self");

View File

@@ -9,7 +9,7 @@ import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IScrollStandardERC20} from "../../libraries/token/IScrollStandardERC20.sol";
import {IScrollERC20} from "../../libraries/token/IScrollERC20.sol";
/// @title L2ERC20Gateway
/// @notice The `L2ERC20Gateway` is used to withdraw custom ERC20 compatible tokens in layer 2 and
@@ -75,11 +75,12 @@ contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20G
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == 0, "nonzero msg.value");
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l1 token mismatch");
IScrollStandardERC20(_l2Token).mint(_to, _amount);
IScrollERC20(_l2Token).mint(_to, _amount);
_doCallback(_to, _data);
@@ -94,7 +95,7 @@ contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20G
/// @param _l2Token The address of corresponding ERC20 token in layer 2.
/// @param _l1Token The address of ERC20 token in layer 1.
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "map to zero address");
require(_l1Token != address(0), "token address cannot be 0");
tokenMapping[_l2Token] = _l1Token;
@@ -112,7 +113,7 @@ contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20G
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) internal virtual override {
) internal virtual override nonReentrant {
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
@@ -125,7 +126,7 @@ contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20G
}
// 2. Burn token.
IScrollStandardERC20(_token).burn(_from, _amount);
IScrollERC20(_token).burn(_from, _amount);
// 3. Generate message passed to L1StandardERC20Gateway.
bytes memory _message = abi.encodeWithSelector(

View File

@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {ERC1155HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {IL2ERC1155Gateway} from "./IL2ERC1155Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
@@ -19,7 +19,6 @@ import {IScrollERC1155} from "../../libraries/token/IScrollERC1155.sol";
/// NFT will be minted and transfered to the recipient.
///
/// This will be changed if we have more specific scenarios.
// @todo Current implementation doesn't support calling from `L2GatewayRouter`.
contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway {
/**********
* Events *
@@ -44,6 +43,9 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC1155HolderUpgradeable.__ERC1155Holder_init();
ERC1155ReceiverUpgradeable.__ERC1155Receiver_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
}
@@ -101,7 +103,10 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
address _to,
uint256 _tokenId,
uint256 _amount
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch");
IScrollERC1155(_l2Token).mint(_to, _tokenId, _amount, "");
emit FinalizeDepositERC1155(_l1Token, _l2Token, _from, _to, _tokenId, _amount);
@@ -115,7 +120,10 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
address _to,
uint256[] calldata _tokenIds,
uint256[] calldata _amounts
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch");
IScrollERC1155(_l2Token).batchMint(_to, _tokenIds, _amounts, "");
emit FinalizeBatchDepositERC1155(_l1Token, _l2Token, _from, _to, _tokenIds, _amounts);
@@ -129,7 +137,7 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
/// @param _l1Token The address of corresponding ERC1155 token in layer 2.
/// @param _l1Token The address of ERC1155 token in layer 1.
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "map to zero address");
require(_l1Token != address(0), "token address cannot be 0");
tokenMapping[_l2Token] = _l1Token;
@@ -156,7 +164,7 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
require(_amount > 0, "withdraw zero amount");
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "token not supported");
require(_l1Token != address(0), "no corresponding l1 token");
// 1. burn token
IScrollERC1155(_token).burn(msg.sender, _tokenId, _amount);
@@ -199,7 +207,7 @@ contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, Scrol
}
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "token not supported");
require(_l1Token != address(0), "no corresponding l1 token");
// 1. transfer token to this contract
IScrollERC1155(_token).batchBurn(msg.sender, _tokenIds, _amounts);

View File

@@ -19,7 +19,6 @@ import {IScrollERC721} from "../../libraries/token/IScrollERC721.sol";
/// NFT will be minted and transfered to the recipient.
///
/// This will be changed if we have more specific scenarios.
// @todo Current implementation doesn't support calling from `L2GatewayRouter`.
contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway {
/**********
* Events *
@@ -44,6 +43,8 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC721HolderUpgradeable.__ERC721Holder_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
}
@@ -96,7 +97,10 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
address _from,
address _to,
uint256 _tokenId
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch");
IScrollERC721(_l2Token).mint(_to, _tokenId);
emit FinalizeDepositERC721(_l1Token, _l2Token, _from, _to, _tokenId);
@@ -109,7 +113,10 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
address _from,
address _to,
uint256[] calldata _tokenIds
) external override nonReentrant onlyCallByCounterpart {
) external override onlyCallByCounterpart nonReentrant {
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l2 token mismatch");
for (uint256 i = 0; i < _tokenIds.length; i++) {
IScrollERC721(_l2Token).mint(_to, _tokenIds[i]);
}
@@ -125,7 +132,7 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
/// @param _l1Token The address of corresponding ERC721 token in layer 2.
/// @param _l1Token The address of ERC721 token in layer 1.
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "map to zero address");
require(_l1Token != address(0), "token address cannot be 0");
tokenMapping[_l2Token] = _l1Token;
@@ -148,7 +155,7 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
uint256 _gasLimit
) internal nonReentrant {
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "token not supported");
require(_l1Token != address(0), "no corresponding l1 token");
// 1. burn token
// @note in case the token has given too much power to the gateway, we check owner here.
@@ -185,7 +192,7 @@ contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollG
require(_tokenIds.length > 0, "no token to withdraw");
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "token not supported");
require(_l1Token != address(0), "no corresponding l1 token");
// 1. transfer token to this contract
for (uint256 i = 0; i < _tokenIds.length; i++) {

View File

@@ -67,7 +67,9 @@ contract L2ETHGateway is Initializable, ScrollGatewayBase, IL2ETHGateway {
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == _amount, "msg.value mismatch");
// solhint-disable-next-line avoid-low-level-calls
(bool _success, ) = _to.call{value: _amount}("");
require(_success, "ETH transfer failed");

View File

@@ -10,7 +10,6 @@ import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ETHGateway} from "../../L1/gateways/IL1ETHGateway.sol";
import {IScrollGateway} from "../../libraries/gateway/IScrollGateway.sol";
import {IScrollStandardERC20} from "../../libraries/token/IScrollStandardERC20.sol";
/// @title L2GatewayRouter
/// @notice The `L2GatewayRouter` is the main entry for withdrawing Ether and ERC20 tokens.
@@ -32,8 +31,6 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
// solhint-disable-next-line var-name-mixedcase
mapping(address => address) public ERC20Gateway;
// @todo: add ERC721/ERC1155 Gateway mapping.
/***************
* Constructor *
***************/

View File

@@ -10,7 +10,7 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol";
import {IScrollStandardERC20} from "../../libraries/token/IScrollStandardERC20.sol";
import {IScrollERC20} from "../../libraries/token/IScrollERC20.sol";
import {ScrollStandardERC20} from "../../libraries/token/ScrollStandardERC20.sol";
import {IScrollStandardERC20Factory} from "../../libraries/token/IScrollStandardERC20Factory.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
@@ -78,8 +78,9 @@ contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gate
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(msg.value == 0, "nonzero msg.value");
require(_l1Token != address(0), "token address cannot be 0");
{
// avoid stack too deep
@@ -98,6 +99,7 @@ contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gate
tokenMapping[_l2Token] = _l1Token;
(_callData, _deployData) = abi.decode(_data, (bytes, bytes));
} else {
require(tokenMapping[_l2Token] == _l1Token, "token mapping mismatch");
_callData = _data;
}
@@ -105,7 +107,7 @@ contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gate
_deployL2Token(_deployData, _l1Token);
}
IScrollStandardERC20(_l2Token).mint(_to, _amount);
IScrollERC20(_l2Token).mint(_to, _amount);
_doCallback(_to, _callData);
@@ -123,7 +125,7 @@ contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gate
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) internal virtual override {
) internal virtual override nonReentrant {
require(_amount > 0, "withdraw zero amount");
// 1. Extract real sender if this call is from L2GatewayRouter.
@@ -136,7 +138,7 @@ contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gate
require(_l1Token != address(0), "no corresponding l1 token");
// 2. Burn token.
IScrollStandardERC20(_token).burn(_from, _amount);
IScrollERC20(_token).burn(_from, _amount);
// 3. Generate message passed to L1StandardERC20Gateway.
bytes memory _message = abi.encodeWithSelector(

View File

@@ -30,7 +30,6 @@ contract L2WETHGateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
address public immutable l1WETH;
/// @notice The address of L2 WETH address.
// @todo It should be predeployed in L2 and make it a constant.
// solhint-disable-next-line var-name-mixedcase
address public immutable WETH;
@@ -82,7 +81,7 @@ contract L2WETHGateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
address _to,
uint256 _amount,
bytes calldata _data
) external payable override onlyCallByCounterpart {
) external payable override onlyCallByCounterpart nonReentrant {
require(_l1Token == l1WETH, "l1 token not WETH");
require(_l2Token == WETH, "l2 token not WETH");
require(_amount == msg.value, "msg.value mismatch");
@@ -106,7 +105,7 @@ contract L2WETHGateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) internal virtual override {
) internal virtual override nonReentrant {
require(_amount > 0, "withdraw zero amount");
require(_token == WETH, "only WETH is allowed");

View File

@@ -40,7 +40,7 @@ interface IL1GasPriceOracle {
/// @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which
/// represents the per-transaction gas overhead of posting the transaction and state
/// roots to L1. Adds 68 bytes of padding to account for the fact that the input does
/// roots to L1. Adds 74 bytes of padding to account for the fact that the input does
/// not have a signature.
/// @param data Unsigned fully RLP-encoded transaction to get the L1 gas for.
/// @return Amount of L1 gas used to publish the transaction.

View File

@@ -42,8 +42,6 @@ contract L1BlockContainer is OwnableBase, IL1BlockContainer {
/// @notice The address of whitelist contract.
IWhitelist public whitelist;
// @todo change to ring buffer to save gas usage.
/// @inheritdoc IL1BlockContainer
bytes32 public override latestBlockHash;
@@ -117,7 +115,6 @@ contract L1BlockContainer is OwnableBase, IL1BlockContainer {
bytes calldata _blockHeaderRLP,
bool _updateGasPriceOracle
) external {
// @todo remove this when ETH 2.0 signature verification is ready.
{
IWhitelist _whitelist = whitelist;
require(

View File

@@ -69,8 +69,14 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
}
/// @inheritdoc IL1GasPriceOracle
/// @dev See the comments in `OVM_GasPriceOracle1` for more details
/// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/predeploys/OVM_GasPriceOracle.sol
/// @dev The extra 74 bytes on top of the RLP encoded unsigned transaction data consist of
/// 4 bytes Add 4 bytes in the beginning for transaction data length
/// 1 byte RLP V prefix
/// 3 bytes V
/// 1 bytes RLP R prefix
/// 32 bytes R
/// 1 bytes RLP S prefix
/// 32 bytes S
function getL1GasUsed(bytes memory _data) public view override returns (uint256) {
uint256 _total = 0;
uint256 _length = _data.length;
@@ -83,7 +89,7 @@ contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {
}
}
uint256 _unsigned = _total + overhead;
return _unsigned + (68 * 16);
return _unsigned + (74 * 16);
}
}

21
contracts/src/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Scroll
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Some files were not shown because too many files have changed in this diff Show More