Commit 912a3fa3 authored by Will Cory's avatar Will Cory

fix(indexer): Fix config usage make config deps more explicit

parent db0e18c9
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/ethereum-optimism/optimism/indexer" "github.com/ethereum-optimism/optimism/indexer"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum-optimism/optimism/op-service/opio"
...@@ -23,17 +24,28 @@ type Cli struct { ...@@ -23,17 +24,28 @@ type Cli struct {
} }
func runIndexer(ctx *cli.Context) error { 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) configPath := ctx.String(ConfigFlag.Name)
cfg, err := config.LoadConfig(configPath) cfg, err := config.LoadConfig(logger, configPath)
if err != nil { if err != nil {
logger.Error("failed to load config", "err", err) logger.Error("failed to load config", "err", err)
return err return err
} }
cfg.Logger = logger logger = log.NewLogger(cfg.Logger)
indexer, err := indexer.NewIndexer(cfg)
db, err := database.NewDB(cfg.DB)
if err != nil {
return err
}
indexer, err := indexer.NewIndexer(cfg.Chain, cfg.RPCs, db, logger)
if err != nil { if err != nil {
return err return err
} }
...@@ -51,13 +63,12 @@ func runApi(ctx *cli.Context) error { ...@@ -51,13 +63,12 @@ func runApi(ctx *cli.Context) error {
logger := log.NewLogger(log.ReadCLIConfig(ctx)) logger := log.NewLogger(log.ReadCLIConfig(ctx))
configPath := ctx.String(ConfigFlag.Name) configPath := ctx.String(ConfigFlag.Name)
cfg, err := config.LoadConfig(configPath) cfg, err := config.LoadConfig(logger, configPath)
if err != nil { if err != nil {
logger.Error("failed to load config", "err", err) logger.Error("failed to load config", "err", err)
return err return err
} }
cfg.Logger = logger
fmt.Println(cfg) fmt.Println(cfg)
// finish me // finish me
......
...@@ -2,11 +2,13 @@ package config ...@@ -2,11 +2,13 @@ package config
import ( import (
"os" "os"
"reflect"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/ethereum-optimism/optimism/indexer/processor" "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/common"
geth_log "github.com/ethereum/go-ethereum/log"
"github.com/joho/godotenv" "github.com/joho/godotenv"
) )
...@@ -17,14 +19,41 @@ type Config struct { ...@@ -17,14 +19,41 @@ type Config struct {
DB DBConfig DB DBConfig
API APIConfig API APIConfig
Metrics MetricsConfig 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 // ChainConfig configures of the chain being indexed
type ChainConfig struct { type ChainConfig struct {
// Configure known chains with the l2 chain id // Configure known chains with the l2 chain id
Preset int Preset int
L1Contracts processor.L1Contracts L1Contracts L1Contracts
} }
// RPCsConfig configures the RPC urls // RPCsConfig configures the RPC urls
...@@ -55,12 +84,12 @@ type MetricsConfig struct { ...@@ -55,12 +84,12 @@ type MetricsConfig struct {
} }
// LoadConfig loads the `indexer.toml` config file from a given path // 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 { if err := godotenv.Load(); err != nil {
log.Warn("Unable to load .env file", err) logger.Warn("Unable to load .env file", err)
log.Info("Continuing without .env file") logger.Info("Continuing without .env file")
} else { } else {
log.Info("Loaded .env file") logger.Info("Loaded .env file")
} }
var conf Config var conf Config
...@@ -76,11 +105,11 @@ func LoadConfig(path string) (Config, error) { ...@@ -76,11 +105,11 @@ func LoadConfig(path string) (Config, error) {
// Decode the TOML data. // Decode the TOML data.
if _, err := toml.Decode(string(data), &conf); err != nil { 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 return conf, err
} }
log.Debug("Loaded config file", conf) logger.Debug("Loaded config file", conf)
return conf, nil return conf, nil
} }
...@@ -4,10 +4,13 @@ import ( ...@@ -4,10 +4,13 @@ import (
"os" "os"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestLoadConfig(t *testing.T) { func TestLoadConfig(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
tmpfile, err := os.CreateTemp("", "test.toml") tmpfile, err := os.CreateTemp("", "test.toml")
require.NoError(t, err) require.NoError(t, err)
defer os.Remove(tmpfile.Name()) defer os.Remove(tmpfile.Name())
...@@ -45,7 +48,7 @@ func TestLoadConfig(t *testing.T) { ...@@ -45,7 +48,7 @@ func TestLoadConfig(t *testing.T) {
err = tmpfile.Close() err = tmpfile.Close()
require.NoError(t, err) require.NoError(t, err)
conf, err := LoadConfig(tmpfile.Name()) conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, conf.Chain.Preset, 1234) require.Equal(t, conf.Chain.Preset, 1234)
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
package database package database
import ( import (
"fmt"
"github.com/ethereum-optimism/optimism/indexer/config"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
...@@ -17,7 +20,14 @@ type DB struct { ...@@ -17,7 +20,14 @@ type DB struct {
BridgeTransactions BridgeTransactionsDB 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{ gorm, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
// The indexer will explicitly manage the transaction // The indexer will explicitly manage the transaction
// flow processing blocks // flow processing blocks
......
...@@ -13,10 +13,10 @@ import ( ...@@ -13,10 +13,10 @@ import (
"github.com/ethereum-optimism/optimism/indexer" "github.com/ethereum-optimism/optimism/indexer"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processor"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e" op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-node/testlog" "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/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -59,7 +59,10 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { ...@@ -59,7 +59,10 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
// Indexer Configuration and Start // Indexer Configuration and Start
indexerCfg := config.Config{ indexerCfg := config.Config{
Logger: logger,
Logger: op_log.CLIConfig{
Level: "warn",
},
DB: config.DBConfig{ DB: config.DBConfig{
Host: "127.0.0.1", Host: "127.0.0.1",
Port: 5432, Port: 5432,
...@@ -71,7 +74,7 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { ...@@ -71,7 +74,7 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
L2RPC: opSys.Nodes["sequencer"].HTTPEndpoint(), L2RPC: opSys.Nodes["sequencer"].HTTPEndpoint(),
}, },
Chain: config.ChainConfig{ Chain: config.ChainConfig{
L1Contracts: processor.L1Contracts{ L1Contracts: config.L1Contracts{
OptimismPortal: opCfg.L1Deployments.OptimismPortalProxy, OptimismPortal: opCfg.L1Deployments.OptimismPortalProxy,
L2OutputOracle: opCfg.L1Deployments.L2OutputOracleProxy, L2OutputOracle: opCfg.L1Deployments.L2OutputOracleProxy,
L1CrossDomainMessenger: opCfg.L1Deployments.L1CrossDomainMessengerProxy, L1CrossDomainMessenger: opCfg.L1Deployments.L1CrossDomainMessengerProxy,
...@@ -81,9 +84,14 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { ...@@ -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) require.NoError(t, err)
indexer, err := indexer.NewIndexer(indexerCfg) indexer, err := indexer.NewIndexer(
indexerCfg.Chain,
indexerCfg.RPCs,
db,
logger,
)
require.NoError(t, err) require.NoError(t, err)
indexerStoppedCh := make(chan interface{}, 1) indexerStoppedCh := make(chan interface{}, 1)
......
...@@ -24,44 +24,31 @@ type Indexer struct { ...@@ -24,44 +24,31 @@ type Indexer struct {
} }
// NewIndexer initializes an instance of the Indexer // NewIndexer initializes an instance of the Indexer
func NewIndexer(cfg config.Config) (*Indexer, error) { func NewIndexer(chainConfig config.ChainConfig, rpcsConfig config.RPCsConfig, db *database.DB, logger log.Logger) (*Indexer, error) {
dsn := fmt.Sprintf("host=%s port=%d dbname=%s sslmode=disable", cfg.DB.Host, cfg.DB.Port, cfg.DB.Name) l1Contracts := chainConfig.L1Contracts
if cfg.DB.User != "" { l1EthClient, err := node.DialEthClient(rpcsConfig.L1RPC)
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)
if err != nil { if err != nil {
return nil, err return nil, err
} }
l1Processor, err := processor.NewL1Processor(cfg.Logger, l1EthClient, db, l1Contracts) l1Processor, err := processor.NewL1Processor(logger, l1EthClient, db, l1Contracts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// L2Processor (predeploys). Although most likely the right setting, make this configurable? // L2Processor (predeploys). Although most likely the right setting, make this configurable?
l2Contracts := processor.L2ContractPredeploys() l2Contracts := processor.L2ContractPredeploys()
l2EthClient, err := node.DialEthClient(cfg.RPCs.L2RPC) l2EthClient, err := node.DialEthClient(rpcsConfig.L2RPC)
if err != nil { if err != nil {
return nil, err return nil, err
} }
l2Processor, err := processor.NewL2Processor(cfg.Logger, l2EthClient, db, l2Contracts) l2Processor, err := processor.NewL2Processor(logger, l2EthClient, db, l2Contracts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
indexer := &Indexer{ indexer := &Indexer{
db: db, db: db,
log: cfg.Logger, log: logger,
L1Processor: l1Processor, L1Processor: l1Processor,
L2Processor: l2Processor, L2Processor: l2Processor,
} }
......
...@@ -6,8 +6,8 @@ import ( ...@@ -6,8 +6,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"reflect"
"github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/indexer/node"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
...@@ -23,32 +23,6 @@ import ( ...@@ -23,32 +23,6 @@ import (
"github.com/ethereum/go-ethereum/log" "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 { type checkpointAbi struct {
l2OutputOracle *abi.ABI l2OutputOracle *abi.ABI
legacyStateCommitmentChain *abi.ABI legacyStateCommitmentChain *abi.ABI
...@@ -58,7 +32,7 @@ type L1Processor struct { ...@@ -58,7 +32,7 @@ type L1Processor struct {
processor 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 := logger.New("processor", "l1")
l1ProcessLog.Info("initializing processor") l1ProcessLog.Info("initializing processor")
...@@ -107,7 +81,7 @@ func NewL1Processor(logger log.Logger, ethClient node.EthClient, db *database.DB ...@@ -107,7 +81,7 @@ func NewL1Processor(logger log.Logger, ethClient node.EthClient, db *database.DB
return l1Processor, nil 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()) rawEthClient := ethclient.NewClient(ethClient.RawRpcClient())
contractAddrs := l1Contracts.ToSlice() contractAddrs := l1Contracts.ToSlice()
...@@ -261,7 +235,7 @@ func l1ProcessFn(processLog log.Logger, ethClient node.EthClient, l1Contracts L1 ...@@ -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 // (1) Process New Deposits
portalDeposits, err := OptimismPortalTransactionDepositEvents(events) portalDeposits, err := OptimismPortalTransactionDepositEvents(events)
if err != nil { if err != nil {
...@@ -294,6 +268,7 @@ func l1ProcessContractEventsBridgeTransactions(processLog log.Logger, db *databa ...@@ -294,6 +268,7 @@ func l1ProcessContractEventsBridgeTransactions(processLog log.Logger, db *databa
TransactionSourceHash: depositTx.SourceHash, TransactionSourceHash: depositTx.SourceHash,
Tx: transactionDeposits[i].Tx, Tx: transactionDeposits[i].Tx,
TokenPair: database.TokenPair{ TokenPair: database.TokenPair{
// TODO index eth token if it doesn't exist
L1TokenAddress: predeploys.LegacyERC20ETHAddr, L1TokenAddress: predeploys.LegacyERC20ETHAddr,
L2TokenAddress: predeploys.LegacyERC20ETHAddr, L2TokenAddress: predeploys.LegacyERC20ETHAddr,
}, },
...@@ -492,7 +467,8 @@ func l1ProcessContractEventsStandardBridge(processLog log.Logger, db *database.D ...@@ -492,7 +467,8 @@ func l1ProcessContractEventsStandardBridge(processLog log.Logger, db *database.D
deposits[i] = &database.L1BridgeDeposit{ deposits[i] = &database.L1BridgeDeposit{
TransactionSourceHash: depositTx.SourceHash, TransactionSourceHash: depositTx.SourceHash,
CrossDomainMessengerNonce: &database.U256{Int: initiatedBridgeEvent.CrossDomainMessengerNonce}, 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{ Tx: database.Transaction{
FromAddress: initiatedBridgeEvent.From, FromAddress: initiatedBridgeEvent.From,
ToAddress: initiatedBridgeEvent.To, ToAddress: initiatedBridgeEvent.To,
......
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