mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-12 23:48:15 -05:00
Compare commits
26 Commits
prealpha-v
...
prealpha-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c05a31524f | ||
|
|
ac342faaf0 | ||
|
|
f54575c410 | ||
|
|
b549816815 | ||
|
|
2bc951f622 | ||
|
|
1aea4a2584 | ||
|
|
11fa61c45c | ||
|
|
9cf8613bb1 | ||
|
|
55de584f80 | ||
|
|
98cd149627 | ||
|
|
303a7d02c8 | ||
|
|
e2f4477852 | ||
|
|
cc2f5b5b0a | ||
|
|
8fedeec337 | ||
|
|
4b32a90d52 | ||
|
|
f2084fff6e | ||
|
|
b71834c0e1 | ||
|
|
b794f31d38 | ||
|
|
09dcaae497 | ||
|
|
02effbc5a1 | ||
|
|
130f2cdf37 | ||
|
|
fed5cef7fc | ||
|
|
c5b56f0068 | ||
|
|
fd92584ab9 | ||
|
|
76131d0de7 | ||
|
|
921268a2b1 |
20
.github/workflows/common.yml
vendored
20
.github/workflows/common.yml
vendored
@@ -24,12 +24,32 @@ jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2022-08-23
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-roller-cargo-registry-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo index
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/git
|
||||
key: ${{ runner.os }}-roller-cargo-index-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo target
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /home/runner/work/scroll/scroll/common/libzkp/impl/target
|
||||
key: ${{ runner.os }}-roller-cargo-build-target-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Lint
|
||||
run: |
|
||||
rm -rf $HOME/.cache/golangci-lint
|
||||
|
||||
20
.github/workflows/coordinator.yml
vendored
20
.github/workflows/coordinator.yml
vendored
@@ -24,12 +24,32 @@ jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2022-08-23
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-roller-cargo-registry-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo index
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/git
|
||||
key: ${{ runner.os }}-roller-cargo-index-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo target
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /home/runner/work/scroll/scroll/common/libzkp/impl/target
|
||||
key: ${{ runner.os }}-roller-cargo-build-target-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Lint
|
||||
run: |
|
||||
rm -rf $HOME/.cache/golangci-lint
|
||||
|
||||
8
.github/workflows/roller.yml
vendored
8
.github/workflows/roller.yml
vendored
@@ -39,17 +39,17 @@ jobs:
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-roller-cargo-registry-${{ hashFiles('roller/core/prover/rust/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-roller-cargo-registry-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo index
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cargo/git
|
||||
key: ${{ runner.os }}-roller-cargo-index-${{ hashFiles('roller/core/prover/rust/Cargo.lock') }}
|
||||
key: ${{ runner.os }}-roller-cargo-index-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Cache cargo target
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /home/runner/work/scroll/scroll/roller/core/prover/rust/target
|
||||
key: ${{ runner.os }}-roller-cargo-build-target-${{ hashFiles('roller/core/prover/rust/Cargo.lock') }}
|
||||
path: /home/runner/work/scroll/scroll/common/libzkp/impl/target
|
||||
key: ${{ runner.os }}-roller-cargo-build-target-${{ hashFiles('common/libzkp/impl/Cargo.lock') }}
|
||||
- name: Test
|
||||
run: |
|
||||
make roller
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,3 +3,6 @@ assets/params*
|
||||
assets/seed
|
||||
coverage.txt
|
||||
build/bin
|
||||
|
||||
# misc
|
||||
sftp-config.json
|
||||
|
||||
8
Jenkinsfile
vendored
8
Jenkinsfile
vendored
@@ -1,8 +1,6 @@
|
||||
imagePrefix = 'scrolltech'
|
||||
credentialDocker = 'dockerhub'
|
||||
|
||||
def boolean test_result = false
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
options {
|
||||
@@ -13,6 +11,7 @@ pipeline {
|
||||
}
|
||||
environment {
|
||||
GO111MODULE = 'on'
|
||||
PATH="/home/ubuntu/.cargo/bin:$PATH"
|
||||
// LOG_DOCKER = 'true'
|
||||
}
|
||||
stages {
|
||||
@@ -29,8 +28,9 @@ pipeline {
|
||||
}
|
||||
}
|
||||
steps {
|
||||
//start to build project
|
||||
// start to build project
|
||||
sh '''#!/bin/bash
|
||||
set -e
|
||||
export PATH=/home/ubuntu/go/bin:$PATH
|
||||
make dev_docker
|
||||
make -C bridge mock_abi
|
||||
@@ -73,8 +73,6 @@ pipeline {
|
||||
sh "cd $i && go test -v -race -coverprofile=coverage.txt -covermode=atomic \$(go list ./... | grep -v 'database\\|l2\\|l1\\|common\\|coordinator')"
|
||||
}
|
||||
}
|
||||
|
||||
script { test_result = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,7 @@ IMAGE_VERSION=latest
|
||||
REPO_ROOT_DIR=./..
|
||||
|
||||
mock_abi:
|
||||
solc --bin mock_bridge/Mock_Bridge.sol -o mock_bridge/ --overwrite
|
||||
solc --abi mock_bridge/Mock_Bridge.sol -o mock_bridge/ --overwrite
|
||||
abigen --bin=mock_bridge/Mock_Bridge.bin \
|
||||
--abi=mock_bridge/Mock_Bridge.abi \
|
||||
--pkg=mock_bridge --out=mock_bridge/Mock_Bridge.go
|
||||
awk '{sub("github.com/ethereum","github.com/scroll-tech")}1' mock_bridge/Mock_Bridge.go > temp && mv temp mock_bridge/Mock_Bridge.go
|
||||
go run github.com/scroll-tech/go-ethereum/cmd/abigen --sol mock_bridge/Mock_Bridge.sol --pkg mock_bridge --out mock_bridge/Mock_Bridge.go
|
||||
|
||||
bridge: ## Builds the Bridge instance.
|
||||
go build -o $(PWD)/build/bin/bridge ./cmd
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Bridge
|
||||
|
||||
[](https://scroll-tech/bridge/actions)
|
||||
[](https://codecov.io/gh/scroll-tech/bridge)
|
||||
|
||||
This repo contains the Scroll bridge.
|
||||
|
||||
In addition, launching the bridge will launch a separate instance of l2geth, and sets up a communication channel
|
||||
@@ -25,38 +22,17 @@ make clean
|
||||
make bridge
|
||||
```
|
||||
|
||||
## db operation
|
||||
## DB config
|
||||
|
||||
* init, show version, rollback, check status db
|
||||
* db settings in config
|
||||
|
||||
```bash
|
||||
# DB_DSN: db data source name
|
||||
export DB_DSN="postgres://admin:123456@localhost/test_db?sslmode=disable"
|
||||
# DB_DRIVER: db driver name
|
||||
export DB_DRIVER="postgres"
|
||||
|
||||
# TEST_DB_DRIVER, TEST_DB_DSN: It is required when executing db test cases
|
||||
export TEST_DB_DRIVER="postgres"
|
||||
export TEST_DB_DSN="postgres://admin:123456@localhost/test_db?sslmode=disable"
|
||||
|
||||
# init db
|
||||
./build/bin/bridge reset [--config ./config.json]
|
||||
|
||||
# show db version
|
||||
./build/bin/bridge version [--config ./config.json]
|
||||
|
||||
# rollback db
|
||||
/build/bin/bridge rollback [--version version] [--config ./config.json]
|
||||
|
||||
# show db status
|
||||
./build/bin/bridge status [--config ./config.json]
|
||||
|
||||
# migrate db
|
||||
./build/bin/bridge migrate [--config ./config.json]
|
||||
```
|
||||
|
||||
## Start
|
||||
|
||||
* use default ports and config.json
|
||||
|
||||
```bash
|
||||
|
||||
@@ -8,6 +8,23 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
)
|
||||
|
||||
const (
|
||||
// SENT_MESSAGE_EVENT_SIGNATURE = keccak256("SentMessage(address,address,uint256,uint256,uint256,bytes,uint256,uint256)")
|
||||
SENT_MESSAGE_EVENT_SIGNATURE = "806b28931bc6fbe6c146babfb83d5c2b47e971edb43b4566f010577a0ee7d9f4"
|
||||
|
||||
// RELAYED_MESSAGE_EVENT_SIGNATURE = keccak256("RelayedMessage(bytes32)")
|
||||
RELAYED_MESSAGE_EVENT_SIGNATURE = "4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c"
|
||||
|
||||
// FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE = keccak256("FailedRelayedMessage(bytes32)")
|
||||
FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE = "99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f"
|
||||
|
||||
// COMMIT_BATCH_EVENT_SIGNATURE = keccak256("CommitBatch(bytes32,bytes32,uint256,bytes32)")
|
||||
COMMIT_BATCH_EVENT_SIGNATURE = "a26d4bd91c4c2eff3b1bf542129607d782506fc1950acfab1472a20d28c06596"
|
||||
|
||||
// FINALIZED_BATCH_EVENT_SIGNATURE = keccak256("FinalizeBatch(bytes32,bytes32,uint256,bytes32)")
|
||||
FINALIZED_BATCH_EVENT_SIGNATURE = "e20f311a96205960de4d2bb351f7729e5136fa36ae64d7f736c67ddc4ca4cd4b"
|
||||
)
|
||||
|
||||
var (
|
||||
// RollupMetaABI holds information about a contract's context and available invokable methods.
|
||||
RollupMetaABI *abi.ABI
|
||||
|
||||
@@ -28,14 +28,8 @@ var (
|
||||
}
|
||||
|
||||
l1Flags = []cli.Flag{
|
||||
&l1ChainIDFlag,
|
||||
&l1UrlFlag,
|
||||
}
|
||||
l1ChainIDFlag = cli.IntFlag{
|
||||
Name: "l1.chainID",
|
||||
Usage: "l1 chain id",
|
||||
Value: 4,
|
||||
}
|
||||
l1UrlFlag = cli.StringFlag{
|
||||
Name: "l1.endpoint",
|
||||
Usage: "The endpoint connect to l1chain node",
|
||||
@@ -43,14 +37,8 @@ var (
|
||||
}
|
||||
|
||||
l2Flags = []cli.Flag{
|
||||
&l2ChainIDFlag,
|
||||
&l2UrlFlag,
|
||||
}
|
||||
l2ChainIDFlag = cli.IntFlag{
|
||||
Name: "l2.chainID",
|
||||
Usage: "l2 chain id",
|
||||
Value: 53077,
|
||||
}
|
||||
l2UrlFlag = cli.StringFlag{
|
||||
Name: "l2.endpoint",
|
||||
Usage: "The endpoint connect to l2chain node",
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"os/signal"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"scroll-tech/database"
|
||||
@@ -33,12 +32,7 @@ func main() {
|
||||
app.Flags = append(app.Flags, l2Flags...)
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
return utils.Setup(&utils.LogConfig{
|
||||
LogFile: ctx.String(utils.LogFileFlag.Name),
|
||||
LogJSONFormat: ctx.Bool(utils.LogJSONFormat.Name),
|
||||
LogDebug: ctx.Bool(utils.LogDebugFlag.Name),
|
||||
Verbosity: ctx.Int(utils.VerbosityFlag.Name),
|
||||
})
|
||||
return utils.LogSetup(ctx)
|
||||
}
|
||||
// Run the sequencer.
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
@@ -48,15 +42,9 @@ func main() {
|
||||
}
|
||||
|
||||
func applyConfig(ctx *cli.Context, cfg *config.Config) {
|
||||
if ctx.IsSet(l1ChainIDFlag.Name) {
|
||||
cfg.L1Config.ChainID = ctx.Int64(l1ChainIDFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(l1UrlFlag.Name) {
|
||||
cfg.L1Config.Endpoint = ctx.String(l1UrlFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(l2ChainIDFlag.Name) {
|
||||
cfg.L2Config.ChainID = ctx.Int64(l2ChainIDFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(l2UrlFlag.Name) {
|
||||
cfg.L2Config.Endpoint = ctx.String(l2UrlFlag.Name)
|
||||
}
|
||||
@@ -107,24 +95,17 @@ func action(ctx *cli.Context) error {
|
||||
log.Crit("couldn't start l2 backend", "error", err)
|
||||
}
|
||||
|
||||
apis := l2Backend.APIs()
|
||||
// Register api and start rpc service.
|
||||
if ctx.Bool(httpEnabledFlag.Name) {
|
||||
srv := rpc.NewServer()
|
||||
apis := l2Backend.APIs()
|
||||
for _, api := range apis {
|
||||
if err = srv.RegisterName(api.Namespace, api.Service); err != nil {
|
||||
log.Crit("register namespace failed", "namespace", api.Namespace, "error", err)
|
||||
}
|
||||
}
|
||||
handler, addr, err := utils.StartHTTPEndpoint(
|
||||
fmt.Sprintf(
|
||||
"%s:%d",
|
||||
ctx.String(httpListenAddrFlag.Name),
|
||||
ctx.Int(httpPortFlag.Name)),
|
||||
rpc.DefaultHTTPTimeouts,
|
||||
srv)
|
||||
apis)
|
||||
if err != nil {
|
||||
log.Crit("Could not start RPC api", "error", err)
|
||||
log.Crit("Could not start HTTP api", "error", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = handler.Shutdown(ctx.Context)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"l1_config": {
|
||||
"confirmations": 6,
|
||||
"chain_id": 4,
|
||||
"endpoint": "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
|
||||
"l1_messenger_address": "0x0000000000000000000000000000000000000000",
|
||||
"start_height": 0,
|
||||
@@ -25,7 +24,6 @@
|
||||
},
|
||||
"l2_config": {
|
||||
"confirmations": 1,
|
||||
"chain_id": 53077,
|
||||
"proof_generation_freq": 1,
|
||||
"skipped_opcodes": [
|
||||
"CREATE2",
|
||||
|
||||
@@ -42,8 +42,6 @@ type SenderConfig struct {
|
||||
type L1Config struct {
|
||||
// Confirmations block height confirmations number.
|
||||
Confirmations uint64 `json:"confirmations"`
|
||||
// l1 chainID.
|
||||
ChainID int64 `json:"chain_id"`
|
||||
// l1 eth node url.
|
||||
Endpoint string `json:"endpoint"`
|
||||
// The start height to sync event from layer 1
|
||||
@@ -58,8 +56,6 @@ type L1Config struct {
|
||||
type L2Config struct {
|
||||
// Confirmations block height confirmations number.
|
||||
Confirmations uint64 `json:"confirmations"`
|
||||
// l2geth chainId.
|
||||
ChainID int64 `json:"chain_id"`
|
||||
// l2geth node url.
|
||||
Endpoint string `json:"endpoint"`
|
||||
// The messenger contract address deployed on layer 2 chain.
|
||||
|
||||
@@ -3,38 +3,42 @@ module scroll-tech/bridge
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/iden3/go-iden3-crypto v0.0.13
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
|
||||
github.com/urfave/cli/v2 v2.10.2
|
||||
golang.org/x/sync v0.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.20.1-beta // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.13 // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.23 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/holiman/uint256 v1.2.0 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rjeczalik/notify v0.9.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/scroll-tech/zktrie v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -71,10 +71,10 @@ github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOC
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
|
||||
github.com/cespare/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=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -82,8 +82,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
@@ -92,8 +93,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
@@ -108,8 +110,9 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM=
|
||||
github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
@@ -186,8 +189,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
|
||||
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||
@@ -200,12 +204,13 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU
|
||||
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
|
||||
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI=
|
||||
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
|
||||
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 h1:dXZF+R9iI07DK49LHX/EKC3jTa0O2z+TUyvxjGK7V38=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 h1:ixWRiaqDULNyIDdOWz2QQJG5t4PpNHkQk2P6GV94cok=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
|
||||
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
|
||||
@@ -218,8 +223,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
|
||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
|
||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
@@ -244,8 +249,9 @@ github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH6
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -310,6 +316,7 @@ github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHu
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -333,10 +340,14 @@ github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1
|
||||
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6 h1:o0Gq2d8nus6x82apluA5RJwjlOca7LIlpAfxlyvQvxs=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6/go.mod h1:jurIpDQ0hqtp9//xxeWzr8X9KMP/+TYn+vz3K1wZrv0=
|
||||
github.com/scroll-tech/zktrie v0.3.0 h1:c0GRNELUyAtyuiwllQKT1XjNbs7NRGfguKouiyLfFNY=
|
||||
@@ -347,7 +358,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -381,13 +391,16 @@ github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y=
|
||||
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@@ -409,8 +422,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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=
|
||||
@@ -478,8 +491,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -524,8 +538,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -536,8 +550,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
||||
@@ -4,11 +4,9 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/database/orm"
|
||||
"scroll-tech/database"
|
||||
|
||||
bridge_abi "scroll-tech/bridge/abi"
|
||||
"scroll-tech/bridge/config"
|
||||
)
|
||||
|
||||
@@ -18,28 +16,22 @@ type Backend struct {
|
||||
cfg *config.L1Config
|
||||
watcher *Watcher
|
||||
relayer *Layer1Relayer
|
||||
orm orm.L1MessageOrm
|
||||
orm database.OrmFactory
|
||||
}
|
||||
|
||||
// New returns a new instance of Backend.
|
||||
func New(ctx context.Context, cfg *config.L1Config, orm orm.L1MessageOrm) (*Backend, error) {
|
||||
func New(ctx context.Context, cfg *config.L1Config, orm database.OrmFactory) (*Backend, error) {
|
||||
client, err := ethclient.Dial(cfg.Endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l1MessengerABI, err := bridge_abi.L1MessengerMetaData.GetAbi()
|
||||
if err != nil {
|
||||
log.Warn("new L1MessengerABI failed", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
relayer, err := NewLayer1Relayer(ctx, client, int64(cfg.Confirmations), orm, cfg.RelayerConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
watcher := NewWatcher(ctx, client, cfg.StartHeight, cfg.Confirmations, cfg.L1MessengerAddress, l1MessengerABI, orm)
|
||||
watcher := NewWatcher(ctx, client, cfg.StartHeight, cfg.Confirmations, cfg.L1MessengerAddress, cfg.RelayerConfig.RollupContractAddress, orm)
|
||||
|
||||
return &Backend{
|
||||
cfg: cfg,
|
||||
|
||||
@@ -70,7 +70,7 @@ func NewLayer1Relayer(ctx context.Context, ethClient *ethclient.Client, l1Confir
|
||||
// ProcessSavedEvents relays saved un-processed cross-domain transactions to desired blockchain
|
||||
func (r *Layer1Relayer) ProcessSavedEvents() {
|
||||
// msgs are sorted by nonce in increasing order
|
||||
msgs, err := r.db.GetL1UnprocessedMessages()
|
||||
msgs, err := r.db.GetL1MessagesByStatus(orm.MsgPending)
|
||||
if err != nil {
|
||||
log.Error("Failed to fetch unprocessed L1 messages", "err", err)
|
||||
return
|
||||
@@ -106,15 +106,15 @@ func (r *Layer1Relayer) processSavedEvent(msg *orm.L1Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := r.sender.SendTransaction(msg.Layer1Hash, &r.cfg.MessengerContractAddress, big.NewInt(0), data)
|
||||
hash, err := r.sender.SendTransaction(msg.MsgHash, &r.cfg.MessengerContractAddress, big.NewInt(0), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("relayMessage to layer2", "layer1 hash", msg.Layer1Hash, "tx hash", hash)
|
||||
log.Info("relayMessage to layer2", "msg hash", msg.MsgHash, "tx hash", hash)
|
||||
|
||||
err = r.db.UpdateLayer1StatusAndLayer2Hash(r.ctx, msg.Layer1Hash, hash.String(), orm.MsgSubmitted)
|
||||
err = r.db.UpdateLayer1StatusAndLayer2Hash(r.ctx, msg.MsgHash, orm.MsgSubmitted, hash.String())
|
||||
if err != nil {
|
||||
log.Error("UpdateLayer1StatusAndLayer2Hash failed", "msg.layer1hash", msg.Layer1Hash, "msg.height", msg.Height, "err", err)
|
||||
log.Error("UpdateLayer1StatusAndLayer2Hash failed", "msg.msgHash", msg.MsgHash, "msg.height", msg.Height, "err", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -132,12 +132,17 @@ func (r *Layer1Relayer) Start() {
|
||||
// number, err := r.client.BlockNumber(r.ctx)
|
||||
// log.Info("receive header", "height", number)
|
||||
r.ProcessSavedEvents()
|
||||
case cfm := <-r.confirmationCh: // @todo handle db error
|
||||
err := r.db.UpdateLayer1StatusAndLayer2Hash(r.ctx, cfm.ID, cfm.TxHash.String(), orm.MsgConfirmed)
|
||||
if err != nil {
|
||||
log.Warn("UpdateLayer1StatusAndLayer2Hash failed", "err", err)
|
||||
case cfm := <-r.confirmationCh:
|
||||
if !cfm.IsSuccessful {
|
||||
log.Warn("transaction confirmed but failed in layer2", "confirmation", cfm)
|
||||
} else {
|
||||
// @todo handle db error
|
||||
err := r.db.UpdateLayer1StatusAndLayer2Hash(r.ctx, cfm.ID, orm.MsgConfirmed, cfm.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateLayer1StatusAndLayer2Hash failed", "err", err)
|
||||
}
|
||||
log.Info("transaction confirmed in layer2", "confirmation", cfm)
|
||||
}
|
||||
log.Info("transaction confirmed in layer2", "confirmation", cfm)
|
||||
case <-r.stopCh:
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,26 +12,39 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/ethclient"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/database"
|
||||
"scroll-tech/database/orm"
|
||||
|
||||
bridge_abi "scroll-tech/bridge/abi"
|
||||
"scroll-tech/bridge/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
type relayedMessage struct {
|
||||
msgHash common.Hash
|
||||
txHash common.Hash
|
||||
isSuccessful bool
|
||||
}
|
||||
|
||||
// keccak256("SentMessage(address,address,uint256,uint256,uint256,bytes,uint256,uint256)")
|
||||
sentMessageEventSignature = "806b28931bc6fbe6c146babfb83d5c2b47e971edb43b4566f010577a0ee7d9f4"
|
||||
)
|
||||
type rollupEvent struct {
|
||||
batchID common.Hash
|
||||
txHash common.Hash
|
||||
status orm.RollupStatus
|
||||
}
|
||||
|
||||
// Watcher will listen for smart contract events from Eth L1.
|
||||
type Watcher struct {
|
||||
ctx context.Context
|
||||
client *ethclient.Client
|
||||
db orm.L1MessageOrm
|
||||
db database.OrmFactory
|
||||
|
||||
// The number of new blocks to wait for a block to be confirmed
|
||||
confirmations uint64
|
||||
messengerAddress common.Address
|
||||
messengerABI *abi.ABI
|
||||
|
||||
rollupAddress common.Address
|
||||
rollupABI *abi.ABI
|
||||
|
||||
// The height of the block that the watcher has retrieved event logs
|
||||
processedMsgHeight uint64
|
||||
|
||||
@@ -40,7 +53,7 @@ type Watcher struct {
|
||||
|
||||
// NewWatcher returns a new instance of Watcher. The instance will be not fully prepared,
|
||||
// and still needs to be finalized and ran by calling `watcher.Start`.
|
||||
func NewWatcher(ctx context.Context, client *ethclient.Client, startHeight uint64, confirmations uint64, messengerAddress common.Address, messengerABI *abi.ABI, db orm.L1MessageOrm) *Watcher {
|
||||
func NewWatcher(ctx context.Context, client *ethclient.Client, startHeight uint64, confirmations uint64, messengerAddress common.Address, rollupAddress common.Address, db database.OrmFactory) *Watcher {
|
||||
savedHeight, err := db.GetLayer1LatestWatchedHeight()
|
||||
if err != nil {
|
||||
log.Warn("Failed to fetch height from db", "err", err)
|
||||
@@ -58,14 +71,16 @@ func NewWatcher(ctx context.Context, client *ethclient.Client, startHeight uint6
|
||||
db: db,
|
||||
confirmations: confirmations,
|
||||
messengerAddress: messengerAddress,
|
||||
messengerABI: messengerABI,
|
||||
messengerABI: bridge_abi.L1MessengerMetaABI,
|
||||
rollupAddress: rollupAddress,
|
||||
rollupABI: bridge_abi.RollupMetaABI,
|
||||
processedMsgHeight: uint64(savedHeight),
|
||||
stop: stop,
|
||||
}
|
||||
}
|
||||
|
||||
// Start the Watcher module.
|
||||
func (r *Watcher) Start() {
|
||||
func (w *Watcher) Start() {
|
||||
go func() {
|
||||
// trigger by timer
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
@@ -74,14 +89,14 @@ func (r *Watcher) Start() {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
blockNumber, err := r.client.BlockNumber(r.ctx)
|
||||
blockNumber, err := w.client.BlockNumber(w.ctx)
|
||||
if err != nil {
|
||||
log.Error("Failed to get block number", "err", err)
|
||||
}
|
||||
if err := r.fetchContractEvent(blockNumber); err != nil {
|
||||
if err := w.fetchContractEvent(blockNumber); err != nil {
|
||||
log.Error("Failed to fetch bridge contract", "err", err)
|
||||
}
|
||||
case <-r.stop:
|
||||
case <-w.stop:
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -89,16 +104,16 @@ func (r *Watcher) Start() {
|
||||
}
|
||||
|
||||
// Stop the Watcher module, for a graceful shutdown.
|
||||
func (r *Watcher) Stop() {
|
||||
r.stop <- true
|
||||
func (w *Watcher) Stop() {
|
||||
w.stop <- true
|
||||
}
|
||||
|
||||
const contractEventsBlocksFetchLimit = int64(10)
|
||||
|
||||
// FetchContractEvent pull latest event logs from given contract address and save in DB
|
||||
func (r *Watcher) fetchContractEvent(blockHeight uint64) error {
|
||||
fromBlock := int64(r.processedMsgHeight) + 1
|
||||
toBlock := int64(blockHeight) - int64(r.confirmations)
|
||||
func (w *Watcher) fetchContractEvent(blockHeight uint64) error {
|
||||
fromBlock := int64(w.processedMsgHeight) + 1
|
||||
toBlock := int64(blockHeight) - int64(w.confirmations)
|
||||
|
||||
if toBlock < fromBlock {
|
||||
return nil
|
||||
@@ -113,74 +128,197 @@ func (r *Watcher) fetchContractEvent(blockHeight uint64) error {
|
||||
FromBlock: big.NewInt(fromBlock), // inclusive
|
||||
ToBlock: big.NewInt(toBlock), // inclusive
|
||||
Addresses: []common.Address{
|
||||
r.messengerAddress,
|
||||
w.messengerAddress,
|
||||
w.rollupAddress,
|
||||
},
|
||||
Topics: make([][]common.Hash, 1),
|
||||
}
|
||||
query.Topics[0] = make([]common.Hash, 1)
|
||||
query.Topics[0][0] = common.HexToHash(sentMessageEventSignature)
|
||||
query.Topics[0] = make([]common.Hash, 5)
|
||||
query.Topics[0][0] = common.HexToHash(bridge_abi.SENT_MESSAGE_EVENT_SIGNATURE)
|
||||
query.Topics[0][1] = common.HexToHash(bridge_abi.RELAYED_MESSAGE_EVENT_SIGNATURE)
|
||||
query.Topics[0][2] = common.HexToHash(bridge_abi.FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE)
|
||||
query.Topics[0][3] = common.HexToHash(bridge_abi.COMMIT_BATCH_EVENT_SIGNATURE)
|
||||
query.Topics[0][4] = common.HexToHash(bridge_abi.FINALIZED_BATCH_EVENT_SIGNATURE)
|
||||
|
||||
logs, err := r.client.FilterLogs(r.ctx, query)
|
||||
logs, err := w.client.FilterLogs(w.ctx, query)
|
||||
if err != nil {
|
||||
log.Warn("Failed to get event logs", "err", err)
|
||||
return err
|
||||
}
|
||||
if len(logs) == 0 {
|
||||
w.processedMsgHeight = uint64(toBlock)
|
||||
return nil
|
||||
}
|
||||
log.Info("Received new L1 messages", "fromBlock", fromBlock, "toBlock", toBlock,
|
||||
"cnt", len(logs))
|
||||
|
||||
eventLogs, err := parseBridgeEventLogs(logs, r.messengerABI)
|
||||
sentMessageEvents, relayedMessageEvents, rollupEvents, err := w.parseBridgeEventLogs(logs)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse emitted events log", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.db.SaveL1Messages(r.ctx, eventLogs)
|
||||
// use rollup event to update rollup results db status
|
||||
var batchIDs []string
|
||||
for _, event := range rollupEvents {
|
||||
batchIDs = append(batchIDs, event.batchID.String())
|
||||
}
|
||||
statuses, err := w.db.GetRollupStatusByIDList(batchIDs)
|
||||
if err != nil {
|
||||
log.Error("Failed to GetRollupStatusByIDList", "err", err)
|
||||
return err
|
||||
}
|
||||
if len(statuses) != len(batchIDs) {
|
||||
log.Error("RollupStatus.Length mismatch with BatchIDs.Length")
|
||||
return nil
|
||||
}
|
||||
|
||||
for index, event := range rollupEvents {
|
||||
batchID := event.batchID.String()
|
||||
status := statuses[index]
|
||||
if event.status != status {
|
||||
if event.status == orm.RollupFinalized {
|
||||
err = w.db.UpdateFinalizeTxHashAndRollupStatus(w.ctx, batchID, event.txHash.String(), event.status)
|
||||
} else if event.status == orm.RollupCommitted {
|
||||
err = w.db.UpdateCommitTxHashAndRollupStatus(w.ctx, batchID, event.txHash.String(), event.status)
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("Failed to update Rollup/Finalize TxHash and Status", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update relayed message first to make sure we don't forget to update submitted message.
|
||||
// Since, we always start sync from the latest unprocessed message.
|
||||
for _, msg := range relayedMessageEvents {
|
||||
if msg.isSuccessful {
|
||||
// succeed
|
||||
err = w.db.UpdateLayer1StatusAndLayer2Hash(w.ctx, msg.msgHash.String(), orm.MsgConfirmed, msg.txHash.String())
|
||||
} else {
|
||||
// failed
|
||||
err = w.db.UpdateLayer1StatusAndLayer2Hash(w.ctx, msg.msgHash.String(), orm.MsgFailed, msg.txHash.String())
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("Failed to update layer1 status and layer2 hash", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = w.db.SaveL1Messages(w.ctx, sentMessageEvents)
|
||||
if err == nil {
|
||||
r.processedMsgHeight = uint64(toBlock)
|
||||
w.processedMsgHeight = uint64(toBlock)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func parseBridgeEventLogs(logs []types.Log, messengerABI *abi.ABI) ([]*orm.L1Message, error) {
|
||||
func (w *Watcher) parseBridgeEventLogs(logs []types.Log) ([]*orm.L1Message, []relayedMessage, []rollupEvent, error) {
|
||||
// Need use contract abi to parse event Log
|
||||
// Can only be tested after we have our contracts set up
|
||||
|
||||
var parsedlogs []*orm.L1Message
|
||||
var l1Messages []*orm.L1Message
|
||||
var relayedMessages []relayedMessage
|
||||
var rollupEvents []rollupEvent
|
||||
for _, vLog := range logs {
|
||||
event := struct {
|
||||
Target common.Address
|
||||
Sender common.Address
|
||||
Value *big.Int // uint256
|
||||
Fee *big.Int // uint256
|
||||
Deadline *big.Int // uint256
|
||||
Message []byte
|
||||
MessageNonce *big.Int // uint256
|
||||
GasLimit *big.Int // uint256
|
||||
}{}
|
||||
switch vLog.Topics[0] {
|
||||
case common.HexToHash(bridge_abi.SENT_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
Target common.Address
|
||||
Sender common.Address
|
||||
Value *big.Int // uint256
|
||||
Fee *big.Int // uint256
|
||||
Deadline *big.Int // uint256
|
||||
Message []byte
|
||||
MessageNonce *big.Int // uint256
|
||||
GasLimit *big.Int // uint256
|
||||
}{}
|
||||
|
||||
err := messengerABI.UnpackIntoInterface(&event, "SentMessage", vLog.Data)
|
||||
if err != nil {
|
||||
log.Warn("Failed to unpack layer1 SentMessage event", "err", err)
|
||||
return parsedlogs, err
|
||||
err := w.messengerABI.UnpackIntoInterface(&event, "SentMessage", vLog.Data)
|
||||
if err != nil {
|
||||
log.Warn("Failed to unpack layer1 SentMessage event", "err", err)
|
||||
return l1Messages, relayedMessages, rollupEvents, err
|
||||
}
|
||||
// target is in topics[1]
|
||||
event.Target = common.HexToAddress(vLog.Topics[1].String())
|
||||
l1Messages = append(l1Messages, &orm.L1Message{
|
||||
Nonce: event.MessageNonce.Uint64(),
|
||||
MsgHash: utils.ComputeMessageHash(event.Target, event.Sender, event.Value, event.Fee, event.Deadline, event.Message, event.MessageNonce).String(),
|
||||
Height: vLog.BlockNumber,
|
||||
Sender: event.Sender.String(),
|
||||
Value: event.Value.String(),
|
||||
Fee: event.Fee.String(),
|
||||
GasLimit: event.GasLimit.Uint64(),
|
||||
Deadline: event.Deadline.Uint64(),
|
||||
Target: event.Target.String(),
|
||||
Calldata: common.Bytes2Hex(event.Message),
|
||||
Layer1Hash: vLog.TxHash.Hex(),
|
||||
})
|
||||
case common.HexToHash(bridge_abi.RELAYED_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
MsgHash common.Hash
|
||||
}{}
|
||||
// MsgHash is in topics[1]
|
||||
event.MsgHash = common.HexToHash(vLog.Topics[1].String())
|
||||
relayedMessages = append(relayedMessages, relayedMessage{
|
||||
msgHash: event.MsgHash,
|
||||
txHash: vLog.TxHash,
|
||||
isSuccessful: true,
|
||||
})
|
||||
case common.HexToHash(bridge_abi.FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
MsgHash common.Hash
|
||||
}{}
|
||||
// MsgHash is in topics[1]
|
||||
event.MsgHash = common.HexToHash(vLog.Topics[1].String())
|
||||
relayedMessages = append(relayedMessages, relayedMessage{
|
||||
msgHash: event.MsgHash,
|
||||
txHash: vLog.TxHash,
|
||||
isSuccessful: false,
|
||||
})
|
||||
case common.HexToHash(bridge_abi.COMMIT_BATCH_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
BatchID common.Hash
|
||||
BatchHash common.Hash
|
||||
BatchIndex *big.Int
|
||||
ParentHash common.Hash
|
||||
}{}
|
||||
// BatchID is in topics[1]
|
||||
event.BatchID = common.HexToHash(vLog.Topics[1].String())
|
||||
err := w.rollupABI.UnpackIntoInterface(&event, "CommitBatch", vLog.Data)
|
||||
if err != nil {
|
||||
log.Warn("Failed to unpack layer1 CommitBatch event", "err", err)
|
||||
return l1Messages, relayedMessages, rollupEvents, err
|
||||
}
|
||||
|
||||
rollupEvents = append(rollupEvents, rollupEvent{
|
||||
batchID: event.BatchID,
|
||||
txHash: vLog.TxHash,
|
||||
status: orm.RollupCommitted,
|
||||
})
|
||||
case common.HexToHash(bridge_abi.FINALIZED_BATCH_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
BatchID common.Hash
|
||||
BatchHash common.Hash
|
||||
BatchIndex *big.Int
|
||||
ParentHash common.Hash
|
||||
}{}
|
||||
// BatchID is in topics[1]
|
||||
event.BatchID = common.HexToHash(vLog.Topics[1].String())
|
||||
err := w.rollupABI.UnpackIntoInterface(&event, "FinalizeBatch", vLog.Data)
|
||||
if err != nil {
|
||||
log.Warn("Failed to unpack layer1 FinalizeBatch event", "err", err)
|
||||
return l1Messages, relayedMessages, rollupEvents, err
|
||||
}
|
||||
|
||||
rollupEvents = append(rollupEvents, rollupEvent{
|
||||
batchID: event.BatchID,
|
||||
txHash: vLog.TxHash,
|
||||
status: orm.RollupFinalized,
|
||||
})
|
||||
default:
|
||||
log.Error("Unknown event", "topic", vLog.Topics[0], "txHash", vLog.TxHash)
|
||||
}
|
||||
// target is in topics[1]
|
||||
event.Target = common.HexToAddress(vLog.Topics[1].String())
|
||||
parsedlogs = append(parsedlogs, &orm.L1Message{
|
||||
Nonce: event.MessageNonce.Uint64(),
|
||||
Height: vLog.BlockNumber,
|
||||
Sender: event.Sender.String(),
|
||||
Value: event.Value.String(),
|
||||
Fee: event.Fee.String(),
|
||||
GasLimit: event.GasLimit.Uint64(),
|
||||
Deadline: event.Deadline.Uint64(),
|
||||
Target: event.Target.String(),
|
||||
Calldata: common.Bytes2Hex(event.Message),
|
||||
Layer1Hash: vLog.TxHash.Hex(),
|
||||
})
|
||||
}
|
||||
|
||||
return parsedlogs, nil
|
||||
return l1Messages, relayedMessages, rollupEvents, nil
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (w *WatcherClient) tryProposeBatch() error {
|
||||
}
|
||||
|
||||
if blocks[0].GasUsed > batchGasThreshold {
|
||||
log.Warn("gas overflow even for only 1 block", "gas", blocks[0].GasUsed)
|
||||
log.Warn("gas overflow even for only 1 block", "height", blocks[0].Number, "gas", blocks[0].GasUsed)
|
||||
return w.createBatchForBlocks(blocks[:1])
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
bridge_abi "scroll-tech/bridge/abi"
|
||||
"scroll-tech/bridge/config"
|
||||
"scroll-tech/bridge/sender"
|
||||
"scroll-tech/bridge/utils"
|
||||
)
|
||||
|
||||
// Layer2Relayer is responsible for
|
||||
@@ -95,7 +96,7 @@ func NewLayer2Relayer(ctx context.Context, ethClient *ethclient.Client, proofGen
|
||||
// ProcessSavedEvents relays saved un-processed cross-domain transactions to desired blockchain
|
||||
func (r *Layer2Relayer) ProcessSavedEvents() {
|
||||
// msgs are sorted by nonce in increasing order
|
||||
msgs, err := r.db.GetL2UnprocessedMessages()
|
||||
msgs, err := r.db.GetL2MessagesByStatus(orm.MsgPending)
|
||||
if err != nil {
|
||||
log.Error("Failed to fetch unprocessed L2 messages", "err", err)
|
||||
return
|
||||
@@ -150,23 +151,23 @@ func (r *Layer2Relayer) processSavedEvent(msg *orm.L2Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := r.messageSender.SendTransaction(msg.Layer2Hash, &r.cfg.MessengerContractAddress, big.NewInt(0), data)
|
||||
hash, err := r.messageSender.SendTransaction(msg.MsgHash, &r.cfg.MessengerContractAddress, big.NewInt(0), data)
|
||||
if err != nil {
|
||||
if !errors.Is(err, sender.ErrNoAvailableAccount) {
|
||||
log.Error("Failed to send relayMessageWithProof tx to layer1 ", "msg.height", msg.Height, "msg.Layer2Hash", msg.Layer2Hash, "err", err)
|
||||
log.Error("Failed to send relayMessageWithProof tx to layer1 ", "msg.height", msg.Height, "msg.MsgHash", msg.MsgHash, "err", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
log.Info("relayMessageWithProof to layer1", "layer2hash", msg.Layer2Hash, "txhash", hash.String())
|
||||
log.Info("relayMessageWithProof to layer1", "msgHash", msg.MsgHash, "txhash", hash.String())
|
||||
|
||||
// save status in db
|
||||
// @todo handle db error
|
||||
err = r.db.UpdateLayer2StatusAndLayer1Hash(r.ctx, msg.Layer2Hash, hash.String(), orm.MsgSubmitted)
|
||||
err = r.db.UpdateLayer2StatusAndLayer1Hash(r.ctx, msg.MsgHash, orm.MsgSubmitted, hash.String())
|
||||
if err != nil {
|
||||
log.Error("UpdateLayer2StatusAndLayer1Hash failed", "layer2hash", msg.Layer2Hash, "err", err)
|
||||
log.Error("UpdateLayer2StatusAndLayer1Hash failed", "msgHash", msg.MsgHash, "err", err)
|
||||
return err
|
||||
}
|
||||
r.processingMessage[msg.Layer2Hash] = msg.Layer2Hash
|
||||
r.processingMessage[msg.MsgHash] = msg.MsgHash
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -328,8 +329,8 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
|
||||
return
|
||||
}
|
||||
|
||||
proof := bufferToUint256Le(proofBuffer)
|
||||
instance := bufferToUint256Le(instanceBuffer)
|
||||
proof := utils.BufferToUint256Le(proofBuffer)
|
||||
instance := utils.BufferToUint256Le(instanceBuffer)
|
||||
data, err := r.l1RollupABI.Pack("finalizeBatchWithProof", common.HexToHash(id), proof, instance)
|
||||
if err != nil {
|
||||
log.Error("Pack finalizeBatchWithProof failed", "err", err)
|
||||
@@ -391,21 +392,26 @@ func (r *Layer2Relayer) Stop() {
|
||||
}
|
||||
|
||||
func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
|
||||
if !confirmation.IsSuccessful {
|
||||
log.Warn("transaction confirmed but failed in layer1", "confirmation", confirmation)
|
||||
return
|
||||
}
|
||||
|
||||
transactionType := "Unknown"
|
||||
// check whether it is message relay transaction
|
||||
if layer2Hash, ok := r.processingMessage[confirmation.ID]; ok {
|
||||
if msgHash, ok := r.processingMessage[confirmation.ID]; ok {
|
||||
transactionType = "MessageRelay"
|
||||
// @todo handle db error
|
||||
err := r.db.UpdateLayer2StatusAndLayer1Hash(r.ctx, layer2Hash, confirmation.TxHash.String(), orm.MsgConfirmed)
|
||||
err := r.db.UpdateLayer2StatusAndLayer1Hash(r.ctx, msgHash, orm.MsgConfirmed, confirmation.TxHash.String())
|
||||
if err != nil {
|
||||
log.Warn("UpdateLayer2StatusAndLayer1Hash failed", "layer2Hash", layer2Hash, "err", err)
|
||||
log.Warn("UpdateLayer2StatusAndLayer1Hash failed", "msgHash", msgHash, "err", err)
|
||||
}
|
||||
delete(r.processingMessage, confirmation.ID)
|
||||
}
|
||||
|
||||
// check whether it is block commitment transaction
|
||||
if batch_id, ok := r.processingCommitment[confirmation.ID]; ok {
|
||||
transactionType = "BlockCommitment"
|
||||
transactionType = "BatchCommitment"
|
||||
// @todo handle db error
|
||||
err := r.db.UpdateCommitTxHashAndRollupStatus(r.ctx, batch_id, confirmation.TxHash.String(), orm.RollupCommitted)
|
||||
if err != nil {
|
||||
@@ -432,30 +438,3 @@ func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
|
||||
}
|
||||
log.Info("transaction confirmed in layer1", "type", transactionType, "confirmation", confirmation)
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func bufferToUint256Be(buffer []byte) []*big.Int {
|
||||
buffer256 := make([]*big.Int, len(buffer)/32)
|
||||
for i := 0; i < len(buffer)/32; i++ {
|
||||
buffer256[i] = big.NewInt(0)
|
||||
for j := 0; j < 32; j++ {
|
||||
buffer256[i] = buffer256[i].Lsh(buffer256[i], 8)
|
||||
buffer256[i] = buffer256[i].Add(buffer256[i], big.NewInt(int64(buffer[i*32+j])))
|
||||
}
|
||||
}
|
||||
return buffer256
|
||||
}
|
||||
|
||||
func bufferToUint256Le(buffer []byte) []*big.Int {
|
||||
buffer256 := make([]*big.Int, len(buffer)/32)
|
||||
for i := 0; i < len(buffer)/32; i++ {
|
||||
v := big.NewInt(0)
|
||||
shft := big.NewInt(1)
|
||||
for j := 0; j < 32; j++ {
|
||||
v = new(big.Int).Add(v, new(big.Int).Mul(shft, big.NewInt(int64(buffer[i*32+j]))))
|
||||
shft = new(big.Int).Mul(shft, big.NewInt(256))
|
||||
}
|
||||
buffer256[i] = v
|
||||
}
|
||||
return buffer256
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -16,15 +17,17 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
bridge_abi "scroll-tech/bridge/abi"
|
||||
"scroll-tech/bridge/utils"
|
||||
|
||||
"scroll-tech/database"
|
||||
"scroll-tech/database/orm"
|
||||
)
|
||||
|
||||
const (
|
||||
// keccak256("SentMessage(address,address,uint256,uint256,uint256,bytes,uint256,uint256)")
|
||||
sentMessageEventSignature = "806b28931bc6fbe6c146babfb83d5c2b47e971edb43b4566f010577a0ee7d9f4"
|
||||
)
|
||||
type relayedMessage struct {
|
||||
msgHash common.Hash
|
||||
txHash common.Hash
|
||||
isSuccessful bool
|
||||
}
|
||||
|
||||
// WatcherClient provide APIs which support others to subscribe to various event from l2geth
|
||||
type WatcherClient struct {
|
||||
@@ -78,10 +81,20 @@ func NewL2WatcherClient(ctx context.Context, client *ethclient.Client, confirmat
|
||||
// Start the Listening process
|
||||
func (w *WatcherClient) Start() {
|
||||
go func() {
|
||||
if w.orm == nil {
|
||||
if reflect.ValueOf(w.orm).IsNil() {
|
||||
panic("must run L2 watcher with DB")
|
||||
}
|
||||
|
||||
lastFetchedBlock, err := w.orm.GetBlockTracesLatestHeight()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to GetBlockTracesLatestHeight in DB: %v", err))
|
||||
}
|
||||
|
||||
if lastFetchedBlock < 0 {
|
||||
lastFetchedBlock = 0
|
||||
}
|
||||
lastBlockHeightChangeTime := time.Now()
|
||||
|
||||
// trigger by timer
|
||||
// TODO: make it configurable
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
@@ -96,7 +109,25 @@ func (w *WatcherClient) Start() {
|
||||
log.Error("failed to get_BlockNumber", "err", err)
|
||||
continue
|
||||
}
|
||||
if err := w.tryFetchRunningMissingBlocks(w.ctx, number); err != nil {
|
||||
duration := time.Since(lastBlockHeightChangeTime)
|
||||
var blockToFetch uint64
|
||||
if number > uint64(lastFetchedBlock)+w.confirmations {
|
||||
// latest block height changed
|
||||
blockToFetch = number - w.confirmations
|
||||
} else if duration.Seconds() > 60 {
|
||||
// l2geth didn't produce any blocks more than 1 minute.
|
||||
blockToFetch = number
|
||||
}
|
||||
// fetch at most `blockTracesFetchLimit=10` missing blocks
|
||||
if blockToFetch > uint64(lastFetchedBlock)+blockTracesFetchLimit {
|
||||
blockToFetch = uint64(lastFetchedBlock) + blockTracesFetchLimit
|
||||
}
|
||||
if lastFetchedBlock != int64(blockToFetch) {
|
||||
lastFetchedBlock = int64(blockToFetch)
|
||||
lastBlockHeightChangeTime = time.Now()
|
||||
}
|
||||
|
||||
if err := w.tryFetchRunningMissingBlocks(w.ctx, blockToFetch); err != nil {
|
||||
log.Error("failed to fetchRunningMissingBlocks", "err", err)
|
||||
}
|
||||
|
||||
@@ -137,11 +168,6 @@ func (w *WatcherClient) tryFetchRunningMissingBlocks(ctx context.Context, backTr
|
||||
backTrackTo = uint64(heightInDB)
|
||||
}
|
||||
|
||||
// note that backTrackFrom >= backTrackTo because we are doing backtracking
|
||||
if backTrackFrom > backTrackTo+blockTracesFetchLimit {
|
||||
backTrackFrom = backTrackTo + blockTracesFetchLimit
|
||||
}
|
||||
|
||||
// start backtracking
|
||||
|
||||
var traces []*types.BlockTrace
|
||||
@@ -188,8 +214,10 @@ func (w *WatcherClient) fetchContractEvent(blockHeight uint64) error {
|
||||
},
|
||||
Topics: make([][]common.Hash, 1),
|
||||
}
|
||||
query.Topics[0] = make([]common.Hash, 1)
|
||||
query.Topics[0][0] = common.HexToHash(sentMessageEventSignature)
|
||||
query.Topics[0] = make([]common.Hash, 3)
|
||||
query.Topics[0][0] = common.HexToHash(bridge_abi.SENT_MESSAGE_EVENT_SIGNATURE)
|
||||
query.Topics[0][1] = common.HexToHash(bridge_abi.RELAYED_MESSAGE_EVENT_SIGNATURE)
|
||||
query.Topics[0][2] = common.HexToHash(bridge_abi.FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE)
|
||||
|
||||
logs, err := w.FilterLogs(w.ctx, query)
|
||||
if err != nil {
|
||||
@@ -197,61 +225,107 @@ func (w *WatcherClient) fetchContractEvent(blockHeight uint64) error {
|
||||
return err
|
||||
}
|
||||
if len(logs) == 0 {
|
||||
w.processedMsgHeight = uint64(toBlock)
|
||||
return nil
|
||||
}
|
||||
log.Info("received new L2 messages", "fromBlock", fromBlock, "toBlock", toBlock,
|
||||
"cnt", len(logs))
|
||||
|
||||
eventLogs, err := parseBridgeEventLogs(logs, w.messengerABI)
|
||||
sentMessageEvents, relayedMessageEvents, err := w.parseBridgeEventLogs(logs)
|
||||
if err != nil {
|
||||
log.Error("failed to parse emitted event log", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = w.orm.SaveL2Messages(w.ctx, eventLogs)
|
||||
// Update relayed message first to make sure we don't forget to update submited message.
|
||||
// Since, we always start sync from the latest unprocessed message.
|
||||
for _, msg := range relayedMessageEvents {
|
||||
if msg.isSuccessful {
|
||||
// succeed
|
||||
err = w.orm.UpdateLayer1StatusAndLayer2Hash(w.ctx, msg.msgHash.String(), orm.MsgConfirmed, msg.txHash.String())
|
||||
} else {
|
||||
// failed
|
||||
err = w.orm.UpdateLayer1StatusAndLayer2Hash(w.ctx, msg.msgHash.String(), orm.MsgFailed, msg.txHash.String())
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("Failed to update layer1 status and layer2 hash", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = w.orm.SaveL2Messages(w.ctx, sentMessageEvents)
|
||||
if err == nil {
|
||||
w.processedMsgHeight = uint64(toBlock)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func parseBridgeEventLogs(logs []types.Log, messengerABI *abi.ABI) ([]*orm.L2Message, error) {
|
||||
func (w *WatcherClient) parseBridgeEventLogs(logs []types.Log) ([]*orm.L2Message, []relayedMessage, error) {
|
||||
// Need use contract abi to parse event Log
|
||||
// Can only be tested after we have our contracts set up
|
||||
|
||||
var parsedlogs []*orm.L2Message
|
||||
var l2Messages []*orm.L2Message
|
||||
var relayedMessages []relayedMessage
|
||||
for _, vLog := range logs {
|
||||
event := struct {
|
||||
Target common.Address
|
||||
Sender common.Address
|
||||
Value *big.Int // uint256
|
||||
Fee *big.Int // uint256
|
||||
Deadline *big.Int // uint256
|
||||
Message []byte
|
||||
MessageNonce *big.Int // uint256
|
||||
GasLimit *big.Int // uint256
|
||||
}{}
|
||||
switch vLog.Topics[0] {
|
||||
case common.HexToHash(bridge_abi.SENT_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
Target common.Address
|
||||
Sender common.Address
|
||||
Value *big.Int // uint256
|
||||
Fee *big.Int // uint256
|
||||
Deadline *big.Int // uint256
|
||||
Message []byte
|
||||
MessageNonce *big.Int // uint256
|
||||
GasLimit *big.Int // uint256
|
||||
}{}
|
||||
|
||||
err := messengerABI.UnpackIntoInterface(&event, "SentMessage", vLog.Data)
|
||||
if err != nil {
|
||||
log.Error("failed to unpack layer2 SentMessage event", "err", err)
|
||||
return parsedlogs, err
|
||||
err := w.messengerABI.UnpackIntoInterface(&event, "SentMessage", vLog.Data)
|
||||
if err != nil {
|
||||
log.Error("failed to unpack layer2 SentMessage event", "err", err)
|
||||
return l2Messages, relayedMessages, err
|
||||
}
|
||||
// target is in topics[1]
|
||||
event.Target = common.HexToAddress(vLog.Topics[1].String())
|
||||
l2Messages = append(l2Messages, &orm.L2Message{
|
||||
Nonce: event.MessageNonce.Uint64(),
|
||||
MsgHash: utils.ComputeMessageHash(event.Target, event.Sender, event.Value, event.Fee, event.Deadline, event.Message, event.MessageNonce).String(),
|
||||
Height: vLog.BlockNumber,
|
||||
Sender: event.Sender.String(),
|
||||
Value: event.Value.String(),
|
||||
Fee: event.Fee.String(),
|
||||
GasLimit: event.GasLimit.Uint64(),
|
||||
Deadline: event.Deadline.Uint64(),
|
||||
Target: event.Target.String(),
|
||||
Calldata: common.Bytes2Hex(event.Message),
|
||||
Layer2Hash: vLog.TxHash.Hex(),
|
||||
})
|
||||
case common.HexToHash(bridge_abi.RELAYED_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
MsgHash common.Hash
|
||||
}{}
|
||||
// MsgHash is in topics[1]
|
||||
event.MsgHash = common.HexToHash(vLog.Topics[1].String())
|
||||
relayedMessages = append(relayedMessages, relayedMessage{
|
||||
msgHash: event.MsgHash,
|
||||
txHash: vLog.TxHash,
|
||||
isSuccessful: true,
|
||||
})
|
||||
case common.HexToHash(bridge_abi.FAILED_RELAYED_MESSAGE_EVENT_SIGNATURE):
|
||||
event := struct {
|
||||
MsgHash common.Hash
|
||||
}{}
|
||||
// MsgHash is in topics[1]
|
||||
event.MsgHash = common.HexToHash(vLog.Topics[1].String())
|
||||
relayedMessages = append(relayedMessages, relayedMessage{
|
||||
msgHash: event.MsgHash,
|
||||
txHash: vLog.TxHash,
|
||||
isSuccessful: false,
|
||||
})
|
||||
default:
|
||||
log.Error("Unknown event", "topic", vLog.Topics[0], "txHash", vLog.TxHash)
|
||||
}
|
||||
// target is in topics[1]
|
||||
event.Target = common.HexToAddress(vLog.Topics[1].String())
|
||||
parsedlogs = append(parsedlogs, &orm.L2Message{
|
||||
Nonce: event.MessageNonce.Uint64(),
|
||||
Height: vLog.BlockNumber,
|
||||
Sender: event.Sender.String(),
|
||||
Value: event.Value.String(),
|
||||
Fee: event.Fee.String(),
|
||||
GasLimit: event.GasLimit.Uint64(),
|
||||
Deadline: event.Deadline.Uint64(),
|
||||
Target: event.Target.String(),
|
||||
Calldata: common.Bytes2Hex(event.Message),
|
||||
Layer2Hash: vLog.TxHash.Hex(),
|
||||
})
|
||||
}
|
||||
|
||||
return parsedlogs, nil
|
||||
return l2Messages, relayedMessages, nil
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"scroll-tech/database"
|
||||
"scroll-tech/database/migrate"
|
||||
"scroll-tech/database/orm"
|
||||
)
|
||||
|
||||
func testCreateNewWatcherAndStop(t *testing.T) {
|
||||
@@ -87,7 +88,7 @@ func testMonitorBridgeContract(t *testing.T) {
|
||||
t.Fatalf("Call failed")
|
||||
}
|
||||
|
||||
//extra block mined
|
||||
// extra block mined
|
||||
toAddress = common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
||||
message = []byte("testbridgecontract")
|
||||
tx, err = instance.SendMessage(auth, toAddress, message, auth.GasPrice)
|
||||
@@ -110,7 +111,7 @@ func testMonitorBridgeContract(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
t.Log("Height in DB is", height)
|
||||
assert.Greater(t, height, int64(previousHeight))
|
||||
msgs, err := db.GetL2UnprocessedMessages()
|
||||
msgs, err := db.GetL2MessagesByStatus(orm.MsgPending)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, len(msgs))
|
||||
}
|
||||
@@ -178,7 +179,7 @@ func testFetchMultipleSentMessageInOneBlock(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
t.Log("LatestHeight is", height)
|
||||
assert.Greater(t, height, int64(previousHeight)) // height must be greater than previousHeight because confirmations is 0
|
||||
msgs, err := db.GetL2UnprocessedMessages()
|
||||
msgs, err := db.GetL2MessagesByStatus(orm.MsgPending)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, len(msgs))
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -69,6 +70,7 @@ type PendingTransaction struct {
|
||||
submitAt uint64
|
||||
id string
|
||||
feeData *FeeData
|
||||
signer *bind.TransactOpts
|
||||
tx *types.Transaction
|
||||
}
|
||||
|
||||
@@ -82,7 +84,6 @@ type Sender struct {
|
||||
// account fields.
|
||||
auths *accountPool
|
||||
|
||||
mu sync.Mutex
|
||||
blockNumber uint64 // Current block number on chain.
|
||||
baseFeePerGas uint64 // Current base fee per gas on chain
|
||||
pendingTxs sync.Map // Mapping from nonce to pending transaction
|
||||
@@ -126,6 +127,7 @@ func NewSender(ctx context.Context, config *config.SenderConfig, privs []*ecdsa.
|
||||
chainID: chainID,
|
||||
auths: auths,
|
||||
confirmCh: make(chan *Confirmation, 128),
|
||||
blockNumber: header.Number.Uint64(),
|
||||
baseFeePerGas: header.BaseFee.Uint64(),
|
||||
pendingTxs: sync.Map{},
|
||||
stopCh: make(chan struct{}),
|
||||
@@ -188,15 +190,23 @@ func (s *Sender) getFeeData(auth *bind.TransactOpts, target *common.Address, val
|
||||
|
||||
// SendTransaction send a signed L2tL1 transaction.
|
||||
func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.Int, data []byte) (hash common.Hash, err error) {
|
||||
if _, ok := s.pendingTxs.Load(ID); ok {
|
||||
// We occupy the ID, in case some other threads call with the same ID in the same time
|
||||
if _, loaded := s.pendingTxs.LoadOrStore(ID, nil); loaded {
|
||||
return common.Hash{}, fmt.Errorf("has the repeat tx ID, ID: %s", ID)
|
||||
}
|
||||
// get
|
||||
auth := s.auths.getAccount()
|
||||
if auth == nil {
|
||||
s.pendingTxs.Delete(ID) // release the ID on failure
|
||||
return common.Hash{}, ErrNoAvailableAccount
|
||||
}
|
||||
|
||||
defer s.auths.releaseAccount(auth)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
s.pendingTxs.Delete(ID) // release the ID on failure
|
||||
}
|
||||
}()
|
||||
|
||||
var (
|
||||
feeData *FeeData
|
||||
@@ -206,11 +216,12 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I
|
||||
if feeData, err = s.getFeeData(auth, target, value, data); err != nil {
|
||||
return
|
||||
}
|
||||
if tx, err = s.createAndSendTx(auth, feeData, target, value, data); err == nil {
|
||||
if tx, err = s.createAndSendTx(auth, feeData, target, value, data, nil); err == nil {
|
||||
// add pending transaction to queue
|
||||
pending := &PendingTransaction{
|
||||
tx: tx,
|
||||
id: ID,
|
||||
signer: auth,
|
||||
submitAt: atomic.LoadUint64(&s.blockNumber),
|
||||
feeData: feeData,
|
||||
}
|
||||
@@ -221,14 +232,17 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, target *common.Address, value *big.Int, data []byte) (tx *types.Transaction, err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, target *common.Address, value *big.Int, data []byte, overrideNonce *uint64) (tx *types.Transaction, err error) {
|
||||
var (
|
||||
nonce = auth.Nonce.Uint64()
|
||||
txData types.TxData
|
||||
)
|
||||
|
||||
// this is a resubmit call, override the nonce
|
||||
if overrideNonce != nil {
|
||||
nonce = *overrideNonce
|
||||
}
|
||||
|
||||
// lock here to avoit blocking when call `SuggestGasPrice`
|
||||
switch s.config.TxType {
|
||||
case LegacyTxType:
|
||||
@@ -284,25 +298,21 @@ func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, targ
|
||||
if err = s.client.SendTransaction(s.ctx, tx); err != nil {
|
||||
log.Error("failed to send tx", "tx hash", tx.Hash().String(), "err", err)
|
||||
// Check if contain nonce, and reset nonce
|
||||
if strings.Contains(err.Error(), "nonce") {
|
||||
// only reset nonce when it is not from resubmit
|
||||
if strings.Contains(err.Error(), "nonce") && overrideNonce == nil {
|
||||
s.auths.resetNonce(context.Background(), auth)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// update nonce
|
||||
auth.Nonce = big.NewInt(int64(nonce + 1))
|
||||
// update nonce when it is not from resubmit
|
||||
if overrideNonce == nil {
|
||||
auth.Nonce = big.NewInt(int64(nonce + 1))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Sender) resubmitTransaction(feeData *FeeData, tx *types.Transaction) (*types.Transaction, error) {
|
||||
// Get a idle account from account pool.
|
||||
auth := s.auths.getAccount()
|
||||
if auth == nil {
|
||||
return nil, ErrNoAvailableAccount
|
||||
}
|
||||
defer s.auths.releaseAccount(auth)
|
||||
|
||||
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)
|
||||
@@ -338,7 +348,8 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, tx *types.Transaction) (*
|
||||
feeData.gasTipCap = gasTipCap
|
||||
}
|
||||
|
||||
return s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data())
|
||||
nonce := tx.Nonce()
|
||||
return s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data(), &nonce)
|
||||
}
|
||||
|
||||
// CheckPendingTransaction Check pending transaction given number of blocks to wait before confirmation.
|
||||
@@ -347,6 +358,11 @@ func (s *Sender) CheckPendingTransaction(header *types.Header) {
|
||||
atomic.StoreUint64(&s.blockNumber, number)
|
||||
atomic.StoreUint64(&s.baseFeePerGas, header.BaseFee.Uint64())
|
||||
s.pendingTxs.Range(func(key, value interface{}) bool {
|
||||
// ignore empty id, since we use empty id to occupy pending task
|
||||
if value == nil || reflect.ValueOf(value).IsNil() {
|
||||
return true
|
||||
}
|
||||
|
||||
pending := value.(*PendingTransaction)
|
||||
receipt, err := s.client.TransactionReceipt(s.ctx, pending.tx.Hash())
|
||||
if (err == nil) && (receipt != nil) {
|
||||
@@ -361,12 +377,43 @@ func (s *Sender) CheckPendingTransaction(header *types.Header) {
|
||||
}
|
||||
} else if s.config.EscalateBlocks+pending.submitAt < number {
|
||||
var tx *types.Transaction
|
||||
tx, err := s.resubmitTransaction(pending.feeData, pending.tx)
|
||||
tx, err := s.resubmitTransaction(pending.feeData, pending.signer, pending.tx)
|
||||
if 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.Delete(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
|
||||
|
||||
69
bridge/utils/utils.go
Normal file
69
bridge/utils/utils.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/keccak256"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/common/math"
|
||||
)
|
||||
|
||||
// Keccak2 compute the keccack256 of two concatenations of bytes32
|
||||
func Keccak2(a common.Hash, b common.Hash) common.Hash {
|
||||
return common.BytesToHash(keccak256.Hash(append(a.Bytes()[:], b.Bytes()[:]...)))
|
||||
}
|
||||
|
||||
func encodePacked(input ...[]byte) []byte {
|
||||
return bytes.Join(input, nil)
|
||||
}
|
||||
|
||||
// ComputeMessageHash compute the message hash
|
||||
func ComputeMessageHash(
|
||||
target common.Address,
|
||||
sender common.Address,
|
||||
value *big.Int,
|
||||
fee *big.Int,
|
||||
deadline *big.Int,
|
||||
message []byte,
|
||||
messageNonce *big.Int,
|
||||
) common.Hash {
|
||||
packed := encodePacked(
|
||||
target.Bytes(),
|
||||
sender.Bytes(),
|
||||
math.U256Bytes(value),
|
||||
math.U256Bytes(fee),
|
||||
math.U256Bytes(deadline),
|
||||
math.U256Bytes(messageNonce),
|
||||
message,
|
||||
)
|
||||
return common.BytesToHash(keccak256.Hash(packed))
|
||||
}
|
||||
|
||||
// BufferToUint256Be convert bytes array to uint256 array assuming big-endian
|
||||
func BufferToUint256Be(buffer []byte) []*big.Int {
|
||||
buffer256 := make([]*big.Int, len(buffer)/32)
|
||||
for i := 0; i < len(buffer)/32; i++ {
|
||||
buffer256[i] = big.NewInt(0)
|
||||
for j := 0; j < 32; j++ {
|
||||
buffer256[i] = buffer256[i].Lsh(buffer256[i], 8)
|
||||
buffer256[i] = buffer256[i].Add(buffer256[i], big.NewInt(int64(buffer[i*32+j])))
|
||||
}
|
||||
}
|
||||
return buffer256
|
||||
}
|
||||
|
||||
// BufferToUint256Le convert bytes array to uint256 array assuming little-endian
|
||||
func BufferToUint256Le(buffer []byte) []*big.Int {
|
||||
buffer256 := make([]*big.Int, len(buffer)/32)
|
||||
for i := 0; i < len(buffer)/32; i++ {
|
||||
v := big.NewInt(0)
|
||||
shft := big.NewInt(1)
|
||||
for j := 0; j < 32; j++ {
|
||||
v = new(big.Int).Add(v, new(big.Int).Mul(shft, big.NewInt(int64(buffer[i*32+j]))))
|
||||
shft = new(big.Int).Mul(shft, big.NewInt(256))
|
||||
}
|
||||
buffer256[i] = v
|
||||
}
|
||||
return buffer256
|
||||
}
|
||||
42
bridge/utils/utils_test.go
Normal file
42
bridge/utils/utils_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"scroll-tech/bridge/utils"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
)
|
||||
|
||||
func TestKeccak2(t *testing.T) {
|
||||
hash := utils.Keccak2(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"))
|
||||
if hash != common.HexToHash("0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5") {
|
||||
t.Fatalf("Invalid keccak, want %s, got %s", "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", hash.Hex())
|
||||
}
|
||||
|
||||
hash = utils.Keccak2(common.HexToHash("0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"), common.HexToHash("0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"))
|
||||
if hash != common.HexToHash("0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30") {
|
||||
t.Fatalf("Invalid keccak, want %s, got %s", "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", hash.Hex())
|
||||
}
|
||||
|
||||
hash = utils.Keccak2(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"), common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000002"))
|
||||
if hash != common.HexToHash("0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0") {
|
||||
t.Fatalf("Invalid keccak, want %s, got %s", "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0", hash.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeMessageHash(t *testing.T) {
|
||||
hash := utils.ComputeMessageHash(
|
||||
common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc5"),
|
||||
common.HexToAddress("0xeafea492d9c6733ae3d56b7ed1adb60692c98bf7"),
|
||||
big.NewInt(1),
|
||||
big.NewInt(2),
|
||||
big.NewInt(1234567),
|
||||
common.Hex2Bytes("0011223344"),
|
||||
big.NewInt(3),
|
||||
)
|
||||
if hash != common.HexToHash("0x58c9a5abfd2a558bb6a6fd5192b36fe9325d98763bafd3a51a1ea28a5d0b990b") {
|
||||
t.Fatalf("Invalid ComputeMessageHash, want %s, got %s", "0x58c9a5abfd2a558bb6a6fd5192b36fe9325d98763bafd3a51a1ea28a5d0b990b", hash.Hex())
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Download Go dependencies
|
||||
FROM scrolltech/go-builder:1.18 as base
|
||||
FROM scrolltech/go-alpine-builder:1.18 as base
|
||||
|
||||
WORKDIR /src
|
||||
COPY go.work* ./
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
# Download Go dependencies
|
||||
FROM scrolltech/go-builder:1.18 as base
|
||||
# Build libzkp dependency
|
||||
FROM scrolltech/go-rust-builder:go-1.17-rust-nightly-2022-08-23 as chef
|
||||
WORKDIR app
|
||||
|
||||
FROM chef as planner
|
||||
COPY ./common/libzkp/impl/ .
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef as zkp-builder
|
||||
COPY ./common/libzkp/impl/rust-toolchain ./
|
||||
COPY --from=planner /app/recipe.json recipe.json
|
||||
RUN cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
COPY ./common/libzkp/impl .
|
||||
RUN cargo build --release
|
||||
|
||||
|
||||
# Download Go dependencies
|
||||
FROM scrolltech/go-rust-builder:go-1.18-rust-nightly-2022-08-23 as base
|
||||
WORKDIR /src
|
||||
COPY go.work* ./
|
||||
COPY ./bridge/go.* ./bridge/
|
||||
@@ -10,17 +26,17 @@ COPY ./database/go.* ./database/
|
||||
COPY ./roller/go.* ./roller/
|
||||
RUN go mod download -x
|
||||
|
||||
|
||||
# Build coordinator
|
||||
FROM base as builder
|
||||
|
||||
RUN --mount=target=. \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
cd /src/coordinator/cmd && go build -v -p 4 -o /bin/coordinator
|
||||
COPY . .
|
||||
RUN cp -r ./common/libzkp/interface ./coordinator/verifier/lib
|
||||
COPY --from=zkp-builder /app/target/release/libzkp.a ./coordinator/verifier/lib/
|
||||
RUN cd ./coordinator && go build -v -p 4 -o /bin/coordinator ./cmd
|
||||
|
||||
# Pull coordinator into a second stage deploy alpine container
|
||||
FROM alpine:latest
|
||||
FROM ubuntu:20.04
|
||||
|
||||
COPY --from=builder /bin/coordinator /bin/
|
||||
|
||||
ENTRYPOINT ["coordinator"]
|
||||
|
||||
ENTRYPOINT ["/bin/coordinator"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Download Go dependencies
|
||||
FROM scrolltech/go-builder:1.18 as base
|
||||
FROM scrolltech/go-alpine-builder:1.18 as base
|
||||
|
||||
WORKDIR /src
|
||||
COPY go.work* ./
|
||||
|
||||
@@ -2,11 +2,15 @@ GO_VERSION := 1.18
|
||||
PYTHON_VERSION := 3.10
|
||||
RUST_VERSION := nightly-2022-08-23
|
||||
|
||||
.PHONY: all go-builder rust-builder rust-alpine-builder go-rust-builder py-runner
|
||||
.PHONY: all go-alpine-builder rust-builder rust-alpine-builder go-rust-alpine-builder go-rust-builder py-runner
|
||||
|
||||
go-builder:
|
||||
docker build -t scrolltech/go-builder:latest -f go-builder.Dockerfile ./
|
||||
docker image tag scrolltech/go-builder:latest scrolltech/go-builder:$(GO_VERSION)
|
||||
go-rust-builder:
|
||||
docker build -t scrolltech/go-rust-builder:latest -f go-rust-builder.Dockerfile ./
|
||||
docker image tag scrolltech/go-rust-builder:latest scrolltech/go-rust-builder:go-$(GO_VERSION)-rust-$(RUST_VERSION)
|
||||
|
||||
go-alpine-builder:
|
||||
docker build -t scrolltech/go-alpine-builder:latest -f go-alpine-builder.Dockerfile ./
|
||||
docker image tag scrolltech/go-alpine-builder:latest scrolltech/go-alpine-builder:$(GO_VERSION)
|
||||
|
||||
rust-builder:
|
||||
docker build -t scrolltech/rust-builder:latest -f rust-builder.Dockerfile ./
|
||||
@@ -16,23 +20,25 @@ rust-alpine-builder:
|
||||
docker build -t scrolltech/rust-alpine-builder:latest -f rust-alpine-builder.Dockerfile ./
|
||||
docker image tag scrolltech/rust-alpine-builder:latest scrolltech/rust-alpine-builder:$(RUST_VERSION)
|
||||
|
||||
go-rust-builder:
|
||||
docker build -t scrolltech/go-rust-builder:latest -f go-rust-builder.Dockerfile ./
|
||||
docker image tag scrolltech/go-rust-builder:latest scrolltech/go-rust-builder:go-$(GO_VERSION)-rust-$(RUST_VERSION)
|
||||
go-rust-alpine-builder:
|
||||
docker build -t scrolltech/go-rust-alpine-builder:latest -f go-rust-alpine-builder.Dockerfile ./
|
||||
docker image tag scrolltech/go-rust-alpine-builder:latest scrolltech/go-rust-alpine-builder:go-$(GO_VERSION)-rust-$(RUST_VERSION)
|
||||
|
||||
py-runner:
|
||||
docker build -t scrolltech/py-runner:latest -f py-runner.Dockerfile ./
|
||||
docker image tag scrolltech/py-runner:latest scrolltech/py-runner:$(PYTHON_VERSION)
|
||||
|
||||
all: go-builder rust-builder rust-alpine-builder go-rust-builder py-runner
|
||||
all: go-alpine-builder rust-builder rust-alpine-builder go-rust-alpine-builder go-rust-builder py-runner
|
||||
|
||||
publish:
|
||||
docker push scrolltech/go-builder:latest
|
||||
docker push scrolltech/go-builder:$(GO_VERSION)
|
||||
docker push scrolltech/go-alpine-builder:latest
|
||||
docker push scrolltech/go-alpine-builder:$(GO_VERSION)
|
||||
docker push scrolltech/rust-builder:latest
|
||||
docker push scrolltech/rust-builder:$(RUST_VERSION)
|
||||
docker push scrolltech/rust-alpine-builder:latest
|
||||
docker push scrolltech/rust-alpine-builder:$(RUST_VERSION)
|
||||
docker push scrolltech/go-rust-alpine-builder:latest
|
||||
docker push scrolltech/go-rust-alpine-builder:go-$(GO_VERSION)-rust-$(RUST_VERSION)
|
||||
docker push scrolltech/go-rust-builder:latest
|
||||
docker push scrolltech/go-rust-builder:go-$(GO_VERSION)-rust-$(RUST_VERSION)
|
||||
docker push scrolltech/py-runner:latest
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
FROM golang:1.18-alpine
|
||||
ARG CARGO_CHEF_TAG=0.1.41
|
||||
ARG DEFAULT_RUST_TOOLCHAIN=nightly-2022-08-23
|
||||
|
||||
RUN apk add --no-cache gcc musl-dev linux-headers git ca-certificates
|
||||
|
||||
# RUN apk add --no-cache libc6-compat
|
||||
# RUN apk add --no-cache gcompat
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
PATH=/usr/local/cargo/bin:$PATH \
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||
|
||||
RUN set -eux; \
|
||||
apkArch="$(apk --print-arch)"; \
|
||||
case "$apkArch" in \
|
||||
x86_64) rustArch='x86_64-unknown-linux-musl' ;; \
|
||||
aarch64) rustArch='aarch64-unknown-linux-musl' ;; \
|
||||
*) echo >&2 "unsupported architecture: $apkArch"; exit 1 ;; \
|
||||
esac; \
|
||||
\
|
||||
url="https://static.rust-lang.org/rustup/dist/${rustArch}/rustup-init"; \
|
||||
wget "$url"; \
|
||||
chmod +x rustup-init;
|
||||
|
||||
RUN ./rustup-init -y --no-modify-path --default-toolchain ${DEFAULT_RUST_TOOLCHAIN}; \
|
||||
rm rustup-init; \
|
||||
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
|
||||
rustup --version; \
|
||||
cargo --version; \
|
||||
rustc --version;
|
||||
|
||||
RUN cargo install cargo-chef --locked --version ${CARGO_CHEF_TAG} \
|
||||
&& rm -rf $CARGO_HOME/registry/
|
||||
@@ -1,32 +1,34 @@
|
||||
FROM golang:1.18-alpine
|
||||
ARG CARGO_CHEF_TAG=0.1.41
|
||||
ARG DEFAULT_RUST_TOOLCHAIN=nightly-2022-08-23
|
||||
FROM ubuntu:20.04
|
||||
|
||||
RUN apk add --no-cache gcc musl-dev linux-headers git ca-certificates
|
||||
RUN apt-get update && ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
PATH=/usr/local/cargo/bin:$PATH \
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||
# Install basic packages
|
||||
RUN apt-get install build-essential curl wget git pkg-config -y
|
||||
|
||||
RUN set -eux; \
|
||||
apkArch="$(apk --print-arch)"; \
|
||||
case "$apkArch" in \
|
||||
x86_64) rustArch='x86_64-unknown-linux-musl' ;; \
|
||||
aarch64) rustArch='aarch64-unknown-linux-musl' ;; \
|
||||
*) echo >&2 "unsupported architecture: $apkArch"; exit 1 ;; \
|
||||
esac; \
|
||||
\
|
||||
url="https://static.rust-lang.org/rustup/dist/${rustArch}/rustup-init"; \
|
||||
wget "$url"; \
|
||||
chmod +x rustup-init;
|
||||
# Install dev-packages
|
||||
RUN apt-get install libclang-dev libssl-dev llvm -y
|
||||
|
||||
RUN ./rustup-init -y --no-modify-path --default-toolchain ${DEFAULT_RUST_TOOLCHAIN}; \
|
||||
rm rustup-init; \
|
||||
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
|
||||
rustup --version; \
|
||||
cargo --version; \
|
||||
rustc --version;
|
||||
# Install Rust
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
ENV CARGO_HOME=/root/.cargo
|
||||
|
||||
# Add Toolchain
|
||||
RUN rustup toolchain install nightly-2022-08-23
|
||||
|
||||
# TODO: make this ARG
|
||||
ENV CARGO_CHEF_TAG=0.1.41
|
||||
|
||||
RUN cargo install cargo-chef --locked --version ${CARGO_CHEF_TAG} \
|
||||
&& rm -rf $CARGO_HOME/registry/
|
||||
|
||||
# Install Go
|
||||
RUN rm -rf /usr/local/go
|
||||
# for 1.17
|
||||
# RUN wget https://go.dev/dl/go1.17.13.linux-amd64.tar.gz
|
||||
# RUN tar -C /usr/local -xzf go1.17.13.linux-amd64.tar.gz
|
||||
# for 1.18
|
||||
RUN wget https://go.dev/dl/go1.18.9.linux-amd64.tar.gz
|
||||
RUN tar -C /usr/local -xzf go1.18.9.linux-amd64.tar.gz
|
||||
|
||||
ENV PATH="/usr/local/go/bin:${PATH}"
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM ubuntu:20.04
|
||||
RUN apt-get update && ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
|
||||
|
||||
# Install basic packages
|
||||
RUN apt-get install build-essential curl git pkg-config -y
|
||||
RUN apt-get install build-essential curl wget git pkg-config -y
|
||||
|
||||
# Install dev-packages
|
||||
RUN apt-get install libclang-dev libssl-dev llvm -y
|
||||
|
||||
2
common/.gitignore
vendored
2
common/.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
/build/bin
|
||||
.idea
|
||||
libzkp/impl/target
|
||||
libzkp/interface/*.a
|
||||
@@ -5,3 +5,4 @@ test:
|
||||
|
||||
lint: ## Lint the files - used for CI
|
||||
GOBIN=$(PWD)/build/bin go run ../build/lint.go
|
||||
cd libzkp/impl && cargo fmt --all -- --check && cargo clippy --release -- -D warnings
|
||||
@@ -81,7 +81,7 @@ func (t *Cmd) Write(data []byte) (int, error) {
|
||||
t.Logf(out)
|
||||
}
|
||||
go func(content string) {
|
||||
t.checkFuncs.Range(func(key, value interface{}) bool {
|
||||
t.checkFuncs.Range(func(key, value any) bool {
|
||||
check := value.(checkFunc)
|
||||
check(content)
|
||||
return true
|
||||
|
||||
@@ -10,24 +10,24 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
github.com/urfave/cli/v2 v2.10.2
|
||||
golang.org/x/sync v0.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
|
||||
github.com/btcsuite/btcd v0.20.1-beta // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.13 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.23 // indirect
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
@@ -36,18 +36,19 @@ require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.3.0 // indirect
|
||||
github.com/hashicorp/go-bexpr v0.1.10 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
||||
github.com/holiman/uint256 v1.2.0 // indirect
|
||||
github.com/huin/goupnp v1.0.2 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 // indirect
|
||||
github.com/huin/goupnp v1.0.3 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 // indirect
|
||||
github.com/influxdata/influxdb v1.8.3 // indirect
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.14 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
@@ -63,25 +64,26 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/tsdb v0.7.1 // indirect
|
||||
github.com/rjeczalik/notify v0.9.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/rs/cors v1.7.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/scroll-tech/zktrie v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.2.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/tools v0.3.0 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -77,8 +77,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -86,8 +87,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
@@ -97,8 +99,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/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=
|
||||
@@ -122,8 +125,9 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM=
|
||||
github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
@@ -210,10 +214,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
|
||||
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
|
||||
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@@ -225,12 +231,14 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU
|
||||
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
|
||||
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI=
|
||||
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
|
||||
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
|
||||
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 h1:dXZF+R9iI07DK49LHX/EKC3jTa0O2z+TUyvxjGK7V38=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 h1:ixWRiaqDULNyIDdOWz2QQJG5t4PpNHkQk2P6GV94cok=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
|
||||
github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8=
|
||||
@@ -246,8 +254,9 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
|
||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
|
||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
@@ -277,8 +286,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
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/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -360,6 +370,7 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -383,10 +394,14 @@ github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1
|
||||
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6 h1:o0Gq2d8nus6x82apluA5RJwjlOca7LIlpAfxlyvQvxs=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6/go.mod h1:jurIpDQ0hqtp9//xxeWzr8X9KMP/+TYn+vz3K1wZrv0=
|
||||
github.com/scroll-tech/zktrie v0.3.0 h1:c0GRNELUyAtyuiwllQKT1XjNbs7NRGfguKouiyLfFNY=
|
||||
@@ -397,7 +412,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
@@ -433,13 +447,16 @@ github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y=
|
||||
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
@@ -462,8 +479,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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=
|
||||
@@ -493,8 +510,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -521,8 +538,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
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=
|
||||
@@ -537,8 +554,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -585,8 +603,8 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -597,8 +615,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -634,13 +653,13 @@ golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
|
||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
|
||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
||||
|
||||
@@ -301,7 +301,7 @@ checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
[[package]]
|
||||
name = "bus-mapping"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"ethers-core",
|
||||
@@ -875,7 +875,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "eth-types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"ethers-core",
|
||||
"ethers-signers",
|
||||
@@ -1027,7 +1027,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "external-tracer"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"geth-utils",
|
||||
@@ -1244,7 +1244,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gadgets"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"digest 0.7.6",
|
||||
"eth-types",
|
||||
@@ -1284,7 +1284,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "geth-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"gobuild",
|
||||
]
|
||||
@@ -1858,7 +1858,7 @@ checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
|
||||
[[package]]
|
||||
name = "keccak256"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"halo2_proofs",
|
||||
@@ -2012,7 +2012,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mock"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"eth-types",
|
||||
"ethers-core",
|
||||
@@ -2492,20 +2492,6 @@ dependencies = [
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prover"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"types",
|
||||
"zkevm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
@@ -3403,7 +3389,7 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
[[package]]
|
||||
name = "types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/common-rs#bad0b6f6da869d40178569c4658c58985c5629fa"
|
||||
source = "git+https://github.com/scroll-tech/common-rs#4a299c70835179be7fcf007ebb122b428d063c56"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"blake2",
|
||||
@@ -3830,7 +3816,7 @@ checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
|
||||
[[package]]
|
||||
name = "zkevm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/common-rs#bad0b6f6da869d40178569c4658c58985c5629fa"
|
||||
source = "git+https://github.com/scroll-tech/common-rs#4a299c70835179be7fcf007ebb122b428d063c56"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"blake2",
|
||||
@@ -3866,7 +3852,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "zkevm-circuits"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#bd9b8eec349bbff14c3d6fd0152b0cb6334b4701"
|
||||
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=scroll-dev-0920#123e4bbd23f196a71037daf40fae66b7ca24a02e"
|
||||
dependencies = [
|
||||
"array-init",
|
||||
"bus-mapping",
|
||||
@@ -3895,3 +3881,18 @@ dependencies = [
|
||||
"strum_macros",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zkp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"libc",
|
||||
"log",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"types",
|
||||
"zkevm",
|
||||
]
|
||||
@@ -1,17 +1,18 @@
|
||||
[package]
|
||||
name = "prover"
|
||||
name = "zkp"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["staticlib", "cdylib"]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
zkevm = { git = "https://github.com/scroll-tech/common-rs" }
|
||||
types = { git = "https://github.com/scroll-tech/common-rs" }
|
||||
|
||||
log = "0.4"
|
||||
env_logger = "0.9.0"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0.66"
|
||||
@@ -25,4 +26,4 @@ debug-assertions = true
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
debug-assertions = true
|
||||
debug-assertions = true
|
||||
@@ -1,6 +1,7 @@
|
||||
#![feature(once_cell)]
|
||||
|
||||
pub mod prove;
|
||||
pub mod verify;
|
||||
|
||||
pub(crate) mod utils {
|
||||
use std::ffi::{CStr, CString};
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec, vec_to_c_char};
|
||||
use libc::c_char;
|
||||
use std::cell::OnceCell;
|
||||
use types::eth::BlockResult;
|
||||
use types::eth::BlockTrace;
|
||||
use zkevm::circuit::AGG_DEGREE;
|
||||
use zkevm::utils::{load_or_create_params, load_or_create_seed};
|
||||
use zkevm::{circuit::DEGREE, prover::Prover};
|
||||
@@ -11,6 +11,8 @@ static mut PROVER: OnceCell<Prover> = OnceCell::new();
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn init_prover(params_path: *const c_char, seed_path: *const c_char) {
|
||||
env_logger::init();
|
||||
|
||||
let params_path = c_char_to_str(params_path);
|
||||
let seed_path = c_char_to_str(seed_path);
|
||||
let params = load_or_create_params(params_path, *DEGREE).unwrap();
|
||||
@@ -24,7 +26,7 @@ pub unsafe extern "C" fn init_prover(params_path: *const c_char, seed_path: *con
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn create_agg_proof(trace_char: *const c_char) -> *const c_char {
|
||||
let trace_vec = c_char_to_vec(trace_char);
|
||||
let trace = serde_json::from_slice::<BlockResult>(&trace_vec).unwrap();
|
||||
let trace = serde_json::from_slice::<BlockTrace>(&trace_vec).unwrap();
|
||||
let proof = PROVER
|
||||
.get_mut()
|
||||
.unwrap()
|
||||
@@ -38,7 +40,7 @@ pub unsafe extern "C" fn create_agg_proof(trace_char: *const c_char) -> *const c
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn create_agg_proof_multi(trace_char: *const c_char) -> *const c_char {
|
||||
let trace_vec = c_char_to_vec(trace_char);
|
||||
let traces = serde_json::from_slice::<Vec<BlockResult>>(&trace_vec).unwrap();
|
||||
let traces = serde_json::from_slice::<Vec<BlockTrace>>(&trace_vec).unwrap();
|
||||
let proof = PROVER
|
||||
.get_mut()
|
||||
.unwrap()
|
||||
40
common/libzkp/impl/src/verify.rs
Normal file
40
common/libzkp/impl/src/verify.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use crate::utils::{c_char_to_str, c_char_to_vec};
|
||||
use libc::c_char;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use zkevm::circuit::{AGG_DEGREE, DEGREE};
|
||||
use zkevm::prover::AggCircuitProof;
|
||||
use zkevm::utils::load_or_create_params;
|
||||
use zkevm::verifier::Verifier;
|
||||
|
||||
static mut VERIFIER: Option<&Verifier> = None;
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn init_verifier(params_path: *const c_char, agg_vk_path: *const c_char) {
|
||||
env_logger::init();
|
||||
|
||||
let params_path = c_char_to_str(params_path);
|
||||
let agg_vk_path = c_char_to_str(agg_vk_path);
|
||||
let mut f = File::open(agg_vk_path).unwrap();
|
||||
let mut agg_vk = vec![];
|
||||
f.read_to_end(&mut agg_vk).unwrap();
|
||||
|
||||
let params = load_or_create_params(params_path, *DEGREE).unwrap();
|
||||
let agg_params = load_or_create_params(params_path, *AGG_DEGREE).unwrap();
|
||||
|
||||
let v = Box::new(Verifier::from_params(params, agg_params, Some(agg_vk)));
|
||||
VERIFIER = Some(Box::leak(v))
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn verify_agg_proof(proof: *const c_char) -> c_char {
|
||||
let proof_vec = c_char_to_vec(proof);
|
||||
let agg_proof = serde_json::from_slice::<AggCircuitProof>(proof_vec.as_slice()).unwrap();
|
||||
let verified = VERIFIER
|
||||
.unwrap()
|
||||
.verify_agg_circuit_proof(agg_proof)
|
||||
.is_ok();
|
||||
verified as c_char
|
||||
}
|
||||
5
common/libzkp/interface/libzkp.h
Normal file
5
common/libzkp/interface/libzkp.h
Normal file
@@ -0,0 +1,5 @@
|
||||
init_prover(char *params_path, char *seed_path);
|
||||
char* create_agg_proof(char *trace);
|
||||
char* create_agg_proof_multi(char *trace);
|
||||
init_verifier(char *params_path, char *agg_vk_path);
|
||||
char verify_agg_proof(char *proof);
|
||||
@@ -2,56 +2,32 @@ package message
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"golang.org/x/crypto/blake2s"
|
||||
)
|
||||
|
||||
// MsgType denotes the type of message being sent or received.
|
||||
type MsgType uint16
|
||||
|
||||
const (
|
||||
// ErrorMsgType error type of message.
|
||||
ErrorMsgType MsgType = iota
|
||||
// RegisterMsgType register type of message, sent by a roller when a connection is established.
|
||||
RegisterMsgType
|
||||
// TaskMsgType task type of message, sent by a sequencer to a roller to notify them
|
||||
// they need to generate a proof.
|
||||
TaskMsgType
|
||||
// ProofMsgType proof type of message, sent by a roller to a sequencer when they have finished
|
||||
// proof generation of a given set of block traces.
|
||||
ProofMsgType
|
||||
)
|
||||
|
||||
// RespStatus is the status of the proof generation
|
||||
// RespStatus represents status code from roller to scroll
|
||||
type RespStatus uint32
|
||||
|
||||
const (
|
||||
// StatusOk indicates the proof generation succeeded
|
||||
// StatusOk means generate proof success
|
||||
StatusOk RespStatus = iota
|
||||
// StatusProofError indicates the proof generation failed
|
||||
// StatusProofError means generate proof failed
|
||||
StatusProofError
|
||||
)
|
||||
|
||||
// Msg is the top-level message container which contains the payload and the
|
||||
// message identifier.
|
||||
type Msg struct {
|
||||
// Message type
|
||||
Type MsgType `json:"type"`
|
||||
// Message payload
|
||||
Payload []byte `json:"payload"`
|
||||
}
|
||||
|
||||
// AuthMessage is the first message exchanged from the Roller to the Sequencer.
|
||||
// AuthMsg is the first message exchanged from the Roller to the Sequencer.
|
||||
// It effectively acts as a registration, and makes the Roller identification
|
||||
// known to the Sequencer.
|
||||
type AuthMessage struct {
|
||||
type AuthMsg struct {
|
||||
// Message fields
|
||||
Identity Identity `json:"message"`
|
||||
Identity *Identity `json:"message"`
|
||||
// Roller signature
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
@@ -67,10 +43,21 @@ type Identity struct {
|
||||
// Version is common.Version+ZK_VERSION. Use the following to check the latest ZK_VERSION version.
|
||||
// curl -sL https://api.github.com/repos/scroll-tech/common-rs/commits | jq -r ".[0].sha"
|
||||
Version string `json:"version"`
|
||||
// Random unique token generated by manager
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// GenerateToken generates token
|
||||
func GenerateToken() (string, error) {
|
||||
b := make([]byte, 16)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
// Sign auth message
|
||||
func (a *AuthMessage) Sign(priv *ecdsa.PrivateKey) error {
|
||||
func (a *AuthMsg) Sign(priv *ecdsa.PrivateKey) error {
|
||||
// Hash identity content
|
||||
hash, err := a.Identity.Hash()
|
||||
if err != nil {
|
||||
@@ -81,11 +68,50 @@ func (a *AuthMessage) Sign(priv *ecdsa.PrivateKey) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Signature = common.Bytes2Hex(sig)
|
||||
a.Signature = hexutil.Encode(sig)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify verifies the message of auth.
|
||||
func (a *AuthMsg) Verify() (bool, error) {
|
||||
hash, err := a.Identity.Hash()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sig := common.FromHex(a.Signature)
|
||||
// recover public key
|
||||
if a.Identity.PublicKey == "" {
|
||||
pk, err := crypto.SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
a.Identity.PublicKey = common.Bytes2Hex(crypto.CompressPubkey(pk))
|
||||
}
|
||||
|
||||
return crypto.VerifySignature(common.FromHex(a.Identity.PublicKey), hash, sig[:len(sig)-1]), nil
|
||||
}
|
||||
|
||||
// PublicKey return public key from signature
|
||||
func (a *AuthMsg) PublicKey() (string, error) {
|
||||
if a.Identity.PublicKey == "" {
|
||||
hash, err := a.Identity.Hash()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sig := common.FromHex(a.Signature)
|
||||
// recover public key
|
||||
pk, err := crypto.SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
a.Identity.PublicKey = common.Bytes2Hex(crypto.CompressPubkey(pk))
|
||||
return a.Identity.PublicKey, nil
|
||||
}
|
||||
|
||||
return a.Identity.PublicKey, nil
|
||||
}
|
||||
|
||||
// Hash returns the hash of the auth message, which should be the message used
|
||||
// to construct the Signature.
|
||||
func (i *Identity) Hash() ([]byte, error) {
|
||||
@@ -94,24 +120,97 @@ func (i *Identity) Hash() ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash := blake2s.Sum256(bs)
|
||||
hash := crypto.Keccak256Hash(bs)
|
||||
return hash[:], nil
|
||||
}
|
||||
|
||||
// ProofMsg is the data structure sent to the coordinator.
|
||||
type ProofMsg struct {
|
||||
*ProofDetail `json:"zkProof"`
|
||||
// Roller signature
|
||||
Signature string `json:"signature"`
|
||||
|
||||
// Roller public key
|
||||
publicKey string
|
||||
}
|
||||
|
||||
// Sign signs the ProofMsg.
|
||||
func (a *ProofMsg) Sign(priv *ecdsa.PrivateKey) error {
|
||||
hash, err := a.ProofDetail.Hash()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sig, err := crypto.Sign(hash, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Signature = hexutil.Encode(sig)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify verifies ProofMsg.Signature.
|
||||
func (a *ProofMsg) Verify() (bool, error) {
|
||||
hash, err := a.ProofDetail.Hash()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sig := common.FromHex(a.Signature)
|
||||
// recover public key
|
||||
if a.publicKey == "" {
|
||||
pk, err := crypto.SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
a.publicKey = common.Bytes2Hex(crypto.CompressPubkey(pk))
|
||||
}
|
||||
|
||||
return crypto.VerifySignature(common.FromHex(a.publicKey), hash, sig[:len(sig)-1]), nil
|
||||
}
|
||||
|
||||
// PublicKey return public key from signature
|
||||
func (a *ProofMsg) PublicKey() (string, error) {
|
||||
if a.publicKey == "" {
|
||||
hash, err := a.ProofDetail.Hash()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sig := common.FromHex(a.Signature)
|
||||
// recover public key
|
||||
pk, err := crypto.SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
a.publicKey = common.Bytes2Hex(crypto.CompressPubkey(pk))
|
||||
return a.publicKey, nil
|
||||
}
|
||||
|
||||
return a.publicKey, nil
|
||||
}
|
||||
|
||||
// TaskMsg is a wrapper type around db ProveTask type.
|
||||
type TaskMsg struct {
|
||||
ID string `json:"id"`
|
||||
Traces []*types.BlockTrace `json:"blockTraces"`
|
||||
}
|
||||
|
||||
// ProofMsg is the message received from rollers that contains zk proof, the status of
|
||||
// ProofDetail is the message received from rollers that contains zk proof, the status of
|
||||
// the proof generation succeeded, and an error message if proof generation failed.
|
||||
type ProofMsg struct {
|
||||
Status RespStatus `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
type ProofDetail struct {
|
||||
ID string `json:"id"`
|
||||
// FIXME: Maybe we need to allow Proof omitempty
|
||||
Proof *AggProof `json:"proof"`
|
||||
Status RespStatus `json:"status"`
|
||||
Proof *AggProof `json:"proof"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Hash return proofMsg content hash.
|
||||
func (z *ProofDetail) Hash() ([]byte, error) {
|
||||
bs, err := json.Marshal(z)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash := crypto.Keccak256Hash(bs)
|
||||
return hash[:], nil
|
||||
}
|
||||
|
||||
// AggProof includes the proof and public input that are required to verification and rollup.
|
||||
@@ -121,14 +220,3 @@ type AggProof struct {
|
||||
FinalPair []byte `json:"final_pair"`
|
||||
Vk []byte `json:"vk"`
|
||||
}
|
||||
|
||||
// Marshal marshals the TraceProof as bytes
|
||||
func (proof *AggProof) Marshal() ([]byte, error) {
|
||||
jsonByt, err := json.Marshal(proof)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, uint32(len(jsonByt)))
|
||||
return append(buf, jsonByt...), nil
|
||||
}
|
||||
|
||||
26
common/message/message_test.go
Normal file
26
common/message/message_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAuthMessageSignAndVerify(t *testing.T) {
|
||||
privkey, err := crypto.GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg := &AuthMsg{
|
||||
Identity: &Identity{
|
||||
Name: "testRoller",
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
},
|
||||
}
|
||||
assert.NoError(t, authMsg.Sign(privkey))
|
||||
|
||||
ok, err := authMsg.Verify()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
@@ -10,9 +10,10 @@ import (
|
||||
// ComputeBatchID compute a unique hash for a batch using "endBlockHash" & "endBlockHash in last batch"
|
||||
// & "batch height", following the logic in `_computeBatchId` in contracts/src/L1/rollup/ZKRollup.sol
|
||||
func ComputeBatchID(endBlockHash common.Hash, lastEndBlockHash common.Hash, index *big.Int) string {
|
||||
indexBytes := make([]byte, 32)
|
||||
return crypto.Keccak256Hash(
|
||||
endBlockHash.Bytes(),
|
||||
lastEndBlockHash.Bytes(),
|
||||
index.Bytes(),
|
||||
index.FillBytes(indexBytes),
|
||||
).String()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
@@ -29,4 +30,11 @@ func TestComputeBatchID(t *testing.T) {
|
||||
expected := "0xafe1e714d2cd3ed5b0fa0a04ee95cd564b955ab8661c5665588758b48b66e263"
|
||||
actual := utils.ComputeBatchID(common.Hash{}, common.Hash{}, math.MaxBig256)
|
||||
assert.Equal(t, expected, actual)
|
||||
|
||||
expected = "0xe05698242b035c0e4d1d58e8ab89507ac7a1403b17fd6a7ea87621a32674ec88"
|
||||
actual = utils.ComputeBatchID(
|
||||
common.HexToHash("0xfaef7761204f43c4ab2528a65fcc7ec2108709e5ebb646bdce9ce3c8862d3f25"),
|
||||
common.HexToHash("0xe3abef08cce4b8a0dcc6b7e4dd11f32863007a86f46c1d136682b5d77bdf0f7a"),
|
||||
big.NewInt(77233900))
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
@@ -9,25 +9,18 @@ import (
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/scroll-tech/go-ethereum/cmd/utils"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// LogConfig is for setup log types of the logger
|
||||
type LogConfig struct {
|
||||
LogFile string
|
||||
LogJSONFormat bool
|
||||
LogDebug bool
|
||||
Verbosity int
|
||||
}
|
||||
|
||||
// Setup is for setup logger
|
||||
func Setup(cfg *LogConfig) error {
|
||||
// LogSetup is for setup logger
|
||||
func LogSetup(ctx *cli.Context) error {
|
||||
var ostream log.Handler
|
||||
if logFile := cfg.LogFile; len(logFile) > 0 {
|
||||
if logFile := ctx.String(LogFileFlag.Name); len(logFile) > 0 {
|
||||
fp, err := os.OpenFile(filepath.Clean(logFile), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to open log file", "err", err)
|
||||
}
|
||||
if cfg.LogJSONFormat {
|
||||
if ctx.Bool(LogJSONFormat.Name) {
|
||||
ostream = log.StreamHandler(io.Writer(fp), log.JSONFormat())
|
||||
} else {
|
||||
ostream = log.StreamHandler(io.Writer(fp), log.TerminalFormat(true))
|
||||
@@ -41,10 +34,10 @@ func Setup(cfg *LogConfig) error {
|
||||
ostream = log.StreamHandler(output, log.TerminalFormat(usecolor))
|
||||
}
|
||||
// show the call file and line number
|
||||
log.PrintOrigins(cfg.LogDebug)
|
||||
log.PrintOrigins(ctx.Bool(LogDebugFlag.Name))
|
||||
glogger := log.NewGlogHandler(ostream)
|
||||
// Set log level
|
||||
glogger.Verbosity(log.Lvl(cfg.Verbosity))
|
||||
glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name)))
|
||||
log.Root().SetHandler(glogger)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,11 +4,18 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
// StartHTTPEndpoint starts the HTTP RPC endpoint.
|
||||
func StartHTTPEndpoint(endpoint string, timeouts rpc.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) {
|
||||
func StartHTTPEndpoint(endpoint string, apis []rpc.API) (*http.Server, net.Addr, error) {
|
||||
srv := rpc.NewServer()
|
||||
for _, api := range apis {
|
||||
if err := srv.RegisterName(api.Namespace, api.Service); err != nil {
|
||||
log.Crit("register namespace failed", "namespace", api.Namespace, "error", err)
|
||||
}
|
||||
}
|
||||
// start the HTTP listener
|
||||
var (
|
||||
listener net.Listener
|
||||
@@ -19,13 +26,23 @@ func StartHTTPEndpoint(endpoint string, timeouts rpc.HTTPTimeouts, handler http.
|
||||
}
|
||||
// Bundle and start the HTTP server
|
||||
httpSrv := &http.Server{
|
||||
Handler: handler,
|
||||
ReadTimeout: timeouts.ReadTimeout,
|
||||
WriteTimeout: timeouts.WriteTimeout,
|
||||
IdleTimeout: timeouts.IdleTimeout,
|
||||
Handler: srv,
|
||||
ReadTimeout: rpc.DefaultHTTPTimeouts.ReadTimeout,
|
||||
WriteTimeout: rpc.DefaultHTTPTimeouts.WriteTimeout,
|
||||
IdleTimeout: rpc.DefaultHTTPTimeouts.IdleTimeout,
|
||||
}
|
||||
go func() {
|
||||
_ = httpSrv.Serve(listener)
|
||||
}()
|
||||
return httpSrv, listener.Addr(), err
|
||||
}
|
||||
|
||||
// StartWSEndpoint starts the WS RPC endpoint.
|
||||
func StartWSEndpoint(endpoint string, apis []rpc.API) (*http.Server, net.Addr, error) {
|
||||
handler, addr, err := StartHTTPEndpoint(endpoint, apis)
|
||||
if err == nil {
|
||||
srv := (handler.Handler).(*rpc.Server)
|
||||
handler.Handler = srv.WebsocketHandler(nil)
|
||||
}
|
||||
return handler, addr, err
|
||||
}
|
||||
|
||||
30
common/utils/trace_gas.go
Normal file
30
common/utils/trace_gas.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// ComputeTraceGasCost computes gascost based on ExecutionResults.StructLogs.GasCost
|
||||
func ComputeTraceGasCost(trace *types.BlockTrace) uint64 {
|
||||
var (
|
||||
gasCost uint64
|
||||
eg errgroup.Group
|
||||
)
|
||||
for idx := range trace.ExecutionResults {
|
||||
i := idx
|
||||
eg.Go(func() error {
|
||||
var sum uint64
|
||||
for _, log := range trace.ExecutionResults[i].StructLogs {
|
||||
sum += log.GasCost
|
||||
}
|
||||
atomic.AddUint64(&gasCost, sum)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
_ = eg.Wait()
|
||||
|
||||
return gasCost
|
||||
}
|
||||
31
common/utils/trace_gas_test.go
Normal file
31
common/utils/trace_gas_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"scroll-tech/common/utils"
|
||||
)
|
||||
|
||||
// TestComputeTraceCost test ComputeTraceGasCost function
|
||||
func TestComputeTraceCost(t *testing.T) {
|
||||
templateBlockTrace, err := os.ReadFile("../testdata/blockTrace_03.json")
|
||||
assert.NoError(t, err)
|
||||
// unmarshal blockTrace
|
||||
blockTrace := &types.BlockTrace{}
|
||||
err = json.Unmarshal(templateBlockTrace, blockTrace)
|
||||
assert.NoError(t, err)
|
||||
var sum uint64
|
||||
for _, v := range blockTrace.ExecutionResults {
|
||||
for _, sv := range v.StructLogs {
|
||||
sum += sv.GasCost
|
||||
}
|
||||
}
|
||||
|
||||
res := utils.ComputeTraceGasCost(blockTrace)
|
||||
assert.Equal(t, sum, res)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var tag = "prealpha-v6.2"
|
||||
var tag = "prealpha-v7.2"
|
||||
|
||||
var commit = func() string {
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
|
||||
1
coordinator/.gitignore
vendored
1
coordinator/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/build/bin
|
||||
.idea
|
||||
verifier/lib
|
||||
@@ -7,9 +7,21 @@ REPO_ROOT_DIR=./..
|
||||
test:
|
||||
go test -v -race -coverprofile=coverage.txt -covermode=atomic -p 1 $(PWD)/...
|
||||
|
||||
libzkp:
|
||||
cd ../common/libzkp/impl && cargo build --release && cp ./target/release/libzkp.a ../interface/
|
||||
cp -r ../common/libzkp/interface ./verifier/lib
|
||||
|
||||
coordinator: ## Builds the Coordinator instance.
|
||||
cd ../common/libzkp/impl && cargo build --release && cp ./target/release/libzkp.a ../interface/
|
||||
cp -r ../common/libzkp/interface ./verifier/lib
|
||||
go build -o $(PWD)/build/bin/coordinator ./cmd
|
||||
|
||||
test-verifier:
|
||||
go test -tags ffi -timeout 0 -v ./verifier
|
||||
|
||||
test-gpu-verifier:
|
||||
go test -tags="gpu ffi" -timeout 0 -v ./verifier
|
||||
|
||||
lint: ## Lint the files - used for CI
|
||||
GOBIN=$(PWD)/build/bin go run ../build/lint.go
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Coordinator
|
||||
|
||||
[](https://scroll-tech/coordinator/actions)
|
||||
[](https://codecov.io/gh/scroll-tech/coordinator)
|
||||
|
||||
This repo contains the Scroll coordinator.
|
||||
|
||||
## Build
|
||||
@@ -12,19 +9,15 @@ make clean
|
||||
make coordinator
|
||||
```
|
||||
|
||||
## db operation
|
||||
## db config
|
||||
|
||||
* init, show version, rollback, check status db
|
||||
* db settings in config
|
||||
|
||||
```bash
|
||||
# DB_DSN: db data source name
|
||||
export DB_DSN="postgres://admin:123456@localhost/test_db?sslmode=disable"
|
||||
# DB_DRIVER: db driver name
|
||||
export DB_DRIVER="postgres"
|
||||
|
||||
# TEST_DB_DRIVER, TEST_DB_DSN: It is required when executing db test cases
|
||||
export TEST_DB_DRIVER="postgres"
|
||||
export TEST_DB_DSN="postgres://admin:123456@localhost/test_db?sslmode=disable"
|
||||
```
|
||||
|
||||
## Start
|
||||
|
||||
@@ -1,91 +1,120 @@
|
||||
package coordinator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"scroll-tech/database/orm"
|
||||
"github.com/patrickmn/go-cache"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
)
|
||||
|
||||
// RollerInfo records the roller name, pub key and active session info (id, start time).
|
||||
type RollerInfo struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
PublicKey string `json:"public_key"`
|
||||
ActiveSession string `json:"active_session,omitempty"`
|
||||
ActiveSessionStartTime time.Time `json:"active_session_start_time"` // latest proof start time.
|
||||
// RollerAPI for rollers inorder to register and submit proof
|
||||
type RollerAPI interface {
|
||||
RequestToken(authMsg *message.AuthMsg) (string, error)
|
||||
Register(ctx context.Context, authMsg *message.AuthMsg) (*rpc.Subscription, error)
|
||||
SubmitProof(proof *message.ProofMsg) (bool, error)
|
||||
}
|
||||
|
||||
// SessionInfo records proof create or proof verify failed session.
|
||||
type SessionInfo struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
FinishTime time.Time `json:"finish_time,omitempty"` // set to 0 if not finished
|
||||
AssignedRollers []string `json:"assigned_rollers,omitempty"` // roller name list
|
||||
Error string `json:"error,omitempty"` // empty string if no error encountered
|
||||
}
|
||||
|
||||
// RollerDebugAPI roller api interface in order go get debug message.
|
||||
type RollerDebugAPI interface {
|
||||
// ListRollers returns all live rollers
|
||||
ListRollers() ([]*RollerInfo, error)
|
||||
// GetSessionInfo returns the session information given the session id.
|
||||
GetSessionInfo(sessionID string) (*SessionInfo, error)
|
||||
}
|
||||
|
||||
// ListRollers returns all live rollers.
|
||||
func (m *Manager) ListRollers() ([]*RollerInfo, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
var res []*RollerInfo
|
||||
for _, roller := range m.server.conns.getAll() {
|
||||
pk := roller.AuthMsg.Identity.PublicKey
|
||||
info := &RollerInfo{
|
||||
Name: roller.AuthMsg.Identity.Name,
|
||||
Version: roller.AuthMsg.Identity.Version,
|
||||
PublicKey: pk,
|
||||
// RequestToken generates and sends back register token for roller
|
||||
func (m *Manager) RequestToken(authMsg *message.AuthMsg) (string, error) {
|
||||
if ok, err := authMsg.Verify(); !ok {
|
||||
if err != nil {
|
||||
log.Error("failed to verify auth message", "error", err)
|
||||
}
|
||||
for id, sess := range m.sessions {
|
||||
if _, ok := sess.rollers[pk]; ok {
|
||||
info.ActiveSessionStartTime = sess.startTime
|
||||
info.ActiveSession = id
|
||||
break
|
||||
return "", errors.New("signature verification failed")
|
||||
}
|
||||
pubkey, _ := authMsg.PublicKey()
|
||||
if token, ok := m.tokenCache.Get(pubkey); ok {
|
||||
return token.(string), nil
|
||||
}
|
||||
token, err := message.GenerateToken()
|
||||
if err != nil {
|
||||
return "", errors.New("token generation failed")
|
||||
}
|
||||
m.tokenCache.Set(pubkey, token, cache.DefaultExpiration)
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// Register register api for roller
|
||||
func (m *Manager) Register(ctx context.Context, authMsg *message.AuthMsg) (*rpc.Subscription, error) {
|
||||
// Verify register message.
|
||||
if ok, err := authMsg.Verify(); !ok {
|
||||
if err != nil {
|
||||
log.Error("failed to verify auth message", "error", err)
|
||||
}
|
||||
return nil, errors.New("signature verification failed")
|
||||
}
|
||||
pubkey, _ := authMsg.PublicKey()
|
||||
|
||||
// Lock here to avoid malicious roller message replay before cleanup of token
|
||||
m.registerMu.Lock()
|
||||
if ok, err := m.VerifyToken(authMsg); !ok {
|
||||
m.registerMu.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
// roller successfully registered, remove token associated with this roller
|
||||
m.tokenCache.Delete(pubkey)
|
||||
m.registerMu.Unlock()
|
||||
|
||||
// create or get the roller message channel
|
||||
taskCh, err := m.register(pubkey, authMsg.Identity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notifier, supported := rpc.NotifierFromContext(ctx)
|
||||
if !supported {
|
||||
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
|
||||
}
|
||||
rpcSub := notifier.CreateSubscription()
|
||||
go func() {
|
||||
defer func() {
|
||||
m.freeRoller(pubkey)
|
||||
log.Info("roller unregister", "name", authMsg.Identity.Name)
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case task := <-taskCh:
|
||||
notifier.Notify(rpcSub.ID, task) //nolint
|
||||
case <-rpcSub.Err():
|
||||
return
|
||||
case <-notifier.Closed():
|
||||
return
|
||||
}
|
||||
}
|
||||
res = append(res, info)
|
||||
}
|
||||
return res, nil
|
||||
}()
|
||||
log.Info("roller register", "name", authMsg.Identity.Name, "version", authMsg.Identity.Version)
|
||||
|
||||
return rpcSub, nil
|
||||
}
|
||||
|
||||
func newSessionInfo(s *session, status orm.ProvingStatus, errMsg string, finished bool) *SessionInfo {
|
||||
now := time.Now()
|
||||
var nameList []string
|
||||
for pk := range s.roller_names {
|
||||
nameList = append(nameList, s.roller_names[pk])
|
||||
// SubmitProof roller pull proof
|
||||
func (m *Manager) SubmitProof(proof *message.ProofMsg) (bool, error) {
|
||||
// Verify the signature
|
||||
if ok, err := proof.Verify(); !ok {
|
||||
if err != nil {
|
||||
log.Error("failed to verify proof message", "error", err)
|
||||
}
|
||||
return false, errors.New("auth signature verify fail")
|
||||
}
|
||||
info := &SessionInfo{
|
||||
ID: s.id,
|
||||
Status: status.String(),
|
||||
AssignedRollers: nameList,
|
||||
StartTime: s.startTime,
|
||||
Error: errMsg,
|
||||
}
|
||||
if finished {
|
||||
info.FinishTime = now
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// GetSessionInfo returns the session information given the session id.
|
||||
func (m *Manager) GetSessionInfo(sessionID string) (*SessionInfo, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
if info, ok := m.failedSessionInfos[sessionID]; ok {
|
||||
return info, nil
|
||||
pubkey, _ := proof.PublicKey()
|
||||
// Only allow registered pub-key.
|
||||
if !m.existTaskIDForRoller(pubkey, proof.ID) {
|
||||
return false, fmt.Errorf("the roller or session id doesn't exist, pubkey: %s, ID: %s", pubkey, proof.ID)
|
||||
}
|
||||
if s, ok := m.sessions[sessionID]; ok {
|
||||
return newSessionInfo(s, orm.ProvingTaskAssigned, "", false), nil
|
||||
|
||||
err := m.handleZkProof(pubkey, proof.ProofDetail)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return nil, fmt.Errorf("no such session, sessionID: %s", sessionID)
|
||||
defer m.freeTaskIDForRoller(pubkey, proof.ID)
|
||||
|
||||
log.Info("Received zk proof", "proof id", proof.ID, "result", true)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
96
coordinator/api_debug.go
Normal file
96
coordinator/api_debug.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package coordinator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"scroll-tech/database/orm"
|
||||
)
|
||||
|
||||
// RollerDebugAPI roller api interface in order go get debug message.
|
||||
type RollerDebugAPI interface {
|
||||
// ListRollers returns all live rollers
|
||||
ListRollers() ([]*RollerInfo, error)
|
||||
// GetSessionInfo returns the session information given the session id.
|
||||
GetSessionInfo(sessionID string) (*SessionInfo, error)
|
||||
}
|
||||
|
||||
// RollerInfo records the roller name, pub key and active session info (id, start time).
|
||||
type RollerInfo struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
PublicKey string `json:"public_key"`
|
||||
ActiveSession string `json:"active_session,omitempty"`
|
||||
ActiveSessionStartTime time.Time `json:"active_session_start_time"` // latest proof start time.
|
||||
}
|
||||
|
||||
// SessionInfo records proof create or proof verify failed session.
|
||||
type SessionInfo struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
FinishTime time.Time `json:"finish_time,omitempty"` // set to 0 if not finished
|
||||
AssignedRollers []string `json:"assigned_rollers,omitempty"` // roller name list
|
||||
Error string `json:"error,omitempty"` // empty string if no error encountered
|
||||
}
|
||||
|
||||
// ListRollers returns all live rollers.
|
||||
func (m *Manager) ListRollers() ([]*RollerInfo, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
var res []*RollerInfo
|
||||
for _, pk := range m.rollerPool.Keys() {
|
||||
node, exist := m.rollerPool.Get(pk)
|
||||
if !exist {
|
||||
continue
|
||||
}
|
||||
roller := node.(*rollerNode)
|
||||
info := &RollerInfo{
|
||||
Name: roller.Name,
|
||||
Version: roller.Version,
|
||||
PublicKey: pk,
|
||||
}
|
||||
for id, sess := range m.sessions {
|
||||
if _, ok := sess.info.Rollers[pk]; ok {
|
||||
info.ActiveSessionStartTime = time.Unix(sess.info.StartTimestamp, 0)
|
||||
info.ActiveSession = id
|
||||
break
|
||||
}
|
||||
}
|
||||
res = append(res, info)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func newSessionInfo(sess *session, status orm.ProvingStatus, errMsg string, finished bool) *SessionInfo {
|
||||
now := time.Now()
|
||||
var nameList []string
|
||||
for pk := range sess.info.Rollers {
|
||||
nameList = append(nameList, sess.info.Rollers[pk].Name)
|
||||
}
|
||||
info := SessionInfo{
|
||||
ID: sess.info.ID,
|
||||
Status: status.String(),
|
||||
AssignedRollers: nameList,
|
||||
StartTime: time.Unix(sess.info.StartTimestamp, 0),
|
||||
Error: errMsg,
|
||||
}
|
||||
if finished {
|
||||
info.FinishTime = now
|
||||
}
|
||||
return &info
|
||||
}
|
||||
|
||||
// GetSessionInfo returns the session information given the session id.
|
||||
func (m *Manager) GetSessionInfo(sessionID string) (*SessionInfo, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
if info, ok := m.failedSessionInfos[sessionID]; ok {
|
||||
return info, nil
|
||||
}
|
||||
if s, ok := m.sessions[sessionID]; ok {
|
||||
return newSessionInfo(s, orm.ProvingTaskAssigned, "", false), nil
|
||||
}
|
||||
return nil, fmt.Errorf("no such session, sessionID: %s", sessionID)
|
||||
}
|
||||
6
coordinator/assets/agg_proof
Normal file
6
coordinator/assets/agg_proof
Normal file
File diff suppressed because one or more lines are too long
BIN
coordinator/assets/agg_vk
Normal file
BIN
coordinator/assets/agg_vk
Normal file
Binary file not shown.
27
coordinator/client/api.go
Normal file
27
coordinator/client/api.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
)
|
||||
|
||||
// RequestToken generates token for roller
|
||||
func (c *Client) RequestToken(ctx context.Context, authMsg *message.AuthMsg) (string, error) {
|
||||
var token string
|
||||
err := c.client.CallContext(ctx, &token, "roller_requestToken", authMsg)
|
||||
return token, err
|
||||
}
|
||||
|
||||
// RegisterAndSubscribe subscribe roller and register, verified by sign data.
|
||||
func (c *Client) RegisterAndSubscribe(ctx context.Context, taskCh chan *message.TaskMsg, authMsg *message.AuthMsg) (ethereum.Subscription, error) {
|
||||
return c.client.Subscribe(ctx, "roller", taskCh, "register", authMsg)
|
||||
}
|
||||
|
||||
// SubmitProof get proof from roller.
|
||||
func (c *Client) SubmitProof(ctx context.Context, proof *message.ProofMsg) (bool, error) {
|
||||
var ok bool
|
||||
return ok, c.client.CallContext(ctx, &ok, "roller_submitProof", proof)
|
||||
}
|
||||
31
coordinator/client/client.go
Normal file
31
coordinator/client/client.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
// Client defines typed wrappers for the Ethereum RPC API.
|
||||
type Client struct {
|
||||
client *rpc.Client
|
||||
}
|
||||
|
||||
// Dial connects a client to the given URL.
|
||||
func Dial(rawurl string) (*Client, error) {
|
||||
return DialContext(context.Background(), rawurl)
|
||||
}
|
||||
|
||||
// DialContext connects a client to the given URL with a given context.
|
||||
func DialContext(ctx context.Context, rawurl string) (*Client, error) {
|
||||
c, err := rpc.DialContext(ctx, rawurl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewClient(c), nil
|
||||
}
|
||||
|
||||
// NewClient creates a client that uses the given RPC client.
|
||||
func NewClient(c *rpc.Client) *Client {
|
||||
return &Client{client: c}
|
||||
}
|
||||
@@ -3,22 +3,20 @@ package main
|
||||
import "github.com/urfave/cli/v2"
|
||||
|
||||
var (
|
||||
verifierFlag = cli.StringFlag{
|
||||
Name: "verifier-socket-file",
|
||||
Usage: "The path of ipc-verifier socket file",
|
||||
Value: "/tmp/verifier.sock",
|
||||
verifierMockFlag = cli.BoolFlag{
|
||||
Name: "verifier.mock",
|
||||
Usage: "Mock the verifier",
|
||||
Value: false,
|
||||
}
|
||||
apiFlags = []cli.Flag{
|
||||
&wsPortFlag,
|
||||
// http flags
|
||||
&httpEnabledFlag,
|
||||
&httpListenAddrFlag,
|
||||
&httpPortFlag,
|
||||
}
|
||||
// wsPortFlag is websocket port
|
||||
wsPortFlag = cli.IntFlag{
|
||||
Name: "ws.port",
|
||||
Usage: "WS-RPC server listening port",
|
||||
Value: 9000,
|
||||
// ws flags
|
||||
&wsEnabledFlag,
|
||||
&wsListenAddrFlag,
|
||||
&wsPortFlag,
|
||||
}
|
||||
// httpEnabledFlag enable rpc server.
|
||||
httpEnabledFlag = cli.BoolFlag{
|
||||
@@ -38,4 +36,19 @@ var (
|
||||
Usage: "HTTP-RPC server listening port",
|
||||
Value: 8390,
|
||||
}
|
||||
wsEnabledFlag = cli.BoolFlag{
|
||||
Name: "ws",
|
||||
Usage: "Enable the WS-RPC server",
|
||||
}
|
||||
wsListenAddrFlag = cli.StringFlag{
|
||||
Name: "ws.addr",
|
||||
Usage: "WS-RPC server listening interface",
|
||||
Value: "localhost",
|
||||
}
|
||||
// websocket port
|
||||
wsPortFlag = cli.IntFlag{
|
||||
Name: "ws.port",
|
||||
Usage: "WS-RPC server listening port",
|
||||
Value: 8391,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"os/signal"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"scroll-tech/common/utils"
|
||||
@@ -27,16 +26,11 @@ func main() {
|
||||
app.Usage = "The Scroll L2 Coordinator"
|
||||
app.Version = version.Version
|
||||
app.Flags = append(app.Flags, utils.CommonFlags...)
|
||||
app.Flags = append(app.Flags, []cli.Flag{&verifierFlag}...)
|
||||
app.Flags = append(app.Flags, apiFlags...)
|
||||
app.Flags = append(app.Flags, &verifierMockFlag)
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
return utils.Setup(&utils.LogConfig{
|
||||
LogFile: ctx.String(utils.LogFileFlag.Name),
|
||||
LogJSONFormat: ctx.Bool(utils.LogJSONFormat.Name),
|
||||
LogDebug: ctx.Bool(utils.LogDebugFlag.Name),
|
||||
Verbosity: ctx.Int(utils.VerbosityFlag.Name),
|
||||
})
|
||||
return utils.LogSetup(ctx)
|
||||
}
|
||||
|
||||
// Run the coordinator.
|
||||
@@ -47,11 +41,8 @@ func main() {
|
||||
}
|
||||
|
||||
func applyConfig(ctx *cli.Context, cfg *config.Config) {
|
||||
if ctx.IsSet(wsPortFlag.Name) {
|
||||
cfg.RollerManagerConfig.Endpoint = fmt.Sprintf(":%d", ctx.Int(wsPortFlag.Name))
|
||||
}
|
||||
if ctx.IsSet(verifierFlag.Name) {
|
||||
cfg.RollerManagerConfig.VerifierEndpoint = ctx.String(verifierFlag.Name)
|
||||
if ctx.IsSet(verifierMockFlag.Name) {
|
||||
cfg.RollerManagerConfig.Verifier = &config.VerifierConfig{MockMode: ctx.Bool(verifierMockFlag.Name)}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,27 +76,20 @@ func action(ctx *cli.Context) error {
|
||||
|
||||
// Start all modules.
|
||||
if err = rollerManager.Start(); err != nil {
|
||||
log.Crit("couldn't start roller manager", "error", err)
|
||||
log.Crit("couldn't start coordinator", "error", err)
|
||||
}
|
||||
|
||||
apis := rollerManager.APIs()
|
||||
// Register api and start rpc service.
|
||||
if ctx.Bool(httpEnabledFlag.Name) {
|
||||
srv := rpc.NewServer()
|
||||
apis := rollerManager.APIs()
|
||||
for _, api := range apis {
|
||||
if err = srv.RegisterName(api.Namespace, api.Service); err != nil {
|
||||
log.Crit("register namespace failed", "namespace", api.Namespace, "error", err)
|
||||
}
|
||||
}
|
||||
handler, addr, err := utils.StartHTTPEndpoint(
|
||||
fmt.Sprintf(
|
||||
"%s:%d",
|
||||
ctx.String(httpListenAddrFlag.Name),
|
||||
ctx.Int(httpPortFlag.Name)),
|
||||
rpc.DefaultHTTPTimeouts,
|
||||
srv)
|
||||
apis)
|
||||
if err != nil {
|
||||
log.Crit("Could not start RPC api", "error", err)
|
||||
log.Crit("Could not start HTTP api", "error", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = handler.Shutdown(ctx.Context)
|
||||
@@ -113,6 +97,22 @@ func action(ctx *cli.Context) error {
|
||||
}()
|
||||
log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%v/", addr))
|
||||
}
|
||||
if ctx.Bool(wsEnabledFlag.Name) {
|
||||
handler, addr, err := utils.StartWSEndpoint(
|
||||
fmt.Sprintf(
|
||||
"%s:%d",
|
||||
ctx.String(wsListenAddrFlag.Name),
|
||||
ctx.Int(wsPortFlag.Name)),
|
||||
apis)
|
||||
if err != nil {
|
||||
log.Crit("Could not start WS api", "error", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = handler.Shutdown(ctx.Context)
|
||||
log.Info("WS endpoint closed", "url", fmt.Sprintf("ws://%v/", addr))
|
||||
}()
|
||||
log.Info("WS endpoint opened", "url", fmt.Sprintf("ws://%v/", addr))
|
||||
}
|
||||
|
||||
// Catch CTRL-C to ensure a graceful shutdown.
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
{
|
||||
"roller_manager_config": {
|
||||
"endpoint": ":9000",
|
||||
"rollers_per_session": 1,
|
||||
"verifier_endpoint": "/tmp/verifier.sock",
|
||||
"collection_time": 180
|
||||
"collection_time": 180,
|
||||
"token_time_to_live": 60,
|
||||
"verifier": {
|
||||
"mock_mode": true,
|
||||
"params_path": "",
|
||||
"agg_vk_path": ""
|
||||
}
|
||||
},
|
||||
"db_config": {
|
||||
"driver_name": "postgres",
|
||||
|
||||
@@ -14,16 +14,16 @@ import (
|
||||
|
||||
// RollerManagerConfig loads sequencer configuration items.
|
||||
type RollerManagerConfig struct {
|
||||
// Endpoint to set websocket server up on.
|
||||
Endpoint string `json:"endpoint"`
|
||||
// asc or desc (default: asc)
|
||||
OrderSession string `json:"order_session,omitempty"`
|
||||
// The amount of rollers to pick per proof generation session.
|
||||
RollersPerSession uint8 `json:"rollers_per_session"`
|
||||
// Unix socket endpoint to which we send proofs to be verified.
|
||||
VerifierEndpoint string `json:"verifier_endpoint,omitempty"`
|
||||
// Zk verifier config.
|
||||
Verifier *VerifierConfig `json:"verifier,omitempty"`
|
||||
// Proof collection time (in minutes).
|
||||
CollectionTime int `json:"collection_time"`
|
||||
// Token time to live (in seconds)
|
||||
TokenTimeToLive int `json:"token_time_to_live"`
|
||||
}
|
||||
|
||||
// Config load configuration items.
|
||||
@@ -32,6 +32,13 @@ type Config struct {
|
||||
DBConfig *db_config.DBConfig `json:"db_config"`
|
||||
}
|
||||
|
||||
// VerifierConfig load zk verifier config.
|
||||
type VerifierConfig struct {
|
||||
MockMode bool `json:"mock_mode"`
|
||||
ParamsPath string `json:"params_path"`
|
||||
AggVkPath string `json:"agg_vk_path"`
|
||||
}
|
||||
|
||||
// NewConfig returns a new instance of Config.
|
||||
func NewConfig(file string) (*Config, error) {
|
||||
buf, err := os.ReadFile(filepath.Clean(file))
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package coordinator
|
||||
|
||||
import (
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
)
|
||||
|
||||
// A thread-safe wrapper for a connection list.
|
||||
type conns struct {
|
||||
cm cmap.ConcurrentMap
|
||||
}
|
||||
|
||||
func newConns() *conns {
|
||||
return &conns{
|
||||
cm: cmap.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conns) add(conn *Roller) {
|
||||
hexPk := conn.AuthMsg.Identity.PublicKey
|
||||
_ = c.cm.Upsert(hexPk, conn, swapFn)
|
||||
}
|
||||
|
||||
func swapFn(exists bool, valueInMap interface{}, newValue interface{}) interface{} {
|
||||
// If the roller already exists, close its connection.
|
||||
if exists {
|
||||
_ = valueInMap.(*Roller).ws.Close()
|
||||
}
|
||||
|
||||
return newValue
|
||||
}
|
||||
|
||||
func (c *conns) get(pk string) *Roller {
|
||||
roller, ok := c.cm.Get(pk)
|
||||
if ok {
|
||||
return roller.(*Roller)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conns) delete(conn *Roller) {
|
||||
if err := conn.close(); err != nil {
|
||||
log.Error("failed to close ws handler", "name", conn.AuthMsg.Identity.Name, "error", err)
|
||||
}
|
||||
hexPk := conn.AuthMsg.Identity.PublicKey
|
||||
_ = c.cm.RemoveCb(hexPk, removeFn)
|
||||
}
|
||||
|
||||
func removeFn(key string, v interface{}, exists bool) bool {
|
||||
if exists {
|
||||
_ = v.(*Roller).ws.Close()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *conns) clear() {
|
||||
for tuple := range c.cm.IterBuffered() {
|
||||
c.delete(tuple.Val.(*Roller))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conns) getAll() (allConns []*Roller) {
|
||||
for tuple := range c.cm.IterBuffered() {
|
||||
allConns = append(allConns, tuple.Val.(*Roller))
|
||||
}
|
||||
return allConns
|
||||
}
|
||||
@@ -3,32 +3,37 @@ module scroll-tech/coordinator
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/ethereum/go-ethereum v1.10.13
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
github.com/urfave/cli/v2 v2.10.2
|
||||
golang.org/x/sync v0.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.20.1-beta // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.23 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/scroll-tech/zktrie v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -70,10 +70,10 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f
|
||||
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -81,8 +81,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
@@ -91,8 +92,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
@@ -106,8 +108,9 @@ github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7j
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM=
|
||||
github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
@@ -180,8 +183,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@@ -194,8 +198,9 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 h1:dXZF+R9iI07DK49LHX/EKC3jTa0O2z+TUyvxjGK7V38=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 h1:ixWRiaqDULNyIDdOWz2QQJG5t4PpNHkQk2P6GV94cok=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
|
||||
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
|
||||
@@ -233,8 +238,9 @@ github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH6
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -288,11 +294,14 @@ github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mo
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
|
||||
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
|
||||
github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -315,9 +324,13 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
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/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6 h1:o0Gq2d8nus6x82apluA5RJwjlOca7LIlpAfxlyvQvxs=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6/go.mod h1:jurIpDQ0hqtp9//xxeWzr8X9KMP/+TYn+vz3K1wZrv0=
|
||||
github.com/scroll-tech/zktrie v0.3.0 h1:c0GRNELUyAtyuiwllQKT1XjNbs7NRGfguKouiyLfFNY=
|
||||
@@ -328,7 +341,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -360,13 +372,16 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y=
|
||||
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@@ -388,8 +403,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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=
|
||||
@@ -458,6 +473,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -501,8 +518,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
||||
@@ -2,7 +2,6 @@ package coordinator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
mathrand "math/rand"
|
||||
@@ -10,11 +9,13 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
"github.com/patrickmn/go-cache"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
"github.com/scroll-tech/go-ethereum/rpc"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
|
||||
"scroll-tech/database"
|
||||
"scroll-tech/database/orm"
|
||||
|
||||
@@ -26,30 +27,15 @@ const (
|
||||
proofAndPkBufferSize = 10
|
||||
)
|
||||
|
||||
type rollerStatus int32
|
||||
|
||||
const (
|
||||
rollerAssigned rollerStatus = iota
|
||||
rollerProofValid
|
||||
rollerProofInvalid
|
||||
)
|
||||
|
||||
type rollerProofStatus struct {
|
||||
id string
|
||||
pk string
|
||||
status rollerStatus
|
||||
status orm.RollerProveStatus
|
||||
}
|
||||
|
||||
// Contains all the information on an ongoing proof generation session.
|
||||
type session struct {
|
||||
// session id
|
||||
id string
|
||||
// A list of all participating rollers and if they finished proof generation for this session.
|
||||
// The map key is a hexadecimal encoding of the roller public key, as byte slices
|
||||
// can not be compared explicitly.
|
||||
rollers map[string]rollerStatus
|
||||
roller_names map[string]string
|
||||
// session start time
|
||||
startTime time.Time
|
||||
info *orm.SessionInfo
|
||||
// finish channel is used to pass the public key of the rollers who finished proving process.
|
||||
finishChan chan rollerProofStatus
|
||||
}
|
||||
@@ -68,14 +54,15 @@ type Manager struct {
|
||||
|
||||
// The indicator whether the backend is running or not.
|
||||
running int32
|
||||
// The websocket server which holds the connections with active rollers.
|
||||
server *server
|
||||
|
||||
// A mutex guarding the boolean below.
|
||||
mu sync.RWMutex
|
||||
// A map containing all active proof generation sessions.
|
||||
sessions map[string]*session
|
||||
// A map containing proof failed or verify failed proof.
|
||||
rollerPool cmap.ConcurrentMap
|
||||
|
||||
// TODO: once put into use, should add to graceful restart.
|
||||
failedSessionInfos map[string]*SessionInfo
|
||||
|
||||
// A direct connection to the Halo2 verifier, used to verify
|
||||
@@ -84,30 +71,32 @@ type Manager struct {
|
||||
|
||||
// db interface
|
||||
orm database.OrmFactory
|
||||
|
||||
// Token cache
|
||||
tokenCache *cache.Cache
|
||||
// A mutex guarding registration
|
||||
registerMu sync.RWMutex
|
||||
}
|
||||
|
||||
// New returns a new instance of Manager. The instance will be not fully prepared,
|
||||
// and still needs to be finalized and ran by calling `manager.Start`.
|
||||
func New(ctx context.Context, cfg *config.RollerManagerConfig, orm database.OrmFactory) (*Manager, error) {
|
||||
var v *verifier.Verifier
|
||||
if cfg.VerifierEndpoint != "" {
|
||||
var err error
|
||||
v, err = verifier.NewVerifier(cfg.VerifierEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v, err := verifier.NewVerifier(cfg.Verifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Info("Start rollerManager successfully.")
|
||||
log.Info("Start coordinator successfully.")
|
||||
|
||||
return &Manager{
|
||||
ctx: ctx,
|
||||
cfg: cfg,
|
||||
server: newServer(cfg.Endpoint),
|
||||
rollerPool: cmap.New(),
|
||||
sessions: make(map[string]*session),
|
||||
failedSessionInfos: make(map[string]*SessionInfo),
|
||||
verifier: v,
|
||||
orm: orm,
|
||||
tokenCache: cache.New(time.Duration(cfg.TokenTimeToLive)*time.Second, 1*time.Hour),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -117,17 +106,8 @@ func (m *Manager) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// m.orm may be nil in scroll tests
|
||||
if m.orm != nil {
|
||||
// clean up assigned but not submitted task
|
||||
if err := m.orm.ResetProvingStatusFor(orm.ProvingTaskAssigned); err != nil {
|
||||
log.Error("fail to reset assigned tasks as unassigned")
|
||||
}
|
||||
}
|
||||
m.restorePrevSessions()
|
||||
|
||||
if err := m.server.start(); err != nil {
|
||||
return err
|
||||
}
|
||||
atomic.StoreInt32(&m.running, 1)
|
||||
|
||||
go m.Loop()
|
||||
@@ -140,12 +120,6 @@ func (m *Manager) Stop() {
|
||||
return
|
||||
}
|
||||
|
||||
// Stop accepting connections
|
||||
if err := m.server.stop(); err != nil {
|
||||
log.Error("Server shutdown failed", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
atomic.StoreInt32(&m.running, 0)
|
||||
}
|
||||
|
||||
@@ -167,14 +141,13 @@ func (m *Manager) Loop() {
|
||||
case <-tick.C:
|
||||
if len(tasks) == 0 && m.orm != nil {
|
||||
var err error
|
||||
numIdleRollers := m.GetNumberOfIdleRollers()
|
||||
// TODO: add cache
|
||||
if tasks, err = m.orm.GetBlockBatches(
|
||||
map[string]interface{}{"proving_status": orm.ProvingTaskUnassigned},
|
||||
fmt.Sprintf(
|
||||
"ORDER BY index %s LIMIT %d;",
|
||||
m.cfg.OrderSession,
|
||||
numIdleRollers,
|
||||
m.GetNumberOfIdleRollers(),
|
||||
),
|
||||
); err != nil {
|
||||
log.Error("failed to get unassigned proving tasks", "error", err)
|
||||
@@ -185,13 +158,6 @@ func (m *Manager) Loop() {
|
||||
for len(tasks) > 0 && m.StartProofGenerationSession(tasks[0]) {
|
||||
tasks = tasks[1:]
|
||||
}
|
||||
case msg := <-m.server.msgChan:
|
||||
if err := m.HandleMessage(msg.pk, msg.message); err != nil {
|
||||
log.Error(
|
||||
"could not handle message",
|
||||
"error", err,
|
||||
)
|
||||
}
|
||||
case <-m.ctx.Done():
|
||||
if m.ctx.Err() != nil {
|
||||
log.Error(
|
||||
@@ -204,61 +170,53 @@ func (m *Manager) Loop() {
|
||||
}
|
||||
}
|
||||
|
||||
// HandleMessage handle a message from a roller.
|
||||
func (m *Manager) HandleMessage(pk string, payload []byte) error {
|
||||
// Recover message
|
||||
msg := &message.Msg{}
|
||||
if err := json.Unmarshal(payload, msg); err != nil {
|
||||
return err
|
||||
func (m *Manager) restorePrevSessions() {
|
||||
// m.orm may be nil in scroll tests
|
||||
if m.orm == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case message.ErrorMsgType:
|
||||
// Just log it for now.
|
||||
log.Error("error message received from roller", "message", msg)
|
||||
// TODO: handle in m.failedSessionInfos
|
||||
return nil
|
||||
case message.RegisterMsgType:
|
||||
// We shouldn't get this message, as the sequencer should handle registering at the start
|
||||
// of the connection.
|
||||
return errors.New("attempted handshake at the wrong time")
|
||||
case message.TaskMsgType:
|
||||
// We shouldn't get this message, as the sequencer should always be the one to send it
|
||||
return errors.New("received illegal message")
|
||||
case message.ProofMsgType:
|
||||
return m.HandleZkProof(pk, msg.Payload)
|
||||
default:
|
||||
return fmt.Errorf("unrecognized message type %v", msg.Type)
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if ids, err := m.orm.GetAssignedBatchIDs(); err != nil {
|
||||
log.Error("failed to get assigned batch ids from db", "error", err)
|
||||
} else if prevSessions, err := m.orm.GetSessionInfosByIDs(ids); err != nil {
|
||||
log.Error("failed to recover roller session info from db", "error", err)
|
||||
} else {
|
||||
for _, v := range prevSessions {
|
||||
sess := &session{
|
||||
info: v,
|
||||
finishChan: make(chan rollerProofStatus, proofAndPkBufferSize),
|
||||
}
|
||||
m.sessions[sess.info.ID] = sess
|
||||
log.Info("Coordinator restart reload sessions", "ID", sess.info.ID, "sess", sess.info)
|
||||
go m.CollectProofs(sess.info.ID, sess)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleZkProof handle a ZkProof submitted from a roller.
|
||||
// For now only proving/verifying error will lead to setting status as skipped.
|
||||
// db/unmarshal errors will not because they are errors on the business logic side.
|
||||
func (m *Manager) HandleZkProof(pk string, payload []byte) error {
|
||||
func (m *Manager) handleZkProof(pk string, msg *message.ProofDetail) error {
|
||||
var dbErr error
|
||||
var success bool
|
||||
|
||||
msg := &message.ProofMsg{}
|
||||
if err := json.Unmarshal(payload, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Assess if the proof generation session for the given ID is still active.
|
||||
// We hold the read lock until the end of the function so that there is no
|
||||
// potential race for channel deletion.
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
s, ok := m.sessions[msg.ID]
|
||||
sess, ok := m.sessions[msg.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf("proof generation session for id %v does not exist", msg.ID)
|
||||
return fmt.Errorf("proof generation session for id %v does not existID", msg.ID)
|
||||
}
|
||||
proofTimeSec := uint64(time.Since(s.startTime).Seconds())
|
||||
proofTimeSec := uint64(time.Since(time.Unix(sess.info.StartTimestamp, 0)).Seconds())
|
||||
|
||||
// Ensure this roller is eligible to participate in the session.
|
||||
if status, ok := s.rollers[pk]; !ok {
|
||||
if roller, ok := sess.info.Rollers[pk]; !ok {
|
||||
return fmt.Errorf("roller %s is not eligible to partake in proof session %v", pk, msg.ID)
|
||||
} else if status == rollerProofValid {
|
||||
} else if roller.Status == orm.RollerProofValid {
|
||||
// In order to prevent DoS attacks, it is forbidden to repeatedly submit valid proofs.
|
||||
// TODO: Defend invalid proof resubmissions by one of the following two methods:
|
||||
// (i) slash the roller for each submission of invalid proof
|
||||
@@ -277,14 +235,12 @@ func (m *Manager) HandleZkProof(pk string, payload []byte) error {
|
||||
}
|
||||
}
|
||||
// set proof status
|
||||
var status rollerStatus
|
||||
status := orm.RollerProofInvalid
|
||||
if success && dbErr == nil {
|
||||
status = rollerProofValid
|
||||
} else {
|
||||
status = rollerProofInvalid
|
||||
status = orm.RollerProofValid
|
||||
}
|
||||
// notify the session that the roller finishes the proving process
|
||||
s.finishChan <- rollerProofStatus{pk, status}
|
||||
sess.finishChan <- rollerProofStatus{msg.ID, pk, status}
|
||||
}()
|
||||
|
||||
if msg.Status != message.StatusOk {
|
||||
@@ -293,7 +249,7 @@ func (m *Manager) HandleZkProof(pk string, payload []byte) error {
|
||||
log.Error("failed to update task status as failed", "error", dbErr)
|
||||
}
|
||||
// record the failed session.
|
||||
m.addFailedSession(s, msg.Error)
|
||||
m.addFailedSession(sess, msg.Error)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -307,30 +263,24 @@ func (m *Manager) HandleZkProof(pk string, payload []byte) error {
|
||||
return dbErr
|
||||
}
|
||||
|
||||
if m.verifier != nil {
|
||||
var err error
|
||||
tasks, err := m.orm.GetBlockBatches(map[string]interface{}{"id": msg.ID})
|
||||
if len(tasks) == 0 {
|
||||
if err != nil {
|
||||
log.Error("failed to get tasks", "error", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
success, err = m.verifier.VerifyProof(msg.Proof)
|
||||
var err error
|
||||
tasks, err := m.orm.GetBlockBatches(map[string]interface{}{"id": msg.ID})
|
||||
if len(tasks) == 0 {
|
||||
if err != nil {
|
||||
// record failed session.
|
||||
m.addFailedSession(s, err.Error())
|
||||
// TODO: this is only a temp workaround for testnet, we should return err in real cases
|
||||
success = false
|
||||
log.Error("Failed to verify zk proof", "proof id", msg.ID, "error", err)
|
||||
// TODO: Roller needs to be slashed if proof is invalid.
|
||||
} else {
|
||||
log.Info("Verify zk proof successfully", "verification result", success, "proof id", msg.ID)
|
||||
log.Error("failed to get tasks", "error", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
success, err = m.verifier.VerifyProof(msg.Proof)
|
||||
if err != nil {
|
||||
// record failed session.
|
||||
m.addFailedSession(sess, err.Error())
|
||||
// TODO: this is only a temp workaround for testnet, we should return err in real cases
|
||||
success = false
|
||||
log.Error("Failed to verify zk proof", "proof id", msg.ID, "error", err)
|
||||
// TODO: Roller needs to be slashed if proof is invalid.
|
||||
} else {
|
||||
success = true
|
||||
log.Info("Verifier disabled, VerifyProof skipped")
|
||||
log.Info("Verify zk proof successfully", "verification result", success, "proof id", msg.ID)
|
||||
}
|
||||
|
||||
@@ -352,7 +302,7 @@ func (m *Manager) HandleZkProof(pk string, payload []byte) error {
|
||||
}
|
||||
|
||||
// CollectProofs collects proofs corresponding to a proof generation session.
|
||||
func (m *Manager) CollectProofs(id string, s *session) {
|
||||
func (m *Manager) CollectProofs(id string, sess *session) {
|
||||
timer := time.NewTimer(time.Duration(m.cfg.CollectionTime) * time.Minute)
|
||||
|
||||
for {
|
||||
@@ -369,8 +319,8 @@ func (m *Manager) CollectProofs(id string, s *session) {
|
||||
// Pick a random winner.
|
||||
// First, round up the keys that actually sent in a valid proof.
|
||||
var participatingRollers []string
|
||||
for pk, status := range s.rollers {
|
||||
if status == rollerProofValid {
|
||||
for pk, roller := range sess.info.Rollers {
|
||||
if roller.Status == orm.RollerProofValid {
|
||||
participatingRollers = append(participatingRollers, pk)
|
||||
}
|
||||
}
|
||||
@@ -378,7 +328,7 @@ func (m *Manager) CollectProofs(id string, s *session) {
|
||||
if len(participatingRollers) == 0 {
|
||||
// record failed session.
|
||||
errMsg := "proof generation session ended without receiving any valid proofs"
|
||||
m.addFailedSession(s, errMsg)
|
||||
m.addFailedSession(sess, errMsg)
|
||||
log.Warn(errMsg, "session id", id)
|
||||
// Set status as skipped.
|
||||
// Note that this is only a workaround for testnet here.
|
||||
@@ -395,24 +345,27 @@ func (m *Manager) CollectProofs(id string, s *session) {
|
||||
_ = participatingRollers[randIndex]
|
||||
// TODO: reward winner
|
||||
return
|
||||
case ret := <-s.finishChan:
|
||||
case ret := <-sess.finishChan:
|
||||
m.mu.Lock()
|
||||
s.rollers[ret.pk] = ret.status
|
||||
sess.info.Rollers[ret.pk].Status = ret.status
|
||||
m.mu.Unlock()
|
||||
if err := m.orm.SetSessionInfo(sess.info); err != nil {
|
||||
log.Error("db set session info fail", "pk", ret.pk, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetRollerChan returns the channel in which newly created wrapped roller connections are sent.
|
||||
func (m *Manager) GetRollerChan() chan *Roller {
|
||||
return m.server.rollerChan
|
||||
}
|
||||
|
||||
// APIs collect API services.
|
||||
func (m *Manager) APIs() []rpc.API {
|
||||
return []rpc.API{
|
||||
{
|
||||
Namespace: "roller",
|
||||
Service: RollerAPI(m),
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "debug",
|
||||
Public: true,
|
||||
Service: RollerDebugAPI(m),
|
||||
},
|
||||
@@ -421,8 +374,8 @@ func (m *Manager) APIs() []rpc.API {
|
||||
|
||||
// StartProofGenerationSession starts a proof generation session
|
||||
func (m *Manager) StartProofGenerationSession(task *orm.BlockBatch) bool {
|
||||
roller := m.SelectRoller()
|
||||
if roller == nil || roller.isClosed() {
|
||||
roller := m.selectRoller()
|
||||
if roller == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -438,9 +391,6 @@ func (m *Manager) StartProofGenerationSession(task *orm.BlockBatch) bool {
|
||||
}
|
||||
}()
|
||||
|
||||
pk := roller.AuthMsg.Identity.PublicKey
|
||||
log.Info("roller is picked", "name", roller.AuthMsg.Identity.Name, "public_key", pk)
|
||||
|
||||
traces, err := m.orm.GetBlockTraces(map[string]interface{}{"batch_id": task.ID})
|
||||
if err != nil {
|
||||
log.Error(
|
||||
@@ -451,36 +401,31 @@ func (m *Manager) StartProofGenerationSession(task *orm.BlockBatch) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
msg, err := createTaskMsg(task.ID, traces)
|
||||
if err != nil {
|
||||
log.Error(
|
||||
"could not create block traces message",
|
||||
"error", err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
// TODO: use some compression?
|
||||
if err := roller.sendMessage(msg); err != nil {
|
||||
log.Error(
|
||||
"could not send traces message to roller",
|
||||
"error", err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
log.Info("roller is picked", "name", roller.Name, "public_key", roller.PublicKey)
|
||||
// send trace to roller
|
||||
roller.sendTask(task.ID, traces)
|
||||
|
||||
s := &session{
|
||||
id: task.ID,
|
||||
rollers: map[string]rollerStatus{
|
||||
pk: rollerAssigned,
|
||||
pk := roller.PublicKey
|
||||
sessionInfo := &orm.SessionInfo{
|
||||
ID: task.ID,
|
||||
Rollers: map[string]*orm.RollerStatus{
|
||||
pk: {
|
||||
PublicKey: pk,
|
||||
Name: roller.Name,
|
||||
Status: orm.RollerAssigned,
|
||||
},
|
||||
},
|
||||
roller_names: map[string]string{
|
||||
pk: roller.AuthMsg.Identity.Name,
|
||||
},
|
||||
startTime: time.Now(),
|
||||
finishChan: make(chan rollerProofStatus, proofAndPkBufferSize),
|
||||
StartTimestamp: time.Now().Unix(),
|
||||
}
|
||||
if err := m.orm.SetSessionInfo(sessionInfo); err != nil {
|
||||
log.Error("db set session info fail", "pk", pk, "error", err)
|
||||
}
|
||||
|
||||
// Create a proof generation session.
|
||||
s := &session{
|
||||
info: sessionInfo,
|
||||
finishChan: make(chan rollerProofStatus, proofAndPkBufferSize),
|
||||
}
|
||||
m.mu.Lock()
|
||||
m.sessions[task.ID] = s
|
||||
m.mu.Unlock()
|
||||
@@ -491,33 +436,6 @@ func (m *Manager) StartProofGenerationSession(task *orm.BlockBatch) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectRoller randomly get one idle roller.
|
||||
func (m *Manager) SelectRoller() *Roller {
|
||||
allRollers := m.server.conns.getAll()
|
||||
for len(allRollers) > 0 {
|
||||
idx := mathrand.Intn(len(allRollers))
|
||||
conn := allRollers[idx]
|
||||
pk := conn.AuthMsg.Identity.PublicKey
|
||||
if conn.isClosed() {
|
||||
log.Debug("roller is closed", "public_key", pk)
|
||||
// Delete closed connection.
|
||||
m.server.conns.delete(conn)
|
||||
// Delete the offline roller.
|
||||
allRollers[idx], allRollers = allRollers[0], allRollers[1:]
|
||||
continue
|
||||
}
|
||||
// Ensure the roller is not currently working on another session.
|
||||
if !m.IsRollerIdle(pk) {
|
||||
log.Debug("roller is busy", "public_key", pk)
|
||||
// Delete the busy roller.
|
||||
allRollers[idx], allRollers = allRollers[0], allRollers[1:]
|
||||
continue
|
||||
}
|
||||
return conn
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsRollerIdle determines whether this roller is idle.
|
||||
func (m *Manager) IsRollerIdle(hexPk string) bool {
|
||||
m.mu.RLock()
|
||||
@@ -525,8 +443,8 @@ func (m *Manager) IsRollerIdle(hexPk string) bool {
|
||||
// We need to iterate over all sessions because finished sessions will be deleted until the
|
||||
// timeout. So a busy roller could be marked as idle in a finished session.
|
||||
for _, sess := range m.sessions {
|
||||
for pk, status := range sess.rollers {
|
||||
if pk == hexPk && status == rollerAssigned {
|
||||
for pk, roller := range sess.info.Rollers {
|
||||
if pk == hexPk && roller.Status == orm.RollerAssigned {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -535,35 +453,16 @@ func (m *Manager) IsRollerIdle(hexPk string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetNumberOfIdleRollers returns the number of idle rollers in maintain list
|
||||
func (m *Manager) GetNumberOfIdleRollers() int {
|
||||
cnt := 0
|
||||
// m.server.conns doesn't have any lock
|
||||
for _, roller := range m.server.conns.getAll() {
|
||||
if m.IsRollerIdle(roller.AuthMsg.Identity.PublicKey) {
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
return cnt
|
||||
func (m *Manager) addFailedSession(sess *session, errMsg string) {
|
||||
m.failedSessionInfos[sess.info.ID] = newSessionInfo(sess, orm.ProvingTaskFailed, errMsg, true)
|
||||
}
|
||||
|
||||
func createTaskMsg(taskID string, traces []*types.BlockTrace) (*message.Msg, error) {
|
||||
idAndTraces := message.TaskMsg{
|
||||
ID: taskID,
|
||||
Traces: traces, // roller should sort traces by height
|
||||
// VerifyToken verifies pukey for token and expiration time
|
||||
func (m *Manager) VerifyToken(authMsg *message.AuthMsg) (bool, error) {
|
||||
pubkey, _ := authMsg.PublicKey()
|
||||
// GetValue returns nil if value is expired
|
||||
if token, ok := m.tokenCache.Get(pubkey); !ok || token != authMsg.Identity.Token {
|
||||
return false, errors.New("failed to find corresponding token")
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(idAndTraces)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &message.Msg{
|
||||
Type: message.TaskMsgType,
|
||||
Payload: payload,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) addFailedSession(s *session, errMsg string) {
|
||||
m.failedSessionInfos[s.id] = newSessionInfo(s, orm.ProvingTaskFailed, errMsg, true)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -3,358 +3,482 @@ package coordinator_test
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"scroll-tech/common/docker"
|
||||
"scroll-tech/common/message"
|
||||
"scroll-tech/common/utils"
|
||||
|
||||
"scroll-tech/database"
|
||||
"scroll-tech/database/migrate"
|
||||
"scroll-tech/database/orm"
|
||||
|
||||
"scroll-tech/coordinator"
|
||||
"scroll-tech/coordinator/config"
|
||||
client2 "scroll-tech/coordinator/client"
|
||||
|
||||
bridge_config "scroll-tech/bridge/config"
|
||||
|
||||
coordinator_config "scroll-tech/coordinator/config"
|
||||
)
|
||||
|
||||
const managerAddr = "localhost:8132"
|
||||
const managerPort = ":8132"
|
||||
const managerURL = "localhost:8132"
|
||||
const newManagerURL = "localhost:8133"
|
||||
|
||||
var (
|
||||
dbConfig = &database.DBConfig{
|
||||
DriverName: "postgres",
|
||||
}
|
||||
l2gethImg docker.ImgInstance
|
||||
dbImg docker.ImgInstance
|
||||
cfg *bridge_config.Config
|
||||
dbImg docker.ImgInstance
|
||||
rollerManager *coordinator.Manager
|
||||
handle *http.Server
|
||||
)
|
||||
|
||||
func setupEnv(t *testing.T) {
|
||||
// initialize l2geth docker image
|
||||
l2gethImg = docker.NewTestL2Docker(t)
|
||||
// initialize db docker image
|
||||
dbImg = docker.NewTestDBDocker(t, "postgres")
|
||||
dbConfig.DSN = dbImg.Endpoint()
|
||||
}
|
||||
|
||||
func TestFunction(t *testing.T) {
|
||||
// Setup
|
||||
setupEnv(t)
|
||||
|
||||
t.Run("TestHandshake", func(t *testing.T) {
|
||||
verifierEndpoint := setupMockVerifier(t)
|
||||
defer os.RemoveAll(verifierEndpoint)
|
||||
|
||||
rollerManager := setupRollerManager(t, verifierEndpoint, nil)
|
||||
defer rollerManager.Stop()
|
||||
|
||||
// Set up client
|
||||
u := url.URL{Scheme: "ws", Host: managerAddr, Path: "/"}
|
||||
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
assert.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
performHandshake(t, c)
|
||||
|
||||
// Roller manager should send a Websocket over the GetRollerChan
|
||||
select {
|
||||
case <-rollerManager.GetRollerChan():
|
||||
// Test succeeded
|
||||
case <-time.After(coordinator.HandshakeTimeout):
|
||||
t.Fail()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TestHandshakeTimeout", func(t *testing.T) {
|
||||
verifierEndpoint := setupMockVerifier(t)
|
||||
defer os.RemoveAll(verifierEndpoint)
|
||||
|
||||
rollerManager := setupRollerManager(t, verifierEndpoint, nil)
|
||||
defer rollerManager.Stop()
|
||||
|
||||
// Set up client
|
||||
u := url.URL{Scheme: "ws", Host: managerAddr, Path: "/"}
|
||||
|
||||
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
assert.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
// Wait for the handshake timeout to pass
|
||||
<-time.After(coordinator.HandshakeTimeout + 1*time.Second)
|
||||
|
||||
performHandshake(t, c)
|
||||
|
||||
// No websocket should be received
|
||||
select {
|
||||
case <-rollerManager.GetRollerChan():
|
||||
t.Fail()
|
||||
case <-time.After(1 * time.Second):
|
||||
// Test succeeded
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TestTwoConnections", func(t *testing.T) {
|
||||
verifierEndpoint := setupMockVerifier(t)
|
||||
defer os.RemoveAll(verifierEndpoint)
|
||||
|
||||
rollerManager := setupRollerManager(t, verifierEndpoint, nil)
|
||||
defer rollerManager.Stop()
|
||||
|
||||
// Set up and register 2 clients
|
||||
for i := 0; i < 2; i++ {
|
||||
u := url.URL{Scheme: "ws", Host: managerAddr, Path: "/"}
|
||||
|
||||
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
assert.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
performHandshake(t, c)
|
||||
|
||||
// Roller manager should send a Websocket over the GetRollerChan
|
||||
select {
|
||||
case <-rollerManager.GetRollerChan():
|
||||
// Test succeeded
|
||||
case <-time.After(coordinator.HandshakeTimeout):
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TestTriggerProofGenerationSession", func(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
db, err := database.NewOrmFactory(dbConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
|
||||
|
||||
// Test with two clients to make sure traces messages aren't duplicated
|
||||
// to rollers.
|
||||
numClients := uint8(2)
|
||||
verifierEndpoint := setupMockVerifier(t)
|
||||
defer os.RemoveAll(verifierEndpoint)
|
||||
|
||||
rollerManager := setupRollerManager(t, verifierEndpoint, db)
|
||||
defer rollerManager.Stop()
|
||||
|
||||
// Set up and register `numClients` clients
|
||||
conns := make([]*websocket.Conn, numClients)
|
||||
for i := 0; i < int(numClients); i++ {
|
||||
u := url.URL{Scheme: "ws", Host: managerAddr, Path: "/"}
|
||||
|
||||
var conn *websocket.Conn
|
||||
conn, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
assert.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
performHandshake(t, conn)
|
||||
|
||||
conns[i] = conn
|
||||
}
|
||||
|
||||
dbTx, err := db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
_, err = db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(1)}, &orm.BlockInfo{Number: uint64(1)}, "0f", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
_, err = db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(2)}, &orm.BlockInfo{Number: uint64(2)}, "0e", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
err = dbTx.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Both rollers should now receive a `BlockTraces` message and should send something back.
|
||||
for _, c := range conns {
|
||||
mt, payload, err := c.ReadMessage()
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, mt, websocket.BinaryMessage)
|
||||
|
||||
msg := &message.Msg{}
|
||||
assert.NoError(t, json.Unmarshal(payload, msg))
|
||||
assert.Equal(t, msg.Type, message.TaskMsgType)
|
||||
|
||||
traces := &message.TaskMsg{}
|
||||
assert.NoError(t, json.Unmarshal(payload, traces))
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TestIdleRollerSelection", func(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
db, err := database.NewOrmFactory(dbConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
|
||||
|
||||
// Test with two clients to make sure traces messages aren't duplicated
|
||||
// to rollers.
|
||||
numClients := uint8(2)
|
||||
verifierEndpoint := setupMockVerifier(t)
|
||||
defer os.RemoveAll(verifierEndpoint)
|
||||
|
||||
// Ensure only one roller is picked per session.
|
||||
rollerManager := setupRollerManager(t, verifierEndpoint, db)
|
||||
defer rollerManager.Stop()
|
||||
|
||||
// Set up and register `numClients` clients
|
||||
conns := make([]*websocket.Conn, numClients)
|
||||
for i := 0; i < int(numClients); i++ {
|
||||
u := url.URL{Scheme: "ws", Host: managerAddr, Path: "/"}
|
||||
|
||||
var conn *websocket.Conn
|
||||
conn, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
assert.NoError(t, err)
|
||||
conn.SetReadDeadline(time.Now().Add(100 * time.Second))
|
||||
|
||||
performHandshake(t, conn)
|
||||
time.Sleep(1 * time.Second)
|
||||
conns[i] = conn
|
||||
}
|
||||
defer func() {
|
||||
for _, conn := range conns {
|
||||
assert.NoError(t, conn.Close())
|
||||
}
|
||||
}()
|
||||
|
||||
assert.Equal(t, 2, rollerManager.GetNumberOfIdleRollers())
|
||||
|
||||
dbTx, err := db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
_, err = db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(1)}, &orm.BlockInfo{Number: uint64(1)}, "0f", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
err = dbTx.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sleep for a little bit, so that we can avoid prematurely fetching connections.
|
||||
// Test Second roller and check if we have all rollers busy
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
assert.Equal(t, 1, rollerManager.GetNumberOfIdleRollers())
|
||||
|
||||
dbTx, err = db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
_, err = db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(2)}, &orm.BlockInfo{Number: uint64(2)}, "0e", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
err = dbTx.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sleep for a little bit, so that we can avoid prematurely fetching connections.
|
||||
// Test Second roller and check if we have all rollers busy
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
for _, c := range conns {
|
||||
c.ReadMessage()
|
||||
}
|
||||
|
||||
assert.Equal(t, 0, rollerManager.GetNumberOfIdleRollers())
|
||||
})
|
||||
// Teardown
|
||||
t.Cleanup(func() {
|
||||
assert.NoError(t, l2gethImg.Stop())
|
||||
assert.NoError(t, dbImg.Stop())
|
||||
})
|
||||
}
|
||||
|
||||
func setupRollerManager(t *testing.T, verifierEndpoint string, orm database.OrmFactory) *coordinator.Manager {
|
||||
rollerManager, err := coordinator.New(context.Background(), &config.RollerManagerConfig{
|
||||
Endpoint: managerPort,
|
||||
RollersPerSession: 1,
|
||||
VerifierEndpoint: verifierEndpoint,
|
||||
CollectionTime: 1,
|
||||
}, orm)
|
||||
func setEnv(t *testing.T) error {
|
||||
var err error
|
||||
// Load config.
|
||||
cfg, err = bridge_config.NewConfig("../bridge/config.json")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create db container.
|
||||
dbImg = docker.NewTestDBDocker(t, cfg.DBConfig.DriverName)
|
||||
cfg.DBConfig.DSN = dbImg.Endpoint()
|
||||
// start roller manager
|
||||
rollerManager = setupRollerManager(t, cfg.DBConfig)
|
||||
|
||||
// start ws service
|
||||
handle, _, err = utils.StartWSEndpoint(managerURL, rollerManager.APIs())
|
||||
assert.NoError(t, err)
|
||||
return err
|
||||
}
|
||||
|
||||
func TestApis(t *testing.T) {
|
||||
// Set up the test environment.
|
||||
assert.True(t, assert.NoError(t, setEnv(t)), "failed to setup the test environment.")
|
||||
|
||||
t.Run("TestHandshake", testHandshake)
|
||||
t.Run("TestFailedHandshake", testFailedHandshake)
|
||||
t.Run("TestSeveralConnections", testSeveralConnections)
|
||||
t.Run("TestIdleRollerSelection", testIdleRollerSelection)
|
||||
t.Run("TestRollerReconnect", testRollerReconnect)
|
||||
t.Run("TestGracefulRestart", testGracefulRestart)
|
||||
|
||||
// Teardown
|
||||
t.Cleanup(func() {
|
||||
handle.Shutdown(context.Background())
|
||||
rollerManager.Stop()
|
||||
dbImg.Stop()
|
||||
})
|
||||
}
|
||||
|
||||
func testHandshake(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
roller := newMockRoller(t, "roller_test")
|
||||
defer roller.close()
|
||||
roller.connectToCoordinator(t, managerURL)
|
||||
|
||||
assert.Equal(t, 1, rollerManager.GetNumberOfIdleRollers())
|
||||
}
|
||||
|
||||
func testFailedHandshake(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
|
||||
// prepare
|
||||
name := "roller_test"
|
||||
wsURL := "ws://" + managerURL
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// Try to perform handshake without token
|
||||
// create a new ws connection
|
||||
client, err := client2.DialContext(ctx, wsURL)
|
||||
assert.NoError(t, err)
|
||||
// create private key
|
||||
privkey, err := crypto.GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg := &message.AuthMsg{
|
||||
Identity: &message.Identity{
|
||||
Name: name,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
},
|
||||
}
|
||||
assert.NoError(t, authMsg.Sign(privkey))
|
||||
taskCh := make(chan *message.TaskMsg, 4)
|
||||
_, err = client.RegisterAndSubscribe(ctx, taskCh, authMsg)
|
||||
assert.Error(t, err)
|
||||
|
||||
// Try to perform handshake with timeouted token
|
||||
// create a new ws connection
|
||||
client, err = client2.DialContext(ctx, wsURL)
|
||||
assert.NoError(t, err)
|
||||
// create private key
|
||||
privkey, err = crypto.GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg = &message.AuthMsg{
|
||||
Identity: &message.Identity{
|
||||
Name: name,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
},
|
||||
}
|
||||
assert.NoError(t, authMsg.Sign(privkey))
|
||||
token, err := client.RequestToken(ctx, authMsg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg.Identity.Token = token
|
||||
assert.NoError(t, authMsg.Sign(privkey))
|
||||
|
||||
tick := time.Tick(6 * time.Second)
|
||||
|
||||
<-tick
|
||||
taskCh = make(chan *message.TaskMsg, 4)
|
||||
_, err = client.RegisterAndSubscribe(ctx, taskCh, authMsg)
|
||||
assert.Error(t, err)
|
||||
|
||||
assert.Equal(t, 0, rollerManager.GetNumberOfIdleRollers())
|
||||
|
||||
close(stopCh)
|
||||
}
|
||||
|
||||
func testSeveralConnections(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
var (
|
||||
batch = 100
|
||||
eg = errgroup.Group{}
|
||||
rollers = make([]*mockRoller, batch)
|
||||
)
|
||||
for i := 0; i < batch; i++ {
|
||||
idx := i
|
||||
eg.Go(func() error {
|
||||
rollers[idx] = newMockRoller(t, "roller_test"+strconv.Itoa(idx))
|
||||
rollers[idx].connectToCoordinator(t, managerURL)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
assert.NoError(t, eg.Wait())
|
||||
|
||||
// check roller's idle connections
|
||||
assert.Equal(t, batch, rollerManager.GetNumberOfIdleRollers())
|
||||
|
||||
// close connection
|
||||
for i := 0; i < batch; i++ {
|
||||
rollers[i].close()
|
||||
}
|
||||
|
||||
var (
|
||||
tick = time.Tick(time.Second)
|
||||
tickStop = time.Tick(time.Second * 15)
|
||||
)
|
||||
for {
|
||||
select {
|
||||
case <-tick:
|
||||
if rollerManager.GetNumberOfIdleRollers() == 0 {
|
||||
return
|
||||
}
|
||||
case <-tickStop:
|
||||
t.Error("roller connect is blocked")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testIdleRollerSelection(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
// create mock rollers.
|
||||
batch := 20
|
||||
rollers := make([]*mockRoller, batch)
|
||||
for i := 0; i < batch; i++ {
|
||||
rollers[i] = newMockRoller(t, "roller_test"+strconv.Itoa(i))
|
||||
defer rollers[i].close()
|
||||
rollers[i].connectToCoordinator(t, managerURL)
|
||||
go rollers[i].waitTaskAndSendProof(t, 1, false)
|
||||
}
|
||||
assert.Equal(t, batch, rollerManager.GetNumberOfIdleRollers())
|
||||
|
||||
var ids = make([]string, 2)
|
||||
dbTx, err := l2db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
for i := range ids {
|
||||
ID, err := l2db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(i)}, &orm.BlockInfo{Number: uint64(i)}, "0f", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
ids[i] = ID
|
||||
}
|
||||
assert.NoError(t, dbTx.Commit())
|
||||
|
||||
// verify proof status
|
||||
var (
|
||||
tick = time.Tick(500 * time.Millisecond)
|
||||
tickStop = time.Tick(10 * time.Second)
|
||||
)
|
||||
for len(ids) > 0 {
|
||||
select {
|
||||
case <-tick:
|
||||
status, err := l2db.GetProvingStatusByID(ids[0])
|
||||
assert.NoError(t, err)
|
||||
if status == orm.ProvingTaskVerified {
|
||||
ids = ids[1:]
|
||||
}
|
||||
case <-tickStop:
|
||||
t.Error("failed to check proof status")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testRollerReconnect(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
var ids = make([]string, 1)
|
||||
dbTx, err := l2db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
for i := range ids {
|
||||
ID, err := l2db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(i)}, &orm.BlockInfo{Number: uint64(i)}, "0f", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
ids[i] = ID
|
||||
}
|
||||
assert.NoError(t, dbTx.Commit())
|
||||
|
||||
// create mock roller
|
||||
roller := newMockRoller(t, "roller_test")
|
||||
defer roller.close()
|
||||
roller.connectToCoordinator(t, managerURL)
|
||||
go roller.waitTaskAndSendProof(t, 1, true)
|
||||
|
||||
// verify proof status
|
||||
var (
|
||||
tick = time.Tick(500 * time.Millisecond)
|
||||
tickStop = time.Tick(15 * time.Second)
|
||||
)
|
||||
for len(ids) > 0 {
|
||||
select {
|
||||
case <-tick:
|
||||
status, err := l2db.GetProvingStatusByID(ids[0])
|
||||
assert.NoError(t, err)
|
||||
if status == orm.ProvingTaskVerified {
|
||||
ids = ids[1:]
|
||||
}
|
||||
case <-tickStop:
|
||||
t.Error("failed to check proof status")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testGracefulRestart(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
||||
defer l2db.Close()
|
||||
|
||||
var ids = make([]string, 1)
|
||||
dbTx, err := l2db.Beginx()
|
||||
assert.NoError(t, err)
|
||||
for i := range ids {
|
||||
ids[i], err = l2db.NewBatchInDBTx(dbTx, &orm.BlockInfo{Number: uint64(i)}, &orm.BlockInfo{Number: uint64(i)}, "0f", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.NoError(t, dbTx.Commit())
|
||||
|
||||
// create mock roller
|
||||
roller := newMockRoller(t, "roller_test")
|
||||
roller.connectToCoordinator(t, managerURL)
|
||||
|
||||
// wait 5 seconds, coordinator restarts before roller submits proof
|
||||
go roller.waitTaskAndSendProof(t, 5, true)
|
||||
|
||||
// wait for coordinator to dispatch task
|
||||
<-time.After(3 * time.Second)
|
||||
|
||||
// the coordinator will delete the roller if the subscription is closed.
|
||||
roller.close()
|
||||
|
||||
// start new roller manager && ws service
|
||||
newRollerManager := setupRollerManager(t, cfg.DBConfig)
|
||||
handle, _, err = utils.StartWSEndpoint(newManagerURL, newRollerManager.APIs())
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
newRollerManager.Stop()
|
||||
handle.Shutdown(context.Background())
|
||||
}()
|
||||
|
||||
for i := range ids {
|
||||
_, err = newRollerManager.GetSessionInfo(ids[i])
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// will overwrite the roller client for `SubmitProof`
|
||||
roller.connectToCoordinator(t, newManagerURL)
|
||||
defer roller.close()
|
||||
|
||||
// at this point, roller haven't submitted
|
||||
status, err := l2db.GetProvingStatusByID(ids[0])
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, orm.ProvingTaskAssigned, status)
|
||||
|
||||
// verify proof status
|
||||
var (
|
||||
tick = time.Tick(500 * time.Millisecond)
|
||||
tickStop = time.Tick(15 * time.Second)
|
||||
)
|
||||
for len(ids) > 0 {
|
||||
select {
|
||||
case <-tick:
|
||||
// this proves that the roller submits to the new coordinator,
|
||||
// because the roller client for `submitProof` has been overwritten
|
||||
status, err := l2db.GetProvingStatusByID(ids[0])
|
||||
assert.NoError(t, err)
|
||||
if status == orm.ProvingTaskVerified {
|
||||
ids = ids[1:]
|
||||
}
|
||||
|
||||
case <-tickStop:
|
||||
t.Error("failed to check proof status")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setupRollerManager(t *testing.T, dbCfg *database.DBConfig) *coordinator.Manager {
|
||||
// Get db handler.
|
||||
db, err := database.NewOrmFactory(dbCfg)
|
||||
assert.True(t, assert.NoError(t, err), "failed to get db handler.")
|
||||
|
||||
rollerManager, err := coordinator.New(context.Background(), &coordinator_config.RollerManagerConfig{
|
||||
RollersPerSession: 1,
|
||||
Verifier: &coordinator_config.VerifierConfig{MockMode: true},
|
||||
CollectionTime: 1,
|
||||
TokenTimeToLive: 5,
|
||||
}, db)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, rollerManager.Start())
|
||||
|
||||
return rollerManager
|
||||
}
|
||||
|
||||
// performHandshake sets up a websocket client to connect to the roller manager.
|
||||
func performHandshake(t *testing.T, c *websocket.Conn) {
|
||||
// Try to perform handshake
|
||||
pk, sk := generateKeyPair()
|
||||
authMsg := &message.AuthMessage{
|
||||
Identity: message.Identity{
|
||||
Name: "testRoller",
|
||||
type mockRoller struct {
|
||||
rollerName string
|
||||
privKey *ecdsa.PrivateKey
|
||||
taskCh chan *message.TaskMsg
|
||||
sub ethereum.Subscription
|
||||
client *client2.Client
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
func newMockRoller(t *testing.T, rollerName string) *mockRoller {
|
||||
privKey, err := crypto.GenerateKey()
|
||||
assert.NoError(t, err)
|
||||
return &mockRoller{
|
||||
rollerName: rollerName,
|
||||
privKey: privKey,
|
||||
taskCh: make(chan *message.TaskMsg, 4)}
|
||||
}
|
||||
|
||||
// connectToCoordinator sets up a websocket client to connect to the roller manager.
|
||||
func (r *mockRoller) connectToCoordinator(t *testing.T, wsURL string) {
|
||||
// create a new ws connection
|
||||
var err error
|
||||
r.client, err = client2.Dial("ws://" + wsURL)
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg := &message.AuthMsg{
|
||||
Identity: &message.Identity{
|
||||
Name: r.rollerName,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
PublicKey: common.Bytes2Hex(pk),
|
||||
},
|
||||
Signature: "",
|
||||
}
|
||||
assert.NoError(t, authMsg.Sign(r.privKey))
|
||||
|
||||
hash, err := authMsg.Identity.Hash()
|
||||
token, err := r.client.RequestToken(context.Background(), authMsg)
|
||||
assert.NoError(t, err)
|
||||
sig, err := secp256k1.Sign(hash, sk)
|
||||
authMsg.Identity.Token = token
|
||||
|
||||
assert.NoError(t, authMsg.Sign(r.privKey))
|
||||
r.sub, err = r.client.RegisterAndSubscribe(context.Background(), r.taskCh, authMsg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
authMsg.Signature = common.Bytes2Hex(sig)
|
||||
|
||||
b, err := json.Marshal(authMsg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
msg := &message.Msg{
|
||||
Type: message.RegisterMsgType,
|
||||
Payload: b,
|
||||
}
|
||||
|
||||
b, err = json.Marshal(msg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, c.WriteMessage(websocket.BinaryMessage, b))
|
||||
}
|
||||
|
||||
func generateKeyPair() (pubkey, privkey []byte) {
|
||||
key, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pubkey = elliptic.Marshal(secp256k1.S256(), key.X, key.Y)
|
||||
|
||||
privkey = make([]byte, 32)
|
||||
blob := key.D.Bytes()
|
||||
copy(privkey[32-len(blob):], blob)
|
||||
|
||||
return pubkey, privkey
|
||||
}
|
||||
|
||||
// setupMockVerifier sets up a mocked verifier for a test case.
|
||||
func setupMockVerifier(t *testing.T) string {
|
||||
verifierEndpoint := "/tmp/" + strconv.Itoa(time.Now().Nanosecond()) + ".sock"
|
||||
|
||||
// Create and listen sock file.
|
||||
l, err := net.Listen("unix", verifierEndpoint)
|
||||
assert.NoError(t, err)
|
||||
r.stopCh = make(chan struct{})
|
||||
|
||||
go func() {
|
||||
conn, err := l.Accept()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Simply read all incoming messages and send a true boolean straight back.
|
||||
for {
|
||||
// Read length
|
||||
buf := make([]byte, 4)
|
||||
_, err = io.ReadFull(conn, buf)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Read message
|
||||
msgLength := binary.LittleEndian.Uint64(buf)
|
||||
buf = make([]byte, msgLength)
|
||||
_, err = io.ReadFull(conn, buf)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Return boolean
|
||||
buf = []byte{1}
|
||||
_, err = conn.Write(buf)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
<-r.stopCh
|
||||
r.sub.Unsubscribe()
|
||||
}()
|
||||
return verifierEndpoint
|
||||
}
|
||||
|
||||
// Wait for the proof task, after receiving the proof task, roller submits proof after proofTime secs.
|
||||
func (r *mockRoller) waitTaskAndSendProof(t *testing.T, proofTime time.Duration, reconnectBeforeSendProof bool) {
|
||||
for {
|
||||
task := <-r.taskCh
|
||||
// simulate proof time
|
||||
<-time.After(proofTime * time.Second)
|
||||
if reconnectBeforeSendProof {
|
||||
// simulating the case that the roller first disconnects and then reconnects to the coordinator
|
||||
// the Subscription and its `Err()` channel will be closed, and the coordinator will `freeRoller()`
|
||||
r.reconnetToCoordinator(t)
|
||||
}
|
||||
proof := &message.ProofMsg{
|
||||
ProofDetail: &message.ProofDetail{
|
||||
ID: task.ID,
|
||||
Status: message.StatusOk,
|
||||
Proof: &message.AggProof{},
|
||||
},
|
||||
}
|
||||
assert.NoError(t, proof.Sign(r.privKey))
|
||||
ok, err := r.client.SubmitProof(context.Background(), proof)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *mockRoller) reconnetToCoordinator(t *testing.T) {
|
||||
authMsg := &message.AuthMsg{
|
||||
Identity: &message.Identity{
|
||||
Name: r.rollerName,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
},
|
||||
}
|
||||
assert.NoError(t, authMsg.Sign(r.privKey))
|
||||
|
||||
token, err := r.client.RequestToken(context.Background(), authMsg)
|
||||
assert.NoError(t, err)
|
||||
authMsg.Identity.Token = token
|
||||
|
||||
assert.NoError(t, authMsg.Sign(r.privKey))
|
||||
r.sub, err = r.client.RegisterAndSubscribe(context.Background(), r.taskCh, authMsg)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func (r *mockRoller) close() {
|
||||
close(r.stopCh)
|
||||
}
|
||||
|
||||
134
coordinator/rollers.go
Normal file
134
coordinator/rollers.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package coordinator
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
|
||||
"scroll-tech/database/orm"
|
||||
)
|
||||
|
||||
// rollerNode records roller status and send task to connected roller.
|
||||
type rollerNode struct {
|
||||
// Roller name
|
||||
Name string
|
||||
// Roller public key
|
||||
PublicKey string
|
||||
// Roller version
|
||||
Version string
|
||||
|
||||
// task channel
|
||||
taskChan chan *message.TaskMsg
|
||||
// session id list which delivered to roller.
|
||||
TaskIDs cmap.ConcurrentMap
|
||||
|
||||
// Time of message creation
|
||||
registerTime time.Time
|
||||
}
|
||||
|
||||
func (r *rollerNode) sendTask(id string, traces []*types.BlockTrace) bool {
|
||||
select {
|
||||
case r.taskChan <- &message.TaskMsg{
|
||||
ID: id,
|
||||
Traces: traces,
|
||||
}:
|
||||
r.TaskIDs.Set(id, struct{}{})
|
||||
default:
|
||||
log.Warn("roller channel is full")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Manager) reloadRollerAssignedTasks(pubkey string) *cmap.ConcurrentMap {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
taskIDs := cmap.New()
|
||||
for id, sess := range m.sessions {
|
||||
for pk, roller := range sess.info.Rollers {
|
||||
if pk == pubkey && roller.Status == orm.RollerAssigned {
|
||||
taskIDs.Set(id, struct{}{})
|
||||
}
|
||||
}
|
||||
}
|
||||
return &taskIDs
|
||||
}
|
||||
|
||||
func (m *Manager) register(pubkey string, identity *message.Identity) (<-chan *message.TaskMsg, error) {
|
||||
node, ok := m.rollerPool.Get(pubkey)
|
||||
if !ok {
|
||||
taskIDs := m.reloadRollerAssignedTasks(pubkey)
|
||||
node = &rollerNode{
|
||||
Name: identity.Name,
|
||||
Version: identity.Version,
|
||||
PublicKey: pubkey,
|
||||
TaskIDs: *taskIDs,
|
||||
taskChan: make(chan *message.TaskMsg, 4),
|
||||
}
|
||||
m.rollerPool.Set(pubkey, node)
|
||||
}
|
||||
roller := node.(*rollerNode)
|
||||
// avoid reconnection too frequently.
|
||||
if time.Since(roller.registerTime) < 60 {
|
||||
return nil, fmt.Errorf("roller reconnect too frequently")
|
||||
}
|
||||
// update register time and status
|
||||
roller.registerTime = time.Now()
|
||||
|
||||
return roller.taskChan, nil
|
||||
}
|
||||
|
||||
func (m *Manager) freeRoller(pk string) {
|
||||
m.rollerPool.Pop(pk)
|
||||
}
|
||||
|
||||
func (m *Manager) existTaskIDForRoller(pk string, id string) bool {
|
||||
if node, ok := m.rollerPool.Get(pk); ok {
|
||||
r := node.(*rollerNode)
|
||||
return r.TaskIDs.Has(id)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Manager) freeTaskIDForRoller(pk string, id string) {
|
||||
if node, ok := m.rollerPool.Get(pk); ok {
|
||||
r := node.(*rollerNode)
|
||||
r.TaskIDs.Pop(id)
|
||||
}
|
||||
}
|
||||
|
||||
// GetNumberOfIdleRollers return the count of idle rollers.
|
||||
func (m *Manager) GetNumberOfIdleRollers() int {
|
||||
pubkeys := m.rollerPool.Keys()
|
||||
for i := 0; i < len(pubkeys); i++ {
|
||||
if val, ok := m.rollerPool.Get(pubkeys[i]); ok {
|
||||
r := val.(*rollerNode)
|
||||
if r.TaskIDs.Count() > 0 {
|
||||
pubkeys[i], pubkeys = pubkeys[len(pubkeys)-1], pubkeys[:len(pubkeys)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(pubkeys)
|
||||
}
|
||||
|
||||
func (m *Manager) selectRoller() *rollerNode {
|
||||
pubkeys := m.rollerPool.Keys()
|
||||
for len(pubkeys) > 0 {
|
||||
idx, _ := rand.Int(rand.Reader, big.NewInt(int64(len(pubkeys))))
|
||||
if val, ok := m.rollerPool.Get(pubkeys[idx.Int64()]); ok {
|
||||
r := val.(*rollerNode)
|
||||
if r.TaskIDs.Count() == 0 {
|
||||
return r
|
||||
}
|
||||
}
|
||||
pubkeys[idx.Int64()], pubkeys = pubkeys[0], pubkeys[1:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
package coordinator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
)
|
||||
|
||||
const (
|
||||
// HandshakeTimeout is a time limit for a handshake to succeed.
|
||||
HandshakeTimeout = 10 * time.Second
|
||||
|
||||
// The amount of time it's acceptable to wait for a pong message.
|
||||
pongWait = 60 * time.Second
|
||||
// The interval between which we send pings.
|
||||
pingWait = (pongWait / 10) * 9
|
||||
writeWait = 10 * time.Second
|
||||
|
||||
wsMessageSizeLimit = 150 * 1024 * 1024 // 150 MB
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{} // use default options
|
||||
|
||||
// Roller represents a websocket connection to a roller, and includes
|
||||
// the roller authentication, and the websocket connection to the roller.
|
||||
type Roller struct {
|
||||
AuthMsg *message.AuthMessage
|
||||
|
||||
// A mutex guarding the ws write methods.
|
||||
wMu sync.RWMutex
|
||||
ws *websocket.Conn
|
||||
|
||||
closed int64
|
||||
closeCh chan struct{}
|
||||
}
|
||||
|
||||
func (r *Roller) close() error {
|
||||
if r.isClosed() {
|
||||
return nil
|
||||
}
|
||||
atomic.StoreInt64(&r.closed, 1)
|
||||
close(r.closeCh)
|
||||
if err := r.ws.Close(); err != nil {
|
||||
log.Error("fail to close WS", "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Roller) isClosed() bool {
|
||||
return atomic.LoadInt64(&r.closed) != 0
|
||||
}
|
||||
|
||||
// A convenient struct to send over incoming messages coupled with their
|
||||
// associated roller pk to the roller manager.
|
||||
type messageAndPk struct {
|
||||
pk string
|
||||
message []byte
|
||||
}
|
||||
|
||||
// A websocket server, responsible for establishing connections with rollers,
|
||||
// and reading their messages, before passing them on to be handled by the roller manager.
|
||||
type server struct {
|
||||
rollerChan chan *Roller
|
||||
server *http.Server
|
||||
|
||||
// All live connections to the rollers in the network.
|
||||
conns *conns
|
||||
// Channel to send incoming messages to (goes to the roller manager).
|
||||
msgChan chan *messageAndPk
|
||||
}
|
||||
|
||||
func newServer(addr string) *server {
|
||||
s := &server{
|
||||
rollerChan: make(chan *Roller, 100),
|
||||
conns: newConns(),
|
||||
msgChan: make(chan *messageAndPk, 100),
|
||||
}
|
||||
|
||||
var srv http.Server
|
||||
s.server = &srv
|
||||
s.server.Addr = addr
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", s.wsHandler)
|
||||
s.server.Handler = mux
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) start() error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
var err error
|
||||
go func() {
|
||||
err = s.server.ListenAndServe()
|
||||
}()
|
||||
|
||||
<-ctx.Done()
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *server) stop() error {
|
||||
s.conns.clear()
|
||||
return s.server.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
func (s *server) wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Debug("Could not upgrade", "error", err)
|
||||
return
|
||||
}
|
||||
c.SetReadLimit(wsMessageSizeLimit)
|
||||
|
||||
// There will not be concurrent read/write on a connection when we handshake
|
||||
// at the very beginning, so there's no need to lock here.
|
||||
authMessage, err := s.handshake(c)
|
||||
if err != nil {
|
||||
log.Error("Could not complete handshake", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
roller := &Roller{
|
||||
AuthMsg: authMessage,
|
||||
ws: c,
|
||||
closeCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Overwrite existing connection.
|
||||
// We don't need to worry about a malicious roller faking its pubkey, because
|
||||
// we've checked `VerifySignature` in `handshake` above
|
||||
if s.conns.get(roller.AuthMsg.Identity.PublicKey) != nil {
|
||||
log.Warn("Roller attempted to connect more than once",
|
||||
"name", roller.AuthMsg.Identity.Name,
|
||||
"pk", roller.AuthMsg.Identity.PublicKey)
|
||||
}
|
||||
|
||||
// There will not be concurrent read/write on a connection when we
|
||||
// SetPingHandler/SetPongHandler at the very beginning, so there's no need
|
||||
// to lock for them. But we may still need to lock for the handlers.
|
||||
roller.ws.SetPingHandler(
|
||||
func(string) error {
|
||||
roller.wMu.Lock()
|
||||
defer roller.wMu.Unlock()
|
||||
return roller.ws.WriteMessage(websocket.PongMessage, nil)
|
||||
})
|
||||
roller.ws.SetPongHandler(
|
||||
func(string) error {
|
||||
return roller.ws.SetReadDeadline(time.Now().Add(pongWait))
|
||||
})
|
||||
s.conns.add(roller)
|
||||
go s.readLoop(roller)
|
||||
go s.pingLoop(roller)
|
||||
|
||||
// avoid being blocked
|
||||
if s.rollerChan != nil {
|
||||
select {
|
||||
case s.rollerChan <- roller:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) handshake(c *websocket.Conn) (*message.AuthMessage, error) {
|
||||
// Set up a timer so that we won't be left hanging by an unresponsive roller.
|
||||
t := time.AfterFunc(HandshakeTimeout, func() {
|
||||
_ = c.Close()
|
||||
})
|
||||
|
||||
// We expect an authentication message to come in from the roller.
|
||||
|
||||
payload, err := func(c *websocket.Conn) ([]byte, error) {
|
||||
for {
|
||||
mt, payload, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if mt == websocket.BinaryMessage {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
}(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read succeeded, cancel timer before we accidentally close the connection.
|
||||
t.Stop()
|
||||
|
||||
msg := &message.Msg{}
|
||||
if err = json.Unmarshal(payload, msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We should receive a Register message
|
||||
if msg.Type != message.RegisterMsgType {
|
||||
return nil, errors.New("got wrong handshake message, expected Register")
|
||||
}
|
||||
|
||||
authMsg := &message.AuthMessage{}
|
||||
if err = json.Unmarshal(msg.Payload, authMsg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify signature
|
||||
hash, err := authMsg.Identity.Hash()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !crypto.VerifySignature(common.FromHex(authMsg.Identity.PublicKey), hash, common.FromHex(authMsg.Signature)[:64]) {
|
||||
return nil, errors.New("signature verification failed")
|
||||
}
|
||||
log.Info("signature verification successfully", "roller name", authMsg.Identity.Name, "version", authMsg.Identity.Version)
|
||||
|
||||
return authMsg, nil
|
||||
}
|
||||
|
||||
func (s *server) readLoop(c *Roller) {
|
||||
defer s.conns.delete(c)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-c.closeCh:
|
||||
return
|
||||
default:
|
||||
if err := c.ws.SetReadDeadline(time.Now().Add(pongWait)); err != nil {
|
||||
log.Error("could not set read deadline", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
mt, msg, err := c.ws.ReadMessage()
|
||||
if err != nil {
|
||||
log.Error("could not read msg", "error", err, "name", c.AuthMsg.Identity.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if this msg needs to be handled manually.
|
||||
if mt == websocket.BinaryMessage {
|
||||
log.Trace("websocket msg received", "msg", msg)
|
||||
|
||||
s.msgChan <- &messageAndPk{
|
||||
pk: c.AuthMsg.Identity.PublicKey,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run a ping loop.
|
||||
func (s *server) pingLoop(c *Roller) {
|
||||
pingTicker := time.NewTicker(pingWait)
|
||||
defer pingTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-c.closeCh:
|
||||
return
|
||||
case <-pingTicker.C:
|
||||
c.wMu.Lock()
|
||||
|
||||
if err := c.ws.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
|
||||
log.Error("could not set write deadline", "error", err)
|
||||
c.wMu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.ws.WriteMessage(websocket.PingMessage, nil); err != nil {
|
||||
log.Error("could not send ping", "error", err)
|
||||
c.wMu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
c.wMu.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Roller) sendMessage(msg *message.Msg) error {
|
||||
b, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.wMu.Lock()
|
||||
defer r.wMu.Unlock()
|
||||
|
||||
if err := r.ws.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
|
||||
log.Error("could not set write deadline", "error", err)
|
||||
return err
|
||||
}
|
||||
return r.ws.WriteMessage(websocket.BinaryMessage, b)
|
||||
}
|
||||
@@ -1,49 +1,64 @@
|
||||
package verifier
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: ${SRCDIR}/lib/libzkp.a -lm -ldl
|
||||
#cgo gpu LDFLAGS: ${SRCDIR}/lib/libzkp.a -lm -ldl -lgmp -lstdc++ -lprocps -L/usr/local/cuda/lib64/ -lcudart
|
||||
#include <stdlib.h>
|
||||
#include "./lib/libzkp.h"
|
||||
*/
|
||||
import "C" //nolint:typecheck
|
||||
|
||||
import (
|
||||
"net"
|
||||
"encoding/json"
|
||||
"unsafe"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/coordinator/config"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
)
|
||||
|
||||
// Verifier represents a socket connection to a halo2 verifier.
|
||||
// Verifier represents a rust ffi to a halo2 verifier.
|
||||
type Verifier struct {
|
||||
conn net.Conn
|
||||
cfg *config.VerifierConfig
|
||||
}
|
||||
|
||||
// NewVerifier Sets up a connection with the Unix socket at `path`.
|
||||
func NewVerifier(path string) (*Verifier, error) {
|
||||
conn, err := net.Dial("unix", path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// NewVerifier Sets up a rust ffi to call verify.
|
||||
func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
|
||||
if cfg.MockMode {
|
||||
return &Verifier{cfg: cfg}, nil
|
||||
}
|
||||
paramsPathStr := C.CString(cfg.ParamsPath)
|
||||
aggVkPathStr := C.CString(cfg.AggVkPath)
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(paramsPathStr))
|
||||
C.free(unsafe.Pointer(aggVkPathStr))
|
||||
}()
|
||||
|
||||
return &Verifier{
|
||||
conn: conn,
|
||||
}, nil
|
||||
}
|
||||
C.init_verifier(paramsPathStr, aggVkPathStr)
|
||||
|
||||
// Stop stops the verifier and close the socket connection
|
||||
func (v *Verifier) Stop() error {
|
||||
return v.conn.Close()
|
||||
return &Verifier{cfg: cfg}, nil
|
||||
}
|
||||
|
||||
// VerifyProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
|
||||
func (v *Verifier) VerifyProof(proof *message.AggProof) (bool, error) {
|
||||
buf, err := proof.Marshal()
|
||||
if v.cfg.MockMode {
|
||||
log.Info("Verifier disabled, VerifyProof skipped")
|
||||
return true, nil
|
||||
|
||||
}
|
||||
buf, err := json.Marshal(proof)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, err := v.conn.Write(buf); err != nil {
|
||||
return false, err
|
||||
}
|
||||
aggProofStr := C.CString(string(buf))
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(aggProofStr))
|
||||
}()
|
||||
|
||||
// Read verified byte
|
||||
bs := make([]byte, 1)
|
||||
if _, err := v.conn.Read(bs); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return bs[0] != 0, nil
|
||||
log.Info("Start to verify proof ...")
|
||||
verified := C.verify_agg_proof(aggProofStr)
|
||||
return verified != 0, nil
|
||||
}
|
||||
|
||||
@@ -1,65 +1,39 @@
|
||||
//go:build ffi
|
||||
|
||||
package verifier_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"scroll-tech/common/message"
|
||||
|
||||
"scroll-tech/coordinator/config"
|
||||
"scroll-tech/coordinator/verifier"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// skipped due to verifier upgrade
|
||||
/*
|
||||
// This test assumes the IPC Verifier is running.
|
||||
func TestIPCComm(t *testing.T) {
|
||||
if os.Getenv("TEST_IPC") != "true" {
|
||||
return
|
||||
func TestFFI(t *testing.T) {
|
||||
as := assert.New(t)
|
||||
cfg := &config.VerifierConfig{
|
||||
MockMode: false,
|
||||
ParamsPath: "../assets/test_params",
|
||||
AggVkPath: "../assets/agg_vk",
|
||||
}
|
||||
v, err := verifier.NewVerifier(cfg)
|
||||
as.NoError(err)
|
||||
|
||||
assert := assert.New(t)
|
||||
verifier, err := verifier.NewVerifier("/tmp/Verifier.sock")
|
||||
assert.NoError(err)
|
||||
f, err := os.Open("../assets/agg_proof")
|
||||
as.NoError(err)
|
||||
byt, err := io.ReadAll(f)
|
||||
as.NoError(err)
|
||||
aggProof := &message.AggProof{}
|
||||
as.NoError(json.Unmarshal(byt, aggProof))
|
||||
|
||||
// Retrieve pre-generated proofs
|
||||
evmProof, err := ioutil.ReadFile("../assets/evm_proof")
|
||||
assert.NoError(err)
|
||||
stateProof, err := ioutil.ReadFile("../assets/state_proof")
|
||||
assert.NoError(err)
|
||||
|
||||
proof := &message.ZkProof{
|
||||
ID: 1,
|
||||
EvmProof: evmProof,
|
||||
StateProof: stateProof,
|
||||
}
|
||||
|
||||
traces := &types.BlockTrace{}
|
||||
|
||||
verified, err := verifier.VerifyProof(proof)
|
||||
assert.NoError(err)
|
||||
assert.True(verified)
|
||||
}
|
||||
*/
|
||||
|
||||
func TestVerifier(t *testing.T) {
|
||||
privkey, err := crypto.HexToECDSA("dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7")
|
||||
assert.NoError(t, err)
|
||||
|
||||
pubkey := crypto.CompressPubkey(&privkey.PublicKey)
|
||||
|
||||
msg := &message.Identity{
|
||||
Name: "scroll_roller",
|
||||
Timestamp: 1649663001,
|
||||
PublicKey: common.Bytes2Hex(pubkey),
|
||||
Version: "some_version",
|
||||
}
|
||||
hash, err := msg.Hash()
|
||||
assert.NoError(t, err)
|
||||
|
||||
sig, err := crypto.Sign(hash, privkey)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ok := crypto.VerifySignature(pubkey, hash, sig[:64])
|
||||
assert.Equal(t, true, ok)
|
||||
ok, err := v.VerifyProof(aggProof)
|
||||
as.NoError(err)
|
||||
as.True(ok)
|
||||
}
|
||||
|
||||
42
database/README.md
Normal file
42
database/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# DATABASE CLIENT
|
||||
|
||||
This repo contains the Scroll database client.
|
||||
|
||||
Database client will provide init, show version, rollback, check status services
|
||||
|
||||
## Build
|
||||
|
||||
``` bash
|
||||
make db_cli
|
||||
```
|
||||
|
||||
## Usage
|
||||
``` bash
|
||||
# Migrate
|
||||
db_cli migrate
|
||||
# Reset
|
||||
db_cli reset
|
||||
# Status
|
||||
db_cli status
|
||||
# Version
|
||||
db_cli version
|
||||
# RollBack
|
||||
db_cli rollback
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
## db config
|
||||
|
||||
* db settings in config
|
||||
|
||||
```bash
|
||||
# DB_DSN: db data source name
|
||||
export DB_DSN="postgres://admin:123456@localhost/test_db?sslmode=disable"
|
||||
# DB_DRIVER: db driver name
|
||||
export DB_DRIVER="postgres"
|
||||
```
|
||||
@@ -1,40 +0,0 @@
|
||||
package main
|
||||
|
||||
import "github.com/urfave/cli/v2"
|
||||
|
||||
var (
|
||||
commonFlags = []cli.Flag{
|
||||
&configFileFlag,
|
||||
&verbosityFlag,
|
||||
&logFileFlag,
|
||||
&logJSONFormat,
|
||||
&logDebugFlag,
|
||||
}
|
||||
// configFileFlag load json type config file.
|
||||
configFileFlag = cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "JSON configuration file",
|
||||
Value: "./config.json",
|
||||
}
|
||||
// verbosityFlag log level.
|
||||
verbosityFlag = cli.IntFlag{
|
||||
Name: "verbosity",
|
||||
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
|
||||
Value: 3,
|
||||
}
|
||||
// logFileFlag decides where the logger output is sent. If this flag is left
|
||||
// empty, it will log to stdout.
|
||||
logFileFlag = cli.StringFlag{
|
||||
Name: "log.file",
|
||||
Usage: "Tells the database where to write log entries",
|
||||
}
|
||||
logJSONFormat = cli.BoolFlag{
|
||||
Name: "log.json",
|
||||
Usage: "Tells the database whether log format is json or not",
|
||||
Value: true,
|
||||
}
|
||||
logDebugFlag = cli.BoolFlag{
|
||||
Name: "log.debug",
|
||||
Usage: "Prepends log messages with call-site location (file and line number)",
|
||||
}
|
||||
)
|
||||
@@ -16,15 +16,10 @@ func main() {
|
||||
app.Name = "db_cli"
|
||||
app.Usage = "The Scroll Database CLI"
|
||||
app.Version = version.Version
|
||||
app.Flags = append(app.Flags, commonFlags...)
|
||||
app.Flags = append(app.Flags, utils.CommonFlags...)
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
return utils.Setup(&utils.LogConfig{
|
||||
LogFile: ctx.String(logFileFlag.Name),
|
||||
LogJSONFormat: ctx.Bool(logJSONFormat.Name),
|
||||
LogDebug: ctx.Bool(logDebugFlag.Name),
|
||||
Verbosity: ctx.Int(verbosityFlag.Name),
|
||||
})
|
||||
return utils.LogSetup(ctx)
|
||||
}
|
||||
|
||||
app.Commands = []*cli.Command{
|
||||
@@ -33,7 +28,7 @@ func main() {
|
||||
Usage: "Clean and reset database.",
|
||||
Action: resetDB,
|
||||
Flags: []cli.Flag{
|
||||
&configFileFlag,
|
||||
&utils.ConfigFileFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -41,7 +36,7 @@ func main() {
|
||||
Usage: "Check migration status.",
|
||||
Action: checkDBStatus,
|
||||
Flags: []cli.Flag{
|
||||
&configFileFlag,
|
||||
&utils.ConfigFileFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -49,7 +44,7 @@ func main() {
|
||||
Usage: "Display the current database version.",
|
||||
Action: dbVersion,
|
||||
Flags: []cli.Flag{
|
||||
&configFileFlag,
|
||||
&utils.ConfigFileFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -57,7 +52,7 @@ func main() {
|
||||
Usage: "Migrate the database to the latest version.",
|
||||
Action: migrateDB,
|
||||
Flags: []cli.Flag{
|
||||
&configFileFlag,
|
||||
&utils.ConfigFileFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -65,7 +60,7 @@ func main() {
|
||||
Usage: "Roll back the database to a previous <version>. Rolls back a single migration if no version specified.",
|
||||
Action: rollbackDB,
|
||||
Flags: []cli.Flag{
|
||||
&configFileFlag,
|
||||
&utils.ConfigFileFlag,
|
||||
&cli.IntFlag{
|
||||
Name: "version",
|
||||
Usage: "Rollback to the specified version.",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"scroll-tech/common/utils"
|
||||
)
|
||||
|
||||
@@ -14,7 +15,7 @@ type DBConfig struct {
|
||||
DriverName string `json:"driver_name"`
|
||||
|
||||
MaxOpenNum int `json:"maxOpenNum" default:"200"`
|
||||
MaxIdleNUm int `json:"maxIdleNum" default:"20"`
|
||||
MaxIdleNum int `json:"maxIdleNum" default:"20"`
|
||||
}
|
||||
|
||||
// NewConfig returns a new instance of Config.
|
||||
|
||||
@@ -9,23 +9,27 @@ require (
|
||||
github.com/pressly/goose/v3 v3.7.0
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
github.com/urfave/cli/v2 v2.10.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.20.1-beta // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.13 // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.23 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 // indirect
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/scroll-tech/zktrie v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/tools v0.3.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -70,10 +70,10 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f
|
||||
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -81,8 +81,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
@@ -105,8 +106,9 @@ github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7j
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM=
|
||||
github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
@@ -195,8 +197,9 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12 h1:dXZF+R9iI07DK49LHX/EKC3jTa0O2z+TUyvxjGK7V38=
|
||||
github.com/iden3/go-iden3-crypto v0.0.12/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13 h1:ixWRiaqDULNyIDdOWz2QQJG5t4PpNHkQk2P6GV94cok=
|
||||
github.com/iden3/go-iden3-crypto v0.0.13/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
|
||||
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
|
||||
@@ -237,8 +240,9 @@ github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH6
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -302,6 +306,7 @@ github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHu
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -327,9 +332,13 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
|
||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
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/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6 h1:o0Gq2d8nus6x82apluA5RJwjlOca7LIlpAfxlyvQvxs=
|
||||
github.com/scroll-tech/go-ethereum v1.10.14-0.20221125025612-4ea77a7577c6/go.mod h1:jurIpDQ0hqtp9//xxeWzr8X9KMP/+TYn+vz3K1wZrv0=
|
||||
github.com/scroll-tech/zktrie v0.3.0 h1:c0GRNELUyAtyuiwllQKT1XjNbs7NRGfguKouiyLfFNY=
|
||||
@@ -340,7 +349,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -372,13 +380,16 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y=
|
||||
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@@ -400,8 +411,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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=
|
||||
@@ -430,7 +441,7 @@ 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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -514,8 +525,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -558,7 +569,8 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK
|
||||
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.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
|
||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
create table l1_message
|
||||
(
|
||||
nonce BIGINT NOT NULL,
|
||||
msg_hash VARCHAR NOT NULL,
|
||||
height BIGINT NOT NULL,
|
||||
sender VARCHAR NOT NULL,
|
||||
target VARCHAR NOT NULL,
|
||||
@@ -21,8 +22,11 @@ create table l1_message
|
||||
comment
|
||||
on column l1_message.status is 'undefined, pending, submitted, confirmed';
|
||||
|
||||
create unique index l1_message_layer1_hash_uindex
|
||||
on l1_message (layer1_hash);
|
||||
create unique index l1_message_hash_uindex
|
||||
on l1_message (msg_hash);
|
||||
|
||||
create unique index l1_message_nonce_uindex
|
||||
on l1_message (nonce);
|
||||
|
||||
create index l1_message_height_index
|
||||
on l1_message (height);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
create table l2_message
|
||||
(
|
||||
nonce BIGINT NOT NULL,
|
||||
msg_hash VARCHAR NOT NULL,
|
||||
height BIGINT NOT NULL,
|
||||
sender VARCHAR NOT NULL,
|
||||
target VARCHAR NOT NULL,
|
||||
@@ -22,8 +23,11 @@ create table l2_message
|
||||
comment
|
||||
on column l2_message.status is 'undefined, pending, submitted, confirmed';
|
||||
|
||||
create unique index l2_message_layer2_hash_uindex
|
||||
on l2_message (layer2_hash);
|
||||
create unique index l2_message_hash_uindex
|
||||
on l2_message (msg_hash);
|
||||
|
||||
create unique index l2_message_nonce_uindex
|
||||
on l2_message (nonce);
|
||||
|
||||
create index l2_message_height_index
|
||||
on l2_message (height);
|
||||
|
||||
18
database/migrate/migrations/00005_session_info.sql
Normal file
18
database/migrate/migrations/00005_session_info.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
create table session_info
|
||||
(
|
||||
id VARCHAR NOT NULL,
|
||||
rollers_info BYTEA NOT NULL
|
||||
);
|
||||
|
||||
create unique index session_info_id_uindex
|
||||
on session_info (id);
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
drop table if exists session_info;
|
||||
-- +goose StatementEnd
|
||||
@@ -260,7 +260,7 @@ func (o *blockBatchOrm) GetPendingBatches() ([]string, error) {
|
||||
}
|
||||
|
||||
func (o *blockBatchOrm) GetLatestFinalizedBatch() (*BlockBatch, error) {
|
||||
row := o.db.QueryRowx(`SELECT * FROM block_batch WHERE rollup_status = $1 ORDER BY index DESC;`, RollupFinalized)
|
||||
row := o.db.QueryRowx(`SELECT * FROM block_batch WHERE rollup_status = $1 OR rollup_status = $2 ORDER BY index DESC;`, RollupFinalized, RollupFinalizationSkipped)
|
||||
batch := &BlockBatch{}
|
||||
if err := row.StructScan(batch); err != nil {
|
||||
return nil, err
|
||||
@@ -300,6 +300,34 @@ func (o *blockBatchOrm) GetRollupStatus(id string) (RollupStatus, error) {
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func (o *blockBatchOrm) GetRollupStatusByIDList(ids []string) ([]RollupStatus, error) {
|
||||
if len(ids) == 0 {
|
||||
return make([]RollupStatus, 0), nil
|
||||
}
|
||||
|
||||
query, args, err := sqlx.In("SELECT rollup_status FROM block_batch WHERE id IN (?);", ids)
|
||||
if err != nil {
|
||||
return make([]RollupStatus, 0), err
|
||||
}
|
||||
// sqlx.In returns queries with the `?` bindvar, we can rebind it for our backend
|
||||
query = o.db.Rebind(query)
|
||||
|
||||
rows, err := o.db.Query(query, args...)
|
||||
|
||||
var statuses []RollupStatus
|
||||
for rows.Next() {
|
||||
var status RollupStatus
|
||||
if err = rows.Scan(&status); err != nil {
|
||||
break
|
||||
}
|
||||
statuses = append(statuses, status)
|
||||
}
|
||||
if err != nil {
|
||||
return statuses, err
|
||||
}
|
||||
return statuses, nil
|
||||
}
|
||||
|
||||
func (o *blockBatchOrm) UpdateRollupStatus(ctx context.Context, id string, status RollupStatus) error {
|
||||
switch status {
|
||||
case RollupCommitted:
|
||||
@@ -335,3 +363,21 @@ func (o *blockBatchOrm) UpdateFinalizeTxHashAndRollupStatus(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (o *blockBatchOrm) GetAssignedBatchIDs() ([]string, error) {
|
||||
rows, err := o.db.Queryx(`SELECT id FROM block_batch WHERE proving_status IN ($1, $2)`, ProvingTaskAssigned, ProvingTaskProved)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ids []string
|
||||
for rows.Next() {
|
||||
var id string
|
||||
if err = rows.Scan(&id); err != nil {
|
||||
break
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
return ids, rows.Close()
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/core/types"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
|
||||
"scroll-tech/common/utils"
|
||||
)
|
||||
|
||||
type blockTraceOrm struct {
|
||||
@@ -163,17 +165,17 @@ func (o *blockTraceOrm) InsertBlockTraces(ctx context.Context, blockTraces []*ty
|
||||
log.Error("failed to marshal blockTrace", "hash", hash, "err", err)
|
||||
return err
|
||||
}
|
||||
gas_cost := utils.ComputeTraceGasCost(trace)
|
||||
traceMaps[i] = map[string]interface{}{
|
||||
"number": number,
|
||||
"hash": hash,
|
||||
"parent_hash": trace.Header.ParentHash.String(),
|
||||
"trace": string(data),
|
||||
"tx_num": tx_num,
|
||||
"gas_used": trace.Header.GasUsed,
|
||||
"gas_used": gas_cost,
|
||||
"block_timestamp": mtime,
|
||||
}
|
||||
}
|
||||
|
||||
_, err := o.db.NamedExec(`INSERT INTO public.block_trace (number, hash, parent_hash, trace, tx_num, gas_used, block_timestamp) VALUES (:number, :hash, :parent_hash, :trace, :tx_num, :gas_used, :block_timestamp);`, traceMaps)
|
||||
if err != nil {
|
||||
log.Error("failed to insert blockTraces", "err", err)
|
||||
|
||||
@@ -24,11 +24,15 @@ const (
|
||||
|
||||
// MsgConfirmed represents the from_layer message status is confirmed
|
||||
MsgConfirmed
|
||||
|
||||
// MsgFailed represents the from_layer message status is failed
|
||||
MsgFailed
|
||||
)
|
||||
|
||||
// L1Message is structure of stored layer1 bridge message
|
||||
type L1Message struct {
|
||||
Nonce uint64 `json:"nonce" db:"nonce"`
|
||||
MsgHash string `json:"msg_hash" db:"msg_hash"`
|
||||
Height uint64 `json:"height" db:"height"`
|
||||
Sender string `json:"sender" db:"sender"`
|
||||
Value string `json:"value" db:"value"`
|
||||
@@ -44,6 +48,7 @@ type L1Message struct {
|
||||
// L2Message is structure of stored layer2 bridge message
|
||||
type L2Message struct {
|
||||
Nonce uint64 `json:"nonce" db:"nonce"`
|
||||
MsgHash string `json:"msg_hash" db:"msg_hash"`
|
||||
Height uint64 `json:"height" db:"height"`
|
||||
Sender string `json:"sender" db:"sender"`
|
||||
Value string `json:"value" db:"value"`
|
||||
@@ -67,6 +72,32 @@ type BlockInfo struct {
|
||||
BlockTimestamp uint64 `json:"block_timestamp" db:"block_timestamp"`
|
||||
}
|
||||
|
||||
// RollerProveStatus is the roller prove status of a block batch (session)
|
||||
type RollerProveStatus int32
|
||||
|
||||
const (
|
||||
// RollerAssigned indicates roller assigned but has not submitted proof
|
||||
RollerAssigned RollerProveStatus = iota
|
||||
// RollerProofValid indicates roller has submitted valid proof
|
||||
RollerProofValid
|
||||
// RollerProofInvalid indicates roller has submitted invalid proof
|
||||
RollerProofInvalid
|
||||
)
|
||||
|
||||
// RollerStatus is the roller name and roller prove status
|
||||
type RollerStatus struct {
|
||||
PublicKey string `json:"public_key"`
|
||||
Name string `json:"name"`
|
||||
Status RollerProveStatus `json:"status"`
|
||||
}
|
||||
|
||||
// SessionInfo is assigned rollers info of a block batch (session)
|
||||
type SessionInfo struct {
|
||||
ID string `json:"id"`
|
||||
Rollers map[string]*RollerStatus `json:"rollers"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}
|
||||
|
||||
// BlockTraceOrm block_trace operation interface
|
||||
type BlockTraceOrm interface {
|
||||
Exist(number uint64) (bool, error)
|
||||
@@ -81,6 +112,12 @@ type BlockTraceOrm interface {
|
||||
SetBatchIDForBlocksInDBTx(dbTx *sqlx.Tx, numbers []uint64, batchID string) error
|
||||
}
|
||||
|
||||
// SessionInfoOrm sessions info operation inte
|
||||
type SessionInfoOrm interface {
|
||||
GetSessionInfosByIDs(ids []string) ([]*SessionInfo, error)
|
||||
SetSessionInfo(rollersInfo *SessionInfo) error
|
||||
}
|
||||
|
||||
// BlockBatchOrm block_batch operation interface
|
||||
type BlockBatchOrm interface {
|
||||
GetBlockBatches(fields map[string]interface{}, args ...string) ([]*BlockBatch, error)
|
||||
@@ -94,39 +131,39 @@ type BlockBatchOrm interface {
|
||||
GetPendingBatches() ([]string, error)
|
||||
GetCommittedBatches() ([]string, error)
|
||||
GetRollupStatus(id string) (RollupStatus, error)
|
||||
GetRollupStatusByIDList(ids []string) ([]RollupStatus, error)
|
||||
GetLatestFinalizedBatch() (*BlockBatch, error)
|
||||
UpdateRollupStatus(ctx context.Context, id string, status RollupStatus) error
|
||||
UpdateCommitTxHashAndRollupStatus(ctx context.Context, id string, commit_tx_hash string, status RollupStatus) error
|
||||
UpdateFinalizeTxHashAndRollupStatus(ctx context.Context, id string, finalize_tx_hash string, status RollupStatus) error
|
||||
GetAssignedBatchIDs() ([]string, error)
|
||||
}
|
||||
|
||||
// L1MessageOrm is layer1 message db interface
|
||||
type L1MessageOrm interface {
|
||||
GetL1MessageByNonce(nonce uint64) (*L1Message, error)
|
||||
GetL1UnprocessedMessages() ([]*L1Message, error)
|
||||
GetL1MessageByMsgHash(msgHash string) (*L1Message, error)
|
||||
GetL1MessagesByStatus(status MsgStatus) ([]*L1Message, error)
|
||||
GetL1ProcessedNonce() (int64, error)
|
||||
SaveL1Messages(ctx context.Context, messages []*L1Message) error
|
||||
UpdateLayer2Hash(ctx context.Context, layer1Hash string, layer2Hash string) error
|
||||
UpdateLayer1Status(ctx context.Context, layer1Hash string, status MsgStatus) error
|
||||
UpdateLayer1StatusAndLayer2Hash(ctx context.Context, layer1Hash, layer2Hash string, status MsgStatus) error
|
||||
UpdateLayer2Hash(ctx context.Context, msgHash string, layer2Hash string) error
|
||||
UpdateLayer1Status(ctx context.Context, msgHash string, status MsgStatus) error
|
||||
UpdateLayer1StatusAndLayer2Hash(ctx context.Context, msgHash string, status MsgStatus, layer2Hash string) error
|
||||
GetLayer1LatestWatchedHeight() (int64, error)
|
||||
GetL1MessageByLayer1Hash(layer1Hash string) (*L1Message, error)
|
||||
}
|
||||
|
||||
// L2MessageOrm is layer2 message db interface
|
||||
type L2MessageOrm interface {
|
||||
GetL2MessageByNonce(nonce uint64) (*L2Message, error)
|
||||
GetL2MessageByMsgHash(msgHash string) (*L2Message, error)
|
||||
MessageProofExist(nonce uint64) (bool, error)
|
||||
GetMessageProofByNonce(nonce uint64) (string, error)
|
||||
GetL2UnprocessedMessages() ([]*L2Message, error)
|
||||
GetL2MessagesByStatus(status MsgStatus) ([]*L2Message, error)
|
||||
GetL2ProcessedNonce() (int64, error)
|
||||
SaveL2Messages(ctx context.Context, messages []*L2Message) error
|
||||
UpdateLayer1Hash(ctx context.Context, layer2Hash string, layer1Hash string) error
|
||||
UpdateLayer2Status(ctx context.Context, layer2Hash string, status MsgStatus) error
|
||||
GetL2MessageByLayer2Hash(layer2Hash string) (*L2Message, error)
|
||||
UpdateMessageProof(ctx context.Context, layer2Hash, proof string) error
|
||||
UpdateLayer1Hash(ctx context.Context, msgHash string, layer1Hash string) error
|
||||
UpdateLayer2Status(ctx context.Context, msgHash string, status MsgStatus) error
|
||||
UpdateLayer2StatusAndLayer1Hash(ctx context.Context, msgHash string, status MsgStatus, layer1Hash string) error
|
||||
UpdateMessageProof(ctx context.Context, nonce uint64, proof string) error
|
||||
GetLayer2LatestWatchedHeight() (int64, error)
|
||||
GetMessageProofByLayer2Hash(layer2Hash string) (string, error)
|
||||
MessageProofExistByLayer2Hash(layer2Hash string) (bool, error)
|
||||
UpdateLayer2StatusAndLayer1Hash(ctx context.Context, layer2Hash string, layer1Hash string, status MsgStatus) error
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ func NewL1MessageOrm(db *sqlx.DB) L1MessageOrm {
|
||||
return &l1MessageOrm{db: db}
|
||||
}
|
||||
|
||||
// GetL1MessageByLayer1Hash fetch message by nonce
|
||||
func (m *l1MessageOrm) GetL1MessageByLayer1Hash(layer1Hash string) (*L1Message, error) {
|
||||
// GetL1MessageByMsgHash fetch message by nonce
|
||||
func (m *l1MessageOrm) GetL1MessageByMsgHash(msgHash string) (*L1Message, error) {
|
||||
msg := L1Message{}
|
||||
|
||||
row := m.db.QueryRow(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE layer1_hash = $1`, layer1Hash)
|
||||
row := m.db.QueryRowx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE msg_hash = $1`, msgHash)
|
||||
|
||||
if err := row.Scan(&msg.Nonce, &msg.Height, &msg.Sender, &msg.Target, &msg.Value, &msg.Fee, &msg.GasLimit, &msg.Deadline, &msg.Calldata, &msg.Layer1Hash, &msg.Status); err != nil {
|
||||
if err := row.StructScan(&msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
@@ -36,17 +36,17 @@ func (m *l1MessageOrm) GetL1MessageByLayer1Hash(layer1Hash string) (*L1Message,
|
||||
func (m *l1MessageOrm) GetL1MessageByNonce(nonce uint64) (*L1Message, error) {
|
||||
msg := L1Message{}
|
||||
|
||||
row := m.db.QueryRow(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE nonce = $1`, nonce)
|
||||
row := m.db.QueryRowx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE nonce = $1`, nonce)
|
||||
|
||||
if err := row.Scan(&msg.Nonce, &msg.Height, &msg.Sender, &msg.Target, &msg.Value, &msg.Fee, &msg.GasLimit, &msg.Deadline, &msg.Calldata, &msg.Layer1Hash, &msg.Status); err != nil {
|
||||
if err := row.StructScan(&msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// GetL1UnprocessedMessages fetch list of unprocessed messages
|
||||
func (m *l1MessageOrm) GetL1UnprocessedMessages() ([]*L1Message, error) {
|
||||
rows, err := m.db.Queryx(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE status = $1 ORDER BY nonce ASC;`, MsgPending)
|
||||
// GetL1MessagesByStatus fetch list of unprocessed messages given msg status
|
||||
func (m *l1MessageOrm) GetL1MessagesByStatus(status MsgStatus) ([]*L1Message, error) {
|
||||
rows, err := m.db.Queryx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash, status FROM l1_message WHERE status = $1 ORDER BY nonce ASC;`, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,17 +72,19 @@ func (m *l1MessageOrm) GetL1UnprocessedMessages() ([]*L1Message, error) {
|
||||
func (m *l1MessageOrm) GetL1ProcessedNonce() (int64, error) {
|
||||
row := m.db.QueryRow(`SELECT MAX(nonce) FROM l1_message WHERE status = $1;`, MsgConfirmed)
|
||||
|
||||
var nonce int64
|
||||
err := row.Scan(&nonce)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
var nonce sql.NullInt64
|
||||
if err := row.Scan(&nonce); err != nil {
|
||||
if err == sql.ErrNoRows || !nonce.Valid {
|
||||
// no row means no message
|
||||
// since nonce starts with 0, return -1 as the processed nonce
|
||||
return -1, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return nonce, nil
|
||||
if nonce.Valid {
|
||||
return nonce.Int64, nil
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// SaveL1Messages batch save a list of layer1 messages
|
||||
@@ -91,6 +93,7 @@ func (m *l1MessageOrm) SaveL1Messages(ctx context.Context, messages []*L1Message
|
||||
for i, msg := range messages {
|
||||
messageMaps[i] = map[string]interface{}{
|
||||
"nonce": msg.Nonce,
|
||||
"msg_hash": msg.MsgHash,
|
||||
"height": msg.Height,
|
||||
"sender": msg.Sender,
|
||||
"target": msg.Target,
|
||||
@@ -102,7 +105,7 @@ func (m *l1MessageOrm) SaveL1Messages(ctx context.Context, messages []*L1Message
|
||||
"layer1_hash": msg.Layer1Hash,
|
||||
}
|
||||
}
|
||||
_, err := m.db.NamedExec(`INSERT INTO public.l1_message (nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash) VALUES (:nonce, :height, :sender, :target, :value, :fee, :gas_limit, :deadline, :calldata, :layer1_hash);`, messageMaps)
|
||||
_, err := m.db.NamedExec(`INSERT INTO public.l1_message (nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer1_hash) VALUES (:nonce, :msg_hash, :height, :sender, :target, :value, :fee, :gas_limit, :deadline, :calldata, :layer1_hash);`, messageMaps)
|
||||
if err != nil {
|
||||
nonces := make([]uint64, 0, len(messages))
|
||||
heights := make([]uint64, 0, len(messages))
|
||||
@@ -115,27 +118,27 @@ func (m *l1MessageOrm) SaveL1Messages(ctx context.Context, messages []*L1Message
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateLayer2Hash update corresponding layer2 hash given message nonce
|
||||
func (m *l1MessageOrm) UpdateLayer2Hash(ctx context.Context, layer1Hash string, layer2Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set layer2_hash = ? where layer1_hash = ?;"), layer2Hash, layer1Hash); err != nil {
|
||||
// UpdateLayer2Hash update corresponding layer2 hash, given message hash
|
||||
func (m *l1MessageOrm) UpdateLayer2Hash(ctx context.Context, msgHash, layer2Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set layer2_hash = ? where msg_hash = ?;"), layer2Hash, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLayer1Status updates message stauts
|
||||
func (m *l1MessageOrm) UpdateLayer1Status(ctx context.Context, layer1Hash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set status = ? where layer1_hash = ?;"), status, layer1Hash); err != nil {
|
||||
// UpdateLayer1Status updates message stauts, given message hash
|
||||
func (m *l1MessageOrm) UpdateLayer1Status(ctx context.Context, msgHash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set status = ? where msg_hash = ?;"), status, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLayer1StatusAndLayer2Hash updates message status and layer2 transaction hash
|
||||
func (m *l1MessageOrm) UpdateLayer1StatusAndLayer2Hash(ctx context.Context, layer1Hash, layer2Hash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set status = ?, layer2_hash = ? where layer1_hash = ?;"), status, layer2Hash, layer1Hash); err != nil {
|
||||
// UpdateLayer1StatusAndLayer2Hash updates message status and layer2 transaction hash, given message hash
|
||||
func (m *l1MessageOrm) UpdateLayer1StatusAndLayer2Hash(ctx context.Context, msgHash string, status MsgStatus, layer2Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l1_message set status = ?, layer2_hash = ? where msg_hash = ?;"), status, layer2Hash, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -148,12 +151,15 @@ func (m *l1MessageOrm) GetLayer1LatestWatchedHeight() (int64, error) {
|
||||
// But it will only be called at start, some redundancy is acceptable.
|
||||
row := m.db.QueryRow("SELECT MAX(height) FROM l1_message;")
|
||||
|
||||
var height int64
|
||||
var height sql.NullInt64
|
||||
if err := row.Scan(&height); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if err == sql.ErrNoRows || !height.Valid {
|
||||
return -1, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return height, nil
|
||||
if height.Valid {
|
||||
return height.Int64, nil
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
@@ -25,54 +25,35 @@ func NewL2MessageOrm(db *sqlx.DB) L2MessageOrm {
|
||||
func (m *layer2MessageOrm) GetL2MessageByNonce(nonce uint64) (*L2Message, error) {
|
||||
msg := L2Message{}
|
||||
|
||||
row := m.db.QueryRow(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash, status FROM l2_message WHERE nonce = $1`, nonce)
|
||||
if err := row.Scan(&msg.Nonce, &msg.Height, &msg.Sender, &msg.Target, &msg.Value, &msg.Fee, &msg.GasLimit, &msg.Deadline, &msg.Calldata, &msg.Layer2Hash, &msg.Status); err != nil {
|
||||
row := m.db.QueryRowx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash, status FROM l2_message WHERE nonce = $1`, nonce)
|
||||
if err := row.StructScan(&msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// GetL2MessageByLayer2Hash fetch message by layer2Hash
|
||||
func (m *layer2MessageOrm) GetL2MessageByLayer2Hash(layer2Hash string) (*L2Message, error) {
|
||||
// GetL2MessageByMsgHash fetch message by message hash
|
||||
func (m *layer2MessageOrm) GetL2MessageByMsgHash(msgHash string) (*L2Message, error) {
|
||||
msg := L2Message{}
|
||||
|
||||
row := m.db.QueryRow(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash, status FROM l2_message WHERE layer2_hash = $1`, layer2Hash)
|
||||
if err := row.Scan(&msg.Nonce, &msg.Height, &msg.Sender, &msg.Target, &msg.Value, &msg.Fee, &msg.GasLimit, &msg.Deadline, &msg.Calldata, &msg.Layer2Hash, &msg.Status); err != nil {
|
||||
row := m.db.QueryRowx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash, status FROM l2_message WHERE msg_hash = $1`, msgHash)
|
||||
if err := row.StructScan(&msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// GetMessageProofByLayer2Hash fetch message proof by layer2Hash
|
||||
func (m *layer2MessageOrm) GetMessageProofByLayer2Hash(layer2Hash string) (string, error) {
|
||||
row := m.db.QueryRow(`SELECT proof FROM l2_message WHERE layer2_hash = $1`, layer2Hash)
|
||||
var proof string
|
||||
if err := row.Scan(&proof); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
// MessageProofExistByLayer2Hash fetch message by layer2Hash
|
||||
func (m *layer2MessageOrm) MessageProofExistByLayer2Hash(layer2Hash string) (bool, error) {
|
||||
err := m.db.QueryRow(`SELECT layer2_hash FROM l2_message WHERE layer2_hash = $1 and proof IS NOT NULL`, layer2Hash).Scan(&layer2Hash)
|
||||
if err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetMessageProofByNonce fetch message by nonce
|
||||
func (m *layer2MessageOrm) GetMessageProofByNonce(nonce uint64) (string, error) {
|
||||
row := m.db.QueryRow(`SELECT proof FROM l2_message WHERE nonce = $1`, nonce)
|
||||
var proof string
|
||||
var proof sql.NullString
|
||||
if err := row.Scan(&proof); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return proof, nil
|
||||
if proof.Valid {
|
||||
return proof.String, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// MessageProofExist fetch message by nonce
|
||||
@@ -91,22 +72,24 @@ func (m *layer2MessageOrm) MessageProofExist(nonce uint64) (bool, error) {
|
||||
func (m *layer2MessageOrm) GetL2ProcessedNonce() (int64, error) {
|
||||
row := m.db.QueryRow(`SELECT MAX(nonce) FROM l2_message WHERE status = $1;`, MsgConfirmed)
|
||||
|
||||
var nonce int64
|
||||
err := row.Scan(&nonce)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// no row means no message
|
||||
// since nonce starts with 0, return -1 as the processed nonce
|
||||
// no row means no message
|
||||
// since nonce starts with 0, return -1 as the processed nonce
|
||||
var nonce sql.NullInt64
|
||||
if err := row.Scan(&nonce); err != nil {
|
||||
if err == sql.ErrNoRows || !nonce.Valid {
|
||||
return -1, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return nonce, nil
|
||||
if nonce.Valid {
|
||||
return nonce.Int64, nil
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// GetL2UnprocessedMessages fetch list of unprocessed messages
|
||||
func (m *layer2MessageOrm) GetL2UnprocessedMessages() ([]*L2Message, error) {
|
||||
rows, err := m.db.Queryx(`SELECT nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash FROM l2_message WHERE status = $1 ORDER BY nonce ASC;`, MsgPending)
|
||||
// GetL2MessagesByStatus fetch list of messages given msg status
|
||||
func (m *layer2MessageOrm) GetL2MessagesByStatus(status MsgStatus) ([]*L2Message, error) {
|
||||
rows, err := m.db.Queryx(`SELECT nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash FROM l2_message WHERE status = $1 ORDER BY nonce ASC;`, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,6 +117,7 @@ func (m *layer2MessageOrm) SaveL2Messages(ctx context.Context, messages []*L2Mes
|
||||
for i, msg := range messages {
|
||||
messageMaps[i] = map[string]interface{}{
|
||||
"nonce": msg.Nonce,
|
||||
"msg_hash": msg.MsgHash,
|
||||
"height": msg.Height,
|
||||
"sender": msg.Sender,
|
||||
"target": msg.Target,
|
||||
@@ -146,7 +130,7 @@ func (m *layer2MessageOrm) SaveL2Messages(ctx context.Context, messages []*L2Mes
|
||||
}
|
||||
}
|
||||
|
||||
_, err := m.db.NamedExec(`INSERT INTO public.l2_message (nonce, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash) VALUES (:nonce, :height, :sender, :target, :value, :fee, :gas_limit, :deadline, :calldata, :layer2_hash);`, messageMaps)
|
||||
_, err := m.db.NamedExec(`INSERT INTO public.l2_message (nonce, msg_hash, height, sender, target, value, fee, gas_limit, deadline, calldata, layer2_hash) VALUES (:nonce, :msg_hash, :height, :sender, :target, :value, :fee, :gas_limit, :deadline, :calldata, :layer2_hash);`, messageMaps)
|
||||
if err != nil {
|
||||
nonces := make([]uint64, 0, len(messages))
|
||||
heights := make([]uint64, 0, len(messages))
|
||||
@@ -159,36 +143,36 @@ func (m *layer2MessageOrm) SaveL2Messages(ctx context.Context, messages []*L2Mes
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateLayer1Hash update corresponding layer1 hash given message nonce
|
||||
func (m *layer2MessageOrm) UpdateLayer1Hash(ctx context.Context, layer2Hash string, layer1Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set layer1_hash = ? where layer2_hash = ?;"), layer1Hash, layer2Hash); err != nil {
|
||||
// UpdateLayer1Hash update corresponding layer1 hash, given message hash
|
||||
func (m *layer2MessageOrm) UpdateLayer1Hash(ctx context.Context, msgHash, layer1Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set layer1_hash = ? where msg_hash = ?;"), layer1Hash, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateMessageProof update corresponding message proof given message nonce
|
||||
func (m *layer2MessageOrm) UpdateMessageProof(ctx context.Context, layer2Hash, proof string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set proof = ? where layer2_hash = ?;"), proof, layer2Hash); err != nil {
|
||||
// UpdateMessageProof update corresponding message proof, given message nonce
|
||||
func (m *layer2MessageOrm) UpdateMessageProof(ctx context.Context, nonce uint64, proof string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set proof = ? where nonce = ?;"), proof, nonce); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLayer2Status updates message stauts
|
||||
func (m *layer2MessageOrm) UpdateLayer2Status(ctx context.Context, layer2Hash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set status = ? where layer2_hash = ?;"), status, layer2Hash); err != nil {
|
||||
// UpdateLayer2Status updates message stauts, given message hash
|
||||
func (m *layer2MessageOrm) UpdateLayer2Status(ctx context.Context, msgHash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set status = ? where msg_hash = ?;"), status, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLayer2StatusAndLayer1Hash updates message stauts and layer1 transaction hash
|
||||
func (m *layer2MessageOrm) UpdateLayer2StatusAndLayer1Hash(ctx context.Context, layer2Hash string, layer1Hash string, status MsgStatus) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set status = ?, layer1_hash = ? where layer2_hash = ?;"), status, layer1Hash, layer2Hash); err != nil {
|
||||
// UpdateLayer2StatusAndLayer1Hash updates message stauts and layer1 transaction hash, given message hash
|
||||
func (m *layer2MessageOrm) UpdateLayer2StatusAndLayer1Hash(ctx context.Context, msgHash string, status MsgStatus, layer1Hash string) error {
|
||||
if _, err := m.db.ExecContext(ctx, m.db.Rebind("update l2_message set status = ?, layer1_hash = ? where msg_hash = ?;"), status, layer1Hash, msgHash); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
55
database/orm/session_info.go
Normal file
55
database/orm/session_info.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type sessionInfoOrm struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
var _ SessionInfoOrm = (*sessionInfoOrm)(nil)
|
||||
|
||||
// NewSessionInfoOrm create an sessionInfoOrm instance
|
||||
func NewSessionInfoOrm(db *sqlx.DB) SessionInfoOrm {
|
||||
return &sessionInfoOrm{db: db}
|
||||
}
|
||||
|
||||
func (o *sessionInfoOrm) GetSessionInfosByIDs(ids []string) ([]*SessionInfo, error) {
|
||||
if len(ids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
query, args, err := sqlx.In("SELECT rollers_info FROM session_info WHERE id IN (?);", ids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows, err := o.db.Queryx(o.db.Rebind(query), args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sessionInfos []*SessionInfo
|
||||
for rows.Next() {
|
||||
var infoBytes []byte
|
||||
if err := rows.Scan(&infoBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sessionInfo := &SessionInfo{}
|
||||
if err := json.Unmarshal(infoBytes, sessionInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sessionInfos = append(sessionInfos, sessionInfo)
|
||||
}
|
||||
return sessionInfos, nil
|
||||
}
|
||||
|
||||
func (o *sessionInfoOrm) SetSessionInfo(rollersInfo *SessionInfo) error {
|
||||
infoBytes, err := json.Marshal(rollersInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sqlStr := "INSERT INTO session_info (id, rollers_info) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET rollers_info = EXCLUDED.rollers_info;"
|
||||
_, err = o.db.Exec(sqlStr, rollersInfo.ID, infoBytes)
|
||||
return err
|
||||
}
|
||||
@@ -13,6 +13,7 @@ type OrmFactory interface {
|
||||
orm.BlockBatchOrm
|
||||
orm.L1MessageOrm
|
||||
orm.L2MessageOrm
|
||||
orm.SessionInfoOrm
|
||||
GetDB() *sqlx.DB
|
||||
Beginx() (*sqlx.Tx, error)
|
||||
Close() error
|
||||
@@ -23,6 +24,7 @@ type ormFactory struct {
|
||||
orm.BlockBatchOrm
|
||||
orm.L1MessageOrm
|
||||
orm.L2MessageOrm
|
||||
orm.SessionInfoOrm
|
||||
*sqlx.DB
|
||||
}
|
||||
|
||||
@@ -35,17 +37,18 @@ func NewOrmFactory(cfg *DBConfig) (OrmFactory, error) {
|
||||
}
|
||||
|
||||
db.SetMaxIdleConns(cfg.MaxOpenNum)
|
||||
db.SetMaxIdleConns(cfg.MaxIdleNUm)
|
||||
db.SetMaxIdleConns(cfg.MaxIdleNum)
|
||||
if err = db.Ping(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ormFactory{
|
||||
BlockTraceOrm: orm.NewBlockTraceOrm(db),
|
||||
BlockBatchOrm: orm.NewBlockBatchOrm(db),
|
||||
L1MessageOrm: orm.NewL1MessageOrm(db),
|
||||
L2MessageOrm: orm.NewL2MessageOrm(db),
|
||||
DB: db,
|
||||
BlockTraceOrm: orm.NewBlockTraceOrm(db),
|
||||
BlockBatchOrm: orm.NewBlockBatchOrm(db),
|
||||
L1MessageOrm: orm.NewL1MessageOrm(db),
|
||||
L2MessageOrm: orm.NewL2MessageOrm(db),
|
||||
SessionInfoOrm: orm.NewSessionInfoOrm(db),
|
||||
DB: db,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ var (
|
||||
templateL1Message = []*orm.L1Message{
|
||||
{
|
||||
Nonce: 1,
|
||||
MsgHash: "msg_hash1",
|
||||
Height: 1,
|
||||
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
|
||||
Value: "0x19ece",
|
||||
@@ -35,6 +36,7 @@ var (
|
||||
},
|
||||
{
|
||||
Nonce: 2,
|
||||
MsgHash: "msg_hash2",
|
||||
Height: 2,
|
||||
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
|
||||
Value: "0x19ece",
|
||||
@@ -49,6 +51,7 @@ var (
|
||||
templateL2Message = []*orm.L2Message{
|
||||
{
|
||||
Nonce: 1,
|
||||
MsgHash: "msg_hash1",
|
||||
Height: 1,
|
||||
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
|
||||
Value: "0x19ece",
|
||||
@@ -61,6 +64,7 @@ var (
|
||||
},
|
||||
{
|
||||
Nonce: 2,
|
||||
MsgHash: "msg_hash2",
|
||||
Height: 2,
|
||||
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
|
||||
Value: "0x19ece",
|
||||
@@ -74,12 +78,13 @@ var (
|
||||
}
|
||||
blockTrace *types.BlockTrace
|
||||
|
||||
dbConfig *database.DBConfig
|
||||
dbImg docker.ImgInstance
|
||||
ormBlock orm.BlockTraceOrm
|
||||
ormLayer1 orm.L1MessageOrm
|
||||
ormLayer2 orm.L2MessageOrm
|
||||
ormBatch orm.BlockBatchOrm
|
||||
dbConfig *database.DBConfig
|
||||
dbImg docker.ImgInstance
|
||||
ormBlock orm.BlockTraceOrm
|
||||
ormLayer1 orm.L1MessageOrm
|
||||
ormLayer2 orm.L2MessageOrm
|
||||
ormBatch orm.BlockBatchOrm
|
||||
ormSession orm.SessionInfoOrm
|
||||
)
|
||||
|
||||
func setupEnv(t *testing.T) error {
|
||||
@@ -99,6 +104,7 @@ func setupEnv(t *testing.T) error {
|
||||
ormLayer1 = orm.NewL1MessageOrm(db)
|
||||
ormLayer2 = orm.NewL2MessageOrm(db)
|
||||
ormBatch = orm.NewBlockBatchOrm(db)
|
||||
ormSession = orm.NewSessionInfoOrm(db)
|
||||
|
||||
templateBlockTrace, err := os.ReadFile("../common/testdata/blockTrace_03.json")
|
||||
if err != nil {
|
||||
@@ -126,7 +132,9 @@ func TestOrmFactory(t *testing.T) {
|
||||
|
||||
t.Run("testOrmL2Message", testOrmL2Message)
|
||||
|
||||
t.Run("testOrmBlockbatch", testOrmBlockbatch)
|
||||
t.Run("testOrmBlockBatch", testOrmBlockBatch)
|
||||
|
||||
t.Run("testOrmSessionInfo", testOrmSessionInfo)
|
||||
}
|
||||
|
||||
func testOrmBlockTraces(t *testing.T) {
|
||||
@@ -182,13 +190,13 @@ func testOrmL1Message(t *testing.T) {
|
||||
err = ormLayer1.SaveL1Messages(context.Background(), templateL1Message)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer1.UpdateLayer1Status(context.Background(), "hash0", orm.MsgConfirmed)
|
||||
err = ormLayer1.UpdateLayer1Status(context.Background(), "msg_hash1", orm.MsgConfirmed)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer1.UpdateLayer1Status(context.Background(), "hash1", orm.MsgSubmitted)
|
||||
err = ormLayer1.UpdateLayer1Status(context.Background(), "msg_hash2", orm.MsgSubmitted)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer1.UpdateLayer2Hash(context.Background(), "hash1", expected)
|
||||
err = ormLayer1.UpdateLayer2Hash(context.Background(), "msg_hash2", expected)
|
||||
assert.NoError(t, err)
|
||||
|
||||
result, err := ormLayer1.GetL1ProcessedNonce()
|
||||
@@ -199,7 +207,7 @@ func testOrmL1Message(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), height)
|
||||
|
||||
msg, err := ormLayer1.GetL1MessageByLayer1Hash("hash1")
|
||||
msg, err := ormLayer1.GetL1MessageByMsgHash("msg_hash2")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, orm.MsgSubmitted, msg.Status)
|
||||
}
|
||||
@@ -216,13 +224,13 @@ func testOrmL2Message(t *testing.T) {
|
||||
err = ormLayer2.SaveL2Messages(context.Background(), templateL2Message)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer2.UpdateLayer2Status(context.Background(), "hash0", orm.MsgConfirmed)
|
||||
err = ormLayer2.UpdateLayer2Status(context.Background(), "msg_hash1", orm.MsgConfirmed)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer2.UpdateLayer2Status(context.Background(), "hash1", orm.MsgSubmitted)
|
||||
err = ormLayer2.UpdateLayer2Status(context.Background(), "msg_hash2", orm.MsgSubmitted)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = ormLayer2.UpdateLayer1Hash(context.Background(), "hash1", expected)
|
||||
err = ormLayer2.UpdateLayer1Hash(context.Background(), "msg_hash2", expected)
|
||||
assert.NoError(t, err)
|
||||
|
||||
result, err := ormLayer2.GetL2ProcessedNonce()
|
||||
@@ -233,13 +241,14 @@ func testOrmL2Message(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), height)
|
||||
|
||||
msg, err := ormLayer2.GetL2MessageByLayer2Hash("hash1")
|
||||
msg, err := ormLayer2.GetL2MessageByMsgHash("msg_hash2")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, orm.MsgSubmitted, msg.Status)
|
||||
assert.Equal(t, msg.MsgHash, "msg_hash2")
|
||||
}
|
||||
|
||||
// testOrmBlockbatch test rollup result table functions
|
||||
func testOrmBlockbatch(t *testing.T) {
|
||||
// testOrmBlockBatch test rollup result table functions
|
||||
func testOrmBlockBatch(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
factory, err := database.NewOrmFactory(dbConfig)
|
||||
assert.NoError(t, err)
|
||||
@@ -309,3 +318,66 @@ func testOrmBlockbatch(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, batchID1, result.ID)
|
||||
}
|
||||
|
||||
// testOrmSessionInfo test rollup result table functions
|
||||
func testOrmSessionInfo(t *testing.T) {
|
||||
// Create db handler and reset db.
|
||||
factory, err := database.NewOrmFactory(dbConfig)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, migrate.ResetDB(factory.GetDB().DB))
|
||||
dbTx, err := factory.Beginx()
|
||||
assert.NoError(t, err)
|
||||
batchID, err := ormBatch.NewBatchInDBTx(dbTx,
|
||||
&orm.BlockInfo{Number: blockTrace.Header.Number.Uint64()},
|
||||
&orm.BlockInfo{Number: blockTrace.Header.Number.Uint64() + 1},
|
||||
"ff", 1, 194676)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, ormBlock.SetBatchIDForBlocksInDBTx(dbTx, []uint64{
|
||||
blockTrace.Header.Number.Uint64(),
|
||||
blockTrace.Header.Number.Uint64() + 1}, batchID))
|
||||
assert.NoError(t, dbTx.Commit())
|
||||
assert.NoError(t, ormBatch.UpdateProvingStatus(batchID, orm.ProvingTaskAssigned))
|
||||
|
||||
// empty
|
||||
ids, err := ormBatch.GetAssignedBatchIDs()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(ids))
|
||||
session_infos, err := ormSession.GetSessionInfosByIDs(ids)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(session_infos))
|
||||
|
||||
sessionInfo := orm.SessionInfo{
|
||||
ID: batchID,
|
||||
Rollers: map[string]*orm.RollerStatus{
|
||||
"0": {
|
||||
PublicKey: "0",
|
||||
Name: "roller-0",
|
||||
Status: orm.RollerAssigned,
|
||||
},
|
||||
},
|
||||
StartTimestamp: time.Now().Unix()}
|
||||
|
||||
// insert
|
||||
assert.NoError(t, ormSession.SetSessionInfo(&sessionInfo))
|
||||
session_infos, err = ormSession.GetSessionInfosByIDs(ids)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(session_infos))
|
||||
assert.Equal(t, sessionInfo, *session_infos[0])
|
||||
|
||||
// update
|
||||
sessionInfo.Rollers["0"].Status = orm.RollerProofValid
|
||||
assert.NoError(t, ormSession.SetSessionInfo(&sessionInfo))
|
||||
session_infos, err = ormSession.GetSessionInfosByIDs(ids)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(session_infos))
|
||||
assert.Equal(t, sessionInfo, *session_infos[0])
|
||||
|
||||
// delete
|
||||
assert.NoError(t, ormBatch.UpdateProvingStatus(batchID, orm.ProvingTaskVerified))
|
||||
ids, err = ormBatch.GetAssignedBatchIDs()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(ids))
|
||||
session_infos, err = ormSession.GetSessionInfosByIDs(ids)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(session_infos))
|
||||
}
|
||||
|
||||
190
go.work.sum
190
go.work.sum
@@ -1,35 +1,199 @@
|
||||
cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
|
||||
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
|
||||
cloud.google.com/go/bigtable v1.2.0 h1:F4cCmA4nuV84V5zYQ3MKY+M1Cw1avHDuf3S/LcZPA9c=
|
||||
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
|
||||
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
|
||||
cloud.google.com/go/storage v1.5.0 h1:RPUcBvDeYgQFMfQu1eBMq6piD1SXmLH+vK3qjewZPus=
|
||||
collectd.org v0.3.0 h1:iNBHGw1VvPJxH2B6RiFWFZ+vsjo1lCdRszBeOuwGi00=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 h1:qoVeMsc9/fh/yhxVaA0obYjVH/oI/ihrOoMwsLS9KSA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3 h1:E+m3SkZCN0Bf5q7YdTs5lSm2CYY3CK4spn5OmUIiQtk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0 h1:Px2UA+2RvSSvv+RvJNuUB6n7rs5Wsel4dXLe90Um2n4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo=
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0 h1:MuueVOYkufCxJw5YZzF842DY2MBsp+hLuh2apKY0mck=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 h1:CxTzQrySOxDnKpLjFJeZAS5Qrv/qFPkgLjx5bOAi//I=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.2.0 h1:dj00TDKY+xwuTJdbpspCSmTLFyWzRJerTHwaBxut1C0=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db h1:nxAtV4VajJDhKysp2kdcJZsq8Ss1xSA0vZTkVHHJd0E=
|
||||
github.com/avast/retry-go/v4 v4.1.0 h1:CwudD9anYv6JMVnDuTRlK6kLo4dBamiL+F3U8YDiyfg=
|
||||
github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.1.1 h1:NbvWIM1Mx6sNPTxowHgS2ewXCRp+NGTzUYb/96FZJbY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 h1:EtEU7WRaWliitZh2nmuxEXrN0Cb8EgPUFGIoTMeqbzI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 h1:4AH9fFjUlVktQMznF+YN33aWNXaR4VgDXyP28qokJC0=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1 h1:cKr6St+CtC3/dl/rEBJvlk7A/IN5D5F02GNkGzfbtVU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 h1:37QubsarExl5ZuCBlnRP+7l1tNwZPBSTqpTBrPH98RU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 h1:TJoIfnIFubCX0ACVeJ0w46HEH5MwjwYN4iFhuYIhfIY=
|
||||
github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
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=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE=
|
||||
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723 h1:ZA/jbKoGcVAnER6pCHPEkGdZOV7U1oLUedErBHCUMs0=
|
||||
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
|
||||
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
|
||||
github.com/c-bata/go-prompt v0.2.2 h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e0=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572 h1:+R8G1+Ftumd0DaveLgMIjrFPcAS4G8MsVXWXiyZL5BY=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c h1:/ovYnF02fwL0kvspmy9AuyKg1JhdTRUgPw4nUxd9oZM=
|
||||
github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc=
|
||||
github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/denisenkom/go-mssqldb v0.12.2 h1:1OcPn5GBIobjWNd+8yjfHNIaFX14B1pWI3F9HZy5KXw=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8 h1:akOQj8IVgoeFfBTzGOEQakCYshWD6RNo1M5pivFXt70=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf h1:Yt+4K30SdjOkRoRRm3vYNQgR+/ZIy0RmeUDZo7Y8zeQ=
|
||||
github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 h1:tYwu/z8Y0NkkzGEh3z21mSWggMg4LwLRFucLS7TjARg=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c h1:CndMRAH4JIwxbW8KYq6Q+cGWcGHz0FjGR3QqcInWcW0=
|
||||
github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg=
|
||||
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=
|
||||
github.com/getkin/kin-openapi v0.61.0 h1:6awGqF5nG5zkVpMsAih1QH4VgzS8phTxECUWIFo7zko=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd h1:r04MMPyLHj/QwZuMJ5+7tJcBr1AQjpiAK/rZWRrQT7o=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
||||
github.com/go-chi/chi/v5 v5.0.0 h1:DBPx88FjZJH3FsICfDAfIfnb7XxKIYVGG6lOPlhENAg=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE=
|
||||
github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec h1:lJwO/92dFXWeXOZdoGXgptLmNLwynMSHUmU6besqtiw=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
||||
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219 h1:utua3L2IbQJmauC5IXdEA547bcoU5dozgQAfc8Onsg4=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/flatbuffers v1.11.0 h1:O7CEyB8Cb3/DmtxODGtLHcEvpr81Jm5qLg/hsHnxA2A=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc h1:DLpL8pWq0v4JYoRpEhDfsJhhJyGKCcQM2WPW2TJs31c=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150 h1:vlNjIqmUZ9CMAWsbURYl3a6wZbw7q5RHVvlXTNS/Bs8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/influxdata/flux v0.65.1 h1:77BcVUCzvN5HMm8+j9PRBQ4iZcu98Dl4Y9rf+J5vhnc=
|
||||
github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385 h1:ED4e5Cc3z5vSN2Tz2GkOHN7vs4Sxe2yds6CXvDnvZFE=
|
||||
github.com/influxdata/promql/v2 v2.12.0 h1:kXn3p0D7zPw16rOtfDR+wo6aaiH8tSMfhPwONTxrlEc=
|
||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6 h1:UzJnB7VRL4PSkUJHwsyzseGOmrO/r4yA+AuxGJxiZmA=
|
||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9 h1:MHTrDWmQpHq/hkq+7cw9oYAt2PqUw52TZazRA0N7PGE=
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368 h1:+TUUmaFa4YD1Q+7bH9o5NCHQGPMqZCYJiNW6lIIS9z4=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
||||
github.com/jackc/pgx/v4 v4.17.0 h1:Hsx+baY8/zU2WtPLQyZi8WbecgcsWEeyoK1jvg/WgIo=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jsternberg/zap-logfmt v1.0.0 h1:0Dz2s/eturmdUS34GM82JwNEdQ9hPoJgqptcEKcbpzY=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
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/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef h1:2jNeR4YUziVtswNP9sEFAI913cVrzH85T+8Q6LpYbT0=
|
||||
github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4=
|
||||
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/scroll-tech/zktrie v0.3.0 h1:c0GRNELUyAtyuiwllQKT1XjNbs7NRGfguKouiyLfFNY=
|
||||
github.com/scroll-tech/zktrie v0.3.0/go.mod h1:CuJFlG1/soTJJBAySxCZgTF7oPvd5qF6utHOEciC43Q=
|
||||
github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299 h1:zQpM52jfKHG6II1ISZY1ZcpygvuSFZpLwfluuF89XOg=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
|
||||
3
roller/.gitignore
vendored
3
roller/.gitignore
vendored
@@ -7,8 +7,7 @@ build/bin/
|
||||
bbolt_db
|
||||
|
||||
# ignore cgo in macOS
|
||||
core/prover/lib/libprover.a
|
||||
core/prover/rust/target
|
||||
core/prover/lib
|
||||
|
||||
params/
|
||||
seed
|
||||
|
||||
@@ -1,30 +1,36 @@
|
||||
.PHONY: lint docker clean roller
|
||||
.PHONY: lint docker clean roller mock_roller
|
||||
|
||||
IMAGE_NAME=go-roller
|
||||
IMAGE_VERSION=latest
|
||||
|
||||
ifeq (4.3,$(firstword $(sort $(MAKE_VERSION) 4.3)))
|
||||
ZK_VERSION=$(shell grep -m 1 "common-rs" core/prover/rust/Cargo.lock | cut -d "#" -f2 | cut -c-7)
|
||||
ZK_VERSION=$(shell grep -m 1 "common-rs" ../common/libzkp/impl/Cargo.lock | cut -d "#" -f2 | cut -c-7)
|
||||
else
|
||||
ZK_VERSION=$(shell grep -m 1 "common-rs" core/prover/rust/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
|
||||
ZK_VERSION=$(shell grep -m 1 "common-rs" ../common/libzkp/impl/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
|
||||
endif
|
||||
|
||||
libprover:
|
||||
cd core/prover/rust && cargo build --release && cp target/release/libprover.a ../lib/
|
||||
libzkp:
|
||||
cd ../common/libzkp/impl && cargo build --release && cp ./target/release/libzkp.a ../interface/
|
||||
cp -r ../common/libzkp/interface ./core/prover/lib
|
||||
|
||||
roller: ## Build the Roller instance.
|
||||
cd core/prover/rust && cargo build --release && cp target/release/libprover.a ../lib/
|
||||
cd ../common/libzkp/impl && cargo build --release && cp ./target/release/libzkp.a ../interface/
|
||||
cp -r ../common/libzkp/interface ./core/prover/lib
|
||||
GOBIN=$(PWD)/build/bin go build -ldflags "-X scroll-tech/roller/core.ZK_VERSION=${ZK_VERSION}" -o $(PWD)/build/bin/roller ./cmd
|
||||
|
||||
gpu-roller: ## Build the GPU Roller instance.
|
||||
cd core/prover/rust && cargo build --release && cp target/release/libprover.a ../lib/
|
||||
cd ../common/libzkp/impl && cargo build --release && cp ./target/release/libzkp.a ../interface/
|
||||
cp -r ../common/libzkp/interface ./core/prover/lib
|
||||
GOBIN=$(PWD)/build/bin go build -ldflags "-X scroll-tech/roller/core.ZK_VERSION=${ZK_VERSION}" -tags gpu -o $(PWD)/build/bin/roller ./cmd
|
||||
|
||||
mock_roller:
|
||||
GOBIN=$(PWD)/build/bin go build -tags mock_prover -o $(PWD)/build/bin/roller $(PWD)/cmd
|
||||
|
||||
test-prover:
|
||||
go test -timeout 0 -v ./core/prover
|
||||
go test -tags ffi -timeout 0 -v ./core/prover
|
||||
|
||||
test-gpu-prover:
|
||||
go test -tags gpu -timeout 0 -v ./core/prover
|
||||
go test -tags="gpu ffi" -timeout 0 -v ./core/prover
|
||||
|
||||
lastest-zk-version:
|
||||
curl -sL https://api.github.com/repos/scroll-tech/common-rs/commits | jq -r ".[0].sha"
|
||||
|
||||
@@ -13,29 +13,6 @@ import (
|
||||
"scroll-tech/roller/core"
|
||||
)
|
||||
|
||||
var (
|
||||
// cfgFileFlag load json type config file.
|
||||
cfgFileFlag = cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "TOML configuration file",
|
||||
Value: "./config.toml",
|
||||
}
|
||||
|
||||
// logFileFlag decides where the logger output is sent. If this flag is left
|
||||
// empty, it will log to stdout.
|
||||
logFileFlag = cli.StringFlag{
|
||||
Name: "logfile",
|
||||
Usage: "Tells the sequencer where to write log entries",
|
||||
}
|
||||
|
||||
// verbosityFlag log level.
|
||||
verbosityFlag = cli.IntFlag{
|
||||
Name: "verbosity",
|
||||
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
|
||||
Value: 3,
|
||||
}
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
|
||||
@@ -43,17 +20,10 @@ func main() {
|
||||
app.Name = "Roller"
|
||||
app.Usage = "The Scroll L2 Roller"
|
||||
app.Version = core.Version
|
||||
app.Flags = append(app.Flags, []cli.Flag{
|
||||
&cfgFileFlag,
|
||||
&logFileFlag,
|
||||
&verbosityFlag,
|
||||
}...)
|
||||
app.Flags = append(app.Flags, utils.CommonFlags...)
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
return utils.Setup(&utils.LogConfig{
|
||||
LogFile: ctx.String(logFileFlag.Name),
|
||||
Verbosity: ctx.Int(verbosityFlag.Name),
|
||||
})
|
||||
return utils.LogSetup(ctx)
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
@@ -63,10 +33,11 @@ func main() {
|
||||
}
|
||||
|
||||
func action(ctx *cli.Context) error {
|
||||
// Get config
|
||||
cfg, err := config.InitConfig(ctx.String(cfgFileFlag.Name))
|
||||
// Load config file.
|
||||
cfgFile := ctx.String(utils.ConfigFileFlag.Name)
|
||||
cfg, err := config.NewConfig(cfgFile)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Crit("failed to load config file", "config file", cfgFile, "error", err)
|
||||
}
|
||||
|
||||
// Create roller
|
||||
@@ -75,7 +46,7 @@ func action(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
log.Info("roller start successfully", "name", cfg.RollerName)
|
||||
log.Info("roller start successfully", "name", cfg.RollerName, "publickey", r.PublicKey(), "version", core.Version)
|
||||
|
||||
return r.Run()
|
||||
}
|
||||
|
||||
11
roller/config.json
Normal file
11
roller/config.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"roller_name": "my_roller",
|
||||
"keystore_path": "keystore.json",
|
||||
"keystore_password": "roller-pwd",
|
||||
"coordinator_url": "ws://localhost:8391",
|
||||
"db_path": "bbolt_db",
|
||||
"prover": {
|
||||
"params_path": "params",
|
||||
"seed_path": "seed"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
roller_name = "my_roller"
|
||||
keystore_path = "keystore.json"
|
||||
keystore_password = "roller-pwd"
|
||||
coordinator_url = "ws://localhost:9000"
|
||||
db_path = "bbolt_db"
|
||||
|
||||
[prover]
|
||||
mock_mode = false
|
||||
params_path = "params"
|
||||
seed_path = "seed"
|
||||
@@ -1,35 +1,38 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/scroll-tech/go-ethereum/log"
|
||||
)
|
||||
|
||||
// Config loads roller configuration items.
|
||||
type Config struct {
|
||||
RollerName string `toml:"roller_name"`
|
||||
KeystorePath string `toml:"keystore_path"`
|
||||
KeystorePassword string `toml:"keystore_password"`
|
||||
CoordinatorURL string `toml:"coordinator_url"`
|
||||
Prover *ProverConfig `toml:"prover"`
|
||||
DBPath string `toml:"db_path"`
|
||||
RollerName string `json:"roller_name"`
|
||||
KeystorePath string `json:"keystore_path"`
|
||||
KeystorePassword string `json:"keystore_password"`
|
||||
CoordinatorURL string `json:"coordinator_url"`
|
||||
Prover *ProverConfig `json:"prover"`
|
||||
DBPath string `json:"db_path"`
|
||||
}
|
||||
|
||||
// ProverConfig loads zk roller configuration items.
|
||||
// ProverConfig load zk prover config.
|
||||
type ProverConfig struct {
|
||||
MockMode bool `toml:"mock_mode"`
|
||||
ParamsPath string `toml:"params_path"`
|
||||
SeedPath string `toml:"seed_path"`
|
||||
ParamsPath string `json:"params_path"`
|
||||
SeedPath string `json:"seed_path"`
|
||||
}
|
||||
|
||||
// InitConfig inits config from file.
|
||||
func InitConfig(path string) (*Config, error) {
|
||||
cfg := &Config{}
|
||||
_, err := toml.DecodeFile(path, cfg)
|
||||
// NewConfig returns a new instance of Config.
|
||||
func NewConfig(file string) (*Config, error) {
|
||||
buf, err := os.ReadFile(filepath.Clean(file))
|
||||
if err != nil {
|
||||
log.Error("init config failed", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := &Config{}
|
||||
if err = json.Unmarshal(buf, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !filepath.IsAbs(cfg.DBPath) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user