Commit 7f3dcaa7 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into 08-13-feat_indexer_Start_adding_ui_to_indexer_docker-compose

parents 6582ff2c 9b65d023
......@@ -43,7 +43,7 @@ require (
golang.org/x/term v0.11.0
golang.org/x/time v0.3.0
gorm.io/driver/postgres v1.5.2
gorm.io/gorm v1.25.2
gorm.io/gorm v1.25.3
)
require (
......
......@@ -1111,8 +1111,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
......
......@@ -3,12 +3,14 @@ package cli
import (
"context"
"fmt"
"strconv"
"github.com/ethereum-optimism/optimism/indexer"
"github.com/ethereum-optimism/optimism/indexer/api"
"github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/opio"
"github.com/ethereum/go-ethereum/params"
"github.com/urfave/cli/v2"
......@@ -23,17 +25,28 @@ type Cli struct {
}
func runIndexer(ctx *cli.Context) error {
logger := log.NewLogger(log.ReadCLIConfig(ctx))
logger := log.NewLogger(log.CLIConfig{
Level: "warn",
Color: false,
Format: "terminal",
})
configPath := ctx.String(ConfigFlag.Name)
cfg, err := config.LoadConfig(configPath)
cfg, err := config.LoadConfig(logger, configPath)
if err != nil {
logger.Error("failed to load config", "err", err)
return err
}
cfg.Logger = logger
indexer, err := indexer.NewIndexer(cfg)
logger = log.NewLogger(cfg.Logger)
db, err := database.NewDB(cfg.DB)
if err != nil {
return err
}
indexer, err := indexer.NewIndexer(cfg.Chain, cfg.RPCs, db, logger)
if err != nil {
return err
}
......@@ -51,17 +64,21 @@ func runApi(ctx *cli.Context) error {
logger := log.NewLogger(log.ReadCLIConfig(ctx))
configPath := ctx.String(ConfigFlag.Name)
cfg, err := config.LoadConfig(configPath)
cfg, err := config.LoadConfig(logger, configPath)
if err != nil {
logger.Error("failed to load config", "err", err)
return err
}
cfg.Logger = logger
fmt.Println(cfg)
db, err := database.NewDB(cfg.DB)
if err != nil {
logger.Crit("Failed to connect to database", "err", err)
}
server := api.NewApi(db.BridgeTransfers, logger)
// finish me
return err
return server.Listen(strconv.Itoa(cfg.API.Port))
}
var (
......@@ -81,7 +98,7 @@ func (c *Cli) Run(args []string) error {
}
func NewCli(GitVersion string, GitCommit string, GitDate string) *Cli {
flags := append([]cli.Flag{ConfigFlag}, log.CLIFlags("INDEXER")...)
flags := []cli.Flag{ConfigFlag}
app := &cli.App{
Version: fmt.Sprintf("%s-%s", GitVersion, params.VersionWithCommit(GitCommit, GitDate)),
Description: "An indexer of all optimism events with a serving api layer",
......
package config
import (
"fmt"
"os"
"reflect"
"github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/indexer/processor"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/common"
geth_log "github.com/ethereum/go-ethereum/log"
"github.com/joho/godotenv"
)
// in future presets can just be onchain config and fetched on initialization
// Config represents the `indexer.toml` file used to configure the indexer
type Config struct {
Chain ChainConfig
......@@ -17,14 +22,42 @@ type Config struct {
DB DBConfig
API APIConfig
Metrics MetricsConfig
Logger log.Logger `toml:"-"`
Logger log.CLIConfig
}
// fetch this via onchain config from RPCsConfig and remove from config in future
type L1Contracts struct {
OptimismPortal common.Address
L2OutputOracle common.Address
L1CrossDomainMessenger common.Address
L1StandardBridge common.Address
L1ERC721Bridge common.Address
// Some more contracts -- ProxyAdmin, SystemConfig, etcc
// Ignore the auxiliary contracts?
// Legacy contracts? We'll add this in to index the legacy chain.
// Remove afterwards?
}
func (c L1Contracts) ToSlice() []common.Address {
fields := reflect.VisibleFields(reflect.TypeOf(c))
v := reflect.ValueOf(c)
contracts := make([]common.Address, len(fields))
for i, field := range fields {
contracts[i] = (v.FieldByName(field.Name).Interface()).(common.Address)
}
return contracts
}
// ChainConfig configures of the chain being indexed
type ChainConfig struct {
// Configure known chains with the l2 chain id
Preset int
L1Contracts processor.L1Contracts
Preset int
// Configure custom chains via providing the L1Contract addresses
L1Contracts L1Contracts
}
// RPCsConfig configures the RPC urls
......@@ -55,32 +88,38 @@ type MetricsConfig struct {
}
// LoadConfig loads the `indexer.toml` config file from a given path
func LoadConfig(path string) (Config, error) {
func LoadConfig(logger geth_log.Logger, path string) (Config, error) {
if err := godotenv.Load(); err != nil {
log.Warn("Unable to load .env file", err)
log.Info("Continuing without .env file")
logger.Warn("Unable to load .env file", err)
logger.Info("Continuing without .env file")
} else {
log.Info("Loaded .env file")
logger.Info("Loaded .env file")
}
var conf Config
// Read the config file.
data, err := os.ReadFile(path)
if err != nil {
return conf, err
}
// Replace environment variables.
data = []byte(os.ExpandEnv(string(data)))
// Decode the TOML data.
if _, err := toml.Decode(string(data), &conf); err != nil {
log.Info("Failed to decode config file", "message", err)
logger.Info("Failed to decode config file", "message", err)
return conf, err
}
log.Debug("Loaded config file", conf)
if conf.Chain.Preset != 0 {
knownContracts, ok := presetL1Contracts[conf.Chain.Preset]
if ok {
conf.Chain.L1Contracts = knownContracts
} else {
return conf, fmt.Errorf("unknown preset: %d", conf.Chain.Preset)
}
}
logger.Debug("Loaded config file", conf)
return conf, nil
}
package config
import (
"fmt"
"os"
"testing"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
func TestLoadConfig(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
tmpfile, err := os.CreateTemp("", "test.toml")
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
......@@ -15,7 +20,7 @@ func TestLoadConfig(t *testing.T) {
testData := `
[chain]
preset = 1234
preset = 420
[rpcs]
l1-rpc = "https://l1.example.com"
......@@ -45,10 +50,15 @@ func TestLoadConfig(t *testing.T) {
err = tmpfile.Close()
require.NoError(t, err)
conf, err := LoadConfig(tmpfile.Name())
conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err)
require.Equal(t, conf.Chain.Preset, 1234)
require.Equal(t, conf.Chain.Preset, 420)
require.Equal(t, conf.Chain.L1Contracts.OptimismPortal.String(), presetL1Contracts[420].OptimismPortal.String())
require.Equal(t, conf.Chain.L1Contracts.L1CrossDomainMessenger.String(), presetL1Contracts[420].L1CrossDomainMessenger.String())
require.Equal(t, conf.Chain.L1Contracts.L1ERC721Bridge.String(), presetL1Contracts[420].L1ERC721Bridge.String())
require.Equal(t, conf.Chain.L1Contracts.L1StandardBridge.String(), presetL1Contracts[420].L1StandardBridge.String())
require.Equal(t, conf.Chain.L1Contracts.L2OutputOracle.String(), presetL1Contracts[420].L2OutputOracle.String())
require.Equal(t, conf.RPCs.L1RPC, "https://l1.example.com")
require.Equal(t, conf.RPCs.L2RPC, "https://l2.example.com")
require.Equal(t, conf.DB.Host, "127.0.0.1")
......@@ -61,3 +71,69 @@ func TestLoadConfig(t *testing.T) {
require.Equal(t, conf.Metrics.Host, "127.0.0.1")
require.Equal(t, conf.Metrics.Port, 7300)
}
func TestLoadConfig_WithoutPreset(t *testing.T) {
tmpfile, err := os.CreateTemp("", "test_without_preset.toml")
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
defer tmpfile.Close()
testData := `
[chain]
l1contracts = { OptimismPortal = "0x4205Fc579115071764c7423A4f12eDde41f106Ed", L2OutputOracle = "0x42097868233d1aa22e815a266982f2cf17685a27", L1CrossDomainMessenger = "0x420ce71c97B33Cc4729CF772ae268934F7ab5fA1", L1StandardBridge = "0x4209fc46f92E8a1c0deC1b1747d010903E884bE1", L1ERC721Bridge ="0x420749f83b81B301cAb5f48EB8516B986DAef23D" }
[rpcs]
l1-rpc = "https://l1.example.com"
l2-rpc = "https://l2.example.com"
`
data := []byte(testData)
err = os.WriteFile(tmpfile.Name(), data, 0644)
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
err = tmpfile.Close()
require.NoError(t, err)
logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err)
require.Equal(t, conf.Chain.L1Contracts.OptimismPortal.String(), common.HexToAddress("0x4205Fc579115071764c7423A4f12eDde41f106Ed").String())
require.Equal(t, conf.Chain.L1Contracts.L2OutputOracle.String(), common.HexToAddress("0x42097868233d1aa22e815a266982f2cf17685a27").String())
require.Equal(t, conf.Chain.L1Contracts.L1CrossDomainMessenger.String(), common.HexToAddress("0x420ce71c97B33Cc4729CF772ae268934F7ab5fA1").String())
require.Equal(t, conf.Chain.L1Contracts.L1StandardBridge.String(), common.HexToAddress("0x4209fc46f92E8a1c0deC1b1747d010903E884bE1").String())
require.Equal(t, conf.Chain.L1Contracts.L1ERC721Bridge.String(), common.HexToAddress("0x420749f83b81B301cAb5f48EB8516B986DAef23D").String())
require.Equal(t, conf.Chain.Preset, 0)
}
func TestLoadConfig_WithUnknownPreset(t *testing.T) {
tmpfile, err := os.CreateTemp("", "test_bad_preset.toml")
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
defer tmpfile.Close()
testData := `
[chain]
preset = 1234567890 # this preset doesn't exist
[rpcs]
l1-rpc = "https://l1.example.com"
l2-rpc = "https://l2.example.com"
`
data := []byte(testData)
err = os.WriteFile(tmpfile.Name(), data, 0644)
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
err = tmpfile.Close()
require.NoError(t, err)
logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name())
var faultyPreset = 1234567890
require.Equal(t, conf.Chain.Preset, faultyPreset)
require.Error(t, err)
require.Equal(t, fmt.Sprintf("unknown preset: %d", faultyPreset), err.Error())
}
package config
import (
"github.com/ethereum/go-ethereum/common"
)
// in future presets can just be onchain config and fetched on initialization
// Mapping of l2 chain ids to their preset chain configurations
var presetL1Contracts = map[int]L1Contracts{
// OP Mainnet
10: {
OptimismPortal: common.HexToAddress("0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"),
L2OutputOracle: common.HexToAddress("0xdfe97868233d1aa22e815a266982f2cf17685a27"),
L1CrossDomainMessenger: common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1"),
L1StandardBridge: common.HexToAddress("0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"),
L1ERC721Bridge: common.HexToAddress("0x5a7749f83b81B301cAb5f48EB8516B986DAef23D"),
},
// OP Goerli
420: {
OptimismPortal: common.HexToAddress("0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383"),
L2OutputOracle: common.HexToAddress("0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0"),
L1CrossDomainMessenger: common.HexToAddress("0x5086d1eEF304eb5284A0f6720f79403b4e9bE294"),
L1StandardBridge: common.HexToAddress("0x636Af16bf2f682dD3109e60102b8E1A089FedAa8"),
L1ERC721Bridge: common.HexToAddress("0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9"),
},
// Base Mainnet
8453: {
OptimismPortal: common.HexToAddress("0x49048044D57e1C92A77f79988d21Fa8fAF74E97e"),
L2OutputOracle: common.HexToAddress("0x56315b90c40730925ec5485cf004d835058518A0"),
L1CrossDomainMessenger: common.HexToAddress("0x866E82a600A1414e583f7F13623F1aC5d58b0Afa"),
L1StandardBridge: common.HexToAddress("0x3154Cf16ccdb4C6d922629664174b904d80F2C35"),
// FIXME update this to the correct address
L1ERC721Bridge: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
// Base Goerli
84531: {
OptimismPortal: common.HexToAddress("0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA"),
L2OutputOracle: common.HexToAddress("0x2A35891ff30313CcFa6CE88dcf3858bb075A2298"),
L1CrossDomainMessenger: common.HexToAddress("0x8e5693140eA606bcEB98761d9beB1BC87383706D"),
L1StandardBridge: common.HexToAddress("0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a"),
// FIXME update this to the correct address
L1ERC721Bridge: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
// Zora mainnet
7777777: {
OptimismPortal: common.HexToAddress("0x1a0ad011913A150f69f6A19DF447A0CfD9551054"),
L2OutputOracle: common.HexToAddress("0x9E6204F750cD866b299594e2aC9eA824E2e5f95c"),
L1CrossDomainMessenger: common.HexToAddress("0xdC40a14d9abd6F410226f1E6de71aE03441ca506"),
L1StandardBridge: common.HexToAddress("0x3e2Ea9B92B7E48A52296fD261dc26fd995284631"),
// FIXME update this to the correct address
L1ERC721Bridge: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
// Zora goerli
999: {
OptimismPortal: common.HexToAddress("0xDb9F51790365e7dc196e7D072728df39Be958ACe"),
L2OutputOracle: common.HexToAddress("0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00"),
L1CrossDomainMessenger: common.HexToAddress("0xD87342e16352D33170557A7dA1e5fB966a60FafC"),
L1StandardBridge: common.HexToAddress("0x7CC09AC2452D6555d5e0C213Ab9E2d44eFbFc956"),
// FIXME update this to the correct address
L1ERC721Bridge: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
}
......@@ -2,6 +2,9 @@
package database
import (
"fmt"
"github.com/ethereum-optimism/optimism/indexer/config"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
......@@ -17,7 +20,14 @@ type DB struct {
BridgeTransactions BridgeTransactionsDB
}
func NewDB(dsn string) (*DB, error) {
func NewDB(dbConfig config.DBConfig) (*DB, error) {
dsn := fmt.Sprintf("host=%s port=%d dbname=%s sslmode=disable", dbConfig.Host, dbConfig.Port, dbConfig.Name)
if dbConfig.User != "" {
dsn += fmt.Sprintf(" user=%s", dbConfig.User)
}
if dbConfig.Password != "" {
dsn += fmt.Sprintf(" password=%s", dbConfig.Password)
}
gorm, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
// The indexer will explicitly manage the transaction
// flow processing blocks
......
......@@ -13,10 +13,10 @@ import (
"github.com/ethereum-optimism/optimism/indexer"
"github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processor"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-node/testlog"
op_log "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
......@@ -59,7 +59,10 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
// Indexer Configuration and Start
indexerCfg := config.Config{
Logger: logger,
Logger: op_log.CLIConfig{
Level: "warn",
},
DB: config.DBConfig{
Host: "127.0.0.1",
Port: 5432,
......@@ -71,7 +74,7 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
L2RPC: opSys.Nodes["sequencer"].HTTPEndpoint(),
},
Chain: config.ChainConfig{
L1Contracts: processor.L1Contracts{
L1Contracts: config.L1Contracts{
OptimismPortal: opCfg.L1Deployments.OptimismPortalProxy,
L2OutputOracle: opCfg.L1Deployments.L2OutputOracleProxy,
L1CrossDomainMessenger: opCfg.L1Deployments.L1CrossDomainMessengerProxy,
......@@ -81,9 +84,14 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
},
}
db, err := database.NewDB(fmt.Sprintf("postgres://%s@localhost:5432/%s?sslmode=disable", dbUser, dbName))
db, err := database.NewDB(indexerCfg.DB)
require.NoError(t, err)
indexer, err := indexer.NewIndexer(indexerCfg)
indexer, err := indexer.NewIndexer(
indexerCfg.Chain,
indexerCfg.RPCs,
db,
logger,
)
require.NoError(t, err)
indexerStoppedCh := make(chan interface{}, 1)
......
......@@ -24,44 +24,31 @@ type Indexer struct {
}
// NewIndexer initializes an instance of the Indexer
func NewIndexer(cfg config.Config) (*Indexer, error) {
dsn := fmt.Sprintf("host=%s port=%d dbname=%s sslmode=disable", cfg.DB.Host, cfg.DB.Port, cfg.DB.Name)
if cfg.DB.User != "" {
dsn += fmt.Sprintf(" user=%s", cfg.DB.User)
}
if cfg.DB.Password != "" {
dsn += fmt.Sprintf(" password=%s", cfg.DB.Password)
}
db, err := database.NewDB(dsn)
if err != nil {
return nil, err
}
l1Contracts := cfg.Chain.L1Contracts
l1EthClient, err := node.DialEthClient(cfg.RPCs.L1RPC)
func NewIndexer(chainConfig config.ChainConfig, rpcsConfig config.RPCsConfig, db *database.DB, logger log.Logger) (*Indexer, error) {
l1Contracts := chainConfig.L1Contracts
l1EthClient, err := node.DialEthClient(rpcsConfig.L1RPC)
if err != nil {
return nil, err
}
l1Processor, err := processor.NewL1Processor(cfg.Logger, l1EthClient, db, l1Contracts)
l1Processor, err := processor.NewL1Processor(logger, l1EthClient, db, l1Contracts)
if err != nil {
return nil, err
}
// L2Processor (predeploys). Although most likely the right setting, make this configurable?
l2Contracts := processor.L2ContractPredeploys()
l2EthClient, err := node.DialEthClient(cfg.RPCs.L2RPC)
l2EthClient, err := node.DialEthClient(rpcsConfig.L2RPC)
if err != nil {
return nil, err
}
l2Processor, err := processor.NewL2Processor(cfg.Logger, l2EthClient, db, l2Contracts)
l2Processor, err := processor.NewL2Processor(logger, l2EthClient, db, l2Contracts)
if err != nil {
return nil, err
}
indexer := &Indexer{
db: db,
log: cfg.Logger,
log: logger,
L1Processor: l1Processor,
L2Processor: l2Processor,
}
......
# Chain configures l1 chain addresses
# Can configure them manually or use a preset l2 ChainId for known chains including OP Mainnet, OP Goerli, Base, Base Goerli, Zora, and Zora goerli
[chain]
# OP Goerli
preset = 420
[rpcs]
l1-rpc = "${INDEXER_RPC_URL_L1}"
l2-rpc = "${INDEXER_RPC_URL_L2}"
......@@ -20,3 +22,11 @@ port = 8080
host = "127.0.0.1"
port = 7300
[logger]
# Log level: trace, debug, info, warn, error, crit. Capitals are accepted too.
level = "info"
# Color the log output. Defaults to true if terminal is detected.
color = true
# Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty'
format = "terminal"
......@@ -6,8 +6,8 @@ import (
"errors"
"fmt"
"math/big"
"reflect"
"github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/node"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
......@@ -23,32 +23,6 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type L1Contracts struct {
OptimismPortal common.Address
L2OutputOracle common.Address
L1CrossDomainMessenger common.Address
L1StandardBridge common.Address
L1ERC721Bridge common.Address
// Some more contracts -- ProxyAdmin, SystemConfig, etcc
// Ignore the auxiliary contracts?
// Legacy contracts? We'll add this in to index the legacy chain.
// Remove afterwards?
}
func (c L1Contracts) ToSlice() []common.Address {
fields := reflect.VisibleFields(reflect.TypeOf(c))
v := reflect.ValueOf(c)
contracts := make([]common.Address, len(fields))
for i, field := range fields {
contracts[i] = (v.FieldByName(field.Name).Interface()).(common.Address)
}
return contracts
}
type checkpointAbi struct {
l2OutputOracle *abi.ABI
legacyStateCommitmentChain *abi.ABI
......@@ -58,7 +32,7 @@ type L1Processor struct {
processor
}
func NewL1Processor(logger log.Logger, ethClient node.EthClient, db *database.DB, l1Contracts L1Contracts) (*L1Processor, error) {
func NewL1Processor(logger log.Logger, ethClient node.EthClient, db *database.DB, l1Contracts config.L1Contracts) (*L1Processor, error) {
l1ProcessLog := logger.New("processor", "l1")
l1ProcessLog.Info("initializing processor")
......@@ -107,7 +81,7 @@ func NewL1Processor(logger log.Logger, ethClient node.EthClient, db *database.DB
return l1Processor, nil
}
func l1ProcessFn(processLog log.Logger, ethClient node.EthClient, l1Contracts L1Contracts, checkpointAbi checkpointAbi) ProcessFn {
func l1ProcessFn(processLog log.Logger, ethClient node.EthClient, l1Contracts config.L1Contracts, checkpointAbi checkpointAbi) ProcessFn {
rawEthClient := ethclient.NewClient(ethClient.RawRpcClient())
contractAddrs := l1Contracts.ToSlice()
......@@ -261,7 +235,7 @@ func l1ProcessFn(processLog log.Logger, ethClient node.EthClient, l1Contracts L1
}
}
func l1ProcessContractEventsBridgeTransactions(processLog log.Logger, db *database.DB, l1Contracts L1Contracts, events *ProcessedContractEvents) error {
func l1ProcessContractEventsBridgeTransactions(processLog log.Logger, db *database.DB, l1Contracts config.L1Contracts, events *ProcessedContractEvents) error {
// (1) Process New Deposits
portalDeposits, err := OptimismPortalTransactionDepositEvents(events)
if err != nil {
......@@ -294,6 +268,7 @@ func l1ProcessContractEventsBridgeTransactions(processLog log.Logger, db *databa
TransactionSourceHash: depositTx.SourceHash,
Tx: transactionDeposits[i].Tx,
TokenPair: database.TokenPair{
// TODO index eth token if it doesn't exist
L1TokenAddress: predeploys.LegacyERC20ETHAddr,
L2TokenAddress: predeploys.LegacyERC20ETHAddr,
},
......@@ -492,7 +467,8 @@ func l1ProcessContractEventsStandardBridge(processLog log.Logger, db *database.D
deposits[i] = &database.L1BridgeDeposit{
TransactionSourceHash: depositTx.SourceHash,
CrossDomainMessengerNonce: &database.U256{Int: initiatedBridgeEvent.CrossDomainMessengerNonce},
TokenPair: database.TokenPair{L1TokenAddress: initiatedBridgeEvent.LocalToken, L2TokenAddress: initiatedBridgeEvent.RemoteToken},
// TODO index the tokens pairs if they don't exist
TokenPair: database.TokenPair{L1TokenAddress: initiatedBridgeEvent.LocalToken, L2TokenAddress: initiatedBridgeEvent.RemoteToken},
Tx: database.Transaction{
FromAddress: initiatedBridgeEvent.From,
ToAddress: initiatedBridgeEvent.To,
......
......@@ -9,12 +9,12 @@
"dist/*"
],
"scripts": {
"start:balance-mon": "ts-node ./src/balance-mon/service.ts",
"start:wallet-mon": "ts-node ./src/wallet-mon/service.ts",
"start:drippie-mon": "ts-node ./src/drippie-mon/service.ts",
"start:wd-mon": "ts-node ./src/wd-mon/service.ts",
"start:fault-mon": "ts-node ./src/fault-mon/service.ts",
"start:replica-mon": "ts-node ./src/replica-mon/service.ts",
"start:balance-mon": "tsx ./src/balance-mon/service.ts",
"start:wallet-mon": "tsx ./src/wallet-mon/service.ts",
"start:drippie-mon": "tsx ./src/drippie-mon/service.ts",
"start:wd-mon": "tsx ./src/wd-mon/service.ts",
"start:fault-mon": "tsx ./src/fault-mon/service.ts",
"start:replica-mon": "tsx ./src/replica-mon/service.ts",
"test": "hardhat test",
"test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json",
"build": "tsc -p ./tsconfig.json",
......@@ -39,21 +39,22 @@
},
"dependencies": {
"@eth-optimism/common-ts": "0.8.3",
"@eth-optimism/contracts-periphery": "1.0.8",
"@eth-optimism/contracts-bedrock": "0.16.0",
"@eth-optimism/contracts-periphery": "1.0.8",
"@eth-optimism/core-utils": "0.12.2",
"@eth-optimism/sdk": "3.1.0",
"ethers": "^5.7.0",
"dotenv": "^16.1.4",
"@types/dateformat": "^5.0.0",
"chai-as-promised": "^7.1.1",
"dateformat": "^4.5.1"
"dateformat": "^4.5.1",
"dotenv": "^16.1.4",
"ethers": "^5.7.0"
},
"devDependencies": {
"@ethersproject/abstract-provider": "^5.7.0",
"@nomiclabs/hardhat-ethers": "^2.0.6",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"hardhat": "^2.9.6",
"ts-node": "^10.9.1"
"ts-node": "^10.9.1",
"tsx": "^3.12.7"
}
}
......@@ -48,7 +48,7 @@ Check the list of available metrics via `pnpm start --help`:
```sh
> pnpm start --help
$ ts-node ./src/service.ts --help
$ tsx ./src/service.ts --help
Usage: service [options]
Options:
......
......@@ -48,7 +48,7 @@
"morgan": "^1.10.0",
"pino": "^6.11.3",
"pino-multi-stream": "^5.3.0",
"pino-sentry": "^0.7.0",
"pino-sentry": "^0.14.0",
"prom-client": "^13.1.0"
},
"devDependencies": {
......
......@@ -156,7 +156,7 @@ export abstract class BaseServiceV2<
}
// Use commander as a way to communicate info about the service. We don't actually *use*
// commander for anything besides the ability to run `ts-node ./service.ts --help`.
// commander for anything besides the ability to run `tsx ./service.ts --help`.
const program = new Command().allowUnknownOption(true)
for (const [optionName, optionSpec] of Object.entries(params.optionsSpec)) {
// Skip options that are not meant to be used by the user.
......
......@@ -102,7 +102,7 @@ All test contracts and functions should be organized and named according to the
These guidelines are also encoded in a script which can be run with:
```
ts-node scripts/forge-test-names.ts
tsx scripts/forge-test-names.ts
```
_Note: This is a work in progress, not all test files are compliant with these guidelines._
......
......@@ -16,7 +16,7 @@
"prebuild": "./scripts/verify-foundry-install.sh",
"build:differential": "go build -o ./scripts/differential-testing/differential-testing ./scripts/differential-testing",
"build:fuzz": "(cd test-case-generator && go build ./cmd/fuzz.go)",
"autogen:invariant-docs": "ts-node scripts/invariant-doc-gen.ts",
"autogen:invariant-docs": "tsx scripts/invariant-doc-gen.ts",
"test": "pnpm build:differential && pnpm build:fuzz && forge test",
"coverage": "pnpm build:differential && pnpm build:fuzz && forge coverage",
"coverage:lcov": "pnpm build:differential && pnpm build:fuzz && forge coverage --report lcov",
......@@ -24,13 +24,13 @@
"storage-snapshot": "./scripts/storage-snapshot.sh",
"semver-lock": "forge script scripts/SemverLock.s.sol",
"validate-deploy-configs": "./scripts/validate-deploy-configs.sh",
"validate-spacers": "pnpm build && npx ts-node scripts/validate-spacers.ts",
"validate-spacers": "pnpm build && npx tsx scripts/validate-spacers.ts",
"slither": "./scripts/slither.sh",
"slither:triage": "TRIAGE_MODE=1 ./scripts/slither.sh",
"clean": "rm -rf ./artifacts ./forge-artifacts ./cache ./tsconfig.tsbuildinfo ./tsconfig.build.tsbuildinfo ./test-case-generator/fuzz ./scripts/differential-testing/differential-testing",
"preinstall": "npx only-allow pnpm",
"lint:ts:check": "eslint . --max-warnings=0",
"lint:forge-tests:check": "ts-node scripts/forge-test-names.ts",
"lint:forge-tests:check": "tsx scripts/forge-test-names.ts",
"lint:contracts:check": "pnpm lint:fix && git diff --exit-code",
"lint:check": "pnpm lint:contracts:check && pnpm lint:ts:check",
"lint:ts:fix": "eslint --fix .",
......@@ -39,9 +39,9 @@
"lint": "pnpm lint:fix && pnpm lint:check"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"ts-node": "^10.9.1",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"tsx": "^3.12.7",
"typescript": "^5.1.6"
}
}
......@@ -2,13 +2,16 @@ import fs from 'fs'
import path from 'path'
import { execSync } from 'child_process'
type Check = (parts: string[]) => boolean
type Checks = Array<{
check: Check
error: string
}>
/**
* Series of function name checks.
*/
const checks: Array<{
check: (parts: string[]) => boolean
error: string
}> = [
const checks: Checks = [
{
error: 'test name parts should be in camelCase',
check: (parts: string[]): boolean => {
......
......@@ -10,5 +10,6 @@ ignores: [
"eslint-config-prettier",
"eslint-plugin-prettier",
"chai",
"ts-node",
"typedoc"
]
......@@ -49,6 +49,7 @@
"isomorphic-fetch": "^3.0.0",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"ts-node": "^10.9.1",
"typedoc": "^0.22.13",
"viem": "^0.3.30",
"vitest": "^0.28.3",
......@@ -58,6 +59,10 @@
"@eth-optimism/contracts": "0.6.0",
"@eth-optimism/contracts-bedrock": "0.16.0",
"@eth-optimism/core-utils": "0.12.2",
"@types/chai": "^4.2.18",
"@types/chai-as-promised": "^7.1.4",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.0",
"lodash": "^4.17.21",
"merkletreejs": "^0.2.27",
"rlp": "^2.2.7"
......
......@@ -60,6 +60,22 @@ task('finalize-withdrawal', 'Finalize a withdrawal')
'OptimismPortalProxy'
)
if (Deployment__L1StandardBridgeProxy?.address === undefined) {
throw new Error('No L1StandardBridgeProxy deployment')
}
if (Deployment__L1CrossDomainMessengerProxy?.address === undefined) {
throw new Error('No L1CrossDomainMessengerProxy deployment')
}
if (Deployment__L2OutputOracleProxy?.address === undefined) {
throw new Error('No L2OutputOracleProxy deployment')
}
if (Deployment__OptimismPortalProxy?.address === undefined) {
throw new Error('No OptimismPortalProxy deployment')
}
const messenger = new CrossChainMessenger({
l1SignerOrProvider: signer,
l2SignerOrProvider: l2Signer,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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