Skip to content

fix: address grunch review on handle-delayed-payment PR#845

Merged
Luquitasjeffrey merged 4 commits into
lnp2pBot:handle_delayed_paymentfrom
Matobi98:fix/handle-delayed-payment
Jun 28, 2026
Merged

fix: address grunch review on handle-delayed-payment PR#845
Luquitasjeffrey merged 4 commits into
lnp2pBot:handle_delayed_paymentfrom
Matobi98:fix/handle-delayed-payment

Conversation

@Matobi98

@Matobi98 Matobi98 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f22fa835-51eb-4b38-8a23-a6343e5c5fac

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@grunch

grunch commented Jun 25, 2026

Copy link
Copy Markdown
Member

@Matobi98 please the CI is failing

@Luquitasjeffrey Luquitasjeffrey left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please handle my inline comments

Comment thread jobs/pending_payments.ts Outdated
i18nCtx: I18nContext,
pending?: IPendingPayment,
): Promise<boolean> => {
const won = await Order.findOneAndUpdate(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why dont you update the IOrder passed as a parameter to the function and later call await order.save()?

@Matobi98 Matobi98 Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Why findOneAndUpdate instead of order.save():
Because if you use order.save() you get a race condition, let me explain:

With order.save() the flow is:

  1. Load the order into memory → status = "PENDING"
  2. Set status = "SUCCESS"
  3. order.save()

The problem shows up when steps 1–2–3 run in parallel. An order can be completed from two places at once: the pending-payments job and the buyer's /setinvoice.

Job: reads order (PENDING) ... sets SUCCESS ... save → notifies + bumps trades
/setinvoice: reads order (PENDING) ... sets SUCCESS ... save → notifies + bumps trades

Both read "PENDING" before the other one saved, so both think it's their job to complete it. Result: the buyer gets notified twice and trades_completed is incremented twice. That's the race condition.

order.save() can't prevent this because it's two separate operations — read first, then write — and the other process slips in between.

With findOneAndUpdate it's a single atomic operation:

Order.findOneAndUpdate(
{ _id: order._id, status: { $ne: 'SUCCESS' } }, // "only if it's NOT already SUCCESS"
{ $set: { status: 'SUCCESS' } }
)

This tells the database: "switch to SUCCESS only if it isn't already, and tell me whether you actually changed it". The DB guarantees that of the two processes, only one gets the order back (won); the other gets null. So only the winner notifies and bumps trades. That's idempotency: the routine runs exactly once, no matter how many callers trigger it.

Comment thread jobs/pending_payments.ts Outdated
// so that if two callers race (e.g. this job and a concurrent /setinvoice), only
// the first one runs the side effects: no double notification, no double trades.
// Returns true if this caller won the race and ran the routine.
export const completeOrderAsSuccess = async (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this function shoumd be located in utils/

@Luquitasjeffrey Luquitasjeffrey left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK

@Luquitasjeffrey Luquitasjeffrey merged commit cf3ccd2 into lnp2pBot:handle_delayed_payment Jun 28, 2026
3 checks passed
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.

3 participants