ethergo/submitter/config/config.go
// Package config provides a configuration struct and getters for the submitter.
//
// Config contains configuration for the submitter. It can be loaded from a YAML file.
// Chain-specific configuration items can be provided via the `Chains` map, which overrides the global config
// for each chain. If a chain-specific item is not provided, the global config is used.
package config
import (
"math/big"
"time"
"github.com/ethereum/go-ethereum/params"
)
// Config contains configuration for the submitter.
//
//go:generate go run github.com/vburenin/ifacemaker -f config.go -s Config -i IConfig -p config -o iconfig_generated.go -c "autogenerated file"
type Config struct {
// GlobalConfig stores the default configuration
ChainConfig `yaml:",inline"`
// Chains overrides the global config for each chain
Chains map[int]ChainConfig `yaml:"chains"`
// ReaperInterval is the interval at which scan for transactions to flush
ReaperInterval time.Duration `yaml:"reaper_interval"`
// MaxRecordAge is the maximum age of a record before it is flushed
MaxRecordAge time.Duration `yaml:"max_record_age"`
}
// ChainConfig contains configuration for a specific chain.
type ChainConfig struct {
// MaxBatchSize is the maximum number of transactions to send in a batch
// if this is zero, the default will be used. This field is ignored if batching is disabled.
MaxBatchSize int `yaml:"max_batch_size"`
// Batch is whether or not to batch transactions at the rpc level
DoNotBatch bool `yaml:"skip_batching"`
// MaxGasPrice is the maximum gas price to use for transactions
MaxGasPrice *big.Int `yaml:"max_gas_price"`
// MinGasPrice is the gas price that will be used if 0 is returned from the gas price oracle
MinGasPrice *big.Int `yaml:"min_gas_price"`
// BumpIntervalSeconds is the number of seconds to wait before bumping a transaction
BumpIntervalSeconds int `yaml:"bump_interval_seconds"`
// GasBumpPercentages is the percentage to bump the gas price by
// this is applied to the greatrer of the chainprice or the last price
GasBumpPercentage int `yaml:"gas_bump_percentage"`
// GasEstimate is the gas estimate to use for transactions
// if dynamic gas estimation is enabled, this is only used as a default if the estimate fails
GasEstimate uint64 `yaml:"gas_estimate"`
// DynamicGasEstimate is whether or not to use dynamic gas estimation
DynamicGasEstimate bool `yaml:"dynamic_gas_estimate"`
// SupportsEIP1559 is whether or not this chain supports EIP1559
SupportsEIP1559 bool `yaml:"supports_eip_1559"`
}
const (
// DefaultMaxBatchSize is the default maximum number of transactions to send in a batch.
DefaultMaxBatchSize = 10
// DefaultBumpIntervalSeconds is the default number of seconds to wait before bumping a transaction.
DefaultBumpIntervalSeconds = 30
// DefaultGasBumpPercentage is the default percentage to bump the gas price by.
// See: https://github.com/ethereum/go-ethereum/blob/8c5576b1ac89473c7ec15c9b03d1ca02e9499dcc/core/txpool/legacypool/legacypool.go#L146
DefaultGasBumpPercentage = 10
// DefaultGasEstimate is the default gas estimate to use for transactions.
DefaultGasEstimate = uint64(1200000)
)
// DefaultMaxPrice is the default max price of a tx.
var DefaultMaxPrice = big.NewInt(500 * params.GWei)
// DefaultMinGasPrice is the default min price of a tx.
var DefaultMinGasPrice = big.NewInt(0.01 * params.GWei)
// DefaultReaperInterval is the default interval at which to scan for transactions to flush.
var DefaultReaperInterval = time.Minute * 5
// DefaultMaxRecordAge is the default maximum age of a record before it is flushed.
var DefaultMaxRecordAge = time.Hour * 24 * 7
// note: there's probably a way to clean these getters up with generics, the real problem comes with the fact that
// that this would require the caller to override the entire struct, which is not ideal..
// GetReaperInterval returns the reaper interval.
func (c *Config) GetReaperInterval() time.Duration {
if c.ReaperInterval == 0 {
return DefaultReaperInterval
}
return c.ReaperInterval
}
// GetMaxRecordAge returns the maximum record age.
func (c *Config) GetMaxRecordAge() time.Duration {
if c.MaxRecordAge == 0 {
return DefaultMaxRecordAge
}
return c.MaxRecordAge
}
// GetMaxBatchSize returns the maximum number of transactions to send in a batch.
func (c *Config) GetMaxBatchSize(chainID int) int {
chainConfig, ok := c.Chains[chainID]
if ok && chainConfig.MaxBatchSize != 0 {
return chainConfig.MaxBatchSize
}
maxBatch := c.MaxBatchSize
if maxBatch == 0 {
return DefaultMaxBatchSize
}
return maxBatch
}
// GetBatch returns whether or not to batch transactions at the rpc level.
func (c *Config) GetBatch(chainID int) bool {
chainConfig, ok := c.Chains[chainID]
if ok {
return !chainConfig.DoNotBatch
}
return !c.DoNotBatch
}
// GetMaxGasPrice returns the maximum gas price to use for transactions.
func (c *Config) GetMaxGasPrice(chainID int) (maxPrice *big.Int) {
maxPrice = c.MaxGasPrice
chainConfig, ok := c.Chains[chainID]
if ok && chainConfig.MaxGasPrice != nil {
maxPrice = chainConfig.MaxGasPrice
}
if maxPrice == nil || maxPrice == big.NewInt(0) {
maxPrice = DefaultMaxPrice
}
return
}
// GetMinGasPrice returns the minimum gas price to use for transactions.
func (c *Config) GetMinGasPrice(chainID int) (minPrice *big.Int) {
minPrice = c.MinGasPrice
chainConfig, ok := c.Chains[chainID]
if ok && chainConfig.MinGasPrice != nil {
minPrice = chainConfig.MinGasPrice
}
if minPrice == nil || minPrice == big.NewInt(0) {
minPrice = DefaultMinGasPrice
}
return
}
// GetBumpInterval returns the number of seconds to wait before bumping a transaction
// TODO: test this method.
func (c *Config) GetBumpInterval(chainID int) time.Duration {
var bumpInterval int
chainConfig, ok := c.Chains[chainID]
if ok {
bumpInterval = chainConfig.BumpIntervalSeconds
}
// if bumpInterval is not set for the chain, use the global config
if bumpInterval == 0 {
bumpInterval = c.BumpIntervalSeconds
}
// if the bump interval isn't set at all, use the default
if bumpInterval == 0 {
bumpInterval = DefaultBumpIntervalSeconds
}
return time.Duration(bumpInterval) * time.Second
}
// GetGasBumpPercentage returns the percentage to bump the gas price by
// TODO: test this method.
func (c *Config) GetGasBumpPercentage(chainID int) (gasBumpPercentage int) {
chainConfig, ok := c.Chains[chainID]
if ok {
gasBumpPercentage = chainConfig.GasBumpPercentage
}
// if gasBumpPercentage is not set for the chain, use the global config
if gasBumpPercentage == 0 {
gasBumpPercentage = c.GasBumpPercentage
}
// if the gasBumpPercentage isn't set at all, use the default
if gasBumpPercentage == 0 {
gasBumpPercentage = DefaultGasBumpPercentage
}
return gasBumpPercentage
}
// GetGasEstimate returns the gas estimate to use for transactions
// TODO: test this method.
func (c *Config) GetGasEstimate(chainID int) (gasEstimate uint64) {
chainConfig, ok := c.Chains[chainID]
if ok {
gasEstimate = chainConfig.GasEstimate
}
// if gasBumpPercentage is not set for the chain, use the global config
if gasEstimate == 0 {
gasEstimate = c.GasEstimate
}
// if the gasBumpPercentage isn't set at all, use the default
if gasEstimate == 0 {
gasEstimate = DefaultGasEstimate
}
return gasEstimate
}
// GetDynamicGasEstimate returns whether or not to use dynamic gas estimation
// TODO: test this method.
func (c *Config) GetDynamicGasEstimate(chainID int) bool {
chainConfig, ok := c.Chains[chainID]
if ok {
return chainConfig.DynamicGasEstimate
}
return c.DynamicGasEstimate
}
// SupportsEIP1559 returns whether or not this chain supports EIP1559.
func (c *Config) SupportsEIP1559(chainID int) bool {
chainConfig, ok := c.Chains[chainID]
if ok {
return chainConfig.SupportsEIP1559
}
return c.ChainConfig.SupportsEIP1559
}
// SetGlobalMaxGasPrice is a helper function that sets the global gas price.
func (c *Config) SetGlobalMaxGasPrice(maxPrice *big.Int) {
c.MaxGasPrice = maxPrice
}
// SetMinGasPrice is a helper function that sets the base gas price.
func (c *Config) SetMinGasPrice(basePrice *big.Int) {
c.MinGasPrice = basePrice
}
// SetGlobalEIP1559Support is a helper function that sets the global EIP1559 support.
func (c *Config) SetGlobalEIP1559Support(supportsEIP1559 bool) {
c.ChainConfig.SupportsEIP1559 = supportsEIP1559
}
var _ IConfig = &Config{}