Commit 75055b51 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #2359 from ethereum-optimism/develop

Develop -> Master
parents 1c858502 0645cd7c
---
'@eth-optimism/replica-healthcheck': patch
---
Fixes a bug in the replica-healthcheck docker file
---
'@eth-optimism/teleportr': patch
---
Add metrics for balances
---
'@eth-optimism/l2geth-exporter': patch
---
Bump to go-ethereum v1.10.16
---
'@eth-optimism/common-ts': patch
---
Properly exposes metrics as part of a metrics server at port 7300
---
'@eth-optimism/integration-tests': patch
---
Add integration test for healthcheck server
---
'@eth-optimism/replica-healthcheck': patch
---
Add checks and metrics for dead networks
---
'@eth-optimism/gas-oracle': patch
---
Allow configurable base fee update poll time with `GAS_PRICE_ORACLE_L1_BASE_FEE_EPOCH_LENGTH_SECONDS`
......@@ -7,32 +7,13 @@ slack-nightly-build-fail-post-step: &slack-nightly-build-fail-post-step
- slack/notify:
channel: $SLACK_DEFAULT_CHANNEL
event: fail
custom: |
{
"text": "",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "🔴 Nightly build failed!"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
template: basic_fail-1
executors:
go-builder:
docker:
- image: ethereumoptimism/go-builder:latest
commands:
build-dockerfile:
parameters:
......@@ -56,6 +37,27 @@ commands:
echo -n "$STACKMAN_REPO_AUTH" | docker login -u _json_key --password-stdin https://us-east4-docker.pkg.dev
docker build -t "$STACKMAN_REPO/<<parameters.image-name>>:nightly" -f <<parameters.dockerfile>> <<#parameters.target>>--target <<parameters.target>><</parameters.target>> .
docker push "$STACKMAN_REPO/<<parameters.image-name>>:nightly"
go-lint-test:
parameters:
working_directory:
description: Working directory
type: string
steps:
- checkout
- run:
name: Lint
command: golangci-lint run -E goimports -E sqlclosecheck -E bodyclose -E asciicheck ./...
working_directory: <<parameters.working_directory>>
- run:
name: Test
command: |
mkdir -p /test-results
gotestsum --junitfile /test-results/tests.xml
working_directory: <<parameters.working_directory>>
- store_test_results:
path: /test-results
jobs:
build-dtl:
docker:
......@@ -154,6 +156,7 @@ jobs:
--env L2_GAS_PRICE=onchain \
--env RUN_DEBUG_TRACE_TESTS=false \
--env RUN_REPLICA_TESTS=false \
--env RUN_HEALTHCHECK_TESTS=false \
--env RUN_STRESS_TESTS=false \
--env OVMCONTEXT_SPEC_NUM_TXS=1 \
--env DTL_ENQUEUE_CONFIRMATIONS=12 \
......@@ -168,8 +171,294 @@ jobs:
command: |
echo "Dummy job."
go-lint-test:
parameters:
working_directory:
description: Working directory
type: string
docker:
- image: ethereumoptimism/go-builder:latest
- image: cimg/postgres:14.1
steps:
- go-lint-test:
working_directory: <<parameters.working_directory>>
go-lint-test-build:
parameters:
binary_name:
description: Binary name to build
type: string
working_directory:
description: Working directory
type: string
docker:
- image: ethereumoptimism/go-builder:latest
- image: cimg/postgres:14.1
steps:
- go-lint-test:
working_directory: <<parameters.working_directory>>
- run:
name: Build
command: make <<parameters.binary_name>>
working_directory: <<parameters.working_directory>>
yarn-monorepo:
docker:
- image: ethereumoptimism/js-builder:latest
steps:
- restore_cache:
keys:
- v1-source-{{ .Branch }}-{{ .Revision }}
- v1-source-{{ .Branch }}
- checkout
- save_cache:
key: v1-source-{{ .Branch }}-{{ .Revision }}
paths:
- ".git"
- restore_cache:
keys:
- v1-yarn-install-{{ checksum "yarn.lock" }}
- v1-yarn-install
- run:
name: Install dependencies
command: yarn --frozen-lockfile
- save_cache:
key: v1-yarn-install-{{ checksum "yarn.lock" }}
paths:
- node_modules
- packages/common-ts/node_modules
- packages/contracts/node_modules
- packages/core-utils/node_modules
- packages/data-transport-layer/node_modules
- packages/message-relayer/node_modules
- packages/replica-healthcheck/node_modules
- packages/sdk/node_modules
- integration-tests/node_modules
- run:
name: Build monorepo
command: yarn build
- save_cache:
key: v1-yarn-build-{{ .Revision }}
paths:
- "."
contracts-slither:
docker:
- image: ethereumoptimism/js-builder:latest
steps:
- restore_cache:
keys:
- v1-yarn-build-{{ .Revision }}
- checkout
- run:
name: Run Slither
command: yarn test:slither
working_directory: packages/contracts
contracts-tests:
docker:
- image: ethereumoptimism/js-builder:latest
resource_class: xlarge
steps:
- restore_cache:
keys:
- v1-yarn-build-{{ .Revision }}
- checkout
- run:
name: Lint
command: yarn lint:check
working_directory: packages/contracts
- run:
name: Slither
command: yarn test:slither
working_directory: packages/contracts
- run:
name: Test
command: yarn test:coverage
working_directory: packages/contracts
dtl-tests:
docker:
- image: ethereumoptimism/js-builder:latest
steps:
- restore_cache:
keys:
- v1-yarn-build-{{ .Revision }}
- checkout
- run:
name: Test
command: yarn test:coverage
working_directory: packages/data-transport-layer
geth-tests:
docker:
- image: ethereumoptimism/go-builder:latest
steps:
- checkout
- run:
name: Test
command: make test
working_directory: l2geth
depcheck:
docker:
- image: ethereumoptimism/js-builder:latest
steps:
- restore_cache:
keys:
- v1-yarn-build-{{ .Revision }}
- checkout
# Note: The below needs to be manually configured whenever we
# add a new package to CI.
- run:
name: Check contracts
command: npx depcheck
working_directory: packages/contracts
- run:
name: Check core-utils
command: npx depcheck
working_directory: packages/core-utils
- run:
name: Check data-transport-layer
command: npx depcheck
working_directory: packages/data-transport-layer
- run:
name: Check sdk
command: npx depcheck
working_directory: packages/sdk
- run:
name: Check integration-tests
command: npx depcheck
working_directory: integration-tests
bss-core-tests:
docker:
- image: ethereumoptimism/go-builder:latest
steps:
- checkout
- run:
name: Lint
command: golangci-lint run -E goimports -E sqlclosecheck -E bodyclose -E asciicheck ./...
working_directory: go/bss-core
- run:
name: Test
command: |
mkdir -p /test-results
gotestsum --junitfile /test-results/tests.xml
working_directory: go/bss-core
- store_test_results:
path: /test-results
integration-tests:
machine:
image: ubuntu-2004:202111-02
docker_layer_caching: true
environment:
DOCKER_BUILDKIT: 1
parallelism: 3
steps:
- checkout
- run:
name: Bring up the stack
command: |
docker-compose build --progress=plain
docker-compose up -d --scale replica-healthcheck=1
working_directory: ops
- run:
name: Wait for sequencer
command: bash scripts/wait-for-sequencer.sh
working_directory: ops
- run:
name: Run integration tests
command: |
circleci tests glob "../integration-tests/test/*.spec.ts" | circleci tests split | tee splits.txt
docker-compose run integration_tests $(cat splits.txt)
working_directory: ops
js-lint-test:
parameters:
package_name:
description: Package name
type: string
docker:
- image: ethereumoptimism/js-builder:latest
steps:
- restore_cache:
keys:
- v1-yarn-build-{{ .Revision }}
- checkout
- run:
name: Lint
command: yarn lint:check
working_directory: packages/<<parameters.package_name>>
- run:
name: Test
command: yarn test:coverage
working_directory: packages/<<parameters.package_name>>
workflows:
main:
jobs:
- yarn-monorepo
- go-lint-test-build:
name: batch-submitter-tests
binary_name: batch-submitter
working_directory: go/batch-submitter
- go-lint-test-build:
name: proxyd-tests
binary_name: proxyd
working_directory: go/proxyd
- go-lint-test-build:
name: teleportr-tests
binary_name: teleportr
working_directory: go/teleportr
- go-lint-test-build:
name: gas-oracle-tests
binary_name: gas-oracle
working_directory: go/gas-oracle
- go-lint-test-build:
name: indexer-tests
binary_name: indexer
working_directory: go/indexer
- go-lint-test:
name: bss-core-tests
working_directory: go/bss-core
- contracts-tests:
requires:
- yarn-monorepo
- js-lint-test:
name: dtl-tests
package_name: data-transport-layer
requires:
- yarn-monorepo
- js-lint-test:
name: core-utils-tests
package_name: core-utils
requires:
- yarn-monorepo
- js-lint-test:
name: sdk-tests
package_name: sdk
requires:
- yarn-monorepo
- js-lint-test:
name: message-relayer-tests
package_name: message-relayer
requires:
- yarn-monorepo
- js-lint-test:
name: replica-healthcheck-tests
package_name: replica-healthcheck
requires:
- yarn-monorepo
- depcheck:
requires:
- yarn-monorepo
- geth-tests
- integration-tests
nightly-itests:
triggers:
- schedule:
......@@ -252,7 +541,7 @@ workflows:
- develop
jobs:
- build-dtl:
context:
context:
- optimism
- slack
<<: *slack-nightly-build-fail-post-step
......@@ -331,4 +620,4 @@ workflows:
}
]
}
event: always
\ No newline at end of file
event: always
......@@ -50,7 +50,7 @@ jobs:
working-directory: ./ops
run: |
./scripts/stats.sh &
docker-compose -f docker-compose.yml up -d
docker-compose -f docker-compose.yml up -d --scale replica-healthcheck=1
- name: Wait for the Sequencer node
working-directory: ./ops
......@@ -64,7 +64,6 @@ jobs:
if: failure()
uses: jwalton/gh-docker-logs@v1
with:
images: 'ethereumoptimism/hardhat,ops_deployer,ops_dtl,ops_l2geth,ethereumoptimism/message-relayer,ops_batch_submitter,ops_replica,ops_integration_tests'
dest: '/home/runner/logs'
- name: Tar logs
......
......@@ -5,7 +5,7 @@ go 1.16
require (
github.com/btcsuite/btcd v0.22.0-beta // indirect
github.com/decred/dcrd/hdkeychain/v3 v3.0.0
github.com/ethereum/go-ethereum v1.10.12
github.com/ethereum/go-ethereum v1.10.16
github.com/getsentry/sentry-go v0.11.0
github.com/prometheus/client_golang v1.11.0
github.com/stretchr/testify v1.7.0
......
......@@ -115,8 +115,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set 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/decred/base58 v1.0.3 h1:KGZuh8d1WEMIrK0leQRM47W85KqCAdl2N+uagbctdDI=
github.com/decred/base58 v1.0.3/go.mod h1:pXP9cXCfM2sFLb2viz2FNIdeMWmZDBKG3ZBYbiSM78E=
github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=
......@@ -159,8 +159,8 @@ github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZi
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/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum/go-ethereum v1.10.12 h1:el/KddB3gLEsnNgGQ3SQuZuiZjwnFTYHe5TwUet5Om4=
github.com/ethereum/go-ethereum v1.10.12/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
github.com/ethereum/go-ethereum v1.10.16 h1:3oPrumn0bCW/idjcxMn5YYVCdK7VzJYIvwGZUGLEaoc=
github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
......@@ -264,7 +264,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
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/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
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/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
......@@ -300,8 +300,8 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
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/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
......@@ -322,7 +322,7 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
......
......@@ -89,6 +89,12 @@ var (
Usage: "length of epochs in seconds",
EnvVar: "GAS_PRICE_ORACLE_EPOCH_LENGTH_SECONDS",
}
L1BaseFeeEpochLengthSecondsFlag = cli.Uint64Flag{
Name: "l1-base-fee-epoch-length-seconds",
Value: 15,
Usage: "polling time for updating the L1 base fee",
EnvVar: "GAS_PRICE_ORACLE_L1_BASE_FEE_EPOCH_LENGTH_SECONDS",
}
L1BaseFeeSignificanceFactorFlag = cli.Float64Flag{
Name: "l1-base-fee-significant-factor",
Value: 0.10,
......@@ -169,6 +175,7 @@ var Flags = []cli.Flag{
MaxPercentChangePerEpochFlag,
AverageBlockGasLimitPerEpochFlag,
EpochLengthSecondsFlag,
L1BaseFeeEpochLengthSecondsFlag,
L2GasPriceSignificanceFactorFlag,
WaitForReceiptFlag,
EnableL1BaseFeeFlag,
......
......@@ -28,6 +28,7 @@ type Config struct {
maxPercentChangePerEpoch float64
averageBlockGasLimitPerEpoch uint64
epochLengthSeconds uint64
l1BaseFeeEpochLengthSeconds uint64
l2GasPriceSignificanceFactor float64
l1BaseFeeSignificanceFactor float64
enableL1BaseFee bool
......@@ -54,6 +55,7 @@ func NewConfig(ctx *cli.Context) *Config {
cfg.maxPercentChangePerEpoch = ctx.GlobalFloat64(flags.MaxPercentChangePerEpochFlag.Name)
cfg.averageBlockGasLimitPerEpoch = ctx.GlobalUint64(flags.AverageBlockGasLimitPerEpochFlag.Name)
cfg.epochLengthSeconds = ctx.GlobalUint64(flags.EpochLengthSecondsFlag.Name)
cfg.l1BaseFeeEpochLengthSeconds = ctx.GlobalUint64(flags.L1BaseFeeEpochLengthSecondsFlag.Name)
cfg.l2GasPriceSignificanceFactor = ctx.GlobalFloat64(flags.L2GasPriceSignificanceFactorFlag.Name)
cfg.floorPrice = ctx.GlobalUint64(flags.FloorPriceFlag.Name)
cfg.l1BaseFeeSignificanceFactor = ctx.GlobalFloat64(flags.L1BaseFeeSignificanceFactorFlag.Name)
......
......@@ -111,6 +111,7 @@ func (g *GasPriceOracle) ensure() error {
func (g *GasPriceOracle) Loop() {
timer := time.NewTicker(time.Duration(g.config.epochLengthSeconds) * time.Second)
defer timer.Stop()
for {
select {
case <-timer.C:
......@@ -126,7 +127,7 @@ func (g *GasPriceOracle) Loop() {
}
func (g *GasPriceOracle) BaseFeeLoop() {
timer := time.NewTicker(15 * time.Second)
timer := time.NewTicker(time.Duration(g.config.l1BaseFeeEpochLengthSeconds) * time.Second)
defer timer.Stop()
updateBaseFee, err := wrapUpdateBaseFee(g.l1Backend, g.l2Backend, g.config)
......
......@@ -38,38 +38,27 @@ func (d *Database) GetL1TokenByAddress(address string) (*Token, error) {
var token *Token
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectL1TokenStatement)
if err != nil {
return err
}
rows, err := queryStmt.Query(address)
if err != nil {
return err
}
if !rows.Next() {
return nil
row := tx.QueryRow(selectL1TokenStatement, address)
if row.Err() != nil {
return row.Err()
}
var name string
var symbol string
var decimals uint8
err = rows.Scan(&name, &symbol, &decimals)
err := row.Scan(&name, &symbol, &decimals)
if errors.Is(err, sql.ErrNoRows) {
return nil
}
if err != nil {
return err
}
if rows.Next() {
return errors.New("address should be unique")
}
token = &Token{
Name: name,
Symbol: symbol,
Decimals: decimals,
}
return nil
})
if err != nil {
......@@ -88,32 +77,22 @@ func (d *Database) GetL2TokenByAddress(address string) (*Token, error) {
var token *Token
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectL2TokenStatement)
if err != nil {
return err
}
rows, err := queryStmt.Query(address)
if err != nil {
return err
}
if !rows.Next() {
return nil
row := tx.QueryRow(selectL2TokenStatement, address)
if row.Err() != nil {
return row.Err()
}
var name string
var symbol string
var decimals uint8
err = rows.Scan(&name, &symbol, &decimals)
err := row.Scan(&name, &symbol, &decimals)
if errors.Is(err, sql.ErrNoRows) {
return nil
}
if err != nil {
return err
}
if rows.Next() {
return errors.New("address should be unique")
}
token = &Token{
Name: name,
Symbol: symbol,
......@@ -141,22 +120,14 @@ func (d *Database) AddL1Token(address string, token *Token) error {
`
return txn(d.db, func(tx *sql.Tx) error {
tokenStmt, err := tx.Prepare(insertTokenStatement)
if err != nil {
return err
}
_, err = tokenStmt.Exec(
_, err := tx.Exec(
insertTokenStatement,
address,
token.Name,
token.Symbol,
token.Decimals,
)
if err != nil {
return err
}
return nil
return err
})
}
......@@ -172,22 +143,14 @@ func (d *Database) AddL2Token(address string, token *Token) error {
`
return txn(d.db, func(tx *sql.Tx) error {
tokenStmt, err := tx.Prepare(insertTokenStatement)
if err != nil {
return err
}
_, err = tokenStmt.Exec(
_, err := tx.Exec(
insertTokenStatement,
address,
token.Name,
token.Symbol,
token.Decimals,
)
if err != nil {
return err
}
return nil
return err
})
}
......@@ -209,12 +172,8 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`
return txn(d.db, func(tx *sql.Tx) error {
blockStmt, err := tx.Prepare(insertBlockStatement)
if err != nil {
return err
}
_, err = blockStmt.Exec(
_, err := tx.Exec(
insertBlockStatement,
block.Hash.String(),
block.ParentHash.String(),
block.Number,
......@@ -228,13 +187,9 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
return nil
}
depositStmt, err := tx.Prepare(insertDepositStatement)
if err != nil {
return err
}
for _, deposit := range block.Deposits {
_, err = depositStmt.Exec(
_, err = tx.Exec(
insertDepositStatement,
NewGUID(),
deposit.FromAddress.String(),
deposit.ToAddress.String(),
......@@ -273,12 +228,8 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`
return txn(d.db, func(tx *sql.Tx) error {
blockStmt, err := tx.Prepare(insertBlockStatement)
if err != nil {
return err
}
_, err = blockStmt.Exec(
_, err := tx.Exec(
insertBlockStatement,
block.Hash.String(),
block.ParentHash.String(),
block.Number,
......@@ -292,13 +243,9 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
return nil
}
withdrawalStmt, err := tx.Prepare(insertWithdrawalStatement)
if err != nil {
return err
}
for _, withdrawal := range block.Withdrawals {
_, err = withdrawalStmt.Exec(
_, err = tx.Exec(
insertWithdrawalStatement,
NewGUID(),
withdrawal.FromAddress.String(),
withdrawal.ToAddress.String(),
......@@ -330,13 +277,9 @@ func (d *Database) AddStateBatch(batches []StateBatch) error {
`
return txn(d.db, func(tx *sql.Tx) error {
stateBatchStmt, err := tx.Prepare(insertStateBatchStatement)
if err != nil {
return err
}
for _, sb := range batches {
_, err = stateBatchStmt.Exec(
_, err := tx.Exec(
insertStateBatchStatement,
sb.Index.Uint64(),
sb.Root.String(),
sb.Size.Uint64(),
......@@ -371,15 +314,11 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
var deposits []DepositJSON
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectDepositsStatement)
if err != nil {
return err
}
rows, err := queryStmt.Query(address.String(), page.Limit, page.Offset)
rows, err := tx.Query(selectDepositsStatement, address.String(), page.Limit, page.Offset)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var deposit DepositJSON
......@@ -397,9 +336,8 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
deposits = append(deposits, deposit)
}
return nil
return rows.Err()
})
if err != nil {
return nil, err
}
......@@ -414,21 +352,17 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
`
var count uint64
err = txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectDepositCountStatement)
row := tx.QueryRow(selectDepositCountStatement, address.String())
if err != nil {
return err
}
row := queryStmt.QueryRow(address.String())
if err != nil {
return err
}
row.Scan(&count)
return nil
return row.Scan(&count)
})
if err != nil {
return nil, err
}
page.Total = count
......@@ -458,12 +392,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro
var batch *StateBatchJSON
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalBatchStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow(hash.String())
row := tx.QueryRow(selectWithdrawalBatchStatement, hash.String())
if row.Err() != nil {
return row.Err()
}
......@@ -471,7 +400,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro
var index, size, prevTotal, blockNumber, blockTimestamp uint64
var root, blockHash string
var extraData []byte
err = row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash,
err := row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash,
&blockNumber, &blockTimestamp)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
......@@ -519,15 +448,11 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
var withdrawals []WithdrawalJSON
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalsStatement)
if err != nil {
return err
}
rows, err := queryStmt.Query(address.String(), page.Limit, page.Offset)
rows, err := tx.Query(selectWithdrawalsStatement, address.String(), page.Limit, page.Offset)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var withdrawal WithdrawalJSON
......@@ -545,7 +470,7 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
withdrawals = append(withdrawals, withdrawal)
}
return nil
return rows.Err()
})
if err != nil {
......@@ -567,21 +492,17 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
`
var count uint64
err = txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalCountStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow(address.String())
row := tx.QueryRow(selectWithdrawalCountStatement, address.String())
if err != nil {
return err
}
row.Scan(&count)
return nil
return row.Scan(&count)
})
if err != nil {
return nil, err
}
page.Total = count
......@@ -599,19 +520,14 @@ func (d *Database) GetHighestL1Block() (*L1BlockLocator, error) {
var highestBlock *L1BlockLocator
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectHighestBlockStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow()
row := tx.QueryRow(selectHighestBlockStatement)
if row.Err() != nil {
return row.Err()
}
var number uint64
var hash string
err = row.Scan(&number, &hash)
err := row.Scan(&number, &hash)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
highestBlock = nil
......@@ -642,19 +558,14 @@ func (d *Database) GetHighestL2Block() (*L2BlockLocator, error) {
var highestBlock *L2BlockLocator
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectHighestBlockStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow()
row := tx.QueryRow(selectHighestBlockStatement)
if row.Err() != nil {
return row.Err()
}
var number uint64
var hash string
err = row.Scan(&number, &hash)
err := row.Scan(&number, &hash)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
highestBlock = nil
......@@ -688,25 +599,20 @@ func (d *Database) GetIndexedL1BlockByHash(hash common.Hash) (*IndexedL1Block, e
var block *IndexedL1Block
err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectBlockByHashStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow(hash.String())
if errors.Is(row.Err(), sql.ErrNoRows) {
return nil
}
row := tx.QueryRow(selectBlockByHashStatement, hash.String())
if row.Err() != nil {
return err
return row.Err()
}
var hash string
var parentHash string
var number uint64
var timestamp uint64
err = row.Scan(&hash, &parentHash, &number, &timestamp)
err := row.Scan(&hash, &parentHash, &number, &timestamp)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil
}
return err
}
......
......@@ -2,12 +2,13 @@ package metrics
import (
"fmt"
"net/http"
l2common "github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum/go-ethereum/common"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)
const metricsNamespace = "indexer"
......
......@@ -2,6 +2,7 @@ package bridge
import (
"fmt"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/address_manager"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
......
......@@ -2,6 +2,7 @@ package bridge
import (
"context"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/go/indexer/db"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
......
......@@ -2,6 +2,7 @@ package l1
import (
"context"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/l1erc20"
"github.com/ethereum/go-ethereum/ethclient"
......@@ -40,7 +41,6 @@ func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, er
}, nil
}
func QueryStateBatches(filterer *scc.StateCommitmentChainFilterer, startHeight, endHeight uint64, ctx context.Context) (map[common.Hash][]db.StateBatch, error) {
batches := make(map[common.Hash][]db.StateBatch)
......
......@@ -3,6 +3,6 @@ module github.com/ethereum-optimism/optimism/go/l2geth-exporter
go 1.16
require (
github.com/ethereum/go-ethereum v1.10.8
github.com/ethereum/go-ethereum v1.10.16
github.com/prometheus/client_golang v1.11.0
)
......@@ -37,6 +37,7 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
......@@ -74,6 +75,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/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=
......@@ -87,32 +89,38 @@ github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3h
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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set 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=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/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.8 h1:0UP5WUR8hh46ffbjJV7PK499+uGEyasRIfffS0vy06o=
github.com/ethereum/go-ethereum v1.10.8/go.mod h1:pJNuIUYfX5+JKzSD/BTdNsvJSZ1TJqmz0dVyXMAbf6M=
github.com/ethereum/go-ethereum v1.10.16 h1:3oPrumn0bCW/idjcxMn5YYVCdK7VzJYIvwGZUGLEaoc=
github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
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=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
......@@ -132,7 +140,7 @@ github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
......@@ -159,8 +167,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
......@@ -171,6 +180,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
......@@ -187,13 +197,19 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
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/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
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=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/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/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=
......@@ -209,7 +225,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/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=
......@@ -227,7 +244,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
......@@ -239,8 +256,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/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/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
......@@ -252,19 +271,26 @@ github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIG
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
......@@ -276,6 +302,7 @@ github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
......@@ -294,8 +321,10 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
......@@ -318,11 +347,13 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
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/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/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
......@@ -340,6 +371,7 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
......@@ -348,13 +380,16 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4=
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
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/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
......@@ -447,6 +482,7 @@ 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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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=
......@@ -499,10 +535,12 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
......@@ -534,6 +572,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
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=
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=
......@@ -584,12 +623,14 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
......@@ -599,6 +640,7 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
......
......@@ -255,7 +255,7 @@ func (b *Backend) ProxyWS(clientConn *websocket.Conn, methodWhitelist *StringSet
return nil, ErrBackendOverCapacity
}
backendConn, _, err := b.dialer.Dial(b.wsURL, nil)
backendConn, _, err := b.dialer.Dial(b.wsURL, nil) // nolint:bodyclose
if err != nil {
b.setOffline()
if err := b.rateLimiter.DecBackendWSConns(b.Name); err != nil {
......@@ -513,7 +513,9 @@ func (w *WSProxier) clientPump(ctx context.Context, errC chan error) {
msgType, msg, err := w.clientConn.ReadMessage()
if err != nil {
errC <- err
outConn.WriteMessage(websocket.CloseMessage, formatWSError(err))
if err := outConn.WriteMessage(websocket.CloseMessage, formatWSError(err)); err != nil {
log.Error("error writing backendConn message", "err", err)
}
return
}
......@@ -575,7 +577,9 @@ func (w *WSProxier) backendPump(ctx context.Context, errC chan error) {
msgType, msg, err := w.backendConn.ReadMessage()
if err != nil {
errC <- err
w.clientConn.WriteMessage(websocket.CloseMessage, formatWSError(err))
if err := w.clientConn.WriteMessage(websocket.CloseMessage, formatWSError(err)); err != nil {
log.Error("error writing clientConn message", "err", err)
}
return
}
......
......@@ -3,12 +3,13 @@ package integration_tests
import (
"bytes"
"fmt"
"github.com/alicebob/miniredis"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os"
"testing"
"time"
"github.com/alicebob/miniredis"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
)
func TestCaching(t *testing.T) {
......
......@@ -2,13 +2,14 @@ package integration_tests
import (
"fmt"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"net/http"
"os"
"sync/atomic"
"testing"
"time"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
)
const (
......@@ -39,7 +40,7 @@ func TestFailover(t *testing.T) {
"backend responds 200 with non-JSON response",
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("this data is not JSON!"))
_, _ = w.Write([]byte("this data is not JSON!"))
}),
},
{
......@@ -87,7 +88,7 @@ func TestFailover(t *testing.T) {
t.Run("backend times out and falls back to another", func(t *testing.T) {
badBackend.SetHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second)
w.Write([]byte("{}"))
_, _ = w.Write([]byte("{}"))
}))
res, statusCode, err := client.SendRPC("eth_chainId", nil)
require.NoError(t, err)
......@@ -133,7 +134,7 @@ func TestRetries(t *testing.T) {
w.WriteHeader(500)
return
}
w.Write([]byte(goodResponse))
_, _ = w.Write([]byte(goodResponse))
}))
// test case where request eventually succeeds
......@@ -169,7 +170,7 @@ func TestOutOfServiceInterval(t *testing.T) {
defer shutdown()
okHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(goodResponse))
_, _ = w.Write([]byte(goodResponse))
})
badBackend.SetHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(503)
......@@ -190,10 +191,12 @@ func TestOutOfServiceInterval(t *testing.T) {
require.Equal(t, 2, len(badBackend.Requests()))
require.Equal(t, 2, len(goodBackend.Requests()))
res, statusCode, err = client.SendBatchRPC(
_, statusCode, err = client.SendBatchRPC(
NewRPCReq("1", "eth_chainId", nil),
NewRPCReq("1", "eth_chainId", nil),
)
require.NoError(t, err)
require.Equal(t, 200, statusCode)
require.Equal(t, 2, len(badBackend.Requests()))
require.Equal(t, 4, len(goodBackend.Requests()))
......
......@@ -4,11 +4,12 @@ import (
"bytes"
"context"
"encoding/json"
"github.com/ethereum-optimism/optimism/go/proxyd"
"io/ioutil"
"net/http"
"net/http/httptest"
"sync"
"github.com/ethereum-optimism/optimism/go/proxyd"
)
type RecordedRequest struct {
......@@ -27,7 +28,7 @@ type MockBackend struct {
func SingleResponseHandler(code int, response string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(code)
w.Write([]byte(response))
_, _ = w.Write([]byte(response))
}
}
......
package integration_tests
import (
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os"
"testing"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
)
type resWithCode struct {
......
......@@ -4,12 +4,13 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"io/ioutil"
"net/http"
"testing"
"github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
)
type ProxydClient struct {
......
package integration_tests
import (
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os"
"strings"
"testing"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
)
const (
......
......@@ -217,7 +217,11 @@ func Start(config *Config) (func(), error) {
if config.Metrics.Enabled {
addr := fmt.Sprintf("%s:%d", config.Metrics.Host, config.Metrics.Port)
log.Info("starting metrics server", "addr", addr)
go http.ListenAndServe(addr, promhttp.Handler())
go func() {
if err := http.ListenAndServe(addr, promhttp.Handler()); err != nil {
log.Error("error starting metrics server", "err", err)
}
}()
}
// To allow integration tests to cleanly come up, wait
......
......@@ -5,10 +5,11 @@ import (
"crypto/rand"
"encoding/hex"
"fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
"sync"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
)
const MaxRPSScript = `
......
......@@ -2,8 +2,9 @@ package proxyd
import (
"encoding/json"
"github.com/stretchr/testify/require"
"testing"
"github.com/stretchr/testify/require"
)
func TestRPCResJSON(t *testing.T) {
......
......@@ -107,15 +107,15 @@ func (s *Server) WSListenAndServe(host string, port int) error {
func (s *Server) Shutdown() {
if s.rpcServer != nil {
s.rpcServer.Shutdown(context.Background())
_ = s.rpcServer.Shutdown(context.Background())
}
if s.wsServer != nil {
s.wsServer.Shutdown(context.Background())
_ = s.wsServer.Shutdown(context.Background())
}
}
func (s *Server) HandleHealthz(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
_, _ = w.Write([]byte("OK"))
}
func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
......@@ -159,7 +159,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
return
}
batchRes := make([]*RPCRes, len(reqs), len(reqs))
batchRes := make([]*RPCRes, len(reqs))
var batchContainsCached bool
for i := 0; i < len(reqs); i++ {
req, err := ParseRPCReq(reqs[i])
......@@ -301,7 +301,7 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
}
return context.WithValue(
r.Context(),
ContextKeyReqID,
ContextKeyReqID, // nolint:staticcheck
randStr(10),
)
}
......@@ -321,11 +321,11 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
}
}
ctx := context.WithValue(r.Context(), ContextKeyAuth, s.authenticatedPaths[authorization])
ctx = context.WithValue(ctx, ContextKeyXForwardedFor, xff)
ctx := context.WithValue(r.Context(), ContextKeyAuth, s.authenticatedPaths[authorization]) // nolint:staticcheck
ctx = context.WithValue(ctx, ContextKeyXForwardedFor, xff) // nolint:staticcheck
return context.WithValue(
ctx,
ContextKeyReqID,
ContextKeyReqID, // nolint:staticcheck
randStr(10),
)
}
......@@ -413,17 +413,6 @@ func GetXForwardedFor(ctx context.Context) string {
return xff
}
type recordLenReader struct {
io.Reader
Len int
}
func (r *recordLenReader) Read(p []byte) (n int, err error) {
n, err = r.Reader.Read(p)
r.Len += n
return
}
type recordLenWriter struct {
io.Writer
Len int
......
......@@ -142,15 +142,15 @@ func NewConfig(ctx *cli.Context) (Config, error) {
return Config{
Hostname: ctx.GlobalString(flags.APIHostnameFlag.Name),
Port: uint16(ctx.GlobalUint64(flags.APIPortFlag.Name)),
L1EthRpc: ctx.GlobalString(flags.APIL1EthRpcFlag.Name),
DepositAddress: ctx.GlobalString(flags.APIDepositAddressFlag.Name),
NumConfirmations: ctx.GlobalUint64(flags.APINumConfirmationsFlag.Name),
PostgresHost: ctx.GlobalString(flags.APIPostgresHostFlag.Name),
PostgresPort: uint16(ctx.GlobalUint64(flags.APIPostgresPortFlag.Name)),
PostgresUser: ctx.GlobalString(flags.APIPostgresUserFlag.Name),
PostgresPassword: ctx.GlobalString(flags.APIPostgresPasswordFlag.Name),
PostgresDBName: ctx.GlobalString(flags.APIPostgresDBNameFlag.Name),
PostgresEnableSSL: ctx.GlobalBool(flags.APIPostgresEnableSSLFlag.Name),
L1EthRpc: ctx.GlobalString(flags.L1EthRpcFlag.Name),
DepositAddress: ctx.GlobalString(flags.DepositAddressFlag.Name),
NumConfirmations: ctx.GlobalUint64(flags.NumDepositConfirmationsFlag.Name),
PostgresHost: ctx.GlobalString(flags.PostgresHostFlag.Name),
PostgresPort: uint16(ctx.GlobalUint64(flags.PostgresPortFlag.Name)),
PostgresUser: ctx.GlobalString(flags.PostgresUserFlag.Name),
PostgresPassword: ctx.GlobalString(flags.PostgresPasswordFlag.Name),
PostgresDBName: ctx.GlobalString(flags.PostgresDBNameFlag.Name),
PostgresEnableSSL: ctx.GlobalBool(flags.PostgresEnableSSLFlag.Name),
}, nil
}
......
......@@ -37,7 +37,7 @@ type TeleportrDisburserDisbursement struct {
// TeleportrDisburserMetaData contains all meta data concerning the TeleportrDisburser contract.
var TeleportrDisburserMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DisbursementFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DisbursementSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nextDepositId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"internalType\":\"structTeleportrDisburser.Disbursement[]\",\"name\":\"_disbursements\",\"type\":\"tuple[]\"}],\"name\":\"disburse\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDisbursements\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x608060405234801561001057600080fd5b5061001a33610024565b6000600155610074565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6109e1806100836000396000f3fe6080604052600436106100655760003560e01c80638da5cb5b116100435780638da5cb5b146100bf578063ad48144d146100f4578063f2fde38b1461010757600080fd5b806325999e7f1461006a5780635fd8c71014610093578063715018a6146100aa575b600080fd5b34801561007657600080fd5b5061008060015481565b6040519081526020015b60405180910390f35b34801561009f57600080fd5b506100a8610127565b005b3480156100b657600080fd5b506100a8610248565b3480156100cb57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008a565b6100a8610102366004610840565b6102d5565b34801561011357600080fd5b506100a86101223660046108bf565b61069b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6000546040805147808252915173ffffffffffffffffffffffffffffffffffffffff9093169283917fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f1919081900360200190a260405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610243573d6000803e3d6000fd5b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b6102d360006107cb565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b80806103be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f2064697362757273656d656e74730000000000000000000000000000000060448201526064016101a4565b60015484811461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e6578706563746564206e657874206465706f73697420696400000000000060448201526064016101a4565b60018054830190556000805b8381101561047757858582818110610450576104506108fc565b610463926040909102013590508361095a565b91508061046f81610972565b915050610436565b50348114610507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f44697362757273656d656e7420746f74616c20213d20616d6f756e742073656e60448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016101a4565b60005b83811015610692576000868683818110610526576105266108fc565b9050604002016000013590506000878784818110610546576105466108fc565b905060400201602001602081019061055e91906108bf565b905060008173ffffffffffffffffffffffffffffffffffffffff16836108fc90604051600060405180830381858888f193505050503d80600081146105bf576040519150601f19603f3d011682016040523d82523d6000602084013e6105c4565b606091505b505090508015610624578173ffffffffffffffffffffffffffffffffffffffff16867feaa22fd2d7b875476355b32cf719794faf9d91b66e73bc6375a053cace9caaee8560405161061791815260200190565b60405180910390a3610676565b8173ffffffffffffffffffffffffffffffffffffffff16867f9b478c095979d3d3a7d602ffd9ee1f0843204d853558ae0882c8fcc0a5bc78cf8560405161066d91815260200190565b60405180910390a35b600186019550505050808061068a90610972565b91505061050a565b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461071c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b73ffffffffffffffffffffffffffffffffffffffff81166107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101a4565b6107c8816107cb565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006040848603121561085557600080fd5b83359250602084013567ffffffffffffffff8082111561087457600080fd5b818601915086601f83011261088857600080fd5b81358181111561089757600080fd5b8760208260061b85010111156108ac57600080fd5b6020830194508093505050509250925092565b6000602082840312156108d157600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561096d5761096d61092b565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156109a4576109a461092b565b506001019056fea2646970667358221220955e65ceaae72ce1d31ed14064916aa5576cb375d1a20fa0959e5a0d69e361fc64736f6c63430008090033",
Bin: "0x608060405234801561001057600080fd5b5061001a33610024565b6000600155610074565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6109e1806100836000396000f3fe6080604052600436106100655760003560e01c80638da5cb5b116100435780638da5cb5b146100bf578063ad48144d146100f4578063f2fde38b1461010757600080fd5b806325999e7f1461006a5780635fd8c71014610093578063715018a6146100aa575b600080fd5b34801561007657600080fd5b5061008060015481565b6040519081526020015b60405180910390f35b34801561009f57600080fd5b506100a8610127565b005b3480156100b657600080fd5b506100a8610248565b3480156100cb57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008a565b6100a8610102366004610840565b6102d5565b34801561011357600080fd5b506100a86101223660046108bf565b61069b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6000546040805147808252915173ffffffffffffffffffffffffffffffffffffffff9093169283917fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f1919081900360200190a260405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610243573d6000803e3d6000fd5b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b6102d360006107cb565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b80806103be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f2064697362757273656d656e74730000000000000000000000000000000060448201526064016101a4565b60015484811461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e6578706563746564206e657874206465706f73697420696400000000000060448201526064016101a4565b60018054830190556000805b8381101561047757858582818110610450576104506108fc565b610463926040909102013590508361095a565b91508061046f81610972565b915050610436565b50348114610507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f44697362757273656d656e7420746f74616c20213d20616d6f756e742073656e60448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016101a4565b60005b83811015610692576000868683818110610526576105266108fc565b9050604002016000013590506000878784818110610546576105466108fc565b905060400201602001602081019061055e91906108bf565b905060008173ffffffffffffffffffffffffffffffffffffffff16836108fc90604051600060405180830381858888f193505050503d80600081146105bf576040519150601f19603f3d011682016040523d82523d6000602084013e6105c4565b606091505b505090508015610624578173ffffffffffffffffffffffffffffffffffffffff16867feaa22fd2d7b875476355b32cf719794faf9d91b66e73bc6375a053cace9caaee8560405161061791815260200190565b60405180910390a3610676565b8173ffffffffffffffffffffffffffffffffffffffff16867f9b478c095979d3d3a7d602ffd9ee1f0843204d853558ae0882c8fcc0a5bc78cf8560405161066d91815260200190565b60405180910390a35b600186019550505050808061068a90610972565b91505061050a565b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461071c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101a4565b73ffffffffffffffffffffffffffffffffffffffff81166107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101a4565b6107c8816107cb565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006040848603121561085557600080fd5b83359250602084013567ffffffffffffffff8082111561087457600080fd5b818601915086601f83011261088857600080fd5b81358181111561089757600080fd5b8760208260061b85010111156108ac57600080fd5b6020830194508093505050509250925092565b6000602082840312156108d157600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561096d5761096d61092b565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156109a4576109a461092b565b506001019056fea26469706673582212209c98cb9cc04bc2bf5e8c0baf23ef87d045122afe6cfbb0e3c31bd854dd7fad7d64736f6c63430008090033",
}
// TeleportrDisburserABI is the input ABI used to generate the binding from.
......
......@@ -33,6 +33,13 @@ func main() {
app.Name = "teleportr"
app.Usage = "Teleportr"
app.Description = "Teleportr bridge from L1 to L2"
app.Commands = []cli.Command{
{
Name: "migrate",
Usage: "Migrates teleportr's database",
Action: teleportr.Migrate(),
},
}
app.Action = teleportr.Main(GitVersion)
err := app.Run(os.Args)
......
......@@ -390,7 +390,8 @@ dep.txn_hash, dep.block_number, dep.block_timestamp,
dis.txn_hash, dis.block_number, dis.block_timestamp
FROM deposits AS dep
LEFT JOIN disbursements AS dis
ON dep.id = dis.id AND dep.txn_hash = $1
ON dep.id = dis.id
WHERE dep.txn_hash = $1
LIMIT 1
`
......@@ -416,7 +417,8 @@ dep.txn_hash, dep.block_number, dep.block_timestamp,
dis.txn_hash, dis.block_number, dis.block_timestamp
FROM deposits AS dep
LEFT JOIN disbursements AS dis
ON dep.id = dis.id AND dep.address = $1
ON dep.id = dis.id
WHERE dep.address = $1
ORDER BY dep.block_timestamp DESC, dep.id DESC
LIMIT 100
`
......
......@@ -139,6 +139,9 @@ func (d *Driver) ClearPendingTx(
func (d *Driver) GetBatchBlockRange(
ctx context.Context) (*big.Int, *big.Int, error) {
// Update balance metrics on each iteration.
d.updateBalanceMetrics(ctx)
// Clear the current deposit IDs from any prior iteration.
d.currentDepositIDs = nil
......@@ -234,6 +237,7 @@ func (d *Driver) CraftBatchTx(
var disbursements []disburse.TeleportrDisburserDisbursement
var depositIDs []uint64
value := new(big.Int)
for _, deposit := range confirmedDeposits {
disbursement := disburse.TeleportrDisburserDisbursement{
Amount: deposit.Amount,
......@@ -241,6 +245,7 @@ func (d *Driver) CraftBatchTx(
}
disbursements = append(disbursements, disbursement)
depositIDs = append(depositIDs, deposit.ID)
value = value.Add(value, deposit.Amount)
}
log.Info(name+" crafting batch tx", "start", start, "end", end,
......@@ -250,7 +255,7 @@ func (d *Driver) CraftBatchTx(
log.Info(name+" batch constructed", "num_disbursements", len(disbursements))
gasPrice, err := d.cfg.L1Client.SuggestGasPrice(ctx)
gasPrice, err := d.cfg.L2Client.SuggestGasPrice(ctx)
if err != nil {
return nil, err
}
......@@ -265,6 +270,7 @@ func (d *Driver) CraftBatchTx(
opts.Nonce = nonce
opts.GasPrice = gasPrice
opts.NoSend = true
opts.Value = value
tx, err := d.disburserContract.Disburse(opts, start, disbursements)
if err != nil {
......@@ -299,6 +305,7 @@ func (d *Driver) UpdateGasPrice(
opts.Context = ctx
opts.Nonce = new(big.Int).SetUint64(tx.Nonce())
opts.GasPrice = gasPrice
opts.Value = tx.Value()
opts.NoSend = true
return d.rawDisburserContract.RawTransact(opts, tx.Data())
......@@ -313,7 +320,7 @@ func (d *Driver) SendTransaction(
txHash := tx.Hash()
startID := d.currentDepositIDs[0]
endID := d.currentDepositIDs[len(d.currentDepositIDs)] + 1
endID := d.currentDepositIDs[len(d.currentDepositIDs)-1] + 1
// Record the pending transaction hash so that we can recover if we crash
// after publishing.
......@@ -426,10 +433,10 @@ func (d *Driver) processPendingTxs(ctx context.Context) error {
"blockTimestamp", blockTimestamp)
}
d.metrics.SuccessfulDisbursements.Set(float64(successfulDisbursements))
d.metrics.FailedDisbursements.Set(float64(failedDisbursements))
d.metrics.SuccessfulDisbursements.Add(float64(successfulDisbursements))
d.metrics.FailedDisbursements.Add(float64(failedDisbursements))
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertDisbursement).
Set(float64(failedUpserts))
Inc()
// We have completed our post-processing once all of the disbursements are
// written without failures.
......@@ -616,7 +623,7 @@ func (d *Driver) logDatabaseContractMismatch(
log.Warn("Recorded disbursements behind contract",
"last_disbursement_id", *lastDisbursementID,
"contract_next_id", contractNextID)
d.metrics.DepositIDMismatch.Set(1.0)
d.metrics.DepositIDMismatch.Inc()
// The last recorded disbursement is ahead of what the contract believes.
// This should NEVER happen unless the sequencer blows up and loses
......@@ -639,7 +646,7 @@ func (d *Driver) logDatabaseContractMismatch(
log.Warn("Recorded disbursements behind contract",
"last_disbursement_id", nil,
"contract_next_id", contractNextID)
d.metrics.DepositIDMismatch.Set(1.0)
d.metrics.DepositIDMismatch.Inc()
// Database and contract indicate we have not done a disbursement.
default:
......@@ -650,10 +657,9 @@ func (d *Driver) logDatabaseContractMismatch(
func (d *Driver) upsertDeposits(deposits []db.Deposit, end uint64) error {
err := d.cfg.Database.UpsertDeposits(deposits, end)
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertDeposits).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertDeposits).Inc()
return err
}
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertDeposits).Set(0.0)
return nil
}
......@@ -662,59 +668,70 @@ func (d *Driver) confirmedDeposits(blockNumber uint64) ([]db.Deposit, error) {
blockNumber, d.cfg.NumConfirmations,
)
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodConfirmedDeposits).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodConfirmedDeposits).Inc()
return nil, err
}
d.metrics.FailedDatabaseMethods.With(DBMethodConfirmedDeposits).Set(0.0)
return confirmedDeposits, nil
}
func (d *Driver) lastProcessedBlock() (*uint64, error) {
lastProcessedBlock, err := d.cfg.Database.LastProcessedBlock()
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodLastProcessedBlock).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodLastProcessedBlock).Inc()
return nil, err
}
d.metrics.FailedDatabaseMethods.With(DBMethodLastProcessedBlock).Set(0.0)
return lastProcessedBlock, nil
}
func (d *Driver) upsertPendingTx(pendingTx db.PendingTx) error {
err := d.cfg.Database.UpsertPendingTx(pendingTx)
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertPendingTx).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertPendingTx).Inc()
return err
}
d.metrics.FailedDatabaseMethods.With(DBMethodUpsertPendingTx).Set(0.0)
return nil
}
func (d *Driver) listPendingTxs() ([]db.PendingTx, error) {
pendingTxs, err := d.cfg.Database.ListPendingTxs()
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodListPendingTxs).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodListPendingTxs).Inc()
return nil, err
}
d.metrics.FailedDatabaseMethods.With(DBMethodListPendingTxs).Set(0.0)
return pendingTxs, nil
}
func (d *Driver) latestDisbursementID() (*uint64, error) {
lastDisbursementID, err := d.cfg.Database.LatestDisbursementID()
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodLatestDisbursementID).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodLatestDisbursementID).Inc()
return nil, err
}
d.metrics.FailedDatabaseMethods.With(DBMethodLatestDisbursementID).Set(0.0)
return lastDisbursementID, nil
}
func (d *Driver) deletePendingTx(startID, endID uint64) error {
err := d.cfg.Database.DeletePendingTx(startID, endID)
if err != nil {
d.metrics.FailedDatabaseMethods.With(DBMethodDeletePendingTx).Set(1.0)
d.metrics.FailedDatabaseMethods.With(DBMethodDeletePendingTx).Inc()
return err
}
d.metrics.FailedDatabaseMethods.With(DBMethodDeletePendingTx).Set(0.0)
return nil
}
func (d *Driver) updateBalanceMetrics(ctx context.Context) {
disburserBal, err := d.cfg.L2Client.BalanceAt(ctx, d.walletAddr, nil)
if err != nil {
log.Error("Error getting disburser wallet balance", "err", err)
disburserBal = big.NewInt(0)
}
depositBal, err := d.cfg.L1Client.BalanceAt(ctx, d.cfg.DepositAddr, nil)
if err != nil {
log.Error("Error getting deposit contract balance", "err", err)
depositBal = big.NewInt(0)
}
d.metrics.DisburserBalance.Set(float64(disburserBal.Uint64()))
d.metrics.DepositContractBalance.Set(float64(depositBal.Uint64()))
}
......@@ -41,7 +41,7 @@ type Metrics struct {
// FailedDatabaseMethods tracks the number of database failures for each
// known database method.
FailedDatabaseMethods *prometheus.GaugeVec
FailedDatabaseMethods *prometheus.CounterVec
// DepositIDMismatch tracks whether or not our database is in sync with the
// disrburser contract. 1 means in sync, 0 means out of sync.
......@@ -53,11 +53,11 @@ type Metrics struct {
// SuccessfulDisbursements tracks the number of disbursements that emit a
// success event from a given tx.
SuccessfulDisbursements prometheus.Gauge
SuccessfulDisbursements prometheus.Counter
// FailedDisbursements tracks the number of disbursements that emit a failed
// event from a given tx.
FailedDisbursements prometheus.Gauge
FailedDisbursements prometheus.Counter
// PostgresLastDisbursedID tracks the latest disbursement id in postgres.
PostgresLastDisbursedID prometheus.Gauge
......@@ -65,6 +65,12 @@ type Metrics struct {
// ContractNextDisbursementID tracks the next disbursement id expected by
// the disburser contract.
ContractNextDisbursementID prometheus.Gauge
// DisburserBalance tracks Teleportr's disburser account balance.
DisburserBalance prometheus.Gauge
// DepositContractBalance tracks Teleportr's deposit contract balance.
DepositContractBalance prometheus.Gauge
}
// NewMetrics initializes a new, extended metrics object.
......@@ -72,7 +78,7 @@ func NewMetrics(subsystem string) *Metrics {
base := metrics.NewBase(subsystem, "")
return &Metrics{
Base: base,
FailedDatabaseMethods: promauto.NewGaugeVec(prometheus.GaugeOpts{
FailedDatabaseMethods: promauto.NewCounterVec(prometheus.CounterOpts{
Name: "failed_database_operations",
Help: "Tracks the number of database failures",
Subsystem: base.SubsystemName(),
......@@ -111,5 +117,15 @@ func NewMetrics(subsystem string) *Metrics {
Help: "Next disbursement id expected by the disburser contract",
Subsystem: base.SubsystemName(),
}),
DisburserBalance: promauto.NewGauge(prometheus.GaugeOpts{
Name: "disburser_balance",
Help: "Balance in Wei of Teleportr's disburser wallet",
Subsystem: base.SubsystemName(),
}),
DepositContractBalance: promauto.NewGauge(prometheus.GaugeOpts{
Name: "deposit_contract_balance",
Help: "Balance in Wei of Teleportr's deposit contract",
Subsystem: base.SubsystemName(),
}),
}
}
......@@ -24,74 +24,18 @@ var (
Required: true,
EnvVar: prefixAPIEnvVar("PORT"),
}
APIL1EthRpcFlag = cli.StringFlag{
Name: "l1-eth-rpc",
Usage: "The endpoint for the L1 ETH provider",
Required: true,
EnvVar: prefixAPIEnvVar("L1_ETH_RPC"),
}
APIDepositAddressFlag = cli.StringFlag{
Name: "deposit-address",
Usage: "Address of the TeleportrDeposit contract",
Required: true,
EnvVar: prefixAPIEnvVar("DEPOSIT_ADDRESS"),
}
APINumConfirmationsFlag = cli.StringFlag{
Name: "num-confirmations",
Usage: "Number of confirmations required until deposits are " +
"considered confirmed",
Required: true,
EnvVar: prefixAPIEnvVar("NUM_CONFIRMATIONS"),
}
APIPostgresHostFlag = cli.StringFlag{
Name: "postgres-host",
Usage: "Host of the teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_HOST"),
}
APIPostgresPortFlag = cli.Uint64Flag{
Name: "postgres-port",
Usage: "Port of the teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_PORT"),
}
APIPostgresUserFlag = cli.StringFlag{
Name: "postgres-user",
Usage: "Username of the teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_USER"),
}
APIPostgresPasswordFlag = cli.StringFlag{
Name: "postgres-password",
Usage: "Password of the teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_PASSWORD"),
}
APIPostgresDBNameFlag = cli.StringFlag{
Name: "postgres-db-name",
Usage: "Database name of the teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_DB_NAME"),
}
APIPostgresEnableSSLFlag = cli.BoolFlag{
Name: "postgres-enable-ssl",
Usage: "Whether or not to enable SSL on connections to " +
"teleportr postgres instance",
Required: true,
EnvVar: prefixAPIEnvVar("POSTGRES_ENABLE_SSL"),
}
)
var APIFlags = []cli.Flag{
APIHostnameFlag,
APIPortFlag,
APIL1EthRpcFlag,
APIDepositAddressFlag,
APINumConfirmationsFlag,
APIPostgresHostFlag,
APIPostgresPortFlag,
APIPostgresUserFlag,
APIPostgresPasswordFlag,
APIPostgresDBNameFlag,
APIPostgresEnableSSLFlag,
L1EthRpcFlag,
DepositAddressFlag,
NumDepositConfirmationsFlag,
PostgresHostFlag,
PostgresPortFlag,
PostgresUserFlag,
PostgresPasswordFlag,
PostgresDBNameFlag,
PostgresEnableSSLFlag,
}
......@@ -126,16 +126,15 @@ var (
Required: true,
EnvVar: prefixEnvVar("POSTGRES_DB_NAME"),
}
/* Optional Flags */
PostgresEnableSSLFlag = cli.BoolFlag{
Name: "postgres-enable-ssl",
Usage: "Whether or not to enable SSL on connections to " +
"teleportr postgres instance",
Required: true,
EnvVar: prefixEnvVar("POSTGRES_ENABLE_SSL"),
EnvVar: prefixEnvVar("POSTGRES_ENABLE_SSL"),
}
/* Optional Flags */
LogLevelFlag = cli.StringFlag{
Name: "log-level",
Usage: "The lowest log level that will be output",
......@@ -208,12 +207,12 @@ var requiredFlags = []cli.Flag{
PostgresUserFlag,
PostgresPasswordFlag,
PostgresDBNameFlag,
PostgresEnableSSLFlag,
}
var optionalFlags = []cli.Flag{
LogLevelFlag,
LogTerminalFlag,
PostgresEnableSSLFlag,
DisburserPrivateKeyFlag,
MnemonicFlag,
DisburserHDPathFlag,
......
......@@ -85,7 +85,7 @@ func Main(gitVersion string) func(ctx *cli.Context) error {
go metrics.RunServer(cfg.MetricsHostname, cfg.MetricsPort)
}
chainID, err := l1Client.ChainID(ctx)
chainID, err := l2Client.ChainID(ctx)
if err != nil {
return err
}
......@@ -120,7 +120,7 @@ func Main(gitVersion string) func(ctx *cli.Context) error {
Driver: teleportrDriver,
PollInterval: cfg.PollInterval,
ClearPendingTx: false,
L1Client: l1Client,
L1Client: l2Client,
TxManagerConfig: txManagerConfig,
})
......@@ -152,3 +152,33 @@ func Main(gitVersion string) func(ctx *cli.Context) error {
return nil
}
}
func Migrate() func(ctx *cli.Context) error {
return func(cliCtx *cli.Context) error {
cfg, err := NewConfig(cliCtx)
if err != nil {
return err
}
log.Info("Initializing teleportr")
database, err := db.Open(db.Config{
Host: cfg.PostgresHost,
Port: uint16(cfg.PostgresPort),
User: cfg.PostgresUser,
Password: cfg.PostgresPassword,
DBName: cfg.PostgresDBName,
EnableSSL: cfg.PostgresEnableSSL,
})
if err != nil {
return err
}
log.Info("Migrating database")
if err := database.Migrate(); err != nil {
return err
}
log.Info("Done")
return nil
}
}
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kovan-replica-0-5-14
commonLabels:
network: kovan
provider: internal
bases:
- ../../envs/kovan-gen5-berlin
resources:
- ../../bases/data-transport-layer
- ../../bases/l2geth-replica
- ../../bases/configmaps
- ../../bases/servicemonitors
- ../../bases/replica-healthcheck
- ./volumes.yaml
images:
- name: ethereumoptimism/data-transport-layer
newName: ethereumoptimism/data-transport-layer
newTag: 0.5.21
- name: ethereumoptimism/l2geth
newName: ethereumoptimism/l2geth
newTag: 0.5.14
- name: ethereumoptimism/replica-healthcheck
newName: ethereumoptimism/replica-healthcheck
newTag: 0.3.3
patchesStrategicMerge:
- ./patches/dtl.yaml
- ./patches/l2geth.yaml
- ./patches/replica-healthcheck.yaml
patches:
- path: ./patches/l2geth-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: l2geth-replica
- path: ./patches/dtl-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: data-transport-layer
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: data-transport-layer
persistentVolumeClaim:
claimName: data-transport-layer-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
value: http://failover-proxyd.default:8080
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
value: http://sequencer.default:8545
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
\ No newline at end of file
- op: replace
path: /spec/template/spec/volumes/0
value:
name: l2geth-replica-data
persistentVolumeClaim:
claimName: l2geth-replica-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: l2geth-replica
spec:
template:
spec:
containers:
- name: l2geth-replica
env:
- name: IPC_DISABLE
value: "false"
resources:
limits:
cpu: "4"
memory: 12Gi
requests:
cpu: "2"
memory: 8Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: replica-healthcheck
spec:
template:
spec:
containers:
- name: replica-healthcheck
env:
- name: REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER
value: http://sequencer.default:8545
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: l2geth-replica-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-transport-layer-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
\ No newline at end of file
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mainnet-replica-0-5-14
commonLabels:
network: mainnet
provider: internal
bases:
- ../../../envs/mainnet-gen5-berlin
- ../../../scripts
resources:
- ../../bases/data-transport-layer
- ../../bases/l2geth-replica
- ../../bases/servicemonitors
- ../../bases/replica-healthcheck
- ./volumes.yaml
images:
- name: ethereumoptimism/data-transport-layer
newName: ethereumoptimism/data-transport-layer
newTag: 0.5.21
- name: ethereumoptimism/l2geth
newName: ethereumoptimism/l2geth
newTag: 0.5.14
- name: ethereumoptimism/replica-healthcheck
newName: ethereumoptimism/replica-healthcheck
newTag: 0.3.6
patchesStrategicMerge:
- ./patches/dtl.yaml
- ./patches/l2geth.yaml
- ./patches/replica-healthcheck.yaml
patches:
- path: ./patches/l2geth-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: l2geth-replica
- path: ./patches/dtl-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: data-transport-layer
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: data-transport-layer
persistentVolumeClaim:
claimName: data-transport-layer-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
value: http://failover-proxyd.default:8080
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
value: http://sequencer.default:8545
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: l2geth-replica-data
persistentVolumeClaim:
claimName: l2geth-replica-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: l2geth-replica
spec:
template:
spec:
containers:
- name: l2geth-replica
env:
- name: IPC_DISABLE
value: "false"
resources:
limits:
cpu: "4"
memory: 12Gi
requests:
cpu: "2"
memory: 8Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: replica-healthcheck
spec:
template:
spec:
containers:
- name: replica-healthcheck
env:
- name: REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER
value: http://sequencer.default:8545
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: l2geth-replica-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-transport-layer-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mainnet-replica-l1-0-5-14
commonLabels:
network: mainnet
provider: internal
sync_source: l1
bases:
- ../../../envs/mainnet-gen5-l1-berlin/
- ../../../scripts
resources:
- ../../bases/data-transport-layer
- ../../bases/l2geth-replica
- ../../bases/servicemonitors
- ../../bases/replica-healthcheck
- ./volumes.yaml
images:
- name: ethereumoptimism/data-transport-layer
newName: ethereumoptimism/data-transport-layer
newTag: 0.5.21
- name: ethereumoptimism/l2geth
newName: ethereumoptimism/l2geth
newTag: 0.5.14
- name: ethereumoptimism/replica-healthcheck
newName: ethereumoptimism/replica-healthcheck
newTag: 0.3.6
patchesStrategicMerge:
- ./patches/dtl.yaml
- ./patches/l2geth.yaml
- ./patches/replica-healthcheck.yaml
patches:
- path: ./patches/l2geth-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: l2geth-replica
- path: ./patches/dtl-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: data-transport-layer
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: data-transport-layer
persistentVolumeClaim:
claimName: data-transport-layer-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
value: http://failover-proxyd.default:8080
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
value: http://sequencer.default:8545
- name: L1_NODE_WEB3_URL
value: http://failover-proxyd.default:8080
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: l2geth-replica-data
persistentVolumeClaim:
claimName: l2geth-replica-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: l2geth-replica
spec:
template:
spec:
containers:
- name: l2geth-replica
env:
- name: IPC_DISABLE
value: "false"
resources:
limits:
cpu: "4"
memory: 12Gi
requests:
cpu: "2"
memory: 8Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: replica-healthcheck
spec:
replicas: 1
template:
spec:
containers:
- name: replica-healthcheck
env:
- name: REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER
value: http://sequencer.default:8545
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: l2geth-replica-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-transport-layer-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kovan-replica-0-5-14
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.global-static-ip-name: kovan-replica-0-5-14
networking.gke.io/managed-certificates: kovan-replica-0-5-14
spec:
rules:
- host: kovan-replica-0-5-14.optimism.io
http:
paths:
- backend:
service:
name: l2geth-replica
port:
name: rpc
path: /
pathType: ImplementationSpecific
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: kovan-replica-0-5-14
spec:
domains:
- kovan-replica-0-5-14.optimism.io
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kovan-replica-0-5-14
commonLabels:
network: kovan
provider: internal
bases:
- ../../../envs/kovan-gen5-berlin
- ../../../scripts
resources:
- ../../bases/data-transport-layer
- ../../bases/l2geth-replica
- ../../bases/servicemonitors
- ../../bases/replica-healthcheck
- ./ingress.yaml
- ./volumes.yaml
images:
- name: ethereumoptimism/data-transport-layer
newName: ethereumoptimism/data-transport-layer
newTag: 0.5.21
- name: ethereumoptimism/l2geth
newName: ethereumoptimism/l2geth
newTag: 0.5.14
- name: ethereumoptimism/replica-healthcheck
newName: ethereumoptimism/replica-healthcheck
newTag: 0.3.6
patchesStrategicMerge:
- ./patches/dtl.yaml
- ./patches/l2geth.yaml
- ./patches/replica-healthcheck.yaml
patches:
- path: ./patches/l2geth-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: l2geth-replica
- path: ./patches/dtl-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: data-transport-layer
\ No newline at end of file
---
- op: replace
path: /spec/template/spec/volumes/0
value:
name: data-transport-layer
persistentVolumeClaim:
claimName: data-transport-layer-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l2-rpc-endpoint
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
\ No newline at end of file
- op: replace
path: /spec/template/spec/volumes/0
value:
name: l2geth-replica-data
persistentVolumeClaim:
claimName: l2geth-replica-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: l2geth-replica
spec:
template:
spec:
containers:
- name: l2geth-replica
env:
- name: IPC_DISABLE
value: "false"
resources:
limits:
cpu: "4"
memory: 12Gi
requests:
cpu: "2"
memory: 8Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: replica-healthcheck
spec:
template:
spec:
containers:
- name: replica-healthcheck
env:
- name: REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER
value: https://kovan.optimism.io
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: l2geth-replica-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-transport-layer-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mainnet-replica-0-5-14
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.global-static-ip-name: mainnet-replica-0-5-14
networking.gke.io/managed-certificates: mainnet-replica-0-5-14
spec:
rules:
- host: mainnet-replica-0-5-14.optimism.io
http:
paths:
- backend:
service:
name: l2geth-replica
port:
name: rpc
path: /
pathType: ImplementationSpecific
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: mainnet-replica-0-5-14
spec:
domains:
- mainnet-replica-0-5-14.optimism.io
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mainnet-replica-0-5-14
commonLabels:
network: mainnet
provider: internal
bases:
- ../../../envs/mainnet-gen5-berlin/
- ../../../scripts
resources:
- ../../bases/data-transport-layer
- ../../bases/l2geth-replica
- ../../bases/servicemonitors
- ../../bases/replica-healthcheck
- ./volumes.yaml
- ./ingress.yaml
images:
- name: ethereumoptimism/data-transport-layer
newName: ethereumoptimism/data-transport-layer
newTag: 0.5.21
- name: ethereumoptimism/l2geth
newName: ethereumoptimism/l2geth
newTag: 0.5.14
- name: ethereumoptimism/replica-healthcheck
newName: ethereumoptimism/replica-healthcheck
newTag: 0.3.3
patchesStrategicMerge:
- ./patches/dtl.yaml
- ./patches/l2geth.yaml
- ./patches/replica-healthcheck.yaml
patches:
- path: ./patches/l2geth-volume.yaml
target:
group: apps
version: v1
kind: StatefulSet
name: l2geth-replica
\ No newline at end of file
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l2-rpc-endpoint
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
\ No newline at end of file
- op: replace
path: /spec/template/spec/volumes/0
value:
name: l2geth-replica-data
persistentVolumeClaim:
claimName: l2geth-replica-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: l2geth-replica
spec:
template:
spec:
containers:
- name: l2geth-replica
command:
- geth
- --config=/l2geth-config/l2geth.toml
- --datadir=$(DATADIR)
- --password=$(DATADIR)/password
- --allow-insecure-unlock
- --unlock=$(BLOCK_SIGNER_ADDRESS)
- --mine
- --miner.etherbase=$(BLOCK_SIGNER_ADDRESS)
- --metrics
- --metrics.influxdb
- --metrics.influxdb.endpoint=http://influxdb.monitoring:8086
- --metrics.influxdb.database=$(NAMESPACE)
resources:
limits:
cpu: "8"
memory: 24Gi
requests:
cpu: "4"
memory: 12Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: data-transport-layer
spec:
template:
spec:
initContainers:
- name: wait-for-l1
env:
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
containers:
- name: data-transport-layer
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
- name: DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT
valueFrom:
secretKeyRef:
name: replica-secrets
key: l2-rpc-endpoint
- name: L1_NODE_WEB3_URL
valueFrom:
secretKeyRef:
name: replica-secrets
key: l1-rpc-endpoint
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: replica-healthcheck
spec:
template:
spec:
containers:
- name: replica-healthcheck
env:
- name: REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER
value: https://mainnet.optimism.io
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: l2geth-replica-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-transport-layer-data
spec:
storageClassName: premium-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
\ No newline at end of file
......@@ -10,8 +10,9 @@ OVMCONTEXT_SPEC_NUM_TXS=1
RUN_WITHDRAWAL_TESTS=false
RUN_DEBUG_TRACE_TESTS=false
RUN_REPLICA_TESTS=false
RUN_HEALTHCHECK_TESTS=false
RUN_STRESS_TESTS=false
# Can be configured up or down as necessary
MOCHA_TIMEOUT=300000
# Set to true to make Mocha stop after the first failed test.
MOCHA_BAIL=false
\ No newline at end of file
MOCHA_BAIL=false
......@@ -67,6 +67,7 @@
"hardhat-gas-reporter": "^1.0.4",
"lint-staged": "11.0.0",
"mocha": "^8.4.0",
"node-fetch": "^2.6.7",
"prom-client": "^14.0.1",
"rimraf": "^3.0.2",
"typescript": "^4.3.5",
......
import fetch from 'node-fetch'
import { expect } from './shared/setup'
import { envConfig } from './shared/utils'
describe('Healthcheck Tests', () => {
before(async function () {
if (!envConfig.RUN_HEALTHCHECK_TESTS) {
this.skip()
}
})
// Super simple test, is the metric server up?
it('should have metrics exposed', async () => {
const response = await fetch(envConfig.HEALTHCHECK_URL)
expect(response.status).to.equal(200)
})
})
......@@ -56,6 +56,8 @@ const procEnv = cleanEnv(process.env, {
VERIFIER_URL: str({ default: 'http://localhost:8547' }),
HEALTHCHECK_URL: str({ default: 'http://localhost:7300/metrics' }),
PRIVATE_KEY: str({
default:
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
......@@ -78,6 +80,9 @@ const procEnv = cleanEnv(process.env, {
RUN_REPLICA_TESTS: bool({
default: true,
}),
RUN_HEALTHCHECK_TESTS: bool({
default: true,
}),
RUN_DEBUG_TRACE_TESTS: bool({
default: true,
}),
......
......@@ -36,30 +36,7 @@ services:
# Env vars for the deployment script.
CONTRACTS_RPC_URL: http://l1_chain:8545
CONTRACTS_DEPLOYER_KEY: 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
CONTRACTS_TARGET_NETWORK: 'custom'
OVM_ADDRESS_MANAGER_OWNER: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266'
OVM_PROPOSER_ADDRESS: '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc'
OVM_SEQUENCER_ADDRESS: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8'
SCC_FRAUD_PROOF_WINDOW: 0
NUM_DEPLOY_CONFIRMATIONS: 0
# skip compilation when run in docker-compose, since the contracts
# were already compiled in the builder step
NO_COMPILE: 1
# Env vars for the dump script.
# Default hardhat account 5
GAS_PRICE_ORACLE_OWNER: '0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc'
# setting the whitelist owner to address(0) disables the whitelist
WHITELIST_OWNER: '0x0000000000000000000000000000000000000000'
L1_FEE_WALLET_ADDRESS: '0x391716d440c151c42cdf1c95c1d83a5427bca52c'
L2_CHAIN_ID: 987
L2_BLOCK_GAS_LIMIT: 15000000
BLOCK_SIGNER_ADDRESS: '0x00000398232E2064F896018496b4b44b3D62751F'
GAS_PRICE_ORACLE_OVERHEAD: 2750
GAS_PRICE_ORACLE_SCALAR: 1500000
GAS_PRICE_ORACLE_L1_BASE_FEE: 1
GAS_PRICE_ORACLE_GAS_PRICE: 1
GAS_PRICE_ORACLE_DECIMALS: 6
CONTRACTS_TARGET_NETWORK: 'local'
ports:
# expose the service to the host for getting the contract addrs
- ${DEPLOYER_PORT:-8080}:8081
......@@ -197,6 +174,23 @@ services:
- ${REPLICA_HTTP_PORT:-8549}:8545
- ${REPLICA_WS_PORT:-8550}:8546
replica-healthcheck:
depends_on:
- l2geth
- replica
deploy:
replicas: 0
build:
context: ..
dockerfile: ./ops/docker/Dockerfile.packages
target: replica-healthcheck
image: ethereumoptimism/replica-healthcheck:${DOCKER_TAG_REPLICA_HEALTHCHECK:-latest}
environment:
HEALTHCHECK__REFERENCE_RPC_PROVIDER: http://l2geth:8545
HEALTHCHECK__TARGET_RPC_PROVIDER: http://replica:8545
ports:
- ${HEALTHCHECK_HTTP_PORT:-7300}:7300
integration_tests:
deploy:
replicas: 0
......@@ -209,6 +203,7 @@ services:
environment:
L1_URL: http://l1_chain:8545
L2_URL: http://l2geth:8545
HEALTHCHECK_URL: http://replica-healthcheck:7300/metrics
REPLICA_URL: http://replica:8545
VERIFIER_URL: http://verifier:8545
URL: http://deployer:8081/addresses.json
......
......@@ -61,5 +61,5 @@ CMD ["npm", "run", "start"]
FROM base as replica-healthcheck
WORKDIR /opts/optimism/packages/replica-healthcheck
WORKDIR /opt/optimism/packages/replica-healthcheck
ENTRYPOINT ["npm", "run", "start"]
FROM golang:1.17.3-alpine3.13 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
COPY ./go/bss-core /go/bss-core
COPY ./go/teleportr/go.mod ./go/teleportr/go.sum /go/teleportr/
WORKDIR /go/teleportr
RUN go mod graph | grep -v bss-core | awk '{if ($1 !~ "@") print $2}' | xargs -n 1 go get
COPY ./go/teleportr/ ./
RUN make teleportr teleportr-api
FROM alpine:3.13
RUN apk add --no-cache ca-certificates jq curl
COPY --from=builder /go/teleportr/teleportr /usr/local/bin/
COPY --from=builder /go/teleportr/teleportr-api /usr/local/bin/
CMD ["teleportr"]
FROM golang:1.17.8-alpine3.15
RUN apk add --no-cache make gcc musl-dev linux-headers git jq curl bash gzip ca-certificates openssh && \
go install gotest.tools/gotestsum@latest && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2
CMD ["bash"]
FROM python:3.8.12-slim-buster
RUN apt-get update && \
apt-get install -y curl openssh-client git build-essential ca-certificates && \
curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh && \
bash nodesource_setup.sh && \
apt-get install -y nodejs && \
npm i -g yarn && \
npm i -g depcheck && \
pip install slither-analyzer
......@@ -24,39 +24,7 @@ curl \
echo "Connected to L1."
echo "Building deployment command."
DEPLOY_CMD="npx hardhat deploy"
# Helper method to concatenate things onto $DEPLOY_CMD.
# Usage: concat_cmd "str-to-concat"
function concat_cmd() {
DEPLOY_CMD="$DEPLOY_CMD $1"
}
# Helper method to conditionally concatenate CLI arguments
# when a given env var is defined.
# Usage: concat_arg "--arg-name" "env-var-name"
function concat_arg() {
ARG=$1
ENV_VAR=$2
if [ -n "${!ENV_VAR+x}" ]; then
echo "$ENV_VAR set to ${!ENV_VAR}, applying $ARG argument."
concat_cmd "$ARG \"${!ENV_VAR}\""
else
echo "$ENV_VAR is not not set, skipping $ARG argument."
fi
}
concat_arg "--network" "CONTRACTS_TARGET_NETWORK"
concat_arg "--ovm-address-manager-owner" "OVM_ADDRESS_MANAGER_OWNER"
concat_arg "--ovm-proposer-address" "OVM_PROPOSER_ADDRESS"
concat_arg "--ovm-sequencer-address" "OVM_SEQUENCER_ADDRESS"
concat_arg "--l1-block-time-seconds" "L1_BLOCK_TIME_SECONDS"
concat_arg "--ctc-max-transaction-gas-limit" "CTC_MAX_TRANSACTION_GAS_LIMIT"
concat_arg "--ctc-l2-gas-discount-divisor" "CTC_L2_GAS_DISCOUNT_DIVISOR"
concat_arg "--ctc-enqueue-gas-cost" "CTC_ENQUEUE_GAS_COST"
concat_arg "--scc-fraud-proof-window" "SCC_FRAUD_PROOF_WINDOW"
concat_arg "--num-deploy-confirmations" "NUM_DEPLOY_CONFIRMATIONS"
concat_arg "--forked" "FORKED"
DEPLOY_CMD="npx hardhat deploy --network $CONTRACTS_TARGET_NETWORK"
echo "Deploying contracts. Deployment command:"
echo "$DEPLOY_CMD"
......@@ -81,20 +49,13 @@ echo "}" >> addresses.json
echo "Built addresses.json. Content:"
jq . addresses.json
echo "Env vars for the dump script:"
export L1_STANDARD_BRIDGE_ADDRESS=$(cat "./addresses.json" | jq -r .Proxy__OVM_L1StandardBridge)
export L1_CROSS_DOMAIN_MESSENGER_ADDRESS=$(cat "./addresses.json" | jq -r .Proxy__OVM_L1CrossDomainMessenger)
echo "ADDRESS_MANAGER_ADDRESS=$ADDRESS_MANAGER_ADDRESS"
echo "L1_STANDARD_BRIDGE_ADDRESS=$L1_STANDARD_BRIDGE_ADDRESS"
echo "L1_CROSS_DOMAIN_MESSENGER_ADDRESS=$L1_CROSS_DOMAIN_MESSENGER_ADDRESS"
echo "Building dump file."
yarn run build:dump
mv addresses.json ./dist/dumps
npx hardhat take-dump --network $CONTRACTS_TARGET_NETWORK
mv addresses.json ./genesis
cp ./genesis/$CONTRACTS_TARGET_NETWORK.json ./genesis/state-dump.latest.json
# service the addresses and dumps
echo "Starting server."
python3 -m http.server \
--bind "0.0.0.0" 8081 \
--directory ./dist/dumps
--directory ./genesis
......@@ -23,4 +23,4 @@ curl \
--output /dev/null \
$L2_URL
npx hardhat test --network optimism --no-compile
npx hardhat test --network optimism --no-compile "$@"
#!/bin/bash
CONTAINER=l2geth
RETRIES=30
RETRIES=90
i=0
until docker-compose logs l2geth | grep -q "Starting Sequencer Loop";
do
sleep 3
sleep 1
if [ $i -eq $RETRIES ]; then
echo 'Timed out waiting for sequencer'
break
......
/* Imports: External */
import { Server } from 'net'
import Config from 'bcfg'
import * as dotenv from 'dotenv'
import { Command, Option } from 'commander'
import { ValidatorSpec, Spec, cleanEnv } from 'envalid'
import { sleep } from '@eth-optimism/core-utils'
import snakeCase from 'lodash/snakeCase'
import express from 'express'
import prometheus, { Registry } from 'prom-client'
/* Imports: Internal */
import { Logger } from '../common/logger'
import { Metric } from './metrics'
......@@ -82,6 +84,26 @@ export abstract class BaseServiceV2<
*/
protected readonly metrics: TMetrics
/**
* Registry for prometheus metrics.
*/
protected readonly metricsRegistry: Registry
/**
* Metrics server.
*/
protected metricsServer: Server
/**
* Port for the metrics server.
*/
protected readonly metricsServerPort: number
/**
* Hostname for the metrics server.
*/
protected readonly metricsServerHostname: string
/**
* @param params Options for the construction of the service.
* @param params.name Name for the service. This name will determine the prefix used for logging,
......@@ -93,6 +115,8 @@ export abstract class BaseServiceV2<
* @param params.options Options to pass to the service.
* @param params.loops Whether or not the service should loop. Defaults to true.
* @param params.loopIntervalMs Loop interval in milliseconds. Defaults to zero.
* @param params.metricsServerPort Port for the metrics server. Defaults to 7300.
* @param params.metricsServerHostname Hostname for the metrics server. Defaults to 0.0.0.0.
*/
constructor(params: {
name: string
......@@ -101,6 +125,8 @@ export abstract class BaseServiceV2<
options?: Partial<TOptions>
loop?: boolean
loopIntervalMs?: number
metricsServerPort?: number
metricsServerHostname?: string
}) {
this.loop = params.loop !== undefined ? params.loop : true
this.loopIntervalMs =
......@@ -203,6 +229,11 @@ export abstract class BaseServiceV2<
return acc
}, {}) as TMetrics
// Create the metrics server.
this.metricsRegistry = prometheus.register
this.metricsServerPort = params.metricsServerPort || 7300
this.metricsServerHostname = params.metricsServerHostname || '0.0.0.0'
this.logger = new Logger({ name: params.name })
// Gracefully handle stop signals.
......@@ -222,6 +253,33 @@ export abstract class BaseServiceV2<
public async run(): Promise<void> {
this.done = false
// Start the metrics server if not yet running.
if (!this.metricsServer) {
this.logger.info('starting metrics server')
await new Promise((resolve) => {
const app = express()
app.get('/metrics', async (_, res) => {
res.status(200).send(await this.metricsRegistry.metrics())
})
this.metricsServer = app.listen(
this.metricsServerPort,
this.metricsServerHostname,
() => {
resolve(null)
}
)
})
this.logger.info(`metrics started`, {
port: this.metricsServerPort,
hostname: this.metricsServerHostname,
route: '/metrics',
})
}
if (this.init) {
this.logger.info('initializing service')
await this.init()
......@@ -267,7 +325,18 @@ export abstract class BaseServiceV2<
while (!this.done) {
await sleep(1000)
}
this.logger.info('main loop finished, goodbye!')
// Shut down the metrics server if it's running.
if (this.metricsServer) {
this.logger.info('stopping metrics server')
await new Promise((resolve) => {
this.metricsServer.close(() => {
resolve(null)
})
})
this.logger.info('metrics server stopped')
this.metricsServer = undefined
}
}
/**
......
# Name for the network to deploy to ("mainnet", "kovan", etc.)
CONTRACTS_TARGET_NETWORK=
# Private key that will send deployment transactions
CONTRACTS_DEPLOYER_KEY=
# RPC URL connected to the L1 chain we're deploying to
CONTRACTS_RPC_URL=
# Your Etherscan API key for the L1 network
ETHERSCAN_API_KEY=
module.exports = {
extends: '../../.eslintrc.js',
ignorePatterns: [
'src/contract-artifacts.ts',
'src/contract-deployed-artifacts.ts',
],
}
......@@ -32,7 +32,9 @@ import { L1CrossDomainMessenger } from "@eth-optimism/contracts/L1/messaging/L1C
```
## Guide for Developers
### Setup
Install the following:
- [`Node.js` (14+)](https://nodejs.org/en/)
- [`npm`](https://www.npmjs.com/get-npm)
......@@ -46,87 +48,75 @@ cd contracts
```
Install `npm` packages:
```shell
yarn install
```
### Running Tests
Tests are executed via `yarn`:
```shell
yarn test
```
Run specific tests by giving a path to the file you want to run:
```shell
yarn test ./test/path/to/my/test.spec.ts
```
### Measuring test coverage:
```shell
yarn test:coverage
```
The output is most easily viewable by opening the html file in your browser:
```shell
open ./coverage/index.html
```
### Compiling and Building
Easiest way is to run the primary build script:
```shell
yarn build
```
Running the full build command will perform the following actions:
1. `build:contracts` - Compile all Solidity contracts with both the EVM and OVM compilers.
2. `build:typescript` - Builds the typescript files that are used to export utilities into js.
3. `build:copy` - Copies various other files into the dist folder.
4. `build:dump` - Generates a genesis state from the contracts that L2 geth will use.
5. `build:typechain` - Generates [TypeChain](https://github.com/ethereum-ts/TypeChain) artifacts.
Compile and build the various required with the `build` command:
You can also build specific components as follows:
```shell
yarn build:contracts
yarn build
```
### Deploying the Contracts
#### Required environment variables
You must set the following environment variables to execute a deployment:
```bash
# Name for the network to deploy to ("mainnet", "kovan", etc.)
export CONTRACTS_TARGET_NETWORK=...
# Private key that will send deployment transactions
export CONTRACTS_DEPLOYER_KEY=...
You must set several required environment variables before you can execute a deployment.
Duplicate the file [`.env.example`](./.env.example) and rename your duplicate to `.env`.
Fill out each of the environment variables before continuing.
# RPC URL connected to the L1 chain we're deploying to
export CONTRACTS_RPC_URL=...
#### Creating a deployment configuration
# Your Etherscan API key for the L1 network
export ETHERSCAN_API_KEY=...
```
#### Creating a deployment script
Before you can carry out a deployment, you must create a deployment configuration file inside of the [deploy-config](./deploy-config/) folder.
Deployment configuration files are TypeScript files that export an object that conforms to the `DeployConfig` type.
See [mainnet.ts](./deploy-config/mainnet.ts) for an example deployment configuration.
We recommend duplicating an existing deployment config and modifying it to satisfy your requirements.
Before you can carry out a deployment, you must create a deployment script.
See [mainnet.sh](./scripts/deploy-scripts/mainnet.sh) for an example deployment script.
We recommend duplicating an existing deployment script and modifying it to satisfy your requirements.
#### Executing a deployment
Most variables within the deploy script are relatively self-explanatory.
If you intend to upgrade an existing system you **MUST** [include the following argument](https://github.com/ethereum-optimism/optimism/blob/6f633f915b34a46ac14430724bed9722af8bd05e/packages/contracts/scripts/deploy-scripts/mainnet.sh#L33) in the deploy script:
Once you've created your deploy config, you can execute a deployment with the following command:
```
--tags upgrade
npx hardhat deploy --network <my network name>
```
If you are deploying a system from scratch, you should **NOT** include `--tags upgrade` or you will fail to deploy several contracts.
Note that this only applies to fresh deployments.
If you want to upgrade an existing system (instead of deploying a new system from scratch), you must use the following command instead:
#### Executing a deployment
```
npx hardhat deploy --network <my network name> --tags upgrade
```
Once you've created your deploy script, simply run the script to trigger a deployment.
During the deployment process, you will be asked to transfer ownership of several contracts to a special contract address.
You will also be asked to verify various configuration values.
This is a safety mechanism to make sure that actions within an upgrade are performed atomically.
......@@ -134,19 +124,29 @@ Ownership of these addresses will be automatically returned to the original owne
The original owner can always recover ownership from the upgrade contract in an emergency.
Please read these instructions carefully, verify each of the presented configuration values, and carefully confirm that the contract you are giving ownership to has not been compromised (e.g., check the code on Etherscan).
After your deployment is complete, your new contracts will be written to an artifacts directory in `./deployments/<name>`.
Your contracts will also be automatically verified as part of the deployment script.
After your deployment is complete, your new contracts will be written to an artifacts directory in `./deployments/<my network name>`.
#### Verifying contract source code
Contracts will be automatically verified via both [Etherscan](https://etherscan.io) and [Sourcify](https://sourcify.dev/) during the deployment process.
If there was an issue with verification during the deployment, you can manually verify your contracts with the command:
```
npx hardhat etherscan-verify --network <my network name>
```
#### Creating a genesis file
Optimism expects that certain contracts (called "predeploys") be deployed to the L2 network at pre-determined addresses.
Doing this requires that you generate a special genesis file to be used by your corresponding L2Geth nodes.
You must first create a genesis generation script.
Like in the deploy script, we recommend starting from an [existing script](./scripts/deploy-scripts/mainnet-genesis.sh).
Modify each of the values within this script to match the values of your own deployment, taking any L1 contract addresses from the `./deployments/<name>` folder that was just generated or modified.
We guarantee this by creating a genesis file in which certain contracts are already within the L2 state at the genesis block.
To create the genesis file for your network, you must first deploy the L1 contracts using the appropriate commands from above.
Once you've deployed your contracts, run the following command:
```
npx hardhat take-dump --network <my network name>
```
Execute this script to generate the genesis file.
You will find this genesis file at `./dist/dumps/state-dump.latest.json`.
A genesis file will be created for you at `/genesis/<my network name>.json`.
You can then ingest this file via `geth init`.
### Hardhat tasks
......
/* External Imports */
import * as fs from 'fs'
import * as path from 'path'
import * as mkdirp from 'mkdirp'
const ensure = (value, key) => {
if (typeof value === 'undefined' || value === null || Number.isNaN(value)) {
throw new Error(`${key} is undefined, null or NaN`)
}
}
/* Internal Imports */
import { makeL2GenesisFile } from '../src/make-genesis'
;(async () => {
const outdir = path.resolve(__dirname, '../dist/dumps')
const outfile = path.join(outdir, 'state-dump.latest.json')
mkdirp.sync(outdir)
const env = process.env
// An account that represents the owner of the whitelist
const whitelistOwner = env.WHITELIST_OWNER
// The gas price oracle owner, can update values is GasPriceOracle L2 predeploy
const gasPriceOracleOwner = env.GAS_PRICE_ORACLE_OWNER
// The initial overhead value for the GasPriceOracle
const gasPriceOracleOverhead = parseInt(
env.GAS_PRICE_ORACLE_OVERHEAD || '2750',
10
)
// The initial scalar value for the GasPriceOracle. The actual
// scalar is scaled downwards by the number of decimals
const gasPriceOracleScalar = parseInt(
env.GAS_PRICE_ORACLE_SCALAR || '1500000',
10
)
// The initial decimals that scale down the scalar in the GasPriceOracle
const gasPriceOracleDecimals = parseInt(
env.GAS_PRICE_ORACLE_DECIMALS || '6',
10
)
// The initial L1 base fee in the GasPriceOracle. This determines how
// expensive the L1 portion of the transaction fee is.
const gasPriceOracleL1BaseFee = parseInt(
env.GAS_PRICE_ORACLE_L1_BASE_FEE || '1',
10
)
// The initial L2 gas price set in the GasPriceOracle
const gasPriceOracleGasPrice = parseInt(
env.GAS_PRICE_ORACLE_GAS_PRICE || '1',
10
)
// The L2 block gas limit, used in the L2 block headers as well to limit
// the amount of execution for a single block.
const l2BlockGasLimit = parseInt(env.L2_BLOCK_GAS_LIMIT, 10)
// The L2 chain id, added to the chain config
const l2ChainId = parseInt(env.L2_CHAIN_ID, 10)
// The block signer address, added to the block extradata for clique consensus
const blockSignerAddress = env.BLOCK_SIGNER_ADDRESS
// The L1 standard bridge address for cross domain messaging
const l1StandardBridgeAddress = env.L1_STANDARD_BRIDGE_ADDRESS
// The L1 fee wallet address, used to restrict the account that fees on L2 can
// be withdrawn to on L1
const l1FeeWalletAddress = env.L1_FEE_WALLET_ADDRESS
// The L1 cross domain messenger address, used for cross domain messaging
const l1CrossDomainMessengerAddress = env.L1_CROSS_DOMAIN_MESSENGER_ADDRESS
// The block height at which the berlin hardfork activates
const berlinBlock = parseInt(env.BERLIN_BLOCK, 10) || 0
ensure(whitelistOwner, 'WHITELIST_OWNER')
ensure(gasPriceOracleOwner, 'GAS_PRICE_ORACLE_OWNER')
ensure(l2BlockGasLimit, 'L2_BLOCK_GAS_LIMIT')
ensure(l2ChainId, 'L2_CHAIN_ID')
ensure(blockSignerAddress, 'BLOCK_SIGNER_ADDRESS')
ensure(l1StandardBridgeAddress, 'L1_STANDARD_BRIDGE_ADDRESS')
ensure(l1FeeWalletAddress, 'L1_FEE_WALLET_ADDRESS')
ensure(l1CrossDomainMessengerAddress, 'L1_CROSS_DOMAIN_MESSENGER_ADDRESS')
ensure(berlinBlock, 'BERLIN_BLOCK')
// Basic warning so users know that the whitelist will be disabled if the owner is the zero address.
if (env.WHITELIST_OWNER === '0x' + '00'.repeat(20)) {
console.log(
'WARNING: whitelist owner is address(0), whitelist will be disabled'
)
}
const genesis = await makeL2GenesisFile({
whitelistOwner,
gasPriceOracleOwner,
gasPriceOracleOverhead,
gasPriceOracleScalar,
gasPriceOracleL1BaseFee,
gasPriceOracleGasPrice,
gasPriceOracleDecimals,
l2BlockGasLimit,
l2ChainId,
blockSignerAddress,
l1StandardBridgeAddress,
l1FeeWalletAddress,
l1CrossDomainMessengerAddress,
berlinBlock,
})
fs.writeFileSync(outfile, JSON.stringify(genesis, null, 4))
})()
import { DeployConfig } from '../src/deploy-config'
const config: DeployConfig = {
network: 'goerli',
l1BlockTimeSeconds: 15,
l2BlockGasLimit: 15_000_000,
l2ChainId: 420,
ctcL2GasDiscountDivisor: 32,
ctcEnqueueGasCost: 60_000,
sccFaultProofWindowSeconds: 604800,
sccSequencerPublishWindowSeconds: 12592000,
ovmSequencerAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244',
ovmProposerAddress: '0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3',
ovmBlockSignerAddress: '0x27770a9694e4B4b1E130Ab91Bc327C36855f612E',
ovmFeeWalletAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244',
ovmAddressManagerOwner: '0x32b70c156302d28A9119445d2bbb9ab1cBD01671',
ovmGasPriceOracleOwner: '0x84f70449f90300997840eCb0918873745Ede7aE6',
}
export default config
import { DeployConfig } from '../src/deploy-config'
const config: DeployConfig = {
network: 'kovan',
numDeployConfirmations: 1,
gasPrice: 5_000_000_000,
l1BlockTimeSeconds: 15,
l2BlockGasLimit: 15_000_000,
l2ChainId: 69,
ctcL2GasDiscountDivisor: 32,
ctcEnqueueGasCost: 60_000,
sccFaultProofWindowSeconds: 10,
sccSequencerPublishWindowSeconds: 12592000,
ovmSequencerAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244',
ovmProposerAddress: '0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3',
ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F',
ovmFeeWalletAddress: '0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244',
ovmAddressManagerOwner: '0x18394B52d3Cb931dfA76F63251919D051953413d',
ovmGasPriceOracleOwner: '0x84f70449f90300997840eCb0918873745Ede7aE6',
}
export default config
import { DeployConfig } from '../src/deploy-config'
const config: DeployConfig = {
network: 'local',
l1BlockTimeSeconds: 15,
l2BlockGasLimit: 15_000_000,
l2ChainId: 987,
ctcL2GasDiscountDivisor: 32,
ctcEnqueueGasCost: 60_000,
sccFaultProofWindowSeconds: 0,
sccSequencerPublishWindowSeconds: 12592000,
ovmSequencerAddress: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
ovmProposerAddress: '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc',
ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F',
ovmFeeWalletAddress: '0x391716d440c151c42cdf1c95c1d83a5427bca52c',
ovmAddressManagerOwner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
ovmGasPriceOracleOwner: '0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc',
}
export default config
import { DeployConfig } from '../src/deploy-config'
const config: DeployConfig = {
network: 'mainnet',
numDeployConfirmations: 4,
gasPrice: 150_000_000_000,
l1BlockTimeSeconds: 15,
l2BlockGasLimit: 15_000_000,
l2ChainId: 10,
ctcL2GasDiscountDivisor: 32,
ctcEnqueueGasCost: 60_000,
sccFaultProofWindowSeconds: 604800,
sccSequencerPublishWindowSeconds: 12592000,
ovmSequencerAddress: '0x6887246668a3b87F54DeB3b94Ba47a6f63F32985',
ovmProposerAddress: '0x473300df21D047806A082244b417f96b32f13A33',
ovmBlockSignerAddress: '0x00000398232E2064F896018496b4b44b3D62751F',
ovmFeeWalletAddress: '0x391716d440c151c42cdf1c95c1d83a5427bca52c',
ovmAddressManagerOwner: '0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A',
ovmGasPriceOracleOwner: '0x7107142636C85c549690b1Aca12Bdb8052d26Ae6',
ovmWhitelistOwner: '0x648E3e8101BFaB7bf5997Bd007Fb473786019159',
}
export default config
......@@ -9,10 +9,12 @@ import {
sendImpersonatedTx,
BIG_BALANCE,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
if ((hre as any).deployConfig.forked !== 'true') {
const deployConfig = getDeployConfig(hre.network.name)
if (!deployConfig.isForkedNetwork) {
return
}
......
......@@ -2,18 +2,20 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { names } from '../src/address-names'
import { getDeployConfig } from '../src/deploy-config'
/* Imports: External */
const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const deployConfig = getDeployConfig(hre.network.name)
await deploy(names.unmanaged.Lib_AddressManager, {
from: deployer,
args: [],
log: true,
waitConfirmations: (hre as any).deployConfig.numDeployConfirmations,
waitConfirmations: deployConfig.numDeployConfirmations,
})
}
......
......@@ -6,9 +6,12 @@ import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const Lib_AddressManager = await getContractFromArtifact(
hre,
names.unmanaged.Lib_AddressManager
......@@ -19,9 +22,9 @@ const deployFn: DeployFunction = async (hre) => {
name: names.managed.contracts.CanonicalTransactionChain,
args: [
Lib_AddressManager.address,
(hre as any).deployConfig.ctcMaxTransactionGasLimit,
(hre as any).deployConfig.ctcL2GasDiscountDivisor,
(hre as any).deployConfig.ctcEnqueueGasCost,
deployConfig.l2BlockGasLimit,
deployConfig.ctcL2GasDiscountDivisor,
deployConfig.ctcEnqueueGasCost,
],
})
}
......
......@@ -6,9 +6,12 @@ import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const Lib_AddressManager = await getContractFromArtifact(
hre,
names.unmanaged.Lib_AddressManager
......@@ -19,8 +22,8 @@ const deployFn: DeployFunction = async (hre) => {
name: names.managed.contracts.StateCommitmentChain,
args: [
Lib_AddressManager.address,
(hre as any).deployConfig.sccFraudProofWindow,
(hre as any).deployConfig.sccSequencerPublishWindow,
deployConfig.sccFaultProofWindowSeconds,
deployConfig.sccSequencerPublishWindowSeconds,
],
})
}
......
......@@ -7,9 +7,12 @@ import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const Lib_AddressManager = await getContractFromArtifact(
hre,
names.unmanaged.Lib_AddressManager
......@@ -45,7 +48,7 @@ const deployFn: DeployFunction = async (hre) => {
console.log(
`Transferring ownership of L1CrossDomainMessenger (implementation)...`
)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
const owner = deployConfig.ovmAddressManagerOwner
await contract.transferOwnership(owner)
console.log(`Checking that contract owner was correctly set...`)
......
......@@ -7,10 +7,13 @@ import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
import { predeploys } from '../src/predeploys'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const Lib_AddressManager = await getContractFromArtifact(
hre,
names.unmanaged.Lib_AddressManager
......@@ -42,13 +45,13 @@ const deployFn: DeployFunction = async (hre) => {
// CanonicalTransactionChain.
{
name: names.managed.accounts.OVM_Sequencer,
address: (hre as any).deployConfig.ovmSequencerAddress,
address: deployConfig.ovmSequencerAddress,
},
// OVM_Proposer is the address allowed to submit state roots (transaction results) to the
// StateCommitmentChain.
{
name: names.managed.accounts.OVM_Proposer,
address: (hre as any).deployConfig.ovmProposerAddress,
address: deployConfig.ovmProposerAddress,
},
]
......@@ -69,7 +72,7 @@ const deployFn: DeployFunction = async (hre) => {
name: names.unmanaged.AddressDictator,
args: [
Lib_AddressManager.address,
(hre as any).deployConfig.ovmAddressManagerOwner,
deployConfig.ovmAddressManagerOwner,
namesAndAddresses.map((pair) => {
return pair.name
}),
......
......@@ -4,9 +4,11 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'
/* Imports: Internal */
import { getContractFromArtifact } from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const { deployer } = await hre.getNamedAccounts()
// There's a risk that we could get front-run during a fresh deployment, which would brick this
......@@ -43,7 +45,7 @@ const deployFn: DeployFunction = async (hre) => {
)
console.log(`Setting Proxy__OVM_L1CrossDomainMessenger owner...`)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
const owner = deployConfig.ovmAddressManagerOwner
await Proxy__OVM_L1CrossDomainMessenger.transferOwnership(owner)
console.log(`Checking that the contract owner was correctly set...`)
......
......@@ -9,9 +9,12 @@ import {
getContractFromArtifact,
deployAndVerifyAndThen,
} from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const Proxy__OVM_L1StandardBridge = await getContractFromArtifact(
hre,
'Proxy__OVM_L1StandardBridge'
......@@ -31,7 +34,7 @@ const deployFn: DeployFunction = async (hre) => {
name: names.unmanaged.ChugSplashDictator,
args: [
Proxy__OVM_L1StandardBridge.address,
(hre as any).deployConfig.ovmAddressManagerOwner,
deployConfig.ovmAddressManagerOwner,
ethers.utils.keccak256(bridgeCode),
ethers.utils.hexZeroPad('0x00', 32),
ethers.utils.hexZeroPad(Proxy__OVM_L1CrossDomainMessenger.address, 32),
......
......@@ -4,9 +4,12 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'
/* Imports: Internal */
import { getContractFromArtifact } from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
const deployFn: DeployFunction = async (hre) => {
const deployConfig = getDeployConfig(hre.network.name)
const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getContractFromArtifact(
hre,
'Lib_AddressManager',
......@@ -15,7 +18,7 @@ const deployFn: DeployFunction = async (hre) => {
}
)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
const owner = deployConfig.ovmAddressManagerOwner
const remoteOwner = await Lib_AddressManager.owner()
if (hexStringEquals(owner, remoteOwner)) {
console.log(
......
{
"address": "0x4821975ca220601c153d02353300d6ad34adc362",
"abi": [
{
"inputs": [
{
"internalType": "uint256",
"name": "_minDepositAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxDepositAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxBalance",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "balance",
"type": "uint256"
}
],
"name": "BalanceWithdrawn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "depositId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "emitter",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "EtherReceived",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousBalance",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newBalance",
"type": "uint256"
}
],
"name": "MaxBalanceSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newAmount",
"type": "uint256"
}
],
"name": "MaxDepositAmountSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newAmount",
"type": "uint256"
}
],
"name": "MinDepositAmountSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "c__0xbf18ea64",
"type": "bytes32"
}
],
"name": "c_0xbf18ea64",
"outputs": [],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "maxBalance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxDepositAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minDepositAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxDepositAmount",
"type": "uint256"
}
],
"name": "setMaxAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxBalance",
"type": "uint256"
}
],
"name": "setMaxBalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_minDepositAmount",
"type": "uint256"
}
],
"name": "setMinAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalDeposits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawBalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"receipt": {
"to": null,
"from": "0x6c2cBc2132aB6Fc48Ebf3569Bdde7B0AA34aa0FC",
"contractAddress": "0x170E152DeDADaa7fE028b025B18748cbab7083bD",
"transactionIndex": 1,
"gasUsed": "1286769",
"logsBloom": "0x00000000000000000000000010000000000000000000000000800000000000000100000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400080000000000000000000000000000040000000000000000000000000000000000000040000000000000000000000000000000000020000000000000000000000000000000000000200000000000000400000000020000000040000000020000000000000000010000000000000008000000000000000000000000000020000",
"blockHash": "0xb2eb3e02f35921cd1201f5a5eecbdf61c6f8196b174fb057e442fc2c85d2635f",
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"logs": [
{
"transactionIndex": 1,
"blockNumber": 30510065,
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"address": "0x170E152DeDADaa7fE028b025B18748cbab7083bD",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000006c2cbc2132ab6fc48ebf3569bdde7b0aa34aa0fc"
],
"data": "0x",
"logIndex": 1,
"blockHash": "0xb2eb3e02f35921cd1201f5a5eecbdf61c6f8196b174fb057e442fc2c85d2635f"
},
{
"transactionIndex": 1,
"blockNumber": 30510065,
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"address": "0x170E152DeDADaa7fE028b025B18748cbab7083bD",
"topics": [
"0x65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000",
"logIndex": 2,
"blockHash": "0xb2eb3e02f35921cd1201f5a5eecbdf61c6f8196b174fb057e442fc2c85d2635f"
},
{
"transactionIndex": 1,
"blockNumber": 30510065,
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"address": "0x170E152DeDADaa7fE028b025B18748cbab7083bD",
"topics": [
"0xb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000",
"logIndex": 3,
"blockHash": "0xb2eb3e02f35921cd1201f5a5eecbdf61c6f8196b174fb057e442fc2c85d2635f"
},
{
"transactionIndex": 1,
"blockNumber": 30510065,
"transactionHash": "0x83a2775ed8bc832e1a4ae46b003b5b0987a4163cc79224d65fc9c38875f0b452",
"address": "0x170E152DeDADaa7fE028b025B18748cbab7083bD",
"topics": [
"0x185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea00000",
"logIndex": 4,
"blockHash": "0xb2eb3e02f35921cd1201f5a5eecbdf61c6f8196b174fb057e442fc2c85d2635f"
}
],
"blockNumber": 30510065,
"cumulativeGasUsed": "1322127",
"status": 1,
"byzantium": true
},
"args": [
"1000000000000000",
"1000000000000000000",
"1000000000000000000000"
],
"solcInputHash": "f20d616c1af6713a0e8ca9fae9d7bae7",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBalance\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"emitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EtherReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"MaxBalanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newAmount\",\"type\":\"uint256\"}],\"name\":\"MaxDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newAmount\",\"type\":\"uint256\"}],\"name\":\"MinDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"c__0xbf18ea64\",\"type\":\"bytes32\"}],\"name\":\"c_0xbf18ea64\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBalance\",\"type\":\"uint256\"}],\"name\":\"setMaxBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMinAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDeposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"params\":{\"balance\":\"The current contract balance paid to the owner.\",\"owner\":\"The current owner and recipient of the funds.\"}},\"EtherReceived(uint256,address,uint256)\":{\"params\":{\"amount\":\"The amount deposited by the payer.\",\"depositId\":\"A unique sequencer number identifying the deposit.\",\"emitter\":\"The sending address of the payer.\"}},\"MaxBalanceSet(uint256,uint256)\":{\"params\":{\"newBalance\":\"The new maximum contract balance.\",\"previousBalance\":\"The previous maximum contract balance.\"}},\"MaxDepositAmountSet(uint256,uint256)\":{\"params\":{\"newAmount\":\"The new maximum deposit amount.\",\"previousAmount\":\"The previous maximum deposit amount.\"}},\"MinDepositAmountSet(uint256,uint256)\":{\"params\":{\"newAmount\":\"The new minimum deposit amount.\",\"previousAmount\":\"The previous minimum deposit amount.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_maxBalance\":\"The initial maximum contract balance.\",\"_maxDepositAmount\":\"The initial maximum deposit amount.\",\"_minDepositAmount\":\"The initial minimum deposit amount.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setMaxAmount(uint256)\":{\"params\":{\"_maxDepositAmount\":\"The new maximum deposit amount.\"}},\"setMaxBalance(uint256)\":{\"params\":{\"_maxBalance\":\"The new maximum contract balance.\"}},\"setMinAmount(uint256)\":{\"params\":{\"_minDepositAmount\":\"The new minimum deposit amount.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"TeleportrDeposit Shout out to 0xclem for providing the inspiration for this contract: https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol\",\"version\":1},\"userdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"notice\":\"Emitted any time the balance is withdrawn by the owner.\"},\"EtherReceived(uint256,address,uint256)\":{\"notice\":\"Emitted any time a successful deposit is received.\"},\"MaxBalanceSet(uint256,uint256)\":{\"notice\":\"Emitted any time the contract maximum balance is set.\"},\"MaxDepositAmountSet(uint256,uint256)\":{\"notice\":\"Emitted any time the maximum deposit amount is set.\"},\"MinDepositAmountSet(uint256,uint256)\":{\"notice\":\"Emitted any time the minimum deposit amount is set.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Initializes a new TeleportrDeposit contract.\"},\"maxBalance()\":{\"notice\":\"The maximum balance the contract can hold after a receive.\"},\"maxDepositAmount()\":{\"notice\":\"The maximum amount that be deposited in a receive.\"},\"minDepositAmount()\":{\"notice\":\"The minimum amount that be deposited in a receive.\"},\"setMaxAmount(uint256)\":{\"notice\":\"Sets the maximum amount that can be deposited in a receive.\"},\"setMaxBalance(uint256)\":{\"notice\":\"Sets the maximum balance the contract can hold after a receive.\"},\"setMinAmount(uint256)\":{\"notice\":\"Sets the minimum amount that can be deposited in a receive.\"},\"totalDeposits()\":{\"notice\":\"The total number of successful deposits received.\"},\"withdrawBalance()\":{\"notice\":\"Sends the contract's current balance to the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/teleportr/TeleportrDeposit.sol\":\"TeleportrDeposit\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2ebbbe6d0011175bd9e7268b83de3f9c2f9d8d4cbfbaef12aff977d7d727163\",\"dweb:/ipfs/Qmd5c7Vxtis9wzkDNhxwc6A2QT5H9xn9kfjhx7qx44vpro\"]},\"@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26e8b38a7ac8e7b4463af00cf7fff1bf48ae9875765bf4f7751e100124d0bc8c\",\"dweb:/ipfs/QmWcsmkVr24xmmjfnBQZoemFniXjj3vwT78Cz6uqZW1Hux\"]},\"contracts/L1/teleportr/TeleportrDeposit.sol\":{\"keccak256\":\"0x885673d5837399f19082826a2bc64889384a39f0999d003bfcca675a26ec2d74\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d44b9d501288828c6fa026eaa02936301ff0e2037294747d7c1605fa93a598e0\",\"dweb:/ipfs/QmbQ2pQnvkTzuwns4azKVPmKvB2oPV6rJ6wL3ZE3vw6n15\"]}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b5060405162001a6a38038062001a6a83398181016040528101906200003791906200054b565b620000576200004b6200043c60201b60201c565b6200044460201b60201c565b6200008a7e64b7c3d2e027eba5da5f5280491bfce7932df45fdf2e0891110c3dc3e84bf460001b6200050860201b60201c565b620000be7f0754617f84d3b5fc04f16a0983e82c729cb6d2698f728b30dfa934b5add9016960001b6200050860201b60201c565b620000f27f1cd5d3f0acece0d68e6ccf8bfd89b818133486ea9f082a4b9b7b11b6000baad560001b6200050860201b60201c565b826001819055506200012d7f30791823e64606c8be3e7feb8b103685a5aaff26eaa6bd2c7f3ce310352527be60001b6200050860201b60201c565b620001617f33d8a274a292fb8ba3cc7d2b767284bf7dc0c506646d5443215dab914e4ca6e860001b6200050860201b60201c565b816002819055506200019c7f50d9a49460146742cae39d07048c68aa13de2a770bed641810140d7a8973a70d60001b6200050860201b60201c565b620001d07f3d77b70ed2057214d5cd1b0ee90db5bba75d46a8e2c1c1175b1c3c6c7477c14260001b6200050860201b60201c565b806003819055506200020b7f942240fbaf8b00e69532f2fbe4ea09bf8f15876f36c4a0d73a3ece54aa0a522960001b6200050860201b60201c565b6200023f7f94060d265c2e1f35f4230c634aaf7f14185d0a42d6d8d5f35fe5492ece57cc0c60001b6200050860201b60201c565b60006004819055506200027b7f2c650db3dc7a065d861e08f687272c0e3d1fd605cd167042d67953202666742f60001b6200050860201b60201c565b620002af7f1b7587159c5f1160ede69f194a9e5c933514c192042fd3415bf2deb3f8f74b0760001b6200050860201b60201c565b7f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f600084604051620002e392919062000605565b60405180910390a16200031f7f14fdcec951a67568c0b528dd486521f51bdc14f531d71f850fa0bd2d9c45829460001b6200050860201b60201c565b620003537f59bcf0476adddb53cd05f64c33dcc191fa4a0a2cbb042239cce51dd2fc7b4b9a60001b6200050860201b60201c565b7fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a51124379117976000836040516200038792919062000605565b60405180910390a1620003c37fd10cdaddea1cf4d5c38c657c8184253dab5a819c5e4b0c88869a9564fd4b4c4960001b6200050860201b60201c565b620003f77fd8d1727cb6b16868521109e26db98e2148155c06bb992b0a0cb83f313921eb9160001b6200050860201b60201c565b7f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b6000826040516200042b92919062000605565b60405180910390a150505062000632565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b50565b600080fd5b6000819050919050565b620005258162000510565b81146200053157600080fd5b50565b60008151905062000545816200051a565b92915050565b6000806000606084860312156200056757620005666200050b565b5b6000620005778682870162000534565b93505060206200058a8682870162000534565b92505060406200059d8682870162000534565b9150509250925092565b6000819050919050565b6000819050919050565b6000620005dc620005d6620005d084620005a7565b620005b1565b62000510565b9050919050565b620005ee81620005bb565b82525050565b620005ff8162000510565b82525050565b60006040820190506200061c6000830185620005e3565b6200062b6020830184620005f4565b9392505050565b61142880620006426000396000f3fe6080604052600436106100cb5760003560e01c80637d882097116100745780638ed832711161004e5780638ed83271146105365780639d51d9b714610561578063f2fde38b1461058a576103dc565b80637d882097146104b7578063897b0637146104e25780638da5cb5b1461050b576103dc565b8063715018a6116100a5578063715018a61461044c57806373ad468a146104635780637d63d0cd1461048e576103dc565b80634fe47f70146103e15780635fd8c7101461040a578063645006ca14610421576103dc565b366103dc576100fc7f5e91eb4e146243c5fc10218c63813d75795efa063ee048a70076cb6ecc61587d60001b6105b3565b6101287f73260b5f05e45d61e42c373897b87998b1a5a7bd70f9af562c4b361e04f0379d60001b6105b3565b60015434101561016d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016490611029565b60405180910390fd5b6101997f23991968fdcb96adbea8af7b4742a78253230d9f76ee5eff35c987310043166a60001b6105b3565b6101c57f249aaae9e0e29e3e4031f40b7d96a68f16ea91f027ace995e46bfdaeffc6f39160001b6105b3565b6101f17fbce8df54e38e3ccc6f9f6481c255cd9804ade53c913156b5c2da09a92946cb2360001b6105b3565b600254341115610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90611095565b60405180910390fd5b6102627f2bd55ff7de06b7bc9a18ccd9faec6cc761628852dff2df2d03f1f08dc28285d660001b6105b3565b61028e7f8ad51416e28945719acfb674a9f9e6907225e745b1f9e523e751b4be1bdaac4e60001b6105b3565b6102ba7fff12f46047487761ec7b26043d01a917e9aecfcdd47cd91d771c8ea30d37e8b860001b6105b3565b6003544711156102ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102f690611101565b60405180910390fd5b61032a7e3763c76368796ee311ec1b0ddfd3708e87b99464363f5ac0147716b637edb160001b6105b3565b6103567f79e71c65a22716d1eba9afec74511a85d8fe55b5f6a98109655aaf23bbcf27f060001b6105b3565b343373ffffffffffffffffffffffffffffffffffffffff166004547f2d27851832fcac28a0d4af1344f01fed7ffcfd15171c14c564a0c42aa57ae5c060405160405180910390a46103c97f1da34b6132b7d28e2dd5dcc9cc69abac10b228d460afab0c9cfbc955300ed96c60001b6105b3565b6001600460008282540192505081905550005b600080fd5b3480156103ed57600080fd5b506104086004803603810190610403919061115c565b6105b6565b005b34801561041657600080fd5b5061041f610753565b005b34801561042d57600080fd5b50610436610a05565b6040516104439190611198565b60405180910390f35b34801561045857600080fd5b50610461610a0b565b005b34801561046f57600080fd5b50610478610a93565b6040516104859190611198565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b091906111e9565b6105b3565b005b3480156104c357600080fd5b506104cc610a99565b6040516104d99190611198565b60405180910390f35b3480156104ee57600080fd5b506105096004803603810190610504919061115c565b610a9f565b005b34801561051757600080fd5b50610520610c3c565b60405161052d9190611257565b60405180910390f35b34801561054257600080fd5b5061054b610c65565b6040516105589190611198565b60405180910390f35b34801561056d57600080fd5b506105886004803603810190610583919061115c565b610c6b565b005b34801561059657600080fd5b506105b160048036038101906105ac919061129e565b610e08565b005b50565b6105be610f00565b73ffffffffffffffffffffffffffffffffffffffff166105dc610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062990611317565b60405180910390fd5b61065e7ffee123fad7ec16093a6435cf2c5d00b4571ad879afd34fb5bbb0d90914f7898160001b6105b3565b61068a7f23b16a5b6e035bf28fefd8536d3d907084332ed11eaad0c731ab33bdf63728ab60001b6105b3565b6106b67fe3990e89e60d0565ab8d3b4f20893f23ea714ef00b2b971bfdca4ed564f9d7bc60001b6105b3565b7fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797600254826040516106e9929190611337565b60405180910390a161071d7f7dcc232dd4ea9159fcc353f5151cc835e78ec60204ecd0bd7d926246ba5419ab60001b6105b3565b6107497fe638d78dd410ed0ed44e18bb848eaffdebe2397f929549a92d78c434746b5a1960001b6105b3565b8060028190555050565b61075b610f00565b73ffffffffffffffffffffffffffffffffffffffff16610779610c3c565b73ffffffffffffffffffffffffffffffffffffffff16146107cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c690611317565b60405180910390fd5b6107fb7fc6b27d465e4053b68a3388de9da95b673c18eb4989d1008c2e06915f910a066060001b6105b3565b6108277f2fca1e77c51979dc28ae8dc9fc4db5c9ce9be137728cb0a61cecdd0d78850eb160001b6105b3565b6108537fec90bc2e2104a1823652f6828778f93075a8d31d8e3ac2bfd179ffcbfe51739b60001b6105b3565b600061085d610c3c565b905061088b7fb45dbc3fc05181c7356e9244306dddabaf0b75b05688c615d0e7a4833ce1b98860001b6105b3565b6108b77fbc38348ea4a9b5cb61c62ee5badf6ec802094b56806baef5ac173cb7461a82d160001b6105b3565b60004790506108e87ff96c8825c2177b3c21775b49f255faad2ce4e7da2e10326bacd5248e8b712dff60001b6105b3565b6109147fd43f2aaa632b9ffeb71c574863f0f8a1552a8f75769c81b9552396c6190eff4160001b6105b3565b8173ffffffffffffffffffffffffffffffffffffffff167fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f18260405161095a9190611198565b60405180910390a261098e7f3c0d0013f3a63b85c4bd529a45060dc1444fc884d2c8cc3cc575aa3a4710e27860001b6105b3565b6109ba7f5b79781fe133b568105927be0b812215d4bec71e3c2215d5d4758c9bac65c62760001b6105b3565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610a00573d6000803e3d6000fd5b505050565b60015481565b610a13610f00565b73ffffffffffffffffffffffffffffffffffffffff16610a31610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610a87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7e90611317565b60405180910390fd5b610a916000610f08565b565b60035481565b60045481565b610aa7610f00565b73ffffffffffffffffffffffffffffffffffffffff16610ac5610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1290611317565b60405180910390fd5b610b477fb433caf62ec08507ab7af9b492ca9c31d5bcdd278f6004a28794eb4106b5cf3e60001b6105b3565b610b737f897c1d74774bdd740f697ebe75144626bd7a18205b591e95d5ad4f8de174ea7060001b6105b3565b610b9f7fd9e9dc42b180f2f843f8d913ef4d43c5f8f8bea2ec782b7a740d2561a257cde260001b6105b3565b7f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f60015482604051610bd2929190611337565b60405180910390a1610c067f8da41a211fc748f0027d0993815cc4ca3cc376d4ae4b4471d749b0984a57239960001b6105b3565b610c327f4aa4ae558612ce08434cb24e0473deb7e6c2752c6a90ce39f24fd88b9cfe6d7d60001b6105b3565b8060018190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60025481565b610c73610f00565b73ffffffffffffffffffffffffffffffffffffffff16610c91610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde90611317565b60405180910390fd5b610d137fce1bcd2174ef6ef3da0e36105bd18a71486b853321242fc762fb2a5064cb2e5360001b6105b3565b610d3f7f96e568f68ceba0bb138445fe1d28ff043c88b4482d666e86c6663627a794d00e60001b6105b3565b610d6b7f83921b77b4f8764a56568881a61495190986808cf7eaa1d617e46cd7e7b52f7360001b6105b3565b7f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b60035482604051610d9e929190611337565b60405180910390a1610dd27f5e9d45d2a21d81f43304c5d88d8c4b9fe0060aae15b5abf9547f24437e7f90fc60001b6105b3565b610dfe7f819805374cc1d4a4ad5b35e7e174e0b0ecb50f725597510954c8cd97e051b56760001b6105b3565b8060038190555050565b610e10610f00565b73ffffffffffffffffffffffffffffffffffffffff16610e2e610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610e84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7b90611317565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eeb906113d2565b60405180910390fd5b610efd81610f08565b50565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082825260208201905092915050565b7f4465706f73697420616d6f756e7420697320746f6f20736d616c6c0000000000600082015250565b6000611013601b83610fcc565b915061101e82610fdd565b602082019050919050565b6000602082019050818103600083015261104281611006565b9050919050565b7f4465706f73697420616d6f756e7420697320746f6f2062696700000000000000600082015250565b600061107f601983610fcc565b915061108a82611049565b602082019050919050565b600060208201905081810360008301526110ae81611072565b9050919050565b7f436f6e7472616374206d61782062616c616e6365206578636565646564000000600082015250565b60006110eb601d83610fcc565b91506110f6826110b5565b602082019050919050565b6000602082019050818103600083015261111a816110de565b9050919050565b600080fd5b6000819050919050565b61113981611126565b811461114457600080fd5b50565b60008135905061115681611130565b92915050565b60006020828403121561117257611171611121565b5b600061118084828501611147565b91505092915050565b61119281611126565b82525050565b60006020820190506111ad6000830184611189565b92915050565b6000819050919050565b6111c6816111b3565b81146111d157600080fd5b50565b6000813590506111e3816111bd565b92915050565b6000602082840312156111ff576111fe611121565b5b600061120d848285016111d4565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061124182611216565b9050919050565b61125181611236565b82525050565b600060208201905061126c6000830184611248565b92915050565b61127b81611236565b811461128657600080fd5b50565b60008135905061129881611272565b92915050565b6000602082840312156112b4576112b3611121565b5b60006112c284828501611289565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611301602083610fcc565b915061130c826112cb565b602082019050919050565b60006020820190508181036000830152611330816112f4565b9050919050565b600060408201905061134c6000830185611189565b6113596020830184611189565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006113bc602683610fcc565b91506113c782611360565b604082019050919050565b600060208201905081810360008301526113eb816113af565b905091905056fea264697066735822122037015225a63ecab5a43f7590abb54032a0ddd923e67369b73360917b27c6e14c64736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100cb5760003560e01c80637d882097116100745780638ed832711161004e5780638ed83271146105365780639d51d9b714610561578063f2fde38b1461058a576103dc565b80637d882097146104b7578063897b0637146104e25780638da5cb5b1461050b576103dc565b8063715018a6116100a5578063715018a61461044c57806373ad468a146104635780637d63d0cd1461048e576103dc565b80634fe47f70146103e15780635fd8c7101461040a578063645006ca14610421576103dc565b366103dc576100fc7f5e91eb4e146243c5fc10218c63813d75795efa063ee048a70076cb6ecc61587d60001b6105b3565b6101287f73260b5f05e45d61e42c373897b87998b1a5a7bd70f9af562c4b361e04f0379d60001b6105b3565b60015434101561016d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016490611029565b60405180910390fd5b6101997f23991968fdcb96adbea8af7b4742a78253230d9f76ee5eff35c987310043166a60001b6105b3565b6101c57f249aaae9e0e29e3e4031f40b7d96a68f16ea91f027ace995e46bfdaeffc6f39160001b6105b3565b6101f17fbce8df54e38e3ccc6f9f6481c255cd9804ade53c913156b5c2da09a92946cb2360001b6105b3565b600254341115610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90611095565b60405180910390fd5b6102627f2bd55ff7de06b7bc9a18ccd9faec6cc761628852dff2df2d03f1f08dc28285d660001b6105b3565b61028e7f8ad51416e28945719acfb674a9f9e6907225e745b1f9e523e751b4be1bdaac4e60001b6105b3565b6102ba7fff12f46047487761ec7b26043d01a917e9aecfcdd47cd91d771c8ea30d37e8b860001b6105b3565b6003544711156102ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102f690611101565b60405180910390fd5b61032a7e3763c76368796ee311ec1b0ddfd3708e87b99464363f5ac0147716b637edb160001b6105b3565b6103567f79e71c65a22716d1eba9afec74511a85d8fe55b5f6a98109655aaf23bbcf27f060001b6105b3565b343373ffffffffffffffffffffffffffffffffffffffff166004547f2d27851832fcac28a0d4af1344f01fed7ffcfd15171c14c564a0c42aa57ae5c060405160405180910390a46103c97f1da34b6132b7d28e2dd5dcc9cc69abac10b228d460afab0c9cfbc955300ed96c60001b6105b3565b6001600460008282540192505081905550005b600080fd5b3480156103ed57600080fd5b506104086004803603810190610403919061115c565b6105b6565b005b34801561041657600080fd5b5061041f610753565b005b34801561042d57600080fd5b50610436610a05565b6040516104439190611198565b60405180910390f35b34801561045857600080fd5b50610461610a0b565b005b34801561046f57600080fd5b50610478610a93565b6040516104859190611198565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b091906111e9565b6105b3565b005b3480156104c357600080fd5b506104cc610a99565b6040516104d99190611198565b60405180910390f35b3480156104ee57600080fd5b506105096004803603810190610504919061115c565b610a9f565b005b34801561051757600080fd5b50610520610c3c565b60405161052d9190611257565b60405180910390f35b34801561054257600080fd5b5061054b610c65565b6040516105589190611198565b60405180910390f35b34801561056d57600080fd5b506105886004803603810190610583919061115c565b610c6b565b005b34801561059657600080fd5b506105b160048036038101906105ac919061129e565b610e08565b005b50565b6105be610f00565b73ffffffffffffffffffffffffffffffffffffffff166105dc610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062990611317565b60405180910390fd5b61065e7ffee123fad7ec16093a6435cf2c5d00b4571ad879afd34fb5bbb0d90914f7898160001b6105b3565b61068a7f23b16a5b6e035bf28fefd8536d3d907084332ed11eaad0c731ab33bdf63728ab60001b6105b3565b6106b67fe3990e89e60d0565ab8d3b4f20893f23ea714ef00b2b971bfdca4ed564f9d7bc60001b6105b3565b7fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797600254826040516106e9929190611337565b60405180910390a161071d7f7dcc232dd4ea9159fcc353f5151cc835e78ec60204ecd0bd7d926246ba5419ab60001b6105b3565b6107497fe638d78dd410ed0ed44e18bb848eaffdebe2397f929549a92d78c434746b5a1960001b6105b3565b8060028190555050565b61075b610f00565b73ffffffffffffffffffffffffffffffffffffffff16610779610c3c565b73ffffffffffffffffffffffffffffffffffffffff16146107cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c690611317565b60405180910390fd5b6107fb7fc6b27d465e4053b68a3388de9da95b673c18eb4989d1008c2e06915f910a066060001b6105b3565b6108277f2fca1e77c51979dc28ae8dc9fc4db5c9ce9be137728cb0a61cecdd0d78850eb160001b6105b3565b6108537fec90bc2e2104a1823652f6828778f93075a8d31d8e3ac2bfd179ffcbfe51739b60001b6105b3565b600061085d610c3c565b905061088b7fb45dbc3fc05181c7356e9244306dddabaf0b75b05688c615d0e7a4833ce1b98860001b6105b3565b6108b77fbc38348ea4a9b5cb61c62ee5badf6ec802094b56806baef5ac173cb7461a82d160001b6105b3565b60004790506108e87ff96c8825c2177b3c21775b49f255faad2ce4e7da2e10326bacd5248e8b712dff60001b6105b3565b6109147fd43f2aaa632b9ffeb71c574863f0f8a1552a8f75769c81b9552396c6190eff4160001b6105b3565b8173ffffffffffffffffffffffffffffffffffffffff167fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f18260405161095a9190611198565b60405180910390a261098e7f3c0d0013f3a63b85c4bd529a45060dc1444fc884d2c8cc3cc575aa3a4710e27860001b6105b3565b6109ba7f5b79781fe133b568105927be0b812215d4bec71e3c2215d5d4758c9bac65c62760001b6105b3565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610a00573d6000803e3d6000fd5b505050565b60015481565b610a13610f00565b73ffffffffffffffffffffffffffffffffffffffff16610a31610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610a87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7e90611317565b60405180910390fd5b610a916000610f08565b565b60035481565b60045481565b610aa7610f00565b73ffffffffffffffffffffffffffffffffffffffff16610ac5610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1290611317565b60405180910390fd5b610b477fb433caf62ec08507ab7af9b492ca9c31d5bcdd278f6004a28794eb4106b5cf3e60001b6105b3565b610b737f897c1d74774bdd740f697ebe75144626bd7a18205b591e95d5ad4f8de174ea7060001b6105b3565b610b9f7fd9e9dc42b180f2f843f8d913ef4d43c5f8f8bea2ec782b7a740d2561a257cde260001b6105b3565b7f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f60015482604051610bd2929190611337565b60405180910390a1610c067f8da41a211fc748f0027d0993815cc4ca3cc376d4ae4b4471d749b0984a57239960001b6105b3565b610c327f4aa4ae558612ce08434cb24e0473deb7e6c2752c6a90ce39f24fd88b9cfe6d7d60001b6105b3565b8060018190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60025481565b610c73610f00565b73ffffffffffffffffffffffffffffffffffffffff16610c91610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde90611317565b60405180910390fd5b610d137fce1bcd2174ef6ef3da0e36105bd18a71486b853321242fc762fb2a5064cb2e5360001b6105b3565b610d3f7f96e568f68ceba0bb138445fe1d28ff043c88b4482d666e86c6663627a794d00e60001b6105b3565b610d6b7f83921b77b4f8764a56568881a61495190986808cf7eaa1d617e46cd7e7b52f7360001b6105b3565b7f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b60035482604051610d9e929190611337565b60405180910390a1610dd27f5e9d45d2a21d81f43304c5d88d8c4b9fe0060aae15b5abf9547f24437e7f90fc60001b6105b3565b610dfe7f819805374cc1d4a4ad5b35e7e174e0b0ecb50f725597510954c8cd97e051b56760001b6105b3565b8060038190555050565b610e10610f00565b73ffffffffffffffffffffffffffffffffffffffff16610e2e610c3c565b73ffffffffffffffffffffffffffffffffffffffff1614610e84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7b90611317565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eeb906113d2565b60405180910390fd5b610efd81610f08565b50565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082825260208201905092915050565b7f4465706f73697420616d6f756e7420697320746f6f20736d616c6c0000000000600082015250565b6000611013601b83610fcc565b915061101e82610fdd565b602082019050919050565b6000602082019050818103600083015261104281611006565b9050919050565b7f4465706f73697420616d6f756e7420697320746f6f2062696700000000000000600082015250565b600061107f601983610fcc565b915061108a82611049565b602082019050919050565b600060208201905081810360008301526110ae81611072565b9050919050565b7f436f6e7472616374206d61782062616c616e6365206578636565646564000000600082015250565b60006110eb601d83610fcc565b91506110f6826110b5565b602082019050919050565b6000602082019050818103600083015261111a816110de565b9050919050565b600080fd5b6000819050919050565b61113981611126565b811461114457600080fd5b50565b60008135905061115681611130565b92915050565b60006020828403121561117257611171611121565b5b600061118084828501611147565b91505092915050565b61119281611126565b82525050565b60006020820190506111ad6000830184611189565b92915050565b6000819050919050565b6111c6816111b3565b81146111d157600080fd5b50565b6000813590506111e3816111bd565b92915050565b6000602082840312156111ff576111fe611121565b5b600061120d848285016111d4565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061124182611216565b9050919050565b61125181611236565b82525050565b600060208201905061126c6000830184611248565b92915050565b61127b81611236565b811461128657600080fd5b50565b60008135905061129881611272565b92915050565b6000602082840312156112b4576112b3611121565b5b60006112c284828501611289565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611301602083610fcc565b915061130c826112cb565b602082019050919050565b60006020820190508181036000830152611330816112f4565b9050919050565b600060408201905061134c6000830185611189565b6113596020830184611189565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006113bc602683610fcc565b91506113c782611360565b604082019050919050565b600060208201905081810360008301526113eb816113af565b905091905056fea264697066735822122037015225a63ecab5a43f7590abb54032a0ddd923e67369b73360917b27c6e14c64736f6c63430008090033",
"devdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"params": {
"balance": "The current contract balance paid to the owner.",
"owner": "The current owner and recipient of the funds."
}
},
"EtherReceived(uint256,address,uint256)": {
"params": {
"amount": "The amount deposited by the payer.",
"depositId": "A unique sequencer number identifying the deposit.",
"emitter": "The sending address of the payer."
}
},
"MaxBalanceSet(uint256,uint256)": {
"params": {
"newBalance": "The new maximum contract balance.",
"previousBalance": "The previous maximum contract balance."
}
},
"MaxDepositAmountSet(uint256,uint256)": {
"params": {
"newAmount": "The new maximum deposit amount.",
"previousAmount": "The previous maximum deposit amount."
}
},
"MinDepositAmountSet(uint256,uint256)": {
"params": {
"newAmount": "The new minimum deposit amount.",
"previousAmount": "The previous minimum deposit amount."
}
}
},
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_maxBalance": "The initial maximum contract balance.",
"_maxDepositAmount": "The initial maximum deposit amount.",
"_minDepositAmount": "The initial minimum deposit amount."
}
},
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"setMaxAmount(uint256)": {
"params": {
"_maxDepositAmount": "The new maximum deposit amount."
}
},
"setMaxBalance(uint256)": {
"params": {
"_maxBalance": "The new maximum contract balance."
}
},
"setMinAmount(uint256)": {
"params": {
"_minDepositAmount": "The new minimum deposit amount."
}
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "TeleportrDeposit Shout out to 0xclem for providing the inspiration for this contract: https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol",
"version": 1
},
"userdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"notice": "Emitted any time the balance is withdrawn by the owner."
},
"EtherReceived(uint256,address,uint256)": {
"notice": "Emitted any time a successful deposit is received."
},
"MaxBalanceSet(uint256,uint256)": {
"notice": "Emitted any time the contract maximum balance is set."
},
"MaxDepositAmountSet(uint256,uint256)": {
"notice": "Emitted any time the maximum deposit amount is set."
},
"MinDepositAmountSet(uint256,uint256)": {
"notice": "Emitted any time the minimum deposit amount is set."
}
},
"kind": "user",
"methods": {
"constructor": {
"notice": "Initializes a new TeleportrDeposit contract."
},
"maxBalance()": {
"notice": "The maximum balance the contract can hold after a receive."
},
"maxDepositAmount()": {
"notice": "The maximum amount that be deposited in a receive."
},
"minDepositAmount()": {
"notice": "The minimum amount that be deposited in a receive."
},
"setMaxAmount(uint256)": {
"notice": "Sets the maximum amount that can be deposited in a receive."
},
"setMaxBalance(uint256)": {
"notice": "Sets the maximum balance the contract can hold after a receive."
},
"setMinAmount(uint256)": {
"notice": "Sets the minimum amount that can be deposited in a receive."
},
"totalDeposits()": {
"notice": "The total number of successful deposits received."
},
"withdrawBalance()": {
"notice": "Sends the contract's current balance to the owner."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 393,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 7830,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "minDepositAmount",
"offset": 0,
"slot": "1",
"type": "t_uint256"
},
{
"astId": 7833,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "maxDepositAmount",
"offset": 0,
"slot": "2",
"type": "t_uint256"
},
{
"astId": 7836,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "maxBalance",
"offset": 0,
"slot": "3",
"type": "t_uint256"
},
{
"astId": 7839,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "totalDeposits",
"offset": 0,
"slot": "4",
"type": "t_uint256"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x4821975ca220601c153d02353300d6ad34adc362",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "balance",
"type": "uint256"
}
],
"name": "BalanceWithdrawn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "depositId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "DisbursementFailed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "depositId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "DisbursementSuccess",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "c__0x16931334",
"type": "bytes32"
}
],
"name": "c_0x16931334",
"outputs": [],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_nextDepositId",
"type": "uint256"
},
{
"components": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"internalType": "struct TeleportrDisburser.Disbursement[]",
"name": "_disbursements",
"type": "tuple[]"
}
],
"name": "disburse",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalDisbursements",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawBalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x91be8d4c1a357b2c06bac93ce2a39015504cdd13910b0b05403bd11f8b5259c8",
"receipt": {
"to": null,
"from": "0x6c2cBc2132aB6Fc48Ebf3569Bdde7B0AA34aa0FC",
"contractAddress": "0xde440ADa095F36835ecB90297D22Ccbe02045a94",
"transactionIndex": 0,
"gasUsed": "1341401",
"logsBloom": "0x00000000000000000000000010000000000000000000000000800000000000010000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000100000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000000000000000000000000",
"blockHash": "0x94f294a93fc7178f06afbe6f97c0c013bbf570016ad491583af420c1d3f21763",
"transactionHash": "0x91be8d4c1a357b2c06bac93ce2a39015504cdd13910b0b05403bd11f8b5259c8",
"logs": [
{
"transactionIndex": 0,
"blockNumber": 1644547,
"transactionHash": "0x91be8d4c1a357b2c06bac93ce2a39015504cdd13910b0b05403bd11f8b5259c8",
"address": "0xde440ADa095F36835ecB90297D22Ccbe02045a94",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000006c2cbc2132ab6fc48ebf3569bdde7b0aa34aa0fc"
],
"data": "0x",
"logIndex": 0,
"blockHash": "0x94f294a93fc7178f06afbe6f97c0c013bbf570016ad491583af420c1d3f21763"
}
],
"blockNumber": 1644547,
"cumulativeGasUsed": "1341401",
"status": 1,
"byzantium": true
},
"args": [],
"solcInputHash": "f20d616c1af6713a0e8ca9fae9d7bae7",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DisbursementFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DisbursementSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"c__0x16931334\",\"type\":\"bytes32\"}],\"name\":\"c_0x16931334\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nextDepositId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"internalType\":\"struct TeleportrDisburser.Disbursement[]\",\"name\":\"_disbursements\",\"type\":\"tuple[]\"}],\"name\":\"disburse\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDisbursements\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"params\":{\"balance\":\"The current contract balance paid to the owner.\",\"owner\":\"The current owner and recipient of the funds.\"}},\"DisbursementFailed(uint256,address,uint256)\":{\"params\":{\"amount\":\"The amount intended to be sent to the recipient.\",\"depositId\":\"The unique sequence number identifying the deposit.\",\"to\":\"The intended recipient of the disbursement.\"}},\"DisbursementSuccess(uint256,address,uint256)\":{\"params\":{\"amount\":\"The amount sent to the recipient.\",\"depositId\":\"The unique sequence number identifying the deposit.\",\"to\":\"The recipient of the disbursement.\"}}},\"kind\":\"dev\",\"methods\":{\"disburse(uint256,(uint256,address)[])\":{\"params\":{\"_disbursements\":\"A list of Disbursements to process.\",\"_nextDepositId\":\"The depositId of the first Dispursement.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"TeleportrDisburser\",\"version\":1},\"userdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"notice\":\"Emitted any time the balance is withdrawn by the owner.\"},\"DisbursementFailed(uint256,address,uint256)\":{\"notice\":\"Emitted any time a disbursement fails to send.\"},\"DisbursementSuccess(uint256,address,uint256)\":{\"notice\":\"Emitted any time a disbursement is successfuly sent.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Initializes a new TeleportrDisburser contract.\"},\"disburse(uint256,(uint256,address)[])\":{\"notice\":\"Accepts a list of Disbursements and forwards the amount paid to the contract to each recipient. The method reverts if there are zero disbursements, the total amount to forward differs from the amount sent in the transaction, or the _nextDepositId is unexpected. Failed disbursements will not cause the method to revert, but will instead be held by the contract and availabe for the owner to withdraw.\"},\"totalDisbursements()\":{\"notice\":\"The total number of disbursements processed.\"},\"withdrawBalance()\":{\"notice\":\"Sends the contract's current balance to the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/teleportr/TeleportrDisburser.sol\":\"TeleportrDisburser\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2ebbbe6d0011175bd9e7268b83de3f9c2f9d8d4cbfbaef12aff977d7d727163\",\"dweb:/ipfs/Qmd5c7Vxtis9wzkDNhxwc6A2QT5H9xn9kfjhx7qx44vpro\"]},\"@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26e8b38a7ac8e7b4463af00cf7fff1bf48ae9875765bf4f7751e100124d0bc8c\",\"dweb:/ipfs/QmWcsmkVr24xmmjfnBQZoemFniXjj3vwT78Cz6uqZW1Hux\"]},\"contracts/L2/teleportr/TeleportrDisburser.sol\":{\"keccak256\":\"0x42a2eb0f230f8b713fb97d6d44330251c067a26344439cb8fc0f6c5008c61e69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5b3f82df2740a5b40c30fca65cbf6d3242bbf34260a266cf579ef015235af676\",\"dweb:/ipfs/QmZyfQh3M3fzGMjrF31NcAG3YpxMGW93mNzVHcxfjo29qt\"]}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b506200003262000026620000dc60201b60201c565b620000e460201b60201c565b620000667f39bbaedb82e6743a336be557192fb64c205b1c7023985a2169da77cfa38456e760001b620001a860201b60201c565b6200009a7f24db5b5cfdf4200d735f11046f2ae1a70f4558a5d72f76885640a569c06c07cf60001b620001a860201b60201c565b620000ce7f317e8430390de1cd59d658f9aa2e38e3fc3ede461a2882fce72bce93ad4b116360001b620001a860201b60201c565b6000600181905550620001ab565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b50565b6116cc80620001bb6000396000f3fe6080604052600436106100705760003560e01c80638da5cb5b1161004e5780638da5cb5b146100ce578063a0adbb93146100f9578063ad48144d14610122578063f2fde38b1461013e57610070565b806325999e7f146100755780635fd8c710146100a0578063715018a6146100b7575b600080fd5b34801561008157600080fd5b5061008a610167565b60405161009791906110ac565b60405180910390f35b3480156100ac57600080fd5b506100b561016d565b005b3480156100c357600080fd5b506100cc61041f565b005b3480156100da57600080fd5b506100e36104a7565b6040516100f09190611108565b60405180910390f35b34801561010557600080fd5b50610120600480360381019061011b9190611163565b6104d0565b005b61013c60048036038101906101379190611221565b6104d3565b005b34801561014a57600080fd5b50610165600480360381019061016091906112ad565b610ecf565b005b60015481565b610175610fc7565b73ffffffffffffffffffffffffffffffffffffffff166101936104a7565b73ffffffffffffffffffffffffffffffffffffffff16146101e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101e090611337565b60405180910390fd5b6102157ffe92f91ad70fcc788c91b5c6377091fddb1bb4643da297f26117462bd94f49fd60001b6104d0565b6102417f1703157428668d098e51859c561d5296ef183d7c69ae701c20e674a9fb1fc99d60001b6104d0565b61026d7fa3bdcd2326103ecf302266dfd6c4af18da60b0396e4465dbc816f02baf137a4d60001b6104d0565b60006102776104a7565b90506102a57fbcfc6ad7959841cabcf36b03dfcd357d7d622acca2ba6e9a43b2372593a2b1f460001b6104d0565b6102d17f627056f9061efb209e979f60571640480c8dc859fd3b1446b24f901abd471d7860001b6104d0565b60004790506103027f872f745d610a98fff77a703564a28bce54c15938fd721d2bb1c1c96b29f02cc060001b6104d0565b61032e7fc7b520880199ff8ecee4cb60a0f2910d8beafd85c2a5d75e88cd45146cbd88c860001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff167fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f18260405161037491906110ac565b60405180910390a26103a87fbb13c854fee71d4d649f60251494946a1dc47696ecdbc5239eebd0f0e09dedb660001b6104d0565b6103d47f848adaf7559bcfbc99734e73f7109730b5e7d6c9dac716b49e5293cd159045da60001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561041a573d6000803e3d6000fd5b505050565b610427610fc7565b73ffffffffffffffffffffffffffffffffffffffff166104456104a7565b73ffffffffffffffffffffffffffffffffffffffff161461049b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049290611337565b60405180910390fd5b6104a56000610fcf565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b50565b6104db610fc7565b73ffffffffffffffffffffffffffffffffffffffff166104f96104a7565b73ffffffffffffffffffffffffffffffffffffffff161461054f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054690611337565b60405180910390fd5b61057b7f2ada5d99a5213ee4ca2bb15d1f40a59e356e720b5882c0781678a5e06b9ddb5960001b6104d0565b6105a77f7a7334b1d6bfe4bd15a6309ce921c6474f6768575c5e38d2b2ce7acc447ba59160001b6104d0565b6105d37fb807ae02c58a5c6be11b494711fb222a14e0d7e215117e68acdd94a81151ba7460001b6104d0565b60008282905090506106077f21ab292895678d1873f05582fb6da03baffcd8dbbf67acb7d05adbe92e38f27360001b6104d0565b6106337f807737600e915e0ac1bda9d244b1b42f3883b11d61a3714e96412ab37d49aa0d60001b6104d0565b61065f7fc1dafb9e03ad5f719e2b448b24a8dec5f2278a2d3a090d11212eccbf65b3b9dc60001b6104d0565b600081116106a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610699906113a3565b60405180910390fd5b6106ce7f23dbf8b6555265ebf2ff79777f7ef74ba63f296fc3b5440ee3f186724f49d63d60001b6104d0565b6106fa7f0f09cdc510c9eeadb6f4ffed3990e7ce53a93e2d1026c772e2303eb967ae645660001b6104d0565b6107267f442b40ff3f756dfe83209f66d82504cceb390151b2ea76b7ce2bce481ddb3b0e60001b6104d0565b600060015490506107597fb14a4d7d74c1e2df0ad5d1ac6189bd833e51ed69416aa7c504d01606d755c7ef60001b6104d0565b6107857f1338effe85e1ba3bde809611b8cd8ff762211afaccab634e6b6449395abbd82260001b6104d0565b6107b17fc20c000c8553b2152a7a80ac43c52f1b7ba7cbd04b533472fc0fd7fd7057f68060001b6104d0565b8481146107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea9061140f565b60405180910390fd5b61081f7fb25de3d3bad93e8f821dbd0a8d2aeb60bfa371bf7f2593187e3d6f3012cbbd1360001b6104d0565b61084b7fc1437f73ab0f757f501060cc8e214fb6e895e2c11fdec90f1c26c337259cb3b260001b6104d0565b816001600082825401925050819055506108877f60fb755f4c85c0f5e4fc55a59a862d71795ee75dd9aebd26397347a776a4438060001b6104d0565b6108b37f961eebfc60945127454266e3a2aa59e195e493c917f20887f27522f65f6138f360001b6104d0565b60006108e17f4a4656352b6110f616892179a43a4db2d257323981851d33e20f1d032afa810160001b6104d0565b61090d7f03453438aaa639cf92f4b9a0819dd07143a378d1d08840fd1091d6142cbd37ea60001b6104d0565b60005b838110156109ad576109447fa06b97308620cba29f8f5270af06b6b2b47882e99ef6a3ab7cb6ae3dff36e6c760001b6104d0565b6109707f1def478f38c0910e76e6a9de11aea3e47f48c79346e34413455d16858a227f7460001b6104d0565b8585828181106109835761098261142f565b5b9050604002016000013582610998919061148d565b915080806109a5906114e3565b915050610910565b506109da7f1bd35d5e9c2fadd60189746ebf51278308a09575bc3dacb8a2ce127511f4bd5b60001b6104d0565b610a067f6ed34bb8ab9df4b9f1295d0d512d642d3757c3c47b131b126385d8539862347060001b6104d0565b610a327f6140d5c902a63db76a3285429152fb3a87752f7db4120de3c9d932f328bc305060001b6104d0565b348114610a74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6b9061159e565b60405180910390fd5b610aa07f18246eeaf0026a3e2c4ac32cbc1dc0606e82d2890a32165286e3d0a8c95fd7a460001b6104d0565b610acc7f70b83d9371755905523d6f1e944a8b8692c0959960315ee55559fafd7c2c52bf60001b6104d0565b610af87f21baa28c2eb7d3242d4afa89ad217acdeea738ab84a007f3e8aa489d3ce867c860001b6104d0565b60005b83811015610ec657610b2f7fcdf5d58952d1caa81fdfa362bb2eeb66956f151aa2b33f407f9833563b20496e60001b6104d0565b610b5b7f82fdec1cc8aa1098d9a8242384eaea39f90e5593c12b39cb109348a772e9fafe60001b6104d0565b6000868683818110610b7057610b6f61142f565b5b905060400201600001359050610ba87faaf73602f455fb6fc88332cf7f6d0caabacde6b54d461dc6eb9a7ee12bb2b57460001b6104d0565b610bd47f0d14c42168fe96cb818965cb522ed1023d13f8dc0ab098cdf8760c35932c9cdf60001b6104d0565b6000878784818110610be957610be861142f565b5b9050604002016020016020810190610c0191906112ad565b9050610c2f7f4fccbbc284abd163c3c18f168872dc29d4fac77f01fc1cf5f9992b361605dc4f60001b6104d0565b610c5b7f14f24022c2530a4720a223a36c798ed655b1320c21a7fb1cd078146c936b277060001b6104d0565b60008173ffffffffffffffffffffffffffffffffffffffff16836108fc90604051610c85906115ef565b600060405180830381858888f193505050503d8060008114610cc3576040519150601f19603f3d011682016040523d82523d6000602084013e610cc8565b606091505b50509050610cf87f990d01d9292bbf5a72b844d9e480c435f5bf3f28c6a3cf01231653128d574a2960001b6104d0565b610d247fbeb05d1cb9e0c8962b3fbce755095395f809190d1f56a0305f52d745ed2be60860001b6104d0565b8015610dd657610d567f926cdb8fa3eec76098df0921133fbad388217c8a5f07adf0e3652e64344ff66760001b6104d0565b610d827fcf258c3a8696678566a6fd532ee096e27d2a9dc64bcc87d8fccf2c9df406855560001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff16867feaa22fd2d7b875476355b32cf719794faf9d91b66e73bc6375a053cace9caaee85604051610dc991906110ac565b60405180910390a3610e7e565b610e027f9065e1e3bc2a1b35f85ca394361800750d7ccf66381f3e69fe4faefe0e5cc78f60001b6104d0565b610e2e7f57081b0378c1c31ae18ff29ec060b75a2fcf8bec375989be94d0d303a4f0021160001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff16867f9b478c095979d3d3a7d602ffd9ee1f0843204d853558ae0882c8fcc0a5bc78cf85604051610e7591906110ac565b60405180910390a35b610eaa7f9de3918864af83d66c46c014e27703f1021307042aef5dcf52b75516706ddd8b60001b6104d0565b6001860195505050508080610ebe906114e3565b915050610afb565b50505050505050565b610ed7610fc7565b73ffffffffffffffffffffffffffffffffffffffff16610ef56104a7565b73ffffffffffffffffffffffffffffffffffffffff1614610f4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4290611337565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb290611676565b60405180910390fd5b610fc481610fcf565b50565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6110a681611093565b82525050565b60006020820190506110c1600083018461109d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006110f2826110c7565b9050919050565b611102816110e7565b82525050565b600060208201905061111d60008301846110f9565b92915050565b600080fd5b600080fd5b6000819050919050565b6111408161112d565b811461114b57600080fd5b50565b60008135905061115d81611137565b92915050565b60006020828403121561117957611178611123565b5b60006111878482850161114e565b91505092915050565b61119981611093565b81146111a457600080fd5b50565b6000813590506111b681611190565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126111e1576111e06111bc565b5b8235905067ffffffffffffffff8111156111fe576111fd6111c1565b5b60208301915083604082028301111561121a576112196111c6565b5b9250929050565b60008060006040848603121561123a57611239611123565b5b6000611248868287016111a7565b935050602084013567ffffffffffffffff81111561126957611268611128565b5b611275868287016111cb565b92509250509250925092565b61128a816110e7565b811461129557600080fd5b50565b6000813590506112a781611281565b92915050565b6000602082840312156112c3576112c2611123565b5b60006112d184828501611298565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006113216020836112da565b915061132c826112eb565b602082019050919050565b6000602082019050818103600083015261135081611314565b9050919050565b7f4e6f2064697362757273656d656e747300000000000000000000000000000000600082015250565b600061138d6010836112da565b915061139882611357565b602082019050919050565b600060208201905081810360008301526113bc81611380565b9050919050565b7f556e6578706563746564206e657874206465706f736974206964000000000000600082015250565b60006113f9601a836112da565b9150611404826113c3565b602082019050919050565b60006020820190508181036000830152611428816113ec565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061149882611093565b91506114a383611093565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156114d8576114d761145e565b5b828201905092915050565b60006114ee82611093565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156115215761152061145e565b5b600182019050919050565b7f44697362757273656d656e7420746f74616c20213d20616d6f756e742073656e60008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b60006115886021836112da565b91506115938261152c565b604082019050919050565b600060208201905081810360008301526115b78161157b565b9050919050565b600081905092915050565b50565b60006115d96000836115be565b91506115e4826115c9565b600082019050919050565b60006115fa826115cc565b9150819050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006116606026836112da565b915061166b82611604565b604082019050919050565b6000602082019050818103600083015261168f81611653565b905091905056fea264697066735822122083f16098b83d1bcd3c8f88b64cd62c2ff0f7149c4df36e3ea3404931581a899064736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100705760003560e01c80638da5cb5b1161004e5780638da5cb5b146100ce578063a0adbb93146100f9578063ad48144d14610122578063f2fde38b1461013e57610070565b806325999e7f146100755780635fd8c710146100a0578063715018a6146100b7575b600080fd5b34801561008157600080fd5b5061008a610167565b60405161009791906110ac565b60405180910390f35b3480156100ac57600080fd5b506100b561016d565b005b3480156100c357600080fd5b506100cc61041f565b005b3480156100da57600080fd5b506100e36104a7565b6040516100f09190611108565b60405180910390f35b34801561010557600080fd5b50610120600480360381019061011b9190611163565b6104d0565b005b61013c60048036038101906101379190611221565b6104d3565b005b34801561014a57600080fd5b50610165600480360381019061016091906112ad565b610ecf565b005b60015481565b610175610fc7565b73ffffffffffffffffffffffffffffffffffffffff166101936104a7565b73ffffffffffffffffffffffffffffffffffffffff16146101e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101e090611337565b60405180910390fd5b6102157ffe92f91ad70fcc788c91b5c6377091fddb1bb4643da297f26117462bd94f49fd60001b6104d0565b6102417f1703157428668d098e51859c561d5296ef183d7c69ae701c20e674a9fb1fc99d60001b6104d0565b61026d7fa3bdcd2326103ecf302266dfd6c4af18da60b0396e4465dbc816f02baf137a4d60001b6104d0565b60006102776104a7565b90506102a57fbcfc6ad7959841cabcf36b03dfcd357d7d622acca2ba6e9a43b2372593a2b1f460001b6104d0565b6102d17f627056f9061efb209e979f60571640480c8dc859fd3b1446b24f901abd471d7860001b6104d0565b60004790506103027f872f745d610a98fff77a703564a28bce54c15938fd721d2bb1c1c96b29f02cc060001b6104d0565b61032e7fc7b520880199ff8ecee4cb60a0f2910d8beafd85c2a5d75e88cd45146cbd88c860001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff167fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f18260405161037491906110ac565b60405180910390a26103a87fbb13c854fee71d4d649f60251494946a1dc47696ecdbc5239eebd0f0e09dedb660001b6104d0565b6103d47f848adaf7559bcfbc99734e73f7109730b5e7d6c9dac716b49e5293cd159045da60001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561041a573d6000803e3d6000fd5b505050565b610427610fc7565b73ffffffffffffffffffffffffffffffffffffffff166104456104a7565b73ffffffffffffffffffffffffffffffffffffffff161461049b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049290611337565b60405180910390fd5b6104a56000610fcf565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b50565b6104db610fc7565b73ffffffffffffffffffffffffffffffffffffffff166104f96104a7565b73ffffffffffffffffffffffffffffffffffffffff161461054f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054690611337565b60405180910390fd5b61057b7f2ada5d99a5213ee4ca2bb15d1f40a59e356e720b5882c0781678a5e06b9ddb5960001b6104d0565b6105a77f7a7334b1d6bfe4bd15a6309ce921c6474f6768575c5e38d2b2ce7acc447ba59160001b6104d0565b6105d37fb807ae02c58a5c6be11b494711fb222a14e0d7e215117e68acdd94a81151ba7460001b6104d0565b60008282905090506106077f21ab292895678d1873f05582fb6da03baffcd8dbbf67acb7d05adbe92e38f27360001b6104d0565b6106337f807737600e915e0ac1bda9d244b1b42f3883b11d61a3714e96412ab37d49aa0d60001b6104d0565b61065f7fc1dafb9e03ad5f719e2b448b24a8dec5f2278a2d3a090d11212eccbf65b3b9dc60001b6104d0565b600081116106a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610699906113a3565b60405180910390fd5b6106ce7f23dbf8b6555265ebf2ff79777f7ef74ba63f296fc3b5440ee3f186724f49d63d60001b6104d0565b6106fa7f0f09cdc510c9eeadb6f4ffed3990e7ce53a93e2d1026c772e2303eb967ae645660001b6104d0565b6107267f442b40ff3f756dfe83209f66d82504cceb390151b2ea76b7ce2bce481ddb3b0e60001b6104d0565b600060015490506107597fb14a4d7d74c1e2df0ad5d1ac6189bd833e51ed69416aa7c504d01606d755c7ef60001b6104d0565b6107857f1338effe85e1ba3bde809611b8cd8ff762211afaccab634e6b6449395abbd82260001b6104d0565b6107b17fc20c000c8553b2152a7a80ac43c52f1b7ba7cbd04b533472fc0fd7fd7057f68060001b6104d0565b8481146107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea9061140f565b60405180910390fd5b61081f7fb25de3d3bad93e8f821dbd0a8d2aeb60bfa371bf7f2593187e3d6f3012cbbd1360001b6104d0565b61084b7fc1437f73ab0f757f501060cc8e214fb6e895e2c11fdec90f1c26c337259cb3b260001b6104d0565b816001600082825401925050819055506108877f60fb755f4c85c0f5e4fc55a59a862d71795ee75dd9aebd26397347a776a4438060001b6104d0565b6108b37f961eebfc60945127454266e3a2aa59e195e493c917f20887f27522f65f6138f360001b6104d0565b60006108e17f4a4656352b6110f616892179a43a4db2d257323981851d33e20f1d032afa810160001b6104d0565b61090d7f03453438aaa639cf92f4b9a0819dd07143a378d1d08840fd1091d6142cbd37ea60001b6104d0565b60005b838110156109ad576109447fa06b97308620cba29f8f5270af06b6b2b47882e99ef6a3ab7cb6ae3dff36e6c760001b6104d0565b6109707f1def478f38c0910e76e6a9de11aea3e47f48c79346e34413455d16858a227f7460001b6104d0565b8585828181106109835761098261142f565b5b9050604002016000013582610998919061148d565b915080806109a5906114e3565b915050610910565b506109da7f1bd35d5e9c2fadd60189746ebf51278308a09575bc3dacb8a2ce127511f4bd5b60001b6104d0565b610a067f6ed34bb8ab9df4b9f1295d0d512d642d3757c3c47b131b126385d8539862347060001b6104d0565b610a327f6140d5c902a63db76a3285429152fb3a87752f7db4120de3c9d932f328bc305060001b6104d0565b348114610a74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6b9061159e565b60405180910390fd5b610aa07f18246eeaf0026a3e2c4ac32cbc1dc0606e82d2890a32165286e3d0a8c95fd7a460001b6104d0565b610acc7f70b83d9371755905523d6f1e944a8b8692c0959960315ee55559fafd7c2c52bf60001b6104d0565b610af87f21baa28c2eb7d3242d4afa89ad217acdeea738ab84a007f3e8aa489d3ce867c860001b6104d0565b60005b83811015610ec657610b2f7fcdf5d58952d1caa81fdfa362bb2eeb66956f151aa2b33f407f9833563b20496e60001b6104d0565b610b5b7f82fdec1cc8aa1098d9a8242384eaea39f90e5593c12b39cb109348a772e9fafe60001b6104d0565b6000868683818110610b7057610b6f61142f565b5b905060400201600001359050610ba87faaf73602f455fb6fc88332cf7f6d0caabacde6b54d461dc6eb9a7ee12bb2b57460001b6104d0565b610bd47f0d14c42168fe96cb818965cb522ed1023d13f8dc0ab098cdf8760c35932c9cdf60001b6104d0565b6000878784818110610be957610be861142f565b5b9050604002016020016020810190610c0191906112ad565b9050610c2f7f4fccbbc284abd163c3c18f168872dc29d4fac77f01fc1cf5f9992b361605dc4f60001b6104d0565b610c5b7f14f24022c2530a4720a223a36c798ed655b1320c21a7fb1cd078146c936b277060001b6104d0565b60008173ffffffffffffffffffffffffffffffffffffffff16836108fc90604051610c85906115ef565b600060405180830381858888f193505050503d8060008114610cc3576040519150601f19603f3d011682016040523d82523d6000602084013e610cc8565b606091505b50509050610cf87f990d01d9292bbf5a72b844d9e480c435f5bf3f28c6a3cf01231653128d574a2960001b6104d0565b610d247fbeb05d1cb9e0c8962b3fbce755095395f809190d1f56a0305f52d745ed2be60860001b6104d0565b8015610dd657610d567f926cdb8fa3eec76098df0921133fbad388217c8a5f07adf0e3652e64344ff66760001b6104d0565b610d827fcf258c3a8696678566a6fd532ee096e27d2a9dc64bcc87d8fccf2c9df406855560001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff16867feaa22fd2d7b875476355b32cf719794faf9d91b66e73bc6375a053cace9caaee85604051610dc991906110ac565b60405180910390a3610e7e565b610e027f9065e1e3bc2a1b35f85ca394361800750d7ccf66381f3e69fe4faefe0e5cc78f60001b6104d0565b610e2e7f57081b0378c1c31ae18ff29ec060b75a2fcf8bec375989be94d0d303a4f0021160001b6104d0565b8173ffffffffffffffffffffffffffffffffffffffff16867f9b478c095979d3d3a7d602ffd9ee1f0843204d853558ae0882c8fcc0a5bc78cf85604051610e7591906110ac565b60405180910390a35b610eaa7f9de3918864af83d66c46c014e27703f1021307042aef5dcf52b75516706ddd8b60001b6104d0565b6001860195505050508080610ebe906114e3565b915050610afb565b50505050505050565b610ed7610fc7565b73ffffffffffffffffffffffffffffffffffffffff16610ef56104a7565b73ffffffffffffffffffffffffffffffffffffffff1614610f4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4290611337565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb290611676565b60405180910390fd5b610fc481610fcf565b50565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6110a681611093565b82525050565b60006020820190506110c1600083018461109d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006110f2826110c7565b9050919050565b611102816110e7565b82525050565b600060208201905061111d60008301846110f9565b92915050565b600080fd5b600080fd5b6000819050919050565b6111408161112d565b811461114b57600080fd5b50565b60008135905061115d81611137565b92915050565b60006020828403121561117957611178611123565b5b60006111878482850161114e565b91505092915050565b61119981611093565b81146111a457600080fd5b50565b6000813590506111b681611190565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126111e1576111e06111bc565b5b8235905067ffffffffffffffff8111156111fe576111fd6111c1565b5b60208301915083604082028301111561121a576112196111c6565b5b9250929050565b60008060006040848603121561123a57611239611123565b5b6000611248868287016111a7565b935050602084013567ffffffffffffffff81111561126957611268611128565b5b611275868287016111cb565b92509250509250925092565b61128a816110e7565b811461129557600080fd5b50565b6000813590506112a781611281565b92915050565b6000602082840312156112c3576112c2611123565b5b60006112d184828501611298565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006113216020836112da565b915061132c826112eb565b602082019050919050565b6000602082019050818103600083015261135081611314565b9050919050565b7f4e6f2064697362757273656d656e747300000000000000000000000000000000600082015250565b600061138d6010836112da565b915061139882611357565b602082019050919050565b600060208201905081810360008301526113bc81611380565b9050919050565b7f556e6578706563746564206e657874206465706f736974206964000000000000600082015250565b60006113f9601a836112da565b9150611404826113c3565b602082019050919050565b60006020820190508181036000830152611428816113ec565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061149882611093565b91506114a383611093565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156114d8576114d761145e565b5b828201905092915050565b60006114ee82611093565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156115215761152061145e565b5b600182019050919050565b7f44697362757273656d656e7420746f74616c20213d20616d6f756e742073656e60008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b60006115886021836112da565b91506115938261152c565b604082019050919050565b600060208201905081810360008301526115b78161157b565b9050919050565b600081905092915050565b50565b60006115d96000836115be565b91506115e4826115c9565b600082019050919050565b60006115fa826115cc565b9150819050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006116606026836112da565b915061166b82611604565b604082019050919050565b6000602082019050818103600083015261168f81611653565b905091905056fea264697066735822122083f16098b83d1bcd3c8f88b64cd62c2ff0f7149c4df36e3ea3404931581a899064736f6c63430008090033",
"devdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"params": {
"balance": "The current contract balance paid to the owner.",
"owner": "The current owner and recipient of the funds."
}
},
"DisbursementFailed(uint256,address,uint256)": {
"params": {
"amount": "The amount intended to be sent to the recipient.",
"depositId": "The unique sequence number identifying the deposit.",
"to": "The intended recipient of the disbursement."
}
},
"DisbursementSuccess(uint256,address,uint256)": {
"params": {
"amount": "The amount sent to the recipient.",
"depositId": "The unique sequence number identifying the deposit.",
"to": "The recipient of the disbursement."
}
}
},
"kind": "dev",
"methods": {
"disburse(uint256,(uint256,address)[])": {
"params": {
"_disbursements": "A list of Disbursements to process.",
"_nextDepositId": "The depositId of the first Dispursement."
}
},
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "TeleportrDisburser",
"version": 1
},
"userdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"notice": "Emitted any time the balance is withdrawn by the owner."
},
"DisbursementFailed(uint256,address,uint256)": {
"notice": "Emitted any time a disbursement fails to send."
},
"DisbursementSuccess(uint256,address,uint256)": {
"notice": "Emitted any time a disbursement is successfuly sent."
}
},
"kind": "user",
"methods": {
"constructor": {
"notice": "Initializes a new TeleportrDisburser contract."
},
"disburse(uint256,(uint256,address)[])": {
"notice": "Accepts a list of Disbursements and forwards the amount paid to the contract to each recipient. The method reverts if there are zero disbursements, the total amount to forward differs from the amount sent in the transaction, or the _nextDepositId is unexpected. Failed disbursements will not cause the method to revert, but will instead be held by the contract and availabe for the owner to withdraw."
},
"totalDisbursements()": {
"notice": "The total number of disbursements processed."
},
"withdrawBalance()": {
"notice": "Sends the contract's current balance to the owner."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 393,
"contract": "contracts/L2/teleportr/TeleportrDisburser.sol:TeleportrDisburser",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 10517,
"contract": "contracts/L2/teleportr/TeleportrDisburser.sol:TeleportrDisburser",
"label": "totalDisbursements",
"offset": 0,
"slot": "1",
"type": "t_uint256"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,6 +23,7 @@ dotenv.config()
const enableGasReport = !!process.env.ENABLE_GAS_REPORT
const privateKey = process.env.PRIVATE_KEY || '0x' + '11'.repeat(32) // this is to avoid hardhat error
const deploy = process.env.DEPLOY_DIRECTORY || 'deploy'
const config: HardhatUserConfig = {
networks: {
......@@ -40,11 +41,13 @@ const config: HardhatUserConfig = {
'optimism-kovan': {
chainId: 69,
url: 'https://kovan.optimism.io',
deploy,
accounts: [privateKey],
},
'optimism-mainnet': {
chainId: 10,
url: 'https://mainnet.optimism.io',
deploy,
accounts: [privateKey],
},
'mainnet-trial': {
......@@ -52,6 +55,18 @@ const config: HardhatUserConfig = {
url: 'http://127.0.0.1:8545',
accounts: [privateKey],
},
kovan: {
chainId: 42,
url: process.env.CONTRACTS_RPC_URL || '',
deploy,
accounts: [privateKey],
},
mainnet: {
chainId: 1,
url: process.env.CONTRACTS_RPC_URL || '',
deploy,
accounts: [privateKey],
},
},
mocha: {
timeout: 50000,
......
......@@ -20,7 +20,6 @@
"build": "yarn build:contracts && yarn autogen:artifacts && yarn build:typescript",
"build:typescript": "tsc -p ./tsconfig.build.json",
"build:contracts": "hardhat compile --show-stack-traces",
"build:dump": "ts-node bin/take-dump.ts",
"autogen:markdown": "ts-node scripts/generate-markdown.ts",
"autogen:artifacts": "ts-node scripts/generate-artifacts.ts && ts-node scripts/generate-deployed-artifacts.ts",
"test": "yarn test:contracts",
......
#!/bin/bash
export L2_BLOCK_GAS_LIMIT=15000000
export L2_CHAIN_ID=420
export BLOCK_SIGNER_ADDRESS=0x27770a9694e4B4b1E130Ab91Bc327C36855f612E
export L1_STANDARD_BRIDGE_ADDRESS=0x73298186A143a54c20ae98EEE5a025bD5979De02
export L1_FEE_WALLET_ADDRESS=0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244
export L1_CROSS_DOMAIN_MESSENGER_ADDRESS=0xEcC89b9EDD804850C4F343A278Be902be11AaF42
export WHITELIST_OWNER=0x0000000000000000000000000000000000000000
export GAS_PRICE_ORACLE_OWNER=0x84f70449f90300997840eCb0918873745Ede7aE6
yarn build:dump
#!/bin/bash
### DEPLOYMENT SCRIPT ###
# To be called from root of contracts dir #
# Required env vars
if [[ -z "$CONTRACTS_DEPLOYER_KEY" ]]; then
echo "Must pass CONTRACTS_DEPLOYER_KEY"
exit 1
fi
if [[ -z "$CONTRACTS_RPC_URL" ]]; then
echo "Must pass CONTRACTS_RPC_URL"
exit 1
fi
if [[ -z "$ETHERSCAN_API_KEY" ]]; then
echo "Must pass ETHERSCAN_API_KEY"
exit 1
fi
CONTRACTS_TARGET_NETWORK=goerli \
npx hardhat deploy \
--l1-block-time-seconds 15 \
--ctc-max-transaction-gas-limit 15000000 \
--ctc-l2-gas-discount-divisor 32 \
--ctc-enqueue-gas-cost 60000 \
--scc-fraud-proof-window 604800 \
--scc-sequencer-publish-window 12592000 \
--ovm-sequencer-address 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--ovm-proposer-address 0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3 \
--ovm-address-manager-owner 0x32b70c156302d28A9119445d2bbb9ab1cBD01671 \
--network goerli
CONTRACTS_TARGET_NETWORK=goerli \
npx hardhat etherscan-verify --network goerli
#!/bin/bash
export L2_BLOCK_GAS_LIMIT=15000000
export L2_CHAIN_ID=69
export BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F
export L1_STANDARD_BRIDGE_ADDRESS=0x22F24361D548e5FaAfb36d1437839f080363982B
export L1_FEE_WALLET_ADDRESS=0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244
export L1_CROSS_DOMAIN_MESSENGER_ADDRESS=0x4361d0F75A0186C05f971c566dC6bEa5957483fD
export WHITELIST_OWNER=0x0000000000000000000000000000000000000000
export GAS_PRICE_ORACLE_OWNER=0x84f70449f90300997840eCb0918873745Ede7aE6
yarn build:dump
#!/bin/bash
### DEPLOYMENT SCRIPT ###
# To be called from root of contracts dir #
# Required env vars
if [[ -z "$CONTRACTS_DEPLOYER_KEY" ]]; then
echo "Must pass CONTRACTS_DEPLOYER_KEY"
exit 1
fi
if [[ -z "$CONTRACTS_RPC_URL" ]]; then
echo "Must pass CONTRACTS_RPC_URL"
exit 1
fi
if [[ -z "$ETHERSCAN_API_KEY" ]]; then
echo "Must pass ETHERSCAN_API_KEY"
exit 1
fi
CONTRACTS_TARGET_NETWORK=kovan \
npx hardhat deploy \
--l1-block-time-seconds 15 \
--ctc-max-transaction-gas-limit 15000000 \
--ctc-l2-gas-discount-divisor 32 \
--ctc-enqueue-gas-cost 60000 \
--scc-fraud-proof-window 10 \
--scc-sequencer-publish-window 12592000 \
--ovm-sequencer-address 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--ovm-proposer-address 0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3 \
--ovm-address-manager-owner 0x18394B52d3Cb931dfA76F63251919D051953413d \
--gasprice 1000000000 \
--num-deploy-confirmations 1 \
--tags upgrade \
--network kovan
CONTRACTS_TARGET_NETWORK=kovan \
npx hardhat etherscan-verify \
--network kovan \
--sleep
#!/bin/bash
export L2_BLOCK_GAS_LIMIT=15000000
export L2_CHAIN_ID=10
export BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F
export L1_STANDARD_BRIDGE_ADDRESS=0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1
export L1_FEE_WALLET_ADDRESS=0x391716d440c151c42cdf1c95c1d83a5427bca52c
export L1_CROSS_DOMAIN_MESSENGER_ADDRESS=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1
export WHITELIST_OWNER=0x648E3e8101BFaB7bf5997Bd007Fb473786019159
export GAS_PRICE_ORACLE_OWNER=0x7107142636C85c549690b1Aca12Bdb8052d26Ae6
yarn build:dump
#!/bin/bash
export L2_BLOCK_GAS_LIMIT=15000000
export L2_CHAIN_ID=66666
export BLOCK_SIGNER_ADDRESS=0x27770a9694e4B4b1E130Ab91Bc327C36855f612E
export L1_STANDARD_BRIDGE_ADDRESS=0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1
export L1_FEE_WALLET_ADDRESS=0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244
export L1_CROSS_DOMAIN_MESSENGER_ADDRESS=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1
export WHITELIST_OWNER=0x0000000000000000000000000000000000000000
export GAS_PRICE_ORACLE_OWNER=0x84f70449f90300997840eCb0918873745Ede7aE6
yarn build:dump
#!/bin/bash
### DEPLOYMENT SCRIPT ###
# To be called from root of contracts dir #
# Required env vars
if [[ -z "$CONTRACTS_DEPLOYER_KEY" ]]; then
echo "Must pass CONTRACTS_DEPLOYER_KEY"
exit 1
fi
if [[ -z "$CONTRACTS_RPC_URL" ]]; then
echo "Must pass CONTRACTS_RPC_URL"
exit 1
fi
if [[ -z "$ETHERSCAN_API_KEY" ]]; then
echo "Must pass ETHERSCAN_API_KEY"
exit 1
fi
CONTRACTS_TARGET_NETWORK=mainnet-trial \
npx hardhat deploy \
--ctc-max-transaction-gas-limit 15000000 \
--ctc-enqueue-gas-cost 60000 \
--ctc-l2-gas-discount-divisor 32 \
--l1-block-time-seconds 15 \
--ovm-address-manager-owner 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A \
--ovm-sequencer-address 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--ovm-proposer-address 0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3 \
--scc-fraud-proof-window 10 \
--scc-sequencer-publish-window 12592000 \
--network mainnet-trial \
--gasprice 2000000000000 \
--forked true \
--num-deploy-confirmations 0 \
--tags upgrade
#!/bin/bash
### DEPLOYMENT SCRIPT ###
# To be called from root of contracts dir #
# Required env vars
if [[ -z "$CONTRACTS_DEPLOYER_KEY" ]]; then
echo "Must pass CONTRACTS_DEPLOYER_KEY"
exit 1
fi
if [[ -z "$CONTRACTS_RPC_URL" ]]; then
echo "Must pass CONTRACTS_RPC_URL"
exit 1
fi
if [[ -z "$ETHERSCAN_API_KEY" ]]; then
echo "Must pass ETHERSCAN_API_KEY"
exit 1
fi
CONTRACTS_TARGET_NETWORK=mainnet \
npx hardhat deploy \
--l1-block-time-seconds 15 \
--ctc-max-transaction-gas-limit 15000000 \
--ctc-l2-gas-discount-divisor 32 \
--ctc-enqueue-gas-cost 60000 \
--scc-fraud-proof-window 604800 \
--scc-sequencer-publish-window 12592000 \
--ovm-sequencer-address 0x6887246668a3b87F54DeB3b94Ba47a6f63F32985 \
--ovm-proposer-address 0x473300df21D047806A082244b417f96b32f13A33 \
--ovm-address-manager-owner 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A \
--gasprice 150000000000 \
--num-deploy-confirmations 4 \
--tags upgrade \
--network mainnet
CONTRACTS_TARGET_NETWORK=mainnet \
npx hardhat etherscan-verify \
--network mainnet \
--sleep
import { ethers } from 'ethers'
/**
* Defines the configuration for a deployment.
*/
export interface DeployConfig {
/**
* Name of the network to deploy to. Must be the name of one of the networks listed in
* hardhat.config.ts.
*/
network: string
/**
* Whether or not this network is a forked network.
*/
isForkedNetwork?: boolean
/**
* Optional number of confs to wait during deployment.
*/
numDeployConfirmations?: number
/**
* Optional gas price to use for deployment transactions.
*/
gasPrice?: number
/**
* Estimated average L1 block time in seconds.
*/
l1BlockTimeSeconds: number
/**
* Gas limit for blocks on L2.
*/
l2BlockGasLimit: number
/**
* Chain ID for the L2 network.
*/
l2ChainId: number
/**
* Discount divisor used to calculate gas burn for L1 to L2 transactions.
*/
ctcL2GasDiscountDivisor: number
/**
* Cost of the "enqueue" function in the CTC.
*/
ctcEnqueueGasCost: number
/**
* Fault proof window in seconds.
*/
sccFaultProofWindowSeconds: number
/**
* Sequencer publish window in seconds.
*/
sccSequencerPublishWindowSeconds: number
/**
* Address of the Sequencer (publishes to CTC).
*/
ovmSequencerAddress: string
/**
* Address of the Proposer (publishes to SCC).
*/
ovmProposerAddress: string
/**
* Address of the account that will sign blocks.
*/
ovmBlockSignerAddress: string
/**
* Address that will receive fees on L1.
*/
ovmFeeWalletAddress: string
/**
* Address of the owner of the AddressManager contract on L1.
*/
ovmAddressManagerOwner: string
/**
* Address of the owner of the GasPriceOracle contract on L2.
*/
ovmGasPriceOracleOwner: string
/**
* Optional whitelist owner address.
*/
ovmWhitelistOwner?: string
/**
* Optional initial overhead value for GPO (default: 2750).
*/
gasPriceOracleOverhead?: number
/**
* Optional initial scalar value for GPO (default: 1500000).
*/
gasPriceOracleScalar?: number
/**
* Optional initial decimals for GPO (default: 6).
*/
gasPriceOracleDecimals?: number
/**
* Optional initial L1 base fee for GPO (default: 1).
*/
gasPriceOracleL1BaseFee?: number
/**
* Optional initial L2 gas price for GPO (default: 1).
*/
gasPriceOracleL2GasPrice?: number
/**
* Optional block number to enable the Berlin hardfork (default: 0).
*/
hfBerlinBlock?: number
}
/**
* Specification for each of the configuration options.
*/
const configSpec: {
[K in keyof DeployConfig]: {
type: string
default?: any
}
} = {
network: {
type: 'string',
},
isForkedNetwork: {
type: 'boolean',
default: false,
},
numDeployConfirmations: {
type: 'number',
default: 0,
},
gasPrice: {
type: 'number',
default: undefined,
},
l1BlockTimeSeconds: {
type: 'number',
},
l2BlockGasLimit: {
type: 'number',
},
l2ChainId: {
type: 'number',
},
ctcL2GasDiscountDivisor: {
type: 'number',
},
ctcEnqueueGasCost: {
type: 'number',
},
sccFaultProofWindowSeconds: {
type: 'number',
},
sccSequencerPublishWindowSeconds: {
type: 'number',
},
ovmSequencerAddress: {
type: 'address',
},
ovmProposerAddress: {
type: 'address',
},
ovmBlockSignerAddress: {
type: 'address',
},
ovmFeeWalletAddress: {
type: 'address',
},
ovmAddressManagerOwner: {
type: 'address',
},
ovmGasPriceOracleOwner: {
type: 'address',
},
ovmWhitelistOwner: {
type: 'address',
default: ethers.constants.AddressZero,
},
gasPriceOracleOverhead: {
type: 'number',
default: 2750,
},
gasPriceOracleScalar: {
type: 'number',
default: 1_500_000,
},
gasPriceOracleDecimals: {
type: 'number',
default: 6,
},
gasPriceOracleL1BaseFee: {
type: 'number',
default: 1,
},
gasPriceOracleL2GasPrice: {
type: 'number',
default: 1,
},
hfBerlinBlock: {
type: 'number',
default: 0,
},
}
/**
* Gets the deploy config for the given network.
*
* @param network Network name.
* @returns Deploy config for the given network.
*/
export const getDeployConfig = (network: string): Required<DeployConfig> => {
let config: DeployConfig
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
config = require(`../deploy-config/${network}.ts`).default
} catch (err) {
throw new Error(
`error while loading deploy config for network: ${network}, ${err}`
)
}
return parseDeployConfig(config)
}
/**
* Parses and validates the given deploy config, replacing any missing values with defaults.
*
* @param config Deploy config to parse.
* @returns Parsed deploy config.
*/
export const parseDeployConfig = (
config: DeployConfig
): Required<DeployConfig> => {
// Create a clone of the config object. Shallow clone is fine because none of the input options
// are expected to be objects or functions etc.
const parsed = { ...config }
for (const [key, spec] of Object.entries(configSpec)) {
// Make sure the value is defined, or use a default.
if (parsed[key] === undefined) {
if ('default' in spec) {
parsed[key] = spec.default
} else {
throw new Error(
`deploy config is missing required field: ${key} (${spec.type})`
)
}
} else {
// Make sure the default has the correct type.
if (spec.type === 'address') {
if (!ethers.utils.isAddress(parsed[key])) {
throw new Error(
`deploy config field: ${key} is not of type ${spec.type}: ${parsed[key]}`
)
}
} else if (typeof parsed[key] !== spec.type) {
throw new Error(
`deploy config field: ${key} is not of type ${spec.type}: ${parsed[key]}`
)
}
}
}
return parsed as Required<DeployConfig>
}
/* Imports: External */
import { ethers, Contract } from 'ethers'
import { Provider } from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer'
import { sleep, awaitCondition } from '@eth-optimism/core-utils'
import { HttpNetworkConfig } from 'hardhat/types'
import { getDeployConfig } from './deploy-config'
/**
* @param {Any} hre Hardhat runtime environment
* @param {String} name Contract name from the names object
......@@ -31,13 +32,14 @@ export const deployAndVerifyAndThen = async ({
}) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const deployConfig = getDeployConfig(hre.network.name)
const result = await deploy(name, {
contract,
from: deployer,
args,
log: true,
waitConfirmations: hre.deployConfig.numDeployConfirmations,
waitConfirmations: deployConfig.numDeployConfirmations,
})
await hre.ethers.provider.waitForTransaction(result.transactionHash)
......@@ -92,6 +94,8 @@ export const getAdvancedContract = (opts: {
hre: any
contract: Contract
}): Contract => {
const deployConfig = getDeployConfig(opts.hre.network.name)
// Temporarily override Object.defineProperty to bypass ether's object protection.
const def = Object.defineProperty
Object.defineProperty = (obj, propName, prop) => {
......@@ -115,7 +119,7 @@ export const getAdvancedContract = (opts: {
// We want to use the gas price that has been configured at the beginning of the deployment.
// However, if the function being triggered is a "constant" (static) function, then we don't
// want to provide a gas price because we're prone to getting insufficient balance errors.
let gasPrice = opts.hre.deployConfig.gasPrice || undefined
let gasPrice = deployConfig.gasPrice || undefined
if (contract.interface.getFunction(fnName).constant) {
gasPrice = 0
}
......@@ -147,7 +151,7 @@ export const getAdvancedContract = (opts: {
return contract[fnName](...args)
}
} else if (
receipt.confirmations >= opts.hre.deployConfig.numDeployConfirmations
receipt.confirmations >= deployConfig.numDeployConfirmations
) {
return tx
}
......@@ -163,7 +167,9 @@ export const fundAccount = async (
address: string,
amount: ethers.BigNumber
) => {
if ((hre as any).deployConfig.forked !== 'true') {
const deployConfig = getDeployConfig(hre.network.name)
if (!deployConfig.isForkedNetwork) {
throw new Error('this method can only be used against a forked network')
}
......@@ -194,7 +200,9 @@ export const sendImpersonatedTx = async (opts: {
gas: string
args: any[]
}) => {
if ((opts.hre as any).deployConfig.forked !== 'true') {
const deployConfig = getDeployConfig(opts.hre.network.name)
if (!deployConfig.isForkedNetwork) {
throw new Error('this method can only be used against a forked network')
}
......
/* Imports: External */
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import * as types from 'hardhat/internal/core/params/argumentTypes'
task('deploy-teleportr-l1')
.addParam(
'minDepositAmountEth',
'Minimum deposit amount, in ETH.',
undefined,
types.string
)
.addParam(
'maxDepositAmountEth',
'Maximum deposit amount, in ETH.',
undefined,
types.string
)
.addParam(
'maxBalanceEth',
'Maximum contract balance, in ETH.',
undefined,
types.string
)
.addOptionalParam(
'numDeployConfirmations',
'Number of confirmations to wait for each transaction in the deployment. More is safer.',
1,
types.int
)
.setAction(
async (
{
minDepositAmountEth,
maxDepositAmountEth,
maxBalanceEth,
numDeployConfirmations,
},
hre: any
) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
console.log('Deploying TeleportrDeposit... ')
await deploy('TeleportrDeposit', {
from: deployer,
args: [
ethers.utils.parseEther(minDepositAmountEth),
ethers.utils.parseEther(maxDepositAmountEth),
ethers.utils.parseEther(maxBalanceEth),
],
log: true,
waitConfirmations: numDeployConfirmations,
})
console.log('Done.')
}
)
task('deploy-teleportr-l2').setAction(
async ({ numDeployConfirmations }, hre: any) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
console.log('Deploying TeleportrDisburser... ')
await deploy('TeleportrDisburser', {
from: deployer,
args: [],
log: true,
waitConfirmations: numDeployConfirmations,
})
console.log('Done.')
}
)
/* Imports: External */
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import * as types from 'hardhat/internal/core/params/argumentTypes'
const DEFAULT_L1_BLOCK_TIME_SECONDS = 15
const DEFAULT_CTC_MAX_TRANSACTION_GAS_LIMIT = 11_000_000
const DEFAULT_CTC_L2_GAS_DISCOUNT_DIVISOR = 32
const DEFAULT_CTC_ENQUEUE_GAS_COST = 60_000
const DEFAULT_SCC_FRAUD_PROOF_WINDOW = 60 * 60 * 24 * 7 // 7 days
const DEFAULT_SCC_SEQUENCER_PUBLISH_WINDOW = 60 * 30 // 30 minutes
const DEFAULT_DEPLOY_CONFIRMATIONS = 12
task('deploy')
// Rollup config options
.addOptionalParam(
'l1BlockTimeSeconds',
'Number of seconds on average between every L1 block.',
DEFAULT_L1_BLOCK_TIME_SECONDS,
types.int
)
.addOptionalParam(
'ctcMaxTransactionGasLimit',
'Max gas limit for L1 queue transactions.',
DEFAULT_CTC_MAX_TRANSACTION_GAS_LIMIT,
types.int
)
.addOptionalParam(
'ctcL2GasDiscountDivisor',
'Max gas limit for L1 queue transactions.',
DEFAULT_CTC_L2_GAS_DISCOUNT_DIVISOR,
types.int
)
.addOptionalParam(
'ctcEnqueueGasCost',
'Max gas limit for L1 queue transactions.',
DEFAULT_CTC_ENQUEUE_GAS_COST,
types.int
)
.addOptionalParam(
'sccFraudProofWindow',
'Number of seconds until a transaction is considered finalized.',
DEFAULT_SCC_FRAUD_PROOF_WINDOW,
types.int
)
.addOptionalParam(
'sccSequencerPublishWindow',
'Number of seconds that the sequencer is exclusively allowed to post state roots.',
DEFAULT_SCC_SEQUENCER_PUBLISH_WINDOW,
types.int
)
// Permissioned address options
.addOptionalParam(
'ovmSequencerAddress',
'Address of the sequencer. Must be provided or this deployment will fail.',
undefined,
types.string
)
.addOptionalParam(
'ovmProposerAddress',
'Address of the account that will propose state roots. Must be provided or this deployment will fail.',
undefined,
types.string
)
.addOptionalParam(
'ovmAddressManagerOwner',
'Address that will own the Lib_AddressManager. Must be provided or this deployment will fail.',
undefined,
types.string
)
.addOptionalParam(
'numDeployConfirmations',
'Number of confirmations to wait for each transaction in the deployment. More is safer.',
DEFAULT_DEPLOY_CONFIRMATIONS,
types.int
)
.addOptionalParam(
'forked',
'Enable this when using a forked network (use "true")',
undefined,
types.string
)
.setAction(async (args, hre: any, runSuper) => {
// Necessary because hardhat doesn't let us attach non-optional parameters to existing tasks.
const validateAddressArg = (argName: string) => {
if (args[argName] === undefined) {
throw new Error(
`argument for ${argName} is required but was not provided`
)
}
if (!ethers.utils.isAddress(args[argName])) {
throw new Error(
`argument for ${argName} is not a valid address: ${args[argName]}`
)
}
}
validateAddressArg('ovmSequencerAddress')
validateAddressArg('ovmProposerAddress')
validateAddressArg('ovmAddressManagerOwner')
hre.deployConfig = args
return runSuper(args)
})
export * from './deploy'
export * from './l2-gasprice'
export * from './set-owner'
export * from './take-dump'
export * from './validate-address-dictator'
export * from './validate-chugsplash-dictator'
export * from './whitelist'
export * from './withdraw-fees'
export * from './fetch-batches'
export * from './deploy-teleportr'
/* External Imports */
import * as path from 'path'
import * as fs from 'fs'
import { exec } from 'child_process'
import { promisify } from 'util'
import * as mkdirp from 'mkdirp'
import { ethers } from 'ethers'
import {
computeStorageSlots,
getStorageLayout,
} from '@defi-wonderland/smock/dist/src/utils'
import { task } from 'hardhat/config'
import { remove0x } from '@eth-optimism/core-utils'
/* Internal Imports */
import { predeploys } from './predeploys'
import { getContractArtifact } from './contract-artifacts'
export interface RollupDeployConfig {
// Address that will own the L2 deployer whitelist.
whitelistOwner: string
// Address that will own the L2 gas price oracle.
gasPriceOracleOwner: string
// Overhead value of the gas price oracle
gasPriceOracleOverhead: number
// Scalar value of the gas price oracle
gasPriceOracleScalar: number
// L1 base fee of the gas price oracle
gasPriceOracleL1BaseFee: number
// L2 gas price of the gas price oracle
gasPriceOracleGasPrice: number
// Number of decimals of the gas price oracle scalar
gasPriceOracleDecimals: number
// Initial value for the L2 block gas limit.
l2BlockGasLimit: number
// Chain ID to give the L2 network.
l2ChainId: number
// Address of the key that will sign blocks.
blockSignerAddress: string
// Address of the L1StandardBridge contract.
l1StandardBridgeAddress: string
// Address of the L1 fee wallet.
l1FeeWalletAddress: string
// Address of the L1CrossDomainMessenger contract.
l1CrossDomainMessengerAddress: string
// Block height to activate berlin hardfork
berlinBlock: number
}
/**
* Generates the initial state for the L2 system by injecting the relevant L2 system contracts.
*
* @param cfg Configuration for the L2 system.
* @returns Generated L2 genesis state.
*/
export const makeL2GenesisFile = async (
cfg: RollupDeployConfig
): Promise<any> => {
// Very basic validation.
for (const [key, val] of Object.entries(cfg)) {
if (val === undefined) {
throw new Error(`must provide an input for config value: ${key}`)
}
import { predeploys } from '../src/predeploys'
import { getContractFromArtifact } from '../src/deploy-utils'
import { getDeployConfig } from '../src/deploy-config'
import { names } from '../src/address-names'
task('take-dump').setAction(async (args, hre) => {
/* eslint-disable @typescript-eslint/no-var-requires */
// Needs to be imported here or hardhat will throw a fit about hardhat being imported from
// within the configuration file.
const {
computeStorageSlots,
getStorageLayout,
} = require('@defi-wonderland/smock/dist/src/utils')
// Needs to be imported here because the artifacts can only be generated after the contracts have
// been compiled, but compiling the contracts will import the config file which, as a result,
// will import this file.
const { getContractArtifact } = require('../src/contract-artifacts')
/* eslint-enable @typescript-eslint/no-var-requires */
// Make sure we have a deploy config for this network
const deployConfig = getDeployConfig(hre.network.name)
// Basic warning so users know that the whitelist will be disabled if the owner is the zero address.
if (
deployConfig.ovmWhitelistOwner === undefined ||
deployConfig.ovmWhitelistOwner === ethers.constants.AddressZero
) {
console.log(
'WARNING: whitelist owner is undefined or address(0), whitelist will be disabled'
)
}
const variables = {
OVM_DeployerWhitelist: {
owner: cfg.whitelistOwner,
owner: deployConfig.ovmWhitelistOwner,
},
OVM_GasPriceOracle: {
_owner: cfg.gasPriceOracleOwner,
gasPrice: cfg.gasPriceOracleGasPrice,
l1BaseFee: cfg.gasPriceOracleL1BaseFee,
overhead: cfg.gasPriceOracleOverhead,
scalar: cfg.gasPriceOracleScalar,
decimals: cfg.gasPriceOracleDecimals,
_owner: deployConfig.ovmGasPriceOracleOwner,
gasPrice: deployConfig.gasPriceOracleL2GasPrice,
l1BaseFee: deployConfig.gasPriceOracleL1BaseFee,
overhead: deployConfig.gasPriceOracleOverhead,
scalar: deployConfig.gasPriceOracleScalar,
decimals: deployConfig.gasPriceOracleDecimals,
},
L2StandardBridge: {
l1TokenBridge: cfg.l1StandardBridgeAddress,
l1TokenBridge: (
await getContractFromArtifact(
hre,
names.managed.contracts.Proxy__OVM_L1StandardBridge
)
).address,
messenger: predeploys.L2CrossDomainMessenger,
},
OVM_SequencerFeeVault: {
l1FeeWallet: cfg.l1FeeWalletAddress,
l1FeeWallet: deployConfig.ovmFeeWalletAddress,
},
OVM_ETH: {
l2Bridge: predeploys.L2StandardBridge,
......@@ -89,7 +77,12 @@ export const makeL2GenesisFile = async (
// We default the xDomainMsgSender to this value to save gas.
// See usage of this default in the L2CrossDomainMessenger contract.
xDomainMsgSender: '0x000000000000000000000000000000000000dEaD',
l1CrossDomainMessenger: cfg.l1CrossDomainMessengerAddress,
l1CrossDomainMessenger: (
await getContractFromArtifact(
hre,
names.managed.contracts.Proxy__OVM_L1CrossDomainMessenger
)
).address,
// Set the messageNonce to a high value to avoid overwriting old sent messages.
messageNonce: 100000,
},
......@@ -139,10 +132,10 @@ export const makeL2GenesisFile = async (
commit = '0000000000000000000000000000000000000000'
}
return {
const genesis = {
commit,
config: {
chainId: cfg.l2ChainId,
chainId: deployConfig.l2ChainId,
homesteadBlock: 0,
eip150Block: 0,
eip155Block: 0,
......@@ -152,19 +145,27 @@ export const makeL2GenesisFile = async (
petersburgBlock: 0,
istanbulBlock: 0,
muirGlacierBlock: 0,
berlinBlock: cfg.berlinBlock,
berlinBlock: deployConfig.hfBerlinBlock,
clique: {
period: 0,
epoch: 30000,
},
},
difficulty: '1',
gasLimit: cfg.l2BlockGasLimit.toString(10),
gasLimit: deployConfig.l2BlockGasLimit.toString(10),
extradata:
'0x' +
'00'.repeat(32) +
remove0x(cfg.blockSignerAddress) +
remove0x(deployConfig.ovmBlockSignerAddress) +
'00'.repeat(65),
alloc: dump,
}
}
// Make sure the output location exists
const outdir = path.resolve(__dirname, '../genesis')
const outfile = path.join(outdir, `${hre.network.name}.json`)
mkdirp.sync(outdir)
// Write the genesis file
fs.writeFileSync(outfile, JSON.stringify(genesis, null, 4))
})
......@@ -10,6 +10,7 @@
],
"scripts": {
"start": "ts-node ./src/service.ts",
"test:coverage": "echo 'No tests defined.'",
"build": "tsc -p ./tsconfig.build.json",
"clean": "rimraf dist/ ./tsconfig.build.tsbuildinfo",
"lint": "yarn lint:fix && yarn lint:check",
......
......@@ -10,6 +10,7 @@
],
"scripts": {
"start": "ts-node ./src/service",
"test:coverage": "echo 'No tests defined.'",
"build": "tsc -p tsconfig.build.json",
"clean": "rimraf ./dist ./tsconfig.build.tsbuildinfo",
"lint": "yarn run lint:fix && yarn run lint:check",
......
import { Provider } from '@ethersproject/abstract-provider'
import { BaseServiceV2, Gauge, validators } from '@eth-optimism/common-ts'
import { Provider, Block } from '@ethersproject/abstract-provider'
import {
BaseServiceV2,
Counter,
Gauge,
validators,
} from '@eth-optimism/common-ts'
import { sleep } from '@eth-optimism/core-utils'
type HealthcheckOptions = {
......@@ -13,6 +18,8 @@ type HealthcheckMetrics = {
isCurrentlyDiverged: Gauge
referenceHeight: Gauge
targetHeight: Gauge
targetConnectionFailures: Counter
referenceConnectionFailures: Counter
}
type HealthcheckState = {}
......@@ -59,15 +66,48 @@ export class HealthcheckService extends BaseServiceV2<
type: Gauge,
desc: 'Block height of the target client',
},
targetConnectionFailures: {
type: Counter,
desc: 'Number of connection failures to the target client',
},
referenceConnectionFailures: {
type: Counter,
desc: 'Number of connection failures to the reference client',
},
},
})
}
async main() {
const targetLatest = await this.options.targetRpcProvider.getBlock('latest')
const referenceLatest = await this.options.referenceRpcProvider.getBlock(
'latest'
)
// Get the latest block from the target client and check for connection failures.
let targetLatest: Block
try {
targetLatest = await this.options.targetRpcProvider.getBlock('latest')
} catch (err) {
if (err.message.includes('could not detect network')) {
this.logger.error('target client not connected')
this.metrics.targetConnectionFailures.inc()
return
} else {
throw err
}
}
// Get the latest block from the reference client and check for connection failures.
let referenceLatest: Block
try {
referenceLatest = await this.options.referenceRpcProvider.getBlock(
'latest'
)
} catch (err) {
if (err.message.includes('could not detect network')) {
this.logger.error('reference client not connected')
this.metrics.referenceConnectionFailures.inc()
return
} else {
throw err
}
}
// Update these metrics first so they'll refresh no matter what.
this.metrics.targetHeight.set(targetLatest.number)
......
......@@ -11106,9 +11106,9 @@ minimist-options@4.1.0, minimist-options@^4.0.2:
kind-of "^6.0.3"
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@~1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minipass-collect@^1.0.2:
version "1.0.2"
......@@ -11520,7 +11520,7 @@ node-fetch@2.6.1:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-fetch@^2.6.0, node-fetch@^2.6.1:
node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment