-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: indexer service to replace etherscan dependency
- Loading branch information
Showing
44 changed files
with
10,635 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
GITCOMMIT := $(shell git rev-parse HEAD) | ||
GITDATE := $(shell git show -s --format='%ct') | ||
GITVERSION := $(shell cat package.json | jq .version) | ||
|
||
LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) | ||
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 | ||
|
||
clean: | ||
rm indexer | ||
|
||
test: | ||
go test -v ./... | ||
|
||
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 \ | ||
| ../../l2geth/build/bin/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 \ | ||
| ../../l2geth/build/bin/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) | ||
|
||
bindings-address-manager: | ||
$(eval temp := $(shell mktemp)) | ||
|
||
cat $(ADDRESS_MANAGER_ABI_ARTIFACT) \ | ||
| jq -r .bytecode > $(temp) | ||
|
||
cat $(ADDRESS_MANAGER_ABI_ARTIFACT) \ | ||
| jq .abi \ | ||
| abigen --pkg address_manager \ | ||
--abi - \ | ||
--out ./bindings/address_manager/address_manager.go \ | ||
--type AddressManager \ | ||
--bin $(temp) | ||
|
||
.PHONY: \ | ||
indexer \ | ||
bindings \ | ||
bindings-l1bridge \ | ||
bindings-l2bridge \ | ||
bindings-l1erc20 \ | ||
bindings-l2erc20 \ | ||
bindings-scc \ | ||
clean \ | ||
test \ | ||
lint |
Large diffs are not rendered by default.
Oops, something went wrong.
1,124 changes: 1,124 additions & 0 deletions
1,124
go/indexer/bindings/l1bridge/l1_standard_bridge.go
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/ethereum/go-ethereum/log" | ||
"github.com/ethereum/go-ethereum/params" | ||
"github.com/urfave/cli" | ||
|
||
"github.com/ethereum-optimism/optimism/go/indexer" | ||
"github.com/ethereum-optimism/optimism/go/indexer/flags" | ||
) | ||
|
||
var ( | ||
GitVersion = "" | ||
GitCommit = "" | ||
GitDate = "" | ||
) | ||
|
||
func main() { | ||
// Set up logger with a default INFO level in case we fail to parse flags. | ||
// Otherwise the final crtiical log won't show what the parsing error was. | ||
log.Root().SetHandler( | ||
log.LvlFilterHandler( | ||
log.LvlInfo, | ||
log.StreamHandler(os.Stdout, log.TerminalFormat(true)), | ||
), | ||
) | ||
|
||
app := cli.NewApp() | ||
app.Flags = flags.Flags | ||
app.Version = fmt.Sprintf("%s-%s", GitVersion, params.VersionWithCommit(GitCommit, GitDate)) | ||
app.Name = "indexer" | ||
app.Usage = "Indexer Service" | ||
app.Description = "Service for indexing deposits and withdrawals " + | ||
"by account on L1 and L2" | ||
|
||
app.Action = indexer.Main(GitVersion) | ||
err := app.Run(os.Args) | ||
if err != nil { | ||
log.Crit("Application failed", "message", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package indexer | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/log" | ||
"github.com/urfave/cli" | ||
|
||
"github.com/ethereum-optimism/optimism/go/indexer/flags" | ||
) | ||
|
||
var ( | ||
// ErrSentryDSNNotSet signals that not Data Source Name was provided | ||
// with which to configure Sentry logging. | ||
ErrSentryDSNNotSet = errors.New("sentry-dsn must be set if use-sentry " + | ||
"is true") | ||
) | ||
|
||
type Config struct { | ||
/* Required Params */ | ||
|
||
// BuildEnv identifies the environment this binary is intended for, i.e. | ||
// production, development, etc. | ||
BuildEnv string | ||
|
||
// EthNetworkName identifies the intended Ethereum network. | ||
EthNetworkName string | ||
|
||
// ChainID identifies the chain being indexed. | ||
ChainID int64 | ||
|
||
// L1EthRpc is the HTTP provider URL for L1. | ||
L1EthRpc string | ||
|
||
// 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 | ||
|
||
// PollInterval is the delay between querying L2 for more transaction | ||
// and creating a new batch. | ||
PollInterval time.Duration | ||
|
||
// Hostname of the database connection. | ||
DBHost string | ||
|
||
// Port of the database connection. | ||
DBPort uint64 | ||
|
||
// Username of the database connection. | ||
DBUser string | ||
|
||
// Password of the database connection. | ||
DBPassword string | ||
|
||
// Database name of the database connection. | ||
DBName string | ||
|
||
/* Optional Params */ | ||
|
||
// LogLevel is the lowest log level that will be output. | ||
LogLevel string | ||
|
||
// LogTerminal if true, prints to stdout in terminal format, otherwise | ||
// prints using JSON. If SentryEnable is true this flag is ignored, and logs | ||
// are printed using JSON. | ||
LogTerminal bool | ||
|
||
// SentryEnable if true, logs any error messages to sentry. SentryDsn | ||
// must also be set if SentryEnable is true. | ||
SentryEnable bool | ||
|
||
// SentryDsn is the sentry Data Source Name. | ||
SentryDsn string | ||
|
||
// SentryTraceRate the frequency with which Sentry should flush buffered | ||
// events. | ||
SentryTraceRate time.Duration | ||
|
||
// StartBlockNumber is the block number to start indexing from. | ||
StartBlockNumber uint64 | ||
|
||
// StartBlockHash is the block hash to start indexing from. | ||
StartBlockHash string | ||
|
||
// ConfDepth is the number of confirmations after which headers are | ||
// considered confirmed. | ||
ConfDepth uint64 | ||
|
||
// MaxHeaderBatchSize is the maximum number of headers to request as a | ||
// batch. | ||
MaxHeaderBatchSize uint64 | ||
|
||
// MetricsServerEnable if true, will create a metrics client and log to | ||
// Prometheus. | ||
MetricsServerEnable bool | ||
|
||
// MetricsHostname is the hostname at which the metrics server is running. | ||
MetricsHostname string | ||
|
||
// MetricsPort is the port at which the metrics server is running. | ||
MetricsPort uint64 | ||
|
||
// DisableIndexer enables/disables the indexer. | ||
DisableIndexer bool | ||
} | ||
|
||
// NewConfig parses the Config from the provided flags or environment variables. | ||
// This method fails if ValidateConfig deems the configuration to be malformed. | ||
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), | ||
/* Optional Flags */ | ||
DisableIndexer: ctx.GlobalBool(flags.DisableIndexer.Name), | ||
LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name), | ||
LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name), | ||
SentryEnable: ctx.GlobalBool(flags.SentryEnableFlag.Name), | ||
SentryDsn: ctx.GlobalString(flags.SentryDsnFlag.Name), | ||
SentryTraceRate: ctx.GlobalDuration(flags.SentryTraceRateFlag.Name), | ||
StartBlockNumber: ctx.GlobalUint64(flags.StartBlockNumberFlag.Name), | ||
StartBlockHash: ctx.GlobalString(flags.StartBlockHashFlag.Name), | ||
ConfDepth: ctx.GlobalUint64(flags.ConfDepthFlag.Name), | ||
MaxHeaderBatchSize: ctx.GlobalUint64(flags.MaxHeaderBatchSizeFlag.Name), | ||
MetricsServerEnable: ctx.GlobalBool(flags.MetricsServerEnableFlag.Name), | ||
MetricsHostname: ctx.GlobalString(flags.MetricsHostnameFlag.Name), | ||
MetricsPort: ctx.GlobalUint64(flags.MetricsPortFlag.Name), | ||
} | ||
|
||
err := ValidateConfig(&cfg) | ||
if err != nil { | ||
return Config{}, err | ||
} | ||
|
||
return cfg, nil | ||
} | ||
|
||
// ValidateConfig ensures additional constraints on the parsed configuration to | ||
// ensure that it is well-formed. | ||
func ValidateConfig(cfg *Config) error { | ||
// Sanity check log level. | ||
if cfg.LogLevel == "" { | ||
cfg.LogLevel = "debug" | ||
} | ||
|
||
_, err := log.LvlFromString(cfg.LogLevel) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Ensure the Sentry Data Source Name is set when using Sentry. | ||
if cfg.SentryEnable && cfg.SentryDsn == "" { | ||
return ErrSentryDSNNotSet | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package indexer_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
indexer "github.com/ethereum-optimism/optimism/go/indexer" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
var validateConfigTests = []struct { | ||
name string | ||
cfg indexer.Config | ||
expErr error | ||
}{ | ||
{ | ||
name: "bad log level", | ||
cfg: indexer.Config{ | ||
LogLevel: "unknown", | ||
}, | ||
expErr: fmt.Errorf("unknown level: unknown"), | ||
}, | ||
} | ||
|
||
// TestValidateConfig asserts the behavior of ValidateConfig by testing expected | ||
// error and success configurations. | ||
func TestValidateConfig(t *testing.T) { | ||
for _, test := range validateConfigTests { | ||
t.Run(test.name, func(t *testing.T) { | ||
err := indexer.ValidateConfig(&test.cfg) | ||
require.Equal(t, err, test.expErr) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"_format": "hh-sol-dbg-1", | ||
"buildInfo": "../../build-info/d8a0f286587dfbd9a9d1e4f1e98e7119.json" | ||
} |
Oops, something went wrong.