Merge pull request #7001 from hieblmi/fwdinghistory-alias-info
lncli: incoming and outgoing peer alias in `fwdinghistory`
This commit is contained in:
7 files changed
+911
-779
No files matched your search
@@ -1297,6 +1297,11 @@ var forwardingHistoryCommand = cli.Command{
|
|||||||
Name: "max_events",
|
Name: "max_events",
|
||||||
Usage: "the max number of events to return",
|
Usage: "the max number of events to return",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "skip_peer_alias_lookup",
|
||||||
|
Usage: "skip the peer alias lookup per forwarding " +
|
||||||
|
"event in order to improve performance",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: actionDecorator(forwardingHistory),
|
Action: actionDecorator(forwardingHistory),
|
||||||
}
|
}
|
||||||
@@ -1347,7 +1352,8 @@ func forwardingHistory(ctx *cli.Context) error {
|
|||||||
case args.Present():
|
case args.Present():
|
||||||
i, err := strconv.ParseInt(args.First(), 10, 64)
|
i, err := strconv.ParseInt(args.First(), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to decode index_offset: %v", err)
|
return fmt.Errorf("unable to decode index_offset: %v",
|
||||||
|
err)
|
||||||
}
|
}
|
||||||
indexOffset = uint32(i)
|
indexOffset = uint32(i)
|
||||||
args = args.Tail()
|
args = args.Tail()
|
||||||
@@ -1359,16 +1365,18 @@ func forwardingHistory(ctx *cli.Context) error {
|
|||||||
case args.Present():
|
case args.Present():
|
||||||
m, err := strconv.ParseInt(args.First(), 10, 64)
|
m, err := strconv.ParseInt(args.First(), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to decode max_events: %v", err)
|
return fmt.Errorf("unable to decode max_events: %v",
|
||||||
|
err)
|
||||||
}
|
}
|
||||||
maxEvents = uint32(m)
|
maxEvents = uint32(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &lnrpc.ForwardingHistoryRequest{
|
req := &lnrpc.ForwardingHistoryRequest{
|
||||||
StartTime: startTime,
|
StartTime: startTime,
|
||||||
EndTime: endTime,
|
EndTime: endTime,
|
||||||
IndexOffset: indexOffset,
|
IndexOffset: indexOffset,
|
||||||
NumMaxEvents: maxEvents,
|
NumMaxEvents: maxEvents,
|
||||||
|
SkipPeerAliasLookup: ctx.Bool("skip_peer_alias_lookup"),
|
||||||
}
|
}
|
||||||
resp, err := client.ForwardingHistory(ctxc, req)
|
resp, err := client.ForwardingHistory(ctxc, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -40,6 +40,12 @@
|
|||||||
* [Make remote channel reserve amount configurable for
|
* [Make remote channel reserve amount configurable for
|
||||||
`openchannel`](https://github.com/lightningnetwork/lnd/pull/6956)
|
`openchannel`](https://github.com/lightningnetwork/lnd/pull/6956)
|
||||||
|
|
||||||
|
* [`ForwardingHistory` ](https://github.com/lightningnetwork/lnd/pull/7001) now
|
||||||
|
enriches each forwarding event with inbound and outbound peer alias names. In
|
||||||
|
order for UIs to preserve the performance of this RPC the alias lookup can be
|
||||||
|
skipped by specifying `skip_peer_alias_lookup`. `lncli fwdinghistory` also
|
||||||
|
adds a flag `skip_peer_alias_lookup` to skip the lookup.
|
||||||
|
|
||||||
## 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
|
||||||
|
|||||||
+777
-741
File diff suppressed because it is too large.
Load diff
@@ -4049,6 +4049,10 @@ message ForwardingHistoryRequest {
|
|||||||
|
|
||||||
// The max number of events to return in the response to this query.
|
// The max number of events to return in the response to this query.
|
||||||
uint32 num_max_events = 4;
|
uint32 num_max_events = 4;
|
||||||
|
|
||||||
|
// Informs the server if the peer alias lookup per forwarding event
|
||||||
|
// should be skipped in order to improve performance.
|
||||||
|
bool skip_peer_alias_lookup = 5;
|
||||||
}
|
}
|
||||||
message ForwardingEvent {
|
message ForwardingEvent {
|
||||||
// Timestamp is the time (unix epoch offset) that this circuit was
|
// Timestamp is the time (unix epoch offset) that this circuit was
|
||||||
@@ -4088,6 +4092,12 @@ message ForwardingEvent {
|
|||||||
// circuit was completed.
|
// circuit was completed.
|
||||||
uint64 timestamp_ns = 11;
|
uint64 timestamp_ns = 11;
|
||||||
|
|
||||||
|
// The peer alias of the incoming channel.
|
||||||
|
string peer_alias_in = 12;
|
||||||
|
|
||||||
|
// The peer alias of the outgoing channel.
|
||||||
|
string peer_alias_out = 13;
|
||||||
|
|
||||||
// TODO(roasbeef): add settlement latency?
|
// TODO(roasbeef): add settlement latency?
|
||||||
// * use FPE on the chan id?
|
// * use FPE on the chan id?
|
||||||
// * also list failures?
|
// * also list failures?
|
||||||
|
|||||||
@@ -4454,6 +4454,14 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"description": "The number of nanoseconds elapsed since January 1, 1970 UTC when this\ncircuit was completed."
|
"description": "The number of nanoseconds elapsed since January 1, 1970 UTC when this\ncircuit was completed."
|
||||||
|
},
|
||||||
|
"peer_alias_in": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The peer alias of the incoming channel."
|
||||||
|
},
|
||||||
|
"peer_alias_out": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The peer alias of the outgoing channel."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4479,6 +4487,10 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"description": "The max number of events to return in the response to this query."
|
"description": "The max number of events to return in the response to this query."
|
||||||
|
},
|
||||||
|
"skip_peer_alias_lookup": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Informs the server if the peer alias lookup per forwarding event\nshould be skipped in order to improve performance."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||||
"github.com/lightningnetwork/lnd/lntest"
|
"github.com/lightningnetwork/lnd/lntest"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
@@ -253,44 +254,41 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// each of the forwarded payments.
|
// each of the forwarded payments.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
feeReport, err := dave.FeeReport(ctxt, &lnrpc.FeeReportRequest{})
|
feeReport, err := dave.FeeReport(ctxt, &lnrpc.FeeReportRequest{})
|
||||||
if err != nil {
|
require.NoError(t.t, err)
|
||||||
t.Fatalf("unable to query for fee report: %v", err)
|
require.EqualValues(t.t, expectedFeeDave, feeReport.DayFeeSum)
|
||||||
}
|
require.EqualValues(t.t, expectedFeeDave, feeReport.WeekFeeSum)
|
||||||
|
require.EqualValues(t.t, expectedFeeDave, feeReport.MonthFeeSum)
|
||||||
if feeReport.DayFeeSum != uint64(expectedFeeDave) {
|
|
||||||
t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
|
|
||||||
feeReport.DayFeeSum)
|
|
||||||
}
|
|
||||||
if feeReport.WeekFeeSum != uint64(expectedFeeDave) {
|
|
||||||
t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
|
|
||||||
feeReport.WeekFeeSum)
|
|
||||||
}
|
|
||||||
if feeReport.MonthFeeSum != uint64(expectedFeeDave) {
|
|
||||||
t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
|
|
||||||
feeReport.MonthFeeSum)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, ensure that if we issue the vanilla query for the forwarding
|
// Next, ensure that if we issue the vanilla query for the forwarding
|
||||||
// history, it returns 5 values, and each entry is formatted properly.
|
// history, it returns 5 values, and each entry is formatted properly.
|
||||||
|
// From David's perspective he receives a payement from Carol and
|
||||||
|
// forwards it to Alice. So let's ensure that the forwarding history
|
||||||
|
// returns Carol's peer alias as inbound and Alice's alias as outbound.
|
||||||
|
info, err := carol.GetInfo(ctxt, &lnrpc.GetInfoRequest{})
|
||||||
|
require.NoError(t.t, err)
|
||||||
|
carolAlias := info.Alias
|
||||||
|
|
||||||
|
info, err = net.Alice.GetInfo(ctxt, &lnrpc.GetInfoRequest{})
|
||||||
|
require.NoError(t.t, err)
|
||||||
|
aliceAlias := info.Alias
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
fwdingHistory, err := dave.ForwardingHistory(
|
fwdingHistory, err := dave.ForwardingHistory(
|
||||||
ctxt, &lnrpc.ForwardingHistoryRequest{},
|
ctxt, &lnrpc.ForwardingHistoryRequest{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
require.NoError(t.t, err)
|
||||||
t.Fatalf("unable to query for fee report: %v", err)
|
require.EqualValues(
|
||||||
}
|
t.t, numPayments, len(fwdingHistory.ForwardingEvents),
|
||||||
if len(fwdingHistory.ForwardingEvents) != numPayments {
|
)
|
||||||
t.Fatalf("wrong number of forwarding event: expected %v, "+
|
|
||||||
"got %v", numPayments,
|
|
||||||
len(fwdingHistory.ForwardingEvents))
|
|
||||||
}
|
|
||||||
expectedForwardingFee := uint64(expectedFeeDave / numPayments)
|
expectedForwardingFee := uint64(expectedFeeDave / numPayments)
|
||||||
for _, event := range fwdingHistory.ForwardingEvents {
|
for _, event := range fwdingHistory.ForwardingEvents {
|
||||||
// Each event should show a fee of 170 satoshi.
|
// Each event should show a fee of 170 satoshi.
|
||||||
if event.Fee != expectedForwardingFee {
|
require.Equal(t.t, expectedForwardingFee, event.Fee)
|
||||||
t.Fatalf("fee mismatch: expected %v, got %v",
|
|
||||||
expectedForwardingFee, event.Fee)
|
// Check that peer aliases adhere to payment flow, namely
|
||||||
}
|
// Carol->Dave->Alice.
|
||||||
|
require.Equal(t.t, carolAlias, event.PeerAliasIn)
|
||||||
|
require.Equal(t.t, aliceAlias, event.PeerAliasOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect Carol to have successful forwards and settles for
|
// We expect Carol to have successful forwards and settles for
|
||||||
|
|||||||
+66
-4
@@ -6740,7 +6740,8 @@ func (r *rpcServer) UpdateChannelPolicy(ctx context.Context,
|
|||||||
// offset can be provided to the request to allow the caller to skip a series
|
// offset can be provided to the request to allow the caller to skip a series
|
||||||
// of records.
|
// of records.
|
||||||
func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
||||||
req *lnrpc.ForwardingHistoryRequest) (*lnrpc.ForwardingHistoryResponse, error) {
|
req *lnrpc.ForwardingHistoryRequest) (*lnrpc.ForwardingHistoryResponse,
|
||||||
|
error) {
|
||||||
|
|
||||||
rpcsLog.Debugf("[forwardinghistory]")
|
rpcsLog.Debugf("[forwardinghistory]")
|
||||||
|
|
||||||
@@ -6758,7 +6759,8 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
|||||||
numEvents uint32
|
numEvents uint32
|
||||||
)
|
)
|
||||||
|
|
||||||
// startTime defaults to the Unix epoch (0 unixtime, or midnight 01-01-1970).
|
// startTime defaults to the Unix epoch (0 unixtime, or
|
||||||
|
// midnight 01-01-1970).
|
||||||
startTime = time.Unix(int64(req.StartTime), 0)
|
startTime = time.Unix(int64(req.StartTime), 0)
|
||||||
|
|
||||||
// If the end time wasn't specified, assume a default end time of now.
|
// If the end time wasn't specified, assume a default end time of now.
|
||||||
@@ -6786,7 +6788,48 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
|||||||
}
|
}
|
||||||
timeSlice, err := r.server.miscDB.ForwardingLog().Query(eventQuery)
|
timeSlice, err := r.server.miscDB.ForwardingLog().Query(eventQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to query forwarding log: %v", err)
|
return nil, fmt.Errorf("unable to query forwarding log: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// chanToPeerAlias caches previously looked up channel information.
|
||||||
|
chanToPeerAlias := make(map[lnwire.ShortChannelID]string)
|
||||||
|
|
||||||
|
// Helper function to extract a peer's node alias given its SCID.
|
||||||
|
getRemoteAlias := func(chanID lnwire.ShortChannelID) (string, error) {
|
||||||
|
// If we'd previously seen this chanID then return the cached
|
||||||
|
// peer alias.
|
||||||
|
if peerAlias, ok := chanToPeerAlias[chanID]; ok {
|
||||||
|
return peerAlias, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else call the server to look up the peer alias.
|
||||||
|
edge, err := r.GetChanInfo(ctx, &lnrpc.ChanInfoRequest{
|
||||||
|
ChanId: chanID.ToUint64(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
remotePub := edge.Node1Pub
|
||||||
|
if r.selfNode.String() == edge.Node1Pub {
|
||||||
|
remotePub = edge.Node2Pub
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex, err := route.NewVertexFromStr(remotePub)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
peer, err := r.server.graphDB.FetchLightningNode(vertex)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the peer alias.
|
||||||
|
chanToPeerAlias[chanID] = peer.Alias
|
||||||
|
|
||||||
|
return peer.Alias, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): add settlement latency?
|
// TODO(roasbeef): add settlement latency?
|
||||||
@@ -6796,8 +6839,11 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
|||||||
// response.
|
// response.
|
||||||
//
|
//
|
||||||
// TODO(roasbeef): show in ns for the outside?
|
// TODO(roasbeef): show in ns for the outside?
|
||||||
|
fwdingEvents := make(
|
||||||
|
[]*lnrpc.ForwardingEvent, len(timeSlice.ForwardingEvents),
|
||||||
|
)
|
||||||
resp := &lnrpc.ForwardingHistoryResponse{
|
resp := &lnrpc.ForwardingHistoryResponse{
|
||||||
ForwardingEvents: make([]*lnrpc.ForwardingEvent, len(timeSlice.ForwardingEvents)),
|
ForwardingEvents: fwdingEvents,
|
||||||
LastOffsetIndex: timeSlice.LastIndexOffset,
|
LastOffsetIndex: timeSlice.LastIndexOffset,
|
||||||
}
|
}
|
||||||
for i, event := range timeSlice.ForwardingEvents {
|
for i, event := range timeSlice.ForwardingEvents {
|
||||||
@@ -6817,6 +6863,22 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context,
|
|||||||
AmtInMsat: uint64(amtInMsat),
|
AmtInMsat: uint64(amtInMsat),
|
||||||
AmtOutMsat: uint64(amtOutMsat),
|
AmtOutMsat: uint64(amtOutMsat),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !req.SkipPeerAliasLookup {
|
||||||
|
aliasIn, err := getRemoteAlias(event.IncomingChanID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to lookup peer "+
|
||||||
|
"alias: %v", err)
|
||||||
|
}
|
||||||
|
resp.ForwardingEvents[i].PeerAliasIn = aliasIn
|
||||||
|
|
||||||
|
aliasOut, err := getRemoteAlias(event.OutgoingChanID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to lookup peer "+
|
||||||
|
"alias: %v", err)
|
||||||
|
}
|
||||||
|
resp.ForwardingEvents[i].PeerAliasOut = aliasOut
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|||||||
Reference in new issue
Block a user