[bug]: Node announcements from peers are not re-propagated if they contain a DNS hostname #9473
Labels
bug
Unintended code behaviour
dns
graph
wire protocol
Encoding of messages for the communication between nodes
Milestone
Background
When our LDK LSP ran on mainnet with LND peers, we discovered that although our node (with confirmed public channels and all other requirements satisfied per the BOLT 7 spec) was broadcasting our node announcements, our LND peers were not propagating them. Our node announcement included several addresses—a valid IPv4 address, an IPv6 address, and a TCP DNS (hostname) address. A connected LDK node saw our announcement when received directly from our LSP, yet our LSP’s LND peers never forwarded the announcement. After we removed the hostname address from our announcement, the node announcement propagated across the network within hours and appeared on LN explorers, strongly suggesting that the presence of a type‑5 (TCP DNS hostname) address is interfering with the normal gossip propagation.
According to #6337 (comment), this problem existed before but was fixed as of August 2022. It's possible that we are observing this problem because all of the LND nodes amongst our 9+ LN peers are running software at least that old, but given it is February 2025 this seems highly unlikely.
It's likely that #9455 fixes this issue, but I'm not sure, so I'm opening this issue and providing a bug report just in case. Would very much appreciate your input on this @mohamedawnallah !
Environment
lnd
: Unknown, our peers run LNDuname -a
on *Nix): Unknownbtcd
,bitcoind
, or other backend: UnknownSteps to reproduce
Run a non-LND node Alice and broadcast a node announcement containing a DNS hostname as one of its addresses. (Must be a non-LND node since LND itself does not support configuring its own DNS hostnames). Connect a LND node Bob to Alice. Connect a non-LND node Charlie to Alice and Bob.
Expected behaviour
Charlie observes the node announcement coming from both Alice and Bob.
Actual behaviour
Charlie observes the node announcement coming from both Alice but not Bob.
Bug hypothesis
LND’s handling of node announcement addresses is performed in two stages: first during deserialization (reading the address from the wire) and later during serialization (writing the address when propagating a gossip message).
Deserialization (ReadElement):
In
lnwire/lnwire.go
, when decoding a[]net.Addr
, the function reads an initial descriptor byte that indicates the address type. For known types—IPv4 (tcp4Addr
), IPv6 (tcp6Addr
), v2 onion, and v3 onion—the function decodes the remaining bytes accordingly. However, if the address type is not one of these, the function falls into the default branch. (Note that BOLT 7 defines address type 5 for a TCP DNS hostname.) In that case the code does the following:Because type 5 is not explicitly handled, a DNS hostname is stored as an
OpaqueAddrs
. This in itself might be acceptable for re-transmission if the opaque payload were later handled properly.Serialization Issue (WriteElement):
When propagating node announcements, LND calls
WriteElement
to serialize each element. In the type switch withinWriteElement
, addresses are re-encoded. However, there is no dedicated case to handle theOpaqueAddrs
type produced by the default branch during deserialization. Instead, if an element is of a type that is not recognized by any of the explicit cases,WriteElement
falls to its default branch, which is:In this case the function recurses (for example, when processing slices such as
[]net.Addr
) and eventually encounters an element of type*OpaqueAddrs
(created to hold our type‑5 DNS hostname). Since there is no case that handles*OpaqueAddrs
, the default branch returns an error. This error in turn prevents the node announcement (which includes a DNS hostname) from being re-serialized and forwarded by the gossip layer.The text was updated successfully, but these errors were encountered: