-
Notifications
You must be signed in to change notification settings - Fork 265
feat(chainstate): Add indexer config #2491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
39e6a11
825abdc
f949cb1
537a241
b97e731
a83bd8c
965d2b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,177 @@ | ||||||||||||||||||||||
| package chainstate | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import ( | ||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||
| "slices" | ||||||||||||||||||||||
| "strconv" | ||||||||||||||||||||||
| "time" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| "github.com/Layr-Labs/eigenda/common/config" | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var _ config.DocumentedConfig = (*RootIndexerConfig)(nil) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // RootIndexerConfig is the root configuration for the chainstate indexer. | ||||||||||||||||||||||
| // It separates public and secret configuration for safety. | ||||||||||||||||||||||
| type RootIndexerConfig struct { | ||||||||||||||||||||||
| Config *IndexerConfig | ||||||||||||||||||||||
| Secret *IndexerSecretConfig | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var _ config.VerifiableConfig = (*IndexerConfig)(nil) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // IndexerConfig contains all public configuration for the chainstate indexer. | ||||||||||||||||||||||
| type IndexerConfig struct { | ||||||||||||||||||||||
| // EigenDADirectory contract address | ||||||||||||||||||||||
| EigenDADirectory string `docs:"required"` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Starting block number for indexing. If 0, starts from contract deployment block. | ||||||||||||||||||||||
| StartBlockNumber uint64 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Number of blocks to process in each batch during indexing. | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wouldn't this be the |
||||||||||||||||||||||
| BlockBatchSize uint64 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Interval between polling for new blocks on the chain. | ||||||||||||||||||||||
| PollInterval time.Duration | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Path to JSON file for persisting indexed state to disk. | ||||||||||||||||||||||
| PersistencePath string `docs:"required"` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Interval for persisting state snapshots to disk. | ||||||||||||||||||||||
| PersistInterval time.Duration | ||||||||||||||||||||||
|
Comment on lines
+37
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. knit:
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Port for the HTTP API server that serves indexed data queries. | ||||||||||||||||||||||
| HTTPPort string `docs:"required"` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // The lowest log level that will be output. Accepted options are "debug", "info", "warn", "error" | ||||||||||||||||||||||
| LogLevel string | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // The format of the log file. Accepted options are 'json' and 'text' | ||||||||||||||||||||||
| LogFormat string | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var _ config.VerifiableConfig = (*IndexerSecretConfig)(nil) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // IndexerSecretConfig contains sensitive configuration values. | ||||||||||||||||||||||
| type IndexerSecretConfig struct { | ||||||||||||||||||||||
| // Ethereum RPC endpoint URLs for connecting to the blockchain. | ||||||||||||||||||||||
| EthRpcUrls []string `docs:"required"` | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // DefaultIndexerConfig returns a default configuration with sensible values. | ||||||||||||||||||||||
| func DefaultIndexerConfig() *IndexerConfig { | ||||||||||||||||||||||
| return &IndexerConfig{ | ||||||||||||||||||||||
| StartBlockNumber: 0, | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there any reason we'd default |
||||||||||||||||||||||
| BlockBatchSize: 1000, | ||||||||||||||||||||||
| PollInterval: 12 * time.Second, | ||||||||||||||||||||||
| PersistInterval: 30 * time.Second, | ||||||||||||||||||||||
| HTTPPort: "8080", | ||||||||||||||||||||||
| LogLevel: "info", | ||||||||||||||||||||||
| LogFormat: "json", | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // DefaultRootIndexerConfig returns a default root configuration. | ||||||||||||||||||||||
| func DefaultRootIndexerConfig() *RootIndexerConfig { | ||||||||||||||||||||||
| return &RootIndexerConfig{ | ||||||||||||||||||||||
| Config: DefaultIndexerConfig(), | ||||||||||||||||||||||
| Secret: &IndexerSecretConfig{}, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetName returns the name of this service for documentation. | ||||||||||||||||||||||
| func (c *IndexerConfig) GetName() string { | ||||||||||||||||||||||
| return "ChainStateIndexer" | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetEnvVarPrefix returns the environment variable prefix for this service. | ||||||||||||||||||||||
| func (c *IndexerConfig) GetEnvVarPrefix() string { | ||||||||||||||||||||||
| return "CHAINSTATE_INDEXER" | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetPackagePaths returns the package paths to scan for documentation. | ||||||||||||||||||||||
| func (c *IndexerConfig) GetPackagePaths() []string { | ||||||||||||||||||||||
| return []string{ | ||||||||||||||||||||||
| "github.com/Layr-Labs/eigenda/chainstate", | ||||||||||||||||||||||
iquidus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| "github.com/Layr-Labs/eigenda/common/config", | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Verify validates the configuration and returns an error if invalid. | ||||||||||||||||||||||
| func (c *IndexerConfig) Verify() error { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we add a check for this |
||||||||||||||||||||||
| if c.EigenDADirectory == "" { | ||||||||||||||||||||||
| return fmt.Errorf("EigenDA directory address is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.PersistencePath == "" { | ||||||||||||||||||||||
| return fmt.Errorf("persistence path is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.HTTPPort == "" { | ||||||||||||||||||||||
dmanc marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| return fmt.Errorf("HTTP port is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| port, err := strconv.Atoi(c.HTTPPort) | ||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||
| return fmt.Errorf("HTTP port must be a valid integer: %w", err) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if port < 1 || port > 65535 { | ||||||||||||||||||||||
| return fmt.Errorf("HTTP port must be between 1 and 65535, got %d", port) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.BlockBatchSize <= 0 { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there's some relationship here between |
||||||||||||||||||||||
| return fmt.Errorf("block batch size must be greater than 0") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.PollInterval <= 0 { | ||||||||||||||||||||||
| return fmt.Errorf("poll interval must be greater than 0") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.PersistInterval <= 0 { | ||||||||||||||||||||||
| return fmt.Errorf("persist interval must be greater than 0") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
iquidus marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| if c.LogLevel != "debug" && c.LogLevel != "info" && c.LogLevel != "warn" && c.LogLevel != "error" { | ||||||||||||||||||||||
| return fmt.Errorf("invalid log level %q, accepted values: debug, info, warn, error", c.LogLevel) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.LogFormat != "json" && c.LogFormat != "text" { | ||||||||||||||||||||||
| return fmt.Errorf("invalid log format %q, accepted values: json, text", c.LogFormat) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Verify validates the secret configuration. | ||||||||||||||||||||||
| func (c *IndexerSecretConfig) Verify() error { | ||||||||||||||||||||||
| if len(c.EthRpcUrls) == 0 { | ||||||||||||||||||||||
| return fmt.Errorf("at least one Ethereum RPC URL is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if slices.Contains(c.EthRpcUrls, "") { | ||||||||||||||||||||||
| return fmt.Errorf("Ethereum RPC URL can not be an empty string") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetName returns the name of this service for documentation. | ||||||||||||||||||||||
| func (c *RootIndexerConfig) GetName() string { | ||||||||||||||||||||||
| return c.Config.GetName() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetEnvVarPrefix returns the environment variable prefix for this service. | ||||||||||||||||||||||
| func (c *RootIndexerConfig) GetEnvVarPrefix() string { | ||||||||||||||||||||||
| return c.Config.GetEnvVarPrefix() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // GetPackagePaths returns the package paths to scan for documentation. | ||||||||||||||||||||||
| func (c *RootIndexerConfig) GetPackagePaths() []string { | ||||||||||||||||||||||
| return c.Config.GetPackagePaths() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Verify validates the root configuration. | ||||||||||||||||||||||
| func (c *RootIndexerConfig) Verify() error { | ||||||||||||||||||||||
| if c.Config == nil { | ||||||||||||||||||||||
| return fmt.Errorf("config is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.Secret == nil { | ||||||||||||||||||||||
| return fmt.Errorf("secret config is required") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if err := c.Config.Verify(); err != nil { | ||||||||||||||||||||||
| return fmt.Errorf("config validation failed: %w", err) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if err := c.Secret.Verify(); err != nil { | ||||||||||||||||||||||
| return fmt.Errorf("secret config validation failed: %w", err) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.