routerrpc: add XAddLocalChanAliases & XDeleteLocalChanAliases
This commit is contained in:
1 parent
604bd81100
commit
70f82bc4ff
12 files changed
+1137
-232
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user