routerrpc: add XAddLocalChanAliases & XDeleteLocalChanAliases

This commit is contained in:
George Tsagkarelis authored and Oliver Gugger committed 2024-09-05 10:29:42 +02:00
1 parent 604bd81100
commit 70f82bc4ff
12 files changed
+1137 -232

No files matched your search

+136
View File
@@ -14,6 +14,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/wire"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/lightningnetwork/lnd/aliasmgr"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/lnrpc"
@@ -55,6 +56,14 @@ var (
errUnexpectedFailureSource = errors.New("unexpected failure source")
// ErrAliasAlreadyExists is returned if a new SCID alias is attempted
// to be added that already exists.
ErrAliasAlreadyExists = errors.New("alias already exists")
// ErrNoValidAlias is returned if an alias is not in the valid range for
// allowed SCID aliases.
ErrNoValidAlias = errors.New("not a valid alias")
// macaroonOps are the set of capabilities that our minted macaroon (if
// it doesn't already exist) will have.
macaroonOps = []bakery.Op{
@@ -142,6 +151,14 @@ var (
Entity: "offchain",
Action: "write",
}},
"/routerrpc.Router/XAddLocalChanAliases": {{
Entity: "offchain",
Action: "write",
}},
"/routerrpc.Router/XDeleteLocalChanAliases": {{
Entity: "offchain",
Action: "write",
}},
}
// DefaultRouterMacFilename is the default name of the router macaroon
@@ -1531,6 +1548,125 @@ func (s *Server) HtlcInterceptor(stream Router_HtlcInterceptorServer) error {
).run()
}
// XAddLocalChanAliases is an experimental API that creates a set of new
// channel SCID alias mappings. The final total set of aliases in the manager
// after the add operation is returned. This is only a locally stored alias, and
// will not be communicated to the channel peer via any message. Therefore,
// routing over such an alias will only work if the peer also calls this same
// RPC on their end. If an alias already exists, an error is returned.
func (s *Server) XAddLocalChanAliases(_ context.Context,
in *AddAliasesRequest) (*AddAliasesResponse, error) {
existingAliases := s.cfg.AliasMgr.ListAliases()
// aliasExists checks if the new alias already exists in the alias map.
aliasExists := func(newAlias uint64,
baseScid lnwire.ShortChannelID) (bool, error) {
// First check that we actually have a channel for the given
// base scid. This should succeed for any channel where the
// option-scid-alias feature bit was negotiated.
if _, ok := existingAliases[baseScid]; !ok {
return false, fmt.Errorf("base scid %v not found",
baseScid)
}
for base, aliases := range existingAliases {
for _, alias := range aliases {
exists := alias.ToUint64() == newAlias
// Trying to add an alias that we already have
// for another channel is wrong.
if exists && base != baseScid {
return true, fmt.Errorf("%w: alias %v "+
"already exists for base scid "+
"%v", ErrAliasAlreadyExists,
alias, base)
}
if exists {
return true, nil
}
}
}
return false, nil
}
for _, v := range in.AliasMaps {
baseScid := lnwire.NewShortChanIDFromInt(v.BaseScid)
for _, rpcAlias := range v.Aliases {
// If not, let's add it to the alias manager now.
aliasScid := lnwire.NewShortChanIDFromInt(rpcAlias)
// But we only add it, if it's a valid alias, as defined
// by the BOLT spec.
if !aliasmgr.IsAlias(aliasScid) {
return nil, fmt.Errorf("%w: SCID alias %v is "+
"not a valid alias", ErrNoValidAlias,
aliasScid)
}
exists, err := aliasExists(rpcAlias, baseScid)
if err != nil {
return nil, err
}
// If the alias already exists, we see that as an error.
// This is to avoid "silent" collisions.
if exists {
return nil, fmt.Errorf("%w: SCID alias %v "+
"already exists", ErrAliasAlreadyExists,
rpcAlias)
}
err = s.cfg.AliasMgr.AddLocalAlias(
aliasScid, baseScid, false, true,
)
if err != nil {
return nil, fmt.Errorf("error adding scid "+
"alias, base_scid=%v, alias_scid=%v: "+
"%w", baseScid, aliasScid, err)
}
}
}
return &AddAliasesResponse{
AliasMaps: lnrpc.MarshalAliasMap(s.cfg.AliasMgr.ListAliases()),
}, nil
}
// XDeleteLocalChanAliases is an experimental API that deletes a set of alias
// mappings. The final total set of aliases in the manager after the delete
// operation is returned. The deletion will not be communicated to the channel
// peer via any message.
func (s *Server) XDeleteLocalChanAliases(_ context.Context,
in *DeleteAliasesRequest) (*DeleteAliasesResponse,
error) {
for _, v := range in.AliasMaps {
baseScid := lnwire.NewShortChanIDFromInt(v.BaseScid)
for _, alias := range v.Aliases {
aliasScid := lnwire.NewShortChanIDFromInt(alias)
err := s.cfg.AliasMgr.DeleteLocalAlias(
aliasScid, baseScid,
)
if err != nil {
return nil, fmt.Errorf("error deleting scid "+
"alias, base_scid=%v, alias_scid=%v: "+
"%w", baseScid, aliasScid, err)
}
}
}
return &DeleteAliasesResponse{
AliasMaps: lnrpc.MarshalAliasMap(s.cfg.AliasMgr.ListAliases()),
}, nil
}
func extractOutPoint(req *UpdateChanStatusRequest) (*wire.OutPoint, error) {
chanPoint := req.GetChanPoint()
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)