lnrpc: add auth_proof to graph APIs

Added flag include_auth_proof to DescribeGraph, GetNodeInfo, GetChanInfo
and the corresponding lncli commands. With the flag, these APIs add AuthProof
(signatures from the channel announcement) to the returned ChannelEdge.

This is useful to extract this data from the DB.
This commit is contained in:
Boris Nagaev committed 2025-06-19 18:19:33 -03:00
1 parent 40efefeb6a
commit 7a70dcb36e
6 files changed
+2689 -2365

No files matched your search

+23 -4
View File
@@ -1987,6 +1987,11 @@ var describeGraphCommand = cli.Command{
"graph. Unannounced channels are both private channels, and " +
"public channels that are not yet announced to the network.",
},
cli.BoolFlag{
Name: "include_auth_proof",
Usage: "If set, will include announcements' " +
"signatures into ChannelEdge.",
},
},
Action: actionDecorator(describeGraph),
}
@@ -1998,6 +2003,7 @@ func describeGraph(ctx *cli.Context) error {
req := &lnrpc.ChannelGraphRequest{
IncludeUnannounced: ctx.Bool("include_unannounced"),
IncludeAuthProof: ctx.Bool("include_auth_proof"),
}
graph, err := client.DescribeGraph(ctxc, req)
@@ -2055,6 +2061,11 @@ var getChanInfoCommand = cli.Command{
"the chan_id param is set this param is " +
"ignored.",
},
cli.BoolFlag{
Name: "include_auth_proof",
Usage: "If set, will include announcements' " +
"signatures into ChannelEdge.",
},
},
Action: actionDecorator(getChanInfo),
}
@@ -2088,8 +2099,9 @@ func getChanInfo(ctx *cli.Context) error {
}
req := &lnrpc.ChanInfoRequest{
ChanId: chanID,
ChanPoint: chanPoint,
ChanId: chanID,
ChanPoint: chanPoint,
IncludeAuthProof: ctx.Bool("include_auth_proof"),
}
chanInfo, err := client.GetChanInfo(ctxc, req)
@@ -2118,6 +2130,12 @@ var getNodeInfoCommand = cli.Command{
Usage: "if true, will return all known channels " +
"associated with the node",
},
cli.BoolFlag{
Name: "include_auth_proof",
Usage: "If set, will include announcements' " +
"signatures into ChannelEdge. Depends on " +
"include_channels",
},
},
Action: actionDecorator(getNodeInfo),
}
@@ -2140,8 +2158,9 @@ func getNodeInfo(ctx *cli.Context) error {
}
req := &lnrpc.NodeInfoRequest{
PubKey: pubKey,
IncludeChannels: ctx.Bool("include_channels"),
PubKey: pubKey,
IncludeChannels: ctx.Bool("include_channels"),
IncludeAuthProof: ctx.Bool("include_auth_proof"),
}
nodeInfo, err := client.GetNodeInfo(ctxc, req)
+30
View File
@@ -106,6 +106,32 @@
}
}
},
"lnrpcChannelAuthProof": {
"type": "object",
"properties": {
"node_sig1": {
"type": "string",
"format": "byte",
"description": "node_sig1 are the raw bytes of the first node signature encoded\nin DER format."
},
"bitcoin_sig1": {
"type": "string",
"format": "byte",
"description": "bitcoin_sig1 are the raw bytes of the first bitcoin signature of the\nMultiSigKey key of the channel encoded in DER format."
},
"node_sig2": {
"type": "string",
"format": "byte",
"description": "node_sig2 are the raw bytes of the second node signature encoded\nin DER format."
},
"bitcoin_sig2": {
"type": "string",
"format": "byte",
"description": "bitcoin_sig2 are the raw bytes of the second bitcoin signature of the\nMultiSigKey key of the channel encoded in DER format."
}
},
"description": "ChannelAuthProof is the authentication proof (the signature portion) for a\nchannel. Using the four signatures contained in the struct, and some\nauxiliary knowledge (the funding script, node identities, and outpoint) nodes\non the network are able to validate the authenticity and existence of a\nchannel."
},
"lnrpcChannelEdge": {
"type": "object",
"properties": {
@@ -144,6 +170,10 @@
"format": "byte"
},
"description": "Custom channel announcement tlv records."
},
"auth_proof": {
"$ref": "#/definitions/lnrpcChannelAuthProof",
"description": "Authentication proof for this channel. This proof contains a set of\nsignatures binding four identities, which attests to the legitimacy of\nthe advertised channel. This only is available for advertised channels.\nThis field is not filled by default. Pass include_auth_proof flag to\nDescribeGraph, GetNodeInfo or GetChanInfo to get this data."
}
},
"description": "A fully authenticated channel along with all its unique attributes.\nOnce an authenticated channel announcement has been processed on the network,\nthen an instance of ChannelEdgeInfo encapsulating the channels attributes is\nstored. The other portions relevant to routing policy of a channel are stored\nwithin a ChannelEdgePolicy for each direction of the channel."
+2517 -2357
View File
File diff suppressed because it is too large. Load diff
+42
View File
@@ -3421,6 +3421,10 @@ message NodeInfoRequest {
// If true, will include all known channels associated with the node.
bool include_channels = 2;
// If true, will include announcements' signatures into ChannelEdge.
// Depends on include_channels.
bool include_auth_proof = 3;
}
message NodeInfo {
@@ -3481,6 +3485,31 @@ message RoutingPolicy {
int32 inbound_fee_rate_milli_msat = 10;
}
/*
ChannelAuthProof is the authentication proof (the signature portion) for a
channel. Using the four signatures contained in the struct, and some
auxiliary knowledge (the funding script, node identities, and outpoint) nodes
on the network are able to validate the authenticity and existence of a
channel.
*/
message ChannelAuthProof {
// node_sig1 are the raw bytes of the first node signature encoded
// in DER format.
bytes node_sig1 = 1;
// bitcoin_sig1 are the raw bytes of the first bitcoin signature of the
// MultiSigKey key of the channel encoded in DER format.
bytes bitcoin_sig1 = 2;
// node_sig2 are the raw bytes of the second node signature encoded
// in DER format.
bytes node_sig2 = 3;
// bitcoin_sig2 are the raw bytes of the second bitcoin signature of the
// MultiSigKey key of the channel encoded in DER format.
bytes bitcoin_sig2 = 4;
}
/*
A fully authenticated channel along with all its unique attributes.
Once an authenticated channel announcement has been processed on the network,
@@ -3509,6 +3538,13 @@ message ChannelEdge {
// Custom channel announcement tlv records.
map<uint64, bytes> custom_records = 9;
// Authentication proof for this channel. This proof contains a set of
// signatures binding four identities, which attests to the legitimacy of
// the advertised channel. This only is available for advertised channels.
// This field is not filled by default. Pass include_auth_proof flag to
// DescribeGraph, GetNodeInfo or GetChanInfo to get this data.
ChannelAuthProof auth_proof = 10;
}
message ChannelGraphRequest {
@@ -3518,6 +3554,9 @@ message ChannelGraphRequest {
channels, and public channels that are not yet announced to the network.
*/
bool include_unannounced = 1;
// If true, will include announcements' signatures into ChannelEdge.
bool include_auth_proof = 2;
}
// Returns a new instance of the directed channel graph.
@@ -3569,6 +3608,9 @@ message ChanInfoRequest {
// The channel point of the channel in format funding_txid:output_index. If
// chan_id is specified, this field is ignored.
string chan_point = 2;
// If true, will include announcements' signatures into ChannelEdge.
bool include_auth_proof = 3;
}
message NetworkInfoRequest {
+51
View File
@@ -1171,6 +1171,13 @@
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "include_auth_proof",
"description": "If true, will include announcements' signatures into ChannelEdge.",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
@@ -1211,6 +1218,13 @@
"in": "query",
"required": false,
"type": "string"
},
{
"name": "include_auth_proof",
"description": "If true, will include announcements' signatures into ChannelEdge.",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
@@ -1273,6 +1287,13 @@
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "include_auth_proof",
"description": "If true, will include announcements' signatures into ChannelEdge.\nDepends on include_channels.",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
@@ -4123,6 +4144,32 @@
}
}
},
"lnrpcChannelAuthProof": {
"type": "object",
"properties": {
"node_sig1": {
"type": "string",
"format": "byte",
"description": "node_sig1 are the raw bytes of the first node signature encoded\nin DER format."
},
"bitcoin_sig1": {
"type": "string",
"format": "byte",
"description": "bitcoin_sig1 are the raw bytes of the first bitcoin signature of the\nMultiSigKey key of the channel encoded in DER format."
},
"node_sig2": {
"type": "string",
"format": "byte",
"description": "node_sig2 are the raw bytes of the second node signature encoded\nin DER format."
},
"bitcoin_sig2": {
"type": "string",
"format": "byte",
"description": "bitcoin_sig2 are the raw bytes of the second bitcoin signature of the\nMultiSigKey key of the channel encoded in DER format."
}
},
"description": "ChannelAuthProof is the authentication proof (the signature portion) for a\nchannel. Using the four signatures contained in the struct, and some\nauxiliary knowledge (the funding script, node identities, and outpoint) nodes\non the network are able to validate the authenticity and existence of a\nchannel."
},
"lnrpcChannelBackup": {
"type": "object",
"properties": {
@@ -4378,6 +4425,10 @@
"format": "byte"
},
"description": "Custom channel announcement tlv records."
},
"auth_proof": {
"$ref": "#/definitions/lnrpcChannelAuthProof",
"description": "Authentication proof for this channel. This proof contains a set of\nsignatures binding four identities, which attests to the legitimacy of\nthe advertised channel. This only is available for advertised channels.\nThis field is not filled by default. Pass include_auth_proof flag to\nDescribeGraph, GetNodeInfo or GetChanInfo to get this data."
}
},
"description": "A fully authenticated channel along with all its unique attributes.\nOnce an authenticated channel announcement has been processed on the network,\nthen an instance of ChannelEdgeInfo encapsulating the channels attributes is\nstored. The other portions relevant to routing policy of a channel are stored\nwithin a ChannelEdgePolicy for each direction of the channel."
+26 -4
View File
@@ -6736,7 +6736,7 @@ func (r *rpcServer) DescribeGraph(ctx context.Context,
return nil
}
edge := marshalDBEdge(edgeInfo, c1, c2)
edge := marshalDBEdge(edgeInfo, c1, c2, req.IncludeAuthProof)
resp.Edges = append(resp.Edges, edge)
return nil
@@ -6782,7 +6782,8 @@ func marshalExtraOpaqueData(data []byte) map[uint64][]byte {
}
func marshalDBEdge(edgeInfo *models.ChannelEdgeInfo,
c1, c2 *models.ChannelEdgePolicy) *lnrpc.ChannelEdge {
c1, c2 *models.ChannelEdgePolicy,
includeAuthProof bool) *lnrpc.ChannelEdge {
// Make sure the policies match the node they belong to. c1 should point
// to the policy for NodeKey1, and c2 for NodeKey2.
@@ -6821,6 +6822,18 @@ func marshalDBEdge(edgeInfo *models.ChannelEdgeInfo,
edge.Node2Policy = marshalDBRoutingPolicy(c2)
}
// We do not expect to have an AuthProof for private channels and for
// our own public channels for the time between channel funding and
// channel announcement.
if includeAuthProof && edgeInfo.AuthProof != nil {
edge.AuthProof = &lnrpc.ChannelAuthProof{
NodeSig1: edgeInfo.AuthProof.NodeSig1Bytes,
BitcoinSig1: edgeInfo.AuthProof.BitcoinSig1Bytes,
NodeSig2: edgeInfo.AuthProof.NodeSig2Bytes,
BitcoinSig2: edgeInfo.AuthProof.BitcoinSig2Bytes,
}
}
return edge
}
@@ -6946,7 +6959,9 @@ func (r *rpcServer) GetChanInfo(_ context.Context,
// Convert the database's edge format into the network/RPC edge format
// which couples the edge itself along with the directional node
// routing policies of each node involved within the channel.
channelEdge := marshalDBEdge(edgeInfo, edge1, edge2)
channelEdge := marshalDBEdge(
edgeInfo, edge1, edge2, in.IncludeAuthProof,
)
return channelEdge, nil
}
@@ -6956,6 +6971,11 @@ func (r *rpcServer) GetChanInfo(_ context.Context,
func (r *rpcServer) GetNodeInfo(ctx context.Context,
in *lnrpc.NodeInfoRequest) (*lnrpc.NodeInfo, error) {
if in.IncludeAuthProof && !in.IncludeChannels {
return nil, fmt.Errorf("include_auth_proof depends on " +
"include_channels")
}
graph := r.server.graphDB
// First, parse the hex-encoded public key into a full in-memory public
@@ -7003,7 +7023,9 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context,
// Convert the database's edge format into the
// network/RPC edge format.
channelEdge := marshalDBEdge(edge, c1, c2)
channelEdge := marshalDBEdge(
edge, c1, c2, in.IncludeAuthProof,
)
channels = append(channels, channelEdge)
}