@@ -17,6 +17,7 @@ import (
17
17
"github.com/lightninglabs/aperture/lsat"
18
18
"github.com/lightninglabs/loop/loopdb"
19
19
"github.com/lightninglabs/loop/looprpc"
20
+ "github.com/lightningnetwork/lnd/lnrpc"
20
21
"github.com/lightningnetwork/lnd/lntypes"
21
22
"github.com/lightningnetwork/lnd/routing/route"
22
23
"github.com/lightningnetwork/lnd/tor"
@@ -74,6 +75,10 @@ type swapServerClient interface {
74
75
// SubscribeLoopInUpdates subscribes to loop in server state.
75
76
SubscribeLoopInUpdates (ctx context.Context ,
76
77
hash lntypes.Hash ) (<- chan * ServerUpdate , <- chan error , error )
78
+
79
+ // CancelLoopOutSwap cancels a loop out swap.
80
+ CancelLoopOutSwap (ctx context.Context ,
81
+ details * outCancelDetails ) error
77
82
}
78
83
79
84
type grpcSwapServerClient struct {
@@ -456,6 +461,104 @@ func (s *grpcSwapServerClient) makeServerUpdate(ctx context.Context,
456
461
return updateChan , errChan
457
462
}
458
463
464
+ // paymentType is an enum representing different types of off-chain payments
465
+ // made by a swap.
466
+ type paymentType uint8
467
+
468
+ const (
469
+ // paymentTypePrepay indicates that we could not route the prepay.
470
+ paymentTypePrepay paymentType = iota
471
+
472
+ // paymentTypeInvoice indicates that we could not route the swap
473
+ // invoice.
474
+ paymentTypeInvoice
475
+ )
476
+
477
+ // routeCancelMetadata contains cancelation information for swaps that are
478
+ // canceled because the client could not route off-chain to the server.
479
+ type routeCancelMetadata struct {
480
+ // paymentType is the type of payment that failed.
481
+ paymentType paymentType
482
+
483
+ // attempts is the set of htlc attempts made by the client, reporting
484
+ // the distance from the invoice's destination node that a failure
485
+ // occurred.
486
+ attempts []uint32
487
+
488
+ // failureReason is the reason that the payment failed.
489
+ failureReason lnrpc.PaymentFailureReason
490
+ }
491
+
492
+ // outCancelDetails contains the informaton required to cancel a loop out swap.
493
+ type outCancelDetails struct {
494
+ // Hash is the swap's hash.
495
+ hash lntypes.Hash
496
+
497
+ // paymentAddr is the payment address for the swap's invoice.
498
+ paymentAddr [32 ]byte
499
+
500
+ // metadata contains additional information about the swap.
501
+ metadata routeCancelMetadata
502
+ }
503
+
504
+ // CancelLoopOutSwap sends an instruction to the server to cancel a loop out
505
+ // swap.
506
+ func (s * grpcSwapServerClient ) CancelLoopOutSwap (ctx context.Context ,
507
+ details * outCancelDetails ) error {
508
+
509
+ req := & looprpc.CancelLoopOutSwapRequest {
510
+ ProtocolVersion : loopdb .CurrentRPCProtocolVersion ,
511
+ SwapHash : details .hash [:],
512
+ PaymentAddress : details .paymentAddr [:],
513
+ }
514
+
515
+ var err error
516
+ req .CancelInfo , err = rpcRouteCancel (details )
517
+ if err != nil {
518
+ return err
519
+ }
520
+
521
+ _ , err = s .server .CancelLoopOutSwap (ctx , req )
522
+ return err
523
+ }
524
+
525
+ func rpcRouteCancel (details * outCancelDetails ) (
526
+ * looprpc.CancelLoopOutSwapRequest_RouteCancel , error ) {
527
+
528
+ attempts := make ([]* looprpc.HtlcAttempt , len (details .metadata .attempts ))
529
+ for i , remaining := range details .metadata .attempts {
530
+ attempts [i ] = & looprpc.HtlcAttempt {
531
+ RemainingHops : remaining ,
532
+ }
533
+ }
534
+
535
+ resp := & looprpc.CancelLoopOutSwapRequest_RouteCancel {
536
+ RouteCancel : & looprpc.RouteCancel {
537
+ Attempts : attempts ,
538
+ // We can cast our lnd failure reason to a loop payment
539
+ // failure reason because these values are copied 1:1
540
+ // from lnd.
541
+ Failure : looprpc .PaymentFailureReason (
542
+ details .metadata .failureReason ,
543
+ ),
544
+ },
545
+ }
546
+
547
+ switch details .metadata .paymentType {
548
+ case paymentTypePrepay :
549
+ resp .RouteCancel .RouteType = looprpc .RoutePaymentType_PREPAY_ROUTE
550
+
551
+ case paymentTypeInvoice :
552
+ resp .RouteCancel .RouteType = looprpc .RoutePaymentType_INVOICE_ROUTE
553
+
554
+ default :
555
+ return nil , fmt .Errorf ("unknown payment type: %v" ,
556
+ details .metadata .paymentType )
557
+ }
558
+
559
+ return resp , nil
560
+ }
561
+
459
562
// getSwapServerConn returns a connection to the swap server. A non-empty
460
563
// proxyAddr indicates that a SOCKS proxy found at the address should be used to
461
564
// establish the connection.
0 commit comments