@@ -259,6 +259,13 @@ func (cl *ClightningClient) getMaxHtlcAmtMsat(scid, nodeId string) (uint64, erro
259
259
return htlcMaximumMilliSatoshis , nil
260
260
}
261
261
262
+ func min (x , y uint64 ) uint64 {
263
+ if x < y {
264
+ return x
265
+ }
266
+ return y
267
+ }
268
+
262
269
// SpendableMsat returns an estimate of the total we could send through the
263
270
// channel with given scid. Falls back to the owned amount in the channel.
264
271
func (cl * ClightningClient ) SpendableMsat (scid string ) (uint64 , error ) {
@@ -288,13 +295,6 @@ func (cl *ClightningClient) SpendableMsat(scid string) (uint64, error) {
288
295
return 0 , fmt .Errorf ("could not find a channel with scid: %s" , scid )
289
296
}
290
297
291
- func min (x , y uint64 ) uint64 {
292
- if x < y {
293
- return x
294
- }
295
- return y
296
- }
297
-
298
298
// ReceivableMsat returns an estimate of the total we could receive through the
299
299
// channel with given scid.
300
300
func (cl * ClightningClient ) ReceivableMsat (scid string ) (uint64 , error ) {
@@ -619,6 +619,69 @@ func (cl *ClightningClient) GetPeers() []string {
619
619
return peerlist
620
620
}
621
621
622
+ // ProbePayment trying to pay via a route with a random payment hash
623
+ // that the receiver doesn't have the preimage of.
624
+ // The receiver node aren't able to settle the payment.
625
+ // When the probe is successful, the receiver will return
626
+ // a incorrect_or_unknown_payment_details error to the sender.
627
+ func (cl * ClightningClient ) ProbePayment (scid string , amountMsat uint64 ) (bool , string , error ) {
628
+ var res ListPeerChannelsResponse
629
+ err := cl .glightning .Request (ListPeerChannelsRequest {}, & res )
630
+ if err != nil {
631
+ return false , "" , fmt .Errorf ("ListPeerChannelsRequest() %w" , err )
632
+ }
633
+ var channel PeerChannel
634
+ for _ , ch := range res .Channels {
635
+ if ch .ShortChannelId == lightning .Scid (scid ).ClnStyle () {
636
+ if err := cl .checkChannel (ch ); err != nil {
637
+ return false , "" , err
638
+ }
639
+ channel = ch
640
+ }
641
+ }
642
+
643
+ preimage , err := lightning .GetPreimage ()
644
+ if err != nil {
645
+ return false , "" , fmt .Errorf ("GetPreimage() %w" , err )
646
+ }
647
+ paymentHash := preimage .Hash ().String ()
648
+ _ , err = cl .glightning .SendPay (
649
+ []glightning.RouteHop {
650
+ {
651
+ Id : channel .PeerId ,
652
+ ShortChannelId : channel .ShortChannelId ,
653
+ AmountMsat : glightning .AmountFromMSat (amountMsat ),
654
+ // The total expected CLTV.
655
+ // The default GetRoute value of 9 is set here.
656
+ Delay : 9 ,
657
+ Direction : 0 ,
658
+ },
659
+ },
660
+ paymentHash ,
661
+ "" ,
662
+ amountMsat ,
663
+ "" ,
664
+ "" ,
665
+ 0 ,
666
+ )
667
+ if err != nil {
668
+ return false , "" , fmt .Errorf ("SendPay() %w" , err )
669
+ }
670
+ _ , err = cl .glightning .WaitSendPay (paymentHash , 0 )
671
+ if err != nil {
672
+ pe , ok := err .(* glightning.PaymentError )
673
+ if ! ok {
674
+ return false , "" , fmt .Errorf ("WaitSendPay() %w" , err )
675
+ }
676
+ failCodeWireIncorrectOrUnknownPaymentDetails := 203
677
+ if pe .RpcError .Code != failCodeWireIncorrectOrUnknownPaymentDetails {
678
+ log .Debugf ("send pay would be failed. reason:%w" , err )
679
+ return false , pe .Error (), nil
680
+ }
681
+ }
682
+ return true , "" , nil
683
+ }
684
+
622
685
type Glightninglogger struct {
623
686
plugin * glightning.Plugin
624
687
}
0 commit comments