Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lnrpc: Add UpdateNodeAnnouncement endpoint #5587

Merged
Merged
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ run:
- chainrpc
- dev
- invoicesrpc
- peersrpc
- signrpc
- walletrpc
- watchtowerrpc
Expand Down
1 change: 1 addition & 0 deletions cmd/lncli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ func main() {
app.Commands = append(app.Commands, watchtowerCommands()...)
app.Commands = append(app.Commands, wtclientCommands()...)
app.Commands = append(app.Commands, devCommands()...)
app.Commands = append(app.Commands, peersCommands()...)

if err := app.Run(os.Args); err != nil {
fatal(err)
Expand Down
162 changes: 162 additions & 0 deletions cmd/lncli/peersrpc_active.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
//go:build peersrpc
// +build peersrpc

package main

import (
"fmt"

"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/peersrpc"
"github.com/urfave/cli"
)

// peersCommands will return the set of commands to enable for peersrpc
// builds.
func peersCommands() []cli.Command {
return []cli.Command{
{
Name: "peers",
Category: "Peers",
Usage: "Interacts with the other nodes of the " +
"newtwork",
Subcommands: []cli.Command{
updateNodeAnnouncementCommand,
},
},
}
}

func getPeersClient(ctx *cli.Context) (peersrpc.PeersClient, func()) {
conn := getClientConn(ctx, false)
cleanUp := func() {
conn.Close()
}
return peersrpc.NewPeersClient(conn), cleanUp
}

var updateNodeAnnouncementCommand = cli.Command{
Name: "updatenodeannouncement",
Category: "Peers",
Usage: "update and brodcast a new node announcement",
Description: `
Update the node's information and broadcast a new node announcement.

Add or remove addresses where your node can be reached at, change the
alias/color of the node or enable/disable supported feature bits without
restarting the node. A node announcement with the new information will
be created and brodcasted to the network.`,
ArgsUsage: "[--address_add=] [--address_remove=] [--alias=] " +
"[--color=] [--feature_bit_add=] [--feature_bit_remove=]",
Flags: []cli.Flag{
cli.StringSliceFlag{
Name: "address_add",
Usage: "a new address that should be added to the " +
"set of URIs of this node. Can be set " +
"multiple times in the same command",
},
cli.StringSliceFlag{
Name: "address_remove",
Usage: "an address that needs to be removed from the " +
"set of URIs of this node. Can be set " +
"multiple times in the same command",
},
cli.StringFlag{
Name: "alias",
Usage: "the new alias for this node, e.g. \"bob\"",
},
cli.StringFlag{
Name: "color",
Usage: "the new color for this node, e.g. #c42a81",
},
cli.Int64SliceFlag{
Name: "feature_bit_add",
Usage: "a feature bit index that needs to be enabled. " +
"Can be set multiple times in the same command",
},
cli.Int64SliceFlag{
Name: "feature_bit_remove",
Usage: "a feature bit that needs to be disabled" +
"Can be set multiple times in the same command",
},
},
Action: actionDecorator(updateNodeAnnouncement),
}

func updateNodeAnnouncement(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getPeersClient(ctx)
defer cleanUp()

change := false

req := &peersrpc.NodeAnnouncementUpdateRequest{}

if ctx.IsSet("address_add") {
change = true
for _, addr := range ctx.StringSlice("address_add") {
action := &peersrpc.UpdateAddressAction{
Action: peersrpc.UpdateAction_ADD,
Address: addr,
}
req.AddressUpdates = append(req.AddressUpdates, action)
}
}

if ctx.IsSet("address_remove") {
change = true
for _, addr := range ctx.StringSlice("address_remove") {
action := &peersrpc.UpdateAddressAction{
Action: peersrpc.UpdateAction_REMOVE,
Address: addr,
}
req.AddressUpdates = append(req.AddressUpdates, action)
}
}

if ctx.IsSet("alias") {
change = true
req.Alias = ctx.String("alias")
}

if ctx.IsSet("color") {
change = true
req.Color = ctx.String("color")
}

if ctx.IsSet("feature_bit_add") {
change = true
for _, feature := range ctx.IntSlice("feature_bit_add") {
action := &peersrpc.UpdateFeatureAction{
Action: peersrpc.UpdateAction_ADD,
FeatureBit: lnrpc.FeatureBit(feature),
}
req.FeatureUpdates = append(req.FeatureUpdates, action)
}
}

if ctx.IsSet("feature_bit_remove") {
change = true
for _, feature := range ctx.IntSlice("feature_bit_remove") {
action := &peersrpc.UpdateFeatureAction{
Action: peersrpc.UpdateAction_REMOVE,
FeatureBit: lnrpc.FeatureBit(feature),
}
req.FeatureUpdates = append(req.FeatureUpdates, action)
}
}

if !change {
return fmt.Errorf("no changes for the node information " +
"detected")
}

resp, err := client.UpdateNodeAnnouncement(ctxc, req)
if err != nil {
return err
}

printRespJSON(resp)

return nil
}
11 changes: 11 additions & 0 deletions cmd/lncli/peersrpc_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build !peersrpc
// +build !peersrpc

package main

import "github.com/urfave/cli"

// peersCommands will return nil for non-peersrpc builds.
func peersCommands() []cli.Command {
return nil
}
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/peersrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
"github.com/lightningnetwork/lnd/lnwallet"
Expand Down Expand Up @@ -516,6 +517,7 @@ func DefaultConfig() Config {
SubRPCServers: &subRPCServerConfigs{
SignRPC: &signrpc.Config{},
RouterRPC: routerrpc.DefaultConfig(),
PeersRPC: &peersrpc.Config{},
},
Autopilot: &lncfg.AutoPilot{
MaxChannels: 5,
Expand Down
2 changes: 1 addition & 1 deletion dev.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COPY . /go/src/github.com/lightningnetwork/lnd

RUN cd /go/src/github.com/lightningnetwork/lnd \
&& make \
&& make install tags="signrpc walletrpc chainrpc invoicesrpc"
&& make install tags="signrpc walletrpc chainrpc invoicesrpc peersrpc"

# Start a new, final image to reduce size.
FROM alpine as final
Expand Down
5 changes: 5 additions & 0 deletions docs/release-notes/release-notes-0.15.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ then watch it on chain. Taproot script spends are also supported through the

* [Update description for `state` command](https://github.com/lightningnetwork/lnd/pull/6237).

* Add [update node announcement](https://github.com/lightningnetwork/lnd/pull/5587)
for updating and propagating node information.

## Bug Fixes

* [Pipelining an UpdateFulfillHTLC message now only happens when the related UpdateAddHTLC is locked-in.](https://github.com/lightningnetwork/lnd/pull/6246)
Expand Down Expand Up @@ -173,6 +176,8 @@ then watch it on chain. Taproot script spends are also supported through the

* [Improve validation of a PSBT packet when handling a request to finalize it.](https://github.com/lightningnetwork/lnd/pull/6217)

* [Add new Peers subserver](https://github.com/lightningnetwork/lnd/pull/5587) with a new endpoint for updating the `NodeAnnouncement` data without having to restart the node.

## Documentation

* Improved instructions on [how to build lnd for mobile](https://github.com/lightningnetwork/lnd/pull/6085).
Expand Down
5 changes: 5 additions & 0 deletions feature/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ func (m *Manager) GetRaw(set Set) *lnwire.RawFeatureVector {
return lnwire.NewRawFeatureVector()
}

// SetRaw sets a new raw feature vector for the given set.
func (m *Manager) SetRaw(set Set, raw *lnwire.RawFeatureVector) {
m.fsets[set] = raw
}

// Get returns a feature vector for the passed set. If no set is known, an empty
// feature vector is returned.
func (m *Manager) Get(set Set) *lnwire.FeatureVector {
Expand Down
20 changes: 2 additions & 18 deletions lnrpc/autopilotrpc/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/lightningnetwork/lnd/build"
)

// log is a logger that is initialized with no output filters. This means the
// log is a logger that is initialized with no output filters. This means the
// package will not perform any logging by default until the caller requests
// it.
var log btclog.Logger
Expand All @@ -21,25 +21,9 @@ func DisableLog() {
UseLogger(btclog.Disabled)
}

// UseLogger uses a specified Logger to output package logging info. This
// UseLogger uses a specified Logger to output package logging info. This
// should be used in preference to SetLogWriter if the caller is also using
// btclog.
func UseLogger(logger btclog.Logger) {
log = logger
}

// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string // nolint:unused

// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
return c()
}

// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure { // nolint:unused
return logClosure(c)
}
18 changes: 1 addition & 17 deletions lnrpc/chainrpc/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/lightningnetwork/lnd/build"
)

// log is a logger that is initialized with no output filters. This
// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger
Expand All @@ -27,19 +27,3 @@ func DisableLog() {
func UseLogger(logger btclog.Logger) {
log = logger
}

// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string // nolint:unused

// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
return c()
}

// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure { // nolint:unused
return logClosure(c)
}
2 changes: 1 addition & 1 deletion lnrpc/gen_protos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function generate() {
--custom_opt="$opts" \
lightning.proto stateservice.proto walletunlocker.proto

PACKAGES="autopilotrpc chainrpc invoicesrpc routerrpc signrpc verrpc walletrpc watchtowerrpc wtclientrpc devrpc"
PACKAGES="autopilotrpc chainrpc invoicesrpc peersrpc routerrpc signrpc verrpc walletrpc watchtowerrpc wtclientrpc devrpc"
for package in $PACKAGES; do
# Special import for the wallet kit.
manual_import=""
Expand Down
4 changes: 2 additions & 2 deletions lnrpc/invoicesrpc/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/lightningnetwork/lnd/build"
)

// log is a logger that is initialized with no output filters. This means the
// log is a logger that is initialized with no output filters. This means the
// package will not perform any logging by default until the caller requests
// it.
var log btclog.Logger
Expand All @@ -21,7 +21,7 @@ func DisableLog() {
UseLogger(btclog.Disabled)
}

// UseLogger uses a specified Logger to output package logging info. This
// UseLogger uses a specified Logger to output package logging info. This
// should be used in preference to SetLogWriter if the caller is also using
// btclog.
func UseLogger(logger btclog.Logger) {
Expand Down
29 changes: 29 additions & 0 deletions lnrpc/peersrpc/config_active.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//go:build peersrpc
// +build peersrpc

package peersrpc

import (
"net"

"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
)

// Config is the primary configuration struct for the peers RPC subserver.
// It contains all the items required for the server to carry out its duties.
// The fields with struct tags are meant to be parsed as normal configuration
// options, while if able to be populated, the latter fields MUST also be
// specified.
type Config struct {
// GetNodeAnnouncement is used to send our retrieve the current
// node announcement information.
GetNodeAnnouncement func() (lnwire.NodeAnnouncement, error)

// ParseAddr parses an address from its string format to a net.Addr.
ParseAddr func(addr string) (net.Addr, error)

// UpdateNodeAnnouncement updates our node announcement applying the
// given NodeAnnModifiers and broadcasts the new version to the network.
UpdateNodeAnnouncement func(...netann.NodeAnnModifier) error
}
7 changes: 7 additions & 0 deletions lnrpc/peersrpc/config_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build !peersrpc
// +build !peersrpc

package peersrpc

// Config is empty for non-peersrpc builds.
type Config struct{}
Loading