Commit 1f618bb7 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #2346 from mslipper/feat/circleci-2

ci: Add CircleCI config
parents edbf338e 8d5ebf21
...@@ -7,32 +7,13 @@ slack-nightly-build-fail-post-step: &slack-nightly-build-fail-post-step ...@@ -7,32 +7,13 @@ slack-nightly-build-fail-post-step: &slack-nightly-build-fail-post-step
- slack/notify: - slack/notify:
channel: $SLACK_DEFAULT_CHANNEL channel: $SLACK_DEFAULT_CHANNEL
event: fail event: fail
custom: | template: basic_fail-1
{
"text": "", executors:
"blocks": [ go-builder:
{ docker:
"type": "section", - image: ethereumoptimism/go-builder:latest
"text": {
"type": "mrkdwn",
"text": "🔴 Nightly build failed!"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
commands: commands:
build-dockerfile: build-dockerfile:
parameters: parameters:
...@@ -56,6 +37,27 @@ commands: ...@@ -56,6 +37,27 @@ commands:
echo -n "$STACKMAN_REPO_AUTH" | docker login -u _json_key --password-stdin https://us-east4-docker.pkg.dev 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 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" 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: jobs:
build-dtl: build-dtl:
docker: docker:
...@@ -169,8 +171,294 @@ jobs: ...@@ -169,8 +171,294 @@ jobs:
command: | command: |
echo "Dummy job." 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: 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: nightly-itests:
triggers: triggers:
- schedule: - schedule:
......
...@@ -38,38 +38,27 @@ func (d *Database) GetL1TokenByAddress(address string) (*Token, error) { ...@@ -38,38 +38,27 @@ func (d *Database) GetL1TokenByAddress(address string) (*Token, error) {
var token *Token var token *Token
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectL1TokenStatement) row := tx.QueryRow(selectL1TokenStatement, address)
if err != nil { if row.Err() != nil {
return err return row.Err()
}
rows, err := queryStmt.Query(address)
if err != nil {
return err
}
if !rows.Next() {
return nil
} }
var name string var name string
var symbol string var symbol string
var decimals uint8 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 { if err != nil {
return err return err
} }
if rows.Next() {
return errors.New("address should be unique")
}
token = &Token{ token = &Token{
Name: name, Name: name,
Symbol: symbol, Symbol: symbol,
Decimals: decimals, Decimals: decimals,
} }
return nil return nil
}) })
if err != nil { if err != nil {
...@@ -88,32 +77,22 @@ func (d *Database) GetL2TokenByAddress(address string) (*Token, error) { ...@@ -88,32 +77,22 @@ func (d *Database) GetL2TokenByAddress(address string) (*Token, error) {
var token *Token var token *Token
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectL2TokenStatement) row := tx.QueryRow(selectL2TokenStatement, address)
if err != nil { if row.Err() != nil {
return err return row.Err()
}
rows, err := queryStmt.Query(address)
if err != nil {
return err
}
if !rows.Next() {
return nil
} }
var name string var name string
var symbol string var symbol string
var decimals uint8 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 { if err != nil {
return err return err
} }
if rows.Next() {
return errors.New("address should be unique")
}
token = &Token{ token = &Token{
Name: name, Name: name,
Symbol: symbol, Symbol: symbol,
...@@ -141,22 +120,14 @@ func (d *Database) AddL1Token(address string, token *Token) error { ...@@ -141,22 +120,14 @@ func (d *Database) AddL1Token(address string, token *Token) error {
` `
return txn(d.db, func(tx *sql.Tx) error { return txn(d.db, func(tx *sql.Tx) error {
tokenStmt, err := tx.Prepare(insertTokenStatement) _, err := tx.Exec(
if err != nil { insertTokenStatement,
return err
}
_, err = tokenStmt.Exec(
address, address,
token.Name, token.Name,
token.Symbol, token.Symbol,
token.Decimals, token.Decimals,
) )
if err != nil { return err
return err
}
return nil
}) })
} }
...@@ -172,22 +143,14 @@ func (d *Database) AddL2Token(address string, token *Token) error { ...@@ -172,22 +143,14 @@ func (d *Database) AddL2Token(address string, token *Token) error {
` `
return txn(d.db, func(tx *sql.Tx) error { return txn(d.db, func(tx *sql.Tx) error {
tokenStmt, err := tx.Prepare(insertTokenStatement) _, err := tx.Exec(
if err != nil { insertTokenStatement,
return err
}
_, err = tokenStmt.Exec(
address, address,
token.Name, token.Name,
token.Symbol, token.Symbol,
token.Decimals, token.Decimals,
) )
if err != nil { return err
return err
}
return nil
}) })
} }
...@@ -209,12 +172,8 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error { ...@@ -209,12 +172,8 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
` `
return txn(d.db, func(tx *sql.Tx) error { return txn(d.db, func(tx *sql.Tx) error {
blockStmt, err := tx.Prepare(insertBlockStatement) _, err := tx.Exec(
if err != nil { insertBlockStatement,
return err
}
_, err = blockStmt.Exec(
block.Hash.String(), block.Hash.String(),
block.ParentHash.String(), block.ParentHash.String(),
block.Number, block.Number,
...@@ -228,13 +187,9 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error { ...@@ -228,13 +187,9 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
return nil return nil
} }
depositStmt, err := tx.Prepare(insertDepositStatement)
if err != nil {
return err
}
for _, deposit := range block.Deposits { for _, deposit := range block.Deposits {
_, err = depositStmt.Exec( _, err = tx.Exec(
insertDepositStatement,
NewGUID(), NewGUID(),
deposit.FromAddress.String(), deposit.FromAddress.String(),
deposit.ToAddress.String(), deposit.ToAddress.String(),
...@@ -273,12 +228,8 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error { ...@@ -273,12 +228,8 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
` `
return txn(d.db, func(tx *sql.Tx) error { return txn(d.db, func(tx *sql.Tx) error {
blockStmt, err := tx.Prepare(insertBlockStatement) _, err := tx.Exec(
if err != nil { insertBlockStatement,
return err
}
_, err = blockStmt.Exec(
block.Hash.String(), block.Hash.String(),
block.ParentHash.String(), block.ParentHash.String(),
block.Number, block.Number,
...@@ -292,13 +243,9 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error { ...@@ -292,13 +243,9 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
return nil return nil
} }
withdrawalStmt, err := tx.Prepare(insertWithdrawalStatement)
if err != nil {
return err
}
for _, withdrawal := range block.Withdrawals { for _, withdrawal := range block.Withdrawals {
_, err = withdrawalStmt.Exec( _, err = tx.Exec(
insertWithdrawalStatement,
NewGUID(), NewGUID(),
withdrawal.FromAddress.String(), withdrawal.FromAddress.String(),
withdrawal.ToAddress.String(), withdrawal.ToAddress.String(),
...@@ -330,13 +277,9 @@ func (d *Database) AddStateBatch(batches []StateBatch) error { ...@@ -330,13 +277,9 @@ func (d *Database) AddStateBatch(batches []StateBatch) error {
` `
return txn(d.db, func(tx *sql.Tx) error { return txn(d.db, func(tx *sql.Tx) error {
stateBatchStmt, err := tx.Prepare(insertStateBatchStatement)
if err != nil {
return err
}
for _, sb := range batches { for _, sb := range batches {
_, err = stateBatchStmt.Exec( _, err := tx.Exec(
insertStateBatchStatement,
sb.Index.Uint64(), sb.Index.Uint64(),
sb.Root.String(), sb.Root.String(),
sb.Size.Uint64(), sb.Size.Uint64(),
...@@ -371,15 +314,11 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP ...@@ -371,15 +314,11 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
var deposits []DepositJSON var deposits []DepositJSON
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectDepositsStatement) rows, err := tx.Query(selectDepositsStatement, address.String(), page.Limit, page.Offset)
if err != nil {
return err
}
rows, err := queryStmt.Query(address.String(), page.Limit, page.Offset)
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var deposit DepositJSON var deposit DepositJSON
...@@ -397,9 +336,8 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP ...@@ -397,9 +336,8 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
deposits = append(deposits, deposit) deposits = append(deposits, deposit)
} }
return nil return rows.Err()
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -414,21 +352,17 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP ...@@ -414,21 +352,17 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
` `
var count uint64 var count uint64
err = txn(d.db, func(tx *sql.Tx) error { err = txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectDepositCountStatement) row := tx.QueryRow(selectDepositCountStatement, address.String())
if err != nil { if err != nil {
return err return err
} }
row := queryStmt.QueryRow(address.String()) return row.Scan(&count)
if err != nil {
return err
}
row.Scan(&count)
return nil
}) })
if err != nil {
return nil, err
}
page.Total = count page.Total = count
...@@ -458,12 +392,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro ...@@ -458,12 +392,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro
var batch *StateBatchJSON var batch *StateBatchJSON
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalBatchStatement) row := tx.QueryRow(selectWithdrawalBatchStatement, hash.String())
if err != nil {
return err
}
row := queryStmt.QueryRow(hash.String())
if row.Err() != nil { if row.Err() != nil {
return row.Err() return row.Err()
} }
...@@ -471,7 +400,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro ...@@ -471,7 +400,7 @@ func (d *Database) GetWithdrawalBatch(hash l2common.Hash) (*StateBatchJSON, erro
var index, size, prevTotal, blockNumber, blockTimestamp uint64 var index, size, prevTotal, blockNumber, blockTimestamp uint64
var root, blockHash string var root, blockHash string
var extraData []byte var extraData []byte
err = row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash, err := row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash,
&blockNumber, &blockTimestamp) &blockNumber, &blockTimestamp)
if err != nil { if err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
...@@ -519,15 +448,11 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina ...@@ -519,15 +448,11 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
var withdrawals []WithdrawalJSON var withdrawals []WithdrawalJSON
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalsStatement) rows, err := tx.Query(selectWithdrawalsStatement, address.String(), page.Limit, page.Offset)
if err != nil {
return err
}
rows, err := queryStmt.Query(address.String(), page.Limit, page.Offset)
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var withdrawal WithdrawalJSON var withdrawal WithdrawalJSON
...@@ -545,7 +470,7 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina ...@@ -545,7 +470,7 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
withdrawals = append(withdrawals, withdrawal) withdrawals = append(withdrawals, withdrawal)
} }
return nil return rows.Err()
}) })
if err != nil { if err != nil {
...@@ -567,21 +492,17 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina ...@@ -567,21 +492,17 @@ func (d *Database) GetWithdrawalsByAddress(address l2common.Address, page Pagina
` `
var count uint64 var count uint64
err = txn(d.db, func(tx *sql.Tx) error { err = txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectWithdrawalCountStatement) row := tx.QueryRow(selectWithdrawalCountStatement, address.String())
if err != nil {
return err
}
row := queryStmt.QueryRow(address.String())
if err != nil { if err != nil {
return err return err
} }
row.Scan(&count) return row.Scan(&count)
return nil
}) })
if err != nil {
return nil, err
}
page.Total = count page.Total = count
...@@ -599,19 +520,14 @@ func (d *Database) GetHighestL1Block() (*L1BlockLocator, error) { ...@@ -599,19 +520,14 @@ func (d *Database) GetHighestL1Block() (*L1BlockLocator, error) {
var highestBlock *L1BlockLocator var highestBlock *L1BlockLocator
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectHighestBlockStatement) row := tx.QueryRow(selectHighestBlockStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow()
if row.Err() != nil { if row.Err() != nil {
return row.Err() return row.Err()
} }
var number uint64 var number uint64
var hash string var hash string
err = row.Scan(&number, &hash) err := row.Scan(&number, &hash)
if err != nil { if err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
highestBlock = nil highestBlock = nil
...@@ -642,19 +558,14 @@ func (d *Database) GetHighestL2Block() (*L2BlockLocator, error) { ...@@ -642,19 +558,14 @@ func (d *Database) GetHighestL2Block() (*L2BlockLocator, error) {
var highestBlock *L2BlockLocator var highestBlock *L2BlockLocator
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectHighestBlockStatement) row := tx.QueryRow(selectHighestBlockStatement)
if err != nil {
return err
}
row := queryStmt.QueryRow()
if row.Err() != nil { if row.Err() != nil {
return row.Err() return row.Err()
} }
var number uint64 var number uint64
var hash string var hash string
err = row.Scan(&number, &hash) err := row.Scan(&number, &hash)
if err != nil { if err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
highestBlock = nil highestBlock = nil
...@@ -688,25 +599,20 @@ func (d *Database) GetIndexedL1BlockByHash(hash common.Hash) (*IndexedL1Block, e ...@@ -688,25 +599,20 @@ func (d *Database) GetIndexedL1BlockByHash(hash common.Hash) (*IndexedL1Block, e
var block *IndexedL1Block var block *IndexedL1Block
err := txn(d.db, func(tx *sql.Tx) error { err := txn(d.db, func(tx *sql.Tx) error {
queryStmt, err := tx.Prepare(selectBlockByHashStatement) row := tx.QueryRow(selectBlockByHashStatement, hash.String())
if err != nil {
return err
}
row := queryStmt.QueryRow(hash.String())
if errors.Is(row.Err(), sql.ErrNoRows) {
return nil
}
if row.Err() != nil { if row.Err() != nil {
return err return row.Err()
} }
var hash string var hash string
var parentHash string var parentHash string
var number uint64 var number uint64
var timestamp uint64 var timestamp uint64
err = row.Scan(&hash, &parentHash, &number, &timestamp) err := row.Scan(&hash, &parentHash, &number, &timestamp)
if err != nil { if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil
}
return err return err
} }
......
...@@ -2,12 +2,13 @@ package metrics ...@@ -2,12 +2,13 @@ package metrics
import ( import (
"fmt" "fmt"
"net/http"
l2common "github.com/ethereum-optimism/optimism/l2geth/common" l2common "github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
) )
const metricsNamespace = "indexer" const metricsNamespace = "indexer"
......
...@@ -2,6 +2,7 @@ package bridge ...@@ -2,6 +2,7 @@ package bridge
import ( import (
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/address_manager" "github.com/ethereum-optimism/optimism/go/indexer/bindings/address_manager"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
......
...@@ -2,6 +2,7 @@ package bridge ...@@ -2,6 +2,7 @@ package bridge
import ( import (
"context" "context"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/l1bridge" "github.com/ethereum-optimism/optimism/go/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/go/indexer/db" "github.com/ethereum-optimism/optimism/go/indexer/db"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
......
...@@ -2,6 +2,7 @@ package l1 ...@@ -2,6 +2,7 @@ package l1
import ( import (
"context" "context"
"github.com/ethereum-optimism/optimism/go/indexer/bindings/l1erc20" "github.com/ethereum-optimism/optimism/go/indexer/bindings/l1erc20"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
...@@ -40,7 +41,6 @@ func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, er ...@@ -40,7 +41,6 @@ func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, er
}, nil }, nil
} }
func QueryStateBatches(filterer *scc.StateCommitmentChainFilterer, startHeight, endHeight uint64, ctx context.Context) (map[common.Hash][]db.StateBatch, error) { func QueryStateBatches(filterer *scc.StateCommitmentChainFilterer, startHeight, endHeight uint64, ctx context.Context) (map[common.Hash][]db.StateBatch, error) {
batches := make(map[common.Hash][]db.StateBatch) batches := make(map[common.Hash][]db.StateBatch)
......
...@@ -255,7 +255,7 @@ func (b *Backend) ProxyWS(clientConn *websocket.Conn, methodWhitelist *StringSet ...@@ -255,7 +255,7 @@ func (b *Backend) ProxyWS(clientConn *websocket.Conn, methodWhitelist *StringSet
return nil, ErrBackendOverCapacity return nil, ErrBackendOverCapacity
} }
backendConn, _, err := b.dialer.Dial(b.wsURL, nil) backendConn, _, err := b.dialer.Dial(b.wsURL, nil) // nolint:bodyclose
if err != nil { if err != nil {
b.setOffline() b.setOffline()
if err := b.rateLimiter.DecBackendWSConns(b.Name); err != nil { if err := b.rateLimiter.DecBackendWSConns(b.Name); err != nil {
...@@ -513,7 +513,9 @@ func (w *WSProxier) clientPump(ctx context.Context, errC chan error) { ...@@ -513,7 +513,9 @@ func (w *WSProxier) clientPump(ctx context.Context, errC chan error) {
msgType, msg, err := w.clientConn.ReadMessage() msgType, msg, err := w.clientConn.ReadMessage()
if err != nil { if err != nil {
errC <- err 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 return
} }
...@@ -575,7 +577,9 @@ func (w *WSProxier) backendPump(ctx context.Context, errC chan error) { ...@@ -575,7 +577,9 @@ func (w *WSProxier) backendPump(ctx context.Context, errC chan error) {
msgType, msg, err := w.backendConn.ReadMessage() msgType, msg, err := w.backendConn.ReadMessage()
if err != nil { if err != nil {
errC <- err 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 return
} }
......
...@@ -3,12 +3,13 @@ package integration_tests ...@@ -3,12 +3,13 @@ package integration_tests
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/alicebob/miniredis"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os" "os"
"testing" "testing"
"time" "time"
"github.com/alicebob/miniredis"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
) )
func TestCaching(t *testing.T) { func TestCaching(t *testing.T) {
......
...@@ -2,13 +2,14 @@ package integration_tests ...@@ -2,13 +2,14 @@ package integration_tests
import ( import (
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"net/http" "net/http"
"os" "os"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "time"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
) )
const ( const (
...@@ -39,7 +40,7 @@ func TestFailover(t *testing.T) { ...@@ -39,7 +40,7 @@ func TestFailover(t *testing.T) {
"backend responds 200 with non-JSON response", "backend responds 200 with non-JSON response",
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200) 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) { ...@@ -87,7 +88,7 @@ func TestFailover(t *testing.T) {
t.Run("backend times out and falls back to another", func(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) { badBackend.SetHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
w.Write([]byte("{}")) _, _ = w.Write([]byte("{}"))
})) }))
res, statusCode, err := client.SendRPC("eth_chainId", nil) res, statusCode, err := client.SendRPC("eth_chainId", nil)
require.NoError(t, err) require.NoError(t, err)
...@@ -133,7 +134,7 @@ func TestRetries(t *testing.T) { ...@@ -133,7 +134,7 @@ func TestRetries(t *testing.T) {
w.WriteHeader(500) w.WriteHeader(500)
return return
} }
w.Write([]byte(goodResponse)) _, _ = w.Write([]byte(goodResponse))
})) }))
// test case where request eventually succeeds // test case where request eventually succeeds
...@@ -169,7 +170,7 @@ func TestOutOfServiceInterval(t *testing.T) { ...@@ -169,7 +170,7 @@ func TestOutOfServiceInterval(t *testing.T) {
defer shutdown() defer shutdown()
okHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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) { badBackend.SetHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(503) w.WriteHeader(503)
...@@ -190,10 +191,12 @@ func TestOutOfServiceInterval(t *testing.T) { ...@@ -190,10 +191,12 @@ func TestOutOfServiceInterval(t *testing.T) {
require.Equal(t, 2, len(badBackend.Requests())) require.Equal(t, 2, len(badBackend.Requests()))
require.Equal(t, 2, len(goodBackend.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),
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, 2, len(badBackend.Requests()))
require.Equal(t, 4, len(goodBackend.Requests())) require.Equal(t, 4, len(goodBackend.Requests()))
......
...@@ -4,11 +4,12 @@ import ( ...@@ -4,11 +4,12 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
"github.com/ethereum-optimism/optimism/go/proxyd"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"sync" "sync"
"github.com/ethereum-optimism/optimism/go/proxyd"
) )
type RecordedRequest struct { type RecordedRequest struct {
...@@ -27,7 +28,7 @@ type MockBackend struct { ...@@ -27,7 +28,7 @@ type MockBackend struct {
func SingleResponseHandler(code int, response string) http.HandlerFunc { func SingleResponseHandler(code int, response string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(code) w.WriteHeader(code)
w.Write([]byte(response)) _, _ = w.Write([]byte(response))
} }
} }
......
package integration_tests package integration_tests
import ( import (
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os" "os"
"testing" "testing"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
) )
type resWithCode struct { type resWithCode struct {
......
...@@ -4,12 +4,13 @@ import ( ...@@ -4,12 +4,13 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"testing" "testing"
"github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
) )
type ProxydClient struct { type ProxydClient struct {
......
package integration_tests package integration_tests
import ( import (
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
"os" "os"
"strings" "strings"
"testing" "testing"
"github.com/ethereum-optimism/optimism/go/proxyd"
"github.com/stretchr/testify/require"
) )
const ( const (
......
...@@ -217,7 +217,11 @@ func Start(config *Config) (func(), error) { ...@@ -217,7 +217,11 @@ func Start(config *Config) (func(), error) {
if config.Metrics.Enabled { if config.Metrics.Enabled {
addr := fmt.Sprintf("%s:%d", config.Metrics.Host, config.Metrics.Port) addr := fmt.Sprintf("%s:%d", config.Metrics.Host, config.Metrics.Port)
log.Info("starting metrics server", "addr", addr) 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 // To allow integration tests to cleanly come up, wait
......
...@@ -5,10 +5,11 @@ import ( ...@@ -5,10 +5,11 @@ import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
) )
const MaxRPSScript = ` const MaxRPSScript = `
......
...@@ -2,8 +2,9 @@ package proxyd ...@@ -2,8 +2,9 @@ package proxyd
import ( import (
"encoding/json" "encoding/json"
"github.com/stretchr/testify/require"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func TestRPCResJSON(t *testing.T) { func TestRPCResJSON(t *testing.T) {
......
...@@ -107,15 +107,15 @@ func (s *Server) WSListenAndServe(host string, port int) error { ...@@ -107,15 +107,15 @@ func (s *Server) WSListenAndServe(host string, port int) error {
func (s *Server) Shutdown() { func (s *Server) Shutdown() {
if s.rpcServer != nil { if s.rpcServer != nil {
s.rpcServer.Shutdown(context.Background()) _ = s.rpcServer.Shutdown(context.Background())
} }
if s.wsServer != nil { if s.wsServer != nil {
s.wsServer.Shutdown(context.Background()) _ = s.wsServer.Shutdown(context.Background())
} }
} }
func (s *Server) HandleHealthz(w http.ResponseWriter, r *http.Request) { 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) { func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
...@@ -159,7 +159,7 @@ 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 return
} }
batchRes := make([]*RPCRes, len(reqs), len(reqs)) batchRes := make([]*RPCRes, len(reqs))
var batchContainsCached bool var batchContainsCached bool
for i := 0; i < len(reqs); i++ { for i := 0; i < len(reqs); i++ {
req, err := ParseRPCReq(reqs[i]) req, err := ParseRPCReq(reqs[i])
...@@ -301,7 +301,7 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context ...@@ -301,7 +301,7 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
} }
return context.WithValue( return context.WithValue(
r.Context(), r.Context(),
ContextKeyReqID, ContextKeyReqID, // nolint:staticcheck
randStr(10), randStr(10),
) )
} }
...@@ -321,11 +321,11 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context ...@@ -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(r.Context(), ContextKeyAuth, s.authenticatedPaths[authorization]) // nolint:staticcheck
ctx = context.WithValue(ctx, ContextKeyXForwardedFor, xff) ctx = context.WithValue(ctx, ContextKeyXForwardedFor, xff) // nolint:staticcheck
return context.WithValue( return context.WithValue(
ctx, ctx,
ContextKeyReqID, ContextKeyReqID, // nolint:staticcheck
randStr(10), randStr(10),
) )
} }
...@@ -413,17 +413,6 @@ func GetXForwardedFor(ctx context.Context) string { ...@@ -413,17 +413,6 @@ func GetXForwardedFor(ctx context.Context) string {
return xff 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 { type recordLenWriter struct {
io.Writer io.Writer
Len int Len int
......
...@@ -35,8 +35,8 @@ func main() { ...@@ -35,8 +35,8 @@ func main() {
app.Description = "Teleportr bridge from L1 to L2" app.Description = "Teleportr bridge from L1 to L2"
app.Commands = []cli.Command{ app.Commands = []cli.Command{
{ {
Name: "migrate", Name: "migrate",
Usage: "Migrates teleportr's database", Usage: "Migrates teleportr's database",
Action: teleportr.Migrate(), Action: teleportr.Migrate(),
}, },
} }
......
...@@ -181,4 +181,4 @@ func Migrate() func(ctx *cli.Context) error { ...@@ -181,4 +181,4 @@ func Migrate() func(ctx *cli.Context) error {
log.Info("Done") log.Info("Done")
return nil return nil
} }
} }
\ No newline at end of file
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
...@@ -23,4 +23,4 @@ curl \ ...@@ -23,4 +23,4 @@ curl \
--output /dev/null \ --output /dev/null \
$L2_URL $L2_URL
npx hardhat test --network optimism --no-compile npx hardhat test --network optimism --no-compile "$@"
#!/bin/bash #!/bin/bash
CONTAINER=l2geth CONTAINER=l2geth
RETRIES=30 RETRIES=90
i=0 i=0
until docker-compose logs l2geth | grep -q "Starting Sequencer Loop"; until docker-compose logs l2geth | grep -q "Starting Sequencer Loop";
do do
sleep 3 sleep 1
if [ $i -eq $RETRIES ]; then if [ $i -eq $RETRIES ]; then
echo 'Timed out waiting for sequencer' echo 'Timed out waiting for sequencer'
break break
......
module.exports = { module.exports = {
extends: '../../.eslintrc.js', extends: '../../.eslintrc.js',
ignorePatterns: [
'src/contract-artifacts.ts',
'src/contract-deployed-artifacts.ts',
],
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
], ],
"scripts": { "scripts": {
"start": "ts-node ./src/service.ts", "start": "ts-node ./src/service.ts",
"test:coverage": "echo 'No tests defined.'",
"build": "tsc -p ./tsconfig.build.json", "build": "tsc -p ./tsconfig.build.json",
"clean": "rimraf dist/ ./tsconfig.build.tsbuildinfo", "clean": "rimraf dist/ ./tsconfig.build.tsbuildinfo",
"lint": "yarn lint:fix && yarn lint:check", "lint": "yarn lint:fix && yarn lint:check",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
], ],
"scripts": { "scripts": {
"start": "ts-node ./src/service", "start": "ts-node ./src/service",
"test:coverage": "echo 'No tests defined.'",
"build": "tsc -p tsconfig.build.json", "build": "tsc -p tsconfig.build.json",
"clean": "rimraf ./dist ./tsconfig.build.tsbuildinfo", "clean": "rimraf ./dist ./tsconfig.build.tsbuildinfo",
"lint": "yarn run lint:fix && yarn run lint:check", "lint": "yarn run lint:fix && yarn run lint:check",
......
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