diff --git a/packages/eventindexer/cmd/flags/common.go b/packages/eventindexer/cmd/flags/common.go index a9a1a258fd5..4b3f0056a47 100644 --- a/packages/eventindexer/cmd/flags/common.go +++ b/packages/eventindexer/cmd/flags/common.go @@ -5,10 +5,9 @@ import ( ) var ( - commonCategory = "COMMON" - indexerCategory = "INDEXER" - generatorCategory = "GENERATOR" - txmgrCategory = "TX_MANAGER" + commonCategory = "COMMON" + indexerCategory = "INDEXER" + txmgrCategory = "TX_MANAGER" ) var ( diff --git a/packages/eventindexer/cmd/flags/generator.go b/packages/eventindexer/cmd/flags/generator.go deleted file mode 100644 index 9f9f4988ee0..00000000000 --- a/packages/eventindexer/cmd/flags/generator.go +++ /dev/null @@ -1,24 +0,0 @@ -package flags - -import "github.com/urfave/cli/v2" - -var ( - GenesisDate = &cli.StringFlag{ - Name: "genesisDate", - Usage: "Genesis date to start generating data from, YYYY-MM-DD", - Required: true, - Category: generatorCategory, - EnvVars: []string{"GENESIS_DATE"}, - } - Regenerate = &cli.StringFlag{ - Name: "regenerate", - Usage: "True to delete all existing data and regenerate from genesis, false to not", - Required: false, - Category: generatorCategory, - EnvVars: []string{"REGENERATE"}, - } -) -var GeneratorFlags = MergeFlags(CommonFlags, []cli.Flag{ - GenesisDate, - Regenerate, -}) diff --git a/packages/eventindexer/cmd/main.go b/packages/eventindexer/cmd/main.go index fac9c636791..f8749ba109a 100644 --- a/packages/eventindexer/cmd/main.go +++ b/packages/eventindexer/cmd/main.go @@ -9,7 +9,6 @@ import ( "github.com/taikoxyz/taiko-mono/packages/eventindexer/api" "github.com/taikoxyz/taiko-mono/packages/eventindexer/cmd/flags" "github.com/taikoxyz/taiko-mono/packages/eventindexer/cmd/utils" - "github.com/taikoxyz/taiko-mono/packages/eventindexer/generator" "github.com/taikoxyz/taiko-mono/packages/eventindexer/indexer" "github.com/urfave/cli/v2" ) @@ -51,13 +50,6 @@ func main() { Description: "Taiko indexer software", Action: utils.SubcommandAction(new(indexer.Indexer)), }, - { - Name: "generator", - Flags: flags.GeneratorFlags, - Usage: "Starts the generator software", - Description: "Taiko time-series data generator", - Action: utils.SubcommandAction(new(generator.Generator)), - }, } if err := app.Run(os.Args); err != nil { diff --git a/packages/eventindexer/generator/config.go b/packages/eventindexer/generator/config.go deleted file mode 100644 index 819a11c7df2..00000000000 --- a/packages/eventindexer/generator/config.go +++ /dev/null @@ -1,70 +0,0 @@ -package generator - -import ( - "time" - - "github.com/urfave/cli/v2" - "gorm.io/driver/mysql" - "gorm.io/gorm" - "gorm.io/gorm/logger" - - "github.com/taikoxyz/taiko-mono/packages/eventindexer/cmd/flags" - "github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/db" -) - -type Config struct { - // db configs - DatabaseUsername string - DatabasePassword string - DatabaseName string - DatabaseHost string - DatabaseMaxIdleConns uint64 - DatabaseMaxOpenConns uint64 - DatabaseMaxConnLifetime uint64 - MetricsHTTPPort uint64 - GenesisDate time.Time - Regenerate bool - OpenDBFunc func() (db.DB, error) -} - -// NewConfigFromCliContext creates a new config instance from command line flags. -func NewConfigFromCliContext(c *cli.Context) (*Config, error) { - date, err := time.Parse("2006-01-02", c.String(flags.GenesisDate.Name)) - if err != nil { - return nil, err - } - - return &Config{ - DatabaseUsername: c.String(flags.DatabaseUsername.Name), - DatabasePassword: c.String(flags.DatabasePassword.Name), - DatabaseName: c.String(flags.DatabaseName.Name), - DatabaseHost: c.String(flags.DatabaseHost.Name), - DatabaseMaxIdleConns: c.Uint64(flags.DatabaseMaxIdleConns.Name), - DatabaseMaxOpenConns: c.Uint64(flags.DatabaseMaxOpenConns.Name), - DatabaseMaxConnLifetime: c.Uint64(flags.DatabaseConnMaxLifetime.Name), - MetricsHTTPPort: c.Uint64(flags.MetricsHTTPPort.Name), - GenesisDate: date, - Regenerate: c.Bool(flags.Regenerate.Name), - OpenDBFunc: func() (db.DB, error) { - return db.OpenDBConnection(db.DBConnectionOpts{ - Name: c.String(flags.DatabaseUsername.Name), - Password: c.String(flags.DatabasePassword.Name), - Database: c.String(flags.DatabaseName.Name), - Host: c.String(flags.DatabaseHost.Name), - MaxIdleConns: c.Uint64(flags.DatabaseMaxIdleConns.Name), - MaxOpenConns: c.Uint64(flags.DatabaseMaxOpenConns.Name), - MaxConnLifetime: c.Uint64(flags.DatabaseConnMaxLifetime.Name), - OpenFunc: func(dsn string) (db.DB, error) { - gormDB, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Silent), - }) - if err != nil { - return nil, err - } - - return db.New(gormDB), nil - }, - }) - }, - }, nil -} diff --git a/packages/eventindexer/generator/config_test.go b/packages/eventindexer/generator/config_test.go deleted file mode 100644 index 83be7c9beb4..00000000000 --- a/packages/eventindexer/generator/config_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package generator - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/urfave/cli/v2" - - "github.com/taikoxyz/taiko-mono/packages/eventindexer/cmd/flags" - "github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/db" -) - -func setupApp() *cli.App { - app := cli.NewApp() - app.Flags = flags.GeneratorFlags - app.Action = func(ctx *cli.Context) error { - _, err := NewConfigFromCliContext(ctx) - return err - } - - return app -} - -func TestNewConfigFromCliContext(t *testing.T) { - app := setupApp() - - app.Action = func(ctx *cli.Context) error { - c, err := NewConfigFromCliContext(ctx) - - assert.Nil(t, err) - assert.Equal(t, "dbuser", c.DatabaseUsername) - assert.Equal(t, "dbpass", c.DatabasePassword) - assert.Equal(t, "dbname", c.DatabaseName) - assert.Equal(t, "dbhost", c.DatabaseHost) - assert.Equal(t, true, c.Regenerate) - - wantTime, _ := time.Parse("2006-01-02", "2023-07-07") - assert.Equal(t, wantTime, c.GenesisDate) - - c.OpenDBFunc = func() (db.DB, error) { - return nil, nil - } - - assert.Nil(t, InitFromConfig(context.Background(), new(Generator), c)) - - return err - } - - assert.Nil(t, app.Run([]string{ - "TestNewConfigFromCliContext", - "--" + flags.DatabaseUsername.Name, "dbuser", - "--" + flags.DatabasePassword.Name, "dbpass", - "--" + flags.DatabaseHost.Name, "dbhost", - "--" + flags.DatabaseName.Name, "dbname", - "--" + flags.GenesisDate.Name, "2023-07-07", - "--" + flags.Regenerate.Name, "true", - })) -} diff --git a/packages/eventindexer/generator/generator.go b/packages/eventindexer/generator/generator.go deleted file mode 100644 index e4e5f4d1743..00000000000 --- a/packages/eventindexer/generator/generator.go +++ /dev/null @@ -1,654 +0,0 @@ -package generator - -import ( - "context" - "errors" - "log/slog" - "os" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/shopspring/decimal" - "github.com/urfave/cli/v2" - "gorm.io/gorm" - - "github.com/taikoxyz/taiko-mono/packages/eventindexer" - "github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/db" - "github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/tasks" -) - -var ( - ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") -) - -// Generator is a subcommand which is intended to be run on an interval, like -// a cronjob, to parse the indexed data from the database, and generate -// time series data that can easily be displayed via charting libraries. -type Generator struct { - db db.DB - genesisDate time.Time - regenerate bool -} - -func (g *Generator) InitFromCli(ctx context.Context, c *cli.Context) error { - config, err := NewConfigFromCliContext(c) - if err != nil { - return err - } - - return InitFromConfig(ctx, g, config) -} - -func InitFromConfig(ctx context.Context, g *Generator, cfg *Config) error { - db, err := cfg.OpenDBFunc() - if err != nil { - return err - } - - g.db = db - g.genesisDate = cfg.GenesisDate - g.regenerate = cfg.Regenerate - - return nil -} - -func (g *Generator) Name() string { - return "generator" -} - -func (g *Generator) Start() error { - if g.regenerate { - slog.Info("regenerating, deleting existing data") - - if err := g.deleteTimeSeriesData(context.Background()); err != nil { - return err - } - } - - slog.Info("generating time series data") - - if err := g.generateTimeSeriesData(context.Background()); err != nil { - return err - } - - os.Exit(0) - - return nil -} - -func (g *Generator) Close(ctx context.Context) { - sqlDB, err := g.db.DB() - if err != nil { - slog.Error("error getting sqldb when closing generator", "err", err.Error()) - } - - if err := sqlDB.Close(); err != nil { - slog.Error("error closing sqlbd connection", "err", err.Error()) - } -} - -func (g *Generator) deleteTimeSeriesData(ctx context.Context) error { - deleteStmt := "DELETE FROM time_series_data;" - if err := g.db.GormDB().Exec(deleteStmt).Error; err != nil { - return err - } - - return nil -} - -// generateTimeSeriesData iterates over each task and generates time series data. -func (g *Generator) generateTimeSeriesData(ctx context.Context) error { - for _, task := range tasks.Tasks { - if err := g.generateByTask(ctx, task); err != nil { - slog.Error("error generating for task", "task", task, "error", err.Error()) - return err - } - } - - return nil -} - -// generateByTask generates time series data for each day in between the current date -// and the most recently generated time series data, for the given task. -func (g *Generator) generateByTask(ctx context.Context, task string) error { - slog.Info("generating for task", "task", task) - - startingDate, err := g.getStartingDateByTask(ctx, task) - if err != nil { - return err - } - - currentDate := g.getCurrentDate() - if startingDate.Compare(currentDate) == 0 { - slog.Info( - "data already generated up-to-date for task", - "task", task, - "date", startingDate.Format("2006-01-02"), - "currentDate", currentDate.Format("2006-01-02"), - ) - - return nil - } - - // Loop through each date from latestDate to currentDate - for d := startingDate; d.Before(currentDate); d = d.AddDate(0, 0, 1) { - slog.Info("Processing", "task", task, "date", d.Format("2006-01-02"), "currentDate", currentDate.Format("2006-01-02")) - - err := g.queryByTask(task, d) - if err != nil { - slog.Info("Query failed", "task", task, "date", d.Format("2006-01-02"), "error", err.Error()) - return err - } - - slog.Info("Processed", "task", task, "date", d.Format("2006-01-02")) - } - - return nil -} - -// getStartingDateByTask returns first required time series data, one after the latest date entry, -// or the genesis date. -func (g *Generator) getStartingDateByTask(ctx context.Context, task string) (time.Time, error) { - var latestDateString string - - var nextRequiredDate time.Time - - q := `SELECT date FROM time_series_data WHERE task = ? ORDER BY date DESC LIMIT 1;` - - err := g.db.GormDB().Raw(q, task).Scan(&latestDateString).Error - - slog.Info("latestDateString", "task", task, "date", latestDateString) - - if err != nil || latestDateString == "" { - nextRequiredDate = g.genesisDate - } else { - latestDate, err := time.Parse("2006-01-02", latestDateString) - if err != nil { - return time.Time{}, err - } - - nextRequiredDate = latestDate.AddDate(0, 0, 1) - } - - slog.Info("next required date for task", "task", task, "nextRequiredDate", nextRequiredDate.Format("2006-01-02")) - - return nextRequiredDate, nil -} - -// getCurrentDate returns the current date in YYYY-MM-DD format -func (g *Generator) getCurrentDate() time.Time { - // Get current date - currentTime := time.Now().UTC() - currentDate := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, time.UTC) - - return currentDate -} - -// nolint: funlen, gocognit -// queryByTask runs a database query which should return result data based on the -// task -func (g *Generator) queryByTask(task string, date time.Time) error { - dateString := date.Format("2006-01-02") - - var result decimal.Decimal - - var err error - - switch task { - case tasks.TotalTransitionProvedByTier: - var tiers []uint16 = make([]uint16, 0) - - query := "SELECT DISTINCT tier FROM events WHERE event = ? AND tier IS NOT NULL;" - - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved). - Scan(&tiers).Error - if err != nil { - return err - } - - slog.Info("tiers", "tiers", tiers) - - for _, tier := range tiers { - t := tier - - var dailyCountByTier decimal.NullDecimal - - // nolint: lll - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ? AND tier = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved, dateString, t). - Scan(&dailyCountByTier).Error - - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, &t) - if err != nil { - return err - } - - result := tsdResult.Decimal.Add(dailyCountByTier.Decimal) - - slog.Info("Query successful", - "task", task, - "date", dateString, - "result", result.String(), - "tier", t, - ) - - insertStmt := ` - INSERT INTO time_series_data(task, value, date, tier) - VALUES (?, ?, ?, ?)` - - err = g.db.GormDB().Exec(insertStmt, task, result, dateString, t).Error - if err != nil { - slog.Info("Insert failed", "task", task, "date", dateString, "error", err.Error()) - return err - } - } - - // return early for array processing data - return nil - case tasks.TransitionProvedByTierPerDay: - var tiers []uint16 = make([]uint16, 0) - - query := "SELECT DISTINCT tier FROM events WHERE event = ? AND tier IS NOT NULL;" - - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved). - Scan(&tiers).Error - if err != nil { - return err - } - - slog.Info("tiers", "tiers", tiers) - - for _, tier := range tiers { - t := tier - - var dailyCountByTier decimal.NullDecimal - - // nolint: lll - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ? AND tier = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved, dateString, t). - Scan(&dailyCountByTier).Error - - if err != nil { - return err - } - - slog.Info("Query successful", - "task", task, - "date", dateString, - "result", dailyCountByTier.Decimal.String(), - "tier", t, - ) - - insertStmt := ` - INSERT INTO time_series_data(task, value, date, tier) - VALUES (?, ?, ?, ?)` - - err = g.db.GormDB().Exec(insertStmt, task, result, dateString, t).Error - if err != nil { - slog.Info("Insert failed", "task", task, "date", dateString, "error", err.Error()) - return err - } - } - - // return early for array processing data - return nil - case tasks.TransitionContestedByTierPerDay: - var tiers []uint16 = make([]uint16, 0) - - query := "SELECT DISTINCT tier FROM events WHERE event = ? AND tier IS NOT NULL;" - - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionContested). - Scan(&tiers).Error - if err != nil { - return err - } - - slog.Info("tiers", "tiers", tiers) - - for _, tier := range tiers { - t := tier - - var dailyCountByTier decimal.NullDecimal - - // nolint: lll - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ? AND tier = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionContested, dateString, t). - Scan(&dailyCountByTier).Error - - if err != nil { - return err - } - - slog.Info("Query successful", - "task", task, - "date", dateString, - "result", dailyCountByTier.Decimal.String(), - "tier", t, - ) - - insertStmt := ` - INSERT INTO time_series_data(task, value, date, tier) - VALUES (?, ?, ?, ?)` - - err = g.db.GormDB().Exec(insertStmt, task, result, dateString, t).Error - if err != nil { - slog.Info("Insert failed", "task", task, "date", dateString, "error", err.Error()) - return err - } - } - - // return early for array processing data - return nil - case tasks.TotalTransitionContestedByTier: - var tiers []uint16 = make([]uint16, 0) - - query := "SELECT DISTINCT tier FROM events WHERE event = ? AND tier IS NOT NULL;" - - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionContested). - Scan(&tiers).Error - if err != nil { - return err - } - - slog.Info("tiers", "tiers", tiers) - - for _, tier := range tiers { - t := tier - - var dailyCountByTier decimal.NullDecimal - - // nolint: lll - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ? AND tier = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionContested, dateString, t). - Scan(&dailyCountByTier).Error - - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, &t) - if err != nil { - return err - } - - result := tsdResult.Decimal.Add(dailyCountByTier.Decimal) - - slog.Info("Query successful", - "task", task, - "date", dateString, - "result", result.String(), - "tier", t, - ) - - insertStmt := ` - INSERT INTO time_series_data(task, value, date, tier) - VALUES (?, ?, ?, ?)` - - err = g.db.GormDB().Exec(insertStmt, task, result, dateString, t).Error - if err != nil { - slog.Info("Insert failed", "task", task, "date", dateString, "error", err.Error()) - return err - } - } - - // return early for array processing data - return nil - case tasks.BridgeMessagesSentPerDay: - err = g.eventCount(task, date, eventindexer.EventNameMessageSent, &result) - case tasks.TotalBridgeMessagesSent: - var dailyMsgSentCount decimal.NullDecimal - - err = g.eventCount(task, date, eventindexer.EventNameMessageSent, &dailyMsgSentCount) - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyMsgSentCount.Decimal) - case tasks.ProposeBlockTxPerDay: - err = g.eventCount(task, date, eventindexer.EventNameBlockProposed, &result) - case tasks.TotalProposeBlockTx: - var dailyProposerCount decimal.NullDecimal - - err = g.eventCount(task, date, eventindexer.EventNameBlockProposed, &dailyProposerCount) - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyProposerCount.Decimal) - case tasks.UniqueProposersPerDay: - query := "SELECT COUNT(DISTINCT address) FROM events WHERE event = ? AND DATE(transacted_at) = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameBlockProposed, dateString). - Scan(&result).Error - case tasks.TotalUniqueProposers: - query := `SELECT COUNT(DISTINCT address) FROM events WHERE event = ?` - - err = g.db.GormDB().Raw( - query, - eventindexer.EventNameBlockProposed, - ).Scan(&result).Error - if err != nil { - return err - } - case tasks.UniqueProversPerDay: - query := "SELECT COUNT(DISTINCT address) FROM events WHERE event = ? AND DATE(transacted_at) = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved, dateString). - Scan(&result).Error - case tasks.TotalUniqueProvers: - query := `SELECT COUNT(DISTINCT address) FROM events WHERE event = ?` - - err = g.db.GormDB().Raw( - query, - eventindexer.EventNameTransitionProved, - ).Scan(&result).Error - if err != nil { - return err - } - case tasks.TransitionProvedTxPerDay: - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionProved, dateString). - Scan(&result).Error - case tasks.TotalTransitionProvedTx: - var dailyTransitionProvedCount decimal.NullDecimal - - query := `SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ?` - - err = g.db.GormDB().Raw( - query, - eventindexer.EventNameTransitionProved, - dateString, - ).Scan(&dailyTransitionProvedCount).Error - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyTransitionProvedCount.Decimal) - case tasks.TransitionContestedTxPerDay: - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ?" - err = g.db.GormDB(). - Raw(query, eventindexer.EventNameTransitionContested, dateString). - Scan(&result).Error - case tasks.TotalTransitionContestedTx: - var dailyTransitionContestedCount decimal.NullDecimal - - query := `SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ?` - - err = g.db.GormDB().Raw( - query, - eventindexer.EventNameTransitionContested, - dateString, - ).Scan(&dailyTransitionContestedCount).Error - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyTransitionContestedCount.Decimal) - case tasks.AccountsPerDay: - query := `SELECT COUNT(*) FROM accounts WHERE DATE(transacted_at) = ?` - err = g.db.GormDB().Raw(query, dateString).Scan(&result).Error - case tasks.TotalAccounts: - var dailyAccountsCount decimal.NullDecimal - - query := `SELECT COUNT(*) FROM accounts WHERE DATE(transacted_at) = ?` - - err = g.db.GormDB().Raw(query, dateString).Scan(&dailyAccountsCount).Error - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyAccountsCount.Decimal) - case tasks.TransactionsPerDay: - query := `SELECT COUNT(*) FROM transactions WHERE DATE(transacted_at) = ?` - err = g.db.GormDB().Raw(query, dateString).Scan(&result).Error - case tasks.TotalTransactions: - var dailyTxCount decimal.NullDecimal - - // get current days txs, get previous entry for the time series data, add them together. - - query := `SELECT COUNT(*) FROM transactions WHERE DATE(transacted_at) = ?` - - err = g.db.GormDB().Raw(query, dateString).Scan(&dailyTxCount).Error - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyTxCount.Decimal) - case tasks.ContractDeploymentsPerDay: - query := `SELECT COUNT(*) FROM transactions WHERE DATE(transacted_at) = ? AND contract_address != ?` - err = g.db.GormDB().Raw(query, dateString, ZeroAddress.Hex()).Scan(&result).Error - case tasks.TotalContractDeployments: - var dailyContractCount decimal.NullDecimal - - // get current days txs, get previous entry for the time series data, add them together. - query := `SELECT COUNT(*) FROM transactions WHERE DATE(transacted_at) = ? AND contract_address != ?` - - err = g.db.GormDB().Raw(query, dateString, ZeroAddress.Hex()).Scan(&dailyContractCount).Error - if err != nil { - return err - } - - tsdResult, err := g.previousDayTsdResultByTask(task, date, nil, nil) - if err != nil { - return err - } - - result = tsdResult.Decimal.Add(dailyContractCount.Decimal) - default: - return errors.New("task not supported") - } - - if err != nil { - return err - } - - slog.Info("Query successful", "task", task, "date", dateString, "result", result.String()) - - insertStmt := ` - INSERT INTO time_series_data(task, value, date) - VALUES (?, ?, ?)` - - err = g.db.GormDB().Exec(insertStmt, task, result, dateString).Error - if err != nil { - slog.Info("Insert failed", "task", task, "date", dateString, "error", err.Error()) - return err - } - - return nil -} - -// previousDayTsdResultByTask returns the previous day's time series data, based on -// task and time passed in. -func (g *Generator) previousDayTsdResultByTask( - task string, - date time.Time, - feeTokenAddress *string, - tier *uint16, -) (decimal.NullDecimal, error) { - var tsdResult decimal.NullDecimal - - var tsdQuery string = `SELECT value FROM time_series_data WHERE task = ? AND date = ?` - - var q *gorm.DB = g.db.GormDB(). - Raw(tsdQuery, task, date.AddDate(0, 0, -1).Format("2006-01-02")) - - if feeTokenAddress != nil { - tsdQuery = `SELECT value FROM time_series_data WHERE task = ? AND date = ? AND fee_token_address = ?` - q = g.db.GormDB(). - Raw(tsdQuery, task, date.AddDate(0, 0, -1).Format("2006-01-02"), *feeTokenAddress) - } - - if tier != nil { - tsdQuery = `SELECT value FROM time_series_data WHERE task = ? AND date = ? AND tier = ?` - q = g.db.GormDB(). - Raw(tsdQuery, task, date.AddDate(0, 0, -1).Format("2006-01-02"), *tier) - } - - err := q. - Scan(&tsdResult).Error - if err != nil { - return tsdResult, err - } - - if !tsdResult.Valid { - return decimal.NullDecimal{ - Valid: true, - Decimal: decimal.Zero, - }, nil - } - - return tsdResult, nil -} - -// eventCount is a helper method to query the database for the count of a specific event -// based on the date. -func (g *Generator) eventCount(task string, date time.Time, event string, result interface{}) error { - query := "SELECT COUNT(*) FROM events WHERE event = ? AND DATE(transacted_at) = ?" - - return g.db.GormDB(). - Raw(query, event, date.Format("2006-01-02")). - Scan(result).Error -}