chanfitness: send peer online event when we see the first channel

We rename `getPeerMonitor` to `getOrCreatePeerMonitor` for clarity - it
will now send an online event when the peer monitor is being created,
which means we will only start counting the peer as online when it has
opened a channel with us.
This commit is contained in:
yyforyongyu
2025-09-15 17:01:03 +08:00
parent 92de9424ce
commit 455e4564eb
2 changed files with 46 additions and 21 deletions

View File

@@ -245,7 +245,7 @@ func (c *ChannelEventStore) Stop() error {
func (c *ChannelEventStore) addChannel(channelPoint wire.OutPoint,
peer route.Vertex) {
peerMonitor, err := c.getPeerMonitor(peer)
peerMonitor, err := c.getOrCreatePeerMonitor(peer)
if err != nil {
log.Error("could not create monitor: %v", err)
return
@@ -256,10 +256,12 @@ func (c *ChannelEventStore) addChannel(channelPoint wire.OutPoint,
}
}
// getPeerMonitor tries to get an existing peer monitor from our in memory list,
// and falls back to creating a new monitor if it is not currently known.
func (c *ChannelEventStore) getPeerMonitor(peer route.Vertex) (peerMonitor,
error) {
// getOrCreatePeerMonitor tries to get an existing peer monitor from our in
// memory list. If the peer is not yet known to us, it will create a new
// monitor and add it to the list. When a new monitor is created, we also send
// an initial online event for the peer.
func (c *ChannelEventStore) getOrCreatePeerMonitor(
peer route.Vertex) (peerMonitor, error) {
peerMonitor, ok := c.peers[peer]
if ok {
@@ -289,6 +291,9 @@ func (c *ChannelEventStore) getPeerMonitor(peer route.Vertex) (peerMonitor,
peerMonitor = newPeerLog(c.cfg.Clock, flapCount, lastFlap)
c.peers[peer] = peerMonitor
// Send an online event given it's the first time we see this peer.
peerMonitor.onlineEvent(true)
return peerMonitor, nil
}
@@ -374,9 +379,12 @@ func (c *ChannelEventStore) consume(subscriptions *subscriptions) {
"from: %v", compressed)
}
c.addChannel(
event.Channel.FundingOutpoint, peerKey,
)
op := event.Channel.FundingOutpoint
log.Tracef("Received OpenChannelEvent(%v) "+
"from %v", op, peerKey)
c.addChannel(op, peerKey)
// A channel has been closed, we must remove the channel
// from the store and record a channel closed event.
@@ -490,7 +498,7 @@ func (c *ChannelEventStore) getChanInfo(req channelInfoRequest) (*ChannelInfo,
peerMonitor, ok := c.peers[req.peer]
if !ok {
return nil, ErrPeerNotFound
return nil, fmt.Errorf("%w: %v", ErrPeerNotFound, req.peer)
}
lifetime, uptime, err := peerMonitor.channelUptime(req.channelPoint)

View File

@@ -189,11 +189,11 @@ func TestStoreFlapCount(t *testing.T) {
// flush our tick count to disk.
testCtx.tickFlapCount()
// Since we just tracked a offline event, we expect a single flap for
// our peer.
// Since we just tracked an offline event, we expect two flaps for our
// peer because the channel opening also records an online event.
expectedUpdate := peerFlapCountMap{
pubkey: {
Count: 1,
Count: 2,
LastFlap: testCtx.clock.Now(),
},
}
@@ -210,9 +210,9 @@ func TestStoreFlapCount(t *testing.T) {
testCtx.tickFlapCount()
// Since we have processed 3 more events for our peer, we update our
// expected online map to have a flap count of 4 for this peer.
// expected online map to have a flap count of 5 for this peer.
expectedUpdate[pubkey] = &channeldb.FlapCount{
Count: 4,
Count: 5,
LastFlap: testCtx.clock.Now(),
}
testCtx.assertFlapCountUpdated()
@@ -234,13 +234,13 @@ func TestGetChanInfo(t *testing.T) {
peer, pk, channel := ctx.newChannel()
// Send an online event for our peer, although we do not yet have an
// open channel.
// open channel - this event will be ignored.
ctx.peerEvent(peer, true)
// Try to get info for a channel that has not been opened yet, we
// expect to get an error.
_, err := ctx.store.GetChanInfo(channel, peer)
require.Equal(t, ErrChannelNotFound, err)
require.ErrorIs(t, err, ErrPeerNotFound)
// Now we send our store a notification that a channel has been opened.
ctx.sendChannelOpenedUpdate(pk, channel)
@@ -310,9 +310,13 @@ func TestFlapCount(t *testing.T) {
ctx.start()
// Create test variables for a peer and channel, but do not add it to
// our store yet.
peer1 := route.Vertex{1, 2, 3}
// Create a valid public key for our peer.
priv, err := btcec.NewPrivateKey()
require.NoError(t, err)
pubkeyBytes := priv.PubKey().SerializeCompressed()
var peer1 route.Vertex
copy(peer1[:], pubkeyBytes)
// First, query for a peer that we have no record of in memory or on
// disk and confirm that we indicate that the peer was not found.
@@ -320,10 +324,23 @@ func TestFlapCount(t *testing.T) {
require.NoError(t, err)
require.Nil(t, ts)
// Send an online event for our peer.
// Send an online event for our peer - given this peer doesn't have a
// channel with, this event will be ignored.
ctx.peerEvent(peer1, true)
// Assert that we now find a record of the peer with flap count = 1.
// Assert the event is ignored.
_, ts, err = ctx.store.FlapCount(peer1)
require.NoError(t, err)
require.Nil(t, ts)
// Create a channel for the peer so that it will be tracked by the
// store.
pk, err := btcec.ParsePubKey(peer1[:])
require.NoError(t, err)
ctx.sendChannelOpenedUpdate(pk, wire.OutPoint{Index: 9})
// Assert that we now find a record of the peer with flap count = 1,
// because the channel open fires an online event.
count, ts, err := ctx.store.FlapCount(peer1)
require.NoError(t, err)
require.Equal(t, lastFlap, *ts)