multi: add base lookup option to AddLocalAlias
What changed, and why it matters
This commit adds a new optional flag to LND's internal alias manager that lets callers request a reverse lookup from a channel alias back to the underlying real channel ID. It is a small feature enhancement for a new RPC endpoint and does not appear to fix or introduce a security vulnerability. The change is defensive in nature and improves consistency for manually-added aliases.
No security action required. Treat as a normal feature/refactor commit. If reviewing for release notes, note it as an RPC usability improvement for custom channel aliases.
Security signals we found
No security-relevant bug fix or vulnerability patch is visible in the diff.
Change is purely additive: a new optional flag with default-off behavior.
Existing `gossip=true` path already stored the reverse mapping; new option only extends that behavior to non-gossip aliases.
No input validation, authorization, cryptographic, or network changes are present.
No incident, CVE, or vendor security disclosure is referenced in the commit or supplied materials.
Evidence from the diff
The patch introduces a functional option WithBaseLookup() for AddLocalAlias in aliasmgr/aliasmgr.go. When set, the alias manager stores the aliasToBase mapping even if the gossip flag is false. Previously this reverse mapping was only stored when gossip=true. The only production caller that enables the new option is XAddLocalChanAliases in lnrpc/routerrpc/router_server.go, so that aliases added via RPC can later be resolved via FindBaseLocalChanAlias. The change updates the aliasHandler interface in funding/interfaces.go, the peer Config callback signature in peer/brontide.go, and corresponding tests/mocks.
Changed components
aliasmgr/aliasmgr.golnrpc/routerrpc/router_server.gofunding/interfaces.gopeer/brontide.goaliasmgr/aliasmgr_test.gofunding/manager_test.goInspect captured patch +63 / −13
diff --git a/aliasmgr/aliasmgr.go b/aliasmgr/aliasmgr.go
index 258d205..a8cd248 100644
--- a/aliasmgr/aliasmgr.go
+++ b/aliasmgr/aliasmgr.go
@@ -239,14 +239,43 @@ func (m *Manager) populateMaps() error {
return nil
}
+// addAliasCfg is a struct that hosts various options related to adding a local
+// alias to the alias manager.
+type addAliasCfg struct {
+ // baseLookup signals that the alias should also store a reverse look-up
+ // to the base scid.
+ baseLookup bool
+}
+
+// AddLocalAliasOption is a functional option that modifies the configuration
+// for adding a local alias.
+type AddLocalAliasOption func(cfg *addAliasCfg)
+
+// WithBaseLookup is a functional option that controls whether a reverse lookup
+// will be stored from the alias to the base scid.
+func WithBaseLookup() AddLocalAliasOption {
+ return func(cfg *addAliasCfg) {
+ cfg.baseLookup = true
+ }
+}
+
// AddLocalAlias adds a database mapping from the passed alias to the passed
// base SCID. The gossip boolean marks whether or not to create a mapping
// that the gossiper will use. It is set to false for the upgrade path where
// the feature-bit is toggled on and there are existing channels. The linkUpdate
-// flag is used to signal whether this function should also trigger an update
-// on the htlcswitch scid alias maps.
+// flag is used to signal whether this function should also trigger an update on
+// the htlcswitch scid alias maps.
+//
+// NOTE: The following aliases will not be persisted (will be lost on restart):
+// - Aliases that were created without gossip flag.
+// - Aliases that correspond to confirmed channels.
func (m *Manager) AddLocalAlias(alias, baseScid lnwire.ShortChannelID,
- gossip, linkUpdate bool) error {
+ gossip, linkUpdate bool, opts ...AddLocalAliasOption) error {
+
+ cfg := addAliasCfg{}
+ for _, opt := range opts {
+ opt(&cfg)
+ }
// We need to lock the manager for the whole duration of this method,
// except for the very last part where we call the link updater. In
@@ -302,8 +331,9 @@ func (m *Manager) AddLocalAlias(alias, baseScid lnwire.ShortChannelID,
// Update the aliasToBase and baseToSet maps.
m.baseToSet[baseScid] = append(m.baseToSet[baseScid], alias)
- // Only store the gossiper map if gossip is true.
- if gossip {
+ // Only store the gossiper map if gossip is true, or if the caller
+ // explicitly asked to store this reverse mapping.
+ if gossip || cfg.baseLookup {
m.aliasToBase[alias] = baseScid
}
@@ -342,7 +372,9 @@ func (m *Manager) GetAliases(
}
// FindBaseSCID finds the base SCID for a given alias. This is used in the
-// gossiper to find the correct SCID to lookup in the graph database.
+// gossiper to find the correct SCID to lookup in the graph database. It can
+// also be used to look up the base for manual aliases that were added over the
+// RPC.
func (m *Manager) FindBaseSCID(
alias lnwire.ShortChannelID) (lnwire.ShortChannelID, error) {
@@ -446,7 +478,7 @@ func (m *Manager) DeleteLocalAlias(alias,
}
// Finally, we'll delete the aliasToBase mapping from the Manager's
- // cache (but this is only set if we gossip the alias).
+ // cache.
delete(m.aliasToBase, alias)
// We definitely need to unlock the Manager before calling the link
diff --git a/aliasmgr/aliasmgr_test.go b/aliasmgr/aliasmgr_test.go
index b288ade..3237e5b 100644
--- a/aliasmgr/aliasmgr_test.go
+++ b/aliasmgr/aliasmgr_test.go
@@ -179,10 +179,19 @@ func TestAliasLifecycle(t *testing.T) {
require.Equal(t, StartingAlias, firstRequested)
// We now manually add the next alias from the range as a custom alias.
+ // This time we also use the base lookup option, in order to be able to
+ // go from alias back to the base scid.
secondAlias := getNextScid(firstRequested)
- err = aliasStore.AddLocalAlias(secondAlias, baseScid, false, true)
+ err = aliasStore.AddLocalAlias(
+ secondAlias, baseScid, false, true, WithBaseLookup(),
+ )
+ require.NoError(t, err)
+
+ baseLookup, err := aliasStore.FindBaseSCID(secondAlias)
require.NoError(t, err)
+ require.Equal(t, baseScid, baseLookup)
+
// When we now request another alias from the allocation list, we expect
// the third one (tx position 2) to be returned.
thirdRequested, err := aliasStore.RequestAlias()
diff --git a/funding/interfaces.go b/funding/interfaces.go
index 30cae08..669f01a 100644
--- a/funding/interfaces.go
+++ b/funding/interfaces.go
@@ -1,6 +1,7 @@
package funding
import (
+ "github.com/lightningnetwork/lnd/aliasmgr"
"github.com/lightningnetwork/lnd/lnpeer"
"github.com/lightningnetwork/lnd/lnwire"
)
@@ -36,8 +37,8 @@ type aliasHandler interface {
GetPeerAlias(lnwire.ChannelID) (lnwire.ShortChannelID, error)
// AddLocalAlias persists an alias to an underlying alias store.
- AddLocalAlias(lnwire.ShortChannelID, lnwire.ShortChannelID, bool,
- bool) error
+ AddLocalAlias(lnwire.ShortChannelID, lnwire.ShortChannelID, bool, bool,
+ ...aliasmgr.AddLocalAliasOption) error
// GetAliases returns the set of aliases given the main SCID of a
// channel. This SCID will be an alias for zero-conf channels and will
diff --git a/funding/manager_test.go b/funding/manager_test.go
index 5f217d4..57d9299 100644
--- a/funding/manager_test.go
+++ b/funding/manager_test.go
@@ -21,6 +21,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/wallet"
+ "github.com/lightningnetwork/lnd/aliasmgr"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/chainreg"
acpt "github.com/lightningnetwork/lnd/chanacceptor"
@@ -162,7 +163,8 @@ func (m *mockAliasMgr) GetPeerAlias(lnwire.ChannelID) (lnwire.ShortChannelID,
}
func (m *mockAliasMgr) AddLocalAlias(lnwire.ShortChannelID,
- lnwire.ShortChannelID, bool, bool) error {
+ lnwire.ShortChannelID, bool, bool,
+ ...aliasmgr.AddLocalAliasOption) error {
return nil
}
diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go
index 894edf2..a1b0eba 100644
--- a/lnrpc/routerrpc/router_server.go
+++ b/lnrpc/routerrpc/router_server.go
@@ -1713,8 +1713,13 @@ func (s *Server) XAddLocalChanAliases(_ context.Context,
rpcAlias)
}
+ // We set the baseLookup flag as we want the alias
+ // manager to keep a mapping from the alias back to its
+ // base scid, in order to be able to provide it via the
+ // FindBaseLocalChanAlias RPC.
err = s.cfg.AliasMgr.AddLocalAlias(
aliasScid, baseScid, false, true,
+ aliasmgr.WithBaseLookup(),
)
if err != nil {
return nil, fmt.Errorf("error adding scid "+
diff --git a/peer/brontide.go b/peer/brontide.go
index ad3ffdc..d1f9ef1 100644
--- a/peer/brontide.go
+++ b/peer/brontide.go
@@ -19,6 +19,7 @@ import (
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btclog/v2"
+ "github.com/lightningnetwork/lnd/aliasmgr"
"github.com/lightningnetwork/lnd/brontide"
"github.com/lightningnetwork/lnd/buffer"
"github.com/lightningnetwork/lnd/chainntnfs"
@@ -404,8 +405,8 @@ type Config struct {
RequestAlias func() (lnwire.ShortChannelID, error)
// AddLocalAlias persists an alias to an underlying alias store.
- AddLocalAlias func(alias, base lnwire.ShortChannelID,
- gossip, liveUpdate bool) error
+ AddLocalAlias func(alias, base lnwire.ShortChannelID, gossip,
+ liveUpdate bool, opts ...aliasmgr.AddLocalAliasOption) error
// AuxLeafStore is an optional store that can be used to store auxiliary
// leaves for certain custom channel types.
Why this scored 21/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.