itest: test channel update subscription

This commit is contained in:
bitromortac committed 2026-02-20 10:47:04 +01:00
1 parent 10e8a69cec
commit fa5722355f
3 files changed
+117

No files matched your search

+4
View File
@@ -206,6 +206,10 @@ var allTestCases = []*lntest.TestCase{
Name: "invoice update subscription",
TestFunc: testInvoiceSubscriptions,
},
{
Name: "channel update subscription",
TestFunc: testChannelUpdateNotifications,
},
{
Name: "streaming channel backup update",
TestFunc: testChannelBackupUpdates,
+99
View File
@@ -3,6 +3,7 @@ package itest
import (
"fmt"
"strings"
"time"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
@@ -1342,3 +1343,101 @@ func testOpenChannelWithShutdownAddr(ht *lntest.HarnessTest) {
require.Equal(ht, bobShutdownAddr.Address, bobUTXOConfirmed.Address)
require.Equal(ht, paymentAmount, bobUTXOConfirmed.AmountSat)
}
// testChannelUpdateNotifications checks that clients subscribed to channel
// events receive real-time updates when the channel state changes.
func testChannelUpdateNotifications(ht *lntest.HarnessTest) {
// We'll start by creating two nodes, Alice and Bob, and a channel
// between them.
alice := ht.NewNodeWithCoins("Alice", nil)
bob := ht.NewNode("Bob", nil)
ht.EnsureConnected(alice, bob)
// We'll subscribe to channel events for both nodes.
aliceSub := alice.RPC.SubscribeChannelEvents()
bobSub := bob.RPC.SubscribeChannelEvents()
// We'll then open a channel between Alice and Bob.
chanPoint := ht.OpenChannel(
alice, bob, lntest.OpenChannelParams{
Amt: 1000000,
PushAmt: 500000,
},
)
// We'll wait for the channel to be active. We expect to receive one
// pending, one open, and one active notification.
ht.AssertChannelActive(alice, chanPoint)
ht.AssertChannelActive(bob, chanPoint)
ht.AssertChannelEventType(
aliceSub, lnrpc.ChannelEventUpdate_PENDING_OPEN_CHANNEL,
)
ht.AssertChannelEventType(
aliceSub, lnrpc.ChannelEventUpdate_OPEN_CHANNEL,
)
ht.AssertChannelEventType(
aliceSub, lnrpc.ChannelEventUpdate_ACTIVE_CHANNEL,
)
ht.AssertChannelEventType(
bobSub, lnrpc.ChannelEventUpdate_PENDING_OPEN_CHANNEL,
)
ht.AssertChannelEventType(
bobSub, lnrpc.ChannelEventUpdate_OPEN_CHANNEL,
)
ht.AssertChannelEventType(
bobSub, lnrpc.ChannelEventUpdate_ACTIVE_CHANNEL,
)
// We'll now make a payment from Alice to Bob to trigger a channel
// update.
payReqs, _, _ := ht.CreatePayReqs(bob, btcutil.Amount(1000), 1)
ht.CompletePaymentRequests(alice, payReqs)
// assertUpdates is a helper function to assert the number of commitment
// updates received by a node.
assertUpdates := func(sub rpc.ChannelEventsClient, numUpdates int) {
event := ht.AssertChannelEventType(
sub, lnrpc.ChannelEventUpdate_CHANNEL_UPDATE,
)
require.IsType(
ht, &lnrpc.ChannelEventUpdate_UpdatedChannel{},
event.Channel,
)
channel := event.GetUpdatedChannel().Channel
require.EqualValues(ht, numUpdates, channel.NumUpdates)
}
// expectNoMoreUpdates is a helper function to assert that no more
// channel updates are received by a node.
expectNoMoreUpdates := func(sub rpc.ChannelEventsClient) {
updates := make(chan struct{})
go func() {
_, err := sub.Recv()
// Only signal if we successfully received an update.
// If Recv fails (e.g., context canceled during test
// cleanup), that's fine - it means no update arrived.
if err == nil {
close(updates)
}
}()
select {
case <-updates:
ht.Fatalf("expected no more updates")
case <-time.After(defaultTimeout):
}
}
// We expect to see two updates from each node's point of view. One for
// the addition of the HTLC, and a second for the settlement.
assertUpdates(aliceSub, 1)
assertUpdates(aliceSub, 2)
expectNoMoreUpdates(aliceSub)
assertUpdates(bobSub, 1)
assertUpdates(bobSub, 2)
expectNoMoreUpdates(bobSub)
}
+14
View File
@@ -425,6 +425,20 @@ func (h *HarnessTest) assertChannelStatus(hn *node.HarnessNode,
return channel
}
// AssertChannelEventType consumes one event from a client and asserts the event
// type is matched.
func (h *HarnessTest) AssertChannelEventType(sub rpc.ChannelEventsClient,
updateType lnrpc.ChannelEventUpdate_UpdateType,
) *lnrpc.ChannelEventUpdate {
update := h.ReceiveChannelEvent(sub)
require.Equalf(h, updateType, update.Type, "wrong event type, "+
"want %v got %v", updateType, update.Type)
return update
}
// AssertOutputScriptClass checks that the specified transaction output has the
// expected script class.
func (h *HarnessTest) AssertOutputScriptClass(tx *btcutil.Tx,