diff --git a/state/indexer/sink/psql/psql.go b/state/indexer/sink/psql/psql.go index 5c5d42ddd..f960de9ab 100644 --- a/state/indexer/sink/psql/psql.go +++ b/state/indexer/sink/psql/psql.go @@ -97,6 +97,11 @@ func insertEvents(tx *sql.Tx, blockID, txID uint32, evts []abci.Event) error { // Add each event to the events table, and retrieve its row ID to use when // adding any attributes the event provides. for _, evt := range evts { + // Skip events with an empty type. + if evt.Type == "" { + continue + } + eid, err := queryWithID(tx, ` INSERT INTO `+tableEvents+` (block_id, tx_id, type) VALUES ($1, $2, $3) RETURNING rowid; @@ -179,13 +184,23 @@ SELECT rowid FROM `+tableBlocks+` WHERE height = $1 AND chain_id = $2; txID, err := queryWithID(tx, ` INSERT INTO `+tableTxResults+` (block_id, index, created_at, tx_hash, tx_result) VALUES ($1, $2, $3, $4, $5) + ON CONFLICT DO NOTHING RETURNING rowid; `, blockID, txr.Index, ts, txHash, resultData) - if err != nil { + if err == sql.ErrNoRows { + return nil // we already saw this transaction; quietly succeed + } else if err != nil { return fmt.Errorf("indexing tx_result: %w", err) } - // Index any events associated with the transaction. + // Insert the special transaction meta-events for hash and height. + if err := insertEvents(tx, blockID, txID, []abci.Event{ + makeIndexedEvent("tx", "hash", txHash), + makeIndexedEvent("tx", "height", fmt.Sprint(txr.Height)), + }); err != nil { + return fmt.Errorf("indexing transaction meta-events: %w", err) + } + // Index any events packaged with the transaction. if err := insertEvents(tx, blockID, txID, txr.Result.Events); err != nil { return fmt.Errorf("indexing transaction events: %w", err) }