Commit 4626bbc9 authored by smartcontracts's avatar smartcontracts Committed by GitHub

Merge pull request #3313 from ethereum-optimism/develop

develop => master
parents 91ba02e1 4fa3d863
---
'@eth-optimism/contracts-bedrock': patch
---
Include latest devnet deployment artifacts
---
'@eth-optimism/contracts-bedrock': patch
---
Bump oz packages to latest release
---
'@eth-optimism/contracts-bedrock': patch
---
Migrate deploy config to json from ts
---
'@eth-optimism/contracts-periphery': patch
---
Support deploy via Ledger or private key
---
'@eth-optimism/indexer': patch
---
Delete dead file
---
'@eth-optimism/contracts-bedrock': patch
---
Fix nonce issue for parallel deployments
---
'@eth-optimism/contracts': patch
---
Add inspect hh task
---
'@eth-optimism/contracts-bedrock': patch
---
Add missing predeploy to Predeploys.sol
---
'@eth-optimism/contracts-bedrock': patch
---
Moves forge-std and ds-test to devDependencies to avoid breaking npm
---
'@eth-optimism/indexer': patch
---
Update go-ethereum to 1.10.21
---
'@eth-optimism/sdk': patch
---
Fix eth withdrawal bug
---
'@eth-optimism/sdk': patch
---
Fixes a bug in the SDK for certain bridge withdrawals.
---
'@eth-optimism/sdk': minor
---
Removes the ICrossChainMessenger interface to speed up SDK development.
---
'@eth-optimism/contracts-bedrock': patch
---
Update the L2 genesis hardhat task to use the ProxyAdmin's deployed address as the admin of each predeploy
---
'@eth-optimism/contracts-bedrock': patch
---
Fix legibility in the L2CrossDomainMessengerInitializer
---
'@eth-optimism/sdk': patch
---
Add eth withdrawal support
---
'@eth-optimism/contracts-bedrock': patch
---
Make a library call internal
---
'@eth-optimism/contracts': patch
'@eth-optimism/sdk': patch
---
Updates the SDK to pull contract addresses from the deployments of the contracts package. Updates the Contracts package to export a function that makes it possible to pull deployed addresses.
---
'@eth-optimism/sdk': patch
---
Minor refactor to variables within the SDK package.
---
'@eth-optimism/contracts-bedrock': patch
---
Add additional deployments of address manager and proxy admin
---
'@eth-optimism/contracts-bedrock': patch
---
Use safecall that doesn't copy calldata
---
'@eth-optimism/ci-builder': patch
---
Update golang, geth and golangci-lint
---
'@eth-optimism/contracts-bedrock': patch
---
Deletes the L2 genesis creation hardhat task as its now replaced by go code
---
'@eth-optimism/contracts-bedrock': patch
---
Update @foundry-rs/hardhat-forge to 0.1.17
---
'@eth-optimism/indexer': patch
---
Remove some duplicated code
This diff is collapsed.
{
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"editor.formatOnSave": true
},
"eslint.workingDirectories": [
{"directory": "packages/core-utils", "changeProcessCWD": true },
{"directory": "packages/common-ts", "changeProcessCWD": true },
{"directory": "packages/contracts", "changeProcessCWD": true },
{"directory": "packages/contracts-periphery", "changeProcessCWD": true },
{"directory": "packages/data-transport-layer", "changeProcessCWD": true },
{"directory": "packages/drippie-mon", "changeProcessCWD": true },
{"directory": "packages/batch-submitter", "changeProcessCWD": true },
{"directory": "packages/message-relayer", "changeProcessCWD": true },
{"directory": "packages/fault-detector", "changeProcessCWD": true },
{
"directory": "packages/core-utils",
"changeProcessCWD": true
},
{
"directory": "packages/common-ts",
"changeProcessCWD": true
},
{
"directory": "packages/contracts",
"changeProcessCWD": true
},
{
"directory": "packages/contracts-periphery",
"changeProcessCWD": true
},
{
"directory": "packages/data-transport-layer",
"changeProcessCWD": true
},
{
"directory": "packages/drippie-mon",
"changeProcessCWD": true
},
{
"directory": "packages/batch-submitter",
"changeProcessCWD": true
},
{
"directory": "packages/message-relayer",
"changeProcessCWD": true
},
{
"directory": "packages/fault-detector",
"changeProcessCWD": true
}
],
"eslint.nodePath": "./node_modules/eslint/bin/",
"eslint.format.enable": true,
"editorconfig.generateAuto": false,
"files.trimTrailingWhitespace": true,
}
"files.trimTrailingWhitespace": true
}
\ No newline at end of file
COMPOSEFLAGS=-d
ITESTS_L2_HOST=http://localhost:9545
BEDROCK_TAGS_REMOTE?=origin
build: build-go build-ts
.PHONY: build
......@@ -40,6 +41,13 @@ op-proposer:
.PHONY: op-proposer
mod-tidy:
# Below GOPRIVATE line allows mod-tidy to be run immediately after
# releasing new versions. This bypasses the Go modules proxy, which
# can take a while to index new versions.
#
# See https://proxy.golang.org/ for more info.
export GOPRIVATE="github.com/ethereum-optimism" && \
cd ./op-service && go mod tidy && cd .. && \
cd ./op-node && go mod tidy && cd .. && \
cd ./op-proposer && go mod tidy && cd .. && \
cd ./op-batcher && go mod tidy && cd .. && \
......@@ -97,3 +105,30 @@ semgrep:
clean-node-modules:
rm -rf node_modules
rm -rf packages/**/node_modules
tag-bedrock-go-modules:
@if [ -z "$(VERSION)" ]; then \
echo "You must specify a version."; \
exit 0; \
fi
@FIRST_CHAR=$(shell printf '%s' "$(VERSION)" | cut -c1); \
if [ "$$FIRST_CHAR" != "v" ]; then \
echo "Tag must start with v."; \
exit 0; \
fi
git tag "op-proposer/$(VERSION)"
git tag "op-node/$(VERSION)"
git tag "op-e2e/$(VERSION)"
git tag "op-bindings/$(VERSION)"
git tag "op-batcher/$(VERSION)"
git tag "op-service/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-proposer/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-node/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-e2e/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-bindings/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-batcher/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-service/$(VERSION)"
......@@ -13,12 +13,13 @@ use (
./op-exporter
./op-node
./op-proposer
./op-service
./proxyd
./op-chain-ops
./teleportr
./state-surgery
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61
// For local debugging:
//replace github.com/ethereum/go-ethereum v1.10.21 => ../go-ethereum
......@@ -18,6 +18,7 @@ cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLq
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI=
github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
......@@ -25,6 +26,7 @@ github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRP
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
......@@ -41,17 +43,39 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid/v2 v2.0.14/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/libp2p/go-libp2p v0.20.0/go.mod h1:g0C5Fu+aXXbCXkusCzLycuBowEih3ElmDqtbo61Em7k=
github.com/libp2p/go-libp2p-core v0.16.1/go.mod h1:O3i/7y+LqUb0N+qhzXjBjjpchgptWAVMG1Voegk7b4c=
github.com/libp2p/go-libp2p-core v0.19.0/go.mod h1:AkA+FUKQfYt1FLNef5fOPlo/naAWjKy/RCjkcPjqzYg=
github.com/libp2p/go-libp2p-resource-manager v0.5.1/go.mod h1:CggtV6EZb+Y0dGh41q5ezO4udcVKyhcEFpydHD8EMe0=
github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI=
github.com/libp2p/go-yamux/v3 v3.1.1/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4=
github.com/lucas-clemente/quic-go v0.27.1/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84=
github.com/multiformats/go-multistream v0.3.1/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg=
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
......@@ -75,10 +99,16 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
......@@ -137,6 +167,7 @@ google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
......@@ -148,3 +179,5 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
......@@ -3,7 +3,6 @@ FROM golang:1.18.0-alpine3.15 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
COPY ./indexer /go/indexer
COPY ./l2geth /go/l2geth
COPY ./op-bindings /go/op-bindings
COPY ./indexer/docker.go.work /go/go.work
......
......@@ -7,13 +7,6 @@ LDFLAGSSTRING +=-X main.GitDate=$(GITDATE)
LDFLAGSSTRING +=-X main.GitVersion=$(GITVERSION)
LDFLAGS := -ldflags "$(LDFLAGSSTRING)"
L1BRIDGE_ABI_ARTIFACT = ../packages/contracts/artifacts/contracts/L1/messaging/L1StandardBridge.sol/L1StandardBridge.json
L2BRIDGE_ABI_ARTIFACT = ../packages/contracts/artifacts/contracts/L2/messaging/L2StandardBridge.sol/L2StandardBridge.json
ERC20_ABI_ARTIFACT = ./contracts/ERC20.sol/ERC20.json
SCC_ABI_ARTIFACT = ../packages/contracts/artifacts/contracts/L1/rollup/StateCommitmentChain.sol/StateCommitmentChain.json
indexer:
env GO111MODULE=on go build -v $(LDFLAGS) ./cmd/indexer
......@@ -26,96 +19,8 @@ test:
lint:
golangci-lint run ./...
bindings: bindings-l1bridge bindings-l2bridge bindings-l1erc20 bindings-l2erc20 bindings-scc
bindings-l1bridge:
$(eval temp := $(shell mktemp))
cat $(L1BRIDGE_ABI_ARTIFACT) \
| jq -r .bytecode > $(temp)
cat $(L1BRIDGE_ABI_ARTIFACT) \
| jq .abi \
| abigen --pkg l1bridge \
--abi - \
--out bindings/l1bridge/l1_standard_bridge.go \
--type L1StandardBridge \
--bin $(temp)
rm $(temp)
bindings-l2bridge:
$(eval temp := $(shell mktemp))
cat $(L2BRIDGE_ABI_ARTIFACT) \
| jq -r .bytecode > $(temp)
cat $(L2BRIDGE_ABI_ARTIFACT) \
| jq .abi \
| abigen --pkg l2bridge \
--abi - \
--out bindings/l2bridge/l2_standard_bridge.go \
--type L2StandardBridge \
--bin $(temp)
rm $(temp)
bindings-l1erc20:
$(eval temp := $(shell mktemp))
cat $(ERC20_ABI_ARTIFACT) \
| jq -r .bytecode > $(temp)
cat $(ERC20_ABI_ARTIFACT) \
| jq .abi \
| abigen --pkg l1erc20 \
--abi - \
--out bindings/l1erc20/l1erc20.go \
--type L1ERC20 \
--bin $(temp)
rm $(temp)
bindings-l2erc20:
$(eval temp := $(shell mktemp))
cat $(ERC20_ABI_ARTIFACT) \
| jq -r .bytecode > $(temp)
cat $(ERC20_ABI_ARTIFACT) \
| jq .abi \
| abigen --pkg l2erc20 \
--abi - \
--out bindings/l2erc20/l2erc20.go \
--type L2ERC20 \
--bin $(temp)
rm $(temp)
bindings-scc:
$(eval temp := $(shell mktemp))
cat $(SCC_ABI_ARTIFACT) \
| jq -r .bytecode > $(temp)
cat $(SCC_ABI_ARTIFACT) \
| jq .abi \
| abigen --pkg scc \
--abi - \
--out bindings/scc/statecommitmentchain.go \
--type StateCommitmentChain \
--bin $(temp)
rm $(temp)
.PHONY: \
indexer \
bindings \
bindings-l1bridge \
bindings-l2bridge \
bindings-l1erc20 \
bindings-l2erc20 \
bindings-scc \
clean \
test \
lint
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -36,9 +36,6 @@ type Config struct {
// L2EthRpc is the HTTP provider URL for L1.
L2EthRpc string
// L1AddressManagerAddress is the address of the address manager for L1.
L1AddressManagerAddress string
// L2GenesisBlockHash is the l2 genesis block hash.
L2GenesisBlockHash string
......@@ -121,18 +118,17 @@ type Config struct {
func NewConfig(ctx *cli.Context) (Config, error) {
cfg := Config{
/* Required Flags */
BuildEnv: ctx.GlobalString(flags.BuildEnvFlag.Name),
EthNetworkName: ctx.GlobalString(flags.EthNetworkNameFlag.Name),
ChainID: ctx.GlobalInt64(flags.ChainIDFlag.Name),
L1EthRpc: ctx.GlobalString(flags.L1EthRPCFlag.Name),
L2EthRpc: ctx.GlobalString(flags.L2EthRPCFlag.Name),
L1AddressManagerAddress: ctx.GlobalString(flags.L1AddressManagerAddressFlag.Name),
L2GenesisBlockHash: ctx.GlobalString(flags.L2GenesisBlockHashFlag.Name),
DBHost: ctx.GlobalString(flags.DBHostFlag.Name),
DBPort: ctx.GlobalUint64(flags.DBPortFlag.Name),
DBUser: ctx.GlobalString(flags.DBUserFlag.Name),
DBPassword: ctx.GlobalString(flags.DBPasswordFlag.Name),
DBName: ctx.GlobalString(flags.DBNameFlag.Name),
BuildEnv: ctx.GlobalString(flags.BuildEnvFlag.Name),
EthNetworkName: ctx.GlobalString(flags.EthNetworkNameFlag.Name),
ChainID: ctx.GlobalInt64(flags.ChainIDFlag.Name),
L1EthRpc: ctx.GlobalString(flags.L1EthRPCFlag.Name),
L2EthRpc: ctx.GlobalString(flags.L2EthRPCFlag.Name),
L2GenesisBlockHash: ctx.GlobalString(flags.L2GenesisBlockHashFlag.Name),
DBHost: ctx.GlobalString(flags.DBHostFlag.Name),
DBPort: ctx.GlobalUint64(flags.DBPortFlag.Name),
DBUser: ctx.GlobalString(flags.DBUserFlag.Name),
DBPassword: ctx.GlobalString(flags.DBPasswordFlag.Name),
DBName: ctx.GlobalString(flags.DBNameFlag.Name),
/* Optional Flags */
DisableIndexer: ctx.GlobalBool(flags.DisableIndexer.Name),
LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
......
......@@ -3,24 +3,14 @@ package indexer
import (
"fmt"
l2common "github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum/go-ethereum/common"
)
// ParseL1Address parses a L1 ETH address from a hex string. This method will
// ParseAddress parses a ETH address from a hex string. This method will
// fail if the address is not a valid hexadecimal address.
func ParseL1Address(address string) (common.Address, error) {
func ParseAddress(address string) (common.Address, error) {
if common.IsHexAddress(address) {
return common.HexToAddress(address), nil
}
return common.Address{}, fmt.Errorf("invalid address: %v", address)
}
// ParseL2Address parses a L2 ETH address from a hex string. This method will
// fail if the address is not a valid hexadecimal address.
func ParseL2Address(address string) (l2common.Address, error) {
if l2common.IsHexAddress(address) {
return l2common.HexToAddress(address), nil
}
return l2common.Address{}, fmt.Errorf("invalid address: %v", address)
}
......@@ -6,15 +6,14 @@ import (
"testing"
indexer "github.com/ethereum-optimism/optimism/indexer"
l2common "github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
// TestParseL1Address asserts that ParseL1Address correctly parses
// TestParseAddress asserts that ParseAddress correctly parses
// 40-characater hexadecimal strings with optional 0x prefix into valid 20-byte
// addresses for the L1 chain.
func TestParseL1Address(t *testing.T) {
// addresses
func TestParseAddress(t *testing.T) {
tests := []struct {
name string
addr string
......@@ -46,52 +45,7 @@ func TestParseL1Address(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
addr, err := indexer.ParseL1Address(test.addr)
require.Equal(t, err, test.expErr)
if test.expErr != nil {
return
}
require.Equal(t, addr, test.expAddr)
})
}
}
// TestParseL2Address asserts that ParseL2Address correctly parses
// 40-characater hexadecimal strings with optional 0x prefix into valid 20-byte
// addresses for the L2 chain.
func TestParseL2Address(t *testing.T) {
tests := []struct {
name string
addr string
expErr error
expAddr l2common.Address
}{
{
name: "empty address",
addr: "",
expErr: errors.New("invalid address: "),
},
{
name: "only 0x",
addr: "0x",
expErr: errors.New("invalid address: 0x"),
},
{
name: "non hex character",
addr: "0xaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
expErr: errors.New("invalid address: 0xaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
},
{
name: "valid address",
addr: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
expErr: nil,
expAddr: l2common.BytesToAddress(bytes.Repeat([]byte{170}, 20)),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
addr, err := indexer.ParseL2Address(test.addr)
addr, err := indexer.ParseAddress(test.addr)
require.Equal(t, err, test.expErr)
if test.expErr != nil {
return
......
......@@ -2,5 +2,4 @@ go 1.18
use (
./indexer
./l2geth
)
......@@ -46,12 +46,6 @@ var (
Required: true,
EnvVar: prefixEnvVar("L2_ETH_RPC"),
}
L1AddressManagerAddressFlag = cli.StringFlag{
Name: "l1-address-manager-address",
Usage: "Address of the L1 address manager",
Required: true,
EnvVar: prefixEnvVar("L1_ADDRESS_MANAGER_ADDRESS"),
}
L2GenesisBlockHashFlag = cli.StringFlag{
Name: "l2-genesis-block-hash",
Usage: "Genesis block hash of the L2 chain",
......@@ -187,7 +181,6 @@ var requiredFlags = []cli.Flag{
ChainIDFlag,
L1EthRPCFlag,
L2EthRPCFlag,
L1AddressManagerAddressFlag,
L2GenesisBlockHashFlag,
DBHostFlag,
DBPortFlag,
......
......@@ -2,79 +2,52 @@ module github.com/ethereum-optimism/optimism/indexer
go 1.17
replace (
github.com/ethereum-optimism/optimism/l2geth v0.0.0 => ../l2geth
github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
)
replace github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
require (
github.com/ethereum-optimism/optimism/l2geth v0.0.0
github.com/ethereum-optimism/optimism/op-bindings v0.0.0
github.com/ethereum/go-ethereum v1.10.17
github.com/ethereum/go-ethereum v1.10.21
github.com/getsentry/sentry-go v0.12.0
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/lib/pq v1.10.4
github.com/prometheus/client_golang v1.11.0
github.com/rs/cors v1.8.2
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.7.2
github.com/urfave/cli v1.22.5
)
require (
github.com/VictoriaMetrics/fastcache v1.9.0 // indirect
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/elastic/gosigar v0.12.0 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/huin/goupnp v1.0.3 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/karalabe/usb v0.0.2 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pborman/uuid v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/status-im/keycard-go v0.0.0-20211109104530-b0e0482ba91d // indirect
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
This diff is collapsed.
......@@ -159,23 +159,17 @@ func NewIndexer(cfg Config, gitVersion string) (*Indexer, error) {
return nil, err
}
l1AddressManagerAddress, err := ParseL1Address(cfg.L1AddressManagerAddress)
if err != nil {
return nil, err
}
l1IndexingService, err := l1.NewService(l1.ServiceConfig{
Context: ctx,
Metrics: m,
L1Client: l1Client,
RawL1Client: rawl1Client,
ChainID: big.NewInt(cfg.ChainID),
AddressManagerAddress: l1AddressManagerAddress,
DB: db,
ConfDepth: cfg.ConfDepth,
MaxHeaderBatchSize: cfg.MaxHeaderBatchSize,
StartBlockNumber: cfg.StartBlockNumber,
StartBlockHash: cfg.StartBlockHash,
Context: ctx,
Metrics: m,
L1Client: l1Client,
RawL1Client: rawl1Client,
ChainID: big.NewInt(cfg.ChainID),
DB: db,
ConfDepth: cfg.ConfDepth,
MaxHeaderBatchSize: cfg.MaxHeaderBatchSize,
StartBlockNumber: cfg.StartBlockNumber,
StartBlockHash: cfg.StartBlockHash,
})
if err != nil {
return nil, err
......
package bridge
import (
"fmt"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
var zeroAddr common.Address
var standardContracts = []string{
"Proxy__OVM_L1CrossDomainMessenger",
"Proxy__OVM_L1StandardBridge",
"StateCommitmentChain",
"CanonicalTransactionChain",
"BondManager",
}
type Addresses struct {
addrs map[string]common.Address
}
func NewAddresses(client bind.ContractBackend, addrMgrAddr common.Address) (*Addresses, error) {
ret := &Addresses{
addrs: make(map[string]common.Address),
}
ret.addrs["AddressManager"] = addrMgrAddr
mgr, err := bindings.NewAddressManager(addrMgrAddr, client)
if err != nil {
return nil, err
}
for _, contractName := range standardContracts {
contractAddr, err := mgr.GetAddress(nil, contractName)
if err != nil {
return nil, fmt.Errorf("error getting contract %s: %v", contractName, err)
}
if contractAddr == zeroAddr {
return nil, fmt.Errorf("contract %s is not deployed", contractName)
}
ret.addrs[contractName] = contractAddr
}
return ret, nil
}
func (a *Addresses) AddressManager() common.Address {
return a.addrs["AddressManager"]
}
func (a *Addresses) L1CrossDomainMessenger() common.Address {
return a.addrs["Proxy__OVM_L1CrossDomainMessenger"]
}
func (a *Addresses) L1StandardBridge() common.Address {
return a.addrs["Proxy__OVM_L1StandardBridge"]
}
func (a *Addresses) StateCommitmentChain() common.Address {
return a.addrs["StateCommitmentChain"]
}
func (a *Addresses) CanonicalTransactionChain() common.Address {
return a.addrs["CanonicalTransactionChain"]
}
func (a *Addresses) BondManager() common.Address {
return a.addrs["BondManager"]
}
......@@ -5,9 +5,9 @@ import (
"errors"
"math/big"
"github.com/ethereum-optimism/optimism/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/indexer/bindings/scc"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
......@@ -26,6 +26,8 @@ type implConfig struct {
addr common.Address
}
var addrs map[string]common.Address
var customBridgeCfgs = map[uint64][]*implConfig{
// Mainnet
1: {
......@@ -40,10 +42,10 @@ var customBridgeCfgs = map[uint64][]*implConfig{
},
}
func BridgesByChainID(chainID *big.Int, client bind.ContractBackend, addrs *Addresses, ctx context.Context) (map[string]Bridge, error) {
func BridgesByChainID(chainID *big.Int, client bind.ContractBackend, ctx context.Context) (map[string]Bridge, error) {
allCfgs := []*implConfig{
{"Standard", "StandardBridge", addrs.L1StandardBridge()},
{"ETH", "ETHBridge", addrs.L1StandardBridge()},
{"Standard", "StandardBridge", addrs["L1StandardBridge"]},
{"ETH", "ETHBridge", addrs["L1StandardBridge"]},
}
allCfgs = append(allCfgs, customBridgeCfgs[chainID.Uint64()]...)
......@@ -51,7 +53,7 @@ func BridgesByChainID(chainID *big.Int, client bind.ContractBackend, addrs *Addr
for _, bridge := range allCfgs {
switch bridge.impl {
case "StandardBridge":
l1StandardBridgeFilter, err := l1bridge.NewL1StandardBridgeFilterer(bridge.addr, client)
l1StandardBridgeFilter, err := bindings.NewL1StandardBridgeFilterer(bridge.addr, client)
if err != nil {
return nil, err
}
......@@ -65,7 +67,7 @@ func BridgesByChainID(chainID *big.Int, client bind.ContractBackend, addrs *Addr
}
bridges[bridge.name] = standardBridge
case "ETHBridge":
l1EthBridgeFilter, err := l1bridge.NewL1StandardBridgeFilterer(bridge.addr, client)
l1EthBridgeFilter, err := bindings.NewL1StandardBridgeFilterer(bridge.addr, client)
if err != nil {
return nil, err
}
......@@ -84,11 +86,3 @@ func BridgesByChainID(chainID *big.Int, client bind.ContractBackend, addrs *Addr
}
return bridges, nil
}
func StateCommitmentChainScanner(client bind.ContractFilterer, addrs *Addresses) (*scc.StateCommitmentChainFilterer, error) {
filter, err := scc.NewStateCommitmentChainFilterer(addrs.StateCommitmentChain(), client)
if err != nil {
return nil, err
}
return filter, nil
}
......@@ -3,8 +3,8 @@ package bridge
import (
"context"
"github.com/ethereum-optimism/optimism/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
......@@ -14,7 +14,7 @@ type EthBridge struct {
ctx context.Context
address common.Address
client bind.ContractFilterer
filterer *l1bridge.L1StandardBridgeFilterer
filterer *bindings.L1StandardBridgeFilterer
}
func (e *EthBridge) Address() common.Address {
......@@ -39,7 +39,7 @@ func (e *EthBridge) GetDepositsByBlockRange(start, end uint64) (DepositsMap, err
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.Data,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
......
......@@ -4,8 +4,7 @@ import (
"context"
"time"
"github.com/ethereum-optimism/optimism/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/indexer/bindings/scc"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
)
......@@ -13,25 +12,9 @@ import (
// calls.
var clientRetryInterval = 5 * time.Second
// FilterStateBatchAppendedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterStateBatchAppendedWithRetry(ctx context.Context, filterer *scc.StateCommitmentChainFilterer, opts *bind.FilterOpts) (*scc.StateCommitmentChainStateBatchAppendedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterStateBatchAppended(opts, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
// FilterETHDepositInitiatedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterETHDepositInitiatedWithRetry(ctx context.Context, filterer *l1bridge.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*l1bridge.L1StandardBridgeETHDepositInitiatedIterator, error) {
func FilterETHDepositInitiatedWithRetry(ctx context.Context, filterer *bindings.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L1StandardBridgeETHDepositInitiatedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
......@@ -47,7 +30,7 @@ func FilterETHDepositInitiatedWithRetry(ctx context.Context, filterer *l1bridge.
// FilterERC20DepositInitiatedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterERC20DepositInitiatedWithRetry(ctx context.Context, filterer *l1bridge.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*l1bridge.L1StandardBridgeERC20DepositInitiatedIterator, error) {
func FilterERC20DepositInitiatedWithRetry(ctx context.Context, filterer *bindings.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L1StandardBridgeERC20DepositInitiatedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
......
......@@ -3,8 +3,8 @@ package bridge
import (
"context"
"github.com/ethereum-optimism/optimism/indexer/bindings/l1bridge"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
......@@ -14,7 +14,7 @@ type StandardBridge struct {
ctx context.Context
address common.Address
client bind.ContractFilterer
filterer *l1bridge.L1StandardBridgeFilterer
filterer *bindings.L1StandardBridgeFilterer
}
func (s *StandardBridge) Address() common.Address {
......@@ -41,7 +41,7 @@ func (s *StandardBridge) GetDepositsByBlockRange(start, end uint64) (DepositsMap
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.Data,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
......
package l1
import (
"context"
"github.com/ethereum-optimism/optimism/indexer/bindings/l1erc20"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum-optimism/optimism/indexer/bindings/scc"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/indexer/services/l1/bridge"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, error) {
contract, err := l1erc20.NewL1ERC20(address, client)
contract, err := bindings.NewERC20(address, client)
if err != nil {
return nil, err
}
......@@ -40,31 +36,3 @@ func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, er
Decimals: decimals,
}, nil
}
func QueryStateBatches(filterer *scc.StateCommitmentChainFilterer, startHeight, endHeight uint64, ctx context.Context) (map[common.Hash][]db.StateBatch, error) {
batches := make(map[common.Hash][]db.StateBatch)
iter, err := bridge.FilterStateBatchAppendedWithRetry(ctx, filterer, &bind.FilterOpts{
Start: startHeight,
End: &endHeight,
})
if err != nil {
return nil, err
}
for iter.Next() {
batches[iter.Event.Raw.BlockHash] = append(
batches[iter.Event.Raw.BlockHash], db.StateBatch{
Index: iter.Event.BatchIndex,
Root: iter.Event.BatchRoot,
Size: iter.Event.BatchSize,
PrevTotal: iter.Event.PrevTotalElements,
ExtraData: iter.Event.ExtraData,
BlockHash: iter.Event.Raw.BlockHash,
})
}
if err := iter.Error(); err != nil {
return nil, err
}
return batches, nil
}
......@@ -14,7 +14,6 @@ import (
"github.com/ethereum-optimism/optimism/indexer/metrics"
"github.com/prometheus/client_golang/prometheus"
"github.com/ethereum-optimism/optimism/indexer/bindings/scc"
"github.com/ethereum-optimism/optimism/indexer/server"
"github.com/ethereum-optimism/optimism/indexer/services/l1/bridge"
......@@ -66,17 +65,16 @@ type Driver interface {
}
type ServiceConfig struct {
Context context.Context
Metrics *metrics.Metrics
L1Client *ethclient.Client
RawL1Client *rpc.Client
ChainID *big.Int
AddressManagerAddress common.Address
ConfDepth uint64
MaxHeaderBatchSize uint64
StartBlockNumber uint64
StartBlockHash string
DB *db.Database
Context context.Context
Metrics *metrics.Metrics
L1Client *ethclient.Client
RawL1Client *rpc.Client
ChainID *big.Int
ConfDepth uint64
MaxHeaderBatchSize uint64
StartBlockNumber uint64
StartBlockHash string
DB *db.Database
}
type Service struct {
......@@ -85,7 +83,6 @@ type Service struct {
cancel func()
bridges map[string]bridge.Bridge
batchScanner *scc.StateCommitmentChainFilterer
latestHeader uint64
headerSelector *ConfirmedHeaderSelector
......@@ -116,24 +113,7 @@ func NewService(cfg ServiceConfig) (*Service, error) {
return nil, fmt.Errorf("chain ID configured with %d but got %d", cfg.ChainID, chainID)
}
addrs, err := bridge.NewAddresses(cfg.L1Client, cfg.AddressManagerAddress)
if err != nil {
cancel()
return nil, err
}
bridges, err := bridge.BridgesByChainID(cfg.ChainID, cfg.L1Client, addrs, ctx)
if err != nil {
cancel()
return nil, err
}
batchScanner, err := bridge.StateCommitmentChainScanner(cfg.L1Client, addrs)
if err != nil {
cancel()
return nil, err
}
var bridges map[string]bridge.Bridge
logger.Info("Scanning bridges for deposits", "bridges", bridges)
confirmedHeaderSelector, err := NewConfirmedHeaderSelector(HeaderSelectorConfig{
......@@ -151,7 +131,6 @@ func NewService(cfg ServiceConfig) (*Service, error) {
ctx: ctx,
cancel: cancel,
bridges: bridges,
batchScanner: batchScanner,
headerSelector: confirmedHeaderSelector,
metrics: cfg.Metrics,
tokenCache: map[common.Address]*db.Token{
......@@ -284,66 +263,6 @@ func (s *Service) Update(newHeader *types.Header) error {
}
}
stateBatches, err := QueryStateBatches(s.batchScanner, startHeight, endHeight, s.ctx)
if err != nil {
logger.Error("Error querying state batches", "err", err)
}
for i, header := range headers {
blockHash := header.Hash
number := header.Number.Uint64()
deposits := depositsByBlockHash[blockHash]
batches := stateBatches[blockHash]
if len(deposits) == 0 && len(batches) == 0 && i != len(headers)-1 {
continue
}
block := &db.IndexedL1Block{
Hash: blockHash,
ParentHash: header.ParentHash,
Number: number,
Timestamp: header.Time,
Deposits: deposits,
}
err := s.cfg.DB.AddIndexedL1Block(block)
if err != nil {
logger.Error(
"Unable to import ",
"block", number,
"hash", blockHash, "err", err,
"block", block,
)
return err
}
err = s.cfg.DB.AddStateBatch(batches)
if err != nil {
logger.Error(
"Unable to import state append batch",
"block", number,
"hash", blockHash, "err", err,
"block", block,
)
return err
}
s.metrics.RecordStateBatches(len(batches))
logger.Debug("Imported ",
"block", number, "hash", blockHash, "deposits", len(block.Deposits))
for _, deposit := range block.Deposits {
token := s.tokenCache[deposit.L1Token]
logger.Info(
"indexed deposit",
"tx_hash", deposit.TxHash,
"symbol", token.Symbol,
"amount", deposit.Amount,
)
s.metrics.RecordDeposit(deposit.L1Token)
}
}
newHeaderNumber := newHeader.Number.Uint64()
s.metrics.SetL1SyncHeight(endHeight)
s.metrics.SetL1SyncPercent(endHeight, newHeaderNumber)
......
......@@ -5,8 +5,8 @@ import (
"errors"
"math/big"
"github.com/ethereum-optimism/optimism/indexer/bindings/l2bridge"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
......@@ -54,7 +54,7 @@ func BridgesByChainID(chainID *big.Int, client bind.ContractFilterer, ctx contex
switch bridge.impl {
case "StandardBridge":
l2StandardBridgeAddress := common.HexToAddress(bridge.addr)
l2StandardBridgeFilter, err := l2bridge.NewL2StandardBridgeFilterer(l2StandardBridgeAddress, client)
l2StandardBridgeFilter, err := bindings.NewL2StandardBridgeFilterer(l2StandardBridgeAddress, client)
if err != nil {
return nil, err
}
......
......@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/ethereum-optimism/optimism/indexer/bindings/l2bridge"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
)
......@@ -14,7 +14,7 @@ var clientRetryInterval = 5 * time.Second
// FilterWithdrawalInitiatedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterWithdrawalInitiatedWithRetry(ctx context.Context, filterer *l2bridge.L2StandardBridgeFilterer, opts *bind.FilterOpts) (*l2bridge.L2StandardBridgeWithdrawalInitiatedIterator, error) {
func FilterWithdrawalInitiatedWithRetry(ctx context.Context, filterer *bindings.L2StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L2StandardBridgeWithdrawalInitiatedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
......
......@@ -3,8 +3,8 @@ package bridge
import (
"context"
"github.com/ethereum-optimism/optimism/indexer/bindings/l2bridge"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
......@@ -15,7 +15,7 @@ type StandardBridge struct {
ctx context.Context
address common.Address
client bind.ContractFilterer
filterer *l2bridge.L2StandardBridgeFilterer
filterer *bindings.L2StandardBridgeFilterer
}
func (s *StandardBridge) Address() common.Address {
......@@ -42,7 +42,7 @@ func (s *StandardBridge) GetWithdrawalsByBlockRange(start, end uint64) (Withdraw
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.Data,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
......
package l2
import (
"github.com/ethereum-optimism/optimism/indexer/bindings/l2erc20"
"github.com/ethereum-optimism/optimism/indexer/db"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
func QueryERC20(address common.Address, client *ethclient.Client) (*db.Token, error) {
contract, err := l2erc20.NewL2ERC20(address, client)
contract, err := bindings.NewERC20(address, client)
if err != nil {
return nil, err
}
......
......@@ -7,6 +7,7 @@ COPY ./op-batcher/docker.go.work /app/go.work
COPY ./op-bindings /app/op-bindings
COPY ./op-node /app/op-node
COPY ./op-proposer /app/op-proposer
COPY ./op-service /app/op-service
COPY ./op-batcher /app/op-batcher
WORKDIR /app/op-batcher
......
This diff is collapsed.
......@@ -4,6 +4,8 @@ import (
"fmt"
"os"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli"
......@@ -18,14 +20,7 @@ var (
)
func main() {
// Set up logger with a default INFO level in case we fail to parse flags,
// otherwise the final critical log won't show what the parsing error was.
log.Root().SetHandler(
log.LvlFilterHandler(
log.LvlInfo,
log.StreamHandler(os.Stdout, log.TerminalFormat(true)),
),
)
oplog.SetupDefaults()
app := cli.NewApp()
app.Flags = flags.Flags
......
This diff is collapsed.
......@@ -5,4 +5,5 @@ use (
./op-bindings
./op-node
./op-proposer
./op-service
)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -31,7 +31,7 @@ var (
// AddressManagerMetaData contains all meta data concerning the AddressManager contract.
var AddressManagerMetaData = &bind.MetaData{
ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6106d98061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046105e4565b610184565b6100906100da366004610632565b6102d0565b6100746100ed36600461066f565b61030c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b610182600061043c565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610205576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b6000610210836104b1565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000083161790925591519293501690610273908590610691565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006102df846104b1565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b73ffffffffffffffffffffffffffffffffffffffff8116610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161016f565b6104398161043c565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016104c49190610691565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261052157600080fd5b813567ffffffffffffffff8082111561053c5761053c6104e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610582576105826104e1565b8160405283815286602085880101111561059b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146105df57600080fd5b919050565b600080604083850312156105f757600080fd5b823567ffffffffffffffff81111561060e57600080fd5b61061a85828601610510565b925050610629602084016105bb565b90509250929050565b60006020828403121561064457600080fd5b813567ffffffffffffffff81111561065b57600080fd5b61066784828501610510565b949350505050565b60006020828403121561068157600080fd5b61068a826105bb565b9392505050565b6000825160005b818110156106b25760208186018101518583015201610698565b818111156106c1576000828501525b50919091019291505056fea164736f6c634300080f000a",
Bin: "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105ef8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a",
}
// AddressManagerABI is the input ABI used to generate the binding from.
......
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.
......@@ -41,4 +41,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61
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.
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