mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
rpcserver: return uptime errors for known channels
Upgrade logging of channel uptime/lifespan query errors to returning the error, with the exception of the case where the channel is known to the store. This error is logged, due to the potential for race conditions between the channel event store being notified of a new open channel and the rpc channel subscription creating a rpc channel struct (which queries for uptime).
This commit is contained in:
parent
ec12463a95
commit
47e700ba9e
86
rpcserver.go
86
rpcserver.go
@ -32,6 +32,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/build"
|
||||
"github.com/lightningnetwork/lnd/chanacceptor"
|
||||
"github.com/lightningnetwork/lnd/chanbackup"
|
||||
"github.com/lightningnetwork/lnd/chanfitness"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/channelnotifier"
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
@ -2752,7 +2753,10 @@ func (r *rpcServer) ListChannels(ctx context.Context,
|
||||
// Next, we'll determine whether we should add this channel to
|
||||
// our list depending on the type of channels requested to us.
|
||||
isActive := peerOnline && linkActive
|
||||
channel := createRPCOpenChannel(r, graph, dbChannel, isActive)
|
||||
channel, err := createRPCOpenChannel(r, graph, dbChannel, isActive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We'll only skip returning this channel if we were requested
|
||||
// for a specific kind and this channel doesn't satisfy it.
|
||||
@ -2775,7 +2779,7 @@ func (r *rpcServer) ListChannels(ctx context.Context,
|
||||
|
||||
// createRPCOpenChannel creates an *lnrpc.Channel from the *channeldb.Channel.
|
||||
func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
||||
dbChannel *channeldb.OpenChannel, isActive bool) *lnrpc.Channel {
|
||||
dbChannel *channeldb.OpenChannel, isActive bool) (*lnrpc.Channel, error) {
|
||||
|
||||
nodePub := dbChannel.IdentityPub
|
||||
nodeID := hex.EncodeToString(nodePub.SerializeCompressed())
|
||||
@ -2810,43 +2814,12 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
||||
}
|
||||
externalCommitFee := dbChannel.Capacity - sumOutputs
|
||||
|
||||
chanID := dbChannel.ShortChannelID.ToUint64()
|
||||
|
||||
var (
|
||||
uptime time.Duration
|
||||
lifespan time.Duration
|
||||
)
|
||||
|
||||
// Get the lifespan observed by the channel event store.
|
||||
startTime, endTime, err := r.server.chanEventStore.GetLifespan(chanID)
|
||||
if err != nil {
|
||||
// If the channel cannot be found, log an error and do not perform
|
||||
// further calculations for uptime and lifespan.
|
||||
rpcsLog.Warnf("GetLifespan %v error: %v", chanID, err)
|
||||
} else {
|
||||
// If endTime is zero, the channel is still open, progress endTime to
|
||||
// the present so we can calculate lifespan.
|
||||
if endTime.IsZero() {
|
||||
endTime = time.Now()
|
||||
}
|
||||
lifespan = endTime.Sub(startTime)
|
||||
|
||||
uptime, err = r.server.chanEventStore.GetUptime(
|
||||
chanID,
|
||||
startTime,
|
||||
endTime,
|
||||
)
|
||||
if err != nil {
|
||||
rpcsLog.Warnf("GetUptime %v error: %v", chanID, err)
|
||||
}
|
||||
}
|
||||
|
||||
channel := &lnrpc.Channel{
|
||||
Active: isActive,
|
||||
Private: !isPublic,
|
||||
RemotePubkey: nodeID,
|
||||
ChannelPoint: chanPoint.String(),
|
||||
ChanId: chanID,
|
||||
ChanId: dbChannel.ShortChannelID.ToUint64(),
|
||||
Capacity: int64(dbChannel.Capacity),
|
||||
LocalBalance: int64(localBalance.ToSatoshis()),
|
||||
RemoteBalance: int64(remoteBalance.ToSatoshis()),
|
||||
@ -2863,8 +2836,6 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
||||
LocalChanReserveSat: int64(dbChannel.LocalChanCfg.ChanReserve),
|
||||
RemoteChanReserveSat: int64(dbChannel.RemoteChanCfg.ChanReserve),
|
||||
StaticRemoteKey: dbChannel.ChanType.IsTweakless(),
|
||||
Lifetime: int64(lifespan.Seconds()),
|
||||
Uptime: int64(uptime.Seconds()),
|
||||
}
|
||||
|
||||
for i, htlc := range localCommit.Htlcs {
|
||||
@ -2881,7 +2852,42 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
||||
channel.UnsettledBalance += channel.PendingHtlcs[i].Amount
|
||||
}
|
||||
|
||||
return channel
|
||||
// Get the lifespan observed by the channel event store. If the channel is
|
||||
// not known to the channel event store, return early because we cannot
|
||||
// calculate any further uptime information.
|
||||
startTime, endTime, err := r.server.chanEventStore.GetLifespan(channel.ChanId)
|
||||
switch err {
|
||||
case chanfitness.ErrChannelNotFound:
|
||||
rpcsLog.Infof("channel: %v not found by channel event store",
|
||||
channel.ChanId)
|
||||
|
||||
return channel, nil
|
||||
case nil:
|
||||
// If there is no error getting lifespan, continue to uptime
|
||||
// calculation.
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If endTime is zero, the channel is still open, progress endTime to
|
||||
// the present so we can calculate lifetime.
|
||||
if endTime.IsZero() {
|
||||
endTime = time.Now()
|
||||
}
|
||||
channel.Lifetime = int64(endTime.Sub(startTime).Seconds())
|
||||
|
||||
// Once we have successfully obtained channel lifespan, we know that the
|
||||
// channel is known to the event store, so we can return any non-nil error
|
||||
// that occurs.
|
||||
uptime, err := r.server.chanEventStore.GetUptime(
|
||||
channel.ChanId, startTime, endTime,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channel.Uptime = int64(uptime.Seconds())
|
||||
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
// createRPCClosedChannel creates an *lnrpc.ClosedChannelSummary from a
|
||||
@ -2947,8 +2953,12 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
||||
var update *lnrpc.ChannelEventUpdate
|
||||
switch event := e.(type) {
|
||||
case channelnotifier.OpenChannelEvent:
|
||||
channel := createRPCOpenChannel(r, graph,
|
||||
channel, err := createRPCOpenChannel(r, graph,
|
||||
event.Channel, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
update = &lnrpc.ChannelEventUpdate{
|
||||
Type: lnrpc.ChannelEventUpdate_OPEN_CHANNEL,
|
||||
Channel: &lnrpc.ChannelEventUpdate_OpenChannel{
|
||||
|
Loading…
Reference in New Issue
Block a user