rpcserver: add LookupHtlc call
This commit is contained in:
11 files changed
+4637
-4100
No files matched your search
@@ -1473,6 +1473,12 @@ func TestFinalHtlcs(t *testing.T) {
|
|||||||
TxPosition: 3,
|
TxPosition: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test unknown htlc lookup.
|
||||||
|
const unknownHtlcID = 999
|
||||||
|
|
||||||
|
_, err = cdb.LookupFinalHtlc(chanID, unknownHtlcID)
|
||||||
|
require.ErrorIs(t, err, ErrHtlcUnknown)
|
||||||
|
|
||||||
// Test offchain final htlcs.
|
// Test offchain final htlcs.
|
||||||
const offchainHtlcID = 1
|
const offchainHtlcID = 1
|
||||||
|
|
||||||
@@ -1489,9 +1495,23 @@ func TestFinalHtlcs(t *testing.T) {
|
|||||||
}, func() {})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
info, err := cdb.LookupFinalHtlc(chanID, offchainHtlcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, info.Settled)
|
||||||
|
require.True(t, info.Offchain)
|
||||||
|
|
||||||
// Test onchain final htlcs.
|
// Test onchain final htlcs.
|
||||||
const onchainHtlcID = 2
|
const onchainHtlcID = 2
|
||||||
|
|
||||||
err = cdb.PutOnchainFinalHtlcOutcome(chanID, onchainHtlcID, true)
|
err = cdb.PutOnchainFinalHtlcOutcome(chanID, onchainHtlcID, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
info, err = cdb.LookupFinalHtlc(chanID, onchainHtlcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, info.Settled)
|
||||||
|
require.False(t, info.Offchain)
|
||||||
|
|
||||||
|
// Test unknown htlc lookup for existing channel.
|
||||||
|
_, err = cdb.LookupFinalHtlc(chanID, unknownHtlcID)
|
||||||
|
require.ErrorIs(t, err, ErrHtlcUnknown)
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,16 @@ var (
|
|||||||
// ErrDryRunMigrationOK signals that a migration executed successful,
|
// ErrDryRunMigrationOK signals that a migration executed successful,
|
||||||
// but we intentionally did not commit the result.
|
// but we intentionally did not commit the result.
|
||||||
ErrDryRunMigrationOK = errors.New("dry run migration successful")
|
ErrDryRunMigrationOK = errors.New("dry run migration successful")
|
||||||
|
|
||||||
|
// ErrFinalHtlcsBucketNotFound signals that the top-level final htlcs
|
||||||
|
// bucket does not exist.
|
||||||
|
ErrFinalHtlcsBucketNotFound = errors.New("final htlcs bucket not " +
|
||||||
|
"found")
|
||||||
|
|
||||||
|
// ErrFinalChannelBucketNotFound signals that the channel bucket for
|
||||||
|
// final htlc outcomes does not exist.
|
||||||
|
ErrFinalChannelBucketNotFound = errors.New("final htlcs channel " +
|
||||||
|
"bucket not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
// migration is a function which takes a prior outdated version of the database
|
// migration is a function which takes a prior outdated version of the database
|
||||||
@@ -1652,6 +1662,80 @@ func (c *ChannelStateDB) FetchHistoricalChannel(outPoint *wire.OutPoint) (
|
|||||||
return channel, nil
|
return channel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fetchFinalHtlcsBucket(tx kvdb.RTx,
|
||||||
|
chanID lnwire.ShortChannelID) (kvdb.RBucket, error) {
|
||||||
|
|
||||||
|
finalHtlcsBucket := tx.ReadBucket(finalHtlcsBucket)
|
||||||
|
if finalHtlcsBucket == nil {
|
||||||
|
return nil, ErrFinalHtlcsBucketNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var chanIDBytes [8]byte
|
||||||
|
byteOrder.PutUint64(chanIDBytes[:], chanID.ToUint64())
|
||||||
|
|
||||||
|
chanBucket := finalHtlcsBucket.NestedReadBucket(chanIDBytes[:])
|
||||||
|
if chanBucket == nil {
|
||||||
|
return nil, ErrFinalChannelBucketNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return chanBucket, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrHtlcUnknown = errors.New("htlc unknown")
|
||||||
|
|
||||||
|
// LookupFinalHtlc retrieves a final htlc resolution from the database. If the
|
||||||
|
// htlc has no final resolution yet, ErrHtlcUnknown is returned.
|
||||||
|
func (c *ChannelStateDB) LookupFinalHtlc(chanID lnwire.ShortChannelID,
|
||||||
|
htlcIndex uint64) (*FinalHtlcInfo, error) {
|
||||||
|
|
||||||
|
var idBytes [8]byte
|
||||||
|
byteOrder.PutUint64(idBytes[:], htlcIndex)
|
||||||
|
|
||||||
|
var settledByte byte
|
||||||
|
|
||||||
|
err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
|
||||||
|
finalHtlcsBucket, err := fetchFinalHtlcsBucket(
|
||||||
|
tx, chanID,
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, ErrFinalHtlcsBucketNotFound):
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
case errors.Is(err, ErrFinalChannelBucketNotFound):
|
||||||
|
return ErrHtlcUnknown
|
||||||
|
|
||||||
|
case err != nil:
|
||||||
|
return fmt.Errorf("cannot fetch final htlcs bucket: %w",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value := finalHtlcsBucket.Get(idBytes[:])
|
||||||
|
if value == nil {
|
||||||
|
return ErrHtlcUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(value) != 1 {
|
||||||
|
return errors.New("unexpected final htlc value length")
|
||||||
|
}
|
||||||
|
|
||||||
|
settledByte = value[0]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, func() {
|
||||||
|
settledByte = 0
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := FinalHtlcInfo{
|
||||||
|
Settled: settledByte&byte(FinalHtlcSettledBit) != 0,
|
||||||
|
Offchain: settledByte&byte(FinalHtlcOffchainBit) != 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PutOnchainFinalHtlcOutcome stores the final on-chain outcome of an htlc in
|
// PutOnchainFinalHtlcOutcome stores the final on-chain outcome of an htlc in
|
||||||
// the database.
|
// the database.
|
||||||
func (c *ChannelStateDB) PutOnchainFinalHtlcOutcome(
|
func (c *ChannelStateDB) PutOnchainFinalHtlcOutcome(
|
||||||
|
|||||||
@@ -51,6 +51,16 @@
|
|||||||
[expose tlv data](https://github.com/lightningnetwork/lnd/pull/7085) that is
|
[expose tlv data](https://github.com/lightningnetwork/lnd/pull/7085) that is
|
||||||
broadcast over the gossip network.
|
broadcast over the gossip network.
|
||||||
|
|
||||||
|
* [Add new HTLC notifier event and lookup
|
||||||
|
RPC](https://github.com/lightningnetwork/lnd/pull/6517) for the final
|
||||||
|
settlement of incoming HTLCs. This allows applications to wait for the HTLC to
|
||||||
|
actually disappear from all valid commitment transactions, rather than assume
|
||||||
|
that it will. With the new extensions, situations can be avoided where the
|
||||||
|
application considers an HTLC settled, but in reality the HTLC has timed out.
|
||||||
|
|
||||||
|
Final resolution data will only be available for htlcs that are resolved
|
||||||
|
after upgrading lnd.
|
||||||
|
|
||||||
## Wallet
|
## Wallet
|
||||||
|
|
||||||
* [Allows Taproot public keys and tap scripts to be imported as watch-only
|
* [Allows Taproot public keys and tap scripts to be imported as watch-only
|
||||||
|
|||||||
+4252
-4100
File diff suppressed because it is too large.
Load diff
@@ -2460,6 +2460,78 @@ func local_request_Lightning_ListAliases_0(ctx context.Context, marshaler runtim
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_Lightning_LookupHtlc_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq LookupHtlcRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["chan_id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chan_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.ChanId, err = runtime.Uint64(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chan_id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["htlc_index"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "htlc_index")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.HtlcIndex, err = runtime.Uint64(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "htlc_index", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.LookupHtlc(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Lightning_LookupHtlc_0(ctx context.Context, marshaler runtime.Marshaler, server LightningServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq LookupHtlcRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["chan_id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chan_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.ChanId, err = runtime.Uint64(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chan_id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["htlc_index"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "htlc_index")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.HtlcIndex, err = runtime.Uint64(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "htlc_index", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.LookupHtlc(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterLightningHandlerServer registers the http handlers for service Lightning to "mux".
|
// RegisterLightningHandlerServer registers the http handlers for service Lightning to "mux".
|
||||||
// UnaryRPC :call LightningServer directly.
|
// UnaryRPC :call LightningServer directly.
|
||||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||||
@@ -3792,6 +3864,29 @@ func RegisterLightningHandlerServer(ctx context.Context, mux *runtime.ServeMux,
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Lightning_LookupHtlc_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)
|
||||||
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/lnrpc.Lightning/LookupHtlc", runtime.WithHTTPPathPattern("/v1/htlc/{chan_id}/{htlc_index}"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Lightning_LookupHtlc_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Lightning_LookupHtlc_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5153,6 +5248,26 @@ func RegisterLightningHandlerClient(ctx context.Context, mux *runtime.ServeMux,
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Lightning_LookupHtlc_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)
|
||||||
|
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/lnrpc.Lightning/LookupHtlc", runtime.WithHTTPPathPattern("/v1/htlc/{chan_id}/{htlc_index}"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Lightning_LookupHtlc_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Lightning_LookupHtlc_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5288,6 +5403,8 @@ var (
|
|||||||
pattern_Lightning_SubscribeCustomMessages_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "custommessage", "subscribe"}, ""))
|
pattern_Lightning_SubscribeCustomMessages_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "custommessage", "subscribe"}, ""))
|
||||||
|
|
||||||
pattern_Lightning_ListAliases_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "aliases", "list"}, ""))
|
pattern_Lightning_ListAliases_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "aliases", "list"}, ""))
|
||||||
|
|
||||||
|
pattern_Lightning_LookupHtlc_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "htlc", "chan_id", "htlc_index"}, ""))
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -5422,4 +5539,6 @@ var (
|
|||||||
forward_Lightning_SubscribeCustomMessages_0 = runtime.ForwardResponseStream
|
forward_Lightning_SubscribeCustomMessages_0 = runtime.ForwardResponseStream
|
||||||
|
|
||||||
forward_Lightning_ListAliases_0 = runtime.ForwardResponseMessage
|
forward_Lightning_ListAliases_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Lightning_LookupHtlc_0 = runtime.ForwardResponseMessage
|
||||||
)
|
)
|
||||||
@@ -1723,4 +1723,29 @@ func RegisterLightningJSONCallbacks(registry map[string]func(ctx context.Context
|
|||||||
}
|
}
|
||||||
callback(string(respBytes), nil)
|
callback(string(respBytes), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registry["lnrpc.Lightning.LookupHtlc"] = func(ctx context.Context,
|
||||||
|
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
|
||||||
|
|
||||||
|
req := &LookupHtlcRequest{}
|
||||||
|
err := marshaler.Unmarshal([]byte(reqJSON), req)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewLightningClient(conn)
|
||||||
|
resp, err := client.LookupHtlc(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := marshaler.Marshal(resp)
|
||||||
|
if err != nil {
|
||||||
|
callback("", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback(string(respBytes), nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -577,6 +577,20 @@ service Lightning {
|
|||||||
zero conf).
|
zero conf).
|
||||||
*/
|
*/
|
||||||
rpc ListAliases (ListAliasesRequest) returns (ListAliasesResponse);
|
rpc ListAliases (ListAliasesRequest) returns (ListAliasesResponse);
|
||||||
|
|
||||||
|
rpc LookupHtlc (LookupHtlcRequest) returns (LookupHtlcResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message LookupHtlcRequest {
|
||||||
|
uint64 chan_id = 1;
|
||||||
|
|
||||||
|
uint64 htlc_index = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LookupHtlcResponse {
|
||||||
|
bool settled = 1;
|
||||||
|
|
||||||
|
bool offchain = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SubscribeCustomMessagesRequest {
|
message SubscribeCustomMessagesRequest {
|
||||||
|
|||||||
@@ -1593,6 +1593,44 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/htlc/{chan_id}/{htlc_index}": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "Lightning_LookupHtlc",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/lnrpcLookupHtlcResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "chan_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"format": "uint64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "htlc_index",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"format": "uint64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Lightning"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/invoice/{r_hash_str}": {
|
"/v1/invoice/{r_hash_str}": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "lncli: `lookupinvoice`\nLookupInvoice attempts to look up an invoice according to its payment hash.\nThe passed payment hash *must* be exactly 32 bytes, if not, an error is\nreturned.",
|
"summary": "lncli: `lookupinvoice`\nLookupInvoice attempts to look up an invoice according to its payment hash.\nThe passed payment hash *must* be exactly 32 bytes, if not, an error is\nreturned.",
|
||||||
@@ -5351,6 +5389,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lnrpcLookupHtlcResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"settled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"offchain": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"lnrpcMPPRecord": {
|
"lnrpcMPPRecord": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -165,3 +165,5 @@ http:
|
|||||||
get: "/v1/custommessage/subscribe"
|
get: "/v1/custommessage/subscribe"
|
||||||
- selector: lnrpc.Lightning.ListAliases
|
- selector: lnrpc.Lightning.ListAliases
|
||||||
get: "/v1/aliases/list"
|
get: "/v1/aliases/list"
|
||||||
|
- selector: lnrpc.Lightning.LookupHtlc
|
||||||
|
get: "/v1/htlc/{chan_id}/{htlc_index}"
|
||||||
@@ -398,6 +398,7 @@ type LightningClient interface {
|
|||||||
// their confirmed SCID (if it exists) and/or the base SCID (in the case of
|
// their confirmed SCID (if it exists) and/or the base SCID (in the case of
|
||||||
// zero conf).
|
// zero conf).
|
||||||
ListAliases(ctx context.Context, in *ListAliasesRequest, opts ...grpc.CallOption) (*ListAliasesResponse, error)
|
ListAliases(ctx context.Context, in *ListAliasesRequest, opts ...grpc.CallOption) (*ListAliasesResponse, error)
|
||||||
|
LookupHtlc(ctx context.Context, in *LookupHtlcRequest, opts ...grpc.CallOption) (*LookupHtlcResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type lightningClient struct {
|
type lightningClient struct {
|
||||||
@@ -1299,6 +1300,15 @@ func (c *lightningClient) ListAliases(ctx context.Context, in *ListAliasesReques
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *lightningClient) LookupHtlc(ctx context.Context, in *LookupHtlcRequest, opts ...grpc.CallOption) (*LookupHtlcResponse, error) {
|
||||||
|
out := new(LookupHtlcResponse)
|
||||||
|
err := c.cc.Invoke(ctx, "/lnrpc.Lightning/LookupHtlc", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// LightningServer is the server API for Lightning service.
|
// LightningServer is the server API for Lightning service.
|
||||||
// All implementations must embed UnimplementedLightningServer
|
// All implementations must embed UnimplementedLightningServer
|
||||||
// for forward compatibility
|
// for forward compatibility
|
||||||
@@ -1683,6 +1693,7 @@ type LightningServer interface {
|
|||||||
// their confirmed SCID (if it exists) and/or the base SCID (in the case of
|
// their confirmed SCID (if it exists) and/or the base SCID (in the case of
|
||||||
// zero conf).
|
// zero conf).
|
||||||
ListAliases(context.Context, *ListAliasesRequest) (*ListAliasesResponse, error)
|
ListAliases(context.Context, *ListAliasesRequest) (*ListAliasesResponse, error)
|
||||||
|
LookupHtlc(context.Context, *LookupHtlcRequest) (*LookupHtlcResponse, error)
|
||||||
mustEmbedUnimplementedLightningServer()
|
mustEmbedUnimplementedLightningServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1888,6 +1899,9 @@ func (UnimplementedLightningServer) SubscribeCustomMessages(*SubscribeCustomMess
|
|||||||
func (UnimplementedLightningServer) ListAliases(context.Context, *ListAliasesRequest) (*ListAliasesResponse, error) {
|
func (UnimplementedLightningServer) ListAliases(context.Context, *ListAliasesRequest) (*ListAliasesResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListAliases not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method ListAliases not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedLightningServer) LookupHtlc(context.Context, *LookupHtlcRequest) (*LookupHtlcResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method LookupHtlc not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedLightningServer) mustEmbedUnimplementedLightningServer() {}
|
func (UnimplementedLightningServer) mustEmbedUnimplementedLightningServer() {}
|
||||||
|
|
||||||
// UnsafeLightningServer may be embedded to opt out of forward compatibility for this service.
|
// UnsafeLightningServer may be embedded to opt out of forward compatibility for this service.
|
||||||
@@ -3148,6 +3162,24 @@ func _Lightning_ListAliases_Handler(srv interface{}, ctx context.Context, dec fu
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Lightning_LookupHtlc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(LookupHtlcRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(LightningServer).LookupHtlc(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/lnrpc.Lightning/LookupHtlc",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(LightningServer).LookupHtlc(ctx, req.(*LookupHtlcRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// Lightning_ServiceDesc is the grpc.ServiceDesc for Lightning service.
|
// Lightning_ServiceDesc is the grpc.ServiceDesc for Lightning service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@@ -3367,6 +3399,10 @@ var Lightning_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "ListAliases",
|
MethodName: "ListAliases",
|
||||||
Handler: _Lightning_ListAliases_Handler,
|
Handler: _Lightning_ListAliases_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "LookupHtlc",
|
||||||
|
Handler: _Lightning_LookupHtlc_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{
|
Streams: []grpc.StreamDesc{
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -577,6 +577,10 @@ func MainRPCServerPermissions() map[string][]bakery.Op {
|
|||||||
Entity: "offchain",
|
Entity: "offchain",
|
||||||
Action: "read",
|
Action: "read",
|
||||||
}},
|
}},
|
||||||
|
"/lnrpc.Lightning/LookupHtlc": {{
|
||||||
|
Entity: "offchain",
|
||||||
|
Action: "read",
|
||||||
|
}},
|
||||||
"/lnrpc.Lightning/ListAliases": {{
|
"/lnrpc.Lightning/ListAliases": {{
|
||||||
Entity: "offchain",
|
Entity: "offchain",
|
||||||
Action: "read",
|
Action: "read",
|
||||||
@@ -3904,6 +3908,28 @@ func (r *rpcServer) ClosedChannels(ctx context.Context,
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LookupHtlc retrieves a final htlc resolution from the database. If the htlc
|
||||||
|
// has no final resolution yet, a NotFound grpc status code is returned.
|
||||||
|
func (r *rpcServer) LookupHtlc(ctx context.Context,
|
||||||
|
in *lnrpc.LookupHtlcRequest) (*lnrpc.LookupHtlcResponse, error) {
|
||||||
|
|
||||||
|
chanID := lnwire.NewShortChanIDFromInt(in.ChanId)
|
||||||
|
|
||||||
|
info, err := r.server.chanStateDB.LookupFinalHtlc(chanID, in.HtlcIndex)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, channeldb.ErrHtlcUnknown):
|
||||||
|
return nil, status.Error(codes.NotFound, err.Error())
|
||||||
|
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lnrpc.LookupHtlcResponse{
|
||||||
|
Settled: info.Settled,
|
||||||
|
Offchain: info.Offchain,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListChannels returns a description of all the open channels that this node
|
// ListChannels returns a description of all the open channels that this node
|
||||||
// is a participant in.
|
// is a participant in.
|
||||||
func (r *rpcServer) ListChannels(ctx context.Context,
|
func (r *rpcServer) ListChannels(ctx context.Context,
|
||||||
|
|||||||
Reference in new issue
Block a user