fix: intercept self hold payments based on invoice rather than payment hash#2027
fix: intercept self hold payments based on invoice rather than payment hash#2027im-adithya merged 3 commits intomasterfrom
Conversation
📝 WalkthroughWalkthroughThis PR refactors the payment handling system to use payment request identifiers instead of payment hashes for hold invoice self-payments. It introduces timeout constants, enhances mock testing infrastructure, and adds comprehensive test coverage for wrapped invoice flows across multiple interacting applications. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
|
@im-adithya @frnandu in the latest version of Polar (LND v20) payments were failing until I set a timeout seconds (which should have been set anyway. I set it to 50s) |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
transactions/self_hold_payments_test.go (2)
254-256:time.Sleepfor synchronization can cause flaky tests.Using
time.Sleep(10 * time.Millisecond)to wait for Alice's payment to be accepted is timing-dependent and could fail on slower CI environments. As the TODO suggests, consider using event-based synchronization or a channel with timeout.♻️ Example approach using channels
// Consider adding a channel to MockLn or using event subscription // to wait for the hold invoice accepted state rather than sleeping🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@transactions/self_hold_payments_test.go` around lines 254 - 256, The test uses time.Sleep(10 * time.Millisecond) for synchronization which is flaky; replace the sleep by waiting on an event or channel from the mock Lightning node instead: add an event subscription or channel on MockLn (e.g., a NotifyInvoiceAccepted / InvoiceAcceptedCh) and have the test block on that with a timeout (context.WithTimeout) to fail reliably if the accept event never arrives; update the test (transactions/self_hold_payments_test.go) to wait on that channel or call MockLn.WaitForInvoiceAccepted (or similar) instead of time.Sleep.
194-200: Mock preimage doesn't match Charlie's invoice preimage.The
PayInvoiceResponsesuseMockLNClientHoldTransaction.Preimage, which differs from Charlie's actual invoice preimage (fcf200c74d9900dc77af17eb1f57c02eec0f94b5b169d3eee23df9a216a3411b). While acceptable for testing the self-payment flow mechanics, this means the test doesn't validate the full preimage chain from Charlie → Bob → Alice settlement.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@transactions/self_hold_payments_test.go` around lines 194 - 200, The test currently sets preimages = []string{tests.MockLNClientHoldTransaction.Preimage, ...} and configures svc.LNClient.(*tests.MockLn).PayInvoiceResponses with those values, but that preimage does not match Charlie’s real invoice preimage (fcf200c74d9900dc77af17eb1f57c02eec0f94b5b169d3eee23df9a216a3411b), so update the mock to use Charlie’s preimage (or include it as the first element) when constructing preimages and PayInvoiceResponses in the test (reference variables: preimages, tests.MockLNClientHoldTransaction.Preimage, svc.LNClient.(*tests.MockLn).PayInvoiceResponses) so the test validates the full preimage chain Charlie → Bob → Alice.tests/mock_ln_client.go (1)
80-81: Shared queue forMakeInvoiceandMakeHoldInvoicemay cause confusion.Both
MakeInvoiceandMakeHoldInvoiceconsume from the sameMakeInvoiceResponsesqueue. While this works for the currentTestWrappedInvoicetest where both are queued in order, it could lead to subtle bugs if tests inadvertently interleave calls. Consider whether separate queues (e.g.,MakeHoldInvoiceResponses) would provide clearer test intent.Also applies to: 122-141
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/mock_ln_client.go` around lines 80 - 81, The tests share a single response/error queue (MakeInvoiceResponses and MakeInvoiceErrors) for both MakeInvoice and MakeHoldInvoice which can lead to ordering bugs; split them by adding distinct MakeHoldInvoiceResponses and MakeHoldInvoiceErrors slices and update the mock methods MakeInvoice and MakeHoldInvoice to consume from their respective queues (preserving current behaviour for MakeInvoice by leaving it unchanged) and update any test setup in tests that rely on interleaving to push responses into the new MakeHoldInvoiceResponses queue so each API uses its own explicit queue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/mock_ln_client.go`:
- Around line 80-81: The tests share a single response/error queue
(MakeInvoiceResponses and MakeInvoiceErrors) for both MakeInvoice and
MakeHoldInvoice which can lead to ordering bugs; split them by adding distinct
MakeHoldInvoiceResponses and MakeHoldInvoiceErrors slices and update the mock
methods MakeInvoice and MakeHoldInvoice to consume from their respective queues
(preserving current behaviour for MakeInvoice by leaving it unchanged) and
update any test setup in tests that rely on interleaving to push responses into
the new MakeHoldInvoiceResponses queue so each API uses its own explicit queue.
In `@transactions/self_hold_payments_test.go`:
- Around line 254-256: The test uses time.Sleep(10 * time.Millisecond) for
synchronization which is flaky; replace the sleep by waiting on an event or
channel from the mock Lightning node instead: add an event subscription or
channel on MockLn (e.g., a NotifyInvoiceAccepted / InvoiceAcceptedCh) and have
the test block on that with a timeout (context.WithTimeout) to fail reliably if
the accept event never arrives; update the test
(transactions/self_hold_payments_test.go) to wait on that channel or call
MockLn.WaitForInvoiceAccepted (or similar) instead of time.Sleep.
- Around line 194-200: The test currently sets preimages =
[]string{tests.MockLNClientHoldTransaction.Preimage, ...} and configures
svc.LNClient.(*tests.MockLn).PayInvoiceResponses with those values, but that
preimage does not match Charlie’s real invoice preimage
(fcf200c74d9900dc77af17eb1f57c02eec0f94b5b169d3eee23df9a216a3411b), so update
the mock to use Charlie’s preimage (or include it as the first element) when
constructing preimages and PayInvoiceResponses in the test (reference variables:
preimages, tests.MockLNClientHoldTransaction.Preimage,
svc.LNClient.(*tests.MockLn).PayInvoiceResponses) so the test validates the full
preimage chain Charlie → Bob → Alice.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
lnclient/lnd/lnd.gotests/mock_ln_client.gotransactions/hold_invoice_self_payment_consumer.gotransactions/payments_test.gotransactions/self_hold_payments_test.gotransactions/transactions_service.go
|
Comments are only on tests, LGTM! |
This PR also fixes a bug where we will fail saying the invoice has already been paid (I think would block wrapped invoices working with LND right now)
TODOs
Follow ups - move to new issue:
Summary by CodeRabbit
Bug Fixes
Tests