lnrpc+rpcserver: encode custom records as custom channel data

With this commit we encode the custom records as a TLV stream into the
custom channel data field of the invoice HTLC.
This allows the custom data parser to parse those records and replace it
with human-readable JSON on the RPC interface.
This commit is contained in:
Oliver Gugger
2024-09-12 17:59:38 +02:00
parent c1aa44c476
commit 0cb599dbf6
9 changed files with 144 additions and 5 deletions

View File

@@ -10,6 +10,7 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/netann"
"google.golang.org/protobuf/proto"
)
// Config is the primary configuration struct for the invoices RPC server. It
@@ -69,4 +70,8 @@ type Config struct {
// GetAlias returns the peer's alias SCID if it exists given the
// 32-byte ChannelID.
GetAlias func(lnwire.ChannelID) (lnwire.ShortChannelID, error)
// ParseAuxData is a function that can be used to parse the auxiliary
// data from the invoice.
ParseAuxData func(message proto.Message) error
}

View File

@@ -784,6 +784,11 @@
"amp": {
"$ref": "#/definitions/lnrpcAMP",
"description": "Details relevant to AMP HTLCs, only populated if this is an AMP HTLC."
},
"custom_channel_data": {
"type": "string",
"format": "byte",
"description": "Custom channel data that might be populated in custom channels."
}
},
"title": "Details of an HTLC that paid to an invoice"

View File

@@ -222,8 +222,9 @@ func (r *ServerShell) RegisterWithRestServer(ctx context.Context,
// methods routed towards it.
//
// NOTE: This is part of the lnrpc.GrpcHandler interface.
func (r *ServerShell) CreateSubServer(configRegistry lnrpc.SubServerConfigDispatcher) (
lnrpc.SubServer, lnrpc.MacaroonPerms, error) {
func (r *ServerShell) CreateSubServer(
configRegistry lnrpc.SubServerConfigDispatcher) (lnrpc.SubServer,
lnrpc.MacaroonPerms, error) {
subServer, macPermissions, err := createNewSubServer(configRegistry)
if err != nil {
@@ -264,6 +265,14 @@ func (s *Server) SubscribeSingleInvoice(req *SubscribeSingleInvoiceRequest,
return err
}
// Give the aux data parser a chance to format the
// custom data in the invoice HTLCs.
err = s.cfg.ParseAuxData(rpcInvoice)
if err != nil {
return fmt.Errorf("error parsing custom data: "+
"%w", err)
}
if err := updateStream.Send(rpcInvoice); err != nil {
return err
}
@@ -451,7 +460,19 @@ func (s *Server) LookupInvoiceV2(ctx context.Context,
return nil, err
}
return CreateRPCInvoice(&invoice, s.cfg.ChainParams)
rpcInvoice, err := CreateRPCInvoice(&invoice, s.cfg.ChainParams)
if err != nil {
return nil, err
}
// Give the aux data parser a chance to format the custom data in the
// invoice HTLCs.
err = s.cfg.ParseAuxData(rpcInvoice)
if err != nil {
return nil, fmt.Errorf("error parsing custom data: %w", err)
}
return rpcInvoice, nil
}
// HtlcModifier is a bidirectional streaming RPC that allows a client to

View File

@@ -123,6 +123,16 @@ func CreateRPCInvoice(invoice *invoices.Invoice,
MppTotalAmtMsat: uint64(htlc.MppTotalAmt),
}
// The custom channel data is currently just the raw bytes of
// the encoded custom records.
customData, err := lnwire.CustomRecords(
htlc.CustomRecords,
).Serialize()
if err != nil {
return nil, err
}
rpcHtlc.CustomChannelData = customData
// Populate any fields relevant to AMP payments.
if htlc.AMP != nil {
rootShare := htlc.AMP.Record.RootShare()