diff --git a/cmd/soroban-rpc/internal/daemon/daemon.go b/cmd/soroban-rpc/internal/daemon/daemon.go
index 44cf75fa..07ca7992 100644
--- a/cmd/soroban-rpc/internal/daemon/daemon.go
+++ b/cmd/soroban-rpc/internal/daemon/daemon.go
@@ -294,8 +294,8 @@ func MustNew(cfg *config.Config, logger *supportlog.Entry) *Daemon {
// mustInitializeStorage initializes the storage using what was on the DB
func (d *Daemon) mustInitializeStorage(cfg *config.Config) *feewindow.FeeWindows {
//
- // There is a lot of complex "ledger window math" here so it's worth
- // clarifying as a comment beforehand.
+ // There's some complex "ledger window math" here so we should clarify it
+ // beforehand.
//
// There are two windows in play here:
// - the ledger retention window, which describes the range of txmeta
@@ -306,9 +306,7 @@ func (d *Daemon) mustInitializeStorage(cfg *config.Config) *feewindow.FeeWindows
// If the fee window *exceeds* the retention window, this doesn't make any
// sense since it implies the user wants to store N amount of actual
// historical data and M > N amount of ledgers just for fee processing,
- // which is nonsense from a performance standpoint. So we should prevent
- // this config on startup.
- //
+ // which is nonsense from a performance standpoint. We prevent this:
maxFeeRetentionWindow := max(
cfg.ClassicFeeStatsLedgerRetentionWindow,
cfg.SorobanFeeStatsLedgerRetentionWindow)
@@ -328,48 +326,40 @@ func (d *Daemon) mustInitializeStorage(cfg *config.Config) *feewindow.FeeWindows
readTxMetaCtx, cancelReadTxMeta := context.WithTimeout(context.Background(), cfg.IngestionTimeout)
defer cancelReadTxMeta()
+ // To combine these windows, we launch as follows:
//
- // With that in mind, it means we should launch as follows:
- //
- // 1. Based on the ledger retention window, identify the ledger range that
- // needs to migrated. We don't do "partial" migrations (a new migration to a
- // migrated table would have a different "Migrated
" meta key in the
- // database), so this should represent the entire range of ledger meta we're
- // storing.
+ // 1. First, identify the ledger range for database migrations based on the
+ // ledger retention window. Since we don't do "partial" migrations (all or
+ // nothing), this represents the entire range of ledger metas we store.
//
retentionRange, err := db.GetMigrationLedgerRange(readTxMetaCtx, d.db, cfg.HistoryRetentionWindow)
if err != nil {
d.logger.WithError(err).Fatal("could not get ledger range for migration")
}
- //
- // 2. However, if we have already performed migrations, we don't want to
- // count those in the "to migrate" ledger range. Thus, db.BuildMigrations
- // will return the *applicable* range for the incomplete set of migrations.
- // That means **it may be empty** if all migrations have occurred.
- //
dataMigrations, err := db.BuildMigrations(
readTxMetaCtx, d.logger, d.db, cfg.NetworkPassphrase, retentionRange)
if err != nil {
d.logger.WithError(err).Fatal("could not build migrations")
}
- //
- // 4. Finally, we can incorporate the fee analysis window. If there are
- // migrations to do, this will have no effect, since the migration window is
- // larger than the fee window. If there were *no* migrations, though, this
- // means the final range is only the fee stat analysis range.
+ // 2. Then, incorporate the fee analysis window. If there are migrations to
+ // do, this has no effect, since migration windows are larger than the fee
+ // window. In the absence of migrations, though, this means the ingestion
+ // range is just the fee stat range.
//
feeStatsRange, err := db.GetMigrationLedgerRange(readTxMetaCtx, d.db, maxFeeRetentionWindow)
- dataMigrations.Append(feeWindows.AsMigration(feeStatsRange))
if err != nil {
d.logger.WithError(err).Fatal("could not get ledger range for fee stats")
}
+ // Additionally, by treating the fee window *as if* it's a migration, we can
+ // make the interface here really clean.
+ dataMigrations.Append(feeWindows.AsMigration(feeStatsRange))
ledgerSeqRange := dataMigrations.ApplicableRange()
//
- // 5. Apply migration for events & transactions, and perform fee stat analysis.
+ // 3. Apply all migrations, including fee stat analysis.
//
var initialSeq, currentSeq uint32
err = db.NewLedgerReader(d.db).StreamLedgerRange(
@@ -400,6 +390,7 @@ func (d *Daemon) mustInitializeStorage(cfg *config.Config) *feewindow.FeeWindows
if err != nil {
d.logger.WithError(err).Fatal("Could not obtain txmeta cache from the database")
}
+
if err := dataMigrations.Commit(readTxMetaCtx); err != nil {
d.logger.WithError(err).Fatal("Could not commit data migrations")
}
diff --git a/cmd/soroban-rpc/internal/db/migration.go b/cmd/soroban-rpc/internal/db/migration.go
index b93b6a21..8ab14e77 100644
--- a/cmd/soroban-rpc/internal/db/migration.go
+++ b/cmd/soroban-rpc/internal/db/migration.go
@@ -205,18 +205,14 @@ func BuildMigrations(
}
//
- // Add new migrations here:
+ // Add new DB migrations here:
//
currentMigrations := map[string]migrationApplierF{
transactionsMigrationName: newTransactionTableMigration,
eventsMigrationName: newEventTableMigration,
}
- mm := MultiMigration{
- migrations: make([]Migration, 0, len(currentMigrations)),
- db: db,
- }
-
+ migrations := make([]Migration, 0, len(currentMigrations))
for migrationName, migrationFunc := range currentMigrations {
migrationLogger := logger.WithField("migration", migrationName)
factory := migrationFunc(
@@ -237,8 +233,11 @@ func BuildMigrations(
continue
}
- mm.Append(guardedM)
+ migrations = append(migrations, guardedM)
}
- return mm, nil
+ return MultiMigration{
+ migrations: migrations,
+ db: db,
+ }, nil
}
diff --git a/cmd/soroban-rpc/internal/feewindow/feewindow.go b/cmd/soroban-rpc/internal/feewindow/feewindow.go
index d914558a..08a84ab4 100644
--- a/cmd/soroban-rpc/internal/feewindow/feewindow.go
+++ b/cmd/soroban-rpc/internal/feewindow/feewindow.go
@@ -225,4 +225,5 @@ func (fw *feeWindowMigration) Commit(_ context.Context) error {
return nil // no-op
}
+// ensure we conform to the migration interface
var _ db.Migration = &feeWindowMigration{}