mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-12 15:38:18 -05:00
Compare commits
1 Commits
v4.3.61
...
fix-access
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4cac65ea5 |
254
.github/workflows/docker.yml
vendored
254
.github/workflows/docker.yml
vendored
@@ -5,17 +5,12 @@ on:
|
||||
tags:
|
||||
- v**
|
||||
|
||||
env:
|
||||
AWS_REGION: us-west-2
|
||||
|
||||
jobs:
|
||||
event_watcher:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
@@ -23,38 +18,22 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: event-watcher
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
- name: Build and push event_watcher docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/event_watcher.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
scrolltech/event-watcher:${{github.ref_name}}
|
||||
scrolltech/event-watcher:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
gas_oracle:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
@@ -62,38 +41,22 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: gas-oracle
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
- name: Build and push gas_oracle docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/gas_oracle.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
scrolltech/gas-oracle:${{github.ref_name}}
|
||||
scrolltech/gas-oracle:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
rollup_relayer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
@@ -101,116 +64,68 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: rollup-relayer
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
- name: Build and push rollup_relayer docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/rollup_relayer.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
scrolltech/rollup-relayer:${{github.ref_name}}
|
||||
scrolltech/rollup-relayer:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
bridgehistoryapi-fetcher:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: bridgehistoryapi-fetcher
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push bridgehistoryapi-fetcher docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
scrolltech/bridgehistoryapi-fetcher:${{github.ref_name}}
|
||||
scrolltech/bridgehistoryapi-fetcher:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
bridgehistoryapi-api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: bridgehistoryapi-api
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/bridgehistoryapi-api.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push bridgehistoryapi-api docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/bridgehistoryapi-api.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
scrolltech/bridgehistoryapi-api:${{github.ref_name}}
|
||||
scrolltech/bridgehistoryapi-api:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
coordinator-api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
@@ -218,38 +133,22 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: coordinator-api
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
- name: Build and push coordinator docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/coordinator-api.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
|
||||
scrolltech/coordinator-api:${{github.ref_name}}
|
||||
scrolltech/coordinator-api:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
coordinator-cron:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
@@ -257,27 +156,14 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
REPOSITORY: coordinator-cron
|
||||
IMAGE_TAG: ${{ github.ref_name }}
|
||||
- name: Build and push coordinator docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfiles/coordinator-cron.Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPOSITORY }}:latest
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
|
||||
scrolltech/coordinator-cron:${{github.ref_name}}
|
||||
scrolltech/coordinator-cron:latest
|
||||
# cache-from: type=gha,scope=${{ github.workflow }}
|
||||
# cache-to: type=gha,scope=${{ github.workflow }}
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022-2024 Scroll
|
||||
Copyright (c) 2022-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
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"confirmation": 0,
|
||||
"endpoint": "https://rpc.ankr.com/eth",
|
||||
"startHeight": 18306000,
|
||||
"blockTime": 12,
|
||||
"fetchLimit": 16,
|
||||
"blockTime": 10,
|
||||
"fetchLimit": 30,
|
||||
"MessengerAddr": "0x6774Bcbd5ceCeF1336b5300fb5186a12DDD8b367",
|
||||
"ETHGatewayAddr": "0x7F2b8C31F88B6006c382775eea88297Ec1e3E905",
|
||||
"WETHGatewayAddr": "0x7AC440cAe8EB6328de4fA621163a792c1EA9D4fE",
|
||||
@@ -23,7 +23,7 @@
|
||||
"confirmation": 0,
|
||||
"endpoint": "https://rpc.scroll.io",
|
||||
"blockTime": 3,
|
||||
"fetchLimit": 64,
|
||||
"fetchLimit": 100,
|
||||
"MessengerAddr": "0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC",
|
||||
"ETHGatewayAddr": "0x6EA73e05AdC79974B931123675ea8F78FfdacDF0",
|
||||
"WETHGatewayAddr": "0x7003E7B7186f0E6601203b99F7B8DECBfA391cf9",
|
||||
|
||||
@@ -6,9 +6,10 @@ require (
|
||||
github.com/gin-contrib/cors v1.5.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/pressly/goose/v3 v3.16.0
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20240131010456-d86b42cdaa9d
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20231130005111-38a3a9c9198c
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/urfave/cli/v2 v2.25.7
|
||||
golang.org/x/sync v0.5.0
|
||||
@@ -39,7 +40,6 @@ require (
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/holiman/uint256 v1.2.4 // indirect
|
||||
github.com/huin/goupnp v1.3.0 // indirect
|
||||
|
||||
@@ -204,8 +204,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
|
||||
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.20240131010456-d86b42cdaa9d h1:bs/VF0h/J68sFoUqLBlb8pw3s18fAcKSLzljCCJ68KA=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20240131010456-d86b42cdaa9d/go.mod h1:DsirsE0wBU56OTnZUGg4PYs+uXLeO2EXzd8FZFoWteo=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20231130005111-38a3a9c9198c h1:MnAdt80steCDli4SAD0J0spBGNY+gQvbdptNjWztHcw=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20231130005111-38a3a9c9198c/go.mod h1:4HrFcoStbViFVy/9l/rvKl1XmizVAaPdgqI8v0U8hOc=
|
||||
github.com/scroll-tech/zktrie v0.7.1 h1:NrmZNjuBzsbrKePqdHDG+t2cXnimbtezPAFS0+L9ElE=
|
||||
github.com/scroll-tech/zktrie v0.7.1/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"scroll-tech/common/database"
|
||||
)
|
||||
|
||||
// FetcherConfig is the configuration of Layer1 or Layer2 fetcher.
|
||||
type FetcherConfig struct {
|
||||
// LayerConfig is the configuration of Layer1/Layer2
|
||||
type LayerConfig struct {
|
||||
Confirmation uint64 `json:"confirmation"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
StartHeight uint64 `json:"startHeight"` // Can only be configured to contract deployment height, message proof should be updated from the very beginning.
|
||||
StartHeight uint64 `json:"startHeight"` // Can only be configured to contract deployment height, otherwise in the current implementation, the message proof could not be successfully updated.
|
||||
BlockTime int64 `json:"blockTime"`
|
||||
FetchLimit uint64 `json:"fetchLimit"`
|
||||
MessengerAddr string `json:"MessengerAddr"`
|
||||
@@ -43,8 +43,8 @@ type RedisConfig struct {
|
||||
|
||||
// Config is the configuration of the bridge history backend
|
||||
type Config struct {
|
||||
L1 *FetcherConfig `json:"L1"`
|
||||
L2 *FetcherConfig `json:"L2"`
|
||||
L1 *LayerConfig `json:"L1"`
|
||||
L2 *LayerConfig `json:"L2"`
|
||||
DB *database.Config `json:"db"`
|
||||
Redis *RedisConfig `json:"redis"`
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// L1MessageFetcher fetches cross message events from L1 and saves them to database.
|
||||
type L1MessageFetcher struct {
|
||||
ctx context.Context
|
||||
cfg *config.FetcherConfig
|
||||
cfg *config.LayerConfig
|
||||
client *ethclient.Client
|
||||
|
||||
l1SyncHeight uint64
|
||||
@@ -35,7 +35,7 @@ type L1MessageFetcher struct {
|
||||
}
|
||||
|
||||
// NewL1MessageFetcher creates a new L1MessageFetcher instance.
|
||||
func NewL1MessageFetcher(ctx context.Context, cfg *config.FetcherConfig, db *gorm.DB, client *ethclient.Client) *L1MessageFetcher {
|
||||
func NewL1MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) *L1MessageFetcher {
|
||||
c := &L1MessageFetcher{
|
||||
ctx: ctx,
|
||||
cfg: cfg,
|
||||
@@ -108,6 +108,7 @@ func (c *L1MessageFetcher) Start() {
|
||||
}
|
||||
|
||||
func (c *L1MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
c.l1MessageFetcherRunningTotal.Inc()
|
||||
startHeight := c.l1SyncHeight + 1
|
||||
endHeight, rpcErr := utils.GetBlockNumber(c.ctx, c.client, confirmation)
|
||||
if rpcErr != nil {
|
||||
@@ -133,7 +134,6 @@ func (c *L1MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
c.l1MessageFetcherReorgTotal.Inc()
|
||||
log.Warn("L1 reorg happened, exit and re-enter fetchAndSaveEvents", "re-sync height", resyncHeight)
|
||||
c.updateL1SyncHeight(resyncHeight, lastBlockHash)
|
||||
c.l1MessageFetcherRunningTotal.Inc()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -143,7 +143,6 @@ func (c *L1MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
}
|
||||
|
||||
c.updateL1SyncHeight(to, lastBlockHash)
|
||||
c.l1MessageFetcherRunningTotal.Inc()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// L2MessageFetcher fetches cross message events from L2 and saves them to database.
|
||||
type L2MessageFetcher struct {
|
||||
ctx context.Context
|
||||
cfg *config.FetcherConfig
|
||||
cfg *config.LayerConfig
|
||||
db *gorm.DB
|
||||
client *ethclient.Client
|
||||
l2SyncHeight uint64
|
||||
@@ -35,7 +35,7 @@ type L2MessageFetcher struct {
|
||||
}
|
||||
|
||||
// NewL2MessageFetcher creates a new L2MessageFetcher instance.
|
||||
func NewL2MessageFetcher(ctx context.Context, cfg *config.FetcherConfig, db *gorm.DB, client *ethclient.Client) *L2MessageFetcher {
|
||||
func NewL2MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) *L2MessageFetcher {
|
||||
c := &L2MessageFetcher{
|
||||
ctx: ctx,
|
||||
cfg: cfg,
|
||||
@@ -110,6 +110,7 @@ func (c *L2MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
return
|
||||
}
|
||||
log.Info("fetch and save missing L2 events", "start height", startHeight, "end height", endHeight, "confirmation", confirmation)
|
||||
c.l2MessageFetcherRunningTotal.Inc()
|
||||
|
||||
for from := startHeight; from <= endHeight; from += c.cfg.FetchLimit {
|
||||
to := from + c.cfg.FetchLimit - 1
|
||||
@@ -127,7 +128,6 @@ func (c *L2MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
c.l2MessageFetcherReorgTotal.Inc()
|
||||
log.Warn("L2 reorg happened, exit and re-enter fetchAndSaveEvents", "re-sync height", resyncHeight)
|
||||
c.updateL2SyncHeight(resyncHeight, lastBlockHash)
|
||||
c.l2MessageFetcherRunningTotal.Inc()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -142,7 +142,6 @@ func (c *L2MessageFetcher) fetchAndSaveEvents(confirmation uint64) {
|
||||
}
|
||||
|
||||
c.updateL2SyncHeight(to, lastBlockHash)
|
||||
c.l2MessageFetcherRunningTotal.Inc()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,30 +76,39 @@ func (b *EventUpdateLogic) GetL2MessageSyncedHeightInDB(ctx context.Context) (ui
|
||||
|
||||
// L1InsertOrUpdate inserts or updates l1 messages
|
||||
func (b *EventUpdateLogic) L1InsertOrUpdate(ctx context.Context, l1FetcherResult *L1FilterResult) error {
|
||||
if err := b.crossMessageOrm.InsertOrUpdateL1Messages(ctx, l1FetcherResult.DepositMessages); err != nil {
|
||||
log.Error("failed to insert L1 deposit messages", "err", err)
|
||||
err := b.db.Transaction(func(tx *gorm.DB) error {
|
||||
if txErr := b.crossMessageOrm.InsertOrUpdateL1Messages(ctx, l1FetcherResult.DepositMessages, tx); txErr != nil {
|
||||
log.Error("failed to insert L1 deposit messages", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
|
||||
if txErr := b.crossMessageOrm.InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx, l1FetcherResult.RelayedMessages, tx); txErr != nil {
|
||||
log.Error("failed to update L1 relayed messages of L2 withdrawals", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
|
||||
if txErr := b.batchEventOrm.InsertOrUpdateBatchEvents(ctx, l1FetcherResult.BatchEvents, tx); txErr != nil {
|
||||
log.Error("failed to insert or update batch events", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
|
||||
if txErr := b.crossMessageOrm.UpdateL1MessageQueueEventsInfo(ctx, l1FetcherResult.MessageQueueEvents, tx); txErr != nil {
|
||||
log.Error("failed to insert L1 message queue events", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
|
||||
if txErr := b.crossMessageOrm.InsertFailedGatewayRouterTxs(ctx, l1FetcherResult.RevertedTxs, tx); txErr != nil {
|
||||
log.Error("failed to insert L1 failed gateway router transactions", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("failed to update db of L1 events", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.crossMessageOrm.InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx, l1FetcherResult.RelayedMessages); err != nil {
|
||||
log.Error("failed to update L1 relayed messages of L2 withdrawals", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.batchEventOrm.InsertOrUpdateBatchEvents(ctx, l1FetcherResult.BatchEvents); err != nil {
|
||||
log.Error("failed to insert or update batch events", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.crossMessageOrm.UpdateL1MessageQueueEventsInfo(ctx, l1FetcherResult.MessageQueueEvents); err != nil {
|
||||
log.Error("failed to insert L1 message queue events", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.crossMessageOrm.InsertFailedL1GatewayTxs(ctx, l1FetcherResult.RevertedTxs); err != nil {
|
||||
log.Error("failed to insert failed L1 gateway transactions", "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -177,18 +186,24 @@ func (b *EventUpdateLogic) UpdateL1BatchIndexAndStatus(ctx context.Context, heig
|
||||
|
||||
// L2InsertOrUpdate inserts or updates L2 messages
|
||||
func (b *EventUpdateLogic) L2InsertOrUpdate(ctx context.Context, l2FetcherResult *L2FilterResult) error {
|
||||
if err := b.crossMessageOrm.InsertOrUpdateL2Messages(ctx, l2FetcherResult.WithdrawMessages); err != nil {
|
||||
log.Error("failed to insert L2 withdrawal messages", "err", err)
|
||||
return err
|
||||
}
|
||||
err := b.db.Transaction(func(tx *gorm.DB) error {
|
||||
if txErr := b.crossMessageOrm.InsertOrUpdateL2Messages(ctx, l2FetcherResult.WithdrawMessages, tx); txErr != nil {
|
||||
log.Error("failed to insert L2 withdrawal messages", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
if txErr := b.crossMessageOrm.InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx, l2FetcherResult.RelayedMessages, tx); txErr != nil {
|
||||
log.Error("failed to update L2 relayed messages of L1 deposits", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
if txErr := b.crossMessageOrm.InsertFailedGatewayRouterTxs(ctx, l2FetcherResult.OtherRevertedTxs, tx); txErr != nil {
|
||||
log.Error("failed to insert L2 failed gateway router transactions", "err", txErr)
|
||||
return txErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := b.crossMessageOrm.InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx, l2FetcherResult.RelayedMessages); err != nil {
|
||||
log.Error("failed to update L2 relayed messages of L1 deposits", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.crossMessageOrm.InsertFailedL2GatewayTxs(ctx, l2FetcherResult.OtherRevertedTxs); err != nil {
|
||||
log.Error("failed to insert failed L2 gateway transactions", "err", err)
|
||||
if err != nil {
|
||||
log.Error("failed to update db of L2 events", "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
@@ -11,27 +10,21 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
backendabi "scroll-tech/bridge-history-api/abi"
|
||||
"scroll-tech/bridge-history-api/internal/config"
|
||||
"scroll-tech/bridge-history-api/internal/orm"
|
||||
"scroll-tech/bridge-history-api/internal/utils"
|
||||
)
|
||||
|
||||
// L1EventParser the l1 event parser
|
||||
type L1EventParser struct {
|
||||
cfg *config.FetcherConfig
|
||||
client *ethclient.Client
|
||||
}
|
||||
|
||||
// NewL1EventParser creates l1 event parser
|
||||
func NewL1EventParser(cfg *config.FetcherConfig, client *ethclient.Client) *L1EventParser {
|
||||
return &L1EventParser{
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
}
|
||||
func NewL1EventParser() *L1EventParser {
|
||||
return &L1EventParser{}
|
||||
}
|
||||
|
||||
// ParseL1CrossChainEventLogs parses L1 watched cross chain events.
|
||||
func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTimestampsMap map[uint64]uint64) ([]*orm.CrossMessage, []*orm.CrossMessage, error) {
|
||||
func (e *L1EventParser) ParseL1CrossChainEventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([]*orm.CrossMessage, []*orm.CrossMessage, error) {
|
||||
var l1DepositMessages []*orm.CrossMessage
|
||||
var l1RelayedMessages []*orm.CrossMessage
|
||||
for _, vlog := range logs {
|
||||
@@ -39,7 +32,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1DepositETHSig:
|
||||
event := backendabi.ETHMessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ETHGatewayABI, &event, "DepositETH", vlog); err != nil {
|
||||
log.Error("Failed to unpack DepositETH event", "err", err)
|
||||
log.Warn("Failed to unpack DepositETH event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -51,7 +44,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
event := backendabi.ERC20MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL1ERC20GatewayABI, &event, "DepositERC20", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack DepositERC20 event", "err", err)
|
||||
log.Warn("Failed to unpack DepositERC20 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -64,7 +57,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1DepositERC721Sig:
|
||||
event := backendabi.ERC721MessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ERC721GatewayABI, &event, "DepositERC721", vlog); err != nil {
|
||||
log.Error("Failed to unpack DepositERC721 event", "err", err)
|
||||
log.Warn("Failed to unpack DepositERC721 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -77,7 +70,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1BatchDepositERC721Sig:
|
||||
event := backendabi.BatchERC721MessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ERC721GatewayABI, &event, "BatchDepositERC721", vlog); err != nil {
|
||||
log.Error("Failed to unpack BatchDepositERC721 event", "err", err)
|
||||
log.Warn("Failed to unpack BatchDepositERC721 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -90,7 +83,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1DepositERC1155Sig:
|
||||
event := backendabi.ERC1155MessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ERC1155GatewayABI, &event, "DepositERC1155", vlog); err != nil {
|
||||
log.Error("Failed to unpack DepositERC1155 event", "err", err)
|
||||
log.Warn("Failed to unpack DepositERC1155 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -104,7 +97,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1BatchDepositERC1155Sig:
|
||||
event := backendabi.BatchERC1155MessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ERC1155GatewayABI, &event, "BatchDepositERC1155", vlog); err != nil {
|
||||
log.Error("Failed to unpack BatchDepositERC1155 event", "err", err)
|
||||
log.Warn("Failed to unpack BatchDepositERC1155 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l1DepositMessages[len(l1DepositMessages)-1]
|
||||
@@ -118,17 +111,12 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1SentMessageEventSig:
|
||||
event := backendabi.L1SentMessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ScrollMessengerABI, &event, "SentMessage", vlog); err != nil {
|
||||
log.Error("Failed to unpack SentMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
from, err := getRealFromAddress(ctx, event.Sender, e.client, vlog.TxHash, e.cfg.GatewayRouterAddr)
|
||||
if err != nil {
|
||||
log.Error("Failed to get real 'from' address", "err", err)
|
||||
log.Warn("Failed to unpack SentMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l1DepositMessages = append(l1DepositMessages, &orm.CrossMessage{
|
||||
L1BlockNumber: vlog.BlockNumber,
|
||||
Sender: from,
|
||||
Sender: event.Sender.String(),
|
||||
Receiver: event.Target.String(),
|
||||
TokenType: int(orm.TokenTypeETH),
|
||||
L1TxHash: vlog.TxHash.String(),
|
||||
@@ -142,7 +130,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1RelayedMessageEventSig:
|
||||
event := backendabi.L1RelayedMessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ScrollMessengerABI, &event, "RelayedMessage", vlog); err != nil {
|
||||
log.Error("Failed to unpack RelayedMessage event", "err", err)
|
||||
log.Warn("Failed to unpack RelayedMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l1RelayedMessages = append(l1RelayedMessages, &orm.CrossMessage{
|
||||
@@ -155,7 +143,7 @@ func (e *L1EventParser) ParseL1CrossChainEventLogs(ctx context.Context, logs []t
|
||||
case backendabi.L1FailedRelayedMessageEventSig:
|
||||
event := backendabi.L1FailedRelayedMessageEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1ScrollMessengerABI, &event, "FailedRelayedMessage", vlog); err != nil {
|
||||
log.Error("Failed to unpack FailedRelayedMessage event", "err", err)
|
||||
log.Warn("Failed to unpack FailedRelayedMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l1RelayedMessages = append(l1RelayedMessages, &orm.CrossMessage{
|
||||
@@ -178,17 +166,17 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
|
||||
case backendabi.L1CommitBatchEventSig:
|
||||
event := backendabi.L1CommitBatchEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IScrollChainABI, &event, "CommitBatch", vlog); err != nil {
|
||||
log.Error("Failed to unpack CommitBatch event", "err", err)
|
||||
log.Warn("Failed to unpack CommitBatch event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
commitTx, isPending, err := client.TransactionByHash(ctx, vlog.TxHash)
|
||||
if err != nil || isPending {
|
||||
log.Error("Failed to get commit batch tx or the tx is still pending", "err", err, "isPending", isPending)
|
||||
log.Warn("Failed to get commit Batch tx receipt or the tx is still pending", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
startBlock, endBlock, err := utils.GetBatchRangeFromCalldata(commitTx.Data())
|
||||
if err != nil {
|
||||
log.Error("Failed to get batch range from calldata", "hash", commitTx.Hash().String(), "height", vlog.BlockNumber)
|
||||
log.Warn("Failed to get batch range from calldata", "hash", commitTx.Hash().String(), "height", vlog.BlockNumber)
|
||||
return nil, err
|
||||
}
|
||||
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
|
||||
@@ -202,7 +190,7 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
|
||||
case backendabi.L1RevertBatchEventSig:
|
||||
event := backendabi.L1RevertBatchEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IScrollChainABI, &event, "RevertBatch", vlog); err != nil {
|
||||
log.Error("Failed to unpack RevertBatch event", "err", err)
|
||||
log.Warn("Failed to unpack RevertBatch event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
|
||||
@@ -214,7 +202,7 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
|
||||
case backendabi.L1FinalizeBatchEventSig:
|
||||
event := backendabi.L1FinalizeBatchEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IScrollChainABI, &event, "FinalizeBatch", vlog); err != nil {
|
||||
log.Error("Failed to unpack FinalizeBatch event", "err", err)
|
||||
log.Warn("Failed to unpack FinalizeBatch event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
l1BatchEvents = append(l1BatchEvents, &orm.BatchEvent{
|
||||
@@ -241,7 +229,7 @@ func (e *L1EventParser) ParseL1MessageQueueEventLogs(logs []types.Log, l1Deposit
|
||||
case backendabi.L1QueueTransactionEventSig:
|
||||
event := backendabi.L1QueueTransactionEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1MessageQueueABI, &event, "QueueTransaction", vlog); err != nil {
|
||||
log.Error("Failed to unpack QueueTransaction event", "err", err)
|
||||
log.Warn("Failed to unpack QueueTransaction event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
messageHash := common.BytesToHash(crypto.Keccak256(event.Data))
|
||||
@@ -257,7 +245,7 @@ func (e *L1EventParser) ParseL1MessageQueueEventLogs(logs []types.Log, l1Deposit
|
||||
case backendabi.L1DequeueTransactionEventSig:
|
||||
event := backendabi.L1DequeueTransactionEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1MessageQueueABI, &event, "DequeueTransaction", vlog); err != nil {
|
||||
log.Error("Failed to unpack DequeueTransaction event", "err", err)
|
||||
log.Warn("Failed to unpack DequeueTransaction event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
skippedIndices := utils.GetSkippedQueueIndices(event.StartIndex.Uint64(), event.SkippedBitmap)
|
||||
@@ -270,7 +258,7 @@ func (e *L1EventParser) ParseL1MessageQueueEventLogs(logs []types.Log, l1Deposit
|
||||
case backendabi.L1DropTransactionEventSig:
|
||||
event := backendabi.L1DropTransactionEvent{}
|
||||
if err := utils.UnpackLog(backendabi.IL1MessageQueueABI, &event, "DropTransaction", vlog); err != nil {
|
||||
log.Error("Failed to unpack DropTransaction event", "err", err)
|
||||
log.Warn("Failed to unpack DropTransaction event", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
l1MessageQueueEvents = append(l1MessageQueueEvents, &orm.MessageQueueEvent{
|
||||
@@ -282,27 +270,3 @@ func (e *L1EventParser) ParseL1MessageQueueEventLogs(logs []types.Log, l1Deposit
|
||||
}
|
||||
return l1MessageQueueEvents, nil
|
||||
}
|
||||
|
||||
func getRealFromAddress(ctx context.Context, eventSender common.Address, client *ethclient.Client, txHash common.Hash, gatewayRouterAddr string) (string, error) {
|
||||
from := eventSender.String()
|
||||
if from == gatewayRouterAddr {
|
||||
tx, isPending, rpcErr := client.TransactionByHash(ctx, txHash)
|
||||
if rpcErr != nil || isPending {
|
||||
log.Error("Failed to get transaction or the transaction is still pending", "rpcErr", rpcErr, "isPending", isPending)
|
||||
return "", rpcErr
|
||||
}
|
||||
// Case 1: deposit/withdraw ETH: EOA -> multisig -> gateway router -> messenger.
|
||||
if tx.To() != nil && (*tx.To()).String() != gatewayRouterAddr {
|
||||
return (*tx.To()).String(), nil
|
||||
}
|
||||
// Case 2: deposit/withdraw ETH: EOA -> gateway router -> messenger.
|
||||
signer := types.LatestSignerForChainID(new(big.Int).SetUint64(tx.ChainId().Uint64()))
|
||||
sender, err := signer.Sender(tx)
|
||||
if err != nil {
|
||||
log.Error("Get sender failed", "chain id", tx.ChainId().Uint64(), "tx hash", tx.Hash().String(), "err", err)
|
||||
return "", err
|
||||
}
|
||||
return sender.String(), nil
|
||||
}
|
||||
return from, nil
|
||||
}
|
||||
|
||||
@@ -34,10 +34,9 @@ type L1FilterResult struct {
|
||||
|
||||
// L1FetcherLogic the L1 fetcher logic
|
||||
type L1FetcherLogic struct {
|
||||
cfg *config.FetcherConfig
|
||||
cfg *config.LayerConfig
|
||||
client *ethclient.Client
|
||||
addressList []common.Address
|
||||
gatewayList []common.Address
|
||||
parser *L1EventParser
|
||||
db *gorm.DB
|
||||
crossMessageOrm *orm.CrossMessage
|
||||
@@ -47,7 +46,7 @@ type L1FetcherLogic struct {
|
||||
}
|
||||
|
||||
// NewL1FetcherLogic creates L1 fetcher logic
|
||||
func NewL1FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient.Client) *L1FetcherLogic {
|
||||
func NewL1FetcherLogic(cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) *L1FetcherLogic {
|
||||
addressList := []common.Address{
|
||||
common.HexToAddress(cfg.ETHGatewayAddr),
|
||||
|
||||
@@ -66,34 +65,16 @@ func NewL1FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient
|
||||
common.HexToAddress(cfg.MessageQueueAddr),
|
||||
}
|
||||
|
||||
gatewayList := []common.Address{
|
||||
common.HexToAddress(cfg.ETHGatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.StandardERC20GatewayAddr),
|
||||
common.HexToAddress(cfg.CustomERC20GatewayAddr),
|
||||
common.HexToAddress(cfg.WETHGatewayAddr),
|
||||
common.HexToAddress(cfg.DAIGatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.ERC721GatewayAddr),
|
||||
common.HexToAddress(cfg.ERC1155GatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.MessengerAddr),
|
||||
|
||||
common.HexToAddress(cfg.GatewayRouterAddr),
|
||||
}
|
||||
|
||||
// Optional erc20 gateways.
|
||||
if common.HexToAddress(cfg.USDCGatewayAddr) != (common.Address{}) {
|
||||
addressList = append(addressList, common.HexToAddress(cfg.USDCGatewayAddr))
|
||||
gatewayList = append(gatewayList, common.HexToAddress(cfg.USDCGatewayAddr))
|
||||
}
|
||||
|
||||
if common.HexToAddress(cfg.LIDOGatewayAddr) != (common.Address{}) {
|
||||
addressList = append(addressList, common.HexToAddress(cfg.LIDOGatewayAddr))
|
||||
gatewayList = append(gatewayList, common.HexToAddress(cfg.LIDOGatewayAddr))
|
||||
}
|
||||
|
||||
log.Info("L1 Fetcher configured with the following address list", "addresses", addressList, "gateways", gatewayList)
|
||||
log.Info("L1 Fetcher configured with the following address list", "addresses", addressList)
|
||||
|
||||
f := &L1FetcherLogic{
|
||||
db: db,
|
||||
@@ -102,8 +83,7 @@ func NewL1FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
addressList: addressList,
|
||||
gatewayList: gatewayList,
|
||||
parser: NewL1EventParser(cfg, client),
|
||||
parser: NewL1EventParser(),
|
||||
}
|
||||
|
||||
reg := prometheus.DefaultRegisterer
|
||||
@@ -151,9 +131,15 @@ func (f *L1FetcherLogic) getRevertedTxs(ctx context.Context, from, to uint64, bl
|
||||
blockTimestampsMap[block.NumberU64()] = block.Time()
|
||||
|
||||
for _, tx := range block.Transactions() {
|
||||
// Gateways: L1 deposit.
|
||||
txTo := tx.To()
|
||||
if txTo == nil {
|
||||
continue
|
||||
}
|
||||
toAddress := txTo.String()
|
||||
|
||||
// GatewayRouter: L1 deposit.
|
||||
// Messenger: L1 deposit retry (replayMessage), L1 deposit refund (dropMessage), L2 withdrawal's claim (relayMessageWithProof).
|
||||
if !isTransactionToGateway(tx, f.gatewayList) {
|
||||
if toAddress != f.cfg.GatewayRouterAddr && toAddress != f.cfg.MessengerAddr {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -247,7 +233,7 @@ func (f *L1FetcherLogic) L1Fetcher(ctx context.Context, from, to uint64, lastBlo
|
||||
return false, 0, common.Hash{}, nil, err
|
||||
}
|
||||
|
||||
l1DepositMessages, l1RelayedMessages, err := f.parser.ParseL1CrossChainEventLogs(ctx, eventLogs, blockTimestampsMap)
|
||||
l1DepositMessages, l1RelayedMessages, err := f.parser.ParseL1CrossChainEventLogs(eventLogs, blockTimestampsMap)
|
||||
if err != nil {
|
||||
log.Error("failed to parse L1 cross chain event logs", "from", from, "to", to, "err", err)
|
||||
return false, 0, common.Hash{}, nil, err
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
backendabi "scroll-tech/bridge-history-api/abi"
|
||||
"scroll-tech/bridge-history-api/internal/config"
|
||||
"scroll-tech/bridge-history-api/internal/orm"
|
||||
"scroll-tech/bridge-history-api/internal/utils"
|
||||
)
|
||||
|
||||
// L2EventParser the L2 event parser
|
||||
type L2EventParser struct {
|
||||
cfg *config.FetcherConfig
|
||||
client *ethclient.Client
|
||||
}
|
||||
|
||||
// NewL2EventParser creates the L2 event parser
|
||||
func NewL2EventParser(cfg *config.FetcherConfig, client *ethclient.Client) *L2EventParser {
|
||||
return &L2EventParser{
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
}
|
||||
func NewL2EventParser() *L2EventParser {
|
||||
return &L2EventParser{}
|
||||
}
|
||||
|
||||
// ParseL2EventLogs parses L2 watched events
|
||||
func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log, blockTimestampsMap map[uint64]uint64) ([]*orm.CrossMessage, []*orm.CrossMessage, error) {
|
||||
func (e *L2EventParser) ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([]*orm.CrossMessage, []*orm.CrossMessage, error) {
|
||||
var l2WithdrawMessages []*orm.CrossMessage
|
||||
var l2RelayedMessages []*orm.CrossMessage
|
||||
for _, vlog := range logs {
|
||||
@@ -38,7 +29,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.ETHMessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ETHGatewayABI, &event, "WithdrawETH", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack WithdrawETH event", "err", err)
|
||||
log.Warn("Failed to unpack WithdrawETH event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -50,7 +41,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.ERC20MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ERC20GatewayABI, &event, "WithdrawERC20", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack WithdrawERC20 event", "err", err)
|
||||
log.Warn("Failed to unpack WithdrawERC20 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -64,7 +55,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.ERC721MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ERC721GatewayABI, &event, "WithdrawERC721", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack WithdrawERC721 event", "err", err)
|
||||
log.Warn("Failed to unpack WithdrawERC721 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -78,7 +69,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.BatchERC721MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ERC721GatewayABI, &event, "BatchWithdrawERC721", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack BatchWithdrawERC721 event", "err", err)
|
||||
log.Warn("Failed to unpack BatchWithdrawERC721 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -92,7 +83,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.ERC1155MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ERC1155GatewayABI, &event, "WithdrawERC1155", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack WithdrawERC1155 event", "err", err)
|
||||
log.Warn("Failed to unpack WithdrawERC1155 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -107,7 +98,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.BatchERC1155MessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ERC1155GatewayABI, &event, "BatchWithdrawERC1155", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack BatchWithdrawERC1155 event", "err", err)
|
||||
log.Warn("Failed to unpack BatchWithdrawERC1155 event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1]
|
||||
@@ -122,17 +113,12 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.L2SentMessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ScrollMessengerABI, &event, "SentMessage", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack SentMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
from, err := getRealFromAddress(ctx, event.Sender, e.client, vlog.TxHash, e.cfg.GatewayRouterAddr)
|
||||
if err != nil {
|
||||
log.Error("Failed to get real 'from' address", "err", err)
|
||||
log.Warn("Failed to unpack SentMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l2WithdrawMessages = append(l2WithdrawMessages, &orm.CrossMessage{
|
||||
MessageHash: utils.ComputeMessageHash(event.Sender, event.Target, event.Value, event.MessageNonce, event.Message).String(),
|
||||
Sender: from,
|
||||
Sender: event.Sender.String(),
|
||||
Receiver: event.Target.String(),
|
||||
TokenType: int(orm.TokenTypeETH),
|
||||
L2TxHash: vlog.TxHash.String(),
|
||||
@@ -151,7 +137,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.L2RelayedMessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ScrollMessengerABI, &event, "RelayedMessage", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack RelayedMessage event", "err", err)
|
||||
log.Warn("Failed to unpack RelayedMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l2RelayedMessages = append(l2RelayedMessages, &orm.CrossMessage{
|
||||
@@ -165,7 +151,7 @@ func (e *L2EventParser) ParseL2EventLogs(ctx context.Context, logs []types.Log,
|
||||
event := backendabi.L2RelayedMessageEvent{}
|
||||
err := utils.UnpackLog(backendabi.IL2ScrollMessengerABI, &event, "FailedRelayedMessage", vlog)
|
||||
if err != nil {
|
||||
log.Error("Failed to unpack FailedRelayedMessage event", "err", err)
|
||||
log.Warn("Failed to unpack FailedRelayedMessage event", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
l2RelayedMessages = append(l2RelayedMessages, &orm.CrossMessage{
|
||||
|
||||
@@ -33,10 +33,9 @@ type L2FilterResult struct {
|
||||
|
||||
// L2FetcherLogic the L2 fetcher logic
|
||||
type L2FetcherLogic struct {
|
||||
cfg *config.FetcherConfig
|
||||
cfg *config.LayerConfig
|
||||
client *ethclient.Client
|
||||
addressList []common.Address
|
||||
gatewayList []common.Address
|
||||
parser *L2EventParser
|
||||
db *gorm.DB
|
||||
crossMessageOrm *orm.CrossMessage
|
||||
@@ -46,7 +45,7 @@ type L2FetcherLogic struct {
|
||||
}
|
||||
|
||||
// NewL2FetcherLogic create L2 fetcher logic
|
||||
func NewL2FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient.Client) *L2FetcherLogic {
|
||||
func NewL2FetcherLogic(cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) *L2FetcherLogic {
|
||||
addressList := []common.Address{
|
||||
common.HexToAddress(cfg.ETHGatewayAddr),
|
||||
|
||||
@@ -61,34 +60,16 @@ func NewL2FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient
|
||||
common.HexToAddress(cfg.MessengerAddr),
|
||||
}
|
||||
|
||||
gatewayList := []common.Address{
|
||||
common.HexToAddress(cfg.ETHGatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.StandardERC20GatewayAddr),
|
||||
common.HexToAddress(cfg.CustomERC20GatewayAddr),
|
||||
common.HexToAddress(cfg.WETHGatewayAddr),
|
||||
common.HexToAddress(cfg.DAIGatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.ERC721GatewayAddr),
|
||||
common.HexToAddress(cfg.ERC1155GatewayAddr),
|
||||
|
||||
common.HexToAddress(cfg.MessengerAddr),
|
||||
|
||||
common.HexToAddress(cfg.GatewayRouterAddr),
|
||||
}
|
||||
|
||||
// Optional erc20 gateways.
|
||||
if common.HexToAddress(cfg.USDCGatewayAddr) != (common.Address{}) {
|
||||
addressList = append(addressList, common.HexToAddress(cfg.USDCGatewayAddr))
|
||||
gatewayList = append(gatewayList, common.HexToAddress(cfg.USDCGatewayAddr))
|
||||
}
|
||||
|
||||
if common.HexToAddress(cfg.LIDOGatewayAddr) != (common.Address{}) {
|
||||
addressList = append(addressList, common.HexToAddress(cfg.LIDOGatewayAddr))
|
||||
gatewayList = append(gatewayList, common.HexToAddress(cfg.USDCGatewayAddr))
|
||||
}
|
||||
|
||||
log.Info("L2 Fetcher configured with the following address list", "addresses", addressList, "gateways", gatewayList)
|
||||
log.Info("L2 Fetcher configured with the following address list", "addresses", addressList)
|
||||
|
||||
f := &L2FetcherLogic{
|
||||
db: db,
|
||||
@@ -97,8 +78,7 @@ func NewL2FetcherLogic(cfg *config.FetcherConfig, db *gorm.DB, client *ethclient
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
addressList: addressList,
|
||||
gatewayList: gatewayList,
|
||||
parser: NewL2EventParser(cfg, client),
|
||||
parser: NewL2EventParser(),
|
||||
}
|
||||
|
||||
reg := prometheus.DefaultRegisterer
|
||||
@@ -147,7 +127,42 @@ func (f *L2FetcherLogic) getRevertedTxs(ctx context.Context, from, to uint64, bl
|
||||
blockTimestampsMap[block.NumberU64()] = block.Time()
|
||||
|
||||
for _, tx := range block.Transactions() {
|
||||
if tx.IsL1MessageTx() {
|
||||
txTo := tx.To()
|
||||
if txTo == nil {
|
||||
continue
|
||||
}
|
||||
toAddress := txTo.String()
|
||||
|
||||
// GatewayRouter: L2 withdrawal.
|
||||
if toAddress == f.cfg.GatewayRouterAddr {
|
||||
receipt, receiptErr := f.client.TransactionReceipt(ctx, tx.Hash())
|
||||
if receiptErr != nil {
|
||||
log.Error("Failed to get transaction receipt", "txHash", tx.Hash().String(), "err", receiptErr)
|
||||
return nil, nil, nil, receiptErr
|
||||
}
|
||||
|
||||
// Check if the transaction is failed
|
||||
if receipt.Status == types.ReceiptStatusFailed {
|
||||
signer := types.LatestSignerForChainID(new(big.Int).SetUint64(tx.ChainId().Uint64()))
|
||||
sender, signerErr := signer.Sender(tx)
|
||||
if signerErr != nil {
|
||||
log.Error("get sender failed", "chain id", tx.ChainId().Uint64(), "tx hash", tx.Hash().String(), "err", signerErr)
|
||||
return nil, nil, nil, signerErr
|
||||
}
|
||||
|
||||
l2RevertedUserTxs = append(l2RevertedUserTxs, &orm.CrossMessage{
|
||||
L2TxHash: tx.Hash().String(),
|
||||
MessageType: int(orm.MessageTypeL2SentMessage),
|
||||
Sender: sender.String(),
|
||||
Receiver: (*tx.To()).String(),
|
||||
L2BlockNumber: receipt.BlockNumber.Uint64(),
|
||||
BlockTimestamp: block.Time(),
|
||||
TxStatus: int(orm.TxStatusTypeSentTxReverted),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if tx.Type() == types.L1MessageTxType {
|
||||
receipt, receiptErr := f.client.TransactionReceipt(ctx, tx.Hash())
|
||||
if receiptErr != nil {
|
||||
log.Error("Failed to get transaction receipt", "txHash", tx.Hash().String(), "err", receiptErr)
|
||||
@@ -164,38 +179,6 @@ func (f *L2FetcherLogic) getRevertedTxs(ctx context.Context, from, to uint64, bl
|
||||
MessageType: int(orm.MessageTypeL1SentMessage),
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Gateways: L2 withdrawal.
|
||||
if !isTransactionToGateway(tx, f.gatewayList) {
|
||||
continue
|
||||
}
|
||||
|
||||
receipt, receiptErr := f.client.TransactionReceipt(ctx, tx.Hash())
|
||||
if receiptErr != nil {
|
||||
log.Error("Failed to get transaction receipt", "txHash", tx.Hash().String(), "err", receiptErr)
|
||||
return nil, nil, nil, receiptErr
|
||||
}
|
||||
|
||||
// Check if the transaction is failed
|
||||
if receipt.Status == types.ReceiptStatusFailed {
|
||||
signer := types.LatestSignerForChainID(new(big.Int).SetUint64(tx.ChainId().Uint64()))
|
||||
sender, signerErr := signer.Sender(tx)
|
||||
if signerErr != nil {
|
||||
log.Error("get sender failed", "chain id", tx.ChainId().Uint64(), "tx hash", tx.Hash().String(), "err", signerErr)
|
||||
return nil, nil, nil, signerErr
|
||||
}
|
||||
|
||||
l2RevertedUserTxs = append(l2RevertedUserTxs, &orm.CrossMessage{
|
||||
L2TxHash: tx.Hash().String(),
|
||||
MessageType: int(orm.MessageTypeL2SentMessage),
|
||||
Sender: sender.String(),
|
||||
Receiver: (*tx.To()).String(),
|
||||
L2BlockNumber: receipt.BlockNumber.Uint64(),
|
||||
BlockTimestamp: block.Time(),
|
||||
TxStatus: int(orm.TxStatusTypeSentTxReverted),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,7 +235,7 @@ func (f *L2FetcherLogic) L2Fetcher(ctx context.Context, from, to uint64, lastBlo
|
||||
return false, 0, common.Hash{}, nil, err
|
||||
}
|
||||
|
||||
l2WithdrawMessages, l2RelayedMessages, err := f.parser.ParseL2EventLogs(ctx, eventLogs, blockTimestampsMap)
|
||||
l2WithdrawMessages, l2RelayedMessages, err := f.parser.ParseL2EventLogs(eventLogs, blockTimestampsMap)
|
||||
if err != nil {
|
||||
log.Error("failed to parse L2 event logs", "from", from, "to", to, "err", err)
|
||||
return false, 0, common.Hash{}, nil, err
|
||||
@@ -296,15 +279,3 @@ func (f *L2FetcherLogic) updateMetrics(res L2FilterResult) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isTransactionToGateway(tx *types.Transaction, gatewayList []common.Address) bool {
|
||||
if tx.To() == nil {
|
||||
return false
|
||||
}
|
||||
for _, gateway := range gatewayList {
|
||||
if *tx.To() == gateway {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// BatchStatusType represents the type of batch status.
|
||||
@@ -90,21 +89,19 @@ func (c *BatchEvent) GetFinalizedBatchesLEBlockHeight(ctx context.Context, block
|
||||
}
|
||||
|
||||
// InsertOrUpdateBatchEvents inserts a new batch event or updates an existing one based on the BatchStatusType.
|
||||
func (c *BatchEvent) InsertOrUpdateBatchEvents(ctx context.Context, l1BatchEvents []*BatchEvent) error {
|
||||
func (c *BatchEvent) InsertOrUpdateBatchEvents(ctx context.Context, l1BatchEvents []*BatchEvent, dbTX ...*gorm.DB) error {
|
||||
for _, l1BatchEvent := range l1BatchEvents {
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&BatchEvent{})
|
||||
updateFields := make(map[string]interface{})
|
||||
switch BatchStatusType(l1BatchEvent.BatchStatus) {
|
||||
case BatchStatusTypeCommitted:
|
||||
// Use the clause to either insert or ignore on conflict
|
||||
db = db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "batch_hash"}},
|
||||
DoNothing: true,
|
||||
})
|
||||
if err := db.Create(l1BatchEvent).Error; err != nil {
|
||||
return fmt.Errorf("failed to insert or ignore batch event, error: %w", err)
|
||||
return fmt.Errorf("failed to insert batch event, error: %w", err)
|
||||
}
|
||||
case BatchStatusTypeFinalized:
|
||||
db = db.Where("batch_index = ?", l1BatchEvent.BatchIndex)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
@@ -46,9 +47,9 @@ const (
|
||||
TxStatusTypeSent TxStatusType = iota
|
||||
TxStatusTypeSentTxReverted // Not track message hash, thus will not be processed again anymore.
|
||||
TxStatusTypeRelayed // Terminal status.
|
||||
// Retry: this often occurs due to an out of gas (OOG) issue if the transaction was initiated via the frontend.
|
||||
TxStatusTypeFailedRelayed
|
||||
// Retry: this often occurs due to an out of gas (OOG) issue if the transaction was initiated via the frontend.
|
||||
// FailedRelayedMessage event: encoded tx failed, cannot retry. e.g., https://sepolia.scrollscan.com/tx/0xfc7d3ea5ec8dc9b664a5a886c3b33d21e665355057601033481a439498efb79a
|
||||
TxStatusTypeFailedRelayed // Terminal status.
|
||||
// In some cases, user can retry with a larger gas limit. e.g., https://sepolia.scrollscan.com/tx/0x7323a7ba29492cb47d92206411be99b27896f2823cee0633a596b646b73f1b5b
|
||||
TxStatusTypeRelayTxReverted
|
||||
TxStatusTypeSkipped
|
||||
TxStatusTypeDropped // Terminal status.
|
||||
@@ -253,27 +254,38 @@ func (c *CrossMessage) GetTxsByAddress(ctx context.Context, sender string) ([]*C
|
||||
}
|
||||
|
||||
// UpdateL1MessageQueueEventsInfo updates the information about L1 message queue events in the database.
|
||||
func (c *CrossMessage) UpdateL1MessageQueueEventsInfo(ctx context.Context, l1MessageQueueEvents []*MessageQueueEvent) error {
|
||||
func (c *CrossMessage) UpdateL1MessageQueueEventsInfo(ctx context.Context, l1MessageQueueEvents []*MessageQueueEvent, dbTX ...*gorm.DB) error {
|
||||
// update tx statuses.
|
||||
for _, l1MessageQueueEvent := range l1MessageQueueEvents {
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
// do not over-write terminal statuses.
|
||||
db = db.Where("tx_status != ?", TxStatusTypeRelayed)
|
||||
db = db.Where("tx_status != ?", TxStatusTypeFailedRelayed)
|
||||
db = db.Where("tx_status != ?", TxStatusTypeDropped)
|
||||
txStatusUpdateFields := make(map[string]interface{})
|
||||
switch l1MessageQueueEvent.EventType {
|
||||
case MessageQueueEventTypeQueueTransaction:
|
||||
continue
|
||||
// only replayMessages or enforced txs (whose message hashes would not be found), sentMessages have been filtered out.
|
||||
// replayMessage case:
|
||||
// First SentMessage in L1: https://sepolia.etherscan.io/tx/0xbee4b631312448fcc2caac86e4dccf0a2ae0a88acd6c5fd8764d39d746e472eb
|
||||
// Transaction reverted in L2: https://sepolia.scrollscan.com/tx/0xde6ef307a7da255888aad7a4c40a6b8c886e46a8a05883070bbf18b736cbfb8c
|
||||
// replayMessage: https://sepolia.etherscan.io/tx/0xa5392891232bb32d98fcdbaca0d91b4d22ef2755380d07d982eebd47b147ce28
|
||||
//
|
||||
// Note: update l1_tx_hash if the user calls replayMessage, cannot use queue index here,
|
||||
// because in replayMessage, queue index != message nonce.
|
||||
// Ref: https://github.com/scroll-tech/scroll/blob/v4.3.44/contracts/src/L1/L1ScrollMessenger.sol#L187-L190
|
||||
db = db.Where("message_hash = ?", l1MessageQueueEvent.MessageHash.String())
|
||||
txStatusUpdateFields["tx_status"] = TxStatusTypeSent // reset status to "sent".
|
||||
case MessageQueueEventTypeDequeueTransaction:
|
||||
// do not over-write terminal statuses.
|
||||
db = db.Where("tx_status != ?", TxStatusTypeRelayed)
|
||||
db = db.Where("tx_status != ?", TxStatusTypeDropped)
|
||||
db = db.Where("message_nonce = ?", l1MessageQueueEvent.QueueIndex)
|
||||
db = db.Where("message_type = ?", MessageTypeL1SentMessage)
|
||||
txStatusUpdateFields["tx_status"] = TxStatusTypeSkipped
|
||||
case MessageQueueEventTypeDropTransaction:
|
||||
// do not over-write terminal statuses.
|
||||
db = db.Where("tx_status != ?", TxStatusTypeRelayed)
|
||||
db = db.Where("tx_status != ?", TxStatusTypeDropped)
|
||||
db = db.Where("message_nonce = ?", l1MessageQueueEvent.QueueIndex)
|
||||
db = db.Where("message_type = ?", MessageTypeL1SentMessage)
|
||||
txStatusUpdateFields["tx_status"] = TxStatusTypeDropped
|
||||
@@ -286,22 +298,15 @@ func (c *CrossMessage) UpdateL1MessageQueueEventsInfo(ctx context.Context, l1Mes
|
||||
// update tx hashes of replay and refund.
|
||||
for _, l1MessageQueueEvent := range l1MessageQueueEvents {
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
txHashUpdateFields := make(map[string]interface{})
|
||||
switch l1MessageQueueEvent.EventType {
|
||||
case MessageQueueEventTypeDequeueTransaction:
|
||||
continue
|
||||
case MessageQueueEventTypeQueueTransaction:
|
||||
// only replayMessages or enforced txs (whose message hashes would not be found), sendMessages have been filtered out.
|
||||
// replayMessage case:
|
||||
// First SentMessage in L1: https://sepolia.etherscan.io/tx/0xbee4b631312448fcc2caac86e4dccf0a2ae0a88acd6c5fd8764d39d746e472eb
|
||||
// Transaction reverted in L2: https://sepolia.scrollscan.com/tx/0xde6ef307a7da255888aad7a4c40a6b8c886e46a8a05883070bbf18b736cbfb8c
|
||||
// replayMessage: https://sepolia.etherscan.io/tx/0xa5392891232bb32d98fcdbaca0d91b4d22ef2755380d07d982eebd47b147ce28
|
||||
//
|
||||
// Note: update l1_tx_hash if the user calls replayMessage, cannot use queue index here,
|
||||
// because in replayMessage, queue index != message nonce.
|
||||
// Ref: https://github.com/scroll-tech/scroll/blob/v4.3.44/contracts/src/L1/L1ScrollMessenger.sol#L187-L190
|
||||
// only replayMessages or enforced txs (whose message hashes would not be found), sentMessages have been filtered out.
|
||||
db = db.Where("message_hash = ?", l1MessageQueueEvent.MessageHash.String())
|
||||
txHashUpdateFields["l1_replay_tx_hash"] = l1MessageQueueEvent.TxHash.String()
|
||||
case MessageQueueEventTypeDropTransaction:
|
||||
@@ -309,8 +314,11 @@ func (c *CrossMessage) UpdateL1MessageQueueEventsInfo(ctx context.Context, l1Mes
|
||||
db = db.Where("message_type = ?", MessageTypeL1SentMessage)
|
||||
txHashUpdateFields["l1_refund_tx_hash"] = l1MessageQueueEvent.TxHash.String()
|
||||
}
|
||||
if err := db.Updates(txHashUpdateFields).Error; err != nil {
|
||||
return fmt.Errorf("failed to update tx hashes of replay and refund in L1 message queue events info, update fields: %v, error: %w", txHashUpdateFields, err)
|
||||
// Check if there are fields to update to avoid empty update operation (skip message).
|
||||
if len(txHashUpdateFields) > 0 {
|
||||
if err := db.Updates(txHashUpdateFields).Error; err != nil {
|
||||
return fmt.Errorf("failed to update tx hashes of replay and refund in L1 message queue events info, update fields: %v, error: %w", txHashUpdateFields, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -354,11 +362,14 @@ func (c *CrossMessage) UpdateBatchIndexRollupStatusMerkleProofOfL2Messages(ctx c
|
||||
}
|
||||
|
||||
// InsertOrUpdateL1Messages inserts or updates a list of L1 cross messages into the database.
|
||||
func (c *CrossMessage) InsertOrUpdateL1Messages(ctx context.Context, messages []*CrossMessage) error {
|
||||
func (c *CrossMessage) InsertOrUpdateL1Messages(ctx context.Context, messages []*CrossMessage, dbTX ...*gorm.DB) error {
|
||||
if len(messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
// 'tx_status' column is not explicitly assigned during the update to prevent a later status from being overwritten back to "sent".
|
||||
@@ -373,14 +384,18 @@ func (c *CrossMessage) InsertOrUpdateL1Messages(ctx context.Context, messages []
|
||||
}
|
||||
|
||||
// InsertOrUpdateL2Messages inserts or updates a list of L2 cross messages into the database.
|
||||
func (c *CrossMessage) InsertOrUpdateL2Messages(ctx context.Context, messages []*CrossMessage) error {
|
||||
func (c *CrossMessage) InsertOrUpdateL2Messages(ctx context.Context, messages []*CrossMessage, dbTX ...*gorm.DB) error {
|
||||
if len(messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
// 'tx_status' column is not explicitly assigned during the update to prevent a later status from being overwritten back to "sent".
|
||||
// The merkle_proof is updated separately in batch status updates and hence is not included here.
|
||||
db = db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "message_hash"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"sender", "receiver", "token_type", "l2_block_number", "l2_tx_hash", "l1_token_address", "l2_token_address", "token_ids", "token_amounts", "message_type", "block_timestamp", "message_from", "message_to", "message_value", "message_data", "message_nonce"}),
|
||||
@@ -391,60 +406,31 @@ func (c *CrossMessage) InsertOrUpdateL2Messages(ctx context.Context, messages []
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertFailedL2GatewayTxs inserts a list of transactions that failed to interact with the L2 gateways into the database.
|
||||
// To resolve unique index confliction, L2 tx hash is used as the MessageHash.
|
||||
// The OnConflict clause is used to prevent inserting same failed transactions multiple times.
|
||||
func (c *CrossMessage) InsertFailedL2GatewayTxs(ctx context.Context, messages []*CrossMessage) error {
|
||||
// InsertFailedGatewayRouterTxs inserts a list of transactions that failed to interact with the gateway router into the database.
|
||||
// These failed transactions are only fetched once, so they are inserted without checking for duplicates.
|
||||
// To resolve unique index confliction, a random UUID will be generated and used as the MessageHash.
|
||||
func (c *CrossMessage) InsertFailedGatewayRouterTxs(ctx context.Context, messages []*CrossMessage, dbTX ...*gorm.DB) error {
|
||||
if len(messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, message := range messages {
|
||||
message.MessageHash = message.L2TxHash
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
|
||||
db := c.db
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
db = db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "message_hash"}},
|
||||
DoNothing: true,
|
||||
})
|
||||
|
||||
if err := db.Create(&messages).Error; err != nil {
|
||||
return fmt.Errorf("failed to insert failed gateway router txs, error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertFailedL1GatewayTxs inserts a list of transactions that failed to interact with the L1 gateways into the database.
|
||||
// To resolve unique index confliction, L1 tx hash is used as the MessageHash.
|
||||
// The OnConflict clause is used to prevent inserting same failed transactions multiple times.
|
||||
func (c *CrossMessage) InsertFailedL1GatewayTxs(ctx context.Context, messages []*CrossMessage) error {
|
||||
if len(messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, message := range messages {
|
||||
message.MessageHash = message.L1TxHash
|
||||
message.MessageHash = uuid.New().String()
|
||||
}
|
||||
|
||||
db := c.db
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
db = db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "message_hash"}},
|
||||
DoNothing: true,
|
||||
})
|
||||
|
||||
if err := db.Create(&messages).Error; err != nil {
|
||||
if err := db.Create(messages).Error; err != nil {
|
||||
return fmt.Errorf("failed to insert failed gateway router txs, error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertOrUpdateL2RelayedMessagesOfL1Deposits inserts or updates the database with a list of L2 relayed messages related to L1 deposits.
|
||||
func (c *CrossMessage) InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx context.Context, l2RelayedMessages []*CrossMessage) error {
|
||||
func (c *CrossMessage) InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx context.Context, l2RelayedMessages []*CrossMessage, dbTX ...*gorm.DB) error {
|
||||
if len(l2RelayedMessages) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -473,7 +459,7 @@ func (c *CrossMessage) InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx context.C
|
||||
for _, msg := range mergedL2RelayedMessages {
|
||||
uniqueL2RelayedMessages = append(uniqueL2RelayedMessages, msg)
|
||||
}
|
||||
// Do not update tx status of successfully relayed messages,
|
||||
// Do not update tx status of successfully or failed relayed messages,
|
||||
// because if a message is handled, the later relayed message tx would be reverted.
|
||||
// ref: https://github.com/scroll-tech/scroll/blob/v4.3.44/contracts/src/L2/L2ScrollMessenger.sol#L102
|
||||
// e.g.,
|
||||
@@ -490,6 +476,7 @@ func (c *CrossMessage) InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx context.C
|
||||
clause.And(
|
||||
// do not over-write terminal statuses.
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeRelayed},
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeFailedRelayed},
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeDropped},
|
||||
),
|
||||
},
|
||||
@@ -502,7 +489,7 @@ func (c *CrossMessage) InsertOrUpdateL2RelayedMessagesOfL1Deposits(ctx context.C
|
||||
}
|
||||
|
||||
// InsertOrUpdateL1RelayedMessagesOfL2Withdrawals inserts or updates the database with a list of L1 relayed messages related to L2 withdrawals.
|
||||
func (c *CrossMessage) InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx context.Context, l1RelayedMessages []*CrossMessage) error {
|
||||
func (c *CrossMessage) InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx context.Context, l1RelayedMessages []*CrossMessage, dbTX ...*gorm.DB) error {
|
||||
if len(l1RelayedMessages) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -532,6 +519,9 @@ func (c *CrossMessage) InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx contex
|
||||
uniqueL1RelayedMessages = append(uniqueL1RelayedMessages, msg)
|
||||
}
|
||||
db := c.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&CrossMessage{})
|
||||
db = db.Clauses(clause.OnConflict{
|
||||
@@ -542,6 +532,7 @@ func (c *CrossMessage) InsertOrUpdateL1RelayedMessagesOfL2Withdrawals(ctx contex
|
||||
clause.And(
|
||||
// do not over-write terminal statuses.
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeRelayed},
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeFailedRelayed},
|
||||
clause.Neq{Column: "cross_message_v2.tx_status", Value: TxStatusTypeDropped},
|
||||
),
|
||||
},
|
||||
|
||||
@@ -15,7 +15,6 @@ CREATE TABLE batch_event_v2
|
||||
deleted_at TIMESTAMP(0) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS unique_idx_be_batch_hash ON batch_event_v2 (batch_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_be_l1_block_number ON batch_event_v2 (l1_block_number);
|
||||
CREATE INDEX IF NOT EXISTS idx_be_batch_index ON batch_event_v2 (batch_index);
|
||||
CREATE INDEX IF NOT EXISTS idx_be_batch_index_batch_hash ON batch_event_v2 (batch_index, batch_hash);
|
||||
|
||||
@@ -21,8 +21,8 @@ const (
|
||||
// GasOracleImported represents the gas oracle status is imported
|
||||
GasOracleImported
|
||||
|
||||
// GasOracleImportedFailed represents the gas oracle status is imported failed
|
||||
GasOracleImportedFailed
|
||||
// GasOracleFailed represents the gas oracle status is failed
|
||||
GasOracleFailed
|
||||
)
|
||||
|
||||
func (s GasOracleStatus) String() string {
|
||||
@@ -35,10 +35,10 @@ func (s GasOracleStatus) String() string {
|
||||
return "GasOracleImporting"
|
||||
case GasOracleImported:
|
||||
return "GasOracleImported"
|
||||
case GasOracleImportedFailed:
|
||||
return "GasOracleImportedFailed"
|
||||
case GasOracleFailed:
|
||||
return "GasOracleFailed"
|
||||
default:
|
||||
return fmt.Sprintf("Undefined GasOracleStatus (%d)", int32(s))
|
||||
return fmt.Sprintf("Undefined (%d)", int32(s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (ps ProvingStatus) String() string {
|
||||
case ProvingTaskFailed:
|
||||
return "failed"
|
||||
default:
|
||||
return fmt.Sprintf("Undefined ProvingStatus (%d)", int32(ps))
|
||||
return fmt.Sprintf("Undefined (%d)", int32(ps))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func (s ChunkProofsStatus) String() string {
|
||||
case ChunkProofsStatusReady:
|
||||
return "ChunkProofsStatusReady"
|
||||
default:
|
||||
return fmt.Sprintf("Undefined ChunkProofsStatus (%d)", int32(s))
|
||||
return fmt.Sprintf("Undefined (%d)", int32(s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,69 +227,6 @@ func (s RollupStatus) String() string {
|
||||
case RollupFinalizeFailed:
|
||||
return "RollupFinalizeFailed"
|
||||
default:
|
||||
return fmt.Sprintf("Undefined RollupStatus (%d)", int32(s))
|
||||
}
|
||||
}
|
||||
|
||||
// SenderType defines the various types of senders sending the transactions.
|
||||
type SenderType int
|
||||
|
||||
const (
|
||||
// SenderTypeUnknown indicates an unknown sender type.
|
||||
SenderTypeUnknown SenderType = iota
|
||||
// SenderTypeCommitBatch indicates the sender is responsible for committing batches.
|
||||
SenderTypeCommitBatch
|
||||
// SenderTypeFinalizeBatch indicates the sender is responsible for finalizing batches.
|
||||
SenderTypeFinalizeBatch
|
||||
// SenderTypeL1GasOracle indicates a sender from L2 responsible for updating L1 gas prices.
|
||||
SenderTypeL1GasOracle
|
||||
// SenderTypeL2GasOracle indicates a sender from L1 responsible for updating L2 gas prices.
|
||||
SenderTypeL2GasOracle
|
||||
)
|
||||
|
||||
// String returns a string representation of the SenderType.
|
||||
func (t SenderType) String() string {
|
||||
switch t {
|
||||
case SenderTypeCommitBatch:
|
||||
return "SenderTypeCommitBatch"
|
||||
case SenderTypeFinalizeBatch:
|
||||
return "SenderTypeFinalizeBatch"
|
||||
case SenderTypeL1GasOracle:
|
||||
return "SenderTypeL1GasOracle"
|
||||
case SenderTypeL2GasOracle:
|
||||
return "SenderTypeL2GasOracle"
|
||||
default:
|
||||
return fmt.Sprintf("Unknown SenderType (%d)", int32(t))
|
||||
}
|
||||
}
|
||||
|
||||
// TxStatus represents the current status of a transaction in the transaction lifecycle.
|
||||
type TxStatus int
|
||||
|
||||
const (
|
||||
// TxStatusUnknown represents an undefined status of the transaction.
|
||||
TxStatusUnknown TxStatus = iota
|
||||
// TxStatusPending indicates that the transaction is yet to be processed.
|
||||
TxStatusPending
|
||||
// TxStatusReplaced indicates that the transaction has been replaced by another one, typically due to a higher gas price.
|
||||
TxStatusReplaced
|
||||
// TxStatusConfirmed indicates that the transaction has been successfully processed and confirmed.
|
||||
TxStatusConfirmed
|
||||
// TxStatusConfirmedFailed indicates that the transaction has failed during processing.
|
||||
TxStatusConfirmedFailed
|
||||
)
|
||||
|
||||
func (s TxStatus) String() string {
|
||||
switch s {
|
||||
case TxStatusPending:
|
||||
return "TxStatusPending"
|
||||
case TxStatusReplaced:
|
||||
return "TxStatusReplaced"
|
||||
case TxStatusConfirmed:
|
||||
return "TxStatusConfirmed"
|
||||
case TxStatusConfirmedFailed:
|
||||
return "TxStatusConfirmedFailed"
|
||||
default:
|
||||
return fmt.Sprintf("Unknown TxStatus (%d)", int32(s))
|
||||
return fmt.Sprintf("Undefined (%d)", int32(s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func TestProvingStatus(t *testing.T) {
|
||||
{
|
||||
"Undefined",
|
||||
ProvingStatus(999), // Invalid value.
|
||||
"Undefined ProvingStatus (999)",
|
||||
"Undefined (999)",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -85,243 +85,3 @@ func TestProvingStatus(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRollupStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
s RollupStatus
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"RollupUndefined",
|
||||
RollupUndefined,
|
||||
"Undefined RollupStatus (0)",
|
||||
},
|
||||
{
|
||||
"RollupPending",
|
||||
RollupPending,
|
||||
"RollupPending",
|
||||
},
|
||||
{
|
||||
"RollupCommitting",
|
||||
RollupCommitting,
|
||||
"RollupCommitting",
|
||||
},
|
||||
{
|
||||
"RollupCommitted",
|
||||
RollupCommitted,
|
||||
"RollupCommitted",
|
||||
},
|
||||
{
|
||||
"RollupFinalizing",
|
||||
RollupFinalizing,
|
||||
"RollupFinalizing",
|
||||
},
|
||||
{
|
||||
"RollupFinalized",
|
||||
RollupFinalized,
|
||||
"RollupFinalized",
|
||||
},
|
||||
{
|
||||
"RollupCommitFailed",
|
||||
RollupCommitFailed,
|
||||
"RollupCommitFailed",
|
||||
},
|
||||
{
|
||||
"RollupFinalizeFailed",
|
||||
RollupFinalizeFailed,
|
||||
"RollupFinalizeFailed",
|
||||
},
|
||||
{
|
||||
"Invalid Value",
|
||||
RollupStatus(999),
|
||||
"Undefined RollupStatus (999)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, tt.s.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSenderType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
t SenderType
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"SenderTypeUnknown",
|
||||
SenderTypeUnknown,
|
||||
"Unknown SenderType (0)",
|
||||
},
|
||||
{
|
||||
"SenderTypeCommitBatch",
|
||||
SenderTypeCommitBatch,
|
||||
"SenderTypeCommitBatch",
|
||||
},
|
||||
{
|
||||
"SenderTypeFinalizeBatch",
|
||||
SenderTypeFinalizeBatch,
|
||||
"SenderTypeFinalizeBatch",
|
||||
},
|
||||
{
|
||||
"SenderTypeL1GasOracle",
|
||||
SenderTypeL1GasOracle,
|
||||
"SenderTypeL1GasOracle",
|
||||
},
|
||||
{
|
||||
"SenderTypeL2GasOracle",
|
||||
SenderTypeL2GasOracle,
|
||||
"SenderTypeL2GasOracle",
|
||||
},
|
||||
{
|
||||
"Invalid Value",
|
||||
SenderType(999),
|
||||
"Unknown SenderType (999)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, tt.t.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
s TxStatus
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"TxStatusUnknown",
|
||||
TxStatusUnknown,
|
||||
"Unknown TxStatus (0)",
|
||||
},
|
||||
{
|
||||
"TxStatusPending",
|
||||
TxStatusPending,
|
||||
"TxStatusPending",
|
||||
},
|
||||
{
|
||||
"TxStatusReplaced",
|
||||
TxStatusReplaced,
|
||||
"TxStatusReplaced",
|
||||
},
|
||||
{
|
||||
"TxStatusConfirmed",
|
||||
TxStatusConfirmed,
|
||||
"TxStatusConfirmed",
|
||||
},
|
||||
{
|
||||
"TxStatusConfirmedFailed",
|
||||
TxStatusConfirmedFailed,
|
||||
"TxStatusConfirmedFailed",
|
||||
},
|
||||
{
|
||||
"Invalid Value",
|
||||
TxStatus(999),
|
||||
"Unknown TxStatus (999)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, tt.s.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGasOracleStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
s GasOracleStatus
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"GasOracleUndefined",
|
||||
GasOracleUndefined,
|
||||
"GasOracleUndefined",
|
||||
},
|
||||
{
|
||||
"GasOraclePending",
|
||||
GasOraclePending,
|
||||
"GasOraclePending",
|
||||
},
|
||||
{
|
||||
"GasOracleImporting",
|
||||
GasOracleImporting,
|
||||
"GasOracleImporting",
|
||||
},
|
||||
{
|
||||
"GasOracleImported",
|
||||
GasOracleImported,
|
||||
"GasOracleImported",
|
||||
},
|
||||
{
|
||||
"GasOracleImportedFailed",
|
||||
GasOracleImportedFailed,
|
||||
"GasOracleImportedFailed",
|
||||
},
|
||||
{
|
||||
"Invalid Value",
|
||||
GasOracleStatus(999),
|
||||
"Undefined GasOracleStatus (999)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, tt.s.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProverTaskFailureType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
r ProverTaskFailureType
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"ProverTaskFailureTypeUndefined",
|
||||
ProverTaskFailureTypeUndefined,
|
||||
"prover task failure undefined",
|
||||
},
|
||||
{
|
||||
"ProverTaskFailureTypeTimeout",
|
||||
ProverTaskFailureTypeTimeout,
|
||||
"prover task failure timeout",
|
||||
},
|
||||
{
|
||||
"ProverTaskFailureTypeSubmitStatusNotOk",
|
||||
ProverTaskFailureTypeSubmitStatusNotOk,
|
||||
"prover task failure validated submit proof status not ok",
|
||||
},
|
||||
{
|
||||
"ProverTaskFailureTypeVerifiedFailed",
|
||||
ProverTaskFailureTypeVerifiedFailed,
|
||||
"prover task failure verified failed",
|
||||
},
|
||||
{
|
||||
"ProverTaskFailureTypeServerError",
|
||||
ProverTaskFailureTypeServerError,
|
||||
"prover task failure server exception",
|
||||
},
|
||||
{
|
||||
"Invalid Value",
|
||||
ProverTaskFailureType(999),
|
||||
"illegal prover task failure type (999)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, tt.r.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var tag = "v4.3.61"
|
||||
var tag = "v4.3.54"
|
||||
|
||||
var commit = func() string {
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
|
||||
2
contracts/circomlib.d.ts
vendored
2
contracts/circomlib.d.ts
vendored
@@ -1,3 +1 @@
|
||||
declare module "circomlib/src/evmasm";
|
||||
declare module "circomlib/src/poseidon_gencontract";
|
||||
declare module "circomlib/src/poseidon_constants";
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/* eslint-disable node/no-missing-import */
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import { expect } from "chai";
|
||||
import { randomBytes } from "crypto";
|
||||
import { BigNumber, Contract } from "ethers";
|
||||
import { ethers } from "hardhat";
|
||||
import fs from "fs";
|
||||
|
||||
import PoseidonWithoutDomain from "circomlib/src/poseidon_gencontract";
|
||||
import { generateABI, createCode } from "../scripts/poseidon";
|
||||
|
||||
describe("PoseidonHash.spec", async () => {
|
||||
// test against with circomlib's implementation.
|
||||
context("domain = zero", async () => {
|
||||
let poseidonCircom: Contract;
|
||||
let poseidon: Contract;
|
||||
|
||||
beforeEach(async () => {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
|
||||
const PoseidonWithoutDomainFactory = new ethers.ContractFactory(
|
||||
PoseidonWithoutDomain.generateABI(2),
|
||||
PoseidonWithoutDomain.createCode(2),
|
||||
deployer
|
||||
);
|
||||
poseidonCircom = await PoseidonWithoutDomainFactory.deploy();
|
||||
await poseidonCircom.deployed();
|
||||
|
||||
const PoseidonWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer);
|
||||
poseidon = await PoseidonWithDomainFactory.deploy();
|
||||
await poseidon.deployed();
|
||||
});
|
||||
|
||||
it("should succeed on zero inputs", async () => {
|
||||
expect(await poseidonCircom["poseidon(uint256[2])"]([0, 0])).to.eq(
|
||||
await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 0)
|
||||
);
|
||||
});
|
||||
|
||||
it("should succeed on random inputs", async () => {
|
||||
for (let bytes = 1; bytes <= 32; ++bytes) {
|
||||
for (let i = 0; i < 5; ++i) {
|
||||
const a = randomBytes(bytes);
|
||||
const b = randomBytes(bytes);
|
||||
expect(await poseidonCircom["poseidon(uint256[2])"]([a, b])).to.eq(
|
||||
await poseidon["poseidon(uint256[2],uint256)"]([a, b], 0)
|
||||
);
|
||||
expect(await poseidonCircom["poseidon(uint256[2])"]([a, 0])).to.eq(
|
||||
await poseidon["poseidon(uint256[2],uint256)"]([a, 0], 0)
|
||||
);
|
||||
expect(await poseidonCircom["poseidon(uint256[2])"]([0, b])).to.eq(
|
||||
await poseidon["poseidon(uint256[2],uint256)"]([0, b], 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// test against with scroll's go implementation.
|
||||
context("domain = nonzero", async () => {
|
||||
let poseidonCircom: Contract;
|
||||
let poseidon: Contract;
|
||||
|
||||
beforeEach(async () => {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
|
||||
const PoseidonWithoutDomainFactory = new ethers.ContractFactory(
|
||||
PoseidonWithoutDomain.generateABI(2),
|
||||
PoseidonWithoutDomain.createCode(2),
|
||||
deployer
|
||||
);
|
||||
poseidonCircom = await PoseidonWithoutDomainFactory.deploy();
|
||||
await poseidonCircom.deployed();
|
||||
|
||||
const PoseidonWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer);
|
||||
poseidon = await PoseidonWithDomainFactory.deploy();
|
||||
await poseidon.deployed();
|
||||
});
|
||||
|
||||
it("should succeed on zero inputs", async () => {
|
||||
expect(await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 6)).to.eq(
|
||||
BigNumber.from("17848312925884193353134534408113064827548730776291701343555436351962284922129")
|
||||
);
|
||||
expect(await poseidon["poseidon(uint256[2],uint256)"]([0, 0], 7)).to.eq(
|
||||
BigNumber.from("20994231331856095272861976502721128670019193481895476667943874333621461724676")
|
||||
);
|
||||
});
|
||||
|
||||
it("should succeed on random inputs", async () => {
|
||||
const lines = String(fs.readFileSync("./integration-test/testdata/poseidon_hash_with_domain.data")).split("\n");
|
||||
for (const line of lines) {
|
||||
const [domain, a, b, hash] = line.split(" ");
|
||||
expect(await poseidon["poseidon(uint256[2],uint256)"]([a, b], domain)).to.eq(BigNumber.from(hash));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,9 +5,7 @@ import { concat } from "ethers/lib/utils";
|
||||
import { ethers } from "hardhat";
|
||||
import { MockZkTrieVerifier } from "../typechain";
|
||||
|
||||
import { generateABI, createCode } from "../scripts/poseidon";
|
||||
|
||||
const chars = "0123456789abcdef";
|
||||
import poseidonUnit from "circomlib/src/poseidon_gencontract";
|
||||
|
||||
interface ITestConfig {
|
||||
block: number;
|
||||
@@ -22,245 +20,170 @@ interface ITestConfig {
|
||||
|
||||
const testcases: Array<ITestConfig> = [
|
||||
{
|
||||
// curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x8391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378"], "0x1111ad"]}' https://rpc.scroll.io
|
||||
block: 1118637,
|
||||
desc: "WETH.balance[0xa7994f02237aed2c116a702a8f5322a1fb325b31]",
|
||||
block: 95216,
|
||||
desc: "contract with storage",
|
||||
account: "0x5300000000000000000000000000000000000004",
|
||||
storage: "0x8391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378",
|
||||
expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103",
|
||||
expectedValue: "0x00000000000000000000000000000000000000000000000000006239b5a2c000",
|
||||
storage: "0x9505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a",
|
||||
expectedRoot: "0x2dc794537b959b575dc216cd11389d802f9389fce7183278561a824aa8e950e2",
|
||||
expectedValue: "0x00000000000000000000000000000000000000000000000111346048bf18a14a",
|
||||
accountProof: [
|
||||
"0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab",
|
||||
"0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143",
|
||||
"0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276",
|
||||
"0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913",
|
||||
"0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4",
|
||||
"0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae",
|
||||
"0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5",
|
||||
"0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7",
|
||||
"0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10",
|
||||
"0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333",
|
||||
"0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733",
|
||||
"0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9",
|
||||
"0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52",
|
||||
"0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3",
|
||||
"0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31",
|
||||
"0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e",
|
||||
"0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc",
|
||||
"0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d",
|
||||
"0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e",
|
||||
"0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e",
|
||||
"0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2",
|
||||
"0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247",
|
||||
"0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000",
|
||||
"0x001988ce414103e97cb80613adde47d5fe0611b30087d1cfcdb84284c42907467e24ac744be2edcb86cdfc42a9bbb7b2a270649161c3ce3a41d3ad5a26927d2c79",
|
||||
"0x0028db7c407cab6652f1f194401bd87bda33c9a1723b4f93515bd5929cad02668123fa5a3e69136c8e03a62c805f89c9d3578a6f5fac4bb281fc4d7df12fbcc5db",
|
||||
"0x000376d1bfe3d5c6afffb5707a34003209c57fbf15430daf0f8022b4df2bb947460ab4fda7be343efd34af2420e8e9d4268f436cb7700a005086df4eba083407c8",
|
||||
"0x0025df09dd66dd9d8b5b1abb82cee9985a2addd12e7f5671c910e27644ccaf498c2a2d7021169172e380831f43a00f0a3bef8576c7c74ac98fd7e7b1ec443ac92e",
|
||||
"0x00218d51f8e754bf89062007dd765b50b7385bbb4a57db258ac8dcf9ad69b6f4552ddc5a17cec74d8e8f06e16c0a6112023c34d6c001060bc783ab4d06a4a9801a",
|
||||
"0x001166c2eedfbbb4568ec27c57b2729437c0c8c38161fad643f03f76fbd807e712286d86bfdceb6729daedb6f219dd0f6080386d9a2a8f9c1dcb89792c8754e125",
|
||||
"0x0028fd666ed406e277f6496bcac13af8b303b58c74be937399095399f4dd141c6f2876f81684c2546ff90b221ba2fe1290e671770af08fd545868e3351401b1503",
|
||||
"0x000b9245c7ccc1eab305d40cced5e8aac6c8ddb877451075185bb7a6c1a4973a5d2852ce761c8e417a5f604a6ef4196ec101014aa1d1e4c684d1b5b8cbec5c37b1",
|
||||
"0x0019755e50ef22e13ae17cbc33d9e708ee9efc011941b3a920bc65da9825b04eb029a43488e5584b68d1a98a215f03f31e063734a3305600f9feed11607271d0d3",
|
||||
"0x002e10cc0afbf5b336e6a6eeae0c863df7a7c2ba61c599618fb973aeff397918e523b18c08a19fa6bc964ae41c56af610ab43d948db94ad2543e9807a5a0f1d2f0",
|
||||
"0x00247f3f0cebebf749e27c8ffd81e9919cab114bd3d75029e3260e99b6c7fe551d06a69531144f521b68d1a2c7450f5a20146efdaf7b47271782bb8746a023cf84",
|
||||
"0x0029ad88f0ee7198edcae37ab88efb2a27ea8956d6b988264b227843c175743c4329916ead363e6adfc27f400977d2d9efb1f896616a18d71e2702ec8201b82c57",
|
||||
"0x002a1de55ee84561850354085516a1101705f8240b8f1e1f9aea3a464650d637a52fad2de438ac5851b0e28508af90bd385dbcad5df8ea23ca78792f094ff7ca0d",
|
||||
"0x001ba118afa1977f1fda1411cd1c7f145ab97a35b1e724060d5cfc3d58b27141ee2b0a8dbf3d494c6a1bf6456c4de00de8e2f0d9be0716a3ca78d4df28948f975b",
|
||||
"0x0025bdbf508c1e3808415136bfdd6dfb548c33348d813882b0d405913405d575010c60f95c658dc8113f7c97935a35d78c23dba131c25866fc8d93920e318d2450",
|
||||
"0x0007bc3ec4d80df884c4d87f4541ffa522046a4c52e6cccb9ff7376ff56149e5d21b87a56676f679f4b8b4478c8a3aa80a09127258cccd4aa373a5c7c2344d2d03",
|
||||
"0x010aef26efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681205300000000000000000000000000000000000004000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564",
|
||||
"0x0912af3ac8f8ea443e6d89d071fccaa2b3c8462220c1c2921234f613b41594f08f2a170e61f5f436b536c155b438044cf0d0f24b94b4c034ad22b3eae824998243",
|
||||
"0x0916011d547d7a54929c3515078f4f672c6b390ccdd4119f0776376910bc5a38da1a059ed9c504fadcc9f77e8a402175743bee1f5be27b7002b0f6c5b51070452c",
|
||||
"0x09017285edc268d979eb410b46627e541afda16cdb3577ce04c15dc14cc6609c60143f0c01e71e99b2efbe3d8e62a2c812889aa9fd88dd4b0ed8eadcf1ec9b096a",
|
||||
"0x0922901e65200b007ad8e1b972e90403b336e459e0cf9b9d68732da345b1b0f6872c9e3f3edacbd857b26d0a66a80aa56c6ebaa9849e9ea5a2b17fd59cabe138e4",
|
||||
"0x091b77a00164a72880eec6c18fc043fa99f922e20bbee156e1ebfd3a358bee6bbb24d97cfaa234befe197a567476cade91b7d97a1017b8d5286dae4dddadffe1cd",
|
||||
"0x09216f1c4d67a9a428885bb8d978ad369d2d69d4dcc1692c3a0c3ea05da7d6f0ac2d6dda722e76eb513c67718e7be0478851758be5547322473a53b5b2b67faf95",
|
||||
"0x091f56c6f18ceb7077125df1ed17a42a85956090594125c1b182161de20f8af6aa2e36977412f9ea2ad2c0951153969eca8408317558ff1b6b4ad731726235f606",
|
||||
"0x092ca197dda6c519d80296f4fcda2933df9608ec684ad000133259024041d070812d29b058a998cf7ffc647b2739041725d77889f58953799c6aba6d9e5b981fc8",
|
||||
"0x091c25a87d321a09ad2a149d1a7eaa77727c7feffb4c39caf44f8edd4377f7bd0c16d1091494d3c90d301c1cb4596692798e78e4cc3d53c3a08e2641de43f9da18",
|
||||
"0x092166058c98245eb85b08da1c569df11f86b00cc44212a9a8ee0d60556d05a8030942c68b535651e11af38264ecc89e5f79b66c3d9ce87233ad65d4894a3d1c3d",
|
||||
"0x0908c3b13b7400630170baec7448c7ec99fa9100cad373e189e42aca121e2c8f450f9e40d92d98bb0b1286a18581591fddfa8637fc941c1630237293d69e5cb98f",
|
||||
"0x091362d251bbd8b255d63cd91bcfc257b8fb3ea608ce652784e3db11b22ca86c0122a0068fa1f1d54f313bed9fd9209212af3f366e4ff28092bf42c4abebffe10a",
|
||||
"0x081d67961bb431a9da78eb976fabd641e20fbf4b7e32eb3faac7dfb5abb50f1faf1438d77000c1cf96c9d61347e1351eb0200260ebe523e69f6e9f334ec86e6b58",
|
||||
"0x0819324d2488778bdef23319a6832001ee85f578cc920670c81f3645f898a46ec62e00385c4416ca4ccbab237b13396e5e25e5da12101021c6a6f9ecfe7c7fed19",
|
||||
"0x041421380c36ea8ef65a9bdb0202b06d1e03f52857cdfea3795463653eaa3dd7d80101000000000000000000000000000000000000000000000000000000006239b5a2c000208391082587ea494a8beba02cc40273f27e5477a967cd400736ac46950da0b378",
|
||||
"0x000a52b818e0a009930d62c17f2b1244179b7c14f8e1ae317fb3bfd3a3ba6060031b2a4aa2df31e79f926474987eea69aab84f4581cfd61b0338438110f6be145b",
|
||||
"0x001684ff1ef6ea054c5a6a5cae45f9280dacfc10c6cde39d1f64a00ad3c77549fe1c14ff8a628c0244ba48d63610e5d0b514c1b7b60301b6f27f77a435caf8bd60",
|
||||
"0x001a2ba0ad7d6447d3c2476aa2e6bd04ab552ac1840450ce11f338f58a80fcdf420df4b9fc89108a0a44d844d981abe44d5ab20a5a101d07e94d131f07bf83ba62",
|
||||
"0x0007158ec8942174c68bde0ab3666eb29b3c5784693bbfcd21126789d98bbdd05409f0313df8ddc438abe4798854f30c9daa2274950ce833a2de21e09b8b2c11b2",
|
||||
"0x000ab27b84c73e447618f030ad9d621b0d61cc783e7ae5671ffcd3ff479b5093fe173d6126fa71986aa679b5384a2dc25f3a15f806a546e933f9fda6ac0a3460d9",
|
||||
"0x0024ca9a7c6b7bf77c7a7acdae9d8e551b08ec6adf30abb7d1c45a6bbd5058ea921802170d5cc7de7d294cf6c67b0ac0208fe76497803554fb5bba9f78721568eb",
|
||||
"0x0018a60c68b26022ced26cce2be1af1d6b33f4c16596d1ba18d5f47fea98ae490b12e66678391e289de1cf981c122e765265b94f0669614d94847480a77c2d3b74",
|
||||
"0x001a776d5e5902c9a073c86a71ee80d167d6e2eb92150df2afb3d87f18b2cce6f02af158ba1cfbc643b36c1e001b59473cc88663b44c8d70739a27b804ec387146",
|
||||
"0x0012cd2c1070b0d2eb215eb760fba9b843bd5c732102ce9773701076b0e37a437e136901c4ddc1cdbef42f46af629296ca5965b41a53cce65237612cea27477076",
|
||||
"0x002bf94aa1fcb474365039e949bbbeabe0162ffc490b1b63ffe0f84bf182a8bf16169fe345e742d176a80f6e733177736d93e40fc9fdd4866efa6cc45ad94e9577",
|
||||
"0x001a2e6e1b585fa0564fc606c3d62c26d9a113d75430966ff3f500e450c762edeb24fb1e5456ed4313d9418a1b073ae8b3f852f0f8435752bbbe65d21726ddb873",
|
||||
"0x002529704fb28f7d3f9d2f3e9d38b000b6bfc2a21cb0a1955797016536066307d70ba7397326ecf50b98153f9e3baa96608efdf7d772b1ff28649bef677860dba9",
|
||||
"0x0022f4f22a1d85ac83a56e7031559cf874c78a2f2ee6b6b93625f588313964a6d0052f6c873c6417d409c2a5317b31449b36fb4faede558d03b448b06b4a198daa",
|
||||
"0x0017167b295954b29f62d7347dab3158aedc8586d5aa233d3f69c14bc7fe31eb840000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x002d7bed0c0f0318a6fc60f903f4a42841cc4fa431ddf1a97fc34f35d6a267434b2a1a818d75328089a9578143e31b1f535517e09ff50a728b100483e712c8bc9a",
|
||||
"0x0126ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111346048bf18a14a209505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
{
|
||||
// curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x0000000000000000000000000000000000000000000000000000000000000002"], "0x1111ad"]}' https://rpc.scroll.io
|
||||
block: 1118637,
|
||||
desc: "WETH.totalSupply",
|
||||
account: "0x5300000000000000000000000000000000000004",
|
||||
block: 95216,
|
||||
desc: "contract with empty storage node",
|
||||
account: "0xb75d7e84517e1504c151b270255b087fd746d34c",
|
||||
storage: "0x0000000000000000000000000000000000000000000000000000000000000002",
|
||||
expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103",
|
||||
expectedValue: "0x0000000000000000000000000000000000000000000000600058d1a5ce14104d",
|
||||
accountProof: [
|
||||
"0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab",
|
||||
"0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143",
|
||||
"0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276",
|
||||
"0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913",
|
||||
"0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4",
|
||||
"0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae",
|
||||
"0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5",
|
||||
"0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7",
|
||||
"0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10",
|
||||
"0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333",
|
||||
"0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733",
|
||||
"0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9",
|
||||
"0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52",
|
||||
"0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3",
|
||||
"0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31",
|
||||
"0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e",
|
||||
"0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc",
|
||||
"0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d",
|
||||
"0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e",
|
||||
"0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e",
|
||||
"0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2",
|
||||
"0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247",
|
||||
"0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564",
|
||||
"0x0912af3ac8f8ea443e6d89d071fccaa2b3c8462220c1c2921234f613b41594f08f2a170e61f5f436b536c155b438044cf0d0f24b94b4c034ad22b3eae824998243",
|
||||
"0x0916011d547d7a54929c3515078f4f672c6b390ccdd4119f0776376910bc5a38da1a059ed9c504fadcc9f77e8a402175743bee1f5be27b7002b0f6c5b51070452c",
|
||||
"0x092293af71b7b9315c32d08f06e291b85e3b3dbba786dd31952369f666281aa21125ab35feae70aaca9349f6af48f7dcf2dee0324e4eae03e929963e7728b633a3",
|
||||
"0x090607033a4b976c1e4683298d66b88a95ed45033ff43dea0670d84a8c42d35bf12562869385c0e70f561f18be4b78e7276b837f140a45ab12ffef1ba4ad5faecb",
|
||||
"0x090abc5f713c2f58583114bb5081d00cbd01789d8efbd95e471b151c71c475142f0f52ad30f8a63288eb9dd12aca2a670de08c03f8384f55d730c943e1c472625b",
|
||||
"0x0905156e8704d6195f6ae562aed2072f4e32422c6dfd4840ca354b9c4d2de5ce760fca52b1e0689ad374bae9fbea262a929f919695149a083fe6bacb806dc02fca",
|
||||
"0x0917078d4c193a3fdbfe8ce3a235a0e1df89e626b5e91636097e299883fc2447892ad46eefbb27909544fe02c05e29760315749f6ce21c17c52158f5f5616c2dad",
|
||||
"0x0917d02e5da8bdb969149c9327b247a6aaa479bcda4a03665da5103c10e616d2f40ccabdacdd25b34235d26e50e7af5d8d312a2cafdcadd41cc589a71a322f254c",
|
||||
"0x090c62f5c476c1def8ed8a8c25ae54581690b39dfab4b0f3f78b93df96f626714328ea922a76a058087563bb5370664e9a1cebe3062f2d904bf5e3a018219d6563",
|
||||
"0x091e481971f770e587b1f62f1da9ac4687abc5b2a23097fc38332e15ab957ca0ab0ec0a95c15313887e0d2f166c100deaf17f2ce50767680e6e5b2e3068801c0cd",
|
||||
"0x0911799e186f1bd299dfa08c07404b9d28e2b179fb6ad523f1846872537b6db85f198b573ac1397048258de38b391fcc5e0c86a0f81f4ca607785fb37041ab8b4d",
|
||||
"0x092053a028cf3bfcdabcb58985efc39f078cb0bcae4439528a0b6fe4b24bbdbd2c019a04a54e9e96077f3c2c39c1602a83387018b6357ea4c28e96764865d1c8f3",
|
||||
"0x07303fad3e4628ccae4de1adb41996c9f38b22445b6525ff163b4c68cbde275b1a06111cae9b4d17b730d94f589e20c6ae2cb59bf0b40ad05bf58703ee6d46eac4",
|
||||
"0x0606bc3fca1f1b3c877aa01a765c18db8b0d7f0bc50bd99f21223055bf1595c84d04fdc0fd416d8402fde743d908d032a20af6f2e65cdc6cc289f72c04f1c2476f",
|
||||
"0x04020953ad52de135367a1ba2629636216ed5174cce5629d11b5d97fe733f07dcc010100000000000000000000000000000000000000000000000000600058d1a5ce14104d200000000000000000000000000000000000000000000000000000000000000002",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
{
|
||||
// curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000004", ["0x0000000000000000000000000000000000000000000000000000000000002222"], "0x1111ad"]}' https://rpc.scroll.io
|
||||
block: 1118637,
|
||||
desc: "random empty storage in WETH",
|
||||
account: "0x5300000000000000000000000000000000000004",
|
||||
storage: "0x0000000000000000000000000000000000000000000000000000000000002222",
|
||||
expectedRoot: "0x1334a21a74914182745c1f5142e70b487262096784ae7669186657462c01b103",
|
||||
expectedRoot: "0x2dc794537b959b575dc216cd11389d802f9389fce7183278561a824aa8e950e2",
|
||||
expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
accountProof: [
|
||||
"0x0907d980105678a2007eb5683d850f36a9caafe6e7fd3279987d7a94a13a360d3a1478f9a4c1f8c755227ee3544929bb0d7cfa2d999a48493d048ff0250bb002ab",
|
||||
"0x092b59a024f142555555c767842c4fcc3996686c57699791fcb10013f69ffd9b2507360087cb303767fd43f2650960621246a8d205d086e03d9c1626e4aaa5b143",
|
||||
"0x091f876342916ac1d5a14ef40cfc5644452170b16d1b045877f303cd52322ba1e00ba09f36443c2a63fbd7ff8feeb2c84e99fde6db08fd8e4c67ad061c482ff276",
|
||||
"0x09277b3069a4b944a45df222366aae727ec64efaf0a8ecb000645d0eea3a3fa93609b925158cc04f610f8c616369094683ca7a86239f49e97852aa286d148a3913",
|
||||
"0x092fb789200a7324067934da8be91c48f86c4e6f35fed6d1ce8ae4d7051f480bc0074019222c788b139b6919dfbc9d0b51f274e0ed3ea03553b8db30392ac05ce4",
|
||||
"0x092f79da8f9f2c3a3a3813580ff18d4619b95f54026b2f16ccbcca684d5e25e1f52912fa319d9a7ba537a52cc6571844b4d1aa99b8a78cea6f686a6279ade5dcae",
|
||||
"0x09249d249bcf92a369bd7715ec63a4b29d706a5dbb304efd678a2e5d7982e7fa9b202e3225c1031d83ab62d78516a4cbdbf2b22842c57182e7cb0dbb4303ac38c5",
|
||||
"0x0904837ebb85ceccab225d4d826fe57edca4b00862199b91082f65dfffa7669b90039c710273b02e60c2e74eb8b243721e852e0e56fa51668b6362fd920f817cb7",
|
||||
"0x090a36f6aabc3768a05dd8f93667a0eb2e5b63d94b5ce27132fb38d13c56d49cb4249c2013daee90184ae285226271f150f6a8f74f2c85dbd0721c5f583e620b10",
|
||||
"0x091b82f139a06af573e871fdd5f5ac18f17c568ffe1c9e271505b371ad7f0603e716b187804a49d2456a0baa7c2317c14d9aa7e58ad64df38bc6c1c7b86b072333",
|
||||
"0x0929668e59dfc2e2aef10194f5d287d8396e1a897d68f106bdb12b9541c0bab71d2bf910dea11e3209b3feff88d630af46006e402e935bc84c559694d88c117733",
|
||||
"0x0914231c92f09f56628c10603dc2d2120d9d11b27fa23753a14171127c3a1ee3dd0d6b9cbd11d031fe6e1b650023edc58aa580fa4f4aa1b30bf82e0e4c7a308bb9",
|
||||
"0x0914c1dd24c520d96aac93b7ef3062526067f1b15a080c482abf449d3c2cde781b195eb63b5e328572090319310914d81b2ca8350b6e15dc9d13e878f8c28c9d52",
|
||||
"0x0927cb93e3d9c144a5a3653c5cf2ed5940d64f461dd588cd192516ae7d855e9408166e85986d4c9836cd6cd822174ba9db9c7a043d73e86b5b2cfc0a2e082894c3",
|
||||
"0x090858bf8a0119626fe9339bd92116a070ba1a66423b0f7d3f4666b6851fdea01400f7f51eb22df168c41162d7f18f9d97155d87da523b05a1dde54e7a30a98c31",
|
||||
"0x0902776c1f5f93a95baea2e209ddb4a5e49dd1112a7f7d755a45addffe4a233dad0d8cc62b957d9b254fdc8199c720fcf8d5c65d14899911e991b4530710aca75e",
|
||||
"0x091d7fde5c78c88bbf6082a20a185cde96a203ea0d29c829c1ab9322fc3ca0ae3100ef7cba868cac216d365a0232ad6227ab1ef3290166bc6c19b719b79dbc17fc",
|
||||
"0x091690160269c53c6b74337a00d02cb40a88ea5eba06e1942088b619baee83279e12d96d62dda9c4b5897d58fea40b5825d87a5526dec37361ec7c93a3256ea76d",
|
||||
"0x091bccb091cde3f8ca7cfda1df379c9bfa412908c41037ae4ec0a20ce984e2c9a51d02c109d2e6e25dc60f10b1bc3b3f97ca1ce1aa025ce4f3146de3979403b99e",
|
||||
"0x0927083540af95e57acba69671a4a596f721432549b8760941f4251e0dd7a013a917cee0f60d333cf88e40ae8710fb1fd6e3920346a376b3ba6686a4b2020a043e",
|
||||
"0x082170b57b8f05f6990eec62e74cdb303741f6c464a85d68582c19c51e53f490000a5029a62ddc14c9c07c549db300bd308b6367454966c94b8526f4ceed5693b2",
|
||||
"0x0827a0b16ef333dcfe00610d19dc468b9e856f544c9b5e9b046357e0a38aedaeb90000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x06126f891e8753e67c5cbfa2a67e9d71942eab3a88cde86e97a4af94ea0dde497821fb69ccdb00e6eaeaf7fc1e73630f39f846970b72ac801e396da0033fb0c247",
|
||||
"0x0420e9fb498ff9c35246d527da24aa1710d2cc9b055ecf9a95a8a2a11d3d836cdf050800000000000000000000000000000000000000000000000016ef00000000000000000000000000000000000000000000000000000000000000600058d1a5ce14104d0dedcaecaab39b6e22c2608e40af67a71908e6e97bbf4a43c59c4537140c25a9e8c4073351c26b9831c1e5af153b9be4713a4af9edfdf32b58077b735e120f14136a7980da529d9e8d3a71433fc9dc5aa8c01e3a4eb60cb3a4f9cf9ca5c8e0be205300000000000000000000000000000000000004000000000000000000000000",
|
||||
"0x001988ce414103e97cb80613adde47d5fe0611b30087d1cfcdb84284c42907467e24ac744be2edcb86cdfc42a9bbb7b2a270649161c3ce3a41d3ad5a26927d2c79",
|
||||
"0x0028db7c407cab6652f1f194401bd87bda33c9a1723b4f93515bd5929cad02668123fa5a3e69136c8e03a62c805f89c9d3578a6f5fac4bb281fc4d7df12fbcc5db",
|
||||
"0x0006801926f00b574e3a88162d192482fecba9918b77e133dd77587d9efaf5c7861712d244ac8ad4bc0bffe0dbe8ab261865c9a69b4b7769e9c188ec048460ce78",
|
||||
"0x002f3161746c2c70c7cefb74c07bc16b28bd9011343f5c6f8756471cd0b184601a25d05d5447a572452964b3c20f40ef841bf313c958e82a6923584e20496df67f",
|
||||
"0x000efef3e3e174da6f3f451b5a2652d2489fff449a217c10841e68e4a15995d6521c4b1552c592020fbc7219c5d67ff00bd630db8102ce5c6ca12bea29b80ba5e5",
|
||||
"0x0019b4749b17792c0ad9f7b460a0faf35400da9423be38ac5c40e81c805acc72592c0b933e1c25d05db98d98fc4f04b27610b2ee88281126099aed42f27cd96b00",
|
||||
"0x002b8d563c5041f28afa38da01b6ec9e7278250be79f7f55e2586955e75ab75fad2055ea72cd44209c41c94ddfb980fe5b007b3e997085bc1fe5b514f72f860c05",
|
||||
"0x001335698617876fcc272740f765d53d53ee511dc9dc33965aaa0a5584f2f0fc02274c435ba9cc0fd5b897350de8cc1837d3a2baaa54ef3f9c66f689f20eddaf1a",
|
||||
"0x0010f766b8dbe13e3f27f45da3ad7e5c31fd1c11c51f4f892851519182cdc9348921c10d83a16e057f99623dcd68ab28a78e48b655df756245631521d04e85e583",
|
||||
"0x002bb5fce9df47073438d61ee438d900ab4ab01ac7f053e57c6ffe3e8f1746285016a600e6b7ee90281bbc3bd9b9523a663261cda2208ae98efcf76df8c965fb76",
|
||||
"0x002cad2eb5194b59d880565b03cd667a842923c1310a60bd818685c8fe4120d86817ee8bfffdb490f78f23d6fb38bb1c27f10f877c5017b8b2c21ad14f23df0eab",
|
||||
"0x001f064044ca94d6f30ef93ee1bb6ae35450acf1c8f5b113b0f0ff39e4b65cfb9a25141ae7fc30c69000991e65c626c1b12fb76bca02c68f8116d15698a5934b71",
|
||||
"0x0014382fa3481f424cc33c39f77fd3df54c5951be347c629ab5baec238e46cab050b2b8bec8ebdbc97dd6c0ab867aae5746e51b69b7b8177c96dbc0c4531521d3e",
|
||||
"0x0011941db7a46d1a3ddbd27a4a57a0ce1865b6e224552b233d9d545745489257f408c8e3a0a147e117dbb89827018a2df52d124cee29e82b15643e4877cabe4d06",
|
||||
"0x0000d7b8f99e5f148297bf4bf7e5133f87dbdf1932dbb152e0cb14c472c7d26f26146c4f72b903bb98b0855c1ca5bef4bada14a773dcda341d10402004e999d757",
|
||||
"0x0104eeb1fce36df4d3f6423137af3855d16bc936184295529c58682bb5217d64d905080000000000000000000000000000000000000000000000000867000000000000000130644e72e131a029b85045b68181585d2833e84879b96ea2850beb8e012d423615fd9926356a5b1f3a4599c7cccd6df3b45097b6527756e572b90fc8c40496f831f2125c021fb94759cb1993a2f07eae01792311e13f209441ff8969cf1eb8351cafbbe8f01ed4c292d9a27be523919a274441a076b20c7d713d192dbe6485c220b75d7e84517e1504c151b270255b087fd746d34c000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x09240ea2601c34d792a0a5a8a84d8e501cfdfdf2c10ef13ea560acac58661882dd1b3644d1d4f3e32fc78498a7ebeffac8c6a494ac6f36923ef1be476444c0d564",
|
||||
"0x092fa31ba6c9b8f291512a582ab446daf7aa3787e68f9628d08ec0db329027d9001af83d361b481ed4b943d988cb0191c350b8efc85cfceba74afb60783488d441",
|
||||
"0x092c2ec2d967208cb5088400d826b52113d606435be011b6c9f721f293fb12242515681c9016eb1c222dcdbeeeb9fd3a504caba892f4c1832741a2b17a7305598a",
|
||||
"0x090c7fe825c29bf5df80c7101ff8a372ba4f7b2ac37c16a3bbda38cc1e38e682460499b7e5d21d3784f496e747140f465eb1a39a019d2be8baf13a5e39f359a4ed",
|
||||
"0x092bb11ebbc7cd1e565b86498aecab16842ab3fa852c7943cfbc49ee4bc593b2f308a78e1bc555e07d36d5c812af57c18f67199197a52ff74bc4e32ca6b7fadf32",
|
||||
"0x092fd1e042080801034c6d6c79d462016c74b97dfbb1272cf606e638911a08f21c02434541eeed6d66002c69042f9354211e40518316a2d98cc0da0f19fb1ea013",
|
||||
"0x09024bd491ec707bc3e8bea6b2754f37b1e85903061aefabd945537eef2f4d38b4136b925b004d29603c5e6195e073322d27f0c6ea3fa1ea5c5b248ff60dda594c",
|
||||
"0x09269e1f468bd9bbde77a13562645a80a77d26d801781ca95d385bd59ee1b0890b03694bf9043190620265bf0bc3baa4d82cc82302ae0bbf33cfa48b0ec9d5ab25",
|
||||
"0x0924d8bf62b2a725684847208dc021d5aee9f3c8f14c14786bc9f93232dfd3e068120bb7d022bbb159b4b84bb9e36cd2fcd89d761e265c1b88c8bdb9745a51cb22",
|
||||
"0x092680f932920fd86de0b417cfdbeb2836a470213097ed5abb1a2b4deba8437f6825fd0ec614b97e6cfa4d50b08ad1e0fd8a5cd72db3a468128d1045d6a54e5e6e",
|
||||
"0x0909e630914cee4db538057a0218a72288b88b2603aee0f805254b865a03de87c92ce46c1aa77ee8c42bb60c4175826f4dbb89d6282c01ff3de654c961599e66c3",
|
||||
"0x091a17302d53ad1b7a4472d111fd27b35720d49ce27259b5e42f46339dddf235e82b973c29f44cf69b589f724d7d2fa54bf38b37bde3fc66c0d965a8c10df80caa",
|
||||
"0x0916572156ae22ae2b0bc84ff41d16668be7163da26db2b13b86c218e0516c97a4131b584b7192464dde26060f66f678b03c8db8f64f1cd7a1f98a22a90cce5850",
|
||||
"0x092c6ee2ca598c123445bbbd403ca3ab8a95ce2443f941ebdcf7bb035e2a3e38e22e8d5b222a1019b126f0ecf277c7fed881413e879cd4dc5df66634b6e9fb688d",
|
||||
"0x0700000000000000000000000000000000000000000000000000000000000000002822301c27c0bd26a8f361545a09d509a2feed981accf780de30244f0300321d",
|
||||
"0x05",
|
||||
"0x000c180cb3d57f72eb405dfc667d167967e4709cf3722a87b4c924f78a1d8fa9e926d16eb1f4902f8ac7a48fdf98274c9c4061f9f14f783e2fb41ef50c53d5f8ad",
|
||||
"0x000f78c968ee196c478c91d12a48edfde6c630d40203652c6420ff5aa3619549a4297615606d62866169d509f77c9cb38751ae282cafdc27caf891585b383b4795",
|
||||
"0x000798716960783afdcfd0749aa3b316d6e3d6ec2724853e629b42b5a9a10208e02e5f5fe3d5b8b823d3481aa1e738a1a24d6d1a63116e0003044672d73a7df2e4",
|
||||
"0x0014748f61c4954d239225204b4611d66384f08ef03db3da82957fd590ee00b6c92b873e4bd217f8dfb0fa29bca1087ac7bc29db616a6830ba456091bab772ac06",
|
||||
"0x000a1c900952239e98f5f1a3009e623bf6cf533d3b0d6d13d28d04f0496761927c0be199ff86f081ebb1c413e850450a4cce01dfd2c455156d7abde31385ae2ab8",
|
||||
"0x00028d4e89bc6ce55b5e6bba0f2f3758dafcdb4722e6c1a06f6faa8bae065bc8ae0644641c0ac696c265b3ec90889e3842c9a7a5902f1a5e807c5767ed49106982",
|
||||
"0x001e8434bf68ee6077d88efb5449ad286455a522e63a6bce5544cf785b77a5842d041a4e324bc47aa8ae42b56446f687758a8091986b6d760fd283a9e097a64e3a",
|
||||
"0x00250bc6ba916a2acb3ce53053a88be40b815fa749d144dc709a7a46a08361e83c05b2b5b05f45324ab921e04ae1278371ebe1e092203259f4e5306eb46ad50f8c",
|
||||
"0x0011c208e2c536c37674b1ecafff0261146c326c939544781da7062bbd0ac2fbca246f5225dc41e9fc17fe531f5bdc3325620e4003b3310a2cf7e31011b19c68a2",
|
||||
"0x001dc8d4177945ac89a3c61977ed787e50c9d8a0c5d85dd6b1409ec11213b324e6228005b222573db7882205be776a5bd2183944b6fcf63af604e31b9285bd010e",
|
||||
"0x0014ba74da33d2ca27e3f78bc1bd052c2b92176ce4136df751a8229051de383c2b0c8994f02704420f1f84963281364401d00f6d5aa9b6f52135bd96159c1c3b9b",
|
||||
"0x00188c7ee45a6c28fa7ad49a86206b70764066b1888b0de90e4410d7132a641f8b0eecbba072e28ed6705379104e30dd2557c47b30be7dd5e8c893b8a641d02701",
|
||||
"0x0010fb29a3bb8191eb03bd345ad1995bf6a57f09929f72dc8a9c42435c2eef734b1d565bfc8ae78d6c1496f2bdfeadff6890e8ddef4c6b730a5ec8575344800c90",
|
||||
"0x001b2abe5a1352c492c3ac47d2ff93896977a99a0783eedadc6246efc9b4e78ab408291f4e9234e4662a365f40090e1b323e3448fa2f6cdc9c929477095499c323",
|
||||
"0x00083b5711eb1cbba5e79c53227057d4987a22dd22b5ef715bf21f558917f48b17027f174fd4ca77e412ca65a7fbf6151e4473fa909ea384c7687b45f860d0103a",
|
||||
"0x00100158ee54f61ba5b093a43a348cfd202c87ba1533af2b24fc2f068de89a8d15100f3cc72c206d05d44db4272bd67db89bc6e5c86d7c1b03b40395ec4661595c",
|
||||
"0x002a15c17fcf2a10c6d1bcbd59ae262f80ad33518d499059a668e115045069ef012788a404ba41b5f8a96f0b294d0ba91e65b1bf58eee74adb8e55ca12f22fdccc",
|
||||
"0x00031177585837e616bc830056a4bd12821c9c779096df361ebe1d77379e96ff9e0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x02",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
{
|
||||
// curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0x5300000000000000000000000000000000000044", ["0x0000000000000000000000000000000000000000000000000000000000000000"], "0x1111ad"]}' https://rpc.scroll.io
|
||||
block: 1154766,
|
||||
desc: "random empty storage in some contract",
|
||||
account: "0x226D078166C78e00ce5E97d8f18CDc408512bb0F",
|
||||
storage: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||
expectedRoot: "0x1e5cf13822e052084c315e944ca84f1ef375583e85e1508055123a182e415fab",
|
||||
expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
accountProof: [
|
||||
"0x09062c633f6d7c7a157025fef8ab1c313a7caadda3a64b23664741f9de3b0478fe27571cf9b45d5f4deddf5f0b5354a613998fdcbe9249bb7cde92fd45513c5a99",
|
||||
"0x0920d6877efe14060018278754e91682430401880981fec1cd1b63610bed0c1e332a63aca7a8898b01983e2c53a7257310318da444fd6c8b705e488943205301a8",
|
||||
"0x090f6dadd53bbc0f5fa4fa03961aff0bf252ae335e11c1836253b6bc214d66759010b10d80991219a66f1eb7e07169b4cec4fa74b04edbdc08c3f238dfdf1d2fac",
|
||||
"0x0921ea10af71b5f3587ff9d42178a151427cbcde37b8bee6575463bf6b83110cca0520d5f97b44e7015453ec16d9c28980d2cec3df5c860eb8a455f49dcfa339be",
|
||||
"0x092d19cf96a7c129aac6f72f780703a9ef3233fc5124d592baee751a3550dd692a02c962b87efbba5aeea4856c3df29c1ea540e1fbc7a74529d5dc793fe8e490d8",
|
||||
"0x0922e20a087e600560007189ccc1a159e4fffeb1876a6de3772b7f450793a1c6620ada74791f3ecd25a650701578ef9661c64e75d836c681503e96228974a53903",
|
||||
"0x0924839671b636ebb56cb9a2860a3edf2a2875774e84dfcf8546135189f808d724260ac8be541ff088a9a1d2468c4c6e2faa793009be553a3cbca003649ee511db",
|
||||
"0x090cd8140d844f62e44ffe820c1b2b0d4aa8f0518c15ff61759d93d805cb017cb628d5b46a4c4ec0a10eb00155808890925050f7af2279b512c25005d963283262",
|
||||
"0x0913c0698673b0be011485eba05c61ac41bf14fc960ce5dbb6f5a021809eabbb0e18adaf85a3724e1a644268b845f5014b39e574928b9a01bfcd25d6fe1cf03e8f",
|
||||
"0x0912c2e7da4b091c52e0012e5c13baf07d9d9daed10a558262d2e700a7c823300e054dce1849561bbeede4368a3be06f5a2bae06bdb1bc2bcefdba84634fd1991c",
|
||||
"0x090b3e9c665497a0f9c1d3f1448c6d9144a287eb0accf86fea6f443f51986df7130392814f078a19643081787478ec3a010e2757a574877a194136c529813cf7ae",
|
||||
"0x09249a0e273abe79a0b99a55516e19213191b7f77ef34f8815edc4e1ede8711f7920615adbac1983d844c8a6ed50922562432c13d030069d8b3e92611b4fe39531",
|
||||
"0x09199575893e55d92fafb3b067130b9b6b5a46e7f6fb2d0af412d12591632dfe961adffb9dd1e7490095aac94bc1fcaeb591f4ba907fe2b882c9f6d8f7ab3a1809",
|
||||
"0x09259308e9398f029ebbe31a4b353f474622b4c96995b7365c3b13c392fcc3e7001be60286a497a3886aa9cff3ad6a5dc71504078eb7a44c43530b7b33eef4743f",
|
||||
"0x090709a21aaf18a1eaea3b925ab36f47a82095aa3e9ddbc4f01463005c4b64f6af0554d854637fcbfd9b1a4c2474de343950569e4f855d66f2ee14fcfb19ee17f5",
|
||||
"0x092d7319be75a70b8ea5f0acc6ab4a96971ec546f72b18bdc3e905ad6ea8a288f70626499aee389335559b1dd3cc8b6711f9fde0c517236190cba24fa87993877a",
|
||||
"0x09081b165a51e3081fc2e3e27d6fdb81134b65284851798de62899db3065a8c1fc040c8dce92508a510c2c34fc2949910dd41247c9f247cd216c03d9bb9d2881b4",
|
||||
"0x092a27c5be32e1ab6e85d1ac094bc1509d92285f45c63fca6dba9b14d485a94af326d44c1ff85666a4790182ddd7e51cbbe06af81d62082e6d79faec29a4501369",
|
||||
"0x091a46df6ffd6b439ffcd1b57e9548f5c4db26ade9e984efc8a91a01ab22134d3c1617b504ac2015793c5dac16d379b5ca6cb70c14243491bb68535ee686a3a553",
|
||||
"0x08180e90f9f9a4fd8065a5849539793bd9e9340b69770eff1716a733241e454c341641f913f1c32e2c652b876f902e5c2c8d51c482411ec44dae969bdc50264c42",
|
||||
"0x06273c162ecb059cd86ec0a01033dd61c39f59ee0a13eb41a28c0b2d49a45f6f94081be344adea9f54587a832b9efef6fc9ec010d86ec5fb2b53b5ff8dbabc4924",
|
||||
"0x040b792f5b15327fc37390341af919c991641846d380397e4c73cbb1298921a546050800000000000000000000000000000000000000000000000000fb0000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be74cc05824041ef286fd08582cdfacec7784a35af72f937acf64ade5073da10889249d61c3649abf8749bf686a73f708d67726fada3e071b03d4541da9156b20226d078166c78e00ce5e97d8f18cdc408512bb0f000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x05",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
{
|
||||
// curl -H "content-type: application/json" -X POST --data '{"id":0,"jsonrpc":"2.0","method":"eth_getProof","params":["0xC73BfBD94fb1FD860997D4E76D116BDE0333BeEf", ["0x0000000000000000000000000000000000000000000000000000000000000000"], "0x2a7531"]}' https://sepolia-rpc.scroll.io
|
||||
block: 2782513,
|
||||
desc: "contract with only one storage entry",
|
||||
account: "0xC73BfBD94fb1FD860997D4E76D116BDE0333BeEf",
|
||||
block: 95216,
|
||||
desc: "contract with no storage",
|
||||
account: "0x9c0fc47d9346e2be1e24f6cef76149779fe52715",
|
||||
storage: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
expectedRoot: "0x13c6008daf17807163a056504e562d4adf13870306814b1a3877cda5297d5ae9",
|
||||
expectedValue: "0x000000000000000000000000000000000000000000000000000000000000000c",
|
||||
expectedRoot: "0x2dc794537b959b575dc216cd11389d802f9389fce7183278561a824aa8e950e2",
|
||||
expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
accountProof: [
|
||||
"0x09272d92cb48d19e41ef64be1da3e10026eb87d227132becb4fba0dd1451783de425f66c55ff0bec0b012e11d64aaaa6c322566d58cf45525cb05302132518f23d",
|
||||
"0x0920908000907fe2260e41f8682510eee0572937459163ea1940c2eae8b2d5862e015e7c84f56f5948bfc9c242506d14f5c3c1b97bba1b262b40b108f5d7e69287",
|
||||
"0x09078402c38a02e2b3dda819b761ca6448029f3dd42ae7876ac0dba0d762e3ddb818d80485f0a15f54f110aad9a98b00bdf9ccb56bbcb069552c7f6c10be1b9c15",
|
||||
"0x09123243fe438606648fe3bcef5eb0165920315fb2b9316ce3ec0daac885577f190b84d9901fc150f52ed177f23ec31de4254b293c6eac2088009f3e13e3a08b78",
|
||||
"0x09053c59663d3eafad212f58c4834090db4bfd0ba2b13d3108e0acade089a5da9229a75e0b30abc41d4fb252faf9f3aa8ef750b780247d83186cdc333635c25038",
|
||||
"0x09163255ef0b1fdec7ec97c4e002cdeb6c963ca26d9d03ebdf78eb44dfdb57e4bd1fa9f68cc583c1e7019cc62133ede53e5636330de9a2c09e75f03760026e3729",
|
||||
"0x09296d3cb1c4fd539ed015f2853649d20f5db111ce13c30b7e6efa4c9468741d1e0eea62adcf73aa5bdb4868cd776df429d26787f424beeda38f4ad19aa83e43e4",
|
||||
"0x0908288df27fa423895de38ec5a52e809d99b683c5b32463501f5dad642b71387f0a3d37ae9df53b5cfdda0ac67765662e8a71a19b05d38f4a464596e129a35570",
|
||||
"0x091a774fef4e8294fcca57d213846e51bfcf71249680e937e14248e532b47abd762ad72878f07f4abbba8bd13da9b75f681f35a748bb8fc078913e16a91bce783e",
|
||||
"0x092799a146ba6b2bf4b6a24aef88c9590d9643d53f429438e348518a17af3d6e8d10e3b39898c3795c9386518438465581ca232445532fb549a8bddbdd6f4e0eed",
|
||||
"0x0914c654d53c9f8656b784709decbd12ba786800a77c929f3b4255d59138b42dff282005f8997b73d64eeb112775885c4c08d2ee4e356cc2db58154dde48a0a1e4",
|
||||
"0x091c71601a71f28ed0f6aeb59cf8a7bf29ce7dd3203352099920086e02007496260b811e85a0cd244d56f199b357d5c3a54f897fea21637698943679d07b33db8d",
|
||||
"0x092a66de31cef7b4b195772a2b96edba3ca7d97a5bbe974d071c37f0d0ca0545be0be9ca0dd4c9d62ec3ba0a404713fefe6b62391ba3f6d283a47e83fdb18c3a4e",
|
||||
"0x09093842042d196ae30784d31ed1526dd5d60cabe292eb5333e42936a2edbbaf1d237998efa424724063547c02cfa835ebfc24131315c34229b363f46fefda33ee",
|
||||
"0x0911637da97122f89f421a4564d5328893ff4b5de123aecad06e07ea45d9622b87096a296e974b5eda0f2d35cb5531c4a55f3c1e181a8bb4a0b33399e7c93853d4",
|
||||
"0x0921feeaba62a4ad78791d662737a3fa52a527dcd892f5d3af2cfbed4b6591d50f2fae639afb8ab4640a2d166616a4803442b26b9a8f5148a1c88adda1e2d911da",
|
||||
"0x090ddbe424e9368f262ef80a144383fc4f518b27200f7a61a996a075b3b84ab5041c755907f230eea27d060fa827a5743c7046cd0dc7487047bc3a7d222d65d2d7",
|
||||
"0x092d6e65349fd6751353b4b72fdd03d3ee4b1721efb434db76679c1c348b60fdc0177c7d961201138c98f85daf8a49b7a083a41e77dcd819d359b3db55c4a941a9",
|
||||
"0x090b0d48518cb602b73a86bd7b2294d401e6ad4851e3c7549fc7d23eea017eadd72e3245236b50c7f256de16bae063df6221b8331443c9d3a79e867fd77dd85cee",
|
||||
"0x07062bf32f202ec2afa65dfa84fffc76b5c05309768078544920f9b56d021606ce0b7371683425d088ad37f063ee847a9accac416314f1308cce69a8beeb2d2ab7",
|
||||
"0x090ffc989b8556e69159e246cb74cf7a2e30df63e9b7dba76ede73996ab60d9799063ca19e1d436cea189d17c5d93b8da0fa11b3ee88de1030602d1e8087cbb3da",
|
||||
"0x070000000000000000000000000000000000000000000000000000000000000000084f906a52b7da7bf35f3cc2431b40cfb90884c2ec0b579c9c096aea959509f7",
|
||||
"0x0620b6c0072d699768c0b52df46b97dae979a14788ed54dad1d7ce67db6e036a07291784b726760c2d728e4084d95df6d1534e27284c8ae2eeb56a80210f37da2b",
|
||||
"0x041245637ec55bae3c02f990e3cc3bf59cc05f515731cfa59ee55f8164953f8965050800000000000000000000000000000000000000000000000000ac000000000000000100000000000000000000000000000000000000000000000000000000000000000f68a43f5508e9c1f845406d9a507b612f97530746e59b93c8705f1a7cb0b93451e52f95aea13b1bc1f37dfbf797bfe7cea82a8c82da148f507e1ef2036fea8314b9fb07c4311e129d72b858c37b6bbe09c616f78416cb53d6e83360aff7b99c20c73bfbd94fb1fd860997d4e76d116bde0333beef000000000000000000000000",
|
||||
"0x001988ce414103e97cb80613adde47d5fe0611b30087d1cfcdb84284c42907467e24ac744be2edcb86cdfc42a9bbb7b2a270649161c3ce3a41d3ad5a26927d2c79",
|
||||
"0x0007af09eec4d7cc8903e99bd9fb9b8e57c30b0c3e34b17da769b01a9a1b943f391c4537228dbbfd7e7cce02123416bfdd61fb83577725516123b569eafcd8087d",
|
||||
"0x0013a22efa6a843f6de1925fce2f6a83c7ed307182b16f661d0e7a8046561999393050830a440d2506adf42ccedece4e3aadc6bc80cea20fc1d8ed9e9c61597da0",
|
||||
"0x001056a19427eac81b91de5db696812b3a0384bf41b37a12e9cbb7dc62404a102a1465c13c8d3721e137a64d9e5ba1267ac418339b3648bfab5a2a86f2343c2b4d",
|
||||
"0x000794d2c0e19bc86772c2d1a43d46de87ad221847bddcfdffa19dbd34f3c3a9b507c5f198eb63c18640af5eff5480830147639cec070d276b778f21677d22ce32",
|
||||
"0x000b23d93f98ec6e3536ffcab6afc6e2eb9b73aeb573d288723350366c05469e2e23837ffea9235351ee533af680d14011825e098f81ce3f8f59e9f08deff05e3d",
|
||||
"0x002ad200ac8be8275ef12b8aeaec526d2b5255128968a2cd2ff775cab14e2ec4e907f2e9b849239e0e94332a50ac9d97320c56ca718c5e023cacd69f80b4c97c86",
|
||||
"0x00284be135a2d7f5822a7949189b90696df39b1b183206c764576bf457df4fd1560204a9fc6c0dc199eecb404acfcabf4a633916fc94d2790dcd34959809c2195d",
|
||||
"0x00270c2cd154aea3b575a1c7d47c62576bbdce6bbc7ccf5682e7962cf6cb77f0d317fdbac10917644860584c3057c750df695f529189f90910c30f114257719990",
|
||||
"0x00174956df87889921e2a6ddb257fa84508fd7ea22c5a622b84378678e781a2289053dc6b3c4f91335b64f4b170bfe70bb5e2e316227b329d2b1205e7c62c4f755",
|
||||
"0x002f9284ded18b8f281841094a93cb55b95884eec55d8eaa759c6175ddb2e037111c63bcee8ccf544fff55c3e502270e574d1f0b6265c4c7c6f42db5061b0120db",
|
||||
"0x00065fdf05e66407d26a36a49d042c9c5e8cebab3baa2d3fd1ae6e673c3636cf7e2d9dbf3781e3f26f06fb503638a8bf00882f58dc83500338df4b7e08a290a5fb",
|
||||
"0x00138987046c770f02f5d8e7d073f6c055536450fa55ccd2a23957598b6070297926f3a0b645072c5bd5c15cdcf03a4474e94d760e3a76fb8714b20b9d74608823",
|
||||
"0x00280e7f8e278e02e43843aaba5a9a722a89af0ece06b5892284f825974e1c1984185be1fda9b5322a4c41023127eee438849ea23390e6c2d4d9abdedb5a1a43fc",
|
||||
"0x00208f32072c6e20863710406ad34339da1124c639941e935818dd9ad9419849c91e0e37873df7eb190a2846789df889bbfd522200e2a41423ff9ab0acf2592be0",
|
||||
"0x0005fb23491fabbc9b3eead71117b86a27952e8fd4b3380336ac3f479832e94bad109a1b6dca757696b8831d2529ffda29f37af36f92fec738376df77561491083",
|
||||
"0x0028baee42b4a9a70b7ec1e50ea1a6817f812082a28598dca106aaecf2761fb63c06e5b589490c27f5cfc233890456ec47a7365ff2882a27c73968f4829d011b05",
|
||||
"0x001708247f7a96b84cad27c31985cd39b6cc9435b4ec3f4db9aeed3311c213de651e2f271ae0fa011e5e6fccd121492400327efb915c95d85956a9cd27ceb4321a",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000002332e856217b3bab09901f1daa9ddc91edf56964e03675d260d00ffdf6e2e715",
|
||||
"0x000571dce6fee951f457db89bae18abbd78b6b06504602a103133d2a38cabf5f5b1ecb13b03e3493e217c65da70baf4c4fad74808110658924869ba0e75d0871db",
|
||||
"0x001738a6461148300d30699edb55d3b5bb62760aeb9384c07d61aa062c401f3a7d0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x000c14152707412177bbe1cfed882d7d7bdfca4e96be701a3c41bb3d254491f0bf0096ebc25015b9a40d4fe7490bda8ecb7f3a01e858d7833dce8f1993be4db07d",
|
||||
"0x0117294cb69b0984b3a26d77eae252f9d8e438808bf276ee8c0c0546b7316c9bca05080000000000000000000000000000000000000000000000000ab1000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ed3aa0dd2cd363d4cea5d5283ec359f75be36a12ceddc7f80a58af9d39a418a02b6a0ff9eb34bf0e52f67047f95556a96c4f40822412da0c8bd0340996a754f4209c0fc47d9346e2be1e24f6cef76149779fe52715000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x041d3c5f8c36e5da873d45bfa1d2399a572ac77493ec089cbf88a37b9e9442842201010000000000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x02",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
{
|
||||
block: 95216,
|
||||
desc: "EOA with balance",
|
||||
account: "0x0384a6f7e2588bb251688f9ab8d10932a98e9f28",
|
||||
storage: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
expectedRoot: "0x2dc794537b959b575dc216cd11389d802f9389fce7183278561a824aa8e950e2",
|
||||
expectedValue: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
accountProof: [
|
||||
"0x001988ce414103e97cb80613adde47d5fe0611b30087d1cfcdb84284c42907467e24ac744be2edcb86cdfc42a9bbb7b2a270649161c3ce3a41d3ad5a26927d2c79",
|
||||
"0x0028db7c407cab6652f1f194401bd87bda33c9a1723b4f93515bd5929cad02668123fa5a3e69136c8e03a62c805f89c9d3578a6f5fac4bb281fc4d7df12fbcc5db",
|
||||
"0x0006801926f00b574e3a88162d192482fecba9918b77e133dd77587d9efaf5c7861712d244ac8ad4bc0bffe0dbe8ab261865c9a69b4b7769e9c188ec048460ce78",
|
||||
"0x002f3161746c2c70c7cefb74c07bc16b28bd9011343f5c6f8756471cd0b184601a25d05d5447a572452964b3c20f40ef841bf313c958e82a6923584e20496df67f",
|
||||
"0x0007602275f17f6c339ec3febc879c2ca72efa782ff1888b04553f82333eb0e60c068c8e4fe6da32f7f80a4acb50b690a7204581e5e4b8e9e7daa115dfcb466ae1",
|
||||
"0x000cb512d4ab158b5e7d5852cc7531788f11e64e5959cc1233d7a64eaaca36426116fea9120cf06c241843db50d81978b402281dfe15ba7d8a8c689bfbe0b31a1a",
|
||||
"0x002eb4fff0642f7be6d8e95793d9371d606df48efd0b62a7eb01b0a9669307be2b0ee7d01463afc3dac441f66e675ba06fec67b692e3f7a46510d096836468a3cb",
|
||||
"0x0003ea09dc5b0ca3ce2961d3200c09b837ea535447e3ba45e5583dbb4e9db48b2208abfec237c907584104b11444f55fa3fa7e6f6a5954817ecea6361516f0271b",
|
||||
"0x001c654478a700ac0414f5cd8da557e04f9570939802c3963e801523f001ebb4d916d301b50f89760520da2a662b03a207e9372902153ba84ef0f5438472f466c6",
|
||||
"0x0009f3b0d95ec5d88cfc2db19520f43d110d12c757a58ae7f578095de96e5d319d2c8f43a67b0c01008670f07eb53071b835f19cbb45d6e76281a083087217d988",
|
||||
"0x000348f024d617f64de7be803547c109b98f833b090e8a3dea0c2bed201ce752c12a4fb71f098941741c42e156651d8a42632e3acbf6f14cd9763b50216af75d61",
|
||||
"0x0029f85b49319fe7dfced69a258b1baf213d638fe3082b9a13f38e553e9d3269333054c4cb6d1e91bc2dfced1559b58cd6474ac6583a1fc5a2bef5eaa7b96ecea0",
|
||||
"0x000a4d19e2ec5f98d9ccdc1e94d9334668b87ea451195f9a8319b98cfdb077c5ce1adc64852505188363c7e98b83501e876862d8ffbd8b4051f3cb6dde7f0e8afe",
|
||||
"0x002568d5d87f19b2b3f2b7341ee61fb45f56dc76734beaa4f1a9865b80b9d9a7d500a191ba054a28841f25c34ad384817a2af2ebada6047517dbb2b6a1338e48c7",
|
||||
"0x0027f6df1a3610c7447efd280fa6a949713456a1ba79b50dc7fb87c5cb3312b19311b3c9c4420874b02bdc1ea102dc77bb803c1a5042d565aea99054ae0eb816b2",
|
||||
"0x0018a3d33e2c0d076ca4ddb093516d90cb8ba8b508e8d372d3a8a93aa9eef6079b138df6cb61c8f92dcbea8cd90ead1efa49f3a24f814c88a7bdca8fd83f4d0675",
|
||||
"0x00268f3122e558d5084a1b3ffc293b67bd2436152fbee80566226d4a753b5b44c40b6d06e2f5f17009a7e146889c2f492b077a462d602e0e72f53373a154aa450e",
|
||||
"0x0006c81bc9375fe1a0ebb75b151c8a321b85970c1a8a5aa7396a7076a4d6f26c8118a7e9e0987d7c6d0100180c9ba496db2b967f6acf7bc11d002314693416b3bf",
|
||||
"0x011fb221b659992b8d98a645cb37666f934ded70f1f5d82dad67dace71d7191f8105080000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000d8d6f2b3da41cda2e0000000000000000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864200384a6f7e2588bb251688f9ab8d10932a98e9f28000000000000000000000000",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
storageProof: [
|
||||
"0x02",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
],
|
||||
},
|
||||
@@ -272,9 +195,13 @@ describe("ZkTrieVerifier", async () => {
|
||||
beforeEach(async () => {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
|
||||
const PoseidonHashWithDomainFactory = new ethers.ContractFactory(generateABI(2), createCode(2), deployer);
|
||||
const Poseidon2Elements = new ethers.ContractFactory(
|
||||
poseidonUnit.generateABI(2),
|
||||
poseidonUnit.createCode(2),
|
||||
deployer
|
||||
);
|
||||
|
||||
const poseidon = await PoseidonHashWithDomainFactory.deploy();
|
||||
const poseidon = await Poseidon2Elements.deploy();
|
||||
await poseidon.deployed();
|
||||
|
||||
const MockZkTrieVerifier = await ethers.getContractFactory("MockZkTrieVerifier", deployer);
|
||||
@@ -282,17 +209,6 @@ describe("ZkTrieVerifier", async () => {
|
||||
await verifier.deployed();
|
||||
});
|
||||
|
||||
const shouldRevert = async (test: ITestConfig, reason: string, extra?: string) => {
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
extra || "0x",
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).to.revertedWith(reason);
|
||||
};
|
||||
|
||||
for (const test of testcases) {
|
||||
it(`should succeed for block[${test.block}] desc[${test.desc}] account[${test.account}] storage[${test.storage}]`, async () => {
|
||||
const proof = concat([
|
||||
@@ -308,277 +224,193 @@ describe("ZkTrieVerifier", async () => {
|
||||
});
|
||||
}
|
||||
|
||||
it("should revert, when InvalidBranchNodeType", async () => {
|
||||
it("should revert, when parent node invalid", async () => {
|
||||
const test = testcases[0];
|
||||
for (const i of [0, 1, test.accountProof.length - 3]) {
|
||||
const correct = test.accountProof[i];
|
||||
const prefix = correct.slice(0, 4);
|
||||
for (let b = 0; b < 16; ++b) {
|
||||
if (b >= 6 && b < 10) continue;
|
||||
test.accountProof[i] = test.accountProof[i].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]);
|
||||
await shouldRevert(test, "InvalidBranchNodeType");
|
||||
test.accountProof[i] = correct;
|
||||
}
|
||||
}
|
||||
test.accountProof[0] =
|
||||
"0x010a52b818e0a009930d62c17f2b1244179b7c14f8e1ae317fb3bfd3a3ba6060031b2a4aa2df31e79f926474987eea69aab84f4581cfd61b0338438110f6be145b";
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid parent node");
|
||||
|
||||
for (const i of [0, 1, test.storageProof.length - 3]) {
|
||||
const correct = test.storageProof[i];
|
||||
const prefix = correct.slice(0, 4);
|
||||
for (let b = 0; b < 16; ++b) {
|
||||
if (b >= 6 && b < 10) continue;
|
||||
test.storageProof[i] = test.storageProof[i].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]);
|
||||
await shouldRevert(test, "InvalidBranchNodeType");
|
||||
test.storageProof[i] = correct;
|
||||
}
|
||||
}
|
||||
test.accountProof[0] =
|
||||
"0x000a52b818e0a009930d62c17f2b1244179b7c14f8e1ae317fb3bfd3a3ba6060031b2a4aa2df31e79f926474987eea69aab84f4581cfd61b0338438110f6be145b";
|
||||
test.storageProof[0] =
|
||||
"0x010a52b818e0a009930d62c17f2b1244179b7c14f8e1ae317fb3bfd3a3ba6060031b2a4aa2df31e79f926474987eea69aab84f4581cfd61b0338438110f6be145b";
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid parent node");
|
||||
});
|
||||
|
||||
it("should revert, when BranchHashMismatch", async () => {
|
||||
it("should revert, when hash mismatch", async () => {
|
||||
const test = testcases[0];
|
||||
for (const i of [1, 2, test.accountProof.length - 3]) {
|
||||
const correct = test.accountProof[i];
|
||||
for (const p of [40, 98]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[i] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "BranchHashMismatch");
|
||||
test.accountProof[i] = correct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const i of [1, 2, test.storageProof.length - 3]) {
|
||||
const correct = test.storageProof[i];
|
||||
for (const p of [40, 98]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[i] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "BranchHashMismatch");
|
||||
test.storageProof[i] = correct;
|
||||
}
|
||||
}
|
||||
}
|
||||
test.accountProof[1] =
|
||||
"0x0028db7c407cab6652f1f194401bd87bda33c9a1723b4f93515bd5929cad02668123fa5a3e69136c8e03a62c805f89c9d3578a6f5fac4bb281fc4d7df12fbcc5dc";
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Hash mismatch");
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountLeafNodeType", async () => {
|
||||
it("should revert, when invalid proof magic bytes", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
const prefix = correct.slice(0, 4);
|
||||
for (let b = 0; b < 20; ++b) {
|
||||
if (b === 4 || b === 5) continue;
|
||||
test.accountProof[index] = test.accountProof[index].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]);
|
||||
await shouldRevert(test, "InvalidAccountLeafNodeType");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
test.accountProof[17] =
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704448";
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid ProofMagicBytes");
|
||||
});
|
||||
|
||||
it("should revert, when AccountKeyMismatch", async () => {
|
||||
it("should revert, when invalid leaf node in account proof", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
for (const p of [4, 10]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "AccountKeyMismatch");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
}
|
||||
// Invalid leaf node in account proof
|
||||
test.accountProof[16] =
|
||||
"0x000aef26efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681205300000000000000000000000000000000000004000000000000000000000000";
|
||||
let proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid leaf node");
|
||||
|
||||
// Node key mismatch in account proof
|
||||
test.accountProof[16] =
|
||||
"0x010aef16efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681205300000000000000000000000000000000000004000000000000000000000000";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Node key mismatch");
|
||||
|
||||
// Invalid leaf node hash in account proof
|
||||
test.accountProof[16] =
|
||||
"0x010aef26efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071e0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681205300000000000000000000000000000000000004000000000000000000000000";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid leaf node hash");
|
||||
|
||||
// Invalid KeyPreimage length in account proof
|
||||
test.accountProof[16] =
|
||||
"0x010aef26efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681215300000000000000000000000000000000000004000000000000000000000000";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith(
|
||||
"Invalid KeyPreimage length"
|
||||
);
|
||||
|
||||
// Invalid KeyPreimage in account proof
|
||||
test.accountProof[16] =
|
||||
"0x010aef26efde9e4bca477d460482bce3de3577f6e9a280dea6d3f9985b4151deab0508000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000013328350573dd32b38291529042b30b83bf20bfc7e18ab6a9755e2ea692d5a7644f896b0d629cf9740d72ccbc90dd6141deb3fab132f1ebc17ab963c612c7123d5a524d0158cc8291b081281272d79459760d885ea652024615d55b114b5872571b21aee99977b8681205300000000000000000000000000000000000003000000000000000000000000";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid KeyPreimage");
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountCompressedFlag", async () => {
|
||||
it("should revert, when storage root mismatch", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
for (const replaced of ["01080000", "05010000"]) {
|
||||
test.accountProof[index] = test.accountProof[index].replace("05080000", replaced);
|
||||
await shouldRevert(test, "InvalidAccountCompressedFlag");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
test.storageProof[0] =
|
||||
"0x000a52b818e0a009930d62c17f2b1244179b7c14f8e1ae317fb3bfd3a3ba6060031b2a4aa2df31e79f926474987eea69aab84f4581cfd61b0338438110f6be145c";
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Storage root mismatch");
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountLeafNodeHash", async () => {
|
||||
it("should revert, when invalid leaf node in storage proof", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
for (const p of [80, 112, 144, 176, 208]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidAccountLeafNodeHash");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
}
|
||||
// Invalid leaf node in account proof
|
||||
test.storageProof[15] =
|
||||
"0x0026ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111346048bf18a14a209505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a";
|
||||
let proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid leaf node");
|
||||
|
||||
// Node key mismatch in account proof
|
||||
test.storageProof[15] =
|
||||
"0x0136ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111346048bf18a14a209505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Node key mismatch");
|
||||
|
||||
// Invalid leaf node hash in account proof
|
||||
test.storageProof[15] =
|
||||
"0x0126ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111446048bf18a14a209505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid leaf node hash");
|
||||
|
||||
// Invalid KeyPreimage length in account proof
|
||||
test.storageProof[15] =
|
||||
"0x0126ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111346048bf18a14a219505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b96a";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith(
|
||||
"Invalid KeyPreimage length"
|
||||
);
|
||||
|
||||
// Invalid KeyPreimage in account proof
|
||||
test.storageProof[15] =
|
||||
"0x0126ae15b478408eb45ea8b6f61aad1345f2b6257efd1acc4a6024b26f664c98240101000000000000000000000000000000000000000000000000000111346048bf18a14a209505174b0709a2a1997fe9797cb89648a93f17ce0096cbc1a6ed52b73170b97a";
|
||||
proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Invalid KeyPreimage");
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountKeyPreimageLength", async () => {
|
||||
it("should revert, when proof length mismatch", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
for (const p of [396, 397]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidAccountKeyPreimageLength");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountKeyPreimage", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.accountProof.length - 2;
|
||||
const correct = test.accountProof[index];
|
||||
for (const p of [398, 438]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidAccountKeyPreimage");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidProofMagicBytes", async () => {
|
||||
const test = testcases[0];
|
||||
let index = test.accountProof.length - 1;
|
||||
let correct = test.accountProof[index];
|
||||
for (const p of [2, 32, 91]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.accountProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidProofMagicBytes");
|
||||
test.accountProof[index] = correct;
|
||||
}
|
||||
}
|
||||
|
||||
index = test.storageProof.length - 1;
|
||||
correct = test.storageProof[index];
|
||||
for (const p of [2, 32, 91]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidProofMagicBytes");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidAccountLeafNodeHash", async () => {
|
||||
const test = testcases[0];
|
||||
const correct = test.storageProof.slice();
|
||||
test.storageProof = [
|
||||
"0x05",
|
||||
"0x5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449",
|
||||
];
|
||||
await shouldRevert(test, "InvalidAccountLeafNodeHash");
|
||||
test.storageProof = correct;
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageLeafNodeType", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
const prefix = correct.slice(0, 4);
|
||||
for (let b = 0; b < 20; ++b) {
|
||||
if (b === 4 || b === 5) continue;
|
||||
test.storageProof[index] = test.storageProof[index].replace(prefix, "0x" + chars[b >> 4] + chars[b % 16]);
|
||||
await shouldRevert(test, "InvalidStorageLeafNodeType");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when StorageKeyMismatch", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
for (const p of [4, 10]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "StorageKeyMismatch");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageCompressedFlag", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
for (const replaced of ["00010000", "01000000"]) {
|
||||
test.storageProof[index] = test.storageProof[index].replace("01010000", replaced);
|
||||
await shouldRevert(test, "InvalidStorageCompressedFlag");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageLeafNodeHash", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
for (const p of [100, 132]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidStorageLeafNodeHash");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageKeyPreimageLength", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
for (const p of [140, 141]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidStorageKeyPreimageLength");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageKeyPreimage", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
for (const p of [142, 205]) {
|
||||
const v = correct[p];
|
||||
for (let b = 0; b < 3; ++b) {
|
||||
if (v === chars[b]) continue;
|
||||
test.storageProof[index] = correct.slice(0, p) + chars[b] + correct.slice(p + 1);
|
||||
await shouldRevert(test, "InvalidStorageKeyPreimage");
|
||||
test.storageProof[index] = correct;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("should revert, when InvalidStorageEmptyLeafNodeHash", async () => {
|
||||
const test = testcases[0];
|
||||
const index = test.storageProof.length - 2;
|
||||
const correct = test.storageProof[index];
|
||||
test.storageProof[index] = "0x05";
|
||||
await shouldRevert(test, "InvalidStorageEmptyLeafNodeHash");
|
||||
test.storageProof[index] = correct;
|
||||
});
|
||||
|
||||
it("should revert, when ProofLengthMismatch", async () => {
|
||||
const test = testcases[0];
|
||||
await shouldRevert(test, "ProofLengthMismatch", "0x0000");
|
||||
const proof = concat([
|
||||
`0x${test.accountProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.accountProof,
|
||||
`0x${test.storageProof.length.toString(16).padStart(2, "0")}`,
|
||||
...test.storageProof,
|
||||
"0x00",
|
||||
]);
|
||||
await expect(verifier.verifyZkTrieProof(test.account, test.storage, proof)).revertedWith("Proof length mismatch");
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
import * as dotenv from "dotenv";
|
||||
|
||||
import { ethers } from "hardhat";
|
||||
import { generateABI, createCode } from "../scripts/poseidon";
|
||||
import poseidonUnit from "circomlib/src/poseidon_gencontract";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -15,7 +15,11 @@ async function main() {
|
||||
let PoseidonUnit2Address = process.env.POSEIDON_UNIT2_ADDR;
|
||||
|
||||
if (!PoseidonUnit2Address) {
|
||||
const Poseidon2Elements = new ethers.ContractFactory(generateABI(2), createCode(2), deployer);
|
||||
const Poseidon2Elements = new ethers.ContractFactory(
|
||||
poseidonUnit.generateABI(2),
|
||||
poseidonUnit.createCode(2),
|
||||
deployer
|
||||
);
|
||||
|
||||
const poseidon = await Poseidon2Elements.deploy();
|
||||
console.log("Deploy PoseidonUnit2 contract, hash:", poseidon.deployTransaction.hash);
|
||||
@@ -24,9 +28,7 @@ async function main() {
|
||||
PoseidonUnit2Address = poseidon.address;
|
||||
}
|
||||
|
||||
const verifier = await ScrollChainCommitmentVerifier.deploy(PoseidonUnit2Address, L1ScrollChainAddress, {
|
||||
gasPrice: 1e9,
|
||||
});
|
||||
const verifier = await ScrollChainCommitmentVerifier.deploy(PoseidonUnit2Address, L1ScrollChainAddress);
|
||||
console.log("Deploy ScrollChainCommitmentVerifier contract, hash:", verifier.deployTransaction.hash);
|
||||
const receipt = await verifier.deployTransaction.wait();
|
||||
console.log(`✅ Deploy ScrollChainCommitmentVerifier contract at: ${verifier.address}, gas used: ${receipt.gasUsed}`);
|
||||
|
||||
@@ -31,8 +31,6 @@ import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStanda
|
||||
contract DeployL2BridgeContracts is Script {
|
||||
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
|
||||
|
||||
address L2_PROXY_ADMIN_ADDR = vm.envAddress("L2_PROXY_ADMIN_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");
|
||||
@@ -60,8 +58,6 @@ contract DeployL2BridgeContracts is Script {
|
||||
address L2_WHITELIST_PREDEPLOY_ADDR = vm.envOr("L2_WHITELIST_PREDEPLOY_ADDR", address(0));
|
||||
|
||||
function run() external {
|
||||
proxyAdmin = ProxyAdmin(L2_PROXY_ADMIN_ADDR);
|
||||
|
||||
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
|
||||
|
||||
// predeploys
|
||||
@@ -71,6 +67,7 @@ contract DeployL2BridgeContracts is Script {
|
||||
deployL2Whitelist();
|
||||
|
||||
// upgradable
|
||||
deployProxyAdmin();
|
||||
deployL2ScrollMessenger();
|
||||
deployL2GatewayRouter();
|
||||
deployScrollStandardERC20Factory();
|
||||
@@ -134,6 +131,12 @@ contract DeployL2BridgeContracts is Script {
|
||||
logAddress("L2_WHITELIST_ADDR", address(whitelist));
|
||||
}
|
||||
|
||||
function deployProxyAdmin() internal {
|
||||
proxyAdmin = new ProxyAdmin();
|
||||
|
||||
logAddress("L2_PROXY_ADMIN_ADDR", address(proxyAdmin));
|
||||
}
|
||||
|
||||
function deployL2ScrollMessenger() internal {
|
||||
L2ScrollMessenger impl = new L2ScrollMessenger(L1_SCROLL_MESSENGER_PROXY_ADDR, address(queue));
|
||||
|
||||
|
||||
@@ -78,21 +78,15 @@ contract InitializeL1BridgeContracts is Script {
|
||||
|
||||
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
|
||||
|
||||
// note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...),
|
||||
// otherwise the contract owner would become ProxyAdmin.
|
||||
|
||||
// initialize ScrollChain
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_SCROLL_CHAIN_PROXY_ADDR),
|
||||
L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR
|
||||
L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
ScrollChain.initialize,
|
||||
(L1_MESSAGE_QUEUE_PROXY_ADDR, L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR, MAX_TX_IN_CHUNK)
|
||||
)
|
||||
);
|
||||
|
||||
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize(
|
||||
L1_MESSAGE_QUEUE_PROXY_ADDR,
|
||||
L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR,
|
||||
MAX_TX_IN_CHUNK
|
||||
);
|
||||
|
||||
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDRESS);
|
||||
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDRESS);
|
||||
|
||||
@@ -109,32 +103,35 @@ contract InitializeL1BridgeContracts is Script {
|
||||
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
|
||||
|
||||
// initialize L1MessageQueueWithGasPriceOracle
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_MESSAGE_QUEUE_PROXY_ADDR),
|
||||
L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR
|
||||
L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1MessageQueue.initialize,
|
||||
(
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR,
|
||||
L1_SCROLL_CHAIN_PROXY_ADDR,
|
||||
L1_ENFORCED_TX_GATEWAY_PROXY_ADDR,
|
||||
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
|
||||
MAX_L1_MESSAGE_GAS_LIMIT
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR,
|
||||
L1_SCROLL_CHAIN_PROXY_ADDR,
|
||||
L1_ENFORCED_TX_GATEWAY_PROXY_ADDR,
|
||||
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
|
||||
MAX_L1_MESSAGE_GAS_LIMIT
|
||||
);
|
||||
|
||||
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2();
|
||||
|
||||
// initialize L1ScrollMessenger
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_SCROLL_MESSENGER_PROXY_ADDR),
|
||||
L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR,
|
||||
L1_FEE_VAULT_ADDR,
|
||||
L1_SCROLL_CHAIN_PROXY_ADDR,
|
||||
L1_MESSAGE_QUEUE_PROXY_ADDR
|
||||
L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1ScrollMessenger.initialize,
|
||||
(
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR,
|
||||
L1_FEE_VAULT_ADDR,
|
||||
L1_SCROLL_CHAIN_PROXY_ADDR,
|
||||
L1_MESSAGE_QUEUE_PROXY_ADDR
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// initialize EnforcedTxGateway
|
||||
@@ -150,72 +147,63 @@ contract InitializeL1BridgeContracts is Script {
|
||||
);
|
||||
|
||||
// initialize L1CustomERC20Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
|
||||
L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
|
||||
L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
|
||||
L1_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1CustomERC20Gateway.initialize,
|
||||
(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// initialize L1ERC1155Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_ERC1155_GATEWAY_PROXY_ADDR),
|
||||
L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
|
||||
L2_ERC1155_GATEWAY_PROXY_ADDR,
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(L1ERC1155Gateway.initialize, (L2_ERC1155_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR))
|
||||
);
|
||||
|
||||
// initialize L1ERC721Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_ERC721_GATEWAY_PROXY_ADDR),
|
||||
L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
|
||||
L2_ERC721_GATEWAY_PROXY_ADDR,
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(L1ERC721Gateway.initialize, (L2_ERC721_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR))
|
||||
);
|
||||
|
||||
// initialize L1ETHGateway
|
||||
proxyAdmin.upgrade(ITransparentUpgradeableProxy(L1_ETH_GATEWAY_PROXY_ADDR), L1_ETH_GATEWAY_IMPLEMENTATION_ADDR);
|
||||
|
||||
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
|
||||
L2_ETH_GATEWAY_PROXY_ADDR,
|
||||
L1_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_ETH_GATEWAY_PROXY_ADDR),
|
||||
L1_ETH_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1ETHGateway.initialize,
|
||||
(L2_ETH_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// initialize L1StandardERC20Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
|
||||
L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
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
|
||||
L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1StandardERC20Gateway.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 L1WETHGateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L1_WETH_GATEWAY_PROXY_ADDR),
|
||||
L1_WETH_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
|
||||
L2_WETH_GATEWAY_PROXY_ADDR,
|
||||
L1_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L1_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L1_WETH_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L1WETHGateway.initialize,
|
||||
(L2_WETH_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// set WETH gateway in router
|
||||
|
||||
@@ -67,9 +67,6 @@ contract InitializeL2BridgeContracts is Script {
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
// note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...),
|
||||
// otherwise the contract owner would become ProxyAdmin.
|
||||
|
||||
// initialize L2MessageQueue
|
||||
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).initialize(L2_SCROLL_MESSENGER_PROXY_ADDR);
|
||||
|
||||
@@ -80,13 +77,12 @@ contract InitializeL2BridgeContracts is Script {
|
||||
L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
|
||||
|
||||
// initialize L2ScrollMessenger
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_SCROLL_MESSENGER_PROXY_ADDR),
|
||||
L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR
|
||||
L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(L2ScrollMessenger.initialize, (L1_SCROLL_MESSENGER_PROXY_ADDR))
|
||||
);
|
||||
|
||||
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(L1_SCROLL_MESSENGER_PROXY_ADDR);
|
||||
|
||||
// initialize L2GatewayRouter
|
||||
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize(
|
||||
L2_ETH_GATEWAY_PROXY_ADDR,
|
||||
@@ -94,71 +90,62 @@ contract InitializeL2BridgeContracts is Script {
|
||||
);
|
||||
|
||||
// initialize L2CustomERC20Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
|
||||
L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L2CustomERC20Gateway(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
|
||||
L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
|
||||
L2_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L2CustomERC20Gateway.initialize,
|
||||
(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// initialize L2ERC1155Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_ERC1155_GATEWAY_PROXY_ADDR),
|
||||
L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L2ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR).initialize(
|
||||
L1_ERC1155_GATEWAY_PROXY_ADDR,
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(L2ERC1155Gateway.initialize, (L1_ERC1155_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR))
|
||||
);
|
||||
|
||||
// initialize L2ERC721Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_ERC721_GATEWAY_PROXY_ADDR),
|
||||
L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L2ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR).initialize(
|
||||
L1_ERC721_GATEWAY_PROXY_ADDR,
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(L2ERC721Gateway.initialize, (L1_ERC721_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR))
|
||||
);
|
||||
|
||||
// initialize L2ETHGateway
|
||||
proxyAdmin.upgrade(ITransparentUpgradeableProxy(L2_ETH_GATEWAY_PROXY_ADDR), L2_ETH_GATEWAY_IMPLEMENTATION_ADDR);
|
||||
|
||||
L2ETHGateway(L2_ETH_GATEWAY_PROXY_ADDR).initialize(
|
||||
L1_ETH_GATEWAY_PROXY_ADDR,
|
||||
L2_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_ETH_GATEWAY_PROXY_ADDR),
|
||||
L2_ETH_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L2ETHGateway.initialize,
|
||||
(L1_ETH_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// initialize L2StandardERC20Gateway
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
|
||||
L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
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
|
||||
L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L2StandardERC20Gateway.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
|
||||
proxyAdmin.upgrade(
|
||||
proxyAdmin.upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(L2_WETH_GATEWAY_PROXY_ADDR),
|
||||
L2_WETH_GATEWAY_IMPLEMENTATION_ADDR
|
||||
);
|
||||
|
||||
L2WETHGateway(payable(L2_WETH_GATEWAY_PROXY_ADDR)).initialize(
|
||||
L1_WETH_GATEWAY_PROXY_ADDR,
|
||||
L2_GATEWAY_ROUTER_PROXY_ADDR,
|
||||
L2_SCROLL_MESSENGER_PROXY_ADDR
|
||||
L2_WETH_GATEWAY_IMPLEMENTATION_ADDR,
|
||||
abi.encodeCall(
|
||||
L2WETHGateway.initialize,
|
||||
(L1_WETH_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
|
||||
)
|
||||
);
|
||||
|
||||
// set WETH gateway in router
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/* eslint-disable node/no-missing-import */
|
||||
import { ethers } from "ethers";
|
||||
|
||||
import Contract from "circomlib/src/evmasm";
|
||||
import * as constants from "circomlib/src/poseidon_constants";
|
||||
|
||||
const N_ROUNDS_F = 8;
|
||||
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
|
||||
|
||||
export function createCode(nInputs: number) {
|
||||
if (nInputs < 1 || nInputs > 8) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
||||
const t = nInputs + 1;
|
||||
const nRoundsF = N_ROUNDS_F;
|
||||
const nRoundsP = N_ROUNDS_P[t - 2];
|
||||
|
||||
const C = new Contract();
|
||||
|
||||
function saveM() {
|
||||
for (let i = 0; i < t; i++) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
C.push(constants.M[t - 2][i][j]);
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mstore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ark(r: number) {
|
||||
// st, q
|
||||
for (let i = 0; i < t; i++) {
|
||||
C.dup(t); // q, st, q
|
||||
C.push(constants.C[t - 2][r * t + i]); // K, q, st, q
|
||||
C.dup(2 + i); // st[i], K, q, st, q
|
||||
C.addmod(); // newSt[i], st, q
|
||||
C.swap(1 + i); // xx, st, q
|
||||
C.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function sigma(p: number) {
|
||||
// sq, q
|
||||
C.dup(t); // q, st, q
|
||||
C.dup(1 + p); // st[p] , q , st, q
|
||||
C.dup(1); // q, st[p] , q , st, q
|
||||
C.dup(0); // q, q, st[p] , q , st, q
|
||||
C.dup(2); // st[p] , q, q, st[p] , q , st, q
|
||||
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
|
||||
C.mulmod(); // st2[p], q, st[p] , q , st, q
|
||||
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
|
||||
C.mulmod(); // st4[p], st[p] , q , st, q
|
||||
C.mulmod(); // st5[p], st, q
|
||||
C.swap(1 + p);
|
||||
C.pop(); // newst, q
|
||||
}
|
||||
|
||||
function mix() {
|
||||
C.label("mix");
|
||||
for (let i = 0; i < t; i++) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
if (j === 0) {
|
||||
C.dup(i + t); // q, newSt, oldSt, q
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mload(); // M, q, newSt, oldSt, q
|
||||
C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q
|
||||
C.mulmod(); // acc, newSt, oldSt, q
|
||||
} else {
|
||||
C.dup(1 + i + t); // q, acc, newSt, oldSt, q
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mload(); // M, q, acc, newSt, oldSt, q
|
||||
C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q
|
||||
C.mulmod(); // aux, acc, newSt, oldSt, q
|
||||
C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q
|
||||
C.swap(2); // acc, aux, q, newSt, oldSt, q
|
||||
C.addmod(); // acc, newSt, oldSt, q
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < t; i++) {
|
||||
C.swap(t - i + (t - i - 1));
|
||||
C.pop();
|
||||
}
|
||||
C.push(0);
|
||||
C.mload();
|
||||
C.jmp();
|
||||
}
|
||||
|
||||
// Check selector
|
||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||
C.push(0);
|
||||
C.calldataload();
|
||||
C.div();
|
||||
C.dup(0);
|
||||
C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(uint256[${nInputs}],uint256)`)).slice(0, 10)); // poseidon(uint256[n],uint256)
|
||||
C.eq();
|
||||
C.swap(1);
|
||||
C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(bytes32[${nInputs}],bytes32)`)).slice(0, 10)); // poseidon(bytes32[n],bytes32)
|
||||
C.eq();
|
||||
C.or();
|
||||
C.jmpi("start");
|
||||
C.invalid();
|
||||
|
||||
C.label("start");
|
||||
|
||||
saveM();
|
||||
|
||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||
|
||||
// Load t values from the call data.
|
||||
// The function has a single array param param
|
||||
// [Selector (4)] [item1 (32)] [item2 (32)] .... [doman (32)]
|
||||
// Stack positions 0-nInputs.
|
||||
for (let i = 0; i < nInputs; i++) {
|
||||
C.push(0x04 + 0x20 * (nInputs - i - 1));
|
||||
C.calldataload();
|
||||
}
|
||||
C.push(0x04 + 0x20 * nInputs);
|
||||
C.calldataload();
|
||||
|
||||
for (let i = 0; i < nRoundsF + nRoundsP; i++) {
|
||||
ark(i);
|
||||
if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
sigma(j);
|
||||
}
|
||||
} else {
|
||||
sigma(0);
|
||||
}
|
||||
const strLabel = "aferMix" + i;
|
||||
C._pushLabel(strLabel);
|
||||
C.push(0);
|
||||
C.mstore();
|
||||
C.jmp("mix");
|
||||
C.label(strLabel);
|
||||
}
|
||||
|
||||
C.push("0x00");
|
||||
C.mstore(); // Save it to pos 0;
|
||||
C.push("0x20");
|
||||
C.push("0x00");
|
||||
C.return();
|
||||
|
||||
mix();
|
||||
|
||||
return C.createTxData();
|
||||
}
|
||||
|
||||
export function generateABI(nInputs: number) {
|
||||
return [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [
|
||||
{
|
||||
internalType: `bytes32[${nInputs}]`,
|
||||
name: "input",
|
||||
type: `bytes32[${nInputs}]`,
|
||||
},
|
||||
{
|
||||
internalType: "bytes32",
|
||||
name: "domain",
|
||||
type: "bytes32",
|
||||
},
|
||||
],
|
||||
name: "poseidon",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bytes32",
|
||||
name: "",
|
||||
type: "bytes32",
|
||||
},
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: "pure",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [
|
||||
{
|
||||
internalType: `uint256[${nInputs}]`,
|
||||
name: "input",
|
||||
type: `uint256[${nInputs}]`,
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "domain",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
name: "poseidon",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: "pure",
|
||||
type: "function",
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pragma solidity =0.8.16;
|
||||
|
||||
import {IScrollChain} from "./IScrollChain.sol";
|
||||
import {ScrollChain} from "./ScrollChain.sol";
|
||||
import {ZkTrieVerifier} from "../../libraries/verifier/ZkTrieVerifier.sol";
|
||||
|
||||
contract ScrollChainCommitmentVerifier {
|
||||
@@ -49,11 +49,11 @@ contract ScrollChainCommitmentVerifier {
|
||||
bytes32 storageKey,
|
||||
bytes calldata proof
|
||||
) external view returns (bytes32 storageValue) {
|
||||
require(IScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized");
|
||||
require(ScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized");
|
||||
|
||||
bytes32 computedStateRoot;
|
||||
(computedStateRoot, storageValue) = ZkTrieVerifier.verifyZkTrieProof(poseidon, account, storageKey, proof);
|
||||
bytes32 expectedStateRoot = IScrollChain(rollup).finalizedStateRoots(batchIndex);
|
||||
bytes32 expectedStateRoot = ScrollChain(rollup).finalizedStateRoots(batchIndex);
|
||||
require(computedStateRoot == expectedStateRoot, "Invalid inclusion proof");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
pragma solidity ^0.8.16;
|
||||
|
||||
// solhint-disable no-inline-assembly
|
||||
interface PoseidonUnit2 {
|
||||
function poseidon(uint256[2] memory) external view returns (uint256);
|
||||
}
|
||||
|
||||
library ZkTrieVerifier {
|
||||
/// @notice Internal function to validates a proof from eth_getProof.
|
||||
@@ -56,20 +58,19 @@ library ZkTrieVerifier {
|
||||
}
|
||||
}
|
||||
// compute poseidon hash of two uint256
|
||||
function poseidon_hash(hasher, v0, v1, domain) -> r {
|
||||
function poseidon_hash(hasher, v0, v1) -> r {
|
||||
let x := mload(0x40)
|
||||
// keccack256("poseidon(uint256[2],uint256)")
|
||||
mstore(x, 0xa717016c00000000000000000000000000000000000000000000000000000000)
|
||||
// keccack256("poseidon(uint256[2])")
|
||||
mstore(x, 0x29a5f2f600000000000000000000000000000000000000000000000000000000)
|
||||
mstore(add(x, 0x04), v0)
|
||||
mstore(add(x, 0x24), v1)
|
||||
mstore(add(x, 0x44), domain)
|
||||
let success := staticcall(gas(), hasher, x, 0x64, 0x20, 0x20)
|
||||
let success := staticcall(gas(), hasher, x, 0x44, 0x20, 0x20)
|
||||
require(success, "poseidon hash failed")
|
||||
r := mload(0x20)
|
||||
}
|
||||
// compute poseidon hash of 1 uint256
|
||||
function hash_uint256(hasher, v) -> r {
|
||||
r := poseidon_hash(hasher, shr(128, v), and(v, 0xffffffffffffffffffffffffffffffff), 512)
|
||||
r := poseidon_hash(hasher, shr(128, v), and(v, 0xffffffffffffffffffffffffffffffff))
|
||||
}
|
||||
|
||||
// traverses the tree from the root to the node before the leaf.
|
||||
@@ -89,16 +90,15 @@ library ZkTrieVerifier {
|
||||
} {
|
||||
// must be a parent node with two children
|
||||
let nodeType := byte(0, calldataload(ptr))
|
||||
// 6 <= nodeType && nodeType < 10
|
||||
require(lt(sub(nodeType, 6), 4), "InvalidBranchNodeType")
|
||||
ptr := add(ptr, 1)
|
||||
require(eq(nodeType, 0), "Invalid parent node")
|
||||
|
||||
// load left/right child hash
|
||||
let childHashL := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20)
|
||||
let childHashR := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20)
|
||||
let hash := poseidon_hash(hasher, childHashL, childHashR, nodeType)
|
||||
let hash := poseidon_hash(hasher, childHashL, childHashR)
|
||||
|
||||
// first item is considered the root node.
|
||||
// Otherwise verifies that the hash of the current node
|
||||
@@ -108,7 +108,7 @@ library ZkTrieVerifier {
|
||||
rootHash := hash
|
||||
}
|
||||
default {
|
||||
require(eq(hash, expectedHash), "BranchHashMismatch")
|
||||
require(eq(hash, expectedHash), "Hash mismatch")
|
||||
}
|
||||
|
||||
// decide which path to walk based on key
|
||||
@@ -130,132 +130,129 @@ library ZkTrieVerifier {
|
||||
x := keccak256(x, 0x2d)
|
||||
require(
|
||||
eq(x, 0x950654da67865a81bc70e45f3230f5179f08e29c66184bf746f71050f117b3b8),
|
||||
"InvalidProofMagicBytes"
|
||||
"Invalid ProofMagicBytes"
|
||||
)
|
||||
ptr := add(ptr, 0x2d) // skip ProofMagicBytes
|
||||
}
|
||||
|
||||
function verifyAccountProof(hasher, _account, _ptr) -> ptr, storageRootHash, _stateRoot {
|
||||
ptr := _ptr
|
||||
|
||||
let leafHash
|
||||
let key := hash_uint256(hasher, shl(96, _account))
|
||||
|
||||
// `stateRoot` is a return value and must be checked by the caller
|
||||
ptr, _stateRoot, leafHash := walkTree(hasher, key, ptr)
|
||||
|
||||
switch byte(0, calldataload(ptr))
|
||||
case 4 {
|
||||
// nonempty leaf node
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(calldataload(ptr), key), "AccountKeyMismatch")
|
||||
ptr := add(ptr, 0x20) // skip NodeKey
|
||||
require(eq(shr(224, calldataload(ptr)), 0x05080000), "InvalidAccountCompressedFlag")
|
||||
ptr := add(ptr, 0x04) // skip CompressedFlag
|
||||
|
||||
// compute value hash for State Account Leaf Node, details can be found in
|
||||
// https://github.com/scroll-tech/mpt-circuit/blob/v0.7/spec/mpt-proof.md#account-segmenttypes
|
||||
// [nonce||codesize||0, balance, storage_root, keccak codehash, poseidon codehash]
|
||||
mstore(0x00, calldataload(ptr))
|
||||
ptr := add(ptr, 0x20) // skip nonce||codesize||0
|
||||
mstore(0x00, poseidon_hash(hasher, mload(0x00), calldataload(ptr), 1280))
|
||||
ptr := add(ptr, 0x20) // skip balance
|
||||
storageRootHash := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20) // skip StorageRoot
|
||||
let tmpHash := hash_uint256(hasher, calldataload(ptr))
|
||||
ptr := add(ptr, 0x20) // skip KeccakCodeHash
|
||||
tmpHash := poseidon_hash(hasher, storageRootHash, tmpHash, 1280)
|
||||
tmpHash := poseidon_hash(hasher, mload(0x00), tmpHash, 1280)
|
||||
tmpHash := poseidon_hash(hasher, tmpHash, calldataload(ptr), 1280)
|
||||
ptr := add(ptr, 0x20) // skip PoseidonCodeHash
|
||||
|
||||
tmpHash := poseidon_hash(hasher, key, tmpHash, 4)
|
||||
require(eq(leafHash, tmpHash), "InvalidAccountLeafNodeHash")
|
||||
|
||||
require(eq(0x20, byte(0, calldataload(ptr))), "InvalidAccountKeyPreimageLength")
|
||||
ptr := add(ptr, 0x01) // skip KeyPreimage length
|
||||
require(eq(shl(96, _account), calldataload(ptr)), "InvalidAccountKeyPreimage")
|
||||
ptr := add(ptr, 0x20) // skip KeyPreimage
|
||||
}
|
||||
case 5 {
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
}
|
||||
default {
|
||||
revertWith("InvalidAccountLeafNodeType")
|
||||
}
|
||||
|
||||
// compare ProofMagicBytes
|
||||
ptr := checkProofMagicBytes(hasher, ptr)
|
||||
}
|
||||
|
||||
function verifyStorageProof(hasher, _storageKey, storageRootHash, _ptr) -> ptr, _storageValue {
|
||||
ptr := _ptr
|
||||
|
||||
let leafHash
|
||||
let key := hash_uint256(hasher, _storageKey)
|
||||
let rootHash
|
||||
ptr, rootHash, leafHash := walkTree(hasher, key, ptr)
|
||||
|
||||
// The root hash of the storage tree must match the value from the account leaf.
|
||||
// But when the leaf node is the same as the root node, the function `walkTree` will return
|
||||
// `rootHash=0` and `leafHash=0`. In such case, we don't need to check the value of `rootHash`.
|
||||
// And the value of `leafHash` should be the same as `storageRootHash`.
|
||||
switch rootHash
|
||||
case 0 {
|
||||
leafHash := storageRootHash
|
||||
}
|
||||
default {
|
||||
require(eq(rootHash, storageRootHash), "StorageRootMismatch")
|
||||
}
|
||||
|
||||
switch byte(0, calldataload(ptr))
|
||||
case 4 {
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(calldataload(ptr), key), "StorageKeyMismatch")
|
||||
ptr := add(ptr, 0x20) // skip NodeKey
|
||||
require(eq(shr(224, calldataload(ptr)), 0x01010000), "InvalidStorageCompressedFlag")
|
||||
ptr := add(ptr, 0x04) // skip CompressedFlag
|
||||
_storageValue := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20) // skip StorageValue
|
||||
|
||||
// compute leaf node hash and compare, details can be found in
|
||||
// https://github.com/scroll-tech/mpt-circuit/blob/v0.7/spec/mpt-proof.md#storage-segmenttypes
|
||||
mstore(0x00, hash_uint256(hasher, _storageValue))
|
||||
mstore(0x00, poseidon_hash(hasher, key, mload(0x00), 4))
|
||||
require(eq(leafHash, mload(0x00)), "InvalidStorageLeafNodeHash")
|
||||
|
||||
require(eq(0x20, byte(0, calldataload(ptr))), "InvalidStorageKeyPreimageLength")
|
||||
ptr := add(ptr, 0x01) // skip KeyPreimage length
|
||||
require(eq(_storageKey, calldataload(ptr)), "InvalidStorageKeyPreimage")
|
||||
ptr := add(ptr, 0x20) // skip KeyPreimage
|
||||
}
|
||||
case 5 {
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(leafHash, 0), "InvalidStorageEmptyLeafNodeHash")
|
||||
}
|
||||
default {
|
||||
revertWith("InvalidStorageLeafNodeType")
|
||||
}
|
||||
|
||||
// compare ProofMagicBytes
|
||||
ptr := checkProofMagicBytes(hasher, ptr)
|
||||
}
|
||||
|
||||
let storageRootHash
|
||||
// shared variable names
|
||||
let storageHash
|
||||
// starting point
|
||||
let ptr := proof.offset
|
||||
|
||||
// check the correctness of account proof
|
||||
ptr, storageRootHash, stateRoot := verifyAccountProof(poseidon, account, ptr)
|
||||
// verify account proof
|
||||
{
|
||||
let leafHash
|
||||
let key := hash_uint256(poseidon, shl(96, account))
|
||||
|
||||
// check the correctness of storage proof
|
||||
ptr, storageValue := verifyStorageProof(poseidon, storageKey, storageRootHash, ptr)
|
||||
// `stateRoot` is a return value and must be checked by the caller
|
||||
ptr, stateRoot, leafHash := walkTree(poseidon, key, ptr)
|
||||
|
||||
require(eq(1, byte(0, calldataload(ptr))), "Invalid leaf node")
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(calldataload(ptr), key), "Node key mismatch")
|
||||
ptr := add(ptr, 0x20) // skip NodeKey
|
||||
{
|
||||
let valuePreimageLength := and(shr(224, calldataload(ptr)), 0xffff)
|
||||
// @todo check CompressedFlag
|
||||
ptr := add(ptr, 0x04) // skip CompressedFlag
|
||||
ptr := add(ptr, valuePreimageLength) // skip ValuePreimage
|
||||
}
|
||||
|
||||
// compute value hash for State Account Leaf Node
|
||||
{
|
||||
let tmpHash1 := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20) // skip nonce/codesize/0
|
||||
tmpHash1 := poseidon_hash(poseidon, tmpHash1, calldataload(ptr))
|
||||
ptr := add(ptr, 0x20) // skip balance
|
||||
storageHash := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20) // skip StorageRoot
|
||||
let tmpHash2 := hash_uint256(poseidon, calldataload(ptr))
|
||||
ptr := add(ptr, 0x20) // skip KeccakCodeHash
|
||||
tmpHash2 := poseidon_hash(poseidon, storageHash, tmpHash2)
|
||||
tmpHash2 := poseidon_hash(poseidon, tmpHash1, tmpHash2)
|
||||
tmpHash2 := poseidon_hash(poseidon, tmpHash2, calldataload(ptr))
|
||||
ptr := add(ptr, 0x20) // skip PoseidonCodeHash
|
||||
|
||||
tmpHash1 := poseidon_hash(poseidon, 1, key)
|
||||
tmpHash1 := poseidon_hash(poseidon, tmpHash1, tmpHash2)
|
||||
|
||||
require(eq(leafHash, tmpHash1), "Invalid leaf node hash")
|
||||
}
|
||||
|
||||
require(eq(0x20, byte(0, calldataload(ptr))), "Invalid KeyPreimage length")
|
||||
ptr := add(ptr, 0x01) // skip KeyPreimage length
|
||||
require(eq(shl(96, account), calldataload(ptr)), "Invalid KeyPreimage")
|
||||
ptr := add(ptr, 0x20) // skip KeyPreimage
|
||||
|
||||
// compare ProofMagicBytes
|
||||
ptr := checkProofMagicBytes(poseidon, ptr)
|
||||
}
|
||||
|
||||
// verify storage proof
|
||||
{
|
||||
let leafHash
|
||||
let key := hash_uint256(poseidon, storageKey)
|
||||
{
|
||||
let rootHash
|
||||
ptr, rootHash, leafHash := walkTree(poseidon, key, ptr)
|
||||
|
||||
switch rootHash
|
||||
case 0 {
|
||||
// in the case that the leaf is the only element, then
|
||||
// the hash of the leaf must match the value from the account leaf
|
||||
require(eq(leafHash, storageHash), "Storage root mismatch")
|
||||
}
|
||||
default {
|
||||
// otherwise the root hash of the storage tree
|
||||
// must match the value from the account leaf
|
||||
require(eq(rootHash, storageHash), "Storage root mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
switch byte(0, calldataload(ptr))
|
||||
case 1 {
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(calldataload(ptr), key), "Node key mismatch")
|
||||
ptr := add(ptr, 0x20) // skip NodeKey
|
||||
{
|
||||
let valuePreimageLength := and(shr(224, calldataload(ptr)), 0xffff)
|
||||
// @todo check CompressedFlag
|
||||
ptr := add(ptr, 0x04) // skip CompressedFlag
|
||||
ptr := add(ptr, valuePreimageLength) // skip ValuePreimage
|
||||
}
|
||||
|
||||
storageValue := calldataload(ptr)
|
||||
ptr := add(ptr, 0x20) // skip StorageValue
|
||||
|
||||
mstore(0x00, hash_uint256(poseidon, storageValue))
|
||||
key := poseidon_hash(poseidon, 1, key)
|
||||
mstore(0x00, poseidon_hash(poseidon, key, mload(0x00)))
|
||||
require(eq(leafHash, mload(0x00)), "Invalid leaf node hash")
|
||||
|
||||
require(eq(0x20, byte(0, calldataload(ptr))), "Invalid KeyPreimage length")
|
||||
ptr := add(ptr, 0x01) // skip KeyPreimage length
|
||||
require(eq(storageKey, calldataload(ptr)), "Invalid KeyPreimage")
|
||||
ptr := add(ptr, 0x20) // skip KeyPreimage
|
||||
}
|
||||
case 2 {
|
||||
ptr := add(ptr, 0x01) // skip NodeType
|
||||
require(eq(leafHash, 0), "Invalid empty node hash")
|
||||
}
|
||||
default {
|
||||
revertWith("Invalid leaf node")
|
||||
}
|
||||
|
||||
// compare ProofMagicBytes
|
||||
ptr := checkProofMagicBytes(poseidon, ptr)
|
||||
}
|
||||
|
||||
// the one and only boundary check
|
||||
// in case an attacker crafted a malicous payload
|
||||
// and succeeds in the prior verification steps
|
||||
// then this should catch any bogus accesses
|
||||
if iszero(eq(ptr, add(proof.offset, proof.length))) {
|
||||
revertWith("ProofLengthMismatch")
|
||||
revertWith("Proof length mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func testResetDB(t *testing.T) {
|
||||
cur, err := Current(pgDB.DB)
|
||||
assert.NoError(t, err)
|
||||
// total number of tables.
|
||||
assert.Equal(t, 15, int(cur))
|
||||
assert.Equal(t, 14, int(cur))
|
||||
}
|
||||
|
||||
func testMigrate(t *testing.T) {
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
CREATE TABLE pending_transaction
|
||||
(
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- context info
|
||||
context_id VARCHAR NOT NULL, -- batch hash in commit/finalize tx, block hash in update gas oracle tx
|
||||
hash VARCHAR NOT NULL,
|
||||
status SMALLINT NOT NULL,
|
||||
rlp_encoding BYTEA NOT NULL,
|
||||
|
||||
-- debug info
|
||||
chain_id BIGINT NOT NULL,
|
||||
type SMALLINT NOT NULL,
|
||||
gas_tip_cap BIGINT NOT NULL,
|
||||
gas_fee_cap BIGINT NOT NULL, -- based on geth's implementation, it's gas price in legacy tx.
|
||||
gas_limit BIGINT NOT NULL,
|
||||
nonce BIGINT NOT NULL,
|
||||
submit_block_number BIGINT NOT NULL,
|
||||
|
||||
-- sender info
|
||||
sender_name VARCHAR NOT NULL,
|
||||
sender_service VARCHAR NOT NULL,
|
||||
sender_address VARCHAR NOT NULL,
|
||||
sender_type SMALLINT NOT NULL,
|
||||
|
||||
created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP(0) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX unique_idx_pending_transaction_on_hash ON pending_transaction(hash);
|
||||
CREATE INDEX idx_pending_transaction_on_sender_type_status_nonce_gas_fee_cap ON pending_transaction (sender_type, status, nonce, gas_fee_cap);
|
||||
CREATE INDEX idx_pending_transaction_on_sender_address_nonce ON pending_transaction(sender_address, nonce);
|
||||
|
||||
COMMENT ON COLUMN pending_transaction.sender_type IS 'unknown, commit batch, finalize batch, L1 gas oracle, L2 gas oracle';
|
||||
COMMENT ON COLUMN pending_transaction.status IS 'unknown, pending, replaced, confirmed, confirmed failed';
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS pending_transaction;
|
||||
-- +goose StatementEnd
|
||||
261
go.work.sum
261
go.work.sum
@@ -1,15 +1,5 @@
|
||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||
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 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
|
||||
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
@@ -18,39 +8,29 @@ cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZ
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/bigtable v1.2.0 h1:F4cCmA4nuV84V5zYQ3MKY+M1Cw1avHDuf3S/LcZPA9c=
|
||||
cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
|
||||
cloud.google.com/go/compute/metadata v0.2.0 h1:nBbNSZyDpkNlo3DepaaLKVuO7ClyifSAmNloSCZrHnQ=
|
||||
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0 h1:RPUcBvDeYgQFMfQu1eBMq6piD1SXmLH+vK3qjewZPus=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
collectd.org v0.3.0 h1:iNBHGw1VvPJxH2B6RiFWFZ+vsjo1lCdRszBeOuwGi00=
|
||||
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
|
||||
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 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
@@ -108,14 +88,12 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1/go.mod h1:4qFor3D/HDsvBME35Xy9rwW9DecL+M2sNw1ybjPtwA0=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ClickHouse/ch-go v0.55.0/go.mod h1:kQT2f+yp2p+sagQA/7kS6G3ukym+GQ5KAu1kuFAFDiU=
|
||||
github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTYWhsuQ99aw=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.2.0 h1:dj00TDKY+xwuTJdbpspCSmTLFyWzRJerTHwaBxut1C0=
|
||||
@@ -130,7 +108,6 @@ github.com/CloudyKit/jet/v3 v3.0.0 h1:1PwO5w5VCtlUUl+KTOBsTGZlhjWkcybsGaAau52tOy
|
||||
github.com/CloudyKit/jet/v6 v6.1.0 h1:hvO96X345XagdH1fAoBjpBYG4a1ghhL/QzalkduPuXk=
|
||||
github.com/CloudyKit/jet/v6 v6.1.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
@@ -157,7 +134,6 @@ github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e
|
||||
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
|
||||
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 h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
@@ -169,13 +145,11 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db h1:nxAtV4VajJDhKysp2kdcJZsq8Ss1xSA0vZTkVHHJd0E=
|
||||
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 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
|
||||
github.com/avast/retry-go/v4 v4.1.0 h1:CwudD9anYv6JMVnDuTRlK6kLo4dBamiL+F3U8YDiyfg=
|
||||
github.com/avast/retry-go/v4 v4.1.0/go.mod h1:HqmLvS2VLdStPCGDFjSuZ9pzlTqVRldCI4w2dO4m1Ms=
|
||||
@@ -230,15 +204,12 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
|
||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible h1:Ppm0npCCsmuR9oQaBtRuZcmILVE74aXE+AmrJj8L2ns=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
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 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo=
|
||||
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
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/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||
@@ -255,12 +226,10 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3
|
||||
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/c-bata/go-prompt v0.2.2 h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e0=
|
||||
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
@@ -269,19 +238,15 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA=
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/cloudflare/cloudflare-go v0.79.0 h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M=
|
||||
@@ -329,7 +294,6 @@ github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c h1:/ovYnF02fwL0kvspmy9AuyKg1JhdTRUgPw4nUxd9oZM=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA=
|
||||
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
@@ -338,7 +302,6 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPc
|
||||
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/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
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/denisenkom/go-mssqldb v0.12.2 h1:1OcPn5GBIobjWNd+8yjfHNIaFX14B1pWI3F9HZy5KXw=
|
||||
@@ -349,12 +312,9 @@ github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN
|
||||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA=
|
||||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
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 h1:akOQj8IVgoeFfBTzGOEQakCYshWD6RNo1M5pivFXt70=
|
||||
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 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/djherbis/atime v1.1.0 h1:rgwVbP/5by8BvvjBNrbh64Qz33idKT3pSnMSJsxhi0g=
|
||||
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
||||
@@ -388,7 +348,6 @@ github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||
github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM=
|
||||
@@ -397,13 +356,11 @@ github.com/elastic/go-sysinfo v1.11.1/go.mod h1:6KQb31j0QeWBDF88jIdWSxE8cwoOB9tO
|
||||
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
|
||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d h1:QyzYnTnPE15SQyUeqU6qLbWxMkwyAyu+vGksa0b7j00=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s=
|
||||
@@ -427,7 +384,6 @@ github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nI
|
||||
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 h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc=
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
|
||||
@@ -438,7 +394,6 @@ github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732 h1:AB7YjNrzlVHsY
|
||||
github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732/go.mod h1:o/XfIXWi4/GqbQirfRm5uTbXMG5NpqxkxblnbZ+QM9I=
|
||||
github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b h1:vMT47RYsrftsHSTQhqXwC3BYflo38OLC3Y4LtXtLyU0=
|
||||
github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b/go.mod h1:CDncRYVRSDqwakm282WEkjfaAj1hxU/v5RXxk5nXOiI=
|
||||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/getkin/kin-openapi v0.61.0 h1:6awGqF5nG5zkVpMsAih1QH4VgzS8phTxECUWIFo7zko=
|
||||
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM=
|
||||
@@ -450,9 +405,7 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd h1:r04MMPyLHj/QwZuMJ5+7tJcBr1AQjpiAK/rZWRrQT7o=
|
||||
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 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
|
||||
github.com/go-chi/chi/v5 v5.0.0 h1:DBPx88FjZJH3FsICfDAfIfnb7XxKIYVGG6lOPlhENAg=
|
||||
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
|
||||
@@ -461,9 +414,7 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop
|
||||
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
|
||||
github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
|
||||
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 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
@@ -473,7 +424,6 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
@@ -496,7 +446,6 @@ github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJ
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
@@ -512,10 +461,8 @@ github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
|
||||
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA=
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
@@ -525,21 +472,13 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2V
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec h1:lJwO/92dFXWeXOZdoGXgptLmNLwynMSHUmU6besqtiw=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
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 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
|
||||
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 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
@@ -549,21 +488,22 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.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.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219 h1:utua3L2IbQJmauC5IXdEA547bcoU5dozgQAfc8Onsg4=
|
||||
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 h1:y0Wmhvml7cGnzPa9nocn/fMraMH/lMDdeG+rkx4VgYY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/flatbuffers v1.11.0 h1:O7CEyB8Cb3/DmtxODGtLHcEvpr81Jm5qLg/hsHnxA2A=
|
||||
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.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -578,13 +518,9 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
|
||||
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64=
|
||||
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc h1:DLpL8pWq0v4JYoRpEhDfsJhhJyGKCcQM2WPW2TJs31c=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
@@ -594,20 +530,16 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.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 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
@@ -632,8 +564,7 @@ github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZn
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw=
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU=
|
||||
@@ -650,7 +581,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3
|
||||
github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91 h1:KyZDvZ/GGn+r+Y3DKZ7UOQ/TP4xV6HNkrwiVMB1GnNY=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
@@ -663,7 +593,6 @@ github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.65.1 h1:77BcVUCzvN5HMm8+j9PRBQ4iZcu98Dl4Y9rf+J5vhnc=
|
||||
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=
|
||||
@@ -671,19 +600,12 @@ github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrp
|
||||
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/influxql v1.1.1-0.20200828144457-65d3ef77d385 h1:ED4e5Cc3z5vSN2Tz2GkOHN7vs4Sxe2yds6CXvDnvZFE=
|
||||
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/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 h1:kXn3p0D7zPw16rOtfDR+wo6aaiH8tSMfhPwONTxrlEc=
|
||||
github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
|
||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6 h1:UzJnB7VRL4PSkUJHwsyzseGOmrO/r4yA+AuxGJxiZmA=
|
||||
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 h1:MHTrDWmQpHq/hkq+7cw9oYAt2PqUw52TZazRA0N7PGE=
|
||||
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 h1:+TUUmaFa4YD1Q+7bH9o5NCHQGPMqZCYJiNW6lIIS9z4=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||
github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4=
|
||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=
|
||||
github.com/iris-contrib/httpexpect/v2 v2.3.1 h1:A69ilxKGW1jDRKK5UAhjTL4uJYh3RjD4qzt9vNZ7fpY=
|
||||
@@ -741,24 +663,18 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jsternberg/zap-logfmt v1.0.0 h1:0Dz2s/eturmdUS34GM82JwNEdQ9hPoJgqptcEKcbpzY=
|
||||
github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
|
||||
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok=
|
||||
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618 h1:MK144iBQF9hTSwBW/9eJm034bVoG30IshVm688T2hi8=
|
||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073 h1:WQM1NildKThwdP7qWrNAFGzp4ijNLw8RlgENkaI4MJs=
|
||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||
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 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0=
|
||||
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 h1:2jNeR4YUziVtswNP9sEFAI913cVrzH85T+8Q6LpYbT0=
|
||||
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
|
||||
github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559 h1:0VWDXPNE0brOek1Q8bLfzKkvOzwbQE/snjGojlCr8CY=
|
||||
github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
@@ -791,12 +707,10 @@ github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwf
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
|
||||
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
|
||||
github.com/klauspost/compress v1.4.0 h1:8nsMz3tWa9SWWPL60G1V6CUsf4lLjWLTNEtibhe8gh8=
|
||||
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.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
@@ -809,21 +723,16 @@ github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/d
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 h1:KAZ1BW2TCmT6PRihDPpocIy1QTtsAsrx6TneU/4+CMg=
|
||||
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
||||
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada h1:3L+neHp83cTjegPdCiOxVOJtRIy7/8RldvMTsyPYH10=
|
||||
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
@@ -833,13 +742,11 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F
|
||||
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
|
||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
@@ -854,17 +761,13 @@ github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd h1:HvFwW+cm9bCbZ/+vuGN
|
||||
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o=
|
||||
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.4/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.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
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=
|
||||
@@ -872,12 +775,8 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104 h1:d8RFOZ2IiFtFWBcKEHAFYJcPTf0wY5q0exFNJZVWa1U=
|
||||
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
|
||||
github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@@ -902,7 +801,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
|
||||
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||
github.com/mmcloughlin/profile v0.1.1 h1:jhDmAqPyebOsVDOCICJoINoLb/AnLBaUw58nFzxWS2w=
|
||||
@@ -916,9 +814,7 @@ github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt
|
||||
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY=
|
||||
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 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
|
||||
@@ -960,19 +856,17 @@ github.com/onsi/ginkgo/v2 v2.7.0 h1:/XxtEV3I3Eif/HobnVx9YmJgk8ENdRsuUmM+fLCFNow=
|
||||
github.com/onsi/ginkgo/v2 v2.8.1 h1:xFTEVwOFa1D/Ty24Ws1npBWkDYEV9BqZrsDxVrVkrrU=
|
||||
github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
|
||||
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||
github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M=
|
||||
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/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
|
||||
github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/paulbellamy/ratecounter v0.2.0 h1:2L/RhJq+HA8gBQImDXtLPrDXK5qAj6ozWVK/zFXVJGs=
|
||||
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
|
||||
github.com/paulmach/orb v0.7.1 h1:Zha++Z5OX/l168sqHK3k4z18LDvr+YAO/VjK0ReQ9rU=
|
||||
github.com/paulmach/orb v0.7.1/go.mod h1:FWRlTgl88VI1RBx/MkrwWDRhQ96ctqMCh8boXhmqB/A=
|
||||
github.com/paulmach/orb v0.9.2/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
@@ -984,13 +878,10 @@ github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwb
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/penglongli/gin-metrics v0.1.10/go.mod h1:wxGsGUwpVGv3hmYSxQn2GZgRL3YuCgiRFq2d0X6+EOU=
|
||||
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 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
@@ -1004,7 +895,6 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgc
|
||||
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/term v0.0.0-20180730021639-bffc007b7fd5 h1:tFwafIEMf0B7NlcxV/zJ6leBIa81D3hgGSgsE5hCkOQ=
|
||||
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
@@ -1013,21 +903,17 @@ github.com/pressly/goose/v3 v3.11.2 h1:QgTP45FhBBHdmf7hWKlbWFHtwPtxo0phSDkwDKGUr
|
||||
github.com/pressly/goose/v3 v3.11.2/go.mod h1:LWQzSc4vwfHA/3B8getTp8g3J5Z8tFBxgxinmGlMlJk=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
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 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
@@ -1035,7 +921,6 @@ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
@@ -1046,9 +931,7 @@ github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52 h1:RnWNS9Hlm8BIkjr6wx8li5abe0fr73jljLycdfemTp0=
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
@@ -1074,9 +957,7 @@ github.com/scroll-tech/go-ethereum v1.10.14-0.20230802095950-4b2bbf6225e7/go.mod
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
|
||||
github.com/scroll-tech/zktrie v0.6.0/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/segmentio/kafka-go v0.2.0 h1:HtCSf6B4gN/87yc5qTl7WsxPKQIIGXLPPM1bMCPOsoY=
|
||||
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
@@ -1093,7 +974,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
@@ -1106,7 +986,6 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
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/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
@@ -1120,15 +999,14 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||
github.com/tdewolff/minify/v2 v2.12.4 h1:kejsHQMM17n6/gwdw53qsi6lg0TGddZADVyQOz1KMdE=
|
||||
github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk=
|
||||
github.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZycQ=
|
||||
@@ -1137,7 +1015,6 @@ github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
|
||||
@@ -1171,7 +1048,6 @@ github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q
|
||||
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 h1:ekJIKh6+YbUIVt9DfNbkR5d6aFcFTLDRyJNAACURBg8=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
@@ -1180,7 +1056,6 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 h1:YdYsPAZ2pC6Tow/nPZOPQ96O3hm/ToAkGsPLzedXERk=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
|
||||
@@ -1205,10 +1080,7 @@ github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wK
|
||||
go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg=
|
||||
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
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 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
@@ -1220,18 +1092,12 @@ go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTN
|
||||
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
||||
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
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-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-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -1250,43 +1116,22 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
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=
|
||||
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 h1:zQpM52jfKHG6II1ISZY1ZcpygvuSFZpLwfluuF89XOg=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
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 h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
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 h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
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 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -1294,17 +1139,11 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
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-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-20190327091125-710a502c58a2/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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -1336,10 +1175,6 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
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/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
|
||||
@@ -1354,27 +1189,16 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
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-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1382,6 +1206,7 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1431,7 +1256,7 @@ golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
@@ -1439,38 +1264,18 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-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.0.0-20220922220347-f3bd1da661af/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-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-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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
@@ -1493,25 +1298,13 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
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 h1:DJy6UzXbahnGUf1ujUNkh/NEtK14qMo2nvlBPs4U5yw=
|
||||
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 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b h1:Qh4dB5D/WpoUUp3lSod7qgoyEHbDGPUWjIbnqdqqe1k=
|
||||
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 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
@@ -1524,27 +1317,12 @@ google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
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/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-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-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
@@ -1570,11 +1348,8 @@ google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
|
||||
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.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
@@ -1587,7 +1362,13 @@ google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
@@ -1615,18 +1396,17 @@ gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHO
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v1.4.0 h1:BjtEgfuw8Qyd+jPvQz8CfoxiO/UjFEidWinwEXZiWv0=
|
||||
gotest.tools v1.4.0/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
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 h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
|
||||
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 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
@@ -1657,7 +1437,6 @@ moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
|
||||
moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
|
||||
nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
|
||||
@@ -56,7 +56,7 @@ func action(ctx *cli.Context) error {
|
||||
defer func() {
|
||||
cancel()
|
||||
if err = database.CloseDB(db); err != nil {
|
||||
log.Crit("failed to close db connection", "error", err)
|
||||
log.Error("can not close ormFactory", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -64,12 +64,14 @@ func action(ctx *cli.Context) error {
|
||||
observability.Server(ctx, db)
|
||||
l1client, err := ethclient.Dial(cfg.L1Config.Endpoint)
|
||||
if err != nil {
|
||||
log.Crit("failed to connect l1 geth", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to connect l1 geth", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
l2client, err := ethclient.Dial(cfg.L2Config.Endpoint)
|
||||
if err != nil {
|
||||
log.Crit("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
l1watcher := watcher.NewL1WatcherClient(ctx.Context, l1client, cfg.L1Config.StartHeight, cfg.L1Config.Confirmations,
|
||||
|
||||
@@ -59,7 +59,7 @@ func action(ctx *cli.Context) error {
|
||||
defer func() {
|
||||
cancel()
|
||||
if err = database.CloseDB(db); err != nil {
|
||||
log.Crit("failed to close db connection", "error", err)
|
||||
log.Error("can not close ormFactory", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -68,24 +68,28 @@ func action(ctx *cli.Context) error {
|
||||
|
||||
l1client, err := ethclient.Dial(cfg.L1Config.Endpoint)
|
||||
if err != nil {
|
||||
log.Crit("failed to connect l1 geth", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to connect l1 geth", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Init l2geth connection
|
||||
l2client, err := ethclient.Dial(cfg.L2Config.Endpoint)
|
||||
if err != nil {
|
||||
log.Crit("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
l1watcher := watcher.NewL1WatcherClient(ctx.Context, l1client, cfg.L1Config.StartHeight, cfg.L1Config.Confirmations, cfg.L1Config.L1MessageQueueAddress, cfg.L1Config.ScrollChainContractAddress, db, registry)
|
||||
|
||||
l1relayer, err := relayer.NewLayer1Relayer(ctx.Context, db, cfg.L1Config.RelayerConfig, relayer.ServiceTypeL1GasOracle, registry)
|
||||
l1relayer, err := relayer.NewLayer1Relayer(ctx.Context, db, cfg.L1Config.RelayerConfig, registry)
|
||||
if err != nil {
|
||||
log.Crit("failed to create new l1 relayer", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to create new l1 relayer", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
l2relayer, err := relayer.NewLayer2Relayer(ctx.Context, l2client, db, cfg.L2Config.RelayerConfig, false /* initGenesis */, relayer.ServiceTypeL2GasOracle, registry)
|
||||
l2relayer, err := relayer.NewLayer2Relayer(ctx.Context, l2client, db, cfg.L2Config.RelayerConfig, false /* initGenesis */, registry)
|
||||
if err != nil {
|
||||
log.Crit("failed to create new l2 relayer", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to create new l2 relayer", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
// Start l1 watcher process
|
||||
go utils.LoopWithContext(subCtx, 10*time.Second, func(ctx context.Context) {
|
||||
@@ -99,7 +103,6 @@ func action(ctx *cli.Context) error {
|
||||
|
||||
if loopErr = l1watcher.FetchBlockHeader(number - 1); loopErr != nil {
|
||||
log.Error("Failed to fetch L1 block header", "lastest", number-1, "err", loopErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -88,9 +88,9 @@ func (b *MockApp) MockConfig(store bool) error {
|
||||
}
|
||||
|
||||
cfg.L1Config.Endpoint = base.L1gethImg.Endpoint()
|
||||
cfg.L1Config.RelayerConfig.SenderConfig.Endpoint = base.L2gethImg.Endpoint()
|
||||
cfg.L2Config.Endpoint = base.L2gethImg.Endpoint()
|
||||
cfg.L2Config.RelayerConfig.SenderConfig.Endpoint = base.L1gethImg.Endpoint()
|
||||
cfg.L2Config.Endpoint = base.L2gethImg.Endpoint()
|
||||
cfg.L1Config.RelayerConfig.SenderConfig.Endpoint = base.L2gethImg.Endpoint()
|
||||
cfg.DBConfig.DSN = base.DBImg.Endpoint()
|
||||
b.Config = cfg
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func action(ctx *cli.Context) error {
|
||||
defer func() {
|
||||
cancel()
|
||||
if err = database.CloseDB(db); err != nil {
|
||||
log.Crit("failed to close db connection", "error", err)
|
||||
log.Error("can not close ormFactory", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -69,23 +69,27 @@ func action(ctx *cli.Context) error {
|
||||
// Init l2geth connection
|
||||
l2client, err := ethclient.Dial(cfg.L2Config.Endpoint)
|
||||
if err != nil {
|
||||
log.Crit("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to connect l2 geth", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
initGenesis := ctx.Bool(utils.ImportGenesisFlag.Name)
|
||||
l2relayer, err := relayer.NewLayer2Relayer(ctx.Context, l2client, db, cfg.L2Config.RelayerConfig, initGenesis, relayer.ServiceTypeL2RollupRelayer, registry)
|
||||
l2relayer, err := relayer.NewLayer2Relayer(ctx.Context, l2client, db, cfg.L2Config.RelayerConfig, initGenesis, registry)
|
||||
if err != nil {
|
||||
log.Crit("failed to create l2 relayer", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to create l2 relayer", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, db, registry)
|
||||
if err != nil {
|
||||
log.Crit("failed to create chunkProposer", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to create chunkProposer", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, db, registry)
|
||||
if err != nil {
|
||||
log.Crit("failed to create batchProposer", "config file", cfgFile, "error", err)
|
||||
log.Error("failed to create batchProposer", "config file", cfgFile, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
l2watcher := watcher.NewL2WatcherClient(subCtx, l2client, cfg.L2Config.Confirmations, cfg.L2Config.L2MessengerAddress,
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
{
|
||||
"l1_config": {
|
||||
"confirmations": "0x6",
|
||||
"endpoint": "https://rpc.ankr.com/eth",
|
||||
"endpoint": "DUMMY_ENDPOINT",
|
||||
"l1_message_queue_address": "0x0000000000000000000000000000000000000000",
|
||||
"scroll_chain_address": "0x0000000000000000000000000000000000000000",
|
||||
"start_height": 0,
|
||||
"relayer_config": {
|
||||
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
|
||||
"sender_config": {
|
||||
"endpoint": "https://rpc.scroll.io",
|
||||
"endpoint": "https://sepolia-rpc.scroll.io",
|
||||
"check_pending_time": 2,
|
||||
"check_balance_time": 100,
|
||||
"escalate_blocks": 100,
|
||||
"confirmations": "0x1",
|
||||
"escalate_multiple_num": 11,
|
||||
"escalate_multiple_den": 10,
|
||||
"max_gas_price": 10000000000,
|
||||
"tx_type": "LegacyTx",
|
||||
"check_pending_time": 3
|
||||
"min_balance": 100000000000000000000,
|
||||
"pending_limit": 10
|
||||
},
|
||||
"gas_oracle_config": {
|
||||
"min_gas_price": 0,
|
||||
@@ -26,21 +29,24 @@
|
||||
},
|
||||
"l2_config": {
|
||||
"confirmations": "0x1",
|
||||
"endpoint": "https://rpc.scroll.io",
|
||||
"endpoint": "https://sepolia-rpc.scroll.io",
|
||||
"l2_messenger_address": "0x0000000000000000000000000000000000000000",
|
||||
"l2_message_queue_address": "0x0000000000000000000000000000000000000000",
|
||||
"relayer_config": {
|
||||
"rollup_contract_address": "0x0000000000000000000000000000000000000000",
|
||||
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
|
||||
"sender_config": {
|
||||
"endpoint": "https://rpc.ankr.com/eth",
|
||||
"endpoint": "https://sepolia-rpc.scroll.io",
|
||||
"check_pending_time": 10,
|
||||
"check_balance_time": 100,
|
||||
"escalate_blocks": 100,
|
||||
"confirmations": "0x6",
|
||||
"escalate_multiple_num": 11,
|
||||
"escalate_multiple_den": 10,
|
||||
"max_gas_price": 10000000000,
|
||||
"tx_type": "DynamicFeeTx",
|
||||
"check_pending_time": 12
|
||||
"tx_type": "LegacyTx",
|
||||
"min_balance": 100000000000000000000,
|
||||
"pending_limit": 10
|
||||
},
|
||||
"gas_oracle_config": {
|
||||
"min_gas_price": 0,
|
||||
|
||||
@@ -6,6 +6,7 @@ require (
|
||||
github.com/agiledragon/gomonkey/v2 v2.9.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20231130005111-38a3a9c9198c
|
||||
github.com/smartystreets/goconvey v1.8.0
|
||||
|
||||
@@ -156,6 +156,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
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/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
@@ -28,6 +29,12 @@ type SenderConfig struct {
|
||||
MaxGasPrice uint64 `json:"max_gas_price"`
|
||||
// The transaction type to use: LegacyTx, AccessListTx, DynamicFeeTx
|
||||
TxType string `json:"tx_type"`
|
||||
// The min balance set for check and set balance for sender's accounts.
|
||||
MinBalance *big.Int `json:"min_balance"`
|
||||
// The interval (in seconds) to check balance and top up sender's accounts
|
||||
CheckBalanceTime uint64 `json:"check_balance_time"`
|
||||
// The sender's pending count limit.
|
||||
PendingLimit int `json:"pending_limit"`
|
||||
}
|
||||
|
||||
// ChainMonitor this config is used to get batch status from chain_monitor API.
|
||||
|
||||
@@ -14,17 +14,3 @@ var (
|
||||
// ErrExecutionRevertedAlreadySuccessExecuted error of Message was already successfully executed
|
||||
ErrExecutionRevertedAlreadySuccessExecuted = errors.New("execution reverted: Message was already successfully executed")
|
||||
)
|
||||
|
||||
// ServiceType defines the various types of services within the relayer.
|
||||
type ServiceType int
|
||||
|
||||
const (
|
||||
// ServiceTypeUnknown indicates an unknown service type.
|
||||
ServiceTypeUnknown ServiceType = iota
|
||||
// ServiceTypeL2RollupRelayer indicates the service is a Layer 2 rollup relayer.
|
||||
ServiceTypeL2RollupRelayer
|
||||
// ServiceTypeL1GasOracle indicates the service is a Layer 1 gas oracle.
|
||||
ServiceTypeL1GasOracle
|
||||
// ServiceTypeL2GasOracle indicates the service is a Layer 2 gas oracle.
|
||||
ServiceTypeL2GasOracle
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package relayer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
@@ -42,24 +43,16 @@ type Layer1Relayer struct {
|
||||
}
|
||||
|
||||
// NewLayer1Relayer will return a new instance of Layer1RelayerClient
|
||||
func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfig, serviceType ServiceType, reg prometheus.Registerer) (*Layer1Relayer, error) {
|
||||
var gasOracleSender *sender.Sender
|
||||
var err error
|
||||
func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfig, reg prometheus.Registerer) (*Layer1Relayer, error) {
|
||||
gasOracleSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.GasOracleSenderPrivateKey, "l1_relayer", "gas_oracle_sender", reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.GasOracleSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new gas oracle sender failed for address %s, err: %v", addr.Hex(), err)
|
||||
}
|
||||
|
||||
switch serviceType {
|
||||
case ServiceTypeL1GasOracle:
|
||||
gasOracleSender, err = sender.NewSender(ctx, cfg.SenderConfig, cfg.GasOracleSenderPrivateKey, "l1_relayer", "gas_oracle_sender", types.SenderTypeL1GasOracle, db, reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.GasOracleSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new gas oracle sender failed for address %s, err: %v", addr.Hex(), err)
|
||||
}
|
||||
|
||||
// Ensure test features aren't enabled on the scroll mainnet.
|
||||
if gasOracleSender.GetChainID().Cmp(big.NewInt(534352)) == 0 && cfg.EnableTestEnvBypassFeatures {
|
||||
return nil, fmt.Errorf("cannot enable test env features in mainnet")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid service type for l1_relayer: %v", serviceType)
|
||||
// Ensure test features aren't enabled on the mainnet.
|
||||
if gasOracleSender.GetChainID() == big.NewInt(1) && cfg.EnableTestEnvBypassFeatures {
|
||||
return nil, fmt.Errorf("cannot enable test env features in mainnet")
|
||||
}
|
||||
|
||||
var minGasPrice uint64
|
||||
@@ -86,13 +79,7 @@ func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfi
|
||||
|
||||
l1Relayer.metrics = initL1RelayerMetrics(reg)
|
||||
|
||||
switch serviceType {
|
||||
case ServiceTypeL1GasOracle:
|
||||
go l1Relayer.handleL1GasOracleConfirmLoop(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid service type for l1_relayer: %v", serviceType)
|
||||
}
|
||||
|
||||
go l1Relayer.handleConfirmLoop(ctx)
|
||||
return l1Relayer, nil
|
||||
}
|
||||
|
||||
@@ -131,7 +118,9 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() {
|
||||
|
||||
hash, err := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data, 0)
|
||||
if err != nil {
|
||||
log.Error("Failed to send setL1BaseFee tx to layer2 ", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
|
||||
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
|
||||
log.Error("Failed to send setL1BaseFee tx to layer2 ", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -147,38 +136,28 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Layer1Relayer) handleConfirmation(cfm *sender.Confirmation) {
|
||||
switch cfm.SenderType {
|
||||
case types.SenderTypeL1GasOracle:
|
||||
var status types.GasOracleStatus
|
||||
if cfm.IsSuccessful {
|
||||
status = types.GasOracleImported
|
||||
r.metrics.rollupL1UpdateGasOracleConfirmedTotal.Inc()
|
||||
log.Info("UpdateGasOracleTxType transaction confirmed in layer2", "confirmation", cfm)
|
||||
} else {
|
||||
status = types.GasOracleImportedFailed
|
||||
r.metrics.rollupL1UpdateGasOracleConfirmedFailedTotal.Inc()
|
||||
log.Warn("UpdateGasOracleTxType transaction confirmed but failed in layer2", "confirmation", cfm)
|
||||
}
|
||||
|
||||
err := r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, cfm.ContextID, status, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateL1GasOracleStatusAndOracleTxHash failed", "confirmation", cfm, "err", err)
|
||||
}
|
||||
default:
|
||||
log.Warn("Unknown transaction type", "confirmation", cfm)
|
||||
}
|
||||
|
||||
log.Info("Transaction confirmed in layer2", "confirmation", cfm)
|
||||
}
|
||||
|
||||
func (r *Layer1Relayer) handleL1GasOracleConfirmLoop(ctx context.Context) {
|
||||
func (r *Layer1Relayer) handleConfirmLoop(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case cfm := <-r.gasOracleSender.ConfirmChan():
|
||||
r.handleConfirmation(cfm)
|
||||
r.metrics.rollupL1GasOraclerConfirmedTotal.Inc()
|
||||
if !cfm.IsSuccessful {
|
||||
// @discuss: maybe make it pending again?
|
||||
err := r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleFailed, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateL1GasOracleStatusAndOracleTxHash failed", "err", err)
|
||||
}
|
||||
log.Warn("transaction confirmed but failed in layer2", "confirmation", cfm)
|
||||
} else {
|
||||
// @todo handle db error
|
||||
err := r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleImported, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateGasOracleStatusAndOracleTxHash failed", "err", err)
|
||||
}
|
||||
log.Info("transaction confirmed in layer2", "confirmation", cfm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@ import (
|
||||
)
|
||||
|
||||
type l1RelayerMetrics struct {
|
||||
rollupL1RelayerGasPriceOraclerRunTotal prometheus.Counter
|
||||
rollupL1RelayerLastGasPrice prometheus.Gauge
|
||||
rollupL1UpdateGasOracleConfirmedTotal prometheus.Counter
|
||||
rollupL1UpdateGasOracleConfirmedFailedTotal prometheus.Counter
|
||||
rollupL1RelayedMsgsTotal prometheus.Counter
|
||||
rollupL1RelayedMsgsFailureTotal prometheus.Counter
|
||||
rollupL1RelayerGasPriceOraclerRunTotal prometheus.Counter
|
||||
rollupL1RelayerLastGasPrice prometheus.Gauge
|
||||
rollupL1MsgsRelayedConfirmedTotal prometheus.Counter
|
||||
rollupL1GasOraclerConfirmedTotal prometheus.Counter
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -22,6 +24,18 @@ var (
|
||||
func initL1RelayerMetrics(reg prometheus.Registerer) *l1RelayerMetrics {
|
||||
initL1RelayerMetricOnce.Do(func() {
|
||||
l1RelayerMetric = &l1RelayerMetrics{
|
||||
rollupL1RelayedMsgsTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_msg_relayed_total",
|
||||
Help: "The total number of the l1 relayed message.",
|
||||
}),
|
||||
rollupL1RelayedMsgsFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_msg_relayed_failure_total",
|
||||
Help: "The total number of the l1 relayed failure message.",
|
||||
}),
|
||||
rollupL1MsgsRelayedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_relayed_confirmed_total",
|
||||
Help: "The total number of layer1 relayed confirmed",
|
||||
}),
|
||||
rollupL1RelayerGasPriceOraclerRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_gas_price_oracler_total",
|
||||
Help: "The total number of layer1 gas price oracler run total",
|
||||
@@ -30,13 +44,9 @@ func initL1RelayerMetrics(reg prometheus.Registerer) *l1RelayerMetrics {
|
||||
Name: "rollup_layer1_gas_price_latest_gas_price",
|
||||
Help: "The latest gas price of rollup relayer l1",
|
||||
}),
|
||||
rollupL1UpdateGasOracleConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_update_gas_oracle_confirmed_total",
|
||||
Help: "The total number of updating layer1 gas oracle confirmed",
|
||||
}),
|
||||
rollupL1UpdateGasOracleConfirmedFailedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_update_gas_oracle_confirmed_failed_total",
|
||||
Help: "The total number of updating layer1 gas oracle confirmed failed",
|
||||
rollupL1GasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer1_gas_oracler_confirmed_total",
|
||||
Help: "The total number of layer1 relayed confirmed",
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -35,7 +35,7 @@ func setupL1RelayerDB(t *testing.T) *gorm.DB {
|
||||
func testCreateNewL1Relayer(t *testing.T) {
|
||||
db := setupL1RelayerDB(t)
|
||||
defer database.CloseDB(db)
|
||||
relayer, err := NewLayer1Relayer(context.Background(), db, cfg.L2Config.RelayerConfig, ServiceTypeL1GasOracle, nil)
|
||||
relayer, err := NewLayer1Relayer(context.Background(), db, cfg.L2Config.RelayerConfig, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, relayer)
|
||||
}
|
||||
@@ -56,19 +56,17 @@ func testL1RelayerGasOracleConfirm(t *testing.T) {
|
||||
l1Cfg := cfg.L1Config
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
l1Relayer, err := NewLayer1Relayer(ctx, db, l1Cfg.RelayerConfig, ServiceTypeL1GasOracle, nil)
|
||||
l1Relayer, err := NewLayer1Relayer(ctx, db, l1Cfg.RelayerConfig, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Simulate message confirmations.
|
||||
l1Relayer.gasOracleSender.SendConfirmation(&sender.Confirmation{
|
||||
ContextID: "gas-oracle-1",
|
||||
ID: "gas-oracle-1",
|
||||
IsSuccessful: true,
|
||||
SenderType: types.SenderTypeL1GasOracle,
|
||||
})
|
||||
l1Relayer.gasOracleSender.SendConfirmation(&sender.Confirmation{
|
||||
ContextID: "gas-oracle-2",
|
||||
ID: "gas-oracle-2",
|
||||
IsSuccessful: false,
|
||||
SenderType: types.SenderTypeL1GasOracle,
|
||||
})
|
||||
|
||||
// Check the database for the updated status using TryTimes.
|
||||
@@ -76,7 +74,7 @@ func testL1RelayerGasOracleConfirm(t *testing.T) {
|
||||
msg1, err1 := l1BlockOrm.GetL1Blocks(ctx, map[string]interface{}{"hash": "gas-oracle-1"})
|
||||
msg2, err2 := l1BlockOrm.GetL1Blocks(ctx, map[string]interface{}{"hash": "gas-oracle-2"})
|
||||
return err1 == nil && len(msg1) == 1 && types.GasOracleStatus(msg1[0].GasOracleStatus) == types.GasOracleImported &&
|
||||
err2 == nil && len(msg2) == 1 && types.GasOracleStatus(msg2[0].GasOracleStatus) == types.GasOracleImportedFailed
|
||||
err2 == nil && len(msg2) == 1 && types.GasOracleStatus(msg2[0].GasOracleStatus) == types.GasOracleFailed
|
||||
})
|
||||
assert.True(t, ok)
|
||||
}
|
||||
@@ -88,7 +86,7 @@ func testL1RelayerProcessGasPriceOracle(t *testing.T) {
|
||||
l1Cfg := cfg.L1Config
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
l1Relayer, err := NewLayer1Relayer(ctx, db, l1Cfg.RelayerConfig, ServiceTypeL1GasOracle, nil)
|
||||
l1Relayer, err := NewLayer1Relayer(ctx, db, l1Cfg.RelayerConfig, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, l1Relayer)
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ package relayer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
@@ -58,47 +60,39 @@ type Layer2Relayer struct {
|
||||
// Used to get batch status from chain_monitor api.
|
||||
chainMonitorClient *resty.Client
|
||||
|
||||
// A list of processing batches commitment.
|
||||
// key(string): confirmation ID, value(string): batch hash.
|
||||
processingCommitment sync.Map
|
||||
|
||||
// A list of processing batch finalization.
|
||||
// key(string): confirmation ID, value(string): batch hash.
|
||||
processingFinalization sync.Map
|
||||
|
||||
metrics *l2RelayerMetrics
|
||||
}
|
||||
|
||||
// NewLayer2Relayer will return a new instance of Layer2RelayerClient
|
||||
func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.DB, cfg *config.RelayerConfig, initGenesis bool, serviceType ServiceType, reg prometheus.Registerer) (*Layer2Relayer, error) {
|
||||
var gasOracleSender, commitSender, finalizeSender *sender.Sender
|
||||
var err error
|
||||
func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.DB, cfg *config.RelayerConfig, initGenesis bool, reg prometheus.Registerer) (*Layer2Relayer, error) {
|
||||
commitSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.CommitSenderPrivateKey, "l2_relayer", "commit_sender", reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.CommitSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new commit sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
finalizeSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.FinalizeSenderPrivateKey, "l2_relayer", "finalize_sender", reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.FinalizeSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new finalize sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
|
||||
switch serviceType {
|
||||
case ServiceTypeL2GasOracle:
|
||||
gasOracleSender, err = sender.NewSender(ctx, cfg.SenderConfig, cfg.GasOracleSenderPrivateKey, "l2_relayer", "gas_oracle_sender", types.SenderTypeL2GasOracle, db, reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.GasOracleSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new gas oracle sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
gasOracleSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.GasOracleSenderPrivateKey, "l2_relayer", "gas_oracle_sender", reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.GasOracleSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new gas oracle sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
|
||||
// Ensure test features aren't enabled on the ethereum mainnet.
|
||||
if gasOracleSender.GetChainID().Cmp(big.NewInt(1)) == 0 && cfg.EnableTestEnvBypassFeatures {
|
||||
return nil, fmt.Errorf("cannot enable test env features in mainnet")
|
||||
}
|
||||
|
||||
case ServiceTypeL2RollupRelayer:
|
||||
commitSender, err = sender.NewSender(ctx, cfg.SenderConfig, cfg.CommitSenderPrivateKey, "l2_relayer", "commit_sender", types.SenderTypeCommitBatch, db, reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.CommitSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new commit sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
|
||||
finalizeSender, err = sender.NewSender(ctx, cfg.SenderConfig, cfg.FinalizeSenderPrivateKey, "l2_relayer", "finalize_sender", types.SenderTypeFinalizeBatch, db, reg)
|
||||
if err != nil {
|
||||
addr := crypto.PubkeyToAddress(cfg.FinalizeSenderPrivateKey.PublicKey)
|
||||
return nil, fmt.Errorf("new finalize sender failed for address %s, err: %w", addr.Hex(), err)
|
||||
}
|
||||
|
||||
// Ensure test features aren't enabled on the ethereum mainnet.
|
||||
if commitSender.GetChainID().Cmp(big.NewInt(1)) == 0 && cfg.EnableTestEnvBypassFeatures {
|
||||
return nil, fmt.Errorf("cannot enable test env features in mainnet")
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid service type for l2_relayer: %v", serviceType)
|
||||
// Ensure test features aren't enabled on the mainnet.
|
||||
if commitSender.GetChainID() == big.NewInt(1) && cfg.EnableTestEnvBypassFeatures {
|
||||
return nil, fmt.Errorf("cannot enable test env features in mainnet")
|
||||
}
|
||||
|
||||
var minGasPrice uint64
|
||||
@@ -131,7 +125,9 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.
|
||||
minGasPrice: minGasPrice,
|
||||
gasPriceDiff: gasPriceDiff,
|
||||
|
||||
cfg: cfg,
|
||||
cfg: cfg,
|
||||
processingCommitment: sync.Map{},
|
||||
processingFinalization: sync.Map{},
|
||||
}
|
||||
|
||||
// chain_monitor client
|
||||
@@ -149,15 +145,7 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.
|
||||
}
|
||||
layer2Relayer.metrics = initL2RelayerMetrics(reg)
|
||||
|
||||
switch serviceType {
|
||||
case ServiceTypeL2GasOracle:
|
||||
go layer2Relayer.handleL2GasOracleConfirmLoop(ctx)
|
||||
case ServiceTypeL2RollupRelayer:
|
||||
go layer2Relayer.handleL2RollupRelayerConfirmLoop(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid service type for l2_relayer: %v", serviceType)
|
||||
}
|
||||
|
||||
go layer2Relayer.handleConfirmLoop(ctx)
|
||||
return layer2Relayer, nil
|
||||
}
|
||||
|
||||
@@ -265,8 +253,8 @@ func (r *Layer2Relayer) commitGenesisBatch(batchHash string, batchHeader []byte,
|
||||
|
||||
// handle confirmation
|
||||
case confirmation := <-r.commitSender.ConfirmChan():
|
||||
if confirmation.ContextID != batchHash {
|
||||
return fmt.Errorf("unexpected import genesis confirmation id, expected: %v, got: %v", batchHash, confirmation.ContextID)
|
||||
if confirmation.ID != batchHash {
|
||||
return fmt.Errorf("unexpected import genesis confirmation id, expected: %v, got: %v", batchHash, confirmation.ID)
|
||||
}
|
||||
if !confirmation.IsSuccessful {
|
||||
return fmt.Errorf("import genesis batch tx failed")
|
||||
@@ -305,7 +293,9 @@ func (r *Layer2Relayer) ProcessGasPriceOracle() {
|
||||
|
||||
hash, err := r.gasOracleSender.SendTransaction(batch.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data, 0)
|
||||
if err != nil {
|
||||
log.Error("Failed to send setL2BaseFee tx to layer2 ", "batch.Hash", batch.Hash, "err", err)
|
||||
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
|
||||
log.Error("Failed to send setL2BaseFee tx to layer2 ", "batch.Hash", batch.Hash, "err", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -392,13 +382,14 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
|
||||
}
|
||||
|
||||
// send transaction
|
||||
txID := batch.Hash + "-commit"
|
||||
fallbackGasLimit := uint64(float64(batch.TotalL1CommitGas) * r.cfg.L1CommitGasLimitMultiplier)
|
||||
if types.RollupStatus(batch.RollupStatus) == types.RollupCommitFailed {
|
||||
// use eth_estimateGas if this batch has been committed failed.
|
||||
fallbackGasLimit = 0
|
||||
log.Warn("Batch commit previously failed, using eth_estimateGas for the re-submission", "hash", batch.Hash)
|
||||
}
|
||||
txHash, err := r.commitSender.SendTransaction(batch.Hash, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, fallbackGasLimit)
|
||||
txHash, err := r.commitSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, fallbackGasLimit)
|
||||
if err != nil {
|
||||
log.Error(
|
||||
"Failed to send commitBatch tx to layer1",
|
||||
@@ -424,6 +415,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
|
||||
return
|
||||
}
|
||||
r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Inc()
|
||||
r.processingCommitment.Store(txID, batch.Hash)
|
||||
log.Info("Sent the commitBatch tx to layer1", "batch index", batch.Index, "batch hash", batch.Hash, "tx hash", txHash.Hex())
|
||||
}
|
||||
}
|
||||
@@ -562,27 +554,34 @@ func (r *Layer2Relayer) finalizeBatch(batch *orm.Batch, withProof bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
txID := batch.Hash + "-finalize"
|
||||
// add suffix `-finalize` to avoid duplication with commit tx in unit tests
|
||||
txHash, err := r.finalizeSender.SendTransaction(batch.Hash, &r.cfg.RollupContractAddress, big.NewInt(0), txCalldata, 0)
|
||||
txHash, err := r.finalizeSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), txCalldata, 0)
|
||||
finalizeTxHash := &txHash
|
||||
if err != nil {
|
||||
log.Error(
|
||||
"finalizeBatch in layer1 failed",
|
||||
"with proof", withProof,
|
||||
"index", batch.Index,
|
||||
"hash", batch.Hash,
|
||||
"RollupContractAddress", r.cfg.RollupContractAddress,
|
||||
"err", err,
|
||||
)
|
||||
log.Debug(
|
||||
"finalizeBatch in layer1 failed",
|
||||
"with proof", withProof,
|
||||
"index", batch.Index,
|
||||
"hash", batch.Hash,
|
||||
"RollupContractAddress", r.cfg.RollupContractAddress,
|
||||
"calldata", common.Bytes2Hex(txCalldata),
|
||||
"err", err,
|
||||
)
|
||||
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
|
||||
// This can happen normally if we try to finalize 2 or more
|
||||
// batches around the same time. The 2nd tx might fail since
|
||||
// the client does not see the 1st tx's updates at this point.
|
||||
// TODO: add more fine-grained error handling
|
||||
log.Error(
|
||||
"finalizeBatch in layer1 failed",
|
||||
"with proof", withProof,
|
||||
"index", batch.Index,
|
||||
"hash", batch.Hash,
|
||||
"RollupContractAddress", r.cfg.RollupContractAddress,
|
||||
"err", err,
|
||||
)
|
||||
log.Debug(
|
||||
"finalizeBatch in layer1 failed",
|
||||
"with proof", withProof,
|
||||
"index", batch.Index,
|
||||
"hash", batch.Hash,
|
||||
"RollupContractAddress", r.cfg.RollupContractAddress,
|
||||
"calldata", common.Bytes2Hex(txCalldata),
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
return err
|
||||
}
|
||||
log.Info("finalizeBatch in layer1", "with proof", withProof, "index", batch.Index, "batch hash", batch.Hash, "tx hash", batch.Hash)
|
||||
@@ -592,6 +591,7 @@ func (r *Layer2Relayer) finalizeBatch(batch *orm.Batch, withProof bool) error {
|
||||
log.Error("UpdateFinalizeTxHashAndRollupStatus failed", "index", batch.Index, "batch hash", batch.Hash, "tx hash", finalizeTxHash.String(), "err", err)
|
||||
return err
|
||||
}
|
||||
r.processingFinalization.Store(txID, batch.Hash)
|
||||
r.metrics.rollupL2RelayerProcessCommittedBatchesFinalizedSuccessTotal.Inc()
|
||||
return nil
|
||||
}
|
||||
@@ -642,81 +642,81 @@ func (r *Layer2Relayer) getBatchStatusByIndex(batch *orm.Batch) (bool, error) {
|
||||
return response.Data, nil
|
||||
}
|
||||
|
||||
func (r *Layer2Relayer) handleConfirmation(cfm *sender.Confirmation) {
|
||||
switch cfm.SenderType {
|
||||
case types.SenderTypeCommitBatch:
|
||||
func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
|
||||
transactionType := "Unknown"
|
||||
// check whether it is CommitBatches transaction
|
||||
if batchHash, ok := r.processingCommitment.Load(confirmation.ID); ok {
|
||||
transactionType = "BatchesCommitment"
|
||||
var status types.RollupStatus
|
||||
if cfm.IsSuccessful {
|
||||
if confirmation.IsSuccessful {
|
||||
status = types.RollupCommitted
|
||||
r.metrics.rollupL2BatchesCommittedConfirmedTotal.Inc()
|
||||
} else {
|
||||
status = types.RollupCommitFailed
|
||||
r.metrics.rollupL2BatchesCommittedConfirmedFailedTotal.Inc()
|
||||
log.Warn("CommitBatchTxType transaction confirmed but failed in layer1", "confirmation", cfm)
|
||||
log.Warn("commitBatch transaction confirmed but failed in layer1", "confirmation", confirmation)
|
||||
}
|
||||
|
||||
err := r.batchOrm.UpdateCommitTxHashAndRollupStatus(r.ctx, cfm.ContextID, cfm.TxHash.String(), status)
|
||||
// @todo handle db error
|
||||
err := r.batchOrm.UpdateCommitTxHashAndRollupStatus(r.ctx, batchHash.(string), confirmation.TxHash.String(), status)
|
||||
if err != nil {
|
||||
log.Warn("UpdateCommitTxHashAndRollupStatus failed", "confirmation", cfm, "err", err)
|
||||
log.Warn("UpdateCommitTxHashAndRollupStatus failed",
|
||||
"batch hash", batchHash.(string),
|
||||
"tx hash", confirmation.TxHash.String(), "err", err)
|
||||
}
|
||||
case types.SenderTypeFinalizeBatch:
|
||||
r.metrics.rollupL2BatchesCommittedConfirmedTotal.Inc()
|
||||
r.processingCommitment.Delete(confirmation.ID)
|
||||
}
|
||||
|
||||
// check whether it is proof finalization transaction
|
||||
if batchHash, ok := r.processingFinalization.Load(confirmation.ID); ok {
|
||||
transactionType = "ProofFinalization"
|
||||
var status types.RollupStatus
|
||||
if cfm.IsSuccessful {
|
||||
if confirmation.IsSuccessful {
|
||||
status = types.RollupFinalized
|
||||
r.metrics.rollupL2BatchesFinalizedConfirmedTotal.Inc()
|
||||
} else {
|
||||
status = types.RollupFinalizeFailed
|
||||
r.metrics.rollupL2BatchesFinalizedConfirmedFailedTotal.Inc()
|
||||
log.Warn("FinalizeBatchTxType transaction confirmed but failed in layer1", "confirmation", cfm)
|
||||
log.Warn("finalizeBatchWithProof transaction confirmed but failed in layer1", "confirmation", confirmation)
|
||||
}
|
||||
|
||||
err := r.batchOrm.UpdateFinalizeTxHashAndRollupStatus(r.ctx, cfm.ContextID, cfm.TxHash.String(), status)
|
||||
// @todo handle db error
|
||||
err := r.batchOrm.UpdateFinalizeTxHashAndRollupStatus(r.ctx, batchHash.(string), confirmation.TxHash.String(), status)
|
||||
if err != nil {
|
||||
log.Warn("UpdateFinalizeTxHashAndRollupStatus failed", "confirmation", cfm, "err", err)
|
||||
log.Warn("UpdateFinalizeTxHashAndRollupStatus failed",
|
||||
"batch hash", batchHash.(string),
|
||||
"tx hash", confirmation.TxHash.String(), "err", err)
|
||||
}
|
||||
case types.SenderTypeL2GasOracle:
|
||||
batchHash := cfm.ContextID
|
||||
var status types.GasOracleStatus
|
||||
if cfm.IsSuccessful {
|
||||
status = types.GasOracleImported
|
||||
r.metrics.rollupL2UpdateGasOracleConfirmedTotal.Inc()
|
||||
} else {
|
||||
status = types.GasOracleImportedFailed
|
||||
r.metrics.rollupL2UpdateGasOracleConfirmedFailedTotal.Inc()
|
||||
log.Warn("UpdateGasOracleTxType transaction confirmed but failed in layer1", "confirmation", cfm)
|
||||
}
|
||||
|
||||
err := r.batchOrm.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, batchHash, status, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateL2GasOracleStatusAndOracleTxHash failed", "confirmation", cfm, "err", err)
|
||||
}
|
||||
default:
|
||||
log.Warn("Unknown transaction type", "confirmation", cfm)
|
||||
r.metrics.rollupL2BatchesFinalizedConfirmedTotal.Inc()
|
||||
r.processingFinalization.Delete(confirmation.ID)
|
||||
}
|
||||
|
||||
log.Info("Transaction confirmed in layer1", "confirmation", cfm)
|
||||
log.Info("transaction confirmed in layer1", "type", transactionType, "confirmation", confirmation)
|
||||
}
|
||||
|
||||
func (r *Layer2Relayer) handleL2GasOracleConfirmLoop(ctx context.Context) {
|
||||
func (r *Layer2Relayer) handleConfirmLoop(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case confirmation := <-r.commitSender.ConfirmChan():
|
||||
r.handleConfirmation(confirmation)
|
||||
case confirmation := <-r.finalizeSender.ConfirmChan():
|
||||
r.handleConfirmation(confirmation)
|
||||
case cfm := <-r.gasOracleSender.ConfirmChan():
|
||||
r.handleConfirmation(cfm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Layer2Relayer) handleL2RollupRelayerConfirmLoop(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case cfm := <-r.commitSender.ConfirmChan():
|
||||
r.handleConfirmation(cfm)
|
||||
case cfm := <-r.finalizeSender.ConfirmChan():
|
||||
r.handleConfirmation(cfm)
|
||||
r.metrics.rollupL2BatchesGasOraclerConfirmedTotal.Inc()
|
||||
if !cfm.IsSuccessful {
|
||||
// @discuss: maybe make it pending again?
|
||||
err := r.batchOrm.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleFailed, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateL2GasOracleStatusAndOracleTxHash failed", "err", err)
|
||||
}
|
||||
log.Warn("transaction confirmed but failed in layer1", "confirmation", cfm)
|
||||
} else {
|
||||
// @todo handle db error
|
||||
err := r.batchOrm.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleImported, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateL2GasOracleStatusAndOracleTxHash failed", "err", err)
|
||||
}
|
||||
log.Info("transaction confirmed in layer1", "confirmation", cfm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ type l2RelayerMetrics struct {
|
||||
rollupL2BatchesCommittedConfirmedFailedTotal prometheus.Counter
|
||||
rollupL2BatchesFinalizedConfirmedTotal prometheus.Counter
|
||||
rollupL2BatchesFinalizedConfirmedFailedTotal prometheus.Counter
|
||||
rollupL2UpdateGasOracleConfirmedTotal prometheus.Counter
|
||||
rollupL2UpdateGasOracleConfirmedFailedTotal prometheus.Counter
|
||||
rollupL2BatchesGasOraclerConfirmedTotal prometheus.Counter
|
||||
rollupL2ChainMonitorLatestFailedCall prometheus.Counter
|
||||
rollupL2ChainMonitorLatestFailedBatchStatus prometheus.Counter
|
||||
}
|
||||
@@ -77,13 +76,9 @@ func initL2RelayerMetrics(reg prometheus.Registerer) *l2RelayerMetrics {
|
||||
Name: "rollup_layer2_process_finalized_batches_confirmed_failed_total",
|
||||
Help: "The total number of layer2 process finalized batches confirmed failed total",
|
||||
}),
|
||||
rollupL2UpdateGasOracleConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer2_update_layer1_gas_oracle_confirmed_total",
|
||||
Help: "The total number of updating layer2 gas oracle confirmed",
|
||||
}),
|
||||
rollupL2UpdateGasOracleConfirmedFailedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer2_update_layer1_gas_oracle_confirmed_failed_total",
|
||||
Help: "The total number of updating layer2 gas oracle confirmed failed",
|
||||
rollupL2BatchesGasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer2_process_gras_oracler_confirmed_total",
|
||||
Help: "The total number of layer2 process finalized batches confirmed total",
|
||||
}),
|
||||
rollupL2ChainMonitorLatestFailedCall: promauto.With(reg).NewCounter(prometheus.CounterOpts{
|
||||
Name: "rollup_layer2_chain_monitor_latest_failed_batch_call",
|
||||
|
||||
@@ -38,7 +38,7 @@ func setupL2RelayerDB(t *testing.T) *gorm.DB {
|
||||
func testCreateNewRelayer(t *testing.T) {
|
||||
db := setupL2RelayerDB(t)
|
||||
defer database.CloseDB(db)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, relayer)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ func testL2RelayerProcessPendingBatches(t *testing.T) {
|
||||
defer database.CloseDB(db)
|
||||
|
||||
l2Cfg := cfg.L2Config
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
l2BlockOrm := orm.NewL2Block(db)
|
||||
@@ -82,7 +82,7 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) {
|
||||
defer database.CloseDB(db)
|
||||
|
||||
l2Cfg := cfg.L2Config
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
batchMeta := &types.BatchMeta{
|
||||
StartChunkIndex: 0,
|
||||
@@ -128,7 +128,7 @@ func testL2RelayerFinalizeTimeoutBatches(t *testing.T) {
|
||||
l2Cfg := cfg.L2Config
|
||||
l2Cfg.RelayerConfig.EnableTestEnvBypassFeatures = true
|
||||
l2Cfg.RelayerConfig.FinalizeBatchWithoutProofTimeoutSec = 0
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
batchMeta := &types.BatchMeta{
|
||||
StartChunkIndex: 0,
|
||||
@@ -160,13 +160,15 @@ func testL2RelayerCommitConfirm(t *testing.T) {
|
||||
l2Cfg := cfg.L2Config
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Simulate message confirmations.
|
||||
processingKeys := []string{"committed-1", "committed-2"}
|
||||
isSuccessful := []bool{true, false}
|
||||
|
||||
batchOrm := orm.NewBatch(db)
|
||||
batchHashes := make([]string, len(isSuccessful))
|
||||
batchHashes := make([]string, len(processingKeys))
|
||||
for i := range batchHashes {
|
||||
batchMeta := &types.BatchMeta{
|
||||
StartChunkIndex: 0,
|
||||
@@ -179,12 +181,12 @@ func testL2RelayerCommitConfirm(t *testing.T) {
|
||||
batchHashes[i] = batch.Hash
|
||||
}
|
||||
|
||||
for i, batchHash := range batchHashes {
|
||||
for i, key := range processingKeys {
|
||||
l2Relayer.processingCommitment.Store(key, batchHashes[i])
|
||||
l2Relayer.commitSender.SendConfirmation(&sender.Confirmation{
|
||||
ContextID: batchHash,
|
||||
ID: key,
|
||||
IsSuccessful: isSuccessful[i],
|
||||
TxHash: common.HexToHash("0x123456789abcdef"),
|
||||
SenderType: types.SenderTypeCommitBatch,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -214,13 +216,15 @@ func testL2RelayerFinalizeConfirm(t *testing.T) {
|
||||
l2Cfg := cfg.L2Config
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Simulate message confirmations.
|
||||
processingKeys := []string{"finalized-1", "finalized-2"}
|
||||
isSuccessful := []bool{true, false}
|
||||
|
||||
batchOrm := orm.NewBatch(db)
|
||||
batchHashes := make([]string, len(isSuccessful))
|
||||
batchHashes := make([]string, len(processingKeys))
|
||||
for i := range batchHashes {
|
||||
batchMeta := &types.BatchMeta{
|
||||
StartChunkIndex: 0,
|
||||
@@ -233,12 +237,12 @@ func testL2RelayerFinalizeConfirm(t *testing.T) {
|
||||
batchHashes[i] = batch.Hash
|
||||
}
|
||||
|
||||
for i, batchHash := range batchHashes {
|
||||
for i, key := range processingKeys {
|
||||
l2Relayer.processingFinalization.Store(key, batchHashes[i])
|
||||
l2Relayer.finalizeSender.SendConfirmation(&sender.Confirmation{
|
||||
ContextID: batchHash,
|
||||
ID: key,
|
||||
IsSuccessful: isSuccessful[i],
|
||||
TxHash: common.HexToHash("0x123456789abcdef"),
|
||||
SenderType: types.SenderTypeFinalizeBatch,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -287,7 +291,7 @@ func testL2RelayerGasOracleConfirm(t *testing.T) {
|
||||
l2Cfg := cfg.L2Config
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, ServiceTypeL2GasOracle, nil)
|
||||
l2Relayer, err := NewLayer2Relayer(ctx, l2Cli, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Simulate message confirmations.
|
||||
@@ -303,14 +307,13 @@ func testL2RelayerGasOracleConfirm(t *testing.T) {
|
||||
|
||||
for _, confirmation := range confirmations {
|
||||
l2Relayer.gasOracleSender.SendConfirmation(&sender.Confirmation{
|
||||
ContextID: confirmation.batchHash,
|
||||
ID: confirmation.batchHash,
|
||||
IsSuccessful: confirmation.isSuccessful,
|
||||
SenderType: types.SenderTypeL2GasOracle,
|
||||
})
|
||||
}
|
||||
// Check the database for the updated status using TryTimes.
|
||||
ok := utils.TryTimes(5, func() bool {
|
||||
expectedStatuses := []types.GasOracleStatus{types.GasOracleImported, types.GasOracleImportedFailed}
|
||||
expectedStatuses := []types.GasOracleStatus{types.GasOracleImported, types.GasOracleFailed}
|
||||
for i, confirmation := range confirmations {
|
||||
gasOracle, err := batchOrm.GetBatches(context.Background(), map[string]interface{}{"hash": confirmation.batchHash}, nil, 0)
|
||||
if err != nil || len(gasOracle) != 1 || types.GasOracleStatus(gasOracle[0].OracleStatus) != expectedStatuses[i] {
|
||||
@@ -326,7 +329,7 @@ func testLayer2RelayerProcessGasPriceOracle(t *testing.T) {
|
||||
db := setupL2RelayerDB(t)
|
||||
defer database.CloseDB(db)
|
||||
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, ServiceTypeL2GasOracle, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, relayer)
|
||||
|
||||
@@ -375,13 +378,13 @@ func testLayer2RelayerProcessGasPriceOracle(t *testing.T) {
|
||||
|
||||
convey.Convey("Failed to send setL2BaseFee tx to layer2", t, func() {
|
||||
targetErr := errors.New("failed to send setL2BaseFee tx to layer2 error")
|
||||
patchGuard.ApplyMethodFunc(relayer.gasOracleSender, "SendTransaction", func(ContextID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (hash common.Hash, err error) {
|
||||
patchGuard.ApplyMethodFunc(relayer.gasOracleSender, "SendTransaction", func(ID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (hash common.Hash, err error) {
|
||||
return common.Hash{}, targetErr
|
||||
})
|
||||
relayer.ProcessGasPriceOracle()
|
||||
})
|
||||
|
||||
patchGuard.ApplyMethodFunc(relayer.gasOracleSender, "SendTransaction", func(ContextID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (hash common.Hash, err error) {
|
||||
patchGuard.ApplyMethodFunc(relayer.gasOracleSender, "SendTransaction", func(ID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (hash common.Hash, err error) {
|
||||
return common.HexToHash("0x56789abcdef1234"), nil
|
||||
})
|
||||
|
||||
@@ -439,7 +442,7 @@ func testGetBatchStatusByIndex(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
cfg.L2Config.RelayerConfig.ChainMonitor.Enabled = true
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, ServiceTypeL2RollupRelayer, nil)
|
||||
relayer, err := NewLayer2Relayer(context.Background(), l2Cli, db, cfg.L2Config.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, relayer)
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"scroll-tech/common/database"
|
||||
@@ -41,10 +40,6 @@ var (
|
||||
)
|
||||
|
||||
func setupEnv(t *testing.T) {
|
||||
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.LogfmtFormat()))
|
||||
glogger.Verbosity(log.LvlInfo)
|
||||
log.Root().SetHandler(glogger)
|
||||
|
||||
// Load config.
|
||||
var err error
|
||||
cfg, err = config.NewConfig("../../../conf/config.json")
|
||||
|
||||
@@ -3,23 +3,25 @@ package sender
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum"
|
||||
"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/log"
|
||||
)
|
||||
|
||||
func (s *Sender) estimateLegacyGas(to *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
|
||||
func (s *Sender) estimateLegacyGas(auth *bind.TransactOpts, contract *common.Address, value *big.Int, input []byte, fallbackGasLimit uint64) (*FeeData, error) {
|
||||
gasPrice, err := s.client.SuggestGasPrice(s.ctx)
|
||||
if err != nil {
|
||||
log.Error("estimateLegacyGas SuggestGasPrice failure", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
gasLimit, _, err := s.estimateGasLimit(to, data, gasPrice, nil, nil, value, false)
|
||||
gasLimit, _, err := s.estimateGasLimit(auth, contract, input, gasPrice, nil, nil, value, false)
|
||||
if err != nil {
|
||||
log.Error("estimateLegacyGas estimateGasLimit failure", "gas price", gasPrice, "from", s.auth.From.String(),
|
||||
"nonce", s.auth.Nonce.Uint64(), "to address", to.String(), "fallback gas limit", fallbackGasLimit, "error", err)
|
||||
log.Error("estimateLegacyGas estimateGasLimit failure", "gas price", gasPrice, "from", auth.From.Hex(),
|
||||
"nonce", auth.Nonce.Uint64(), "contract address", contract.Hex(), "fallback gas limit", fallbackGasLimit, "error", err)
|
||||
if fallbackGasLimit == 0 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -33,18 +35,25 @@ func (s *Sender) estimateLegacyGas(to *common.Address, value *big.Int, data []by
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Sender) estimateDynamicGas(to *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64, baseFee uint64) (*FeeData, error) {
|
||||
func (s *Sender) estimateDynamicGas(auth *bind.TransactOpts, contract *common.Address, value *big.Int, input []byte, fallbackGasLimit uint64) (*FeeData, error) {
|
||||
gasTipCap, err := s.client.SuggestGasTipCap(s.ctx)
|
||||
if err != nil {
|
||||
log.Error("estimateDynamicGas SuggestGasTipCap failure", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(new(big.Int).SetUint64(baseFee), big.NewInt(2)))
|
||||
gasLimit, accessList, err := s.estimateGasLimit(to, data, nil, gasTipCap, gasFeeCap, value, true)
|
||||
baseFee := big.NewInt(0)
|
||||
if feeGas := atomic.LoadUint64(&s.baseFeePerGas); feeGas != 0 {
|
||||
baseFee.SetUint64(feeGas)
|
||||
}
|
||||
gasFeeCap := new(big.Int).Add(
|
||||
gasTipCap,
|
||||
new(big.Int).Mul(baseFee, big.NewInt(2)),
|
||||
)
|
||||
gasLimit, accessList, err := s.estimateGasLimit(auth, contract, input, nil, gasTipCap, gasFeeCap, value, true)
|
||||
if err != nil {
|
||||
log.Error("estimateDynamicGas estimateGasLimit failure",
|
||||
"from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "to address", to.String(),
|
||||
"from", auth.From.Hex(), "nonce", auth.Nonce.Uint64(), "contract address", contract.Hex(),
|
||||
"fallback gas limit", fallbackGasLimit, "error", err)
|
||||
if fallbackGasLimit == 0 {
|
||||
return nil, err
|
||||
@@ -64,15 +73,15 @@ func (s *Sender) estimateDynamicGas(to *common.Address, value *big.Int, data []b
|
||||
return feeData, nil
|
||||
}
|
||||
|
||||
func (s *Sender) estimateGasLimit(to *common.Address, data []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int, useAccessList bool) (uint64, *types.AccessList, error) {
|
||||
func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Address, input []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int, useAccessList bool) (uint64, *types.AccessList, error) {
|
||||
msg := ethereum.CallMsg{
|
||||
From: s.auth.From,
|
||||
To: to,
|
||||
From: opts.From,
|
||||
To: contract,
|
||||
GasPrice: gasPrice,
|
||||
GasTipCap: gasTipCap,
|
||||
GasFeeCap: gasFeeCap,
|
||||
Value: value,
|
||||
Data: data,
|
||||
Data: input,
|
||||
}
|
||||
gasLimitWithoutAccessList, err := s.client.EstimateGas(s.ctx, msg)
|
||||
if err != nil {
|
||||
@@ -84,7 +93,8 @@ func (s *Sender) estimateGasLimit(to *common.Address, data []byte, gasPrice, gas
|
||||
return gasLimitWithoutAccessList, nil, nil
|
||||
}
|
||||
|
||||
accessList, gasLimitWithAccessList, errStr, rpcErr := s.gethClient.CreateAccessList(s.ctx, msg)
|
||||
var gasLimitWithAccessList uint64
|
||||
accessList, gasUsed, errStr, rpcErr := s.gethClient.CreateAccessList(s.ctx, msg)
|
||||
if rpcErr != nil {
|
||||
log.Error("CreateAccessList RPC error", "error", rpcErr)
|
||||
return gasLimitWithoutAccessList, nil, rpcErr
|
||||
@@ -94,36 +104,17 @@ func (s *Sender) estimateGasLimit(to *common.Address, data []byte, gasPrice, gas
|
||||
return gasLimitWithoutAccessList, nil, fmt.Errorf(errStr)
|
||||
}
|
||||
|
||||
// Fine-tune accessList because 'to' address is automatically included in the access list by the Ethereum protocol: https://github.com/ethereum/go-ethereum/blob/v1.13.10/core/state/statedb.go#L1322
|
||||
// This function returns a gas estimation because GO SDK does not support access list: https://github.com/ethereum/go-ethereum/blob/v1.13.10/ethclient/ethclient.go#L642
|
||||
accessList, gasLimitWithAccessList = finetuneAccessList(accessList, gasLimitWithAccessList, msg.To)
|
||||
msg.AccessList = *accessList
|
||||
gasLimitWithAccessList, err = s.client.EstimateGas(s.ctx, msg)
|
||||
if err != nil {
|
||||
log.Error("estimateGasLimit EstimateGas failure with access list", "error", err)
|
||||
return gasLimitWithoutAccessList, nil, err
|
||||
}
|
||||
|
||||
log.Info("gas", "senderName", s.name, "senderService", s.service, "gasLimitWithAccessList", gasLimitWithAccessList, "gasLimitWithoutAccessList", gasLimitWithoutAccessList, "accessList", accessList)
|
||||
log.Info("gas", "senderName", s.name, "senderService", s.service, "accessListGasUsed", gasUsed, "gasLimitWithAccessList", gasLimitWithAccessList, "gasLimitWithoutAccessList", gasLimitWithoutAccessList)
|
||||
|
||||
if gasLimitWithAccessList < gasLimitWithoutAccessList {
|
||||
return gasLimitWithAccessList, accessList, nil
|
||||
}
|
||||
return gasLimitWithoutAccessList, nil, nil
|
||||
}
|
||||
|
||||
func finetuneAccessList(accessList *types.AccessList, gasLimitWithAccessList uint64, to *common.Address) (*types.AccessList, uint64) {
|
||||
if accessList == nil || to == nil {
|
||||
return accessList, gasLimitWithAccessList
|
||||
}
|
||||
|
||||
var newAccessList types.AccessList
|
||||
for _, entry := range *accessList {
|
||||
if entry.Address == *to && len(entry.StorageKeys) < 24 {
|
||||
// Based on: https://arxiv.org/pdf/2312.06574.pdf
|
||||
// We remove the address and respective storage keys as long as the number of storage keys < 24.
|
||||
// This removal helps in preventing double-counting of the 'to' address in access list calculations.
|
||||
gasLimitWithAccessList -= 2400
|
||||
// Each storage key saves 100 gas units.
|
||||
gasLimitWithAccessList += uint64(100 * len(entry.StorageKeys))
|
||||
} else {
|
||||
// Otherwise, keep the entry in the new access list.
|
||||
newAccessList = append(newAccessList, entry)
|
||||
}
|
||||
}
|
||||
return &newAccessList, gasLimitWithAccessList
|
||||
}
|
||||
|
||||
95
rollup/internal/controller/sender/metrics.go
Normal file
95
rollup/internal/controller/sender/metrics.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package sender
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
type senderMetrics struct {
|
||||
senderCheckBalancerTotal *prometheus.CounterVec
|
||||
senderCheckPendingTransactionTotal *prometheus.CounterVec
|
||||
sendTransactionTotal *prometheus.CounterVec
|
||||
sendTransactionFailureFullTx *prometheus.GaugeVec
|
||||
sendTransactionFailureRepeatTransaction *prometheus.CounterVec
|
||||
sendTransactionFailureGetFee *prometheus.CounterVec
|
||||
sendTransactionFailureSendTx *prometheus.CounterVec
|
||||
resubmitTransactionTotal *prometheus.CounterVec
|
||||
currentPendingTxsNum *prometheus.GaugeVec
|
||||
currentGasFeeCap *prometheus.GaugeVec
|
||||
currentGasTipCap *prometheus.GaugeVec
|
||||
currentGasPrice *prometheus.GaugeVec
|
||||
currentGasLimit *prometheus.GaugeVec
|
||||
currentNonce *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
var (
|
||||
initSenderMetricOnce sync.Once
|
||||
sm *senderMetrics
|
||||
)
|
||||
|
||||
func initSenderMetrics(reg prometheus.Registerer) *senderMetrics {
|
||||
initSenderMetricOnce.Do(func() {
|
||||
sm = &senderMetrics{
|
||||
sendTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_total",
|
||||
Help: "The total number of sending transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureFullTx: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_send_transaction_full_tx_failure_total",
|
||||
Help: "The total number of sending transaction failure for full size tx.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureRepeatTransaction: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_repeat_transaction_failure_total",
|
||||
Help: "The total number of sending transaction failure for repeat transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureGetFee: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_get_fee_failure_total",
|
||||
Help: "The total number of sending transaction failure for getting fee.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureSendTx: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_send_tx_failure_total",
|
||||
Help: "The total number of sending transaction failure for sending tx.",
|
||||
}, []string{"service", "name"}),
|
||||
resubmitTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_resubmit_send_transaction_total",
|
||||
Help: "The total number of resubmit transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentPendingTxsNum: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_pending_tx_count",
|
||||
Help: "The pending tx count in the sender.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasFeeCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_fee_cap",
|
||||
Help: "The gas fee of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasTipCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_tip_cap",
|
||||
Help: "The gas tip of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasPrice: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_price_cap",
|
||||
Help: "The gas price of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasLimit: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_limit",
|
||||
Help: "The gas limit of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentNonce: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_nonce",
|
||||
Help: "The nonce of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
senderCheckPendingTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_check_pending_transaction_total",
|
||||
Help: "The total number of check pending transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
senderCheckBalancerTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_check_balancer_total",
|
||||
Help: "The total number of check balancer.",
|
||||
}, []string{"service", "name"}),
|
||||
}
|
||||
})
|
||||
|
||||
return sm
|
||||
}
|
||||
@@ -1,30 +1,26 @@
|
||||
package sender
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
cmapV2 "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/ethclient/gethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rlp"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"scroll-tech/common/types"
|
||||
|
||||
"scroll-tech/rollup/internal/config"
|
||||
"scroll-tech/rollup/internal/orm"
|
||||
"scroll-tech/rollup/internal/utils"
|
||||
)
|
||||
|
||||
@@ -39,12 +35,18 @@ const (
|
||||
LegacyTxType = "LegacyTx"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoAvailableAccount indicates no available account error in the account pool.
|
||||
ErrNoAvailableAccount = errors.New("sender has no available account to send transaction")
|
||||
// ErrFullPending sender's pending pool is full.
|
||||
ErrFullPending = errors.New("sender's pending pool is full")
|
||||
)
|
||||
|
||||
// Confirmation struct used to indicate transaction confirmation details
|
||||
type Confirmation struct {
|
||||
ContextID string
|
||||
ID string
|
||||
IsSuccessful bool
|
||||
TxHash common.Hash
|
||||
SenderType types.SenderType
|
||||
}
|
||||
|
||||
// FeeData fee struct used to estimate gas price
|
||||
@@ -53,11 +55,20 @@ type FeeData struct {
|
||||
gasTipCap *big.Int
|
||||
gasPrice *big.Int
|
||||
|
||||
accessList gethTypes.AccessList
|
||||
accessList types.AccessList
|
||||
|
||||
gasLimit uint64
|
||||
}
|
||||
|
||||
// PendingTransaction submitted but pending transactions
|
||||
type PendingTransaction struct {
|
||||
submitAt uint64
|
||||
id string
|
||||
feeData *FeeData
|
||||
signer *bind.TransactOpts
|
||||
tx *types.Transaction
|
||||
}
|
||||
|
||||
// Sender Transaction sender to send transaction to l1/l2 geth
|
||||
type Sender struct {
|
||||
config *config.SenderConfig
|
||||
@@ -67,25 +78,23 @@ type Sender struct {
|
||||
ctx context.Context
|
||||
service string
|
||||
name string
|
||||
senderType types.SenderType
|
||||
|
||||
auth *bind.TransactOpts
|
||||
auth *bind.TransactOpts
|
||||
minBalance *big.Int
|
||||
|
||||
db *gorm.DB
|
||||
pendingTransactionOrm *orm.PendingTransaction
|
||||
blockNumber uint64 // Current block number on chain.
|
||||
baseFeePerGas uint64 // Current base fee per gas on chain
|
||||
pendingTxs cmapV2.ConcurrentMap[string, *PendingTransaction] // Mapping from nonce to pending transaction
|
||||
confirmCh chan *Confirmation
|
||||
|
||||
confirmCh chan *Confirmation
|
||||
stopCh chan struct{}
|
||||
stopCh chan struct{}
|
||||
|
||||
metrics *senderMetrics
|
||||
}
|
||||
|
||||
// NewSender returns a new instance of transaction sender
|
||||
func NewSender(ctx context.Context, config *config.SenderConfig, priv *ecdsa.PrivateKey, service, name string, senderType types.SenderType, db *gorm.DB, reg prometheus.Registerer) (*Sender, error) {
|
||||
if config.EscalateMultipleNum <= config.EscalateMultipleDen {
|
||||
return nil, fmt.Errorf("invalid params, EscalateMultipleNum; %v, EscalateMultipleDen: %v", config.EscalateMultipleNum, config.EscalateMultipleDen)
|
||||
}
|
||||
|
||||
// txConfirmationCh is used to notify confirmed transaction
|
||||
func NewSender(ctx context.Context, config *config.SenderConfig, priv *ecdsa.PrivateKey, service, name string, reg prometheus.Registerer) (*Sender, error) {
|
||||
rpcClient, err := rpc.Dial(config.Endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to dial eth client, err: %w", err)
|
||||
@@ -109,20 +118,36 @@ func NewSender(ctx context.Context, config *config.SenderConfig, priv *ecdsa.Pri
|
||||
}
|
||||
auth.Nonce = big.NewInt(int64(nonce))
|
||||
|
||||
// get header by number
|
||||
header, err := client.HeaderByNumber(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get header by number, err: %w", err)
|
||||
}
|
||||
|
||||
var baseFeePerGas uint64
|
||||
if config.TxType == DynamicFeeTxType {
|
||||
if header.BaseFee != nil {
|
||||
baseFeePerGas = header.BaseFee.Uint64()
|
||||
} else {
|
||||
return nil, errors.New("dynamic fee tx type not supported: header.BaseFee is nil")
|
||||
}
|
||||
}
|
||||
|
||||
sender := &Sender{
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
gethClient: gethclient.New(rpcClient),
|
||||
client: client,
|
||||
chainID: chainID,
|
||||
auth: auth,
|
||||
db: db,
|
||||
pendingTransactionOrm: orm.NewPendingTransaction(db),
|
||||
confirmCh: make(chan *Confirmation, 128),
|
||||
stopCh: make(chan struct{}),
|
||||
name: name,
|
||||
service: service,
|
||||
senderType: senderType,
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
gethClient: gethclient.New(rpcClient),
|
||||
client: client,
|
||||
chainID: chainID,
|
||||
auth: auth,
|
||||
minBalance: config.MinBalance,
|
||||
confirmCh: make(chan *Confirmation, 128),
|
||||
blockNumber: header.Number.Uint64(),
|
||||
baseFeePerGas: baseFeePerGas,
|
||||
pendingTxs: cmapV2.New[*PendingTransaction](),
|
||||
stopCh: make(chan struct{}),
|
||||
name: name,
|
||||
service: service,
|
||||
}
|
||||
sender.metrics = initSenderMetrics(reg)
|
||||
|
||||
@@ -131,6 +156,21 @@ func NewSender(ctx context.Context, config *config.SenderConfig, priv *ecdsa.Pri
|
||||
return sender, nil
|
||||
}
|
||||
|
||||
// PendingCount returns the current number of pending txs.
|
||||
func (s *Sender) PendingCount() int {
|
||||
return s.pendingTxs.Count()
|
||||
}
|
||||
|
||||
// PendingLimit returns the maximum number of pending txs the sender can handle.
|
||||
func (s *Sender) PendingLimit() int {
|
||||
return s.config.PendingLimit
|
||||
}
|
||||
|
||||
// IsFull returns true if the sender's pending tx pool is full.
|
||||
func (s *Sender) IsFull() bool {
|
||||
return s.pendingTxs.Count() >= s.config.PendingLimit
|
||||
}
|
||||
|
||||
// GetChainID returns the chain ID associated with the sender.
|
||||
func (s *Sender) GetChainID() *big.Int {
|
||||
return s.chainID
|
||||
@@ -139,7 +179,7 @@ func (s *Sender) GetChainID() *big.Int {
|
||||
// Stop stop the sender module.
|
||||
func (s *Sender) Stop() {
|
||||
close(s.stopCh)
|
||||
log.Info("sender stopped", "name", s.name, "service", s.service, "address", s.auth.From.String())
|
||||
log.Info("Transaction sender stopped")
|
||||
}
|
||||
|
||||
// ConfirmChan channel used to communicate with transaction sender
|
||||
@@ -153,51 +193,67 @@ func (s *Sender) SendConfirmation(cfm *Confirmation) {
|
||||
s.confirmCh <- cfm
|
||||
}
|
||||
|
||||
func (s *Sender) getFeeData(target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64, baseFee uint64) (*FeeData, error) {
|
||||
func (s *Sender) getFeeData(auth *bind.TransactOpts, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
|
||||
if s.config.TxType == DynamicFeeTxType {
|
||||
return s.estimateDynamicGas(target, value, data, fallbackGasLimit, baseFee)
|
||||
return s.estimateDynamicGas(auth, target, value, data, fallbackGasLimit)
|
||||
}
|
||||
return s.estimateLegacyGas(target, value, data, fallbackGasLimit)
|
||||
return s.estimateLegacyGas(auth, target, value, data, fallbackGasLimit)
|
||||
}
|
||||
|
||||
// SendTransaction send a signed L2tL1 transaction.
|
||||
func (s *Sender) SendTransaction(contextID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (common.Hash, error) {
|
||||
func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (common.Hash, error) {
|
||||
s.metrics.sendTransactionTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
if s.IsFull() {
|
||||
s.metrics.sendTransactionFailureFullTx.WithLabelValues(s.service, s.name).Set(1)
|
||||
return common.Hash{}, ErrFullPending
|
||||
}
|
||||
|
||||
s.metrics.sendTransactionFailureFullTx.WithLabelValues(s.service, s.name).Set(0)
|
||||
if ok := s.pendingTxs.SetIfAbsent(ID, nil); !ok {
|
||||
s.metrics.sendTransactionFailureRepeatTransaction.WithLabelValues(s.service, s.name).Inc()
|
||||
return common.Hash{}, fmt.Errorf("repeat transaction ID: %s", ID)
|
||||
}
|
||||
|
||||
var (
|
||||
feeData *FeeData
|
||||
tx *gethTypes.Transaction
|
||||
tx *types.Transaction
|
||||
err error
|
||||
)
|
||||
|
||||
blockNumber, baseFee, err := s.getBlockNumberAndBaseFee(s.ctx)
|
||||
if err != nil {
|
||||
log.Error("failed to get block number and base fee", "error", err)
|
||||
return common.Hash{}, fmt.Errorf("failed to get block number and base fee, err: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
s.pendingTxs.Remove(ID) // release the ID on failure
|
||||
}
|
||||
}()
|
||||
|
||||
if feeData, err = s.getFeeData(target, value, data, fallbackGasLimit, baseFee); err != nil {
|
||||
if feeData, err = s.getFeeData(s.auth, target, value, data, fallbackGasLimit); err != nil {
|
||||
s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc()
|
||||
log.Error("failed to get fee data", "from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "fallback gas limit", fallbackGasLimit, "err", err)
|
||||
return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err)
|
||||
}
|
||||
|
||||
if tx, err = s.createAndSendTx(feeData, target, value, data, nil); err != nil {
|
||||
if tx, err = s.createAndSendTx(s.auth, feeData, target, value, data, nil); err != nil {
|
||||
s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc()
|
||||
log.Error("failed to create and send tx (non-resubmit case)", "from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "err", err)
|
||||
return common.Hash{}, fmt.Errorf("failed to create and send transaction, err: %w", err)
|
||||
}
|
||||
|
||||
if err = s.pendingTransactionOrm.InsertPendingTransaction(s.ctx, contextID, s.getSenderMeta(), tx, blockNumber); err != nil {
|
||||
log.Error("failed to insert transaction", "from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "err", err)
|
||||
return common.Hash{}, fmt.Errorf("failed to insert transaction, err: %w", err)
|
||||
// add pending transaction
|
||||
pending := &PendingTransaction{
|
||||
tx: tx,
|
||||
id: ID,
|
||||
signer: s.auth,
|
||||
submitAt: atomic.LoadUint64(&s.blockNumber),
|
||||
feeData: feeData,
|
||||
}
|
||||
s.pendingTxs.Set(ID, pending)
|
||||
return tx.Hash(), nil
|
||||
}
|
||||
|
||||
func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value *big.Int, data []byte, overrideNonce *uint64) (*gethTypes.Transaction, error) {
|
||||
func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, target *common.Address, value *big.Int, data []byte, overrideNonce *uint64) (*types.Transaction, error) {
|
||||
var (
|
||||
nonce = s.auth.Nonce.Uint64()
|
||||
txData gethTypes.TxData
|
||||
nonce = auth.Nonce.Uint64()
|
||||
txData types.TxData
|
||||
)
|
||||
|
||||
// this is a resubmit call, override the nonce
|
||||
@@ -205,10 +261,11 @@ func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value
|
||||
nonce = *overrideNonce
|
||||
}
|
||||
|
||||
// lock here to avoit blocking when call `SuggestGasPrice`
|
||||
switch s.config.TxType {
|
||||
case LegacyTxType:
|
||||
// for ganache mock node
|
||||
txData = &gethTypes.LegacyTx{
|
||||
txData = &types.LegacyTx{
|
||||
Nonce: nonce,
|
||||
GasPrice: feeData.gasPrice,
|
||||
Gas: feeData.gasLimit,
|
||||
@@ -220,7 +277,7 @@ func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value
|
||||
S: new(big.Int),
|
||||
}
|
||||
case AccessListTxType:
|
||||
txData = &gethTypes.AccessListTx{
|
||||
txData = &types.AccessListTx{
|
||||
ChainID: s.chainID,
|
||||
Nonce: nonce,
|
||||
GasPrice: feeData.gasPrice,
|
||||
@@ -234,7 +291,7 @@ func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value
|
||||
S: new(big.Int),
|
||||
}
|
||||
default:
|
||||
txData = &gethTypes.DynamicFeeTx{
|
||||
txData = &types.DynamicFeeTx{
|
||||
Nonce: nonce,
|
||||
To: target,
|
||||
Data: common.CopyBytes(data),
|
||||
@@ -251,14 +308,13 @@ func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value
|
||||
}
|
||||
|
||||
// sign and send
|
||||
tx, err := s.auth.Signer(s.auth.From, gethTypes.NewTx(txData))
|
||||
tx, err := auth.Signer(auth.From, types.NewTx(txData))
|
||||
if err != nil {
|
||||
log.Error("failed to sign tx", "address", s.auth.From.String(), "err", err)
|
||||
log.Error("failed to sign tx", "address", auth.From.String(), "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = s.client.SendTransaction(s.ctx, tx); err != nil {
|
||||
log.Error("failed to send tx", "tx hash", tx.Hash().String(), "from", s.auth.From.String(), "nonce", tx.Nonce(), "err", err)
|
||||
log.Error("failed to send tx", "tx hash", tx.Hash().String(), "from", auth.From.String(), "nonce", tx.Nonce(), "err", err)
|
||||
// Check if contain nonce, and reset nonce
|
||||
// only reset nonce when it is not from resubmit
|
||||
if strings.Contains(err.Error(), "nonce") && overrideNonce == nil {
|
||||
@@ -283,12 +339,12 @@ func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value
|
||||
|
||||
// update nonce when it is not from resubmit
|
||||
if overrideNonce == nil {
|
||||
s.auth.Nonce = big.NewInt(int64(nonce + 1))
|
||||
auth.Nonce = big.NewInt(int64(nonce + 1))
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// resetNonce reset nonce if send signed tx failed.
|
||||
// reSetNonce reset nonce if send signed tx failed.
|
||||
func (s *Sender) resetNonce(ctx context.Context) {
|
||||
nonce, err := s.client.PendingNonceAt(ctx, s.auth.From)
|
||||
if err != nil {
|
||||
@@ -298,7 +354,7 @@ func (s *Sender) resetNonce(ctx context.Context) {
|
||||
s.auth.Nonce = big.NewInt(int64(nonce))
|
||||
}
|
||||
|
||||
func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64) (*gethTypes.Transaction, error) {
|
||||
func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts, tx *types.Transaction) (*types.Transaction, error) {
|
||||
escalateMultipleNum := new(big.Int).SetUint64(s.config.EscalateMultipleNum)
|
||||
escalateMultipleDen := new(big.Int).SetUint64(s.config.EscalateMultipleDen)
|
||||
maxGasPrice := new(big.Int).SetUint64(s.config.MaxGasPrice)
|
||||
@@ -306,17 +362,18 @@ func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64)
|
||||
txInfo := map[string]interface{}{
|
||||
"tx_hash": tx.Hash().String(),
|
||||
"tx_type": s.config.TxType,
|
||||
"from": s.auth.From.String(),
|
||||
"from": auth.From.String(),
|
||||
"nonce": tx.Nonce(),
|
||||
}
|
||||
|
||||
var feeData FeeData
|
||||
feeData.gasLimit = tx.Gas()
|
||||
switch s.config.TxType {
|
||||
case LegacyTxType, AccessListTxType: // `LegacyTxType`is for ganache mock node
|
||||
originalGasPrice := tx.GasPrice()
|
||||
gasPrice := new(big.Int).Mul(escalateMultipleNum, originalGasPrice)
|
||||
originalGasPrice := feeData.gasPrice
|
||||
gasPrice := escalateMultipleNum.Mul(escalateMultipleNum, big.NewInt(feeData.gasPrice.Int64()))
|
||||
gasPrice = gasPrice.Div(gasPrice, escalateMultipleDen)
|
||||
if gasPrice.Cmp(feeData.gasPrice) < 0 {
|
||||
gasPrice = feeData.gasPrice
|
||||
}
|
||||
if gasPrice.Cmp(maxGasPrice) > 0 {
|
||||
gasPrice = maxGasPrice
|
||||
}
|
||||
@@ -330,16 +387,27 @@ func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64)
|
||||
txInfo["original_gas_price"] = originalGasPrice.Uint64()
|
||||
txInfo["adjusted_gas_price"] = gasPrice.Uint64()
|
||||
default:
|
||||
originalGasTipCap := tx.GasTipCap()
|
||||
originalGasFeeCap := tx.GasFeeCap()
|
||||
originalGasTipCap := big.NewInt(feeData.gasTipCap.Int64())
|
||||
originalGasFeeCap := big.NewInt(feeData.gasFeeCap.Int64())
|
||||
|
||||
gasTipCap := new(big.Int).Mul(originalGasTipCap, escalateMultipleNum)
|
||||
gasTipCap := big.NewInt(feeData.gasTipCap.Int64())
|
||||
gasTipCap = gasTipCap.Mul(gasTipCap, escalateMultipleNum)
|
||||
gasTipCap = gasTipCap.Div(gasTipCap, escalateMultipleDen)
|
||||
gasFeeCap := new(big.Int).Mul(originalGasFeeCap, escalateMultipleNum)
|
||||
gasFeeCap := big.NewInt(feeData.gasFeeCap.Int64())
|
||||
gasFeeCap = gasFeeCap.Mul(gasFeeCap, escalateMultipleNum)
|
||||
gasFeeCap = gasFeeCap.Div(gasFeeCap, escalateMultipleDen)
|
||||
if gasFeeCap.Cmp(feeData.gasFeeCap) < 0 {
|
||||
gasFeeCap = feeData.gasFeeCap
|
||||
}
|
||||
if gasTipCap.Cmp(feeData.gasTipCap) < 0 {
|
||||
gasTipCap = feeData.gasTipCap
|
||||
}
|
||||
|
||||
// adjust for rising basefee
|
||||
adjBaseFee := new(big.Int).SetUint64(baseFee)
|
||||
adjBaseFee := big.NewInt(0)
|
||||
if feeGas := atomic.LoadUint64(&s.baseFeePerGas); feeGas != 0 {
|
||||
adjBaseFee.SetUint64(feeGas)
|
||||
}
|
||||
adjBaseFee = adjBaseFee.Mul(adjBaseFee, escalateMultipleNum)
|
||||
adjBaseFee = adjBaseFee.Div(adjBaseFee, escalateMultipleDen)
|
||||
currentGasFeeCap := new(big.Int).Add(gasTipCap, adjBaseFee)
|
||||
@@ -352,11 +420,6 @@ func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64)
|
||||
gasFeeCap = maxGasPrice
|
||||
}
|
||||
|
||||
// gasTipCap <= gasFeeCap
|
||||
if gasTipCap.Cmp(gasFeeCap) > 0 {
|
||||
gasTipCap = gasFeeCap
|
||||
}
|
||||
|
||||
if originalGasTipCap.Cmp(gasTipCap) == 0 {
|
||||
log.Warn("gas tip cap bump corner case, add 1 wei", "original", originalGasTipCap.Uint64(), "adjusted", gasTipCap.Uint64())
|
||||
gasTipCap = new(big.Int).Add(gasTipCap, big.NewInt(1))
|
||||
@@ -375,11 +438,11 @@ func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64)
|
||||
txInfo["adjusted_gas_fee_cap"] = gasFeeCap.Uint64()
|
||||
}
|
||||
|
||||
log.Info("Transaction gas adjustment details", "service", s.service, "name", s.name, "txInfo", txInfo)
|
||||
log.Info("Transaction gas adjustment details", txInfo)
|
||||
|
||||
nonce := tx.Nonce()
|
||||
s.metrics.resubmitTransactionTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
tx, err := s.createAndSendTx(&feeData, tx.To(), tx.Value(), tx.Data(), &nonce)
|
||||
tx, err := s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data(), &nonce)
|
||||
if err != nil {
|
||||
log.Error("failed to create and send tx (resubmit case)", "from", s.auth.From.String(), "nonce", nonce, "err", err)
|
||||
return nil, err
|
||||
@@ -389,120 +452,137 @@ func (s *Sender) resubmitTransaction(tx *gethTypes.Transaction, baseFee uint64)
|
||||
|
||||
// checkPendingTransaction checks the confirmation status of pending transactions against the latest confirmed block number.
|
||||
// If a transaction hasn't been confirmed after a certain number of blocks, it will be resubmitted with an increased gas price.
|
||||
func (s *Sender) checkPendingTransaction() {
|
||||
s.metrics.senderCheckPendingTransactionTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
func (s *Sender) checkPendingTransaction(header *types.Header, confirmed uint64) {
|
||||
number := header.Number.Uint64()
|
||||
atomic.StoreUint64(&s.blockNumber, number)
|
||||
|
||||
blockNumber, baseFee, err := s.getBlockNumberAndBaseFee(s.ctx)
|
||||
if err != nil {
|
||||
log.Error("failed to get block number and base fee", "error", err)
|
||||
return
|
||||
if s.config.TxType == DynamicFeeTxType {
|
||||
if header.BaseFee != nil {
|
||||
atomic.StoreUint64(&s.baseFeePerGas, header.BaseFee.Uint64())
|
||||
} else {
|
||||
log.Error("DynamicFeeTxType not supported, header.BaseFee nil")
|
||||
}
|
||||
}
|
||||
|
||||
transactionsToCheck, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(s.ctx, s.senderType, 100)
|
||||
if err != nil {
|
||||
log.Error("failed to load pending transactions", "sender meta", s.getSenderMeta(), "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
confirmed, err := utils.GetLatestConfirmedBlockNumber(s.ctx, s.client, s.config.Confirmations)
|
||||
if err != nil {
|
||||
log.Error("failed to get latest confirmed block number", "confirmations", s.config.Confirmations, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, txnToCheck := range transactionsToCheck {
|
||||
tx := new(gethTypes.Transaction)
|
||||
if err := tx.DecodeRLP(rlp.NewStream(bytes.NewReader(txnToCheck.RLPEncoding), 0)); err != nil {
|
||||
log.Error("failed to decode RLP", "context ID", txnToCheck.ContextID, "sender meta", s.getSenderMeta(), "err", err)
|
||||
for item := range s.pendingTxs.IterBuffered() {
|
||||
key, pending := item.Key, item.Val
|
||||
// ignore empty id, since we use empty id to occupy pending task
|
||||
if pending == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
receipt, err := s.client.TransactionReceipt(s.ctx, tx.Hash())
|
||||
if (err == nil) && (receipt != nil) { // tx confirmed.
|
||||
receipt, err := s.client.TransactionReceipt(s.ctx, pending.tx.Hash())
|
||||
if (err == nil) && (receipt != nil) {
|
||||
if receipt.BlockNumber.Uint64() <= confirmed {
|
||||
err := s.db.Transaction(func(dbTX *gorm.DB) error {
|
||||
// Update the status of the transaction to TxStatusConfirmed.
|
||||
if err := s.pendingTransactionOrm.UpdatePendingTransactionStatusByTxHash(s.ctx, tx.Hash(), types.TxStatusConfirmed, dbTX); err != nil {
|
||||
log.Error("failed to update transaction status by tx hash", "hash", tx.Hash().String(), "sender meta", s.getSenderMeta(), "from", s.auth.From.String(), "nonce", tx.Nonce(), "err", err)
|
||||
return err
|
||||
}
|
||||
// Update other transactions with the same nonce and sender address as failed.
|
||||
if err := s.pendingTransactionOrm.UpdateOtherTransactionsAsFailedByNonce(s.ctx, txnToCheck.SenderAddress, tx.Nonce(), tx.Hash(), dbTX); err != nil {
|
||||
log.Error("failed to update other transactions as failed by nonce", "senderAddress", txnToCheck.SenderAddress, "nonce", tx.Nonce(), "excludedTxHash", tx.Hash(), "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("db transaction failed after receiving confirmation", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
s.pendingTxs.Remove(key)
|
||||
// send confirm message
|
||||
s.confirmCh <- &Confirmation{
|
||||
ContextID: txnToCheck.ContextID,
|
||||
IsSuccessful: receipt.Status == gethTypes.ReceiptStatusSuccessful,
|
||||
TxHash: tx.Hash(),
|
||||
SenderType: s.senderType,
|
||||
ID: pending.id,
|
||||
IsSuccessful: receipt.Status == types.ReceiptStatusSuccessful,
|
||||
TxHash: pending.tx.Hash(),
|
||||
}
|
||||
}
|
||||
} else if txnToCheck.Status == types.TxStatusPending && // Only try resubmitting a new transaction based on gas price of the last transaction (status pending) with same ContextID.
|
||||
s.config.EscalateBlocks+txnToCheck.SubmitBlockNumber <= blockNumber {
|
||||
// It's possible that the pending transaction was marked as failed earlier in this loop (e.g., if one of its replacements has already been confirmed).
|
||||
// Therefore, we fetch the current transaction status again for accuracy before proceeding.
|
||||
status, err := s.pendingTransactionOrm.GetTxStatusByTxHash(s.ctx, tx.Hash())
|
||||
if err != nil {
|
||||
log.Error("failed to get transaction status by tx hash", "hash", tx.Hash().String(), "err", err)
|
||||
return
|
||||
}
|
||||
if status == types.TxStatusConfirmedFailed {
|
||||
log.Warn("transaction already marked as failed, skipping resubmission", "hash", tx.Hash().String())
|
||||
continue
|
||||
}
|
||||
|
||||
} else if s.config.EscalateBlocks+pending.submitAt < number {
|
||||
log.Info("resubmit transaction",
|
||||
"service", s.service,
|
||||
"name", s.name,
|
||||
"hash", tx.Hash().String(),
|
||||
"from", s.auth.From.String(),
|
||||
"nonce", tx.Nonce(),
|
||||
"submitBlockNumber", txnToCheck.SubmitBlockNumber,
|
||||
"currentBlockNumber", blockNumber,
|
||||
"escalateBlocks", s.config.EscalateBlocks)
|
||||
"hash", pending.tx.Hash().String(),
|
||||
"from", pending.signer.From.String(),
|
||||
"nonce", pending.tx.Nonce(),
|
||||
"submit block number", pending.submitAt,
|
||||
"current block number", number,
|
||||
"configured escalateBlocks", s.config.EscalateBlocks)
|
||||
|
||||
if newTx, err := s.resubmitTransaction(tx, baseFee); err != nil {
|
||||
s.metrics.resubmitTransactionFailedTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
log.Error("failed to resubmit transaction", "context ID", txnToCheck.ContextID, "sender meta", s.getSenderMeta(), "from", s.auth.From.String(), "nonce", newTx.Nonce(), "err", err)
|
||||
} else {
|
||||
err := s.db.Transaction(func(dbTX *gorm.DB) error {
|
||||
// Update the status of the original transaction as replaced, while still checking its confirmation status.
|
||||
if err := s.pendingTransactionOrm.UpdatePendingTransactionStatusByTxHash(s.ctx, tx.Hash(), types.TxStatusReplaced, dbTX); err != nil {
|
||||
return fmt.Errorf("failed to update status of transaction with hash %s to TxStatusReplaced, err: %w", tx.Hash().String(), err)
|
||||
}
|
||||
// Record the new transaction that has replaced the original one.
|
||||
if err := s.pendingTransactionOrm.InsertPendingTransaction(s.ctx, txnToCheck.ContextID, s.getSenderMeta(), newTx, blockNumber, dbTX); err != nil {
|
||||
return fmt.Errorf("failed to insert new pending transaction with context ID: %s, nonce: %d, hash: %v, previous block number: %v, current block number: %v, err: %w", txnToCheck.ContextID, newTx.Nonce(), newTx.Hash().String(), txnToCheck.SubmitBlockNumber, blockNumber, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("db transaction failed after resubmitting", "err", err)
|
||||
return
|
||||
if tx, err := s.resubmitTransaction(pending.feeData, pending.signer, pending.tx); err != nil {
|
||||
// If account pool is empty, it will try again in next loop.
|
||||
if !errors.Is(err, ErrNoAvailableAccount) {
|
||||
log.Error("failed to resubmit transaction, reset submitAt", "tx hash", pending.tx.Hash().String(), "err", err)
|
||||
}
|
||||
// This means one of the old transactions is confirmed
|
||||
// One scenario is
|
||||
// 1. Initially, we replace the tx three times and submit it to local node.
|
||||
// Currently, we keep the last tx hash in the memory.
|
||||
// 2. Other node packed the 2-nd tx or 3-rd tx, and the local node has received the block now.
|
||||
// 3. When we resubmit the 4-th tx, we got a nonce error.
|
||||
// 4. We need to check the status of 3-rd tx stored in our memory
|
||||
// 4.1 If the 3-rd tx is packed, we got a receipt and 3-nd is marked as confirmed.
|
||||
// 4.2 If the 2-nd tx is packed, we got nothing from `TransactionReceipt` call. Since we
|
||||
// cannot do anything about, we just log some information. In this case, the caller
|
||||
// of `sender.SendTransaction` should write extra code to handle the situation.
|
||||
// Another scenario is private key leaking and someone send a transaction with the same nonce.
|
||||
// We need to stop the program and manually handle the situation.
|
||||
if strings.Contains(err.Error(), "nonce") {
|
||||
// This key can be deleted
|
||||
s.pendingTxs.Remove(key)
|
||||
// Try get receipt by the latest replaced tx hash
|
||||
receipt, err := s.client.TransactionReceipt(s.ctx, pending.tx.Hash())
|
||||
if (err == nil) && (receipt != nil) {
|
||||
// send confirm message
|
||||
s.confirmCh <- &Confirmation{
|
||||
ID: pending.id,
|
||||
IsSuccessful: receipt.Status == types.ReceiptStatusSuccessful,
|
||||
TxHash: pending.tx.Hash(),
|
||||
}
|
||||
} else {
|
||||
// The receipt can be nil since the confirmed transaction may not be the latest one.
|
||||
// We just ignore it, the caller of the sender pool should handle this situation.
|
||||
log.Warn("Pending transaction is confirmed by one of the replaced transactions", "key", key, "signer", pending.signer.From, "nonce", pending.tx.Nonce())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// flush submitAt
|
||||
pending.tx = tx
|
||||
pending.submitAt = number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkBalance checks balance and print error log if balance is under a threshold.
|
||||
func (s *Sender) checkBalance(ctx context.Context) error {
|
||||
bls, err := s.client.BalanceAt(ctx, s.auth.From, nil)
|
||||
if err != nil {
|
||||
log.Warn("failed to get balance", "address", s.auth.From.String(), "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if bls.Cmp(s.minBalance) < 0 {
|
||||
return fmt.Errorf("insufficient account balance - actual balance: %s, minimum required balance: %s, address: %s",
|
||||
bls.String(), s.minBalance.String(), s.auth.From.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Loop is the main event loop
|
||||
func (s *Sender) loop(ctx context.Context) {
|
||||
checkTick := time.NewTicker(time.Duration(s.config.CheckPendingTime) * time.Second)
|
||||
defer checkTick.Stop()
|
||||
|
||||
checkBalanceTicker := time.NewTicker(time.Duration(s.config.CheckBalanceTime) * time.Second)
|
||||
defer checkBalanceTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-checkTick.C:
|
||||
s.checkPendingTransaction()
|
||||
s.metrics.senderCheckPendingTransactionTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
header, err := s.client.HeaderByNumber(s.ctx, nil)
|
||||
if err != nil {
|
||||
log.Error("failed to get latest head", "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
confirmed, err := utils.GetLatestConfirmedBlockNumber(s.ctx, s.client, s.config.Confirmations)
|
||||
if err != nil {
|
||||
log.Error("failed to get latest confirmed block number", "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
s.checkPendingTransaction(header, confirmed)
|
||||
case <-checkBalanceTicker.C:
|
||||
s.metrics.senderCheckBalancerTotal.WithLabelValues(s.service, s.name).Inc()
|
||||
// Check and set balance.
|
||||
if err := s.checkBalance(ctx); err != nil {
|
||||
log.Error("check balance error", "err", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-s.stopCh:
|
||||
@@ -510,29 +590,3 @@ func (s *Sender) loop(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sender) getSenderMeta() *orm.SenderMeta {
|
||||
return &orm.SenderMeta{
|
||||
Name: s.name,
|
||||
Service: s.service,
|
||||
Address: s.auth.From,
|
||||
Type: s.senderType,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sender) getBlockNumberAndBaseFee(ctx context.Context) (uint64, uint64, error) {
|
||||
header, err := s.client.HeaderByNumber(ctx, nil)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to get header by number, err: %w", err)
|
||||
}
|
||||
|
||||
var baseFeePerGas uint64
|
||||
if s.config.TxType == DynamicFeeTxType {
|
||||
if header.BaseFee != nil {
|
||||
baseFeePerGas = header.BaseFee.Uint64()
|
||||
} else {
|
||||
return 0, 0, errors.New("dynamic fee tx type not supported: header.BaseFee is nil")
|
||||
}
|
||||
}
|
||||
return header.Number.Uint64(), baseFeePerGas, nil
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package sender
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
type senderMetrics struct {
|
||||
senderCheckPendingTransactionTotal *prometheus.CounterVec
|
||||
sendTransactionTotal *prometheus.CounterVec
|
||||
sendTransactionFailureGetFee *prometheus.CounterVec
|
||||
sendTransactionFailureSendTx *prometheus.CounterVec
|
||||
resubmitTransactionTotal *prometheus.CounterVec
|
||||
resubmitTransactionFailedTotal *prometheus.CounterVec
|
||||
currentGasFeeCap *prometheus.GaugeVec
|
||||
currentGasTipCap *prometheus.GaugeVec
|
||||
currentGasPrice *prometheus.GaugeVec
|
||||
currentGasLimit *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
var (
|
||||
initSenderMetricOnce sync.Once
|
||||
sm *senderMetrics
|
||||
)
|
||||
|
||||
func initSenderMetrics(reg prometheus.Registerer) *senderMetrics {
|
||||
initSenderMetricOnce.Do(func() {
|
||||
sm = &senderMetrics{
|
||||
sendTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_total",
|
||||
Help: "The total number of sending transactions.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureGetFee: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_get_fee_failure_total",
|
||||
Help: "The total number of sending transactions failure for getting fee.",
|
||||
}, []string{"service", "name"}),
|
||||
sendTransactionFailureSendTx: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_send_tx_failure_total",
|
||||
Help: "The total number of sending transactions failure for sending tx.",
|
||||
}, []string{"service", "name"}),
|
||||
resubmitTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_resubmit_send_transaction_total",
|
||||
Help: "The total number of resubmit transactions.",
|
||||
}, []string{"service", "name"}),
|
||||
resubmitTransactionFailedTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_send_transaction_resubmit_send_transaction_failed_total",
|
||||
Help: "The total number of failed resubmit transactions.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasFeeCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_fee_cap",
|
||||
Help: "The gas fee cap of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasTipCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_tip_cap",
|
||||
Help: "The gas tip cap of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasPrice: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_price_cap",
|
||||
Help: "The gas price of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
currentGasLimit: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "rollup_sender_gas_limit",
|
||||
Help: "The gas limit of current transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
senderCheckPendingTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "rollup_sender_check_pending_transaction_total",
|
||||
Help: "The total number of check pending transaction.",
|
||||
}, []string{"service", "name"}),
|
||||
}
|
||||
})
|
||||
|
||||
return sm
|
||||
}
|
||||
@@ -4,41 +4,31 @@ import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/agiledragon/gomonkey/v2"
|
||||
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
|
||||
"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/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"scroll-tech/common/database"
|
||||
"scroll-tech/common/docker"
|
||||
"scroll-tech/common/types"
|
||||
"scroll-tech/database/migrate"
|
||||
|
||||
bridgeAbi "scroll-tech/rollup/abi"
|
||||
"scroll-tech/rollup/internal/config"
|
||||
"scroll-tech/rollup/mock_bridge"
|
||||
)
|
||||
|
||||
const TXBatch = 50
|
||||
|
||||
var (
|
||||
privateKey *ecdsa.PrivateKey
|
||||
cfg *config.Config
|
||||
base *docker.App
|
||||
txTypes = []string{"LegacyTx", "AccessListTx", "DynamicFeeTx"}
|
||||
db *gorm.DB
|
||||
mockL1ContractsAddress common.Address
|
||||
privateKey *ecdsa.PrivateKey
|
||||
cfg *config.Config
|
||||
base *docker.App
|
||||
txTypes = []string{"LegacyTx", "AccessListTx", "DynamicFeeTx"}
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -50,45 +40,17 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func setupEnv(t *testing.T) {
|
||||
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.LogfmtFormat()))
|
||||
glogger.Verbosity(log.LvlInfo)
|
||||
log.Root().SetHandler(glogger)
|
||||
|
||||
var err error
|
||||
cfg, err = config.NewConfig("../../../conf/config.json")
|
||||
assert.NoError(t, err)
|
||||
base.RunL1Geth(t)
|
||||
priv, err := crypto.HexToECDSA("1212121212121212121212121212121212121212121212121212121212121212")
|
||||
assert.NoError(t, err)
|
||||
// Load default private key.
|
||||
privateKey = priv
|
||||
|
||||
base.RunL1Geth(t)
|
||||
cfg.L1Config.RelayerConfig.SenderConfig.Endpoint = base.L1gethImg.Endpoint()
|
||||
|
||||
base.RunDBImage(t)
|
||||
db, err = database.InitDB(
|
||||
&database.Config{
|
||||
DSN: base.DBConfig.DSN,
|
||||
DriverName: base.DBConfig.DriverName,
|
||||
MaxOpenNum: base.DBConfig.MaxOpenNum,
|
||||
MaxIdleNum: base.DBConfig.MaxIdleNum,
|
||||
},
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, base.L1gethImg.ChainID())
|
||||
assert.NoError(t, err)
|
||||
|
||||
l1Client, err := base.L1Client()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, tx, _, err := mock_bridge.DeployMockBridgeL1(auth, l1Client)
|
||||
assert.NoError(t, err)
|
||||
|
||||
mockL1ContractsAddress, err = bind.WaitDeployed(context.Background(), l1Client, tx)
|
||||
assert.NoError(t, err)
|
||||
cfg.L1Config.RelayerConfig.SenderConfig.CheckBalanceTime = 1
|
||||
}
|
||||
|
||||
func TestSender(t *testing.T) {
|
||||
@@ -96,29 +58,21 @@ func TestSender(t *testing.T) {
|
||||
setupEnv(t)
|
||||
|
||||
t.Run("test new sender", testNewSender)
|
||||
t.Run("test pending limit", testPendLimit)
|
||||
t.Run("test fallback gas limit", testFallbackGasLimit)
|
||||
t.Run("test send and retrieve transaction", testSendAndRetrieveTransaction)
|
||||
t.Run("test access list transaction gas limit", testAccessListTransactionGasLimit)
|
||||
t.Run("test resubmit zero gas price transaction", testResubmitZeroGasPriceTransaction)
|
||||
t.Run("test resubmit non-zero gas price transaction", testResubmitNonZeroGasPriceTransaction)
|
||||
t.Run("test resubmit under priced transaction", testResubmitUnderpricedTransaction)
|
||||
t.Run("test resubmit transaction with rising base fee", testResubmitTransactionWithRisingBaseFee)
|
||||
t.Run("test check pending transaction tx confirmed", testCheckPendingTransactionTxConfirmed)
|
||||
t.Run("test check pending transaction resubmit tx confirmed", testCheckPendingTransactionResubmitTxConfirmed)
|
||||
t.Run("test check pending transaction replaced tx confirmed", testCheckPendingTransactionReplacedTxConfirmed)
|
||||
t.Run("test check pending transaction multiple times with only one transaction pending", testCheckPendingTransactionTxMultipleTimesWithOnlyOneTxPending)
|
||||
t.Run("test check pending transaction", testCheckPendingTransaction)
|
||||
}
|
||||
|
||||
func testNewSender(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
// exit by Stop()
|
||||
cfgCopy1 := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy1.TxType = txType
|
||||
newSender1, err := NewSender(context.Background(), &cfgCopy1, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
newSender1, err := NewSender(context.Background(), &cfgCopy1, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
newSender1.Stop()
|
||||
|
||||
@@ -126,57 +80,43 @@ func testNewSender(t *testing.T) {
|
||||
cfgCopy2 := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy2.TxType = txType
|
||||
subCtx, cancel := context.WithCancel(context.Background())
|
||||
_, err = NewSender(subCtx, &cfgCopy2, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
_, err = NewSender(subCtx, &cfgCopy2, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
func testSendAndRetrieveTransaction(t *testing.T) {
|
||||
for i, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
func testPendLimit(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
cfgCopy.Confirmations = rpc.LatestBlockNumber
|
||||
cfgCopy.PendingLimit = 2
|
||||
newSender, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
hash, err := s.SendTransaction("0", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
assert.Equal(t, "0", txs[0].ContextID)
|
||||
assert.Equal(t, hash.String(), txs[0].Hash)
|
||||
assert.Equal(t, uint8(i), txs[0].Type)
|
||||
assert.Equal(t, types.TxStatusPending, txs[0].Status)
|
||||
assert.Equal(t, "0x1C5A77d9FA7eF466951B2F01F724BCa3A5820b63", txs[0].SenderAddress)
|
||||
assert.Equal(t, types.SenderTypeUnknown, txs[0].SenderType)
|
||||
assert.Equal(t, "test", txs[0].SenderService)
|
||||
assert.Equal(t, "test", txs[0].SenderName)
|
||||
s.Stop()
|
||||
for i := 0; i < 2*newSender.PendingLimit(); i++ {
|
||||
_, err = newSender.SendTransaction(strconv.Itoa(i), &common.Address{}, big.NewInt(1), nil, 0)
|
||||
assert.True(t, err == nil || (err != nil && err.Error() == "sender's pending pool is full"))
|
||||
}
|
||||
assert.True(t, newSender.PendingCount() <= newSender.PendingLimit())
|
||||
newSender.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func testFallbackGasLimit(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
cfgCopy.Confirmations = rpc.LatestBlockNumber
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
client, err := ethclient.Dial(cfgCopy.Endpoint)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// FallbackGasLimit = 0
|
||||
txHash0, err := s.SendTransaction("0", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
txHash0, err := s.SendTransaction("0", &common.Address{}, big.NewInt(1), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
tx0, _, err := client.TransactionByHash(context.Background(), txHash0)
|
||||
assert.NoError(t, err)
|
||||
@@ -184,12 +124,12 @@ func testFallbackGasLimit(t *testing.T) {
|
||||
|
||||
// FallbackGasLimit = 100000
|
||||
patchGuard := gomonkey.ApplyPrivateMethod(s, "estimateGasLimit",
|
||||
func(contract *common.Address, data []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int) (uint64, *gethTypes.AccessList, error) {
|
||||
func(opts *bind.TransactOpts, contract *common.Address, input []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int) (uint64, *types.AccessList, error) {
|
||||
return 0, nil, errors.New("estimateGasLimit error")
|
||||
},
|
||||
)
|
||||
|
||||
txHash1, err := s.SendTransaction("1", &common.Address{}, big.NewInt(0), nil, 100000)
|
||||
txHash1, err := s.SendTransaction("1", &common.Address{}, big.NewInt(1), nil, 100000)
|
||||
assert.NoError(t, err)
|
||||
tx1, _, err := client.TransactionByHash(context.Background(), txHash1)
|
||||
assert.NoError(t, err)
|
||||
@@ -202,13 +142,9 @@ func testFallbackGasLimit(t *testing.T) {
|
||||
|
||||
func testResubmitZeroGasPriceTransaction(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
feeData := &FeeData{
|
||||
gasPrice: big.NewInt(0),
|
||||
@@ -216,59 +152,24 @@ func testResubmitZeroGasPriceTransaction(t *testing.T) {
|
||||
gasFeeCap: big.NewInt(0),
|
||||
gasLimit: 50000,
|
||||
}
|
||||
tx, err := s.createAndSendTx(feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
tx, err := s.createAndSendTx(s.auth, feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tx)
|
||||
// Increase at least 1 wei in gas price, gas tip cap and gas fee cap.
|
||||
_, err = s.resubmitTransaction(tx, 0)
|
||||
_, err = s.resubmitTransaction(feeData, s.auth, tx)
|
||||
assert.NoError(t, err)
|
||||
s.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func testAccessListTransactionGasLimit(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
l2GasOracleABI, err := bridgeAbi.L2GasPriceOracleMetaData.GetAbi()
|
||||
assert.NoError(t, err)
|
||||
|
||||
data, err := l2GasOracleABI.Pack("setL2BaseFee", big.NewInt(2333))
|
||||
assert.NoError(t, err)
|
||||
|
||||
gasLimit, accessList, err := s.estimateGasLimit(&mockL1ContractsAddress, data, big.NewInt(100000000000), big.NewInt(100000000000), big.NewInt(100000000000), big.NewInt(0), true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, uint64(43472), gasLimit)
|
||||
assert.NotNil(t, accessList)
|
||||
|
||||
gasLimit, accessList, err = s.estimateGasLimit(&mockL1ContractsAddress, data, big.NewInt(100000000000), big.NewInt(100000000000), big.NewInt(100000000000), big.NewInt(0), false)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, uint64(43949), gasLimit)
|
||||
assert.Nil(t, accessList)
|
||||
|
||||
s.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func testResubmitNonZeroGasPriceTransaction(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
// Bump gas price, gas tip cap and gas fee cap just touch the minimum threshold of 10% (default config of geth).
|
||||
cfgCopy.EscalateMultipleNum = 110
|
||||
cfgCopy.EscalateMultipleDen = 100
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
feeData := &FeeData{
|
||||
gasPrice: big.NewInt(100000),
|
||||
@@ -276,10 +177,10 @@ func testResubmitNonZeroGasPriceTransaction(t *testing.T) {
|
||||
gasFeeCap: big.NewInt(100000),
|
||||
gasLimit: 50000,
|
||||
}
|
||||
tx, err := s.createAndSendTx(feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
tx, err := s.createAndSendTx(s.auth, feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tx)
|
||||
_, err = s.resubmitTransaction(tx, 0)
|
||||
_, err = s.resubmitTransaction(feeData, s.auth, tx)
|
||||
assert.NoError(t, err)
|
||||
s.Stop()
|
||||
}
|
||||
@@ -287,16 +188,12 @@ func testResubmitNonZeroGasPriceTransaction(t *testing.T) {
|
||||
|
||||
func testResubmitUnderpricedTransaction(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
// Bump gas price, gas tip cap and gas fee cap less than 10% (default config of geth).
|
||||
cfgCopy.EscalateMultipleNum = 109
|
||||
cfgCopy.EscalateMultipleDen = 100
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
feeData := &FeeData{
|
||||
gasPrice: big.NewInt(100000),
|
||||
@@ -304,32 +201,30 @@ func testResubmitUnderpricedTransaction(t *testing.T) {
|
||||
gasFeeCap: big.NewInt(100000),
|
||||
gasLimit: 50000,
|
||||
}
|
||||
tx, err := s.createAndSendTx(feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
tx, err := s.createAndSendTx(s.auth, feeData, &common.Address{}, big.NewInt(0), nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tx)
|
||||
_, err = s.resubmitTransaction(tx, 0)
|
||||
_, err = s.resubmitTransaction(feeData, s.auth, tx)
|
||||
assert.Error(t, err, "replacement transaction underpriced")
|
||||
s.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func testResubmitTransactionWithRisingBaseFee(t *testing.T) {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
txType := "DynamicFeeTx"
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
tx := types.NewTransaction(s.auth.Nonce.Uint64(), common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil)
|
||||
s.baseFeePerGas = 1000
|
||||
feeData, err := s.getFeeData(s.auth, &common.Address{}, big.NewInt(0), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
tx := gethTypes.NewTransaction(s.auth.Nonce.Uint64(), common.Address{}, big.NewInt(0), 21000, big.NewInt(0), nil)
|
||||
baseFeePerGas := uint64(1000)
|
||||
// bump the basefee by 10x
|
||||
baseFeePerGas *= 10
|
||||
s.baseFeePerGas *= 10
|
||||
// resubmit and check that the gas fee has been adjusted accordingly
|
||||
newTx, err := s.resubmitTransaction(tx, baseFeePerGas)
|
||||
newTx, err := s.resubmitTransaction(feeData, s.auth, tx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
escalateMultipleNum := new(big.Int).SetUint64(s.config.EscalateMultipleNum)
|
||||
@@ -337,214 +232,104 @@ func testResubmitTransactionWithRisingBaseFee(t *testing.T) {
|
||||
maxGasPrice := new(big.Int).SetUint64(s.config.MaxGasPrice)
|
||||
|
||||
adjBaseFee := new(big.Int)
|
||||
adjBaseFee.SetUint64(baseFeePerGas)
|
||||
adjBaseFee.SetUint64(s.baseFeePerGas)
|
||||
adjBaseFee = adjBaseFee.Mul(adjBaseFee, escalateMultipleNum)
|
||||
adjBaseFee = adjBaseFee.Div(adjBaseFee, escalateMultipleDen)
|
||||
|
||||
expectedGasFeeCap := new(big.Int).Add(tx.GasTipCap(), adjBaseFee)
|
||||
expectedGasFeeCap := new(big.Int).Add(feeData.gasTipCap, adjBaseFee)
|
||||
if expectedGasFeeCap.Cmp(maxGasPrice) > 0 {
|
||||
expectedGasFeeCap = maxGasPrice
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedGasFeeCap.Int64(), newTx.GasFeeCap().Int64())
|
||||
|
||||
s.Stop()
|
||||
}
|
||||
|
||||
func testCheckPendingTransactionTxConfirmed(t *testing.T) {
|
||||
func testCheckPendingTransaction(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeCommitBatch, db, nil)
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = s.SendTransaction("test", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
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)}
|
||||
tx := types.NewTransaction(s.auth.Nonce.Uint64(), common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil)
|
||||
|
||||
txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
assert.Equal(t, types.TxStatusPending, txs[0].Status)
|
||||
assert.Equal(t, types.SenderTypeCommitBatch, txs[0].SenderType)
|
||||
|
||||
patchGuard := gomonkey.ApplyMethodFunc(s.client, "TransactionReceipt", func(_ context.Context, hash common.Hash) (*gethTypes.Receipt, error) {
|
||||
return &gethTypes.Receipt{TxHash: hash, BlockNumber: big.NewInt(0), Status: gethTypes.ReceiptStatusSuccessful}, nil
|
||||
})
|
||||
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 0)
|
||||
|
||||
s.Stop()
|
||||
patchGuard.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckPendingTransactionResubmitTxConfirmed(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
cfgCopy.EscalateBlocks = 0
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeFinalizeBatch, db, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
originTxHash, err := s.SendTransaction("test", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
assert.Equal(t, types.TxStatusPending, txs[0].Status)
|
||||
assert.Equal(t, types.SenderTypeFinalizeBatch, txs[0].SenderType)
|
||||
|
||||
patchGuard := gomonkey.ApplyMethodFunc(s.client, "TransactionReceipt", func(_ context.Context, hash common.Hash) (*gethTypes.Receipt, error) {
|
||||
if hash == originTxHash {
|
||||
return nil, fmt.Errorf("simulated transaction receipt error")
|
||||
}
|
||||
return &gethTypes.Receipt{TxHash: hash, BlockNumber: big.NewInt(0), Status: gethTypes.ReceiptStatusSuccessful}, nil
|
||||
})
|
||||
|
||||
// Attempt to resubmit the transaction.
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
status, err := s.pendingTransactionOrm.GetTxStatusByTxHash(context.Background(), originTxHash)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, types.TxStatusReplaced, status)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 2)
|
||||
assert.Equal(t, types.TxStatusReplaced, txs[0].Status)
|
||||
assert.Equal(t, types.TxStatusPending, txs[1].Status)
|
||||
|
||||
// Check the pending transactions again after attempting to resubmit.
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 0)
|
||||
|
||||
s.Stop()
|
||||
patchGuard.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckPendingTransactionReplacedTxConfirmed(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
cfgCopy.EscalateBlocks = 0
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeL1GasOracle, db, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txHash, err := s.SendTransaction("test", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
assert.Equal(t, types.TxStatusPending, txs[0].Status)
|
||||
assert.Equal(t, types.SenderTypeL1GasOracle, txs[0].SenderType)
|
||||
|
||||
patchGuard := gomonkey.ApplyMethodFunc(s.client, "TransactionReceipt", func(_ context.Context, hash common.Hash) (*gethTypes.Receipt, error) {
|
||||
var status types.TxStatus
|
||||
status, err = s.pendingTransactionOrm.GetTxStatusByTxHash(context.Background(), hash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get transaction status, hash: %s, err: %w", hash.String(), err)
|
||||
}
|
||||
// If the transaction status is 'replaced', return a successful receipt.
|
||||
if status == types.TxStatusReplaced {
|
||||
return &gethTypes.Receipt{
|
||||
TxHash: hash,
|
||||
BlockNumber: big.NewInt(0),
|
||||
Status: gethTypes.ReceiptStatusSuccessful,
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("simulated transaction receipt error")
|
||||
})
|
||||
|
||||
// Attempt to resubmit the transaction.
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
status, err := s.pendingTransactionOrm.GetTxStatusByTxHash(context.Background(), txHash)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, types.TxStatusReplaced, status)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 2)
|
||||
assert.Equal(t, types.TxStatusReplaced, txs[0].Status)
|
||||
assert.Equal(t, types.TxStatusPending, txs[1].Status)
|
||||
|
||||
// Check the pending transactions again after attempting to resubmit.
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 0)
|
||||
|
||||
s.Stop()
|
||||
patchGuard.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckPendingTransactionTxMultipleTimesWithOnlyOneTxPending(t *testing.T) {
|
||||
for _, txType := range txTypes {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
cfgCopy := *cfg.L1Config.RelayerConfig.SenderConfig
|
||||
cfgCopy.TxType = txType
|
||||
cfgCopy.EscalateBlocks = 0
|
||||
s, err := NewSender(context.Background(), &cfgCopy, privateKey, "test", "test", types.SenderTypeCommitBatch, db, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = s.SendTransaction("test", &common.Address{}, big.NewInt(0), nil, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
assert.Equal(t, types.TxStatusPending, txs[0].Status)
|
||||
assert.Equal(t, types.SenderTypeCommitBatch, txs[0].SenderType)
|
||||
|
||||
patchGuard := gomonkey.ApplyMethodFunc(s.client, "TransactionReceipt", func(_ context.Context, hash common.Hash) (*gethTypes.Receipt, error) {
|
||||
return nil, fmt.Errorf("simulated transaction receipt error")
|
||||
})
|
||||
|
||||
for i := 1; i <= 6; i++ {
|
||||
s.checkPendingTransaction()
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, i+1)
|
||||
for j := 0; j < i; j++ {
|
||||
assert.Equal(t, types.TxStatusReplaced, txs[j].Status)
|
||||
}
|
||||
assert.Equal(t, types.TxStatusPending, txs[i].Status)
|
||||
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, signer: s.auth, 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()
|
||||
patchGuard.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"scroll-tech/common/database"
|
||||
"scroll-tech/common/types"
|
||||
cutils "scroll-tech/common/utils"
|
||||
|
||||
bridgeAbi "scroll-tech/rollup/abi"
|
||||
@@ -52,7 +51,7 @@ func testCreateNewWatcherAndStop(t *testing.T) {
|
||||
|
||||
l1cfg := cfg.L1Config
|
||||
l1cfg.RelayerConfig.SenderConfig.Confirmations = rpc.LatestBlockNumber
|
||||
newSender, err := sender.NewSender(context.Background(), l1cfg.RelayerConfig.SenderConfig, l1cfg.RelayerConfig.GasOracleSenderPrivateKey, "test", "test", types.SenderTypeUnknown, db, nil)
|
||||
newSender, err := sender.NewSender(context.Background(), l1cfg.RelayerConfig.SenderConfig, l1cfg.RelayerConfig.GasOracleSenderPrivateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create several transactions and commit to block
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -34,10 +33,6 @@ var (
|
||||
)
|
||||
|
||||
func setupEnv(t *testing.T) (err error) {
|
||||
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.LogfmtFormat()))
|
||||
glogger.Verbosity(log.LvlInfo)
|
||||
log.Root().SetHandler(glogger)
|
||||
|
||||
// Load config.
|
||||
cfg, err = config.NewConfig("../../../conf/config.json")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -3,29 +3,27 @@ package orm
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"scroll-tech/common/database"
|
||||
"scroll-tech/common/docker"
|
||||
"scroll-tech/common/types"
|
||||
|
||||
"scroll-tech/database/migrate"
|
||||
)
|
||||
|
||||
var (
|
||||
base *docker.App
|
||||
|
||||
db *gorm.DB
|
||||
l2BlockOrm *L2Block
|
||||
chunkOrm *Chunk
|
||||
batchOrm *Batch
|
||||
pendingTransactionOrm *PendingTransaction
|
||||
db *gorm.DB
|
||||
l2BlockOrm *L2Block
|
||||
chunkOrm *Chunk
|
||||
batchOrm *Batch
|
||||
|
||||
wrappedBlock1 *types.WrappedBlock
|
||||
wrappedBlock2 *types.WrappedBlock
|
||||
@@ -62,7 +60,6 @@ func setupEnv(t *testing.T) {
|
||||
batchOrm = NewBatch(db)
|
||||
chunkOrm = NewChunk(db)
|
||||
l2BlockOrm = NewL2Block(db)
|
||||
pendingTransactionOrm = NewPendingTransaction(db)
|
||||
|
||||
templateBlockTrace, err := os.ReadFile("../../../common/testdata/blockTrace_02.json")
|
||||
assert.NoError(t, err)
|
||||
@@ -313,85 +310,3 @@ func TestBatchOrm(t *testing.T) {
|
||||
assert.Equal(t, "finalizeTxHash", updatedBatch.FinalizeTxHash)
|
||||
assert.Equal(t, types.RollupFinalizeFailed, types.RollupStatus(updatedBatch.RollupStatus))
|
||||
}
|
||||
|
||||
func TestTransactionOrm(t *testing.T) {
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(sqlDB))
|
||||
|
||||
tx0 := gethTypes.NewTx(&gethTypes.DynamicFeeTx{
|
||||
Nonce: 0,
|
||||
To: &common.Address{},
|
||||
Data: []byte{},
|
||||
Gas: 21000,
|
||||
AccessList: gethTypes.AccessList{},
|
||||
Value: big.NewInt(0),
|
||||
ChainID: big.NewInt(1),
|
||||
GasTipCap: big.NewInt(0),
|
||||
GasFeeCap: big.NewInt(1),
|
||||
V: big.NewInt(0),
|
||||
R: big.NewInt(0),
|
||||
S: big.NewInt(0),
|
||||
})
|
||||
tx1 := gethTypes.NewTx(&gethTypes.DynamicFeeTx{
|
||||
Nonce: 0,
|
||||
To: &common.Address{},
|
||||
Data: []byte{},
|
||||
Gas: 42000,
|
||||
AccessList: gethTypes.AccessList{},
|
||||
Value: big.NewInt(0),
|
||||
ChainID: big.NewInt(1),
|
||||
GasTipCap: big.NewInt(1),
|
||||
GasFeeCap: big.NewInt(2),
|
||||
V: big.NewInt(0),
|
||||
R: big.NewInt(0),
|
||||
S: big.NewInt(0),
|
||||
})
|
||||
senderMeta := &SenderMeta{
|
||||
Name: "testName",
|
||||
Service: "testService",
|
||||
Address: common.HexToAddress("0x1"),
|
||||
Type: types.SenderTypeCommitBatch,
|
||||
}
|
||||
|
||||
err = pendingTransactionOrm.InsertPendingTransaction(context.Background(), "test", senderMeta, tx0, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = pendingTransactionOrm.InsertPendingTransaction(context.Background(), "test", senderMeta, tx1, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = pendingTransactionOrm.UpdatePendingTransactionStatusByTxHash(context.Background(), tx0.Hash(), types.TxStatusReplaced)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err := pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), senderMeta.Type, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 2)
|
||||
assert.Equal(t, tx1.Type(), txs[1].Type)
|
||||
assert.Equal(t, tx1.Nonce(), txs[1].Nonce)
|
||||
assert.Equal(t, tx1.Gas(), txs[1].GasLimit)
|
||||
assert.Equal(t, tx1.GasTipCap().Uint64(), txs[1].GasTipCap)
|
||||
assert.Equal(t, tx1.GasFeeCap().Uint64(), txs[1].GasFeeCap)
|
||||
assert.Equal(t, tx1.ChainId().Uint64(), txs[1].ChainID)
|
||||
assert.Equal(t, senderMeta.Name, txs[1].SenderName)
|
||||
assert.Equal(t, senderMeta.Service, txs[1].SenderService)
|
||||
assert.Equal(t, senderMeta.Address.String(), txs[1].SenderAddress)
|
||||
assert.Equal(t, senderMeta.Type, txs[1].SenderType)
|
||||
|
||||
err = pendingTransactionOrm.UpdatePendingTransactionStatusByTxHash(context.Background(), tx1.Hash(), types.TxStatusConfirmed)
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), senderMeta.Type, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 1)
|
||||
|
||||
err = pendingTransactionOrm.UpdateOtherTransactionsAsFailedByNonce(context.Background(), senderMeta.Address.String(), tx1.Nonce(), tx1.Hash())
|
||||
assert.NoError(t, err)
|
||||
|
||||
txs, err = pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), senderMeta.Type, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, txs, 0)
|
||||
|
||||
status, err := pendingTransactionOrm.GetTxStatusByTxHash(context.Background(), tx0.Hash())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, types.TxStatusConfirmedFailed, status)
|
||||
}
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"scroll-tech/common/types"
|
||||
)
|
||||
|
||||
// SenderMeta holds the metadata for a transaction sender including the name, service, address and type.
|
||||
type SenderMeta struct {
|
||||
Name string
|
||||
Service string
|
||||
Address common.Address
|
||||
Type types.SenderType
|
||||
}
|
||||
|
||||
// PendingTransaction represents the structure of a transaction in the database.
|
||||
type PendingTransaction struct {
|
||||
db *gorm.DB `gorm:"column:-"`
|
||||
|
||||
ID uint `json:"id" gorm:"id;primaryKey"`
|
||||
ContextID string `json:"context_id" gorm:"context_id"`
|
||||
Hash string `json:"hash" gorm:"hash"`
|
||||
ChainID uint64 `json:"chain_id" gorm:"chain_id"`
|
||||
Type uint8 `json:"type" gorm:"type"`
|
||||
GasTipCap uint64 `json:"gas_tip_cap" gorm:"gas_tip_cap"`
|
||||
GasFeeCap uint64 `json:"gas_fee_cap" gorm:"gas_fee_cap"`
|
||||
GasLimit uint64 `json:"gas_limit" gorm:"gas_limit"`
|
||||
Nonce uint64 `json:"nonce" gorm:"nonce"`
|
||||
SubmitBlockNumber uint64 `json:"submit_block_number" gorm:"submit_block_number"`
|
||||
Status types.TxStatus `json:"status" gorm:"status"`
|
||||
RLPEncoding []byte `json:"rlp_encoding" gorm:"rlp_encoding"`
|
||||
SenderName string `json:"sender_name" gorm:"sender_name"`
|
||||
SenderService string `json:"sender_service" gorm:"sender_service"`
|
||||
SenderAddress string `json:"sender_address" gorm:"sender_address"`
|
||||
SenderType types.SenderType `json:"sender_type" gorm:"sender_type"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"column:deleted_at"`
|
||||
}
|
||||
|
||||
// TableName returns the table name for the Transaction model.
|
||||
func (*PendingTransaction) TableName() string {
|
||||
return "pending_transaction"
|
||||
}
|
||||
|
||||
// NewPendingTransaction returns a new instance of PendingTransaction.
|
||||
func NewPendingTransaction(db *gorm.DB) *PendingTransaction {
|
||||
return &PendingTransaction{db: db}
|
||||
}
|
||||
|
||||
// GetTxStatusByTxHash retrieves the status of a transaction by its hash.
|
||||
func (o *PendingTransaction) GetTxStatusByTxHash(ctx context.Context, hash common.Hash) (types.TxStatus, error) {
|
||||
var status types.TxStatus
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&PendingTransaction{})
|
||||
db = db.Select("status")
|
||||
db = db.Where("hash = ?", hash.String())
|
||||
if err := db.Scan(&status).Error; err != nil {
|
||||
return types.TxStatusUnknown, fmt.Errorf("failed to get tx status by hash, hash: %v, err: %w", hash, err)
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// GetPendingOrReplacedTransactionsBySenderType retrieves pending or replaced transactions filtered by sender type, ordered by nonce, then gas_fee_cap (gas_price in legacy tx), and limited to a specified count.
|
||||
func (o *PendingTransaction) GetPendingOrReplacedTransactionsBySenderType(ctx context.Context, senderType types.SenderType, limit int) ([]PendingTransaction, error) {
|
||||
var transactions []PendingTransaction
|
||||
db := o.db.WithContext(ctx)
|
||||
db = db.Model(&PendingTransaction{})
|
||||
db = db.Where("sender_type = ?", senderType)
|
||||
db = db.Where("status = ? OR status = ?", types.TxStatusPending, types.TxStatusReplaced)
|
||||
db = db.Order("nonce asc")
|
||||
db = db.Order("gas_fee_cap asc")
|
||||
db = db.Limit(limit)
|
||||
if err := db.Find(&transactions).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get pending or replaced transactions by sender type, error: %w", err)
|
||||
}
|
||||
return transactions, nil
|
||||
}
|
||||
|
||||
// InsertPendingTransaction creates a new pending transaction record and stores it in the database.
|
||||
func (o *PendingTransaction) InsertPendingTransaction(ctx context.Context, contextID string, senderMeta *SenderMeta, tx *gethTypes.Transaction, submitBlockNumber uint64, dbTX ...*gorm.DB) error {
|
||||
rlp := new(bytes.Buffer)
|
||||
if err := tx.EncodeRLP(rlp); err != nil {
|
||||
return fmt.Errorf("failed to encode rlp, err: %w", err)
|
||||
}
|
||||
|
||||
newTransaction := &PendingTransaction{
|
||||
ContextID: contextID,
|
||||
Hash: tx.Hash().String(),
|
||||
Type: tx.Type(),
|
||||
ChainID: tx.ChainId().Uint64(),
|
||||
GasFeeCap: tx.GasFeeCap().Uint64(),
|
||||
GasTipCap: tx.GasTipCap().Uint64(),
|
||||
GasLimit: tx.Gas(),
|
||||
Nonce: tx.Nonce(),
|
||||
SubmitBlockNumber: submitBlockNumber,
|
||||
Status: types.TxStatusPending,
|
||||
RLPEncoding: rlp.Bytes(),
|
||||
SenderName: senderMeta.Name,
|
||||
SenderAddress: senderMeta.Address.String(),
|
||||
SenderService: senderMeta.Service,
|
||||
SenderType: senderMeta.Type,
|
||||
}
|
||||
|
||||
db := o.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&PendingTransaction{})
|
||||
if err := db.Create(newTransaction).Error; err != nil {
|
||||
return fmt.Errorf("failed to InsertTransaction, error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePendingTransactionStatusByTxHash updates the status of a transaction based on the transaction hash.
|
||||
func (o *PendingTransaction) UpdatePendingTransactionStatusByTxHash(ctx context.Context, hash common.Hash, status types.TxStatus, dbTX ...*gorm.DB) error {
|
||||
db := o.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&PendingTransaction{})
|
||||
db = db.Where("hash = ?", hash.String())
|
||||
if err := db.Update("status", status).Error; err != nil {
|
||||
return fmt.Errorf("failed to UpdatePendingTransactionStatusByTxHash, txHash: %s, error: %w", hash, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateOtherTransactionsAsFailedByNonce updates the status of all transactions to TxStatusConfirmedFailed for a specific nonce and sender address, excluding a specified transaction hash.
|
||||
func (o *PendingTransaction) UpdateOtherTransactionsAsFailedByNonce(ctx context.Context, senderAddress string, nonce uint64, hash common.Hash, dbTX ...*gorm.DB) error {
|
||||
db := o.db
|
||||
if len(dbTX) > 0 && dbTX[0] != nil {
|
||||
db = dbTX[0]
|
||||
}
|
||||
db = db.WithContext(ctx)
|
||||
db = db.Model(&PendingTransaction{})
|
||||
db = db.Where("sender_address = ?", senderAddress)
|
||||
db = db.Where("nonce = ?", nonce)
|
||||
db = db.Where("hash != ?", hash.String())
|
||||
if err := db.Update("status", types.TxStatusConfirmedFailed).Error; err != nil {
|
||||
return fmt.Errorf("failed to update other transactions as failed by nonce, senderAddress: %s, nonce: %d, txHash: %s, error: %w", senderAddress, nonce, hash, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -79,16 +79,16 @@ contract MockBridgeL1 {
|
||||
* Variables *
|
||||
*************/
|
||||
|
||||
/// @notice Message nonce, used to avoid relay attack.
|
||||
uint256 public messageNonce;
|
||||
|
||||
mapping(uint256 => bytes32) public committedBatches;
|
||||
uint256 public l2BaseFee;
|
||||
|
||||
/***********************************
|
||||
* Functions from L2GasPriceOracle *
|
||||
***********************************/
|
||||
|
||||
function setL2BaseFee(uint256 _newL2BaseFee) external {
|
||||
l2BaseFee = _newL2BaseFee;
|
||||
function setL2BaseFee(uint256) external {
|
||||
}
|
||||
|
||||
/************************************
|
||||
@@ -128,10 +128,6 @@ contract MockBridgeL1 {
|
||||
* Functions from ScrollChain *
|
||||
******************************/
|
||||
|
||||
/// @notice Import layer 2 genesis block
|
||||
function importGenesisBatch(bytes calldata _batchHeader, bytes32 _stateRoot) external {
|
||||
}
|
||||
|
||||
function commitBatch(
|
||||
uint8 /*version*/,
|
||||
bytes calldata _parentBatchHeader,
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -15,7 +14,6 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -70,10 +68,6 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func setupEnv(t *testing.T) {
|
||||
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.LogfmtFormat()))
|
||||
glogger.Verbosity(log.LvlInfo)
|
||||
log.Root().SetHandler(glogger)
|
||||
|
||||
base.RunImages(t)
|
||||
|
||||
var err error
|
||||
@@ -144,10 +138,15 @@ func TestFunction(t *testing.T) {
|
||||
t.Run("TestProcessStartEnableMetrics", testProcessStartEnableMetrics)
|
||||
|
||||
// l1 rollup and watch rollup events
|
||||
t.Run("TestCommitAndFinalizeGenesisBatch", testCommitAndFinalizeGenesisBatch)
|
||||
t.Run("TestCommitBatchAndFinalizeBatch", testCommitBatchAndFinalizeBatch)
|
||||
|
||||
// l1 message
|
||||
|
||||
// l2 message
|
||||
// TODO: add a "user relay l2msg Succeed" test
|
||||
|
||||
// l1/l2 gas oracle
|
||||
t.Run("TestImportL1GasPrice", testImportL1GasPrice)
|
||||
t.Run("TestImportL2GasPrice", testImportL2GasPrice)
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func testImportL1GasPrice(t *testing.T) {
|
||||
l1Cfg := rollupApp.Config.L1Config
|
||||
|
||||
// Create L1Relayer
|
||||
l1Relayer, err := relayer.NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig, relayer.ServiceTypeL1GasOracle, nil)
|
||||
l1Relayer, err := relayer.NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create L1Watcher
|
||||
@@ -67,7 +67,7 @@ func testImportL2GasPrice(t *testing.T) {
|
||||
prepareContracts(t)
|
||||
|
||||
l2Cfg := rollupApp.Config.L2Config
|
||||
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig, false, relayer.ServiceTypeL2GasOracle, nil)
|
||||
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// add fake chunk
|
||||
|
||||
@@ -20,34 +20,6 @@ import (
|
||||
"scroll-tech/rollup/internal/orm"
|
||||
)
|
||||
|
||||
func testCommitAndFinalizeGenesisBatch(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer database.CloseDB(db)
|
||||
|
||||
prepareContracts(t)
|
||||
|
||||
l2Cfg := rollupApp.Config.L2Config
|
||||
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig, true, relayer.ServiceTypeL2RollupRelayer, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, l2Relayer)
|
||||
|
||||
genesisChunkHash := common.HexToHash("0x00e076380b00a3749816fcc9a2a576b529952ef463222a54544d21b7d434dfe1")
|
||||
chunkOrm := orm.NewChunk(db)
|
||||
dbChunk, err := chunkOrm.GetChunksInRange(context.Background(), 0, 0)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, dbChunk, 1)
|
||||
assert.Equal(t, genesisChunkHash.String(), dbChunk[0].Hash)
|
||||
assert.Equal(t, types.ProvingTaskVerified, types.ProvingStatus(dbChunk[0].ProvingStatus))
|
||||
|
||||
genesisBatchHash := common.HexToHash("0x2d214b024f5337d83a5681f88575ab225f345ec2e4e3ce53cf4dc4b0cb5c96b1")
|
||||
batchOrm := orm.NewBatch(db)
|
||||
batch, err := batchOrm.GetBatchByIndex(context.Background(), 0)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, genesisBatchHash.String(), batch.Hash)
|
||||
assert.Equal(t, types.ProvingTaskVerified, types.ProvingStatus(batch.ProvingStatus))
|
||||
assert.Equal(t, types.RollupFinalized, types.RollupStatus(batch.RollupStatus))
|
||||
}
|
||||
|
||||
func testCommitBatchAndFinalizeBatch(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer database.CloseDB(db)
|
||||
@@ -56,7 +28,7 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
|
||||
|
||||
// Create L2Relayer
|
||||
l2Cfg := rollupApp.Config.L2Config
|
||||
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig, false, relayer.ServiceTypeL2RollupRelayer, nil)
|
||||
l2Relayer, err := relayer.NewLayer2Relayer(context.Background(), l2Client, db, l2Cfg.RelayerConfig, false, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create L1Watcher
|
||||
|
||||
Reference in New Issue
Block a user