Merge pull request #9625 from MPins/issue-8161
Add deletecanceledinvoice RPC call
This commit is contained in:
15 files changed
+2203
-1616
No files matched your search
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AddInvoiceCommand = cli.Command{
|
var AddInvoiceCommand = cli.Command{
|
||||||
@@ -440,3 +441,56 @@ func decodePayReq(ctx *cli.Context) error {
|
|||||||
printRespJSON(resp)
|
printRespJSON(resp)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var deleteCanceledInvoiceCommand = cli.Command{
|
||||||
|
Name: "deletecanceledinvoice",
|
||||||
|
Category: "Invoices",
|
||||||
|
Usage: "Delete a canceled invoice from the database.",
|
||||||
|
ArgsUsage: "invoice_hash",
|
||||||
|
Description: `
|
||||||
|
This command deletes a canceled invoice from the database. Note that
|
||||||
|
expired invoices are automatically moved to the canceled state.
|
||||||
|
Once canceled, they can be deleted using this command.
|
||||||
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "invoice_hash",
|
||||||
|
Usage: "the invoice hash to be deleted",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(deleteCanceledInvoice),
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteCanceledInvoice(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
client, cleanUp := getClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
var (
|
||||||
|
invoiceHash string
|
||||||
|
err error
|
||||||
|
resp proto.Message
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("invoice_hash"):
|
||||||
|
invoiceHash = ctx.String("invoice_hash")
|
||||||
|
case ctx.Args().Present():
|
||||||
|
invoiceHash = ctx.Args().First()
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invoice_hash argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &lnrpc.DelCanceledInvoiceReq{
|
||||||
|
InvoiceHash: invoiceHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = client.DeleteCanceledInvoice(ctxc, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printJSON(resp)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -478,6 +478,7 @@ func Main() {
|
|||||||
AddInvoiceCommand,
|
AddInvoiceCommand,
|
||||||
lookupInvoiceCommand,
|
lookupInvoiceCommand,
|
||||||
listInvoicesCommand,
|
listInvoicesCommand,
|
||||||
|
deleteCanceledInvoiceCommand,
|
||||||
ListChannelsCommand,
|
ListChannelsCommand,
|
||||||
closedChannelsCommand,
|
closedChannelsCommand,
|
||||||
listPaymentsCommand,
|
listPaymentsCommand,
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ circuit. The indices are only available for forwarding events saved after v0.20.
|
|||||||
1MB, and `gossip.msg-burst-bytes` has been increased from 200KB to 2MB.
|
1MB, and `gossip.msg-burst-bytes` has been increased from 200KB to 2MB.
|
||||||
|
|
||||||
|
|
||||||
|
* Added [`deletecanceledinvoices`](
|
||||||
|
https://github.com/lightningnetwork/lnd/pull/9625) RPC to allow the removal of
|
||||||
|
a canceled invoice. Supports deleting a canceled invoice by providing its
|
||||||
|
payment hash.
|
||||||
|
|
||||||
## lncli Additions
|
## lncli Additions
|
||||||
|
|
||||||
* [`lncli sendpayment` and `lncli queryroutes` now support the
|
* [`lncli sendpayment` and `lncli queryroutes` now support the
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ var (
|
|||||||
// canceled.
|
// canceled.
|
||||||
ErrInvoiceAlreadyCanceled = errors.New("invoice already canceled")
|
ErrInvoiceAlreadyCanceled = errors.New("invoice already canceled")
|
||||||
|
|
||||||
|
// ErrInvoiceNotCanceled is returned when the invoice is not canceled.
|
||||||
|
ErrInvoiceNotCanceled = errors.New("invoice not canceled")
|
||||||
|
|
||||||
// ErrInvoiceAlreadyAccepted is returned when the invoice is already
|
// ErrInvoiceAlreadyAccepted is returned when the invoice is already
|
||||||
// accepted.
|
// accepted.
|
||||||
ErrInvoiceAlreadyAccepted = errors.New("invoice already accepted")
|
ErrInvoiceAlreadyAccepted = errors.New("invoice already accepted")
|
||||||
@@ -33,6 +36,10 @@ var (
|
|||||||
// match the invoice hash.
|
// match the invoice hash.
|
||||||
ErrInvoicePreimageMismatch = errors.New("preimage does not match")
|
ErrInvoicePreimageMismatch = errors.New("preimage does not match")
|
||||||
|
|
||||||
|
// ErrNoInvoiceHash is returned when an invoice hash is expected, and
|
||||||
|
// none is provided.
|
||||||
|
ErrNoInvoiceHash = errors.New("invoice hash must be provided")
|
||||||
|
|
||||||
// ErrHTLCPreimageMissing is returned when trying to accept/settle an
|
// ErrHTLCPreimageMissing is returned when trying to accept/settle an
|
||||||
// AMP HTLC but the HTLC-level preimage has not been set.
|
// AMP HTLC but the HTLC-level preimage has not been set.
|
||||||
ErrHTLCPreimageMissing = errors.New("AMP htlc missing preimage")
|
ErrHTLCPreimageMissing = errors.New("AMP htlc missing preimage")
|
||||||
|
|||||||
@@ -727,6 +727,10 @@ var allTestCases = []*lntest.TestCase{
|
|||||||
Name: "grpc not found",
|
Name: "grpc not found",
|
||||||
TestFunc: testGRPCNotFound,
|
TestFunc: testGRPCNotFound,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "delete canceled invoice",
|
||||||
|
TestFunc: testDeleteCanceledInvoice,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendPrefixed is used to add a prefix to each test name in the subtests
|
// appendPrefixed is used to add a prefix to each test name in the subtests
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package itest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/invoices"
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lntest"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testDeleteCanceledInvoice(ht *lntest.HarnessTest) {
|
||||||
|
bob := ht.NewNode("bob", nil)
|
||||||
|
|
||||||
|
// Create 2 invoices for Bob.
|
||||||
|
const numInvoices = 2
|
||||||
|
invoiceResp := make([]*lnrpc.AddInvoiceResponse, numInvoices)
|
||||||
|
|
||||||
|
for i := range numInvoices {
|
||||||
|
// Create a unique 32-byte preimage for each invoice.
|
||||||
|
preimage := bytes.Repeat([]byte{byte(i + 1)}, 32)
|
||||||
|
|
||||||
|
invoice := &lnrpc.Invoice{
|
||||||
|
RPreimage: preimage,
|
||||||
|
Value: paymentAmt,
|
||||||
|
}
|
||||||
|
|
||||||
|
invoiceResp[i] = bob.RPC.AddInvoice(invoice)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel all invoices except the last one.
|
||||||
|
for i := range numInvoices - 1 {
|
||||||
|
bob.RPC.CancelInvoice(invoiceResp[i].RHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's assert an error while providing no invoice hash.
|
||||||
|
bob.RPC.DeleteCanceledInvoiceAssertErr(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{},
|
||||||
|
invoices.ErrNoInvoiceHash.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Let's assert an error while providing a hash with an invalid length.
|
||||||
|
bob.RPC.DeleteCanceledInvoiceAssertErr(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{InvoiceHash: "bb02fbfa62983b6b62"},
|
||||||
|
"invalid hash string length",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Let's assert an error is returned for a hash with invalid encoding.
|
||||||
|
bob.RPC.DeleteCanceledInvoiceAssertErr(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{
|
||||||
|
InvoiceHash: "bb02fbfa62983b6b621376bf8230732dd3a6dce" +
|
||||||
|
"a9f5df803c0935ae6ce7440dg",
|
||||||
|
}, "encoding/hex: invalid byte",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Let's delete one canceled invoice.
|
||||||
|
invoiceToDelete := lntypes.Hash(invoiceResp[0].RHash).String()
|
||||||
|
resp := bob.RPC.DeleteCanceledInvoice(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{InvoiceHash: invoiceToDelete},
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Contains(
|
||||||
|
ht, resp.String(), "canceled invoice deleted successfully",
|
||||||
|
)
|
||||||
|
|
||||||
|
respList := bob.RPC.ListInvoices(&lnrpc.ListInvoiceRequest{})
|
||||||
|
|
||||||
|
// Assert that the invoice was deleted.
|
||||||
|
require.Len(ht, respList.Invoices, numInvoices-1)
|
||||||
|
|
||||||
|
// Let's assert an error while deleting a non-existent invoice.
|
||||||
|
bob.RPC.DeleteCanceledInvoiceAssertErr(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{InvoiceHash: invoiceToDelete},
|
||||||
|
invoices.ErrInvoiceNotFound.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Let's assert an error while deleting a non canceled invoice.
|
||||||
|
notCanceledInvoice := lntypes.Hash(invoiceResp[numInvoices-1].RHash).
|
||||||
|
String()
|
||||||
|
|
||||||
|
bob.RPC.DeleteCanceledInvoiceAssertErr(
|
||||||
|
&lnrpc.DelCanceledInvoiceReq{InvoiceHash: notCanceledInvoice},
|
||||||
|
invoices.ErrInvoiceNotCanceled.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Assert that the last invoice in the invoiceResp is still present and
|
||||||
|
// OPEN.
|
||||||
|
respList = bob.RPC.ListInvoices(&lnrpc.ListInvoiceRequest{})
|
||||||
|
require.Equal(
|
||||||
|
ht, invoiceResp[numInvoices-1].RHash,
|
||||||
|
respList.Invoices[0].RHash,
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Equal(ht, lnrpc.Invoice_OPEN, respList.Invoices[0].State)
|
||||||
|
|
||||||
|
// Assert that just one invoice exists.
|
||||||
|
require.Len(ht, respList.Invoices, 1)
|
||||||
|
}
|
||||||
+1752
-1616
File diff suppressed because it is too large.
Load diff
@@ -1305,6 +1305,42 @@ func request_Lightning_SubscribeInvoices_0(ctx context.Context, marshaler runtim
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Lightning_DeleteCanceledInvoice_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Lightning_DeleteCanceledInvoice_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq DelCanceledInvoiceReq
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Lightning_DeleteCanceledInvoice_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.DeleteCanceledInvoice(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Lightning_DeleteCanceledInvoice_0(ctx context.Context, marshaler runtime.Marshaler, server LightningServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq DelCanceledInvoiceReq
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Lightning_DeleteCanceledInvoice_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.DeleteCanceledInvoice(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_Lightning_DecodePayReq_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_Lightning_DecodePayReq_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq PayReqString
|
var protoReq PayReqString
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
@@ -3339,6 +3375,31 @@ func RegisterLightningHandlerServer(ctx context.Context, mux *runtime.ServeMux,
|
|||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("DELETE", pattern_Lightning_DeleteCanceledInvoice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/lnrpc.Lightning/DeleteCanceledInvoice", runtime.WithHTTPPathPattern("/v1/invoices"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Lightning_DeleteCanceledInvoice_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Lightning_DeleteCanceledInvoice_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_Lightning_DecodePayReq_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_Lightning_DecodePayReq_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -4900,6 +4961,28 @@ func RegisterLightningHandlerClient(ctx context.Context, mux *runtime.ServeMux,
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("DELETE", pattern_Lightning_DeleteCanceledInvoice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/lnrpc.Lightning/DeleteCanceledInvoice", runtime.WithHTTPPathPattern("/v1/invoices"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Lightning_DeleteCanceledInvoice_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Lightning_DeleteCanceledInvoice_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_Lightning_DecodePayReq_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_Lightning_DecodePayReq_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -5680,6 +5763,8 @@ var (
|
|||||||
|
|
||||||
pattern_Lightning_SubscribeInvoices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "invoices", "subscribe"}, ""))
|
pattern_Lightning_SubscribeInvoices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "invoices", "subscribe"}, ""))
|
||||||
|
|
||||||
|
pattern_Lightning_DeleteCanceledInvoice_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "invoices"}, ""))
|
||||||
|
|
||||||
pattern_Lightning_DecodePayReq_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "payreq", "pay_req"}, ""))
|
pattern_Lightning_DecodePayReq_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "payreq", "pay_req"}, ""))
|
||||||
|
|
||||||
pattern_Lightning_ListPayments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "payments"}, ""))
|
pattern_Lightning_ListPayments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "payments"}, ""))
|
||||||
@@ -5818,6 +5903,8 @@ var (
|
|||||||
|
|
||||||
forward_Lightning_SubscribeInvoices_0 = runtime.ForwardResponseStream
|
forward_Lightning_SubscribeInvoices_0 = runtime.ForwardResponseStream
|
||||||
|
|
||||||
|
forward_Lightning_DeleteCanceledInvoice_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Lightning_DecodePayReq_0 = runtime.ForwardResponseMessage
|
forward_Lightning_DecodePayReq_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Lightning_ListPayments_0 = runtime.ForwardResponseMessage
|
forward_Lightning_ListPayments_0 = runtime.ForwardResponseMessage
|
||||||
|
|||||||
@@ -973,6 +973,31 @@ func RegisterLightningJSONCallbacks(registry map[string]func(ctx context.Context
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registry["lnrpc.Lightning.DeleteCanceledInvoice"] = func(ctx context.Context,
|
||||||
|
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
|
||||||
|
|
||||||
|
req := &DelCanceledInvoiceReq{}
|
||||||
|
err := marshaler.Unmarshal([]byte(reqJSON), req)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewLightningClient(conn)
|
||||||
|
resp, err := client.DeleteCanceledInvoice(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := marshaler.Marshal(resp)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback(string(respBytes), nil)
|
||||||
|
}
|
||||||
|
|
||||||
registry["lnrpc.Lightning.DecodePayReq"] = func(ctx context.Context,
|
registry["lnrpc.Lightning.DecodePayReq"] = func(ctx context.Context,
|
||||||
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
|
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
|
||||||
|
|
||||||
|
|||||||
@@ -341,6 +341,13 @@ service Lightning {
|
|||||||
*/
|
*/
|
||||||
rpc SubscribeInvoices (InvoiceSubscription) returns (stream Invoice);
|
rpc SubscribeInvoices (InvoiceSubscription) returns (stream Invoice);
|
||||||
|
|
||||||
|
/* lncli: `deletecanceledinvoice`
|
||||||
|
DeleteCanceledInvoice removes a canceled invoice from the database. If the
|
||||||
|
invoice is not in the canceled state, an error will be returned.
|
||||||
|
*/
|
||||||
|
rpc DeleteCanceledInvoice (DelCanceledInvoiceReq)
|
||||||
|
returns (DelCanceledInvoiceResp);
|
||||||
|
|
||||||
/* lncli: `decodepayreq`
|
/* lncli: `decodepayreq`
|
||||||
DecodePayReq takes an encoded payment request string and attempts to decode
|
DecodePayReq takes an encoded payment request string and attempts to decode
|
||||||
it, returning a full description of the conditions encoded within the
|
it, returning a full description of the conditions encoded within the
|
||||||
@@ -4234,6 +4241,16 @@ message InvoiceSubscription {
|
|||||||
uint64 settle_index = 2;
|
uint64 settle_index = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DelCanceledInvoiceReq {
|
||||||
|
// Invoice payment hash to delete.
|
||||||
|
string invoice_hash = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DelCanceledInvoiceResp {
|
||||||
|
// The status of the delete operation.
|
||||||
|
string status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
enum PaymentFailureReason {
|
enum PaymentFailureReason {
|
||||||
/*
|
/*
|
||||||
Payment isn't failed (yet).
|
Payment isn't failed (yet).
|
||||||
|
|||||||
@@ -1874,6 +1874,36 @@
|
|||||||
"Lightning"
|
"Lightning"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "lncli: `deletecanceledinvoice`\nDeleteCanceledInvoice removes a canceled invoice from the database. If the\ninvoice is not in the canceled state, an error will be returned.",
|
||||||
|
"operationId": "Lightning_DeleteCanceledInvoice",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/lnrpcDelCanceledInvoiceResp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "invoice_hash",
|
||||||
|
"description": "Invoice payment hash to delete.",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Lightning"
|
||||||
|
]
|
||||||
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "lncli: `addinvoice`\nAddInvoice attempts to add a new invoice to the invoice database. Any\nduplicated invoices are rejected, therefore all invoices *must* have a\nunique payment preimage.",
|
"summary": "lncli: `addinvoice`\nAddInvoice attempts to add a new invoice to the invoice database. Any\nduplicated invoices are rejected, therefore all invoices *must* have a\nunique payment preimage.",
|
||||||
"operationId": "Lightning_AddInvoice",
|
"operationId": "Lightning_AddInvoice",
|
||||||
@@ -4857,6 +4887,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lnrpcDelCanceledInvoiceResp": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The status of the delete operation."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"lnrpcDeleteAllPaymentsResponse": {
|
"lnrpcDeleteAllPaymentsResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ http:
|
|||||||
get: "/v1/invoice/{r_hash_str}"
|
get: "/v1/invoice/{r_hash_str}"
|
||||||
- selector: lnrpc.Lightning.SubscribeInvoices
|
- selector: lnrpc.Lightning.SubscribeInvoices
|
||||||
get: "/v1/invoices/subscribe"
|
get: "/v1/invoices/subscribe"
|
||||||
|
- selector: lnrpc.Lightning.DeleteCanceledInvoice
|
||||||
|
delete: "/v1/invoices"
|
||||||
- selector: lnrpc.Lightning.DecodePayReq
|
- selector: lnrpc.Lightning.DecodePayReq
|
||||||
get: "/v1/payreq/{pay_req}"
|
get: "/v1/payreq/{pay_req}"
|
||||||
- selector: lnrpc.Lightning.DeletePayment
|
- selector: lnrpc.Lightning.DeletePayment
|
||||||
|
|||||||
@@ -243,6 +243,10 @@ type LightningClient interface {
|
|||||||
// of these fields can be set. If no fields are set, then we'll only send out
|
// of these fields can be set. If no fields are set, then we'll only send out
|
||||||
// the latest add/settle events.
|
// the latest add/settle events.
|
||||||
SubscribeInvoices(ctx context.Context, in *InvoiceSubscription, opts ...grpc.CallOption) (Lightning_SubscribeInvoicesClient, error)
|
SubscribeInvoices(ctx context.Context, in *InvoiceSubscription, opts ...grpc.CallOption) (Lightning_SubscribeInvoicesClient, error)
|
||||||
|
// lncli: `deletecanceledinvoice`
|
||||||
|
// DeleteCanceledInvoice removes a canceled invoice from the database. If the
|
||||||
|
// invoice is not in the canceled state, an error will be returned.
|
||||||
|
DeleteCanceledInvoice(ctx context.Context, in *DelCanceledInvoiceReq, opts ...grpc.CallOption) (*DelCanceledInvoiceResp, error)
|
||||||
// lncli: `decodepayreq`
|
// lncli: `decodepayreq`
|
||||||
// DecodePayReq takes an encoded payment request string and attempts to decode
|
// DecodePayReq takes an encoded payment request string and attempts to decode
|
||||||
// it, returning a full description of the conditions encoded within the
|
// it, returning a full description of the conditions encoded within the
|
||||||
@@ -973,6 +977,15 @@ func (x *lightningSubscribeInvoicesClient) Recv() (*Invoice, error) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *lightningClient) DeleteCanceledInvoice(ctx context.Context, in *DelCanceledInvoiceReq, opts ...grpc.CallOption) (*DelCanceledInvoiceResp, error) {
|
||||||
|
out := new(DelCanceledInvoiceResp)
|
||||||
|
err := c.cc.Invoke(ctx, "/lnrpc.Lightning/DeleteCanceledInvoice", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *lightningClient) DecodePayReq(ctx context.Context, in *PayReqString, opts ...grpc.CallOption) (*PayReq, error) {
|
func (c *lightningClient) DecodePayReq(ctx context.Context, in *PayReqString, opts ...grpc.CallOption) (*PayReq, error) {
|
||||||
out := new(PayReq)
|
out := new(PayReq)
|
||||||
err := c.cc.Invoke(ctx, "/lnrpc.Lightning/DecodePayReq", in, out, opts...)
|
err := c.cc.Invoke(ctx, "/lnrpc.Lightning/DecodePayReq", in, out, opts...)
|
||||||
@@ -1572,6 +1585,10 @@ type LightningServer interface {
|
|||||||
// of these fields can be set. If no fields are set, then we'll only send out
|
// of these fields can be set. If no fields are set, then we'll only send out
|
||||||
// the latest add/settle events.
|
// the latest add/settle events.
|
||||||
SubscribeInvoices(*InvoiceSubscription, Lightning_SubscribeInvoicesServer) error
|
SubscribeInvoices(*InvoiceSubscription, Lightning_SubscribeInvoicesServer) error
|
||||||
|
// lncli: `deletecanceledinvoice`
|
||||||
|
// DeleteCanceledInvoice removes a canceled invoice from the database. If the
|
||||||
|
// invoice is not in the canceled state, an error will be returned.
|
||||||
|
DeleteCanceledInvoice(context.Context, *DelCanceledInvoiceReq) (*DelCanceledInvoiceResp, error)
|
||||||
// lncli: `decodepayreq`
|
// lncli: `decodepayreq`
|
||||||
// DecodePayReq takes an encoded payment request string and attempts to decode
|
// DecodePayReq takes an encoded payment request string and attempts to decode
|
||||||
// it, returning a full description of the conditions encoded within the
|
// it, returning a full description of the conditions encoded within the
|
||||||
@@ -1869,6 +1886,9 @@ func (UnimplementedLightningServer) LookupInvoice(context.Context, *PaymentHash)
|
|||||||
func (UnimplementedLightningServer) SubscribeInvoices(*InvoiceSubscription, Lightning_SubscribeInvoicesServer) error {
|
func (UnimplementedLightningServer) SubscribeInvoices(*InvoiceSubscription, Lightning_SubscribeInvoicesServer) error {
|
||||||
return status.Errorf(codes.Unimplemented, "method SubscribeInvoices not implemented")
|
return status.Errorf(codes.Unimplemented, "method SubscribeInvoices not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedLightningServer) DeleteCanceledInvoice(context.Context, *DelCanceledInvoiceReq) (*DelCanceledInvoiceResp, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method DeleteCanceledInvoice not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedLightningServer) DecodePayReq(context.Context, *PayReqString) (*PayReq, error) {
|
func (UnimplementedLightningServer) DecodePayReq(context.Context, *PayReqString) (*PayReq, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method DecodePayReq not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method DecodePayReq not implemented")
|
||||||
}
|
}
|
||||||
@@ -2683,6 +2703,24 @@ func (x *lightningSubscribeInvoicesServer) Send(m *Invoice) error {
|
|||||||
return x.ServerStream.SendMsg(m)
|
return x.ServerStream.SendMsg(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Lightning_DeleteCanceledInvoice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(DelCanceledInvoiceReq)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(LightningServer).DeleteCanceledInvoice(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/lnrpc.Lightning/DeleteCanceledInvoice",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(LightningServer).DeleteCanceledInvoice(ctx, req.(*DelCanceledInvoiceReq))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _Lightning_DecodePayReq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _Lightning_DecodePayReq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(PayReqString)
|
in := new(PayReqString)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@@ -3377,6 +3415,10 @@ var Lightning_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "LookupInvoice",
|
MethodName: "LookupInvoice",
|
||||||
Handler: _Lightning_LookupInvoice_Handler,
|
Handler: _Lightning_LookupInvoice_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "DeleteCanceledInvoice",
|
||||||
|
Handler: _Lightning_DeleteCanceledInvoice_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "DecodePayReq",
|
MethodName: "DecodePayReq",
|
||||||
Handler: _Lightning_DecodePayReq_Handler,
|
Handler: _Lightning_DecodePayReq_Handler,
|
||||||
|
|||||||
@@ -831,3 +831,29 @@ func (h *HarnessRPC) SubscribePeerEvents(
|
|||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteCanceledInvoice makes a RPC call to the node's DeleteCanceledInvoice
|
||||||
|
// and asserts.
|
||||||
|
func (h *HarnessRPC) DeleteCanceledInvoice(
|
||||||
|
req *lnrpc.DelCanceledInvoiceReq) *lnrpc.DelCanceledInvoiceResp {
|
||||||
|
|
||||||
|
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
resp, err := h.LN.DeleteCanceledInvoice(ctxt, req)
|
||||||
|
h.NoError(err, "DeleteCanceledInvoice")
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCanceledInvoiceAssertErr makes a RPC call to the node's
|
||||||
|
// DeleteCanceledInvoice and asserts if an RPC error is returned.
|
||||||
|
func (h *HarnessRPC) DeleteCanceledInvoiceAssertErr(
|
||||||
|
req *lnrpc.DelCanceledInvoiceReq, errStr string) {
|
||||||
|
|
||||||
|
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
_, err := h.LN.DeleteCanceledInvoice(ctxt, req)
|
||||||
|
require.ErrorContains(h, err, errStr)
|
||||||
|
}
|
||||||
@@ -467,6 +467,10 @@ func MainRPCServerPermissions() map[string][]bakery.Op {
|
|||||||
Entity: "info",
|
Entity: "info",
|
||||||
Action: "read",
|
Action: "read",
|
||||||
}},
|
}},
|
||||||
|
"/lnrpc.Lightning/DeleteCanceledInvoice": {{
|
||||||
|
Entity: "invoices",
|
||||||
|
Action: "write",
|
||||||
|
}},
|
||||||
"/lnrpc.Lightning/ListPayments": {{
|
"/lnrpc.Lightning/ListPayments": {{
|
||||||
Entity: "offchain",
|
Entity: "offchain",
|
||||||
Action: "read",
|
Action: "read",
|
||||||
@@ -7550,6 +7554,45 @@ func (r *rpcServer) ListPayments(ctx context.Context,
|
|||||||
return paymentsResp, nil
|
return paymentsResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteCanceledInvoice remove a canceled invoice from the database.
|
||||||
|
func (r *rpcServer) DeleteCanceledInvoice(ctx context.Context,
|
||||||
|
req *lnrpc.DelCanceledInvoiceReq) (*lnrpc.DelCanceledInvoiceResp,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
if req.InvoiceHash == "" {
|
||||||
|
return nil, invoices.ErrNoInvoiceHash
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := lntypes.MakeHashFromStr(req.InvoiceHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
invoice, err := r.server.invoices.LookupInvoice(ctx, hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if invoice.State != invoices.ContractCanceled {
|
||||||
|
return nil, invoices.ErrInvoiceNotCanceled
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.server.invoicesDB.DeleteInvoice(ctx,
|
||||||
|
[]invoices.InvoiceDeleteRef{
|
||||||
|
{
|
||||||
|
PayHash: hash,
|
||||||
|
AddIndex: invoice.AddIndex,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lnrpc.DelCanceledInvoiceResp{Status: fmt.Sprintf("canceled "+
|
||||||
|
"invoice deleted successfully: invoice hash %v", hash)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeletePayment deletes a payment from the DB given its payment hash. If
|
// DeletePayment deletes a payment from the DB given its payment hash. If
|
||||||
// failedHtlcsOnly is set, only failed HTLC attempts of the payment will be
|
// failedHtlcsOnly is set, only failed HTLC attempts of the payment will be
|
||||||
// deleted.
|
// deleted.
|
||||||
|
|||||||
Reference in new issue
Block a user