Merge pull request #5587 from positiveblue/5466-update-node-announcement-data

lnrpc: Add UpdateNodeAnnouncement endpoint
This commit is contained in:
Olaoluwa Osuntokun authored and GitHub committed 2022-04-11 22:32:12 -04:00
commit 2fd900b172
40 files changed
+2348 -112

No files matched your search

+2 -18
View File
@@ -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
@@ -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)
}
+1 -17
View File
@@ -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
@@ -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)
}
+1 -1
View File
@@ -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=""
+2 -2
View File
@@ -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
@@ -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) {
+29
View File
@@ -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
View File
@@ -0,0 +1,7 @@
//go:build !peersrpc
// +build !peersrpc
package peersrpc
// Config is empty for non-peersrpc builds.
type Config struct{}
+55
View File
@@ -0,0 +1,55 @@
//go:build peersrpc
// +build peersrpc
package peersrpc
import (
"fmt"
"github.com/lightningnetwork/lnd/lnrpc"
)
// createNewSubServer is a helper method that will create the new sub server
// given the main config dispatcher method. If we're unable to find the config
// that is meant for us in the config dispatcher, then we'll exit with an
// error.
func createNewSubServer(configRegistry lnrpc.SubServerConfigDispatcher) (
*Server, lnrpc.MacaroonPerms, error) {
// We'll attempt to look up the config that we expect, according to our
// subServerName name. If we can't find this, then we'll exit with an
// error, as we're unable to properly initialize ourselves without this
// config.
subServerConf, ok := configRegistry.FetchConfig(subServerName)
if !ok {
return nil, nil, fmt.Errorf("unable to find config for "+
"subserver type %s", subServerName)
}
// Now that we've found an object mapping to our service name, we'll
// ensure that it's the type we need.
config, ok := subServerConf.(*Config)
if !ok {
return nil, nil, fmt.Errorf("wrong type of config for "+
"subserver %s, expected %T got %T", subServerName,
&Config{}, subServerConf)
}
return New(config)
}
func init() {
subServer := &lnrpc.SubServerDriver{
SubServerName: subServerName,
NewGrpcHandler: func() lnrpc.GrpcHandler {
return &ServerShell{}
},
}
// If the build tag is active, then we'll register ourselves as a
// sub-RPC server within the global lnrpc package namespace.
if err := lnrpc.RegisterSubServer(subServer); err != nil {
panic(fmt.Sprintf("failed to register sub server driver "+
"'%s': %v", subServerName, err))
}
}
+32
View File
@@ -0,0 +1,32 @@
package peersrpc
import (
"github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/build"
)
// 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
// Subsystem defines the logging code for this subsystem.
const Subsystem = "PRPC"
// The default amount of logging is none.
func init() {
UseLogger(build.NewSubLogger(Subsystem, nil))
}
// DisableLog disables all library log output. Logging output is disabled by
// by default until UseLogger is called.
func DisableLog() {
UseLogger(btclog.Disabled)
}
// 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
}
+554
View File
@@ -0,0 +1,554 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.6.1
// source: peersrpc/peers.proto
package peersrpc
import (
lnrpc "github.com/lightningnetwork/lnd/lnrpc"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// UpdateAction is used to determine the kind of action we are referring to.
type UpdateAction int32
const (
// ADD indicates this is an "insertion" kind of action.
UpdateAction_ADD UpdateAction = 0
// REMOVE indicates this is a "deletion" kind of action.
UpdateAction_REMOVE UpdateAction = 1
)
// Enum value maps for UpdateAction.
var (
UpdateAction_name = map[int32]string{
0: "ADD",
1: "REMOVE",
}
UpdateAction_value = map[string]int32{
"ADD": 0,
"REMOVE": 1,
}
)
func (x UpdateAction) Enum() *UpdateAction {
p := new(UpdateAction)
*p = x
return p
}
func (x UpdateAction) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (UpdateAction) Descriptor() protoreflect.EnumDescriptor {
return file_peersrpc_peers_proto_enumTypes[0].Descriptor()
}
func (UpdateAction) Type() protoreflect.EnumType {
return &file_peersrpc_peers_proto_enumTypes[0]
}
func (x UpdateAction) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use UpdateAction.Descriptor instead.
func (UpdateAction) EnumDescriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{0}
}
type FeatureSet int32
const (
//
//SET_INIT identifies features that should be sent in an Init message to
//a remote peer.
FeatureSet_SET_INIT FeatureSet = 0
//
//SET_LEGACY_GLOBAL identifies features that should be set in the legacy
//GlobalFeatures field of an Init message, which maintains backwards
//compatibility with nodes that haven't implemented flat features.
FeatureSet_SET_LEGACY_GLOBAL FeatureSet = 1
//
//SET_NODE_ANN identifies features that should be advertised on node
//announcements.
FeatureSet_SET_NODE_ANN FeatureSet = 2
//
//SET_INVOICE identifies features that should be advertised on invoices
//generated by the daemon.
FeatureSet_SET_INVOICE FeatureSet = 3
//
//SET_INVOICE_AMP identifies the features that should be advertised on
//AMP invoices generated by the daemon.
FeatureSet_SET_INVOICE_AMP FeatureSet = 4
)
// Enum value maps for FeatureSet.
var (
FeatureSet_name = map[int32]string{
0: "SET_INIT",
1: "SET_LEGACY_GLOBAL",
2: "SET_NODE_ANN",
3: "SET_INVOICE",
4: "SET_INVOICE_AMP",
}
FeatureSet_value = map[string]int32{
"SET_INIT": 0,
"SET_LEGACY_GLOBAL": 1,
"SET_NODE_ANN": 2,
"SET_INVOICE": 3,
"SET_INVOICE_AMP": 4,
}
)
func (x FeatureSet) Enum() *FeatureSet {
p := new(FeatureSet)
*p = x
return p
}
func (x FeatureSet) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (FeatureSet) Descriptor() protoreflect.EnumDescriptor {
return file_peersrpc_peers_proto_enumTypes[1].Descriptor()
}
func (FeatureSet) Type() protoreflect.EnumType {
return &file_peersrpc_peers_proto_enumTypes[1]
}
func (x FeatureSet) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use FeatureSet.Descriptor instead.
func (FeatureSet) EnumDescriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{1}
}
type UpdateAddressAction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Determines the kind of action.
Action UpdateAction `protobuf:"varint,1,opt,name=action,proto3,enum=peersrpc.UpdateAction" json:"action,omitempty"`
// The address used to apply the update action.
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
}
func (x *UpdateAddressAction) Reset() {
*x = UpdateAddressAction{}
if protoimpl.UnsafeEnabled {
mi := &file_peersrpc_peers_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateAddressAction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateAddressAction) ProtoMessage() {}
func (x *UpdateAddressAction) ProtoReflect() protoreflect.Message {
mi := &file_peersrpc_peers_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateAddressAction.ProtoReflect.Descriptor instead.
func (*UpdateAddressAction) Descriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{0}
}
func (x *UpdateAddressAction) GetAction() UpdateAction {
if x != nil {
return x.Action
}
return UpdateAction_ADD
}
func (x *UpdateAddressAction) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
type UpdateFeatureAction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Determines the kind of action.
Action UpdateAction `protobuf:"varint,1,opt,name=action,proto3,enum=peersrpc.UpdateAction" json:"action,omitempty"`
// The feature bit used to apply the update action.
FeatureBit lnrpc.FeatureBit `protobuf:"varint,2,opt,name=feature_bit,json=featureBit,proto3,enum=lnrpc.FeatureBit" json:"feature_bit,omitempty"`
}
func (x *UpdateFeatureAction) Reset() {
*x = UpdateFeatureAction{}
if protoimpl.UnsafeEnabled {
mi := &file_peersrpc_peers_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateFeatureAction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateFeatureAction) ProtoMessage() {}
func (x *UpdateFeatureAction) ProtoReflect() protoreflect.Message {
mi := &file_peersrpc_peers_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateFeatureAction.ProtoReflect.Descriptor instead.
func (*UpdateFeatureAction) Descriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{1}
}
func (x *UpdateFeatureAction) GetAction() UpdateAction {
if x != nil {
return x.Action
}
return UpdateAction_ADD
}
func (x *UpdateFeatureAction) GetFeatureBit() lnrpc.FeatureBit {
if x != nil {
return x.FeatureBit
}
return lnrpc.FeatureBit_DATALOSS_PROTECT_REQ
}
type NodeAnnouncementUpdateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Set of changes for the features that the node supports.
FeatureUpdates []*UpdateFeatureAction `protobuf:"bytes,1,rep,name=feature_updates,json=featureUpdates,proto3" json:"feature_updates,omitempty"`
// Color is the node's color in hex code format.
Color string `protobuf:"bytes,2,opt,name=color,proto3" json:"color,omitempty"`
// Alias or nick name of the node.
Alias string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
// Set of changes for the node's known addresses.
AddressUpdates []*UpdateAddressAction `protobuf:"bytes,4,rep,name=address_updates,json=addressUpdates,proto3" json:"address_updates,omitempty"`
}
func (x *NodeAnnouncementUpdateRequest) Reset() {
*x = NodeAnnouncementUpdateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_peersrpc_peers_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NodeAnnouncementUpdateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NodeAnnouncementUpdateRequest) ProtoMessage() {}
func (x *NodeAnnouncementUpdateRequest) ProtoReflect() protoreflect.Message {
mi := &file_peersrpc_peers_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NodeAnnouncementUpdateRequest.ProtoReflect.Descriptor instead.
func (*NodeAnnouncementUpdateRequest) Descriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{2}
}
func (x *NodeAnnouncementUpdateRequest) GetFeatureUpdates() []*UpdateFeatureAction {
if x != nil {
return x.FeatureUpdates
}
return nil
}
func (x *NodeAnnouncementUpdateRequest) GetColor() string {
if x != nil {
return x.Color
}
return ""
}
func (x *NodeAnnouncementUpdateRequest) GetAlias() string {
if x != nil {
return x.Alias
}
return ""
}
func (x *NodeAnnouncementUpdateRequest) GetAddressUpdates() []*UpdateAddressAction {
if x != nil {
return x.AddressUpdates
}
return nil
}
type NodeAnnouncementUpdateResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ops []*lnrpc.Op `protobuf:"bytes,1,rep,name=ops,proto3" json:"ops,omitempty"`
}
func (x *NodeAnnouncementUpdateResponse) Reset() {
*x = NodeAnnouncementUpdateResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_peersrpc_peers_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NodeAnnouncementUpdateResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NodeAnnouncementUpdateResponse) ProtoMessage() {}
func (x *NodeAnnouncementUpdateResponse) ProtoReflect() protoreflect.Message {
mi := &file_peersrpc_peers_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NodeAnnouncementUpdateResponse.ProtoReflect.Descriptor instead.
func (*NodeAnnouncementUpdateResponse) Descriptor() ([]byte, []int) {
return file_peersrpc_peers_proto_rawDescGZIP(), []int{3}
}
func (x *NodeAnnouncementUpdateResponse) GetOps() []*lnrpc.Op {
if x != nil {
return x.Ops
}
return nil
}
var File_peersrpc_peers_proto protoreflect.FileDescriptor
var file_peersrpc_peers_proto_rawDesc = []byte{
0x0a, 0x14, 0x70, 0x65, 0x65, 0x72, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x65, 0x65, 0x72, 0x73, 0x72, 0x70, 0x63,
0x1a, 0x0f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x5f, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x73,
0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x22, 0x79, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x61, 0x74,
0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x70, 0x65, 0x65, 0x72,
0x73, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x0b, 0x66, 0x65, 0x61,
0x74, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x69,
0x74, 0x52, 0x0a, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x69, 0x74, 0x22, 0xdb, 0x01,
0x0a, 0x1d, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65,
0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x46, 0x0a, 0x0f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x73,
0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72,
0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x14, 0x0a,
0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c,
0x69, 0x61, 0x73, 0x12, 0x46, 0x0a, 0x0f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70,
0x65, 0x65, 0x72, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x1e, 0x4e,
0x6f, 0x64, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a,
0x03, 0x6f, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x6c, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x4f, 0x70, 0x52, 0x03, 0x6f, 0x70, 0x73, 0x2a, 0x23, 0x0a, 0x0c, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x44,
0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x01, 0x2a,
0x69, 0x0a, 0x0a, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x12, 0x0c, 0x0a,
0x08, 0x53, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53,
0x45, 0x54, 0x5f, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c,
0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x41,
0x4e, 0x4e, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x4f,
0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x56,
0x4f, 0x49, 0x43, 0x45, 0x5f, 0x41, 0x4d, 0x50, 0x10, 0x04, 0x32, 0x74, 0x0a, 0x05, 0x50, 0x65,
0x65, 0x72, 0x73, 0x12, 0x6b, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64,
0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x2e,
0x70, 0x65, 0x65, 0x72, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x6e, 0x6e,
0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x73, 0x72, 0x70,
0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65,
0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x72,
0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_peersrpc_peers_proto_rawDescOnce sync.Once
file_peersrpc_peers_proto_rawDescData = file_peersrpc_peers_proto_rawDesc
)
func file_peersrpc_peers_proto_rawDescGZIP() []byte {
file_peersrpc_peers_proto_rawDescOnce.Do(func() {
file_peersrpc_peers_proto_rawDescData = protoimpl.X.CompressGZIP(file_peersrpc_peers_proto_rawDescData)
})
return file_peersrpc_peers_proto_rawDescData
}
var file_peersrpc_peers_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_peersrpc_peers_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_peersrpc_peers_proto_goTypes = []interface{}{
(UpdateAction)(0), // 0: peersrpc.UpdateAction
(FeatureSet)(0), // 1: peersrpc.FeatureSet
(*UpdateAddressAction)(nil), // 2: peersrpc.UpdateAddressAction
(*UpdateFeatureAction)(nil), // 3: peersrpc.UpdateFeatureAction
(*NodeAnnouncementUpdateRequest)(nil), // 4: peersrpc.NodeAnnouncementUpdateRequest
(*NodeAnnouncementUpdateResponse)(nil), // 5: peersrpc.NodeAnnouncementUpdateResponse
(lnrpc.FeatureBit)(0), // 6: lnrpc.FeatureBit
(*lnrpc.Op)(nil), // 7: lnrpc.Op
}
var file_peersrpc_peers_proto_depIdxs = []int32{
0, // 0: peersrpc.UpdateAddressAction.action:type_name -> peersrpc.UpdateAction
0, // 1: peersrpc.UpdateFeatureAction.action:type_name -> peersrpc.UpdateAction
6, // 2: peersrpc.UpdateFeatureAction.feature_bit:type_name -> lnrpc.FeatureBit
3, // 3: peersrpc.NodeAnnouncementUpdateRequest.feature_updates:type_name -> peersrpc.UpdateFeatureAction
2, // 4: peersrpc.NodeAnnouncementUpdateRequest.address_updates:type_name -> peersrpc.UpdateAddressAction
7, // 5: peersrpc.NodeAnnouncementUpdateResponse.ops:type_name -> lnrpc.Op
4, // 6: peersrpc.Peers.UpdateNodeAnnouncement:input_type -> peersrpc.NodeAnnouncementUpdateRequest
5, // 7: peersrpc.Peers.UpdateNodeAnnouncement:output_type -> peersrpc.NodeAnnouncementUpdateResponse
7, // [7:8] is the sub-list for method output_type
6, // [6:7] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
}
func init() { file_peersrpc_peers_proto_init() }
func file_peersrpc_peers_proto_init() {
if File_peersrpc_peers_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_peersrpc_peers_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateAddressAction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_peersrpc_peers_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateFeatureAction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_peersrpc_peers_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeAnnouncementUpdateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_peersrpc_peers_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeAnnouncementUpdateResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_peersrpc_peers_proto_rawDesc,
NumEnums: 2,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_peersrpc_peers_proto_goTypes,
DependencyIndexes: file_peersrpc_peers_proto_depIdxs,
EnumInfos: file_peersrpc_peers_proto_enumTypes,
MessageInfos: file_peersrpc_peers_proto_msgTypes,
}.Build()
File_peersrpc_peers_proto = out.File
file_peersrpc_peers_proto_rawDesc = nil
file_peersrpc_peers_proto_goTypes = nil
file_peersrpc_peers_proto_depIdxs = nil
}
+167
View File
@@ -0,0 +1,167 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: peersrpc/peers.proto
/*
Package peersrpc is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package peersrpc
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
func request_Peers_UpdateNodeAnnouncement_0(ctx context.Context, marshaler runtime.Marshaler, client PeersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq NodeAnnouncementUpdateRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.UpdateNodeAnnouncement(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Peers_UpdateNodeAnnouncement_0(ctx context.Context, marshaler runtime.Marshaler, server PeersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq NodeAnnouncementUpdateRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.UpdateNodeAnnouncement(ctx, &protoReq)
return msg, metadata, err
}
// RegisterPeersHandlerServer registers the http handlers for service Peers to "mux".
// UnaryRPC :call PeersServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterPeersHandlerFromEndpoint instead.
func RegisterPeersHandlerServer(ctx context.Context, mux *runtime.ServeMux, server PeersServer) error {
mux.Handle("POST", pattern_Peers_UpdateNodeAnnouncement_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/peersrpc.Peers/UpdateNodeAnnouncement", runtime.WithHTTPPathPattern("/v2/peers/nodeannouncement"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Peers_UpdateNodeAnnouncement_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Peers_UpdateNodeAnnouncement_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterPeersHandlerFromEndpoint is same as RegisterPeersHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterPeersHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterPeersHandler(ctx, mux, conn)
}
// RegisterPeersHandler registers the http handlers for service Peers to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterPeersHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterPeersHandlerClient(ctx, mux, NewPeersClient(conn))
}
// RegisterPeersHandlerClient registers the http handlers for service Peers
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "PeersClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "PeersClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "PeersClient" to call the correct interceptors.
func RegisterPeersHandlerClient(ctx context.Context, mux *runtime.ServeMux, client PeersClient) error {
mux.Handle("POST", pattern_Peers_UpdateNodeAnnouncement_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/peersrpc.Peers/UpdateNodeAnnouncement", runtime.WithHTTPPathPattern("/v2/peers/nodeannouncement"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Peers_UpdateNodeAnnouncement_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Peers_UpdateNodeAnnouncement_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Peers_UpdateNodeAnnouncement_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "peers", "nodeannouncement"}, ""))
)
var (
forward_Peers_UpdateNodeAnnouncement_0 = runtime.ForwardResponseMessage
)
+50
View File
@@ -0,0 +1,50 @@
// Code generated by falafel 0.9.1. DO NOT EDIT.
// source: peers.proto
// +build js
package peersrpc
import (
"context"
gateway "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/protobuf/encoding/protojson"
)
func RegisterPeersJSONCallbacks(registry map[string]func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error))) {
marshaler := &gateway.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
},
}
registry["peersrpc.Peers.UpdateNodeAnnouncement"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
req := &NodeAnnouncementUpdateRequest{}
err := marshaler.Unmarshal([]byte(reqJSON), req)
if err != nil {
callback("", err)
return
}
client := NewPeersClient(conn)
resp, err := client.UpdateNodeAnnouncement(ctx, req)
if err != nil {
callback("", err)
return
}
respBytes, err := marshaler.Marshal(resp)
if err != nil {
callback("", err)
return
}
callback(string(respBytes), nil)
}
}
+94
View File
@@ -0,0 +1,94 @@
syntax = "proto3";
import "lightning.proto";
package peersrpc;
option go_package = "github.com/lightningnetwork/lnd/lnrpc/peersrpc";
// Peers is a service that can be used to get information and interact
// with the other nodes of the newtwork.
service Peers {
/* lncli: peers updatenodeannouncement
UpdateNodeAnnouncement allows the caller to update the node parameters
and broadcasts a new version of the node announcement to its peers.
*/
rpc UpdateNodeAnnouncement (NodeAnnouncementUpdateRequest)
returns (NodeAnnouncementUpdateResponse);
}
// UpdateAction is used to determine the kind of action we are referring to.
enum UpdateAction {
// ADD indicates this is an "insertion" kind of action.
ADD = 0;
// REMOVE indicates this is a "deletion" kind of action.
REMOVE = 1;
}
enum FeatureSet {
/*
SET_INIT identifies features that should be sent in an Init message to
a remote peer.
*/
SET_INIT = 0;
/*
SET_LEGACY_GLOBAL identifies features that should be set in the legacy
GlobalFeatures field of an Init message, which maintains backwards
compatibility with nodes that haven't implemented flat features.
*/
SET_LEGACY_GLOBAL = 1;
/*
SET_NODE_ANN identifies features that should be advertised on node
announcements.
*/
SET_NODE_ANN = 2;
/*
SET_INVOICE identifies features that should be advertised on invoices
generated by the daemon.
*/
SET_INVOICE = 3;
/*
SET_INVOICE_AMP identifies the features that should be advertised on
AMP invoices generated by the daemon.
*/
SET_INVOICE_AMP = 4;
}
message UpdateAddressAction {
// Determines the kind of action.
UpdateAction action = 1;
// The address used to apply the update action.
string address = 2;
}
message UpdateFeatureAction {
// Determines the kind of action.
UpdateAction action = 1;
// The feature bit used to apply the update action.
lnrpc.FeatureBit feature_bit = 2;
}
message NodeAnnouncementUpdateRequest {
// Set of changes for the features that the node supports.
repeated UpdateFeatureAction feature_updates = 1;
// Color is the node's color in hex code format.
string color = 2;
// Alias or nick name of the node.
string alias = 3;
// Set of changes for the node's known addresses.
repeated UpdateAddressAction address_updates = 4;
}
message NodeAnnouncementUpdateResponse {
repeated lnrpc.Op ops = 1;
}
+203
View File
@@ -0,0 +1,203 @@
{
"swagger": "2.0",
"info": {
"title": "peersrpc/peers.proto",
"version": "version not set"
},
"tags": [
{
"name": "Peers"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/v2/peers/nodeannouncement": {
"post": {
"summary": "lncli: peers updatenodeannouncement\nUpdateNodeAnnouncement allows the caller to update the node parameters\nand broadcasts a new version of the node announcement to its peers.",
"operationId": "Peers_UpdateNodeAnnouncement",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/peersrpcNodeAnnouncementUpdateResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/peersrpcNodeAnnouncementUpdateRequest"
}
}
],
"tags": [
"Peers"
]
}
}
},
"definitions": {
"lnrpcFeatureBit": {
"type": "string",
"enum": [
"DATALOSS_PROTECT_REQ",
"DATALOSS_PROTECT_OPT",
"INITIAL_ROUING_SYNC",
"UPFRONT_SHUTDOWN_SCRIPT_REQ",
"UPFRONT_SHUTDOWN_SCRIPT_OPT",
"GOSSIP_QUERIES_REQ",
"GOSSIP_QUERIES_OPT",
"TLV_ONION_REQ",
"TLV_ONION_OPT",
"EXT_GOSSIP_QUERIES_REQ",
"EXT_GOSSIP_QUERIES_OPT",
"STATIC_REMOTE_KEY_REQ",
"STATIC_REMOTE_KEY_OPT",
"PAYMENT_ADDR_REQ",
"PAYMENT_ADDR_OPT",
"MPP_REQ",
"MPP_OPT",
"WUMBO_CHANNELS_REQ",
"WUMBO_CHANNELS_OPT",
"ANCHORS_REQ",
"ANCHORS_OPT",
"ANCHORS_ZERO_FEE_HTLC_REQ",
"ANCHORS_ZERO_FEE_HTLC_OPT",
"AMP_REQ",
"AMP_OPT"
],
"default": "DATALOSS_PROTECT_REQ"
},
"lnrpcOp": {
"type": "object",
"properties": {
"entity": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"peersrpcNodeAnnouncementUpdateRequest": {
"type": "object",
"properties": {
"feature_updates": {
"type": "array",
"items": {
"$ref": "#/definitions/peersrpcUpdateFeatureAction"
},
"description": "Set of changes for the features that the node supports."
},
"color": {
"type": "string",
"description": "Color is the node's color in hex code format."
},
"alias": {
"type": "string",
"description": "Alias or nick name of the node."
},
"address_updates": {
"type": "array",
"items": {
"$ref": "#/definitions/peersrpcUpdateAddressAction"
},
"description": "Set of changes for the node's known addresses."
}
}
},
"peersrpcNodeAnnouncementUpdateResponse": {
"type": "object",
"properties": {
"ops": {
"type": "array",
"items": {
"$ref": "#/definitions/lnrpcOp"
}
}
}
},
"peersrpcUpdateAction": {
"type": "string",
"enum": [
"ADD",
"REMOVE"
],
"default": "ADD",
"description": "UpdateAction is used to determine the kind of action we are referring to.\n\n - ADD: ADD indicates this is an \"insertion\" kind of action.\n - REMOVE: REMOVE indicates this is a \"deletion\" kind of action."
},
"peersrpcUpdateAddressAction": {
"type": "object",
"properties": {
"action": {
"$ref": "#/definitions/peersrpcUpdateAction",
"description": "Determines the kind of action."
},
"address": {
"type": "string",
"description": "The address used to apply the update action."
}
}
},
"peersrpcUpdateFeatureAction": {
"type": "object",
"properties": {
"action": {
"$ref": "#/definitions/peersrpcUpdateAction",
"description": "Determines the kind of action."
},
"feature_bit": {
"$ref": "#/definitions/lnrpcFeatureBit",
"description": "The feature bit used to apply the update action."
}
}
},
"protobufAny": {
"type": "object",
"properties": {
"type_url": {
"type": "string"
},
"value": {
"type": "string",
"format": "byte"
}
}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
type: google.api.Service
config_version: 3
http:
rules:
- selector: peersrpc.Peers.UpdateNodeAnnouncement
post: "/v2/peers/nodeannouncement"
body: "*"
+107
View File
@@ -0,0 +1,107 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package peersrpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// PeersClient is the client API for Peers service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type PeersClient interface {
// lncli: peers updatenodeannouncement
//UpdateNodeAnnouncement allows the caller to update the node parameters
//and broadcasts a new version of the node announcement to its peers.
UpdateNodeAnnouncement(ctx context.Context, in *NodeAnnouncementUpdateRequest, opts ...grpc.CallOption) (*NodeAnnouncementUpdateResponse, error)
}
type peersClient struct {
cc grpc.ClientConnInterface
}
func NewPeersClient(cc grpc.ClientConnInterface) PeersClient {
return &peersClient{cc}
}
func (c *peersClient) UpdateNodeAnnouncement(ctx context.Context, in *NodeAnnouncementUpdateRequest, opts ...grpc.CallOption) (*NodeAnnouncementUpdateResponse, error) {
out := new(NodeAnnouncementUpdateResponse)
err := c.cc.Invoke(ctx, "/peersrpc.Peers/UpdateNodeAnnouncement", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// PeersServer is the server API for Peers service.
// All implementations must embed UnimplementedPeersServer
// for forward compatibility
type PeersServer interface {
// lncli: peers updatenodeannouncement
//UpdateNodeAnnouncement allows the caller to update the node parameters
//and broadcasts a new version of the node announcement to its peers.
UpdateNodeAnnouncement(context.Context, *NodeAnnouncementUpdateRequest) (*NodeAnnouncementUpdateResponse, error)
mustEmbedUnimplementedPeersServer()
}
// UnimplementedPeersServer must be embedded to have forward compatible implementations.
type UnimplementedPeersServer struct {
}
func (UnimplementedPeersServer) UpdateNodeAnnouncement(context.Context, *NodeAnnouncementUpdateRequest) (*NodeAnnouncementUpdateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateNodeAnnouncement not implemented")
}
func (UnimplementedPeersServer) mustEmbedUnimplementedPeersServer() {}
// UnsafePeersServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to PeersServer will
// result in compilation errors.
type UnsafePeersServer interface {
mustEmbedUnimplementedPeersServer()
}
func RegisterPeersServer(s grpc.ServiceRegistrar, srv PeersServer) {
s.RegisterService(&Peers_ServiceDesc, srv)
}
func _Peers_UpdateNodeAnnouncement_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NodeAnnouncementUpdateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PeersServer).UpdateNodeAnnouncement(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/peersrpc.Peers/UpdateNodeAnnouncement",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PeersServer).UpdateNodeAnnouncement(ctx, req.(*NodeAnnouncementUpdateRequest))
}
return interceptor(ctx, in, info, handler)
}
// Peers_ServiceDesc is the grpc.ServiceDesc for Peers service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Peers_ServiceDesc = grpc.ServiceDesc{
ServiceName: "peersrpc.Peers",
HandlerType: (*PeersServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "UpdateNodeAnnouncement",
Handler: _Peers_UpdateNodeAnnouncement_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "peersrpc/peers.proto",
}
+403
View File
@@ -0,0 +1,403 @@
//go:build peersrpc
// +build peersrpc
package peersrpc
import (
"context"
"fmt"
"net"
"sync/atomic"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
"google.golang.org/grpc"
"gopkg.in/macaroon-bakery.v2/bakery"
)
const (
// subServerName is the name of the sub rpc server. We'll use this name
// to register ourselves, and we also require that the main
// SubServerConfigDispatcher instance recognize tt as the name of our
// RPC service.
subServerName = "PeersRPC"
)
var (
// macPermissions maps RPC calls to the permissions they require.
macPermissions = map[string][]bakery.Op{
"/peersrpc.Peers/UpdateNodeAnnouncement": {{
Entity: "peers",
Action: "write",
}},
}
)
// ServerShell is a shell struct holding a reference to the actual sub-server.
// It is used to register the gRPC sub-server with the root server before we
// have the necessary dependencies to populate the actual sub-server.
type ServerShell struct {
PeersServer
}
// Server is a sub-server of the main RPC server: the peers RPC. This sub
// RPC server allows to intereact with our Peers in the Lightning Network.
type Server struct {
started int32 // To be used atomically.
shutdown int32 // To be used atomically.
// Required by the grpc-gateway/v2 library for forward compatibility.
// Must be after the atomically used variables to not break struct
// alignment.
UnimplementedPeersServer
cfg *Config
}
// A compile time check to ensure that Server fully implements the PeersServer
// gRPC service.
var _ PeersServer = (*Server)(nil)
// New returns a new instance of the peersrpc Peers sub-server. We also
// return the set of permissions for the macaroons that we may create within
// this method. If the macaroons we need aren't found in the filepath, then
// we'll create them on start up. If we're unable to locate, or create the
// macaroons we need, then we'll return with an error.
func New(cfg *Config) (*Server, lnrpc.MacaroonPerms, error) {
server := &Server{
cfg: cfg,
}
return server, macPermissions, nil
}
// Start launches any helper goroutines required for the Server to function.
//
// NOTE: This is part of the lnrpc.SubServer interface.
func (s *Server) Start() error {
if atomic.AddInt32(&s.started, 1) != 1 {
return nil
}
return nil
}
// Stop signals any active goroutines for a graceful closure.
//
// NOTE: This is part of the lnrpc.SubServer interface.
func (s *Server) Stop() error {
if atomic.AddInt32(&s.shutdown, 1) != 1 {
return nil
}
return nil
}
// Name returns a unique string representation of the sub-server. This can be
// used to identify the sub-server and also de-duplicate them.
//
// NOTE: This is part of the lnrpc.SubServer interface.
func (s *Server) Name() string {
return subServerName
}
// RegisterWithRootServer will be called by the root gRPC server to direct a
// sub RPC server to register itself with the main gRPC root server. Until this
// is called, each sub-server won't be able to have
// requests routed towards it.
//
// NOTE: This is part of the lnrpc.GrpcHandler interface.
func (r *ServerShell) RegisterWithRootServer(grpcServer *grpc.Server) error {
// We make sure that we register it with the main gRPC server to ensure
// all our methods are routed properly.
RegisterPeersServer(grpcServer, r)
log.Debugf("Peers RPC server successfully register with root " +
"gRPC server")
return nil
}
// RegisterWithRestServer will be called by the root REST mux to direct a sub
// RPC server to register itself with the main REST mux server. Until this is
// called, each sub-server won't be able to have requests routed towards it.
//
// NOTE: This is part of the lnrpc.GrpcHandler interface.
func (r *ServerShell) RegisterWithRestServer(ctx context.Context,
mux *runtime.ServeMux, dest string, opts []grpc.DialOption) error {
// We make sure that we register it with the main REST server to ensure
// all our methods are routed properly.
err := RegisterPeersHandlerFromEndpoint(ctx, mux, dest, opts)
if err != nil {
log.Errorf("Could not register Peers REST server "+
"with root REST server: %v", err)
return err
}
log.Debugf("Peers REST server successfully registered with " +
"root REST server")
return nil
}
// CreateSubServer populates the subserver's dependencies using the passed
// SubServerConfigDispatcher. This method should fully initialize the
// sub-server instance, making it ready for action. It returns the macaroon
// permissions that the sub-server wishes to pass on to the root server for all
// methods routed towards it.
//
// NOTE: This is part of the lnrpc.GrpcHandler interface.
func (r *ServerShell) CreateSubServer(configRegistry lnrpc.SubServerConfigDispatcher) (
lnrpc.SubServer, lnrpc.MacaroonPerms, error) {
subServer, macPermissions, err := createNewSubServer(configRegistry)
if err != nil {
return nil, nil, err
}
r.PeersServer = subServer
return subServer, macPermissions, nil
}
// updateAddresses computes the new address set after executing the update
// actions.
func (s *Server) updateAddresses(currentAddresses []net.Addr,
updates []*UpdateAddressAction) ([]net.Addr, *lnrpc.Op, error) {
// net.Addr is not comparable so we cannot use the default map
// (map[net.Addr]struct{}) so we have to use arrays and a helping
// function.
findAddr := func(addr net.Addr, slice []net.Addr) bool {
for _, sAddr := range slice {
if sAddr.Network() != addr.Network() {
continue
}
if sAddr.String() == addr.String() {
return true
}
}
return false
}
// Preallocate enough memory for both arrays.
removeAddr := make([]net.Addr, 0, len(updates))
addAddr := make([]net.Addr, 0, len(updates))
for _, update := range updates {
addr, err := s.cfg.ParseAddr(update.Address)
if err != nil {
return nil, nil, fmt.Errorf("unable to resolve "+
"address %v: %v", update.Address, err)
}
switch update.Action {
case UpdateAction_ADD:
addAddr = append(addAddr, addr)
case UpdateAction_REMOVE:
removeAddr = append(removeAddr, addr)
default:
return nil, nil, fmt.Errorf("invalid address update "+
"action: %v", update.Action)
}
}
// Look for any inconsistency trying to add AND remove the same address.
for _, addr := range removeAddr {
if findAddr(addr, addAddr) {
return nil, nil, fmt.Errorf("invalid updates for "+
"removing AND adding %v", addr)
}
}
ops := &lnrpc.Op{Entity: "addresses"}
newAddrs := make([]net.Addr, 0, len(updates)+len(currentAddresses))
// Copy current addresses excluding the ones that need to be removed.
for _, addr := range currentAddresses {
if findAddr(addr, removeAddr) {
ops.Actions = append(
ops.Actions,
fmt.Sprintf("%s removed", addr.String()),
)
continue
}
newAddrs = append(newAddrs, addr)
}
// Add new adresses if needed.
for _, addr := range addAddr {
if !findAddr(addr, newAddrs) {
ops.Actions = append(
ops.Actions,
fmt.Sprintf("%s added", addr.String()),
)
newAddrs = append(newAddrs, addr)
}
}
return newAddrs, ops, nil
}
// updateFeatures computes the new raw SetNodeAnn after executing the update
// actions.
func (s *Server) updateFeatures(currentfeatures *lnwire.RawFeatureVector,
updates []*UpdateFeatureAction) (*lnwire.RawFeatureVector,
*lnrpc.Op, error) {
ops := &lnrpc.Op{Entity: "features"}
raw := currentfeatures.Clone()
for _, update := range updates {
bit := lnwire.FeatureBit(update.FeatureBit)
switch update.Action {
case UpdateAction_ADD:
if raw.IsSet(bit) {
return nil, nil, fmt.Errorf(
"invalid add action for bit %v, "+
"bit is already set",
update.FeatureBit,
)
}
raw.Set(bit)
ops.Actions = append(
ops.Actions,
fmt.Sprintf("%s set", lnwire.Features[bit]),
)
case UpdateAction_REMOVE:
if !raw.IsSet(bit) {
return nil, nil, fmt.Errorf(
"invalid remove action for bit %v, "+
"bit is already unset",
update.FeatureBit,
)
}
raw.Unset(bit)
ops.Actions = append(
ops.Actions,
fmt.Sprintf("%s unset", lnwire.Features[bit]),
)
default:
return nil, nil, fmt.Errorf(
"invalid update action (%v) for bit %v",
update.Action,
update.FeatureBit,
)
}
}
// Validate our new SetNodeAnn.
fv := lnwire.NewFeatureVector(raw, lnwire.Features)
if err := feature.ValidateDeps(fv); err != nil {
return nil, nil, fmt.Errorf(
"invalid feature set (SetNodeAnn): %v",
err,
)
}
return raw, ops, nil
}
// UpdateNodeAnnouncement allows the caller to update the node parameters
// and broadcasts a new version of the node announcement to its peers.
func (s *Server) UpdateNodeAnnouncement(_ context.Context,
req *NodeAnnouncementUpdateRequest) (
*NodeAnnouncementUpdateResponse, error) {
resp := &NodeAnnouncementUpdateResponse{}
nodeModifiers := make([]netann.NodeAnnModifier, 0)
currentNodeAnn, err := s.cfg.GetNodeAnnouncement()
if err != nil {
return nil, fmt.Errorf("unable to get current node "+
"announcement: %v", err)
}
if len(req.FeatureUpdates) > 0 {
features, ops, err := s.updateFeatures(
currentNodeAnn.Features,
req.FeatureUpdates,
)
if err != nil {
return nil, fmt.Errorf("error trying to update node "+
"features: %w", err)
}
resp.Ops = append(resp.Ops, ops)
nodeModifiers = append(
nodeModifiers,
netann.NodeAnnSetFeatures(features),
)
}
if req.Color != "" {
color, err := lncfg.ParseHexColor(req.Color)
if err != nil {
return nil, fmt.Errorf("unable to parse color: %v", err)
}
if color != currentNodeAnn.RGBColor {
resp.Ops = append(resp.Ops, &lnrpc.Op{
Entity: "color",
Actions: []string{
fmt.Sprintf("changed to %v", color),
},
})
nodeModifiers = append(
nodeModifiers,
netann.NodeAnnSetColor(color),
)
}
}
if req.Alias != "" {
alias, err := lnwire.NewNodeAlias(req.Alias)
if err != nil {
return nil, fmt.Errorf("invalid alias value: %v", err)
}
if alias != currentNodeAnn.Alias {
resp.Ops = append(resp.Ops, &lnrpc.Op{
Entity: "alias",
Actions: []string{
fmt.Sprintf("changed to %v", alias),
},
})
nodeModifiers = append(
nodeModifiers,
netann.NodeAnnSetAlias(alias),
)
}
}
if len(req.AddressUpdates) > 0 {
newAddrs, ops, err := s.updateAddresses(
currentNodeAnn.Addresses,
req.AddressUpdates,
)
if err != nil {
return nil, fmt.Errorf("error trying to update node "+
"addresses: %w", err)
}
resp.Ops = append(resp.Ops, ops)
nodeModifiers = append(
nodeModifiers,
netann.NodeAnnSetAddrs(newAddrs),
)
}
if len(nodeModifiers) == 0 {
return nil, fmt.Errorf("unable detect any new values to " +
"update the node announcement")
}
if err := s.cfg.UpdateNodeAnnouncement(nodeModifiers...); err != nil {
return nil, err
}
return resp, nil
}
+1 -17
View File
@@ -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
@@ -30,19 +30,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)
}
+1 -17
View File
@@ -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
@@ -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)
}
+1 -1
View File
@@ -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
+2 -18
View File
@@ -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
@@ -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)
}
-16
View File
@@ -29,19 +29,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)
}