Commit c1b643af authored by Adrian Sutton's avatar Adrian Sutton

Merge branch 'develop' into aj/multicaller

parents e8ab03d2 38125b92
This diff is collapsed.
3b1129b5bc43ba22a9bcf4e4323c5a9df0023140 ee5d02c3ef5f55a06b069e4a70a820661a9130c8
v1.13.4
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
/op-exporter @ethereum-optimism/go-reviewers /op-exporter @ethereum-optimism/go-reviewers
/op-heartbeat @ethereum-optimism/go-reviewers /op-heartbeat @ethereum-optimism/go-reviewers
/op-node @ethereum-optimism/go-reviewers /op-node @ethereum-optimism/go-reviewers
/op-node/rollup @protolambda @trianglesphere /op-node/rollup @protolambda @trianglesphere @ajsutton
/op-preimage @ethereum-optimism/go-reviewers /op-preimage @ethereum-optimism/go-reviewers
/op-program @ethereum-optimism/go-reviewers /op-program @ethereum-optimism/go-reviewers
/op-proposer @ethereum-optimism/go-reviewers /op-proposer @ethereum-optimism/go-reviewers
......
COMPOSEFLAGS=-d COMPOSEFLAGS=-d
ITESTS_L2_HOST=http://localhost:9545 ITESTS_L2_HOST=http://localhost:9545
BEDROCK_TAGS_REMOTE?=origin BEDROCK_TAGS_REMOTE?=origin
OP_STACK_GO_BUILDER?=us-docker.pkg.dev/oplabs-tools-artifacts/images/op_stack_go:latest
build: build-go build-ts build: build-go build-ts
.PHONY: build .PHONY: build
...@@ -8,6 +9,10 @@ build: build-go build-ts ...@@ -8,6 +9,10 @@ build: build-go build-ts
build-go: submodules op-node op-proposer op-batcher build-go: submodules op-node op-proposer op-batcher
.PHONY: build-go .PHONY: build-go
lint-go:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
.PHONY: lint-go
build-ts: submodules build-ts: submodules
if [ -n "$$NVM_DIR" ]; then \ if [ -n "$$NVM_DIR" ]; then \
. $$NVM_DIR/nvm.sh && nvm use; \ . $$NVM_DIR/nvm.sh && nvm use; \
...@@ -19,6 +24,13 @@ build-ts: submodules ...@@ -19,6 +24,13 @@ build-ts: submodules
ci-builder: ci-builder:
docker build -t ci-builder -f ops/docker/ci-builder/Dockerfile . docker build -t ci-builder -f ops/docker/ci-builder/Dockerfile .
golang-docker:
DOCKER_BUILDKIT=1 docker build -t op-stack-go \
--build-arg GIT_COMMIT=$$(git rev-parse HEAD) \
--build-arg GIT_DATE=$$(git show -s --format='%ct') \
-f ops/docker/op-stack-go/Dockerfile .
.PHONY: golang-docker
submodules: submodules:
# CI will checkout submodules on its own (and fails on these commands) # CI will checkout submodules on its own (and fails on these commands)
if [ -z "$$GITHUB_ENV" ]; then \ if [ -z "$$GITHUB_ENV" ]; then \
...@@ -163,4 +175,10 @@ bedrock-markdown-links: ...@@ -163,4 +175,10 @@ bedrock-markdown-links:
--exclude-mail /input/README.md "/input/specs/**/*.md" --exclude-mail /input/README.md "/input/specs/**/*.md"
install-geth: install-geth:
go install github.com/ethereum/go-ethereum/cmd/geth@v1.12.0 ./ops/scripts/geth-version-checker.sh && \
(echo "Geth versions match, not installing geth..."; true) || \
(echo "Versions do not match, installing geth!"; \
go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell cat .gethrc); \
echo "Installed geth!"; true)
.PHONY: install-geth
...@@ -96,7 +96,9 @@ def main(): ...@@ -96,7 +96,9 @@ def main():
log.info('Building docker images') log.info('Building docker images')
run_command(['docker', 'compose', 'build', '--progress', 'plain'], cwd=paths.ops_bedrock_dir, env={ run_command(['docker', 'compose', 'build', '--progress', 'plain'], cwd=paths.ops_bedrock_dir, env={
'PWD': paths.ops_bedrock_dir 'PWD': paths.ops_bedrock_dir,
'DOCKER_BUILDKIT': '1', # (should be available by default in later versions, but explicitly enable it anyway)
'COMPOSE_DOCKER_CLI_BUILD': '1' # use the docker cache
}) })
log.info('Devnet starting') log.info('Devnet starting')
......
GITCOMMIT := $(shell git rev-parse HEAD) GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct') GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0 VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
...@@ -20,9 +20,6 @@ elf: ...@@ -20,9 +20,6 @@ elf:
test: elf test: elf
go test -v ./... go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is"
fuzz: fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallBrk ./mipsevm go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallBrk ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallClone ./mipsevm go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallClone ./mipsevm
......
...@@ -229,7 +229,7 @@ of checking email at the start of their day. This caused some delay in the initi ...@@ -229,7 +229,7 @@ of checking email at the start of their day. This caused some delay in the initi
Early in the process, the existence of the issue was openly discussed in a public slack channel, Early in the process, the existence of the issue was openly discussed in a public slack channel,
although the details of the vulnerability and exploit path were not described. This violates the although the details of the vulnerability and exploit path were not described. This violates the
[principle of least priviledge](https://en.wikipedia.org/wiki/Principle_of_least_privilege), as well [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), as well
as our already existing incident response protocols as our already existing incident response protocols
**Action taken:** **Action taken:**
......
GITCOMMIT := $(shell git rev-parse HEAD) GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct') GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0 VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
......
...@@ -8,7 +8,7 @@ require ( ...@@ -8,7 +8,7 @@ require (
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231001123245-7b48d3818686 github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171
github.com/ethereum/go-ethereum v1.13.1 github.com/ethereum/go-ethereum v1.13.1
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/chi/v5 v5.0.10
...@@ -28,7 +28,7 @@ require ( ...@@ -28,7 +28,7 @@ require (
github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-mplex v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub v0.9.3
github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-libp2p-testing v0.12.0
github.com/mattn/go-isatty v0.0.19 github.com/mattn/go-isatty v0.0.20
github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-base32 v0.1.0
github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multiaddr v0.12.0
github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multiaddr-dns v0.3.1
...@@ -62,8 +62,9 @@ require ( ...@@ -62,8 +62,9 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect
github.com/cockroachdb/redact v1.1.3 // indirect github.com/cockroachdb/redact v1.1.3 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.0 // indirect github.com/consensys/gnark-crypto v0.12.0 // indirect
github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect
...@@ -208,7 +209,7 @@ require ( ...@@ -208,7 +209,7 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect rsc.io/tmplfunc v0.0.3 // indirect
) )
replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101301.0-rc.2.0.20231002141926-1e6910b91798 replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101301.2-0.20231018201518-63125bd85c80
//replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain
//replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum //replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum
...@@ -84,17 +84,19 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk ...@@ -84,17 +84,19 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A=
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo=
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
...@@ -175,10 +177,10 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 ...@@ -175,10 +177,10 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.101301.0-rc.2.0.20231002141926-1e6910b91798 h1:WRaF/uniRnlxTVlMfFWPtMe9NefzZWg/8Fc93Nao76w= github.com/ethereum-optimism/op-geth v1.101301.2-0.20231018201518-63125bd85c80 h1:HeYvf3+kVe4N3heNiyZwfAU1s4GjwbMnBEuOhNmFh6c=
github.com/ethereum-optimism/op-geth v1.101301.0-rc.2.0.20231002141926-1e6910b91798/go.mod h1:p02vxGt8jcF8pCwkUU5Oy56X8/JsM1Js+KC+fwihVgk= github.com/ethereum-optimism/op-geth v1.101301.2-0.20231018201518-63125bd85c80/go.mod h1:QoC1Xf6dzEFrZjjsi2tKhze1MwRAk6KXFbIzcHnIXx4=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231001123245-7b48d3818686 h1:f57hd8G96c8ORWd4ameFpveSnHcb0hA2D1VatviwoDc= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171 h1:MjCUj16JSLZRDnQQ6OOUy6Chfb4dKo7ahFceNi0RKZ8=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231001123245-7b48d3818686/go.mod h1:q0u2UbyOr1q/y94AgMOj/V8b1KO05ZwILTR/qKt7Auo= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk=
github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg=
github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
...@@ -552,8 +554,8 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y ...@@ -552,8 +554,8 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
......
...@@ -25,3 +25,9 @@ func Clamp(start, end *big.Int, size uint64) *big.Int { ...@@ -25,3 +25,9 @@ func Clamp(start, end *big.Int, size uint64) *big.Int {
func Matcher(num int64) func(*big.Int) bool { func Matcher(num int64) func(*big.Int) bool {
return func(bi *big.Int) bool { return bi.Int64() == num } return func(bi *big.Int) bool { return bi.Int64() == num }
} }
func WeiToETH(wei *big.Int) *big.Float {
f := new(big.Float)
f.SetString(wei.String())
return f.Quo(f, big.NewFloat(1e18))
}
...@@ -30,6 +30,8 @@ var ( ...@@ -30,6 +30,8 @@ var (
func runIndexer(ctx *cli.Context) error { func runIndexer(ctx *cli.Context) error {
log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "indexer") log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "indexer")
oplog.SetGlobalLogHandler(log.GetHandler()) oplog.SetGlobalLogHandler(log.GetHandler())
log.Info("running indexer...")
cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name))
if err != nil { if err != nil {
log.Error("failed to load config", "err", err) log.Error("failed to load config", "err", err)
...@@ -49,13 +51,14 @@ func runIndexer(ctx *cli.Context) error { ...@@ -49,13 +51,14 @@ func runIndexer(ctx *cli.Context) error {
return err return err
} }
log.Info("running indexer...")
return indexer.Run(ctx.Context) return indexer.Run(ctx.Context)
} }
func runApi(ctx *cli.Context) error { func runApi(ctx *cli.Context) error {
log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "api") log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "api")
oplog.SetGlobalLogHandler(log.GetHandler()) oplog.SetGlobalLogHandler(log.GetHandler())
log.Info("running api...")
cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name))
if err != nil { if err != nil {
log.Error("failed to load config", "err", err) log.Error("failed to load config", "err", err)
...@@ -69,7 +72,6 @@ func runApi(ctx *cli.Context) error { ...@@ -69,7 +72,6 @@ func runApi(ctx *cli.Context) error {
} }
defer db.Close() defer db.Close()
log.Info("running api...")
api := api.NewApi(log, db.BridgeTransfers, cfg.HTTPServer, cfg.MetricsServer) api := api.NewApi(log, db.BridgeTransfers, cfg.HTTPServer, cfg.MetricsServer)
return api.Run(ctx.Context) return api.Run(ctx.Context)
} }
...@@ -77,8 +79,9 @@ func runApi(ctx *cli.Context) error { ...@@ -77,8 +79,9 @@ func runApi(ctx *cli.Context) error {
func runMigrations(ctx *cli.Context) error { func runMigrations(ctx *cli.Context) error {
log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "migrations") log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "migrations")
oplog.SetGlobalLogHandler(log.GetHandler()) oplog.SetGlobalLogHandler(log.GetHandler())
log.Info("running migrations...")
cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name))
migrationsDir := ctx.String(MigrationsFlag.Name)
if err != nil { if err != nil {
log.Error("failed to load config", "err", err) log.Error("failed to load config", "err", err)
return err return err
...@@ -91,7 +94,7 @@ func runMigrations(ctx *cli.Context) error { ...@@ -91,7 +94,7 @@ func runMigrations(ctx *cli.Context) error {
} }
defer db.Close() defer db.Close()
log.Info("running migrations...") migrationsDir := ctx.String(MigrationsFlag.Name)
return db.ExecuteSQLMigration(migrationsDir) return db.ExecuteSQLMigration(migrationsDir)
} }
......
...@@ -27,5 +27,6 @@ func main() { ...@@ -27,5 +27,6 @@ func main() {
app := newCli(GitCommit, GitDate) app := newCli(GitCommit, GitDate)
if err := app.RunContext(ctx, os.Args); err != nil { if err := app.RunContext(ctx, os.Args); err != nil {
log.Error("application failed", "err", err) log.Error("application failed", "err", err)
os.Exit(1)
} }
} }
...@@ -7,8 +7,10 @@ import ( ...@@ -7,8 +7,10 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
) )
/** /**
...@@ -67,17 +69,23 @@ type BlocksDB interface { ...@@ -67,17 +69,23 @@ type BlocksDB interface {
*/ */
type blocksDB struct { type blocksDB struct {
log log.Logger
gorm *gorm.DB gorm *gorm.DB
} }
func newBlocksDB(db *gorm.DB) BlocksDB { func newBlocksDB(log log.Logger, db *gorm.DB) BlocksDB {
return &blocksDB{gorm: db} return &blocksDB{log: log.New("table", "blocks"), gorm: db}
} }
// L1 // L1
func (db *blocksDB) StoreL1BlockHeaders(headers []L1BlockHeader) error { func (db *blocksDB) StoreL1BlockHeaders(headers []L1BlockHeader) error {
result := db.gorm.CreateInBatches(&headers, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "hash"}}, DoNothing: true})
result := deduped.Create(&headers)
if result.Error == nil && int(result.RowsAffected) < len(headers) {
db.log.Warn("ignored L1 block duplicates", "duplicates", len(headers)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -115,7 +123,12 @@ func (db *blocksDB) L1LatestBlockHeader() (*L1BlockHeader, error) { ...@@ -115,7 +123,12 @@ func (db *blocksDB) L1LatestBlockHeader() (*L1BlockHeader, error) {
// L2 // L2
func (db *blocksDB) StoreL2BlockHeaders(headers []L2BlockHeader) error { func (db *blocksDB) StoreL2BlockHeaders(headers []L2BlockHeader) error {
result := db.gorm.CreateInBatches(&headers, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "hash"}}, DoNothing: true})
result := deduped.Create(&headers)
if result.Error == nil && int(result.RowsAffected) < len(headers) {
db.log.Warn("ignored L2 block duplicates", "duplicates", len(headers)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
......
...@@ -6,8 +6,10 @@ import ( ...@@ -6,8 +6,10 @@ import (
"math/big" "math/big"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/google/uuid" "github.com/google/uuid"
) )
...@@ -60,11 +62,12 @@ type BridgeMessagesDB interface { ...@@ -60,11 +62,12 @@ type BridgeMessagesDB interface {
*/ */
type bridgeMessagesDB struct { type bridgeMessagesDB struct {
log log.Logger
gorm *gorm.DB gorm *gorm.DB
} }
func newBridgeMessagesDB(db *gorm.DB) BridgeMessagesDB { func newBridgeMessagesDB(log log.Logger, db *gorm.DB) BridgeMessagesDB {
return &bridgeMessagesDB{gorm: db} return &bridgeMessagesDB{log: log.New("table", "bridge_messages"), gorm: db}
} }
/** /**
...@@ -72,7 +75,12 @@ func newBridgeMessagesDB(db *gorm.DB) BridgeMessagesDB { ...@@ -72,7 +75,12 @@ func newBridgeMessagesDB(db *gorm.DB) BridgeMessagesDB {
*/ */
func (db bridgeMessagesDB) StoreL1BridgeMessages(messages []L1BridgeMessage) error { func (db bridgeMessagesDB) StoreL1BridgeMessages(messages []L1BridgeMessage) error {
result := db.gorm.CreateInBatches(&messages, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "message_hash"}}, DoNothing: true})
result := deduped.Create(&messages)
if result.Error == nil && int(result.RowsAffected) < len(messages) {
db.log.Warn("ignored L1 bridge message duplicates", "duplicates", len(messages)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -98,7 +106,13 @@ func (db bridgeMessagesDB) MarkRelayedL1BridgeMessage(messageHash common.Hash, r ...@@ -98,7 +106,13 @@ func (db bridgeMessagesDB) MarkRelayedL1BridgeMessage(messageHash common.Hash, r
if err != nil { if err != nil {
return err return err
} else if message == nil { } else if message == nil {
return fmt.Errorf("L1BridgeMessage with message hash %s not found", messageHash) return fmt.Errorf("L1BridgeMessage %s not found", messageHash)
}
if message.RelayedMessageEventGUID != nil && message.RelayedMessageEventGUID.ID() == relayEvent.ID() {
return nil
} else if message.RelayedMessageEventGUID != nil {
return fmt.Errorf("relayed message %s re-relayed with a different event %d", messageHash, relayEvent)
} }
message.RelayedMessageEventGUID = &relayEvent message.RelayedMessageEventGUID = &relayEvent
...@@ -111,7 +125,12 @@ func (db bridgeMessagesDB) MarkRelayedL1BridgeMessage(messageHash common.Hash, r ...@@ -111,7 +125,12 @@ func (db bridgeMessagesDB) MarkRelayedL1BridgeMessage(messageHash common.Hash, r
*/ */
func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) error { func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) error {
result := db.gorm.CreateInBatches(&messages, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "message_hash"}}, DoNothing: true})
result := deduped.Create(&messages)
if result.Error == nil && int(result.RowsAffected) < len(messages) {
db.log.Warn("ignored L2 bridge message duplicates", "duplicates", len(messages)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -137,7 +156,13 @@ func (db bridgeMessagesDB) MarkRelayedL2BridgeMessage(messageHash common.Hash, r ...@@ -137,7 +156,13 @@ func (db bridgeMessagesDB) MarkRelayedL2BridgeMessage(messageHash common.Hash, r
if err != nil { if err != nil {
return err return err
} else if message == nil { } else if message == nil {
return fmt.Errorf("L2BridgeMessage with message hash %s not found", messageHash) return fmt.Errorf("L2BridgeMessage %s not found", messageHash)
}
if message.RelayedMessageEventGUID != nil && message.RelayedMessageEventGUID.ID() == relayEvent.ID() {
return nil
} else if message.RelayedMessageEventGUID != nil {
return fmt.Errorf("relayed message %s re-relayed with a different event %s", messageHash, relayEvent)
} }
message.RelayedMessageEventGUID = &relayEvent message.RelayedMessageEventGUID = &relayEvent
......
...@@ -7,8 +7,10 @@ import ( ...@@ -7,8 +7,10 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
) )
/** /**
...@@ -68,11 +70,12 @@ type BridgeTransactionsDB interface { ...@@ -68,11 +70,12 @@ type BridgeTransactionsDB interface {
*/ */
type bridgeTransactionsDB struct { type bridgeTransactionsDB struct {
log log.Logger
gorm *gorm.DB gorm *gorm.DB
} }
func newBridgeTransactionsDB(db *gorm.DB) BridgeTransactionsDB { func newBridgeTransactionsDB(log log.Logger, db *gorm.DB) BridgeTransactionsDB {
return &bridgeTransactionsDB{gorm: db} return &bridgeTransactionsDB{log: log.New("table", "bridge_transactions"), gorm: db}
} }
/** /**
...@@ -80,7 +83,12 @@ func newBridgeTransactionsDB(db *gorm.DB) BridgeTransactionsDB { ...@@ -80,7 +83,12 @@ func newBridgeTransactionsDB(db *gorm.DB) BridgeTransactionsDB {
*/ */
func (db *bridgeTransactionsDB) StoreL1TransactionDeposits(deposits []L1TransactionDeposit) error { func (db *bridgeTransactionsDB) StoreL1TransactionDeposits(deposits []L1TransactionDeposit) error {
result := db.gorm.CreateInBatches(&deposits, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "source_hash"}}, DoNothing: true})
result := deduped.Create(&deposits)
if result.Error == nil && int(result.RowsAffected) < len(deposits) {
db.log.Warn("ignored L1 tx deposit duplicates", "duplicates", len(deposits)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -133,7 +141,12 @@ func (db *bridgeTransactionsDB) L1LatestBlockHeader() (*L1BlockHeader, error) { ...@@ -133,7 +141,12 @@ func (db *bridgeTransactionsDB) L1LatestBlockHeader() (*L1BlockHeader, error) {
*/ */
func (db *bridgeTransactionsDB) StoreL2TransactionWithdrawals(withdrawals []L2TransactionWithdrawal) error { func (db *bridgeTransactionsDB) StoreL2TransactionWithdrawals(withdrawals []L2TransactionWithdrawal) error {
result := db.gorm.CreateInBatches(&withdrawals, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "withdrawal_hash"}}, DoNothing: true})
result := deduped.Create(&withdrawals)
if result.Error == nil && int(result.RowsAffected) < len(withdrawals) {
db.log.Warn("ignored L2 tx withdrawal duplicates", "duplicates", len(withdrawals)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -155,11 +168,16 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalProvenEvent(withdrawa ...@@ -155,11 +168,16 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalProvenEvent(withdrawa
withdrawal, err := db.L2TransactionWithdrawal(withdrawalHash) withdrawal, err := db.L2TransactionWithdrawal(withdrawalHash)
if err != nil { if err != nil {
return err return err
} } else if withdrawal == nil {
if withdrawal == nil {
return fmt.Errorf("transaction withdrawal hash %s not found", withdrawalHash) return fmt.Errorf("transaction withdrawal hash %s not found", withdrawalHash)
} }
if withdrawal.ProvenL1EventGUID != nil && withdrawal.ProvenL1EventGUID.ID() == provenL1EventGuid.ID() {
return nil
} else if withdrawal.ProvenL1EventGUID != nil {
return fmt.Errorf("proven withdrawal %s re-proven with a different event %s", withdrawalHash, provenL1EventGuid)
}
withdrawal.ProvenL1EventGUID = &provenL1EventGuid withdrawal.ProvenL1EventGUID = &provenL1EventGuid
result := db.gorm.Save(&withdrawal) result := db.gorm.Save(&withdrawal)
return result.Error return result.Error
...@@ -170,14 +188,18 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalFinalizedEvent(withdr ...@@ -170,14 +188,18 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalFinalizedEvent(withdr
withdrawal, err := db.L2TransactionWithdrawal(withdrawalHash) withdrawal, err := db.L2TransactionWithdrawal(withdrawalHash)
if err != nil { if err != nil {
return err return err
} } else if withdrawal == nil {
if withdrawal == nil {
return fmt.Errorf("transaction withdrawal hash %s not found", withdrawalHash) return fmt.Errorf("transaction withdrawal hash %s not found", withdrawalHash)
} } else if withdrawal.ProvenL1EventGUID == nil {
if withdrawal.ProvenL1EventGUID == nil {
return fmt.Errorf("cannot mark unproven withdrawal hash %s as finalized", withdrawal.WithdrawalHash) return fmt.Errorf("cannot mark unproven withdrawal hash %s as finalized", withdrawal.WithdrawalHash)
} }
if withdrawal.FinalizedL1EventGUID != nil && withdrawal.FinalizedL1EventGUID.ID() == finalizedL1EventGuid.ID() {
return nil
} else if withdrawal.FinalizedL1EventGUID != nil {
return fmt.Errorf("finalized withdrawal %s re-finalized with a different event %s", withdrawalHash, finalizedL1EventGuid)
}
withdrawal.FinalizedL1EventGUID = &finalizedL1EventGuid withdrawal.FinalizedL1EventGUID = &finalizedL1EventGuid
withdrawal.Succeeded = &succeeded withdrawal.Succeeded = &succeeded
result := db.gorm.Save(&withdrawal) result := db.gorm.Save(&withdrawal)
......
...@@ -5,9 +5,11 @@ import ( ...@@ -5,9 +5,11 @@ import (
"fmt" "fmt"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
) )
var ( var (
...@@ -79,11 +81,12 @@ type BridgeTransfersDB interface { ...@@ -79,11 +81,12 @@ type BridgeTransfersDB interface {
*/ */
type bridgeTransfersDB struct { type bridgeTransfersDB struct {
log log.Logger
gorm *gorm.DB gorm *gorm.DB
} }
func newBridgeTransfersDB(db *gorm.DB) BridgeTransfersDB { func newBridgeTransfersDB(log log.Logger, db *gorm.DB) BridgeTransfersDB {
return &bridgeTransfersDB{gorm: db} return &bridgeTransfersDB{log: log.New("table", "bridge_transfers"), gorm: db}
} }
/** /**
...@@ -91,7 +94,12 @@ func newBridgeTransfersDB(db *gorm.DB) BridgeTransfersDB { ...@@ -91,7 +94,12 @@ func newBridgeTransfersDB(db *gorm.DB) BridgeTransfersDB {
*/ */
func (db *bridgeTransfersDB) StoreL1BridgeDeposits(deposits []L1BridgeDeposit) error { func (db *bridgeTransfersDB) StoreL1BridgeDeposits(deposits []L1BridgeDeposit) error {
result := db.gorm.CreateInBatches(&deposits, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "transaction_source_hash"}}, DoNothing: true})
result := deduped.Create(&deposits)
if result.Error == nil && int(result.RowsAffected) < len(deposits) {
db.log.Warn("ignored L1 bridge transfer duplicates", "duplicates", len(deposits)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -204,7 +212,12 @@ l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, re ...@@ -204,7 +212,12 @@ l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, re
*/ */
func (db *bridgeTransfersDB) StoreL2BridgeWithdrawals(withdrawals []L2BridgeWithdrawal) error { func (db *bridgeTransfersDB) StoreL2BridgeWithdrawals(withdrawals []L2BridgeWithdrawal) error {
result := db.gorm.CreateInBatches(&withdrawals, batchInsertSize) deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "transaction_withdrawal_hash"}}, DoNothing: true})
result := deduped.Create(&withdrawals)
if result.Error == nil && int(result.RowsAffected) < len(withdrawals) {
db.log.Warn("ignored L2 bridge transfer duplicates", "duplicates", len(withdrawals)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
......
...@@ -6,9 +6,11 @@ import ( ...@@ -6,9 +6,11 @@ import (
"math/big" "math/big"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/google/uuid" "github.com/google/uuid"
) )
...@@ -99,17 +101,25 @@ type ContractEventsDB interface { ...@@ -99,17 +101,25 @@ type ContractEventsDB interface {
*/ */
type contractEventsDB struct { type contractEventsDB struct {
log log.Logger
gorm *gorm.DB gorm *gorm.DB
} }
func newContractEventsDB(db *gorm.DB) ContractEventsDB { func newContractEventsDB(log log.Logger, db *gorm.DB) ContractEventsDB {
return &contractEventsDB{gorm: db} return &contractEventsDB{log: log.New("table", "events"), gorm: db}
} }
// L1 // L1
func (db *contractEventsDB) StoreL1ContractEvents(events []L1ContractEvent) error { func (db *contractEventsDB) StoreL1ContractEvents(events []L1ContractEvent) error {
result := db.gorm.CreateInBatches(&events, batchInsertSize) // Since the block hash refers back to L1, we dont necessarily have to check
// that the RLP bytes match when doing conflict resolution.
deduped := db.gorm.Clauses(clause.OnConflict{OnConstraint: "l1_contract_events_block_hash_log_index_key", DoNothing: true})
result := deduped.Create(&events)
if result.Error == nil && int(result.RowsAffected) < len(events) {
db.log.Warn("ignored L1 contract event duplicates", "duplicates", len(events)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -144,7 +154,7 @@ func (db *contractEventsDB) L1ContractEventsWithFilter(filter ContractEvent, fro ...@@ -144,7 +154,7 @@ func (db *contractEventsDB) L1ContractEventsWithFilter(filter ContractEvent, fro
query := db.gorm.Table("l1_contract_events").Where(&filter) query := db.gorm.Table("l1_contract_events").Where(&filter)
query = query.Joins("INNER JOIN l1_block_headers ON l1_contract_events.block_hash = l1_block_headers.hash") query = query.Joins("INNER JOIN l1_block_headers ON l1_contract_events.block_hash = l1_block_headers.hash")
query = query.Where("l1_block_headers.number >= ? AND l1_block_headers.number <= ?", fromHeight, toHeight) query = query.Where("l1_block_headers.number >= ? AND l1_block_headers.number <= ?", fromHeight, toHeight)
query = query.Order("l1_block_headers.number ASC").Select("l1_contract_events.*") query = query.Order("l1_block_headers.number ASC, l1_contract_events.log_index ASC").Select("l1_contract_events.*")
// NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support // NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support
// model hooks like `ContractEvent#AfterFind`. Functionally they are the same // model hooks like `ContractEvent#AfterFind`. Functionally they are the same
...@@ -176,7 +186,14 @@ func (db *contractEventsDB) L1LatestContractEventWithFilter(filter ContractEvent ...@@ -176,7 +186,14 @@ func (db *contractEventsDB) L1LatestContractEventWithFilter(filter ContractEvent
// L2 // L2
func (db *contractEventsDB) StoreL2ContractEvents(events []L2ContractEvent) error { func (db *contractEventsDB) StoreL2ContractEvents(events []L2ContractEvent) error {
result := db.gorm.CreateInBatches(&events, batchInsertSize) // Since the block hash refers back to L2, we dont necessarily have to check
// that the RLP bytes match when doing conflict resolution.
deduped := db.gorm.Clauses(clause.OnConflict{OnConstraint: "l2_contract_events_block_hash_log_index_key", DoNothing: true})
result := deduped.Create(&events)
if result.Error == nil && int(result.RowsAffected) < len(events) {
db.log.Warn("ignored L2 contract event duplicates", "duplicates", len(events)-int(result.RowsAffected))
}
return result.Error return result.Error
} }
...@@ -211,7 +228,7 @@ func (db *contractEventsDB) L2ContractEventsWithFilter(filter ContractEvent, fro ...@@ -211,7 +228,7 @@ func (db *contractEventsDB) L2ContractEventsWithFilter(filter ContractEvent, fro
query := db.gorm.Table("l2_contract_events").Where(&filter) query := db.gorm.Table("l2_contract_events").Where(&filter)
query = query.Joins("INNER JOIN l2_block_headers ON l2_contract_events.block_hash = l2_block_headers.hash") query = query.Joins("INNER JOIN l2_block_headers ON l2_contract_events.block_hash = l2_block_headers.hash")
query = query.Where("l2_block_headers.number >= ? AND l2_block_headers.number <= ?", fromHeight, toHeight) query = query.Where("l2_block_headers.number >= ? AND l2_block_headers.number <= ?", fromHeight, toHeight)
query = query.Order("l2_block_headers.number ASC").Select("l2_contract_events.*") query = query.Order("l2_block_headers.number ASC, l2_contract_events.log_index ASC").Select("l2_contract_events.*")
// NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support // NOTE: We use `Find` here instead of `Scan` since `Scan` doesn't not support
// model hooks like `ContractEvent#AfterFind`. Functionally they are the same // model hooks like `ContractEvent#AfterFind`. Functionally they are the same
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
_ "github.com/ethereum-optimism/optimism/indexer/database/serializers" _ "github.com/ethereum-optimism/optimism/indexer/database/serializers"
"github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -18,16 +19,9 @@ import ( ...@@ -18,16 +19,9 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
var (
// The postgres parameter counter for a given query is stored via a uint16,
// resulting in a parameter limit of 65535. In order to avoid reaching this limit
// we'll utilize a batch size of 3k for inserts, well below as long as the the number
// of columns < 20.
batchInsertSize int = 3_000
)
type DB struct { type DB struct {
gorm *gorm.DB gorm *gorm.DB
log log.Logger
Blocks BlocksDB Blocks BlocksDB
ContractEvents ContractEventsDB ContractEvents ContractEventsDB
...@@ -37,7 +31,7 @@ type DB struct { ...@@ -37,7 +31,7 @@ type DB struct {
} }
func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) {
retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} log = log.New("module", "db")
dsn := fmt.Sprintf("host=%s dbname=%s sslmode=disable", dbConfig.Host, dbConfig.Name) dsn := fmt.Sprintf("host=%s dbname=%s sslmode=disable", dbConfig.Host, dbConfig.Name)
if dbConfig.Port != 0 { if dbConfig.Port != 0 {
...@@ -51,11 +45,19 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { ...@@ -51,11 +45,19 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) {
} }
gormConfig := gorm.Config{ gormConfig := gorm.Config{
Logger: newLogger(log),
// The indexer will explicitly manage the transactions // The indexer will explicitly manage the transactions
SkipDefaultTransaction: true, SkipDefaultTransaction: true,
Logger: newLogger(log),
// The postgres parameter counter for a given query is represented with uint16,
// resulting in a parameter limit of 65535. In order to avoid reaching this limit
// we'll utilize a batch size of 3k for inserts, well below the limit as long as
// the number of columns < 20.
CreateBatchSize: 3_000,
} }
retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250}
gorm, err := retry.Do[*gorm.DB](context.Background(), 10, retryStrategy, func() (*gorm.DB, error) { gorm, err := retry.Do[*gorm.DB](context.Background(), 10, retryStrategy, func() (*gorm.DB, error) {
gorm, err := gorm.Open(postgres.Open(dsn), &gormConfig) gorm, err := gorm.Open(postgres.Open(dsn), &gormConfig)
if err != nil { if err != nil {
...@@ -66,16 +68,17 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { ...@@ -66,16 +68,17 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) {
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to connect to database after multiple retries: %w", err) return nil, err
} }
db := &DB{ db := &DB{
gorm: gorm, gorm: gorm,
Blocks: newBlocksDB(gorm), log: log,
ContractEvents: newContractEventsDB(gorm), Blocks: newBlocksDB(log, gorm),
BridgeTransfers: newBridgeTransfersDB(gorm), ContractEvents: newContractEventsDB(log, gorm),
BridgeMessages: newBridgeMessagesDB(gorm), BridgeTransfers: newBridgeTransfersDB(log, gorm),
BridgeTransactions: newBridgeTransactionsDB(gorm), BridgeMessages: newBridgeMessagesDB(log, gorm),
BridgeTransactions: newBridgeTransactionsDB(log, gorm),
} }
return db, nil return db, nil
...@@ -85,11 +88,21 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { ...@@ -85,11 +88,21 @@ func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) {
// transaction. If the supplied function errors, the transaction is rolled back. // transaction. If the supplied function errors, the transaction is rolled back.
func (db *DB) Transaction(fn func(db *DB) error) error { func (db *DB) Transaction(fn func(db *DB) error) error {
return db.gorm.Transaction(func(tx *gorm.DB) error { return db.gorm.Transaction(func(tx *gorm.DB) error {
return fn(dbFromGormTx(tx)) txDB := &DB{
gorm: tx,
Blocks: newBlocksDB(db.log, tx),
ContractEvents: newContractEventsDB(db.log, tx),
BridgeTransfers: newBridgeTransfersDB(db.log, tx),
BridgeMessages: newBridgeMessagesDB(db.log, tx),
BridgeTransactions: newBridgeTransactionsDB(db.log, tx),
}
return fn(txDB)
}) })
} }
func (db *DB) Close() error { func (db *DB) Close() error {
db.log.Info("closing database")
sql, err := db.gorm.DB() sql, err := db.gorm.DB()
if err != nil { if err != nil {
return err return err
...@@ -98,17 +111,6 @@ func (db *DB) Close() error { ...@@ -98,17 +111,6 @@ func (db *DB) Close() error {
return sql.Close() return sql.Close()
} }
func dbFromGormTx(tx *gorm.DB) *DB {
return &DB{
gorm: tx,
Blocks: newBlocksDB(tx),
ContractEvents: newContractEventsDB(tx),
BridgeTransfers: newBridgeTransfersDB(tx),
BridgeMessages: newBridgeMessagesDB(tx),
BridgeTransactions: newBridgeTransactionsDB(tx),
}
}
func (db *DB) ExecuteSQLMigration(migrationsFolder string) error { func (db *DB) ExecuteSQLMigration(migrationsFolder string) error {
err := filepath.Walk(migrationsFolder, func(path string, info os.FileInfo, err error) error { err := filepath.Walk(migrationsFolder, func(path string, info os.FileInfo, err error) error {
// Check for any walking error // Check for any walking error
...@@ -122,12 +124,14 @@ func (db *DB) ExecuteSQLMigration(migrationsFolder string) error { ...@@ -122,12 +124,14 @@ func (db *DB) ExecuteSQLMigration(migrationsFolder string) error {
} }
// Read the migration file content // Read the migration file content
db.log.Info("reading sql file", "path", path)
fileContent, readErr := os.ReadFile(path) fileContent, readErr := os.ReadFile(path)
if readErr != nil { if readErr != nil {
return errors.Wrap(readErr, fmt.Sprintf("Error reading SQL file: %s", path)) return errors.Wrap(readErr, fmt.Sprintf("Error reading SQL file: %s", path))
} }
// Execute the migration // Execute the migration
db.log.Info("executing sql file", "path", path)
execErr := db.gorm.Exec(string(fileContent)).Error execErr := db.gorm.Exec(string(fileContent)).Error
if execErr != nil { if execErr != nil {
return errors.Wrap(execErr, fmt.Sprintf("Error executing SQL script: %s", path)) return errors.Wrap(execErr, fmt.Sprintf("Error executing SQL script: %s", path))
...@@ -136,5 +140,6 @@ func (db *DB) ExecuteSQLMigration(migrationsFolder string) error { ...@@ -136,5 +140,6 @@ func (db *DB) ExecuteSQLMigration(migrationsFolder string) error {
return nil return nil
}) })
db.log.Info("finished migrations")
return err return err
} }
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
var ( var (
_ logger.Interface = Logger{} _ logger.Interface = Logger{}
SlowThresholdMilliseconds = 200 SlowThresholdMilliseconds int64 = 500
) )
type Logger struct { type Logger struct {
...@@ -22,7 +22,7 @@ type Logger struct { ...@@ -22,7 +22,7 @@ type Logger struct {
} }
func newLogger(log log.Logger) Logger { func newLogger(log log.Logger) Logger {
return Logger{log.New("module", "db")} return Logger{log}
} }
func (l Logger) LogMode(lvl logger.LogLevel) logger.Interface { func (l Logger) LogMode(lvl logger.LogLevel) logger.Interface {
...@@ -50,7 +50,7 @@ func (l Logger) Trace(ctx context.Context, begin time.Time, fc func() (sql strin ...@@ -50,7 +50,7 @@ func (l Logger) Trace(ctx context.Context, begin time.Time, fc func() (sql strin
sql = fmt.Sprintf("%sVALUES (...)", sql[:i]) sql = fmt.Sprintf("%sVALUES (...)", sql[:i])
} }
if elapsedMs < 200 { if elapsedMs < SlowThresholdMilliseconds {
l.log.Debug("database operation", "duration_ms", elapsedMs, "rows_affected", rows, "sql", sql) l.log.Debug("database operation", "duration_ms", elapsedMs, "rows_affected", rows, "sql", sql)
} else { } else {
l.log.Warn("database operation", "duration_ms", elapsedMs, "rows_affected", rows, "sql", sql) l.log.Warn("database operation", "duration_ms", elapsedMs, "rows_affected", rows, "sql", sql)
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"reflect" "reflect"
"strings"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
...@@ -70,5 +71,5 @@ func (BytesSerializer) Value(ctx context.Context, field *schema.Field, dst refle ...@@ -70,5 +71,5 @@ func (BytesSerializer) Value(ctx context.Context, field *schema.Field, dst refle
} }
hexStr := hexutil.Encode(fieldBytes.Bytes()) hexStr := hexutil.Encode(fieldBytes.Bytes())
return hexStr, nil return strings.ToLower(hexStr), nil
} }
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"reflect" "reflect"
"strings"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
...@@ -52,5 +53,5 @@ func (RLPSerializer) Value(ctx context.Context, field *schema.Field, dst reflect ...@@ -52,5 +53,5 @@ func (RLPSerializer) Value(ctx context.Context, field *schema.Field, dst reflect
} }
hexStr := hexutil.Encode(rlpBytes) hexStr := hexutil.Encode(rlpBytes)
return hexStr, nil return strings.ToLower(hexStr), nil
} }
...@@ -155,7 +155,7 @@ services: ...@@ -155,7 +155,7 @@ services:
- MAINNET_BEDROCK=true - MAINNET_BEDROCK=true
- TRM_API_KEY=$TRM_API_KEY - TRM_API_KEY=$TRM_API_KEY
- GOOGLE_CLOUD_STORAGE_BUCKET_NAME=oplabs-dev-web-content - GOOGLE_CLOUD_STORAGE_BUCKET_NAME=oplabs-dev-web-content
# Recommened to uncomment for local dev unless you need it # Recommend to uncomment for local dev unless you need it
#- BYPASS_EVENT_LOG_POLLER_BOOTSTRAP=true #- BYPASS_EVENT_LOG_POLLER_BOOTSTRAP=true
ports: ports:
- 7422:7300 - 7422:7300
......
...@@ -63,6 +63,7 @@ CREATE INDEX IF NOT EXISTS l1_contract_events_timestamp ON l1_contract_events(ti ...@@ -63,6 +63,7 @@ CREATE INDEX IF NOT EXISTS l1_contract_events_timestamp ON l1_contract_events(ti
CREATE INDEX IF NOT EXISTS l1_contract_events_block_hash ON l1_contract_events(block_hash); CREATE INDEX IF NOT EXISTS l1_contract_events_block_hash ON l1_contract_events(block_hash);
CREATE INDEX IF NOT EXISTS l1_contract_events_event_signature ON l1_contract_events(event_signature); CREATE INDEX IF NOT EXISTS l1_contract_events_event_signature ON l1_contract_events(event_signature);
CREATE INDEX IF NOT EXISTS l1_contract_events_contract_address ON l1_contract_events(contract_address); CREATE INDEX IF NOT EXISTS l1_contract_events_contract_address ON l1_contract_events(contract_address);
ALTER TABLE l1_contract_events ADD UNIQUE (block_hash, log_index);
CREATE TABLE IF NOT EXISTS l2_contract_events ( CREATE TABLE IF NOT EXISTS l2_contract_events (
-- Searchable fields -- Searchable fields
...@@ -81,6 +82,7 @@ CREATE INDEX IF NOT EXISTS l2_contract_events_timestamp ON l2_contract_events(ti ...@@ -81,6 +82,7 @@ CREATE INDEX IF NOT EXISTS l2_contract_events_timestamp ON l2_contract_events(ti
CREATE INDEX IF NOT EXISTS l2_contract_events_block_hash ON l2_contract_events(block_hash); CREATE INDEX IF NOT EXISTS l2_contract_events_block_hash ON l2_contract_events(block_hash);
CREATE INDEX IF NOT EXISTS l2_contract_events_event_signature ON l2_contract_events(event_signature); CREATE INDEX IF NOT EXISTS l2_contract_events_event_signature ON l2_contract_events(event_signature);
CREATE INDEX IF NOT EXISTS l2_contract_events_contract_address ON l2_contract_events(contract_address); CREATE INDEX IF NOT EXISTS l2_contract_events_contract_address ON l2_contract_events(contract_address);
ALTER TABLE l2_contract_events ADD UNIQUE (block_hash, log_index);
/** /**
* BRIDGING DATA * BRIDGING DATA
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum-optimism/optimism/indexer/processors/contracts"
...@@ -28,11 +29,14 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -28,11 +29,14 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
log.Info("detected transaction deposits", "size", len(optimismPortalTxDeposits)) log.Info("detected transaction deposits", "size", len(optimismPortalTxDeposits))
} }
var mintedGWEI = bigint.Zero
portalDeposits := make(map[logKey]*contracts.OptimismPortalTransactionDepositEvent, len(optimismPortalTxDeposits)) portalDeposits := make(map[logKey]*contracts.OptimismPortalTransactionDepositEvent, len(optimismPortalTxDeposits))
transactionDeposits := make([]database.L1TransactionDeposit, len(optimismPortalTxDeposits)) transactionDeposits := make([]database.L1TransactionDeposit, len(optimismPortalTxDeposits))
for i := range optimismPortalTxDeposits { for i := range optimismPortalTxDeposits {
depositTx := optimismPortalTxDeposits[i] depositTx := optimismPortalTxDeposits[i]
portalDeposits[logKey{depositTx.Event.BlockHash, depositTx.Event.LogIndex}] = &depositTx portalDeposits[logKey{depositTx.Event.BlockHash, depositTx.Event.LogIndex}] = &depositTx
mintedGWEI = new(big.Int).Add(mintedGWEI, depositTx.Tx.Amount)
transactionDeposits[i] = database.L1TransactionDeposit{ transactionDeposits[i] = database.L1TransactionDeposit{
SourceHash: depositTx.DepositTx.SourceHash, SourceHash: depositTx.DepositTx.SourceHash,
L2TransactionHash: types.NewTx(depositTx.DepositTx).Hash(), L2TransactionHash: types.NewTx(depositTx.DepositTx).Hash(),
...@@ -40,12 +44,17 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -40,12 +44,17 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
GasLimit: depositTx.GasLimit, GasLimit: depositTx.GasLimit,
Tx: depositTx.Tx, Tx: depositTx.Tx,
} }
} }
if len(transactionDeposits) > 0 { if len(transactionDeposits) > 0 {
if err := db.BridgeTransactions.StoreL1TransactionDeposits(transactionDeposits); err != nil { if err := db.BridgeTransactions.StoreL1TransactionDeposits(transactionDeposits); err != nil {
return err return err
} }
metrics.RecordL1TransactionDeposits(len(transactionDeposits))
// Convert to from wei to eth
mintedETH, _ := bigint.WeiToETH(mintedGWEI).Float64()
metrics.RecordL1TransactionDeposits(len(transactionDeposits), mintedETH)
} }
// (2) L1CrossDomainMessenger // (2) L1CrossDomainMessenger
...@@ -68,6 +77,9 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -68,6 +77,9 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
if !ok { if !ok {
log.Error("expected TransactionDeposit preceding SentMessage event", "tx_hash", sentMessage.Event.TransactionHash.String()) log.Error("expected TransactionDeposit preceding SentMessage event", "tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("expected TransactionDeposit preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String()) return fmt.Errorf("expected TransactionDeposit preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String())
} else if portalDeposit.Event.TransactionHash != sentMessage.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "deposit_tx_hash", portalDeposit.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: portalDeposit.DepositTx.SourceHash, BridgeMessage: sentMessage.BridgeMessage} bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: portalDeposit.DepositTx.SourceHash, BridgeMessage: sentMessage.BridgeMessage}
...@@ -98,15 +110,22 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -98,15 +110,22 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
if !ok { if !ok {
log.Error("expected TransactionDeposit following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected TransactionDeposit following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected TransactionDeposit following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected TransactionDeposit following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if portalDeposit.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "deposit_tx_hash", portalDeposit.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}] sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}]
if !ok { if !ok {
log.Error("expected SentMessage following TransactionDeposit event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected SentMessage following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected SentMessage following TransactionDeposit event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++ bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
bridgeDeposits[i] = database.L1BridgeDeposit{ bridgeDeposits[i] = database.L1BridgeDeposit{
TransactionSourceHash: portalDeposit.DepositTx.SourceHash, TransactionSourceHash: portalDeposit.DepositTx.SourceHash,
BridgeTransfer: initiatedBridge.BridgeTransfer, BridgeTransfer: initiatedBridge.BridgeTransfer,
...@@ -168,17 +187,17 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -168,17 +187,17 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
} }
for i := range finalizedWithdrawals { for i := range finalizedWithdrawals {
finalized := finalizedWithdrawals[i] finalizedWithdrawal := finalizedWithdrawals[i]
withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(finalized.WithdrawalHash) withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(finalizedWithdrawal.WithdrawalHash)
if err != nil { if err != nil {
return err return err
} else if withdrawal == nil { } else if withdrawal == nil {
log.Error("missing indexed withdrawal on finalization event!", "tx_hash", finalized.Event.TransactionHash.String()) log.Error("missing indexed withdrawal on finalization event!", "tx_hash", finalizedWithdrawal.Event.TransactionHash.String())
return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash: %s", finalized.Event.TransactionHash.String()) return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash: %s", finalizedWithdrawal.Event.TransactionHash.String())
} }
if err = db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(finalized.WithdrawalHash, finalized.Event.GUID, finalized.Success); err != nil { if err = db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(finalizedWithdrawal.WithdrawalHash, finalizedWithdrawal.Event.GUID, finalizedWithdrawal.Success); err != nil {
log.Error("failed to mark withdrawal as finalized", "err", err, "tx_hash", finalized.Event.TransactionHash.String()) log.Error("failed to mark withdrawal as finalized", "err", err, "tx_hash", finalizedWithdrawal.Event.TransactionHash.String())
return err return err
} }
} }
...@@ -234,6 +253,9 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -234,6 +253,9 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
if !ok { if !ok {
log.Error("expected RelayedMessage following BridgeFinalized event", "tx_hash", finalizedBridge.Event.TransactionHash.String()) log.Error("expected RelayedMessage following BridgeFinalized event", "tx_hash", finalizedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected RelayedMessage following BridgeFinalized event. tx_hash = %s", finalizedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected RelayedMessage following BridgeFinalized event. tx_hash = %s", finalizedBridge.Event.TransactionHash.String())
} else if relayedMessage.Event.TransactionHash != finalizedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", relayedMessage.Event.TransactionHash.String(), "bridge_tx_hash", finalizedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
// Since the message hash is computed from the relayed message, this ensures the deposit fields must match // Since the message hash is computed from the relayed message, this ensures the deposit fields must match
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum-optimism/optimism/indexer/processors/contracts"
...@@ -28,11 +29,14 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M ...@@ -28,11 +29,14 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M
log.Info("detected transaction withdrawals", "size", len(l2ToL1MPMessagesPassed)) log.Info("detected transaction withdrawals", "size", len(l2ToL1MPMessagesPassed))
} }
var withdrawnWEI = bigint.Zero
messagesPassed := make(map[logKey]*contracts.L2ToL1MessagePasserMessagePassed, len(l2ToL1MPMessagesPassed)) messagesPassed := make(map[logKey]*contracts.L2ToL1MessagePasserMessagePassed, len(l2ToL1MPMessagesPassed))
transactionWithdrawals := make([]database.L2TransactionWithdrawal, len(l2ToL1MPMessagesPassed)) transactionWithdrawals := make([]database.L2TransactionWithdrawal, len(l2ToL1MPMessagesPassed))
for i := range l2ToL1MPMessagesPassed { for i := range l2ToL1MPMessagesPassed {
messagePassed := l2ToL1MPMessagesPassed[i] messagePassed := l2ToL1MPMessagesPassed[i]
messagesPassed[logKey{messagePassed.Event.BlockHash, messagePassed.Event.LogIndex}] = &messagePassed messagesPassed[logKey{messagePassed.Event.BlockHash, messagePassed.Event.LogIndex}] = &messagePassed
withdrawnWEI = new(big.Int).Add(withdrawnWEI, messagePassed.Tx.Amount)
transactionWithdrawals[i] = database.L2TransactionWithdrawal{ transactionWithdrawals[i] = database.L2TransactionWithdrawal{
WithdrawalHash: messagePassed.WithdrawalHash, WithdrawalHash: messagePassed.WithdrawalHash,
InitiatedL2EventGUID: messagePassed.Event.GUID, InitiatedL2EventGUID: messagePassed.Event.GUID,
...@@ -45,7 +49,10 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M ...@@ -45,7 +49,10 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M
if err := db.BridgeTransactions.StoreL2TransactionWithdrawals(transactionWithdrawals); err != nil { if err := db.BridgeTransactions.StoreL2TransactionWithdrawals(transactionWithdrawals); err != nil {
return err return err
} }
metrics.RecordL2TransactionWithdrawals(len(transactionWithdrawals))
// Convert the withdrawn WEI to ETH
withdrawnETH, _ := bigint.WeiToETH(withdrawnWEI).Float64()
metrics.RecordL2TransactionWithdrawals(len(transactionWithdrawals), withdrawnETH)
} }
// (2) L2CrossDomainMessenger // (2) L2CrossDomainMessenger
...@@ -68,6 +75,9 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M ...@@ -68,6 +75,9 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M
if !ok { if !ok {
log.Error("expected MessagePassedEvent preceding SentMessage", "tx_hash", sentMessage.Event.TransactionHash.String()) log.Error("expected MessagePassedEvent preceding SentMessage", "tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("expected MessagePassedEvent preceding SentMessage. tx_hash = %s", sentMessage.Event.TransactionHash.String()) return fmt.Errorf("expected MessagePassedEvent preceding SentMessage. tx_hash = %s", sentMessage.Event.TransactionHash.String())
} else if messagePassed.Event.TransactionHash != sentMessage.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "withdraw_tx_hash", messagePassed.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
bridgeMessages[i] = database.L2BridgeMessage{TransactionWithdrawalHash: messagePassed.WithdrawalHash, BridgeMessage: sentMessage.BridgeMessage} bridgeMessages[i] = database.L2BridgeMessage{TransactionWithdrawalHash: messagePassed.WithdrawalHash, BridgeMessage: sentMessage.BridgeMessage}
...@@ -93,16 +103,23 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M ...@@ -93,16 +103,23 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M
for i := range initiatedBridges { for i := range initiatedBridges {
initiatedBridge := initiatedBridges[i] initiatedBridge := initiatedBridges[i]
// extract the cross domain message hash & deposit source hash from the following events // extract the cross domain message hash & withdraw hash from the following events
messagePassed, ok := messagesPassed[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 1}] messagePassed, ok := messagesPassed[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 1}]
if !ok { if !ok {
log.Error("expected MessagePassed following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected MessagePassed following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected MessagePassed following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected MessagePassed following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if messagePassed.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "withdraw_tx_hash", messagePassed.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}] sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}]
if !ok { if !ok {
log.Error("expected SentMessage following MessagePassed event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected SentMessage following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected SentMessage following MessagePassed event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
...@@ -180,6 +197,9 @@ func L2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L2M ...@@ -180,6 +197,9 @@ func L2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L2M
if !ok { if !ok {
log.Error("expected RelayedMessage following BridgeFinalized event", "tx_hash", finalizedBridge.Event.TransactionHash.String()) log.Error("expected RelayedMessage following BridgeFinalized event", "tx_hash", finalizedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected RelayedMessage following BridgeFinalized event. tx_hash = %s", finalizedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected RelayedMessage following BridgeFinalized event. tx_hash = %s", finalizedBridge.Event.TransactionHash.String())
} else if relayedMessage.Event.TransactionHash != finalizedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", relayedMessage.Event.TransactionHash.String(), "bridge_tx_hash", finalizedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
// Since the message hash is computed from the relayed message, this ensures the withdrawal fields must match // Since the message hash is computed from the relayed message, this ensures the withdrawal fields must match
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/indexer/node"
...@@ -31,17 +32,18 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -31,17 +32,18 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
log.Info("detected legacy transaction deposits", "size", len(ctcTxDepositEvents)) log.Info("detected legacy transaction deposits", "size", len(ctcTxDepositEvents))
} }
mintedWEI := bigint.Zero
ctcTxDeposits := make(map[logKey]*contracts.LegacyCTCDepositEvent, len(ctcTxDepositEvents)) ctcTxDeposits := make(map[logKey]*contracts.LegacyCTCDepositEvent, len(ctcTxDepositEvents))
transactionDeposits := make([]database.L1TransactionDeposit, len(ctcTxDepositEvents)) transactionDeposits := make([]database.L1TransactionDeposit, len(ctcTxDepositEvents))
for i := range ctcTxDepositEvents { for i := range ctcTxDepositEvents {
deposit := ctcTxDepositEvents[i] deposit := ctcTxDepositEvents[i]
ctcTxDeposits[logKey{deposit.Event.BlockHash, deposit.Event.LogIndex}] = &deposit ctcTxDeposits[logKey{deposit.Event.BlockHash, deposit.Event.LogIndex}] = &deposit
transactionDeposits[i] = database.L1TransactionDeposit{ mintedWEI = new(big.Int).Add(mintedWEI, deposit.Tx.Amount)
// We re-use the L2 Transaction hash as the source hash
// to remain consistent in the schema.
SourceHash: deposit.TxHash,
L2TransactionHash: deposit.TxHash,
transactionDeposits[i] = database.L1TransactionDeposit{
// We re-use the L2 Transaction hash as the source hash to remain consistent in the schema.
SourceHash: deposit.TxHash,
L2TransactionHash: deposit.TxHash,
InitiatedL1EventGUID: deposit.Event.GUID, InitiatedL1EventGUID: deposit.Event.GUID,
GasLimit: deposit.GasLimit, GasLimit: deposit.GasLimit,
Tx: deposit.Tx, Tx: deposit.Tx,
...@@ -51,7 +53,9 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -51,7 +53,9 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
if err := db.BridgeTransactions.StoreL1TransactionDeposits(transactionDeposits); err != nil { if err := db.BridgeTransactions.StoreL1TransactionDeposits(transactionDeposits); err != nil {
return err return err
} }
metrics.RecordL1TransactionDeposits(len(transactionDeposits))
mintedETH, _ := bigint.WeiToETH(mintedWEI).Float64()
metrics.RecordL1TransactionDeposits(len(transactionDeposits), mintedETH)
} }
// (2) L1CrossDomainMessenger // (2) L1CrossDomainMessenger
...@@ -72,8 +76,11 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -72,8 +76,11 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
// extract the deposit hash from the previous TransactionDepositedEvent // extract the deposit hash from the previous TransactionDepositedEvent
ctcTxDeposit, ok := ctcTxDeposits[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex - 1}] ctcTxDeposit, ok := ctcTxDeposits[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex - 1}]
if !ok { if !ok {
log.Error("missing transaction deposit for cross domain message", "tx_hash", sentMessage.Event.TransactionHash.String()) log.Error("expected TransactionEnqueued preceding SentMessage event", "tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("missing preceding TransactionEnqueued for SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String()) return fmt.Errorf("expected TransactionEnqueued preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String())
} else if ctcTxDeposit.Event.TransactionHash != sentMessage.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "deposit_tx_hash", ctcTxDeposit.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: ctcTxDeposit.TxHash, BridgeMessage: sentMessage.BridgeMessage} bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: ctcTxDeposit.TxHash, BridgeMessage: sentMessage.BridgeMessage}
...@@ -104,13 +111,20 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -104,13 +111,20 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
// - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated // - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated
sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}] sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}]
if !ok { if !ok {
log.Error("missing cross domain message for bridge transfer", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected SentMessage preceding BridgeInitiated event", "tx_hash", sentMessage.Event.TransactionHash.String())
return fmt.Errorf("expected SentMessage preceding DepositInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected SentMessage preceding DepositInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
ctcTxDeposit, ok := ctcTxDeposits[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 2}] ctcTxDeposit, ok := ctcTxDeposits[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 2}]
if !ok { if !ok {
log.Error("missing transaction deposit for bridge transfer", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected TransactionEnqueued preceding BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected TransactionEnqueued preceding DepostInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected TransactionEnqueued preceding BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String())
} else if ctcTxDeposit.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "deposit_tx_hash", ctcTxDeposit.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
...@@ -148,12 +162,14 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -148,12 +162,14 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
log.Info("detected legacy transaction withdrawals (via L2CrossDomainMessenger)", "size", len(crossDomainSentMessages)) log.Info("detected legacy transaction withdrawals (via L2CrossDomainMessenger)", "size", len(crossDomainSentMessages))
} }
withdrawnWEI := bigint.Zero
sentMessages := make(map[logKey]*contracts.CrossDomainMessengerSentMessageEvent, len(crossDomainSentMessages)) sentMessages := make(map[logKey]*contracts.CrossDomainMessengerSentMessageEvent, len(crossDomainSentMessages))
bridgeMessages := make([]database.L2BridgeMessage, len(crossDomainSentMessages)) bridgeMessages := make([]database.L2BridgeMessage, len(crossDomainSentMessages))
transactionWithdrawals := make([]database.L2TransactionWithdrawal, len(crossDomainSentMessages)) transactionWithdrawals := make([]database.L2TransactionWithdrawal, len(crossDomainSentMessages))
for i := range crossDomainSentMessages { for i := range crossDomainSentMessages {
sentMessage := crossDomainSentMessages[i] sentMessage := crossDomainSentMessages[i]
sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = &sentMessage sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = &sentMessage
withdrawnWEI = new(big.Int).Add(withdrawnWEI, sentMessage.BridgeMessage.Tx.Amount)
// To ensure consistency in the schema, we duplicate this as the "root" transaction withdrawal. The storage key in the message // To ensure consistency in the schema, we duplicate this as the "root" transaction withdrawal. The storage key in the message
// passer contract is sha3(calldata + sender). The sender always being the L2CrossDomainMessenger pre-bedrock. // passer contract is sha3(calldata + sender). The sender always being the L2CrossDomainMessenger pre-bedrock.
...@@ -184,7 +200,9 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -184,7 +200,9 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
if err := db.BridgeMessages.StoreL2BridgeMessages(bridgeMessages); err != nil { if err := db.BridgeMessages.StoreL2BridgeMessages(bridgeMessages); err != nil {
return err return err
} }
metrics.RecordL2TransactionWithdrawals(len(transactionWithdrawals))
withdrawnETH, _ := bigint.WeiToETH(withdrawnWEI).Float64()
metrics.RecordL2TransactionWithdrawals(len(transactionWithdrawals), withdrawnETH)
metrics.RecordL2CrossDomainSentMessages(len(bridgeMessages)) metrics.RecordL2CrossDomainSentMessages(len(bridgeMessages))
} }
...@@ -207,12 +225,15 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -207,12 +225,15 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
// - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated // - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated
sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}] sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}]
if !ok { if !ok {
log.Error("expected SentMessage preceding DepositInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) log.Error("expected SentMessage preceding BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("expected SentMessage preceding DepositInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) return fmt.Errorf("expected SentMessage preceding BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash)
} else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash {
log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String())
return fmt.Errorf("correlated events tx hash mismatch")
} }
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++ bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++
initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash
l2BridgeWithdrawals[i] = database.L2BridgeWithdrawal{ l2BridgeWithdrawals[i] = database.L2BridgeWithdrawal{
TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash, TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash,
BridgeTransfer: initiatedBridge.BridgeTransfer, BridgeTransfer: initiatedBridge.BridgeTransfer,
......
...@@ -16,7 +16,7 @@ var ( ...@@ -16,7 +16,7 @@ var (
type L1Metricer interface { type L1Metricer interface {
RecordLatestIndexedL1Height(height *big.Int) RecordLatestIndexedL1Height(height *big.Int)
RecordL1TransactionDeposits(size int) RecordL1TransactionDeposits(size int, mintedETH float64)
RecordL1ProvenWithdrawals(size int) RecordL1ProvenWithdrawals(size int)
RecordL1FinalizedWithdrawals(size int) RecordL1FinalizedWithdrawals(size int)
...@@ -30,7 +30,7 @@ type L1Metricer interface { ...@@ -30,7 +30,7 @@ type L1Metricer interface {
type L2Metricer interface { type L2Metricer interface {
RecordLatestIndexedL2Height(height *big.Int) RecordLatestIndexedL2Height(height *big.Int)
RecordL2TransactionWithdrawals(size int) RecordL2TransactionWithdrawals(size int, withdrawnETH float64)
RecordL2CrossDomainSentMessages(size int) RecordL2CrossDomainSentMessages(size int)
RecordL2CrossDomainRelayedMessages(size int) RecordL2CrossDomainRelayedMessages(size int)
...@@ -55,7 +55,9 @@ type bridgeMetrics struct { ...@@ -55,7 +55,9 @@ type bridgeMetrics struct {
latestL2Height prometheus.Gauge latestL2Height prometheus.Gauge
txDeposits prometheus.Counter txDeposits prometheus.Counter
txMintedETH prometheus.Counter
txWithdrawals prometheus.Counter txWithdrawals prometheus.Counter
txWithdrawnETH prometheus.Counter
provenWithdrawals prometheus.Counter provenWithdrawals prometheus.Counter
finalizedWithdrawals prometheus.Counter finalizedWithdrawals prometheus.Counter
...@@ -101,11 +103,21 @@ func NewMetrics(registry *prometheus.Registry) Metricer { ...@@ -101,11 +103,21 @@ func NewMetrics(registry *prometheus.Registry) Metricer {
Name: "tx_deposits", Name: "tx_deposits",
Help: "number of processed transactions deposited from l1", Help: "number of processed transactions deposited from l1",
}), }),
txMintedETH: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace,
Name: "tx_minted_eth",
Help: "amount of eth bridged from l1",
}),
txWithdrawals: factory.NewCounter(prometheus.CounterOpts{ txWithdrawals: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace, Namespace: MetricsNamespace,
Name: "tx_withdrawals", Name: "tx_withdrawals",
Help: "number of processed transactions withdrawn from l2", Help: "number of processed transactions withdrawn from l2",
}), }),
txWithdrawnETH: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace,
Name: "tx_withdrawn_eth",
Help: "amount of eth withdrawn from l2",
}),
provenWithdrawals: factory.NewCounter(prometheus.CounterOpts{ provenWithdrawals: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace, Namespace: MetricsNamespace,
Name: "proven_withdrawals", Name: "proven_withdrawals",
...@@ -166,8 +178,9 @@ func (m *bridgeMetrics) RecordLatestIndexedL1Height(height *big.Int) { ...@@ -166,8 +178,9 @@ func (m *bridgeMetrics) RecordLatestIndexedL1Height(height *big.Int) {
m.latestL1Height.Set(float64(height.Uint64())) m.latestL1Height.Set(float64(height.Uint64()))
} }
func (m *bridgeMetrics) RecordL1TransactionDeposits(size int) { func (m *bridgeMetrics) RecordL1TransactionDeposits(size int, mintedETH float64) {
m.txDeposits.Add(float64(size)) m.txDeposits.Add(float64(size))
m.txMintedETH.Add(mintedETH)
} }
func (m *bridgeMetrics) RecordL1ProvenWithdrawals(size int) { func (m *bridgeMetrics) RecordL1ProvenWithdrawals(size int) {
...@@ -200,8 +213,9 @@ func (m *bridgeMetrics) RecordLatestIndexedL2Height(height *big.Int) { ...@@ -200,8 +213,9 @@ func (m *bridgeMetrics) RecordLatestIndexedL2Height(height *big.Int) {
m.latestL2Height.Set(float64(height.Uint64())) m.latestL2Height.Set(float64(height.Uint64()))
} }
func (m *bridgeMetrics) RecordL2TransactionWithdrawals(size int) { func (m *bridgeMetrics) RecordL2TransactionWithdrawals(size int, withdrawnETH float64) {
m.txWithdrawals.Add(float64(size)) m.txWithdrawals.Add(float64(size))
m.txWithdrawnETH.Add(withdrawnETH)
} }
func (m *bridgeMetrics) RecordL2CrossDomainSentMessages(size int) { func (m *bridgeMetrics) RecordL2CrossDomainSentMessages(size int) {
......
FROM --platform=$BUILDPLATFORM golang:1.21.1-alpine3.18 as builder ARG OP_STACK_GO_BUILDER=us-docker.pkg.dev/oplabs-tools-artifacts/images/op_stack_go:latest
FROM $OP_STACK_GO_BUILDER as builder
ARG VERSION=v0.0.0 # See "make golang-docker" and /ops/docker/op-stack-go
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
COPY ./go.mod /app/go.mod
COPY ./go.sum /app/go.sum
WORKDIR /app
RUN go mod download
# build op-batcher with the shared go.mod & go.sum files
COPY ./op-batcher /app/op-batcher
COPY ./op-bindings /app/op-bindings
COPY ./op-node /app/op-node
COPY ./op-service /app/op-service
COPY ./.git /app/.git
WORKDIR /app/op-batcher
ARG TARGETOS TARGETARCH
RUN make op-batcher VERSION="$VERSION" GOOS=$TARGETOS GOARCH=$TARGETARCH
FROM alpine:3.18 FROM alpine:3.18
COPY --from=builder /app/op-batcher/bin/op-batcher /usr/local/bin COPY --from=builder /usr/local/bin/op-batcher /usr/local/bin/op-batcher
ENTRYPOINT ["op-batcher"] CMD ["op-batcher"]
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
GITCOMMIT := $(shell git rev-parse HEAD) GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct') GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0 VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
...@@ -16,9 +16,6 @@ clean: ...@@ -16,9 +16,6 @@ clean:
test: test:
go test -v ./... go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
fuzz: fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzChannelConfig_CheckTimeout ./batcher go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzChannelConfig_CheckTimeout ./batcher
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzDurationZero ./batcher go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzDurationZero ./batcher
...@@ -33,5 +30,4 @@ fuzz: ...@@ -33,5 +30,4 @@ fuzz:
op-batcher \ op-batcher \
clean \ clean \
test \ test \
lint \
fuzz fuzz
...@@ -26,9 +26,6 @@ bindings-build: ...@@ -26,9 +26,6 @@ bindings-build:
-package $(pkg) \ -package $(pkg) \
-monorepo-base $(monorepo-base) -monorepo-base $(monorepo-base)
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
mkdir: mkdir:
mkdir -p $(pkg) mkdir -p $(pkg)
......
This diff is collapsed.
...@@ -13,7 +13,7 @@ const BaseFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\ ...@@ -13,7 +13,7 @@ const BaseFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\
var BaseFeeVaultStorageLayout = new(solc.StorageLayout) var BaseFeeVaultStorageLayout = new(solc.StorageLayout)
var BaseFeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a" var BaseFeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a"
func init() { func init() {
if err := json.Unmarshal([]byte(BaseFeeVaultStorageLayoutJSON), BaseFeeVaultStorageLayout); err != nil { if err := json.Unmarshal([]byte(BaseFeeVaultStorageLayoutJSON), BaseFeeVaultStorageLayout); err != nil {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -13,7 +13,7 @@ const L1FeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\": ...@@ -13,7 +13,7 @@ const L1FeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":
var L1FeeVaultStorageLayout = new(solc.StorageLayout) var L1FeeVaultStorageLayout = new(solc.StorageLayout)
var L1FeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a" var L1FeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a"
func init() { func init() {
if err := json.Unmarshal([]byte(L1FeeVaultStorageLayoutJSON), L1FeeVaultStorageLayout); err != nil { if err := json.Unmarshal([]byte(L1FeeVaultStorageLayoutJSON), L1FeeVaultStorageLayout); err != nil {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
GITCOMMIT := $(shell git rev-parse HEAD) GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct') GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0 VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
...@@ -16,11 +16,7 @@ clean: ...@@ -16,11 +16,7 @@ clean:
test: test:
go test -v ./... go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
.PHONY: \ .PHONY: \
op-bootnode \ op-bootnode \
clean \ clean \
test \ test
lint
...@@ -6,9 +6,6 @@ check-l2: ...@@ -6,9 +6,6 @@ check-l2:
test: test:
go test ./... go test ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
fuzz: fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeWithdrawal ./crossdomain go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeWithdrawal ./crossdomain
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeLegacyWithdrawal ./crossdomain go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzEncodeDecodeLegacyWithdrawal ./crossdomain
......
...@@ -34,5 +34,5 @@ be read out of the directory as needed. ...@@ -34,5 +34,5 @@ be read out of the directory as needed.
#### Outfile #### Outfile
The file that the bundle shoudl be written to. If omitted, the file The file that the bundle should be written to. If omitted, the file
will be written to stdout. will be written to stdout.
This diff is collapsed.
...@@ -49,6 +49,18 @@ func TestRegolithTimeAsOffset(t *testing.T) { ...@@ -49,6 +49,18 @@ func TestRegolithTimeAsOffset(t *testing.T) {
require.Equal(t, uint64(1500+5000), *config.RegolithTime(5000)) require.Equal(t, uint64(1500+5000), *config.RegolithTime(5000))
} }
func TestCanyonTimeZero(t *testing.T) {
canyonOffset := hexutil.Uint64(0)
config := &DeployConfig{L2GenesisCanyonTimeOffset: &canyonOffset}
require.Equal(t, uint64(0), *config.CanyonTime(1234))
}
func TestCanyonTimeOffset(t *testing.T) {
canyonOffset := hexutil.Uint64(1500)
config := &DeployConfig{L2GenesisCanyonTimeOffset: &canyonOffset}
require.Equal(t, uint64(1234+1500), *config.CanyonTime(1234))
}
// TestCopy will copy a DeployConfig and ensure that the copy is equal to the original. // TestCopy will copy a DeployConfig and ensure that the copy is equal to the original.
func TestCopy(t *testing.T) { func TestCopy(t *testing.T) {
b, err := os.ReadFile("testdata/test-deploy-config-full.json") b, err := os.ReadFile("testdata/test-deploy-config-full.json")
......
...@@ -58,6 +58,8 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro ...@@ -58,6 +58,8 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro
TerminalTotalDifficultyPassed: true, TerminalTotalDifficultyPassed: true,
BedrockBlock: new(big.Int).SetUint64(uint64(config.L2GenesisBlockNumber)), BedrockBlock: new(big.Int).SetUint64(uint64(config.L2GenesisBlockNumber)),
RegolithTime: config.RegolithTime(block.Time()), RegolithTime: config.RegolithTime(block.Time()),
CanyonTime: config.CanyonTime(block.Time()),
ShanghaiTime: config.CanyonTime(block.Time()),
Optimism: &params.OptimismConfig{ Optimism: &params.OptimismConfig{
EIP1559Denominator: eip1559Denom, EIP1559Denominator: eip1559Denom,
EIP1559Elasticity: eip1559Elasticity, EIP1559Elasticity: eip1559Elasticity,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
GITCOMMIT := $(shell git rev-parse HEAD) GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE := $(shell git show -s --format='%ct') GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0 VERSION := v0.0.0
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
...@@ -16,9 +16,6 @@ clean: ...@@ -16,9 +16,6 @@ clean:
test: test:
go test -v ./... go test -v ./...
lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
visualize: visualize:
./scripts/visualize.sh ./scripts/visualize.sh
......
This diff is collapsed.
...@@ -124,7 +124,7 @@ func TestGetStepData(t *testing.T) { ...@@ -124,7 +124,7 @@ func TestGetStepData(t *testing.T) {
require.EqualValues(t, generator.proof.StateData, preimage) require.EqualValues(t, generator.proof.StateData, preimage)
require.EqualValues(t, generator.proof.ProofData, proof) require.EqualValues(t, generator.proof.ProofData, proof)
expectedData := types.NewPreimageOracleData(generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset) expectedData := types.NewPreimageOracleData(0, generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset)
require.EqualValues(t, expectedData, data) require.EqualValues(t, expectedData, data)
}) })
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -21,7 +21,7 @@ func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1M ...@@ -21,7 +21,7 @@ func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1M
miner := NewL1Miner(t, log, sd.L1Cfg) miner := NewL1Miner(t, log, sd.L1Cfg)
l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindBasic)) l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard))
require.NoError(t, err) require.NoError(t, err)
engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath)
l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg))
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -491,7 +491,7 @@ func TestSystemMockP2P(t *testing.T) { ...@@ -491,7 +491,7 @@ func TestSystemMockP2P(t *testing.T) {
verifierPeerID := sys.RollupNodes["verifier"].P2P().Host().ID() verifierPeerID := sys.RollupNodes["verifier"].P2P().Host().ID()
check := func() bool { check := func() bool {
sequencerBlocksTopicPeers := sys.RollupNodes["sequencer"].P2P().GossipOut().BlocksTopicPeers() sequencerBlocksTopicPeers := sys.RollupNodes["sequencer"].P2P().GossipOut().AllBlockTopicsPeers()
return slices.Contains[[]peer.ID](sequencerBlocksTopicPeers, verifierPeerID) return slices.Contains[[]peer.ID](sequencerBlocksTopicPeers, verifierPeerID)
} }
...@@ -592,6 +592,10 @@ func TestSystemRPCAltSync(t *testing.T) { ...@@ -592,6 +592,10 @@ func TestSystemRPCAltSync(t *testing.T) {
opts.VerifyOnClients(l2Verif) opts.VerifyOnClients(l2Verif)
}) })
// Sometimes we get duplicate blocks on the sequencer which makes this test flaky
published = slices.Compact(published)
received = slices.Compact(received)
// Verify that the tx was received via RPC sync (P2P is disabled) // Verify that the tx was received via RPC sync (P2P is disabled)
require.Contains(t, received, eth.BlockID{Hash: receiptSeq.BlockHash, Number: receiptSeq.BlockNumber.Uint64()}.String()) require.Contains(t, received, eth.BlockID{Hash: receiptSeq.BlockHash, Number: receiptSeq.BlockNumber.Uint64()}.String())
......
This diff is collapsed.
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
This diff is collapsed.
This diff is collapsed.
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
This diff is collapsed.
This diff is collapsed.
...@@ -78,7 +78,7 @@ var ( ...@@ -78,7 +78,7 @@ var (
openum.EnumString(sources.RPCProviderKinds), openum.EnumString(sources.RPCProviderKinds),
EnvVars: prefixEnvVars("L1_RPC_KIND"), EnvVars: prefixEnvVars("L1_RPC_KIND"),
Value: func() *sources.RPCProviderKind { Value: func() *sources.RPCProviderKind {
out := sources.RPCKindBasic out := sources.RPCKindStandard
return &out return &out
}(), }(),
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -40,6 +40,11 @@ func TestGuardGossipValidator(t *testing.T) { ...@@ -40,6 +40,11 @@ func TestGuardGossipValidator(t *testing.T) {
require.Equal(t, pubsub.ValidationIgnore, val(context.Background(), "bob", nil)) require.Equal(t, pubsub.ValidationIgnore, val(context.Background(), "bob", nil))
} }
func TestCombinePeers(t *testing.T) {
res := combinePeers([]peer.ID{"foo", "bar"}, []peer.ID{"bar", "baz"})
require.Equal(t, []peer.ID{"foo", "bar", "baz"}, res)
}
func TestVerifyBlockSignature(t *testing.T) { func TestVerifyBlockSignature(t *testing.T) {
logger := testlog.Logger(t, log.LvlCrit) logger := testlog.Logger(t, log.LvlCrit)
cfg := &rollup.Config{ cfg := &rollup.Config{
......
...@@ -112,7 +112,10 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l ...@@ -112,7 +112,10 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l
n.syncCl.AddPeer(conn.RemotePeer()) n.syncCl.AddPeer(conn.RemotePeer())
}, },
DisconnectedF: func(nw network.Network, conn network.Conn) { DisconnectedF: func(nw network.Network, conn network.Conn) {
n.syncCl.RemovePeer(conn.RemotePeer()) // only when no connection is available, we can remove the peer
if nw.Connectedness(conn.RemotePeer()) == network.NotConnected {
n.syncCl.RemovePeer(conn.RemotePeer())
}
}, },
}) })
n.syncCl.Start() n.syncCl.Start()
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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