Skip to content

Commit

Permalink
add context timeout check in call to get outgoing payment status
Browse files Browse the repository at this point in the history
  • Loading branch information
elnosh committed Oct 3, 2024
1 parent 0242910 commit 3fd56f9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
6 changes: 6 additions & 0 deletions mint/lightning/lnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,18 @@ func (lnd *LndClient) OutgoingPaymentStatus(ctx context.Context, hash string) (P

trackPaymentStream, err := lnd.routerClient.TrackPaymentV2(ctx, &trackPaymentRequest)
if err != nil {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
return PaymentStatus{PaymentStatus: Pending}, nil
}
return PaymentStatus{PaymentStatus: Failed}, err
}

// this should block until final payment update
payment, err := trackPaymentStream.Recv()
if err != nil {
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
return PaymentStatus{PaymentStatus: Pending}, nil
}
return PaymentStatus{PaymentStatus: Failed}, fmt.Errorf("payment failed: %w", err)
}
if payment.Status == lnrpc.Payment_UNKNOWN || payment.Status == lnrpc.Payment_FAILED {
Expand Down
44 changes: 27 additions & 17 deletions mint/mint_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func TestMintQuoteState(t *testing.T) {
t.Fatalf("unexpected error getting quote state: %v", err)
}
if quoteStateResponse.State != nut04.Unpaid {
t.Fatalf("expected quote state '%v' but got '%v' instead", nut04.Unpaid.String(), quoteStateResponse.State.String())
t.Fatalf("expected quote state '%s' but got '%s' instead", nut04.Unpaid, quoteStateResponse.State)
}

//pay invoice
Expand All @@ -167,7 +167,7 @@ func TestMintQuoteState(t *testing.T) {
t.Fatalf("unexpected error getting quote state: %v", err)
}
if quoteStateResponse.State != nut04.Paid {
t.Fatalf("expected quote state '%v' but got '%v' instead", nut04.Paid.String(), quoteStateResponse.State.String())
t.Fatalf("expected quote state '%s' but got '%s' instead", nut04.Paid, quoteStateResponse.State)
}

blindedMessages, _, _, err := testutils.CreateBlindedMessages(mintAmount, keyset)
Expand All @@ -184,7 +184,7 @@ func TestMintQuoteState(t *testing.T) {
t.Fatalf("unexpected error getting quote state: %v", err)
}
if quoteStateResponse.State != nut04.Issued {
t.Fatalf("expected quote state '%v' but got '%v' instead", nut04.Issued.String(), quoteStateResponse.State.String())
t.Fatalf("expected quote state '%s' but got '%s' instead", nut04.Issued, quoteStateResponse.State)
}

}
Expand Down Expand Up @@ -419,7 +419,7 @@ func TestMeltQuoteState(t *testing.T) {
t.Fatalf("unexpected error getting melt quote state: %v", err)
}
if meltQuote.State != nut05.Unpaid {
t.Fatalf("expected quote state '%v' but got '%v' instead", nut05.Unpaid.String(), meltQuote.State.String())
t.Fatalf("expected quote state '%s' but got '%s' instead", nut05.Unpaid, meltQuote.State)
}

// test state after melting
Expand All @@ -438,7 +438,7 @@ func TestMeltQuoteState(t *testing.T) {
t.Fatalf("unexpected error getting melt quote state: %v", err)
}
if meltQuote.State != nut05.Paid {
t.Fatalf("expected quote state '%v' but got '%v' instead", nut05.Paid.String(), meltQuote.State.String())
t.Fatalf("expected quote state '%s' but got '%s' instead", nut05.Paid, meltQuote.State)
}
preimageString := hex.EncodeToString(lookupInvoice.RPreimage)
if meltQuote.Preimage != preimageString {
Expand Down Expand Up @@ -595,8 +595,7 @@ func TestMelt(t *testing.T) {
meltResponse, err := testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs)
if meltResponse.State != nut05.Unpaid {
// expecting unpaid since payment should have failed
t.Fatalf("expected melt quote with state of '%v' but got '%v' instead",
nut05.Unpaid.String(), meltResponse.State.String())
t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Unpaid, meltResponse.State)
}

// test internal quotes (mint and melt quotes with same invoice)
Expand Down Expand Up @@ -634,8 +633,10 @@ func TestMelt(t *testing.T) {
if err != nil {
t.Fatalf("got unexpected error in mint: %v", err)
}
}

// tests for pending state
func TestPendingProofs(t *testing.T) {
// use hodl invoice to cause payment to stuck and put quote and proofs in state of pending
preimage, _ := testutils.GenerateRandomBytes()
hash := sha256.Sum256(preimage)
hodlInvoice := invoicesrpc.AddHoldInvoiceRequest{Hash: hash[:], Value: 2100}
Expand All @@ -644,27 +645,36 @@ func TestMelt(t *testing.T) {
t.Fatalf("error creating hodl invoice: %v", err)
}

meltQuote, err = testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addHodlInvoiceRes.PaymentRequest, testutils.SAT_UNIT)
meltQuote, err := testMint.RequestMeltQuote(testutils.BOLT11_METHOD, addHodlInvoiceRes.PaymentRequest, testutils.SAT_UNIT)
if err != nil {
t.Fatalf("got unexpected error in melt request: %v", err)
}

validProofs, err = testutils.GetValidProofsForAmount(2200, testMint, lnd2)
validProofs, err := testutils.GetValidProofsForAmount(2200, testMint, lnd2)
if err != nil {
t.Fatalf("error generating valid proofs: %v", err)
}

// custom context just for this melt call to timeout afte 5s and return pending
// custom context just for this melt call to timeout after 5s and return pending
// for the stuck hodl invoice
meltContext, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

melt, err = testMint.MeltTokens(meltContext, testutils.BOLT11_METHOD, meltQuote.Id, validProofs)
melt, err := testMint.MeltTokens(meltContext, testutils.BOLT11_METHOD, meltQuote.Id, validProofs)
if err != nil {
t.Fatalf("got unexpected error in melt: %v", err)
}
if melt.State != nut05.Pending {
t.Fatalf("expected melt quote with state of '%v' but got '%v' instead", nut05.Pending.String(), melt.State.String())
t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Pending, melt.State)
}

meltQuote, err = testMint.GetMeltQuoteState(meltContext, testutils.BOLT11_METHOD, meltQuote.Id)
if err != nil {
t.Fatalf("unexpected error getting melt quote state: %v", err)
}

if meltQuote.State != nut05.Pending {
t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Pending, melt.State)
}

_, err = testMint.MeltTokens(ctx, testutils.BOLT11_METHOD, meltQuote.Id, validProofs)
Expand All @@ -674,7 +684,7 @@ func TestMelt(t *testing.T) {

// try to use currently pending proofs in another op.
// swap should return err saying proofs are pending
blindedMessages, _, _, _ = testutils.CreateBlindedMessages(validProofs.Amount(), testMint.GetActiveKeyset())
blindedMessages, _, _, _ := testutils.CreateBlindedMessages(validProofs.Amount(), testMint.GetActiveKeyset())
_, err = testMint.Swap(validProofs, blindedMessages)
if !errors.Is(err, cashu.ProofPendingErr) {
t.Fatalf("expected error '%v' but got '%v' instead", cashu.ProofPendingErr, err)
Expand All @@ -691,7 +701,7 @@ func TestMelt(t *testing.T) {
t.Fatalf("unexpected error getting melt quote state: %v", err)
}
if meltQuote.State != nut05.Paid {
t.Fatalf("expected melt quote with state of '%v' but got '%v' instead", nut05.Paid.String(), meltQuote.State.String())
t.Fatalf("expected melt quote with state of '%s' but got '%s' instead", nut05.Paid, meltQuote.State)
}

expectedPreimage := hex.EncodeToString(preimage)
Expand Down Expand Up @@ -721,7 +731,7 @@ func TestProofsStateCheck(t *testing.T) {
// proofs should be unspent here
for _, proofState := range proofStates {
if proofState.State != nut07.Unspent {
t.Fatalf("expected proof state '%v' but got '%v'", nut07.Unspent.String(), proofState.State.String())
t.Fatalf("expected proof state '%s' but got '%s'", nut07.Unspent, proofState.State)
}
}

Expand Down Expand Up @@ -749,7 +759,7 @@ func TestProofsStateCheck(t *testing.T) {

for _, proofState := range proofStates {
if proofState.State != nut07.Spent {
t.Fatalf("expected proof state '%v' but got '%v'", nut07.Spent.String(), proofState.State.String())
t.Fatalf("expected proof state '%s' but got '%s'", nut07.Spent, proofState.State)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion mint/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func (ms *MintServer) meltQuoteState(rw http.ResponseWriter, req *http.Request)
method := vars["method"]
quoteId := vars["quote_id"]

ctx, cancel := context.WithTimeout(context.Background(), time.Minute*1)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()

meltQuote, err := ms.mint.GetMeltQuoteState(ctx, method, quoteId)
Expand Down

0 comments on commit 3fd56f9

Please sign in to comment.