Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: DB write of upsert pins in run as group #1598

Closed
wants to merge 1 commit into from

Conversation

EnriqueL8
Copy link
Contributor

In the case where FireFly is restarted and the listener for BatchPin events is recreated in the blockchain connector, FireFly will re-index all the events into the system. The Pins table has an index for uniqueness of batch_id+hash+namespace so it will not allow inserting a duplicate record. In this case, the code falls back to upsetting the batch which is correct but this code is run in the context of DB TX which will never succeed as the previous insert fails.

You get the error current transaction is aborted, commands ignored until end of transaction block, explanation at
https://stackoverflow.com/questions/10399727/psqlexception-current-transaction-is-aborted-commands-ignored-until-end-of-tra why you get this error.

So there are two options:

  • When we insert we ignore on conflict, so don't error and we always upsert
  • We upsert using a different DB TX. In this case I achieve this by using a different context

@EnriqueL8 EnriqueL8 requested a review from a team as a code owner November 12, 2024 11:26
Copy link

codecov bot commented Nov 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (62ee71f) to head (6d10892).

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #1598   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          337       337           
  Lines        29498     29502    +4     
=========================================
+ Hits         29498     29502    +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@EnriqueL8
Copy link
Contributor Author

Tested locally and you can see that the insert fails but then the upset is fine

[2024-11-12T12:04:08.983Z] DEBUG SQL<- query pins (0.30ms) dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.983Z] DEBUG Existing pin returned at sequence 4 dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.983Z] DEBUG Batch cache hit 16169315-2dcb-4505-8bb4-b01f8abbba25/b9843b5d70d2d40618a37d27574d5bc0e3a83cf91300a416e103eb4b202dd062 ns=default pid=1 role=aggregator
[2024-11-12T12:04:08.984Z] ERROR SQL insert failed: UNIQUE constraint failed: pins.namespace, pins.hash, pins.batch_id, pins.idx sql=[ INSERT INTO pins (namespace,masked,hash,batch_id,batch_hash,idx,signer,dispatched,created) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) ]: UNIQUE constraint failed: pins.namespace, pins.hash, pins.batch_id, pins.idx dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.984Z]  WARN Batch insert of pins failed - assuming replay and performing upserts: FF00177: Database insert failed: UNIQUE constraint failed: pins.namespace, pins.hash, pins.batch_id, pins.idx dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.985Z] DEBUG SQL<- query pins (0.28ms) dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.985Z] DEBUG Existing pin returned at sequence 5 dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.987Z] DEBUG SQL<- query pins (0.56ms) dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.987Z] DEBUG Existing pin returned at sequence 6 dbtx=tBaB41Bs ns=default pid=1 role=event-manager
[2024-11-12T12:04:08.987Z] DEBUG Batch cache hit 73cef8e4-2b65-45d7-9e0d-288cecb740a9/3c69dee7f91d4a7e5271be2421d6bdfac3c0a0e04c60f141766ca8b09852a0fd ns=default pid=1 role=aggregator

for _, pin := range pins {
if err := em.database.UpsertPin(ctx, pin); err != nil {
if err := em.database.UpsertPin(upsertCtx, pin); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a very bad idea to intentionally do this outside the database transaction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The batch insert above should be non-fatal (should be configured to return an empty result on conflict)

@EnriqueL8
Copy link
Contributor Author

No longer need as was already fixed by b26fa27

@EnriqueL8 EnriqueL8 closed this Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants