diff --git a/itest/list_on_test.go b/itest/list_on_test.go index 7f9eaf574..aecbd1462 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -170,6 +170,10 @@ var allTestCases = []*lntest.TestCase{ Name: "update node announcement rpc", TestFunc: testUpdateNodeAnnouncement, }, + { + Name: "self node announcement persistence", + TestFunc: testSelfNodeAnnouncementPersistence, + }, { Name: "list payments", TestFunc: testListPayments, diff --git a/itest/lnd_channel_graph_test.go b/itest/lnd_channel_graph_test.go index 397a81e0e..6d30fe211 100644 --- a/itest/lnd_channel_graph_test.go +++ b/itest/lnd_channel_graph_test.go @@ -1,6 +1,7 @@ package itest import ( + "encoding/hex" "fmt" "strings" "testing" @@ -654,6 +655,135 @@ func testUpdateNodeAnnouncement(ht *lntest.HarnessTest) { dave.RPC.UpdateNodeAnnouncementErr(nodeAnnReq) } +// testSelfNodeAnnouncementPersistence tests that the node announcement configs +// are persisted correctly and reused when the node is restarted using the +// correct hierarchy (config > source node > defaults). +func testSelfNodeAnnouncementPersistence(ht *lntest.HarnessTest) { + // Start Alice with default node announcement options. + alice := ht.NewNode("Alice", nil) + + // assertAddrs is a helper function to assert that the node info + // contains the correct addresses. + assertAddrs := func(addrsFound []string, targetAddrs ...string) error { + addrs := make(map[string]struct{}, len(addrsFound)) + for _, addr := range addrsFound { + addr = strings.Split(addr, "@")[1] + addrs[addr] = struct{}{} + } + + for _, addr := range targetAddrs { + _, ok := addrs[addr] + if !ok { + return fmt.Errorf("address %v not found in "+ + "node announcement", addr) + } + } + + return nil + } + + // assertNodeInfo is a helper function to assert that the node info + // contains the correct values. + assertNodeInfo := func(resp *lnrpc.GetInfoResponse, expectedAlias, + expectedColor string, expectedAddrs ...string) { + + require.Equal(ht, expectedAlias, resp.Alias) + require.Equal(ht, expectedColor, resp.Color) + err := assertAddrs(resp.Uris, expectedAddrs...) + require.NoError(ht, err) + } + + // Get the node info and verify that the default values are used for + // alias and color. + resp := alice.RPC.GetInfo() + + // The alias should be the first 10 bytes of the serialized public key. + defaultAlias := hex.EncodeToString(alice.PubKey[:10]) + + // Assert that the default values are used for alias and color. + assertNodeInfo(resp, defaultAlias, "#3399ff") + + // Update the node announcement and set an alias, color, and addresses. + nodeAnnReq := &peersrpc.NodeAnnouncementUpdateRequest{ + Alias: "alice", + Color: "#eeeeee", + AddressUpdates: []*peersrpc.UpdateAddressAction{ + { + Action: peersrpc.UpdateAction_ADD, + Address: "192.168.1.10:8333", + }, + { + Action: peersrpc.UpdateAction_ADD, + Address: "192.168.1.11:8333", + }, + }, + } + + response := alice.RPC.UpdateNodeAnnouncement(nodeAnnReq) + + expectedOps := map[string]int{ + "alias": 1, + "color": 1, + "addresses": 2, + } + assertUpdateNodeAnnouncementResponse(ht, response, expectedOps) + + resp = alice.RPC.GetInfo() + assertNodeInfo( + resp, "alice", "#eeeeee", "192.168.1.10:8333", + "192.168.1.11:8333", + ) + + // Restart Alice. + ht.RestartNode(alice) + + // After restarting, the node info should contain the values that were + // set in the update request since the updated values take precedence + // over the default values. + resp = alice.RPC.GetInfo() + assertNodeInfo( + resp, "alice", "#eeeeee", "192.168.1.10:8333", + "192.168.1.11:8333", + ) + + // Test that we can still remove an address. + removeAddrReq := &peersrpc.NodeAnnouncementUpdateRequest{ + AddressUpdates: []*peersrpc.UpdateAddressAction{ + { + Action: peersrpc.UpdateAction_REMOVE, + Address: "192.168.1.10:8333", + }, + }, + } + response = alice.RPC.UpdateNodeAnnouncement(removeAddrReq) + expectedOps = map[string]int{ + "addresses": 1, + } + assertUpdateNodeAnnouncementResponse(ht, response, expectedOps) + + // Now we restart the node with custom values in the config. + lndArgs := []string{ + "--externalip=192.168.1.12:8333", + "--externalip=192.168.1.13:8333", + "--alias=alice-updated", + "--color=#ffffff", + } + ht.RestartNodeWithExtraArgs(alice, lndArgs) + + // Get the node info and verify that the values are the same as the + // ones we set in the config (and not the updated values). + // The addresses should be the same as the ones we set in the config + // plus the ones we set in the update request earlier. + resp = alice.RPC.GetInfo() + assertNodeInfo( + resp, "alice-updated", "#ffffff", "192.168.1.11:8333", + "192.168.1.12:8333", "192.168.1.13:8333", + ) + + // The address we removed earlier should not be present. + require.Error(ht, assertAddrs(resp.Uris, "192.168.1.10:8333")) +} + // assertSyncType asserts that the peer has an expected syncType. // // NOTE: only made for tests in this file.