graph/db: extract DNS addresses during SQL migration
In this commit, we take advantage of the graph SQL migration and use it to also extract DNS addresses from the opaque address type. We use opaque addresses to store addresses that we dont understand yet. We recently added logic for DNS addresses and so we may have persisted node announcements that have DNS addresses but we would currently have them stored under the opaque address type. So we use this migration to see if we can extract such addresses. A few decisions were made here: 1) If multiple DNS addressees are extracted, this is ok and we continue to migrate the node even though this is actually invalid at a protocol level. We will currently check (at a higher level) that a node announcement only has 1 DNS address in it before we broadcast it though. 2) If an invalid DNS address is encountered (so we hit the DNS type descriptor but then the rest of the DNS address payload is invalid and cannot be parsed into the expected hostname:port, then we skip migrating the node completely.
This commit is contained in:
2 files changed
+249
-10
No files matched your search
+79
-10
@@ -260,18 +260,17 @@ func migrateNodes(ctx context.Context, cfg *sqldb.QueryConfig,
|
||||
"opaque data for node %x: %w", pub, err)
|
||||
}
|
||||
|
||||
if err = maybeOverrideNodeAddresses(node); err != nil {
|
||||
skipped++
|
||||
log.Warnf("Skipping migration of node %x with invalid "+
|
||||
"address (%v): %v", pub, node.Addresses, err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
count++
|
||||
chunk++
|
||||
|
||||
// TODO(elle): At this point, we should check the loaded node
|
||||
// to see if we should extract any DNS addresses from its
|
||||
// opaque type addresses. This is expected to be done in:
|
||||
// https://github.com/lightningnetwork/lnd/pull/9455.
|
||||
// This TODO is being tracked in
|
||||
// https://github.com/lightningnetwork/lnd/issues/9795 as this
|
||||
// must be addressed before making this code path active in
|
||||
// production.
|
||||
|
||||
// Write the node to the SQL database.
|
||||
id, err := insertNodeSQLMig(ctx, sqlDB, node)
|
||||
if err != nil {
|
||||
@@ -323,12 +322,82 @@ func migrateNodes(ctx context.Context, cfg *sqldb.QueryConfig,
|
||||
}
|
||||
|
||||
log.Infof("Migrated %d nodes from KV to SQL in %v (skipped %d nodes "+
|
||||
"due to invalid TLV streams)", count, time.Since(totalTime),
|
||||
"due to invalid TLV streams or invalid addresses)", count,
|
||||
time.Since(totalTime),
|
||||
|
||||
skipped)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// maybeOverrideNodeAddresses checks if the node has any opaque addresses that
|
||||
// can be parsed. If so, it replaces the node's addresses with the parsed
|
||||
// addresses. If the address is unparseable, it returns an error.
|
||||
func maybeOverrideNodeAddresses(node *models.LightningNode) error {
|
||||
// In the majority of cases, the number of node addresses will remain
|
||||
// unchanged, so we pre-allocate a slice of the same length.
|
||||
addrs := make([]net.Addr, 0, len(node.Addresses))
|
||||
|
||||
// Iterate over each address in search of any opaque addresses that we
|
||||
// can inspect.
|
||||
for _, addr := range node.Addresses {
|
||||
opaque, ok := addr.(*lnwire.OpaqueAddrs)
|
||||
if !ok {
|
||||
// Any non-opaque address is left unchanged.
|
||||
addrs = append(addrs, addr)
|
||||
continue
|
||||
}
|
||||
|
||||
// For each opaque address, we'll now attempt to parse out any
|
||||
// known addresses. We'll do this in a loop, as it's possible
|
||||
// that there are several addresses encoded in a single opaque
|
||||
// address.
|
||||
payload := opaque.Payload
|
||||
for len(payload) > 0 {
|
||||
var (
|
||||
r = bytes.NewReader(payload)
|
||||
numAddrBytes = uint16(len(payload))
|
||||
)
|
||||
byteRead, readAddr, err := lnwire.ReadAddress(
|
||||
r, numAddrBytes,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we were able to read an address, we'll add it to
|
||||
// our list of addresses.
|
||||
if readAddr != nil {
|
||||
addrs = append(addrs, readAddr)
|
||||
}
|
||||
|
||||
// If the address we read was an opaque address, it
|
||||
// means we've hit an unknown address type, and it has
|
||||
// consumed the rest of the payload. We can break out
|
||||
// of the loop.
|
||||
if _, ok := readAddr.(*lnwire.OpaqueAddrs); ok {
|
||||
break
|
||||
}
|
||||
|
||||
// If we've read all the bytes, we can also break.
|
||||
if byteRead >= numAddrBytes {
|
||||
break
|
||||
}
|
||||
|
||||
// Otherwise, we'll advance our payload slice and
|
||||
// continue.
|
||||
payload = payload[byteRead:]
|
||||
}
|
||||
}
|
||||
|
||||
// Override the node addresses if we have any.
|
||||
if len(addrs) != 0 {
|
||||
node.Addresses = addrs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateSourceNode migrates the source node from the KV backend to the
|
||||
// SQL database.
|
||||
func migrateSourceNode(ctx context.Context, kvdb kvdb.Backend,
|
||||
|
||||
Reference in new issue
Block a user