graph/db+chanbackup: dns add encoding/decoding for persistence

This commit is contained in:
Elle Mouton
2025-08-07 12:25:44 +02:00
committed by Mohamed Awnallah
parent 4bd2bbca27
commit 6ef80db746
7 changed files with 107 additions and 11 deletions

View File

@@ -160,6 +160,7 @@ func TestFetchStaticChanBackups(t *testing.T) {
chanSource.addAddrsForNode(randomChan2.IdentityPub, []net.Addr{addr2})
chanSource.addAddrsForNode(randomChan2.IdentityPub, []net.Addr{addr3})
chanSource.addAddrsForNode(randomChan2.IdentityPub, []net.Addr{addr4})
chanSource.addAddrsForNode(randomChan2.IdentityPub, []net.Addr{addr5})
// With the channel source populated, we'll now attempt to create a set
// of backups for all the channels. This should succeed, as all items

View File

@@ -23,7 +23,7 @@ func TestMultiPackUnpack(t *testing.T) {
}
single := NewSingle(
channel, []net.Addr{addr1, addr2, addr3, addr4},
channel, []net.Addr{addr1, addr2, addr3, addr4, addr5},
)
originalSingles = append(originalSingles, single)

View File

@@ -41,7 +41,11 @@ var (
OnionService: "3g2upl4pq6kufc4m.onion",
Port: 9735,
}
addr4 = &lnwire.OpaqueAddrs{
addr4 = &lnwire.DNSAddress{
Hostname: "example.com",
Port: 8080,
}
addr5 = &lnwire.OpaqueAddrs{
// The first byte must be an address type we are not yet aware
// of for it to be a valid OpaqueAddrs.
Payload: []byte{math.MaxUint8, 1, 2, 3, 4},
@@ -320,7 +324,7 @@ func TestSinglePackUnpack(t *testing.T) {
require.NoError(t, err, "unable to gen open channel")
singleChanBackup := NewSingle(
channel, []net.Addr{addr1, addr2, addr3, addr4},
channel, []net.Addr{addr1, addr2, addr3, addr4, addr5},
)
keyRing := &lnencrypt.MockKeyRing{}
@@ -647,7 +651,7 @@ func TestSingleUnconfirmedChannel(t *testing.T) {
channel.FundingBroadcastHeight = fundingBroadcastHeight
singleChanBackup := NewSingle(
channel, []net.Addr{addr1, addr2, addr3, addr4},
channel, []net.Addr{addr1, addr2, addr3, addr4, addr5},
)
keyRing := &lnencrypt.MockKeyRing{}

View File

@@ -31,8 +31,36 @@ const (
// opaqueAddrs denotes an address (or a set of addresses) that LND was
// not able to parse since LND is not yet aware of the address type.
opaqueAddrs addressType = 4
// dnsAddr denotes a DNS address type.
dnsAddr addressType = 5
)
// encodeDNSAddr encodes a DNS address.
func encodeDNSAddr(w io.Writer, addr *lnwire.DNSAddress) error {
if _, err := w.Write([]byte{byte(dnsAddr)}); err != nil {
return err
}
// Write the length of the hostname.
hostLen := len(addr.Hostname)
if _, err := w.Write([]byte{byte(hostLen)}); err != nil {
return err
}
if _, err := w.Write([]byte(addr.Hostname)); err != nil {
return err
}
var port [2]byte
byteOrder.PutUint16(port[:], addr.Port)
if _, err := w.Write(port[:]); err != nil {
return err
}
return nil
}
// encodeTCPAddr serializes a TCP address into its compact raw bytes
// representation.
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
@@ -230,6 +258,30 @@ func DeserializeAddr(r io.Reader) (net.Addr, error) {
Port: port,
}
case dnsAddr:
// Read the length of the hostname.
var hostLen [1]byte
if _, err := r.Read(hostLen[:]); err != nil {
return nil, err
}
// Read the hostname.
hostname := make([]byte, hostLen[0])
if _, err := r.Read(hostname); err != nil {
return nil, err
}
// Read the port.
var port [2]byte
if _, err := r.Read(port[:]); err != nil {
return nil, err
}
address = &lnwire.DNSAddress{
Hostname: string(hostname),
Port: binary.BigEndian.Uint16(port[:]),
}
case opaqueAddrs:
// Read the length of the payload.
var l [2]byte
@@ -264,6 +316,8 @@ func SerializeAddr(w io.Writer, address net.Addr) error {
return encodeOnionAddr(w, addr)
case *lnwire.OpaqueAddrs:
return encodeOpaqueAddrs(w, addr)
case *lnwire.DNSAddress:
return encodeDNSAddr(w, addr)
default:
return ErrUnknownAddressType
}

View File

@@ -6,6 +6,7 @@ import (
"strings"
"testing"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tor"
"github.com/stretchr/testify/require"
)
@@ -38,6 +39,18 @@ var (
OnionService: "vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion", //nolint:ll
Port: 80,
}
testOpaqueAddr = &lnwire.OpaqueAddrs{
// NOTE: the first byte is a protocol level address type. So
// for we set it to 0xff to guarantee that we do not know this
// type yet.
Payload: []byte{0xff, 0x02, 0x03, 0x04, 0x05, 0x06},
}
testDNSAddr = &lnwire.DNSAddress{
Hostname: "example.com",
Port: 8080,
}
)
var addrTests = []struct {
@@ -57,6 +70,12 @@ var addrTests = []struct {
{
expAddr: testOnionV3Addr,
},
{
expAddr: testOpaqueAddr,
},
{
expAddr: testDNSAddr,
},
// Invalid addresses.
{

View File

@@ -37,13 +37,7 @@ var (
Port: 9000}
anotherAddr, _ = net.ResolveTCPAddr("tcp",
"[2001:db8:85a3:0:0:8a2e:370:7334]:80")
testAddrs = []net.Addr{testAddr, anotherAddr}
testOpaqueAddr = &lnwire.OpaqueAddrs{
// NOTE: the first byte is a protocol level address type. So
// for we set it to 0xff to guarantee that we do not know this
// type yet.
Payload: []byte{0xff, 0x02, 0x03, 0x04, 0x05, 0x06},
}
testAddrs = []net.Addr{testAddr, anotherAddr}
testRBytes, _ = hex.DecodeString("8ce2bc69281ce27da07e6683571319d18" +
"e949ddfa2965fb6caa1bf0314f882d7")
@@ -211,6 +205,8 @@ func TestNodeInsertionAndDeletion(t *testing.T) {
// Add one v2 and one v3 onion address.
testOnionV2Addr,
testOnionV3Addr,
// Add a DNS host address.
testDNSAddr,
// Make sure to also test the opaque address type.
testOpaqueAddr,
}

View File

@@ -3530,6 +3530,7 @@ const (
addressTypeIPv6 dbAddressType = 2
addressTypeTorV2 dbAddressType = 3
addressTypeTorV3 dbAddressType = 4
addressTypeDNS dbAddressType = 5
addressTypeOpaque dbAddressType = math.MaxInt8
)
@@ -3545,6 +3546,7 @@ func collectAddressRecords(addresses []net.Addr) (map[dbAddressType][]string,
addressTypeIPv6: {},
addressTypeTorV2: {},
addressTypeTorV3: {},
addressTypeDNS: {},
addressTypeOpaque: {},
}
addAddr := func(t dbAddressType, addr net.Addr) {
@@ -3574,6 +3576,9 @@ func collectAddressRecords(addresses []net.Addr) (map[dbAddressType][]string,
"a tor address")
}
case *lnwire.DNSAddress:
addAddr(addressTypeDNS, addr)
case *lnwire.OpaqueAddrs:
addAddr(addressTypeOpaque, addr)
@@ -4663,6 +4668,23 @@ func parseAddress(addrType dbAddressType, address string) (net.Addr, error) {
Port: port,
}, nil
case addressTypeDNS:
hostname, portStr, err := net.SplitHostPort(address)
if err != nil {
return nil, fmt.Errorf("unable to split DNS "+
"address: %v", address)
}
port, err := strconv.Atoi(portStr)
if err != nil {
return nil, err
}
return &lnwire.DNSAddress{
Hostname: hostname,
Port: uint16(port),
}, nil
case addressTypeOpaque:
opaque, err := hex.DecodeString(address)
if err != nil {