diff --git a/chanfitness/chaneventstore.go b/chanfitness/chaneventstore.go index fe7ca4028..881e9a35e 100644 --- a/chanfitness/chaneventstore.go +++ b/chanfitness/chaneventstore.go @@ -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) diff --git a/chanfitness/chaneventstore_test.go b/chanfitness/chaneventstore_test.go index 0608889a9..ecec3ea47 100644 --- a/chanfitness/chaneventstore_test.go +++ b/chanfitness/chaneventstore_test.go @@ -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)