What version are you using?
latest
Problem
File: internal/services/ingest_backfill.go lines 418-486
Buggy code:
for attempt := 0; attempt < maxIngestProcessedDataRetries; attempt++ {
err := db.RunInTransaction(ctx, m.models.DB, func(dbTx pgx.Tx) error {
// This in-memory append is NOT rolled back when the transaction fails
batchChanges.ContractChanges = append(batchChanges.ContractChanges, buffer.GetContractChanges()...)
// ... DB operations that may fail ...
})
// On failure, retries the loop — appending ContractChanges AGAIN
}
Description: The batchChanges.ContractChanges slice append happens inside the transaction closure but is an in-memory operation not rolled back on DB transaction failure. On retry, the same contract changes are appended again, creating duplicates that propagate to ProcessTokenChanges. The map-based merges (mergeTrustlineChanges, mergeAccountChanges, etc.) are idempotent, but the slice append is not.
Suggested fix: Move the batchChanges collection after the successful transaction commit, or reset batchChanges.ContractChanges at the start of each retry.
What version are you using?
latest
Problem
File:
internal/services/ingest_backfill.golines 418-486Buggy code:
Description: The
batchChanges.ContractChangesslice append happens inside the transaction closure but is an in-memory operation not rolled back on DB transaction failure. On retry, the same contract changes are appended again, creating duplicates that propagate toProcessTokenChanges. The map-based merges (mergeTrustlineChanges,mergeAccountChanges, etc.) are idempotent, but the slice append is not.Suggested fix: Move the batchChanges collection after the successful transaction commit, or reset
batchChanges.ContractChangesat the start of each retry.