Merge pull request #7153 from carlaKC/7093-custommessage
multi: Add ability to handle protocol-range messages in Custom Message APIs
This commit is contained in:
12 files changed
+311
-7
No files matched your search
@@ -39,6 +39,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/routing"
|
"github.com/lightningnetwork/lnd/routing"
|
||||||
"github.com/lightningnetwork/lnd/signal"
|
"github.com/lightningnetwork/lnd/signal"
|
||||||
"github.com/lightningnetwork/lnd/sweep"
|
"github.com/lightningnetwork/lnd/sweep"
|
||||||
@@ -1656,6 +1657,17 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
|
|||||||
lncfg.DefaultIncomingBroadcastDelta)
|
lncfg.DefaultIncomingBroadcastDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the experimental protocol options specify any protocol messages
|
||||||
|
// that we want to handle as custom messages, set them now.
|
||||||
|
//nolint:lll
|
||||||
|
customMsg := cfg.ProtocolOptions.ExperimentalProtocol.CustomMessageOverrides()
|
||||||
|
|
||||||
|
// We can safely set our custom override values during startup because
|
||||||
|
// startup is blocked on config parsing.
|
||||||
|
if err := lnwire.SetCustomOverrides(customMsg); err != nil {
|
||||||
|
return nil, mkErr("custom-message: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Validate the subconfigs for workers, caches, and the tower client.
|
// Validate the subconfigs for workers, caches, and the tower client.
|
||||||
err = lncfg.Validate(
|
err = lncfg.Validate(
|
||||||
cfg.Workers,
|
cfg.Workers,
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ current gossip sync query status.
|
|||||||
* [Ensure that closing addresses match the node network for `OpenChannel`
|
* [Ensure that closing addresses match the node network for `OpenChannel`
|
||||||
requests](https://github.com/lightningnetwork/lnd/pull/7272)
|
requests](https://github.com/lightningnetwork/lnd/pull/7272)
|
||||||
|
|
||||||
|
* The `SendCustomMessage` and `SubscribeCustomMessage` APIs can now be used to
|
||||||
|
send and receive custom messages below the custom range if lnd is built with
|
||||||
|
the `dev` tag, and configured to [opt into overriding a specific message
|
||||||
|
type](https://github.com/lightningnetwork/lnd/pull/7153)
|
||||||
|
|
||||||
## Wallet
|
## Wallet
|
||||||
|
|
||||||
* [Allows Taproot public keys and tap scripts to be imported as watch-only
|
* [Allows Taproot public keys and tap scripts to be imported as watch-only
|
||||||
|
|||||||
@@ -7,3 +7,9 @@ package lncfg
|
|||||||
// features that also require a build-tag to activate.
|
// features that also require a build-tag to activate.
|
||||||
type ExperimentalProtocol struct {
|
type ExperimentalProtocol struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CustomMessageOverrides returns the set of protocol messages that we override
|
||||||
|
// to allow custom handling.
|
||||||
|
func (p ExperimentalProtocol) CustomMessageOverrides() []uint16 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -5,5 +5,14 @@ package lncfg
|
|||||||
|
|
||||||
// ExperimentalProtocol is a sub-config that houses any experimental protocol
|
// ExperimentalProtocol is a sub-config that houses any experimental protocol
|
||||||
// features that also require a build-tag to activate.
|
// features that also require a build-tag to activate.
|
||||||
|
//
|
||||||
|
//nolint:lll
|
||||||
type ExperimentalProtocol struct {
|
type ExperimentalProtocol struct {
|
||||||
|
CustomMessage []uint16 `long:"custom-message" description:"allows the custom message apis to send and report messages with the protocol number provided that fall outside of the custom message number range."`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomMessageOverrides returns the set of protocol messages that we override
|
||||||
|
// to allow custom handling.
|
||||||
|
func (p ExperimentalProtocol) CustomMessageOverrides() []uint16 {
|
||||||
|
return p.CustomMessage
|
||||||
}
|
}
|
||||||
@@ -1517,6 +1517,9 @@ type SendCustomMessageRequest struct {
|
|||||||
// Peer to send the message to
|
// Peer to send the message to
|
||||||
Peer []byte `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"`
|
Peer []byte `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"`
|
||||||
// Message type. This value needs to be in the custom range (>= 32768).
|
// Message type. This value needs to be in the custom range (>= 32768).
|
||||||
|
// To send a type < custom range, lnd needs to be compiled with the `dev`
|
||||||
|
// build tag, and the message type to override should be specified in lnd's
|
||||||
|
// experimental protocol configuration.
|
||||||
Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
|
Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
// Raw message data.
|
// Raw message data.
|
||||||
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
|
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
|
||||||
|
|||||||
@@ -567,6 +567,10 @@ service Lightning {
|
|||||||
/* lncli: `subscribecustom`
|
/* lncli: `subscribecustom`
|
||||||
SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
||||||
messages.
|
messages.
|
||||||
|
|
||||||
|
To include messages with type outside of the custom range (>= 32768) lnd
|
||||||
|
needs to be compiled with the `dev` build tag, and the message type to
|
||||||
|
override should be specified in lnd's experimental protocol configuration.
|
||||||
*/
|
*/
|
||||||
rpc SubscribeCustomMessages (SubscribeCustomMessagesRequest)
|
rpc SubscribeCustomMessages (SubscribeCustomMessagesRequest)
|
||||||
returns (stream CustomMessage);
|
returns (stream CustomMessage);
|
||||||
@@ -612,6 +616,9 @@ message SendCustomMessageRequest {
|
|||||||
bytes peer = 1;
|
bytes peer = 1;
|
||||||
|
|
||||||
// Message type. This value needs to be in the custom range (>= 32768).
|
// Message type. This value needs to be in the custom range (>= 32768).
|
||||||
|
// To send a type < custom range, lnd needs to be compiled with the `dev`
|
||||||
|
// build tag, and the message type to override should be specified in lnd's
|
||||||
|
// experimental protocol configuration.
|
||||||
uint32 type = 2;
|
uint32 type = 2;
|
||||||
|
|
||||||
// Raw message data.
|
// Raw message data.
|
||||||
|
|||||||
@@ -918,6 +918,7 @@
|
|||||||
"/v1/custommessage/subscribe": {
|
"/v1/custommessage/subscribe": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "lncli: `subscribecustom`\nSubscribeCustomMessages subscribes to a stream of incoming custom peer\nmessages.",
|
"summary": "lncli: `subscribecustom`\nSubscribeCustomMessages subscribes to a stream of incoming custom peer\nmessages.",
|
||||||
|
"description": "To include messages with type outside of the custom range (\u003e= 32768) lnd\nneeds to be compiled with the `dev` build tag, and the message type to\noverride should be specified in lnd's experimental protocol configuration.",
|
||||||
"operationId": "Lightning_SubscribeCustomMessages",
|
"operationId": "Lightning_SubscribeCustomMessages",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@@ -6616,7 +6617,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"description": "Message type. This value needs to be in the custom range (\u003e= 32768)."
|
"description": "Message type. This value needs to be in the custom range (\u003e= 32768).\nTo send a type \u003c custom range, lnd needs to be compiled with the `dev`\nbuild tag, and the message type to override should be specified in lnd's\nexperimental protocol configuration."
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -392,6 +392,10 @@ type LightningClient interface {
|
|||||||
// lncli: `subscribecustom`
|
// lncli: `subscribecustom`
|
||||||
// SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
// SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
||||||
// messages.
|
// messages.
|
||||||
|
//
|
||||||
|
// To include messages with type outside of the custom range (>= 32768) lnd
|
||||||
|
// needs to be compiled with the `dev` build tag, and the message type to
|
||||||
|
// override should be specified in lnd's experimental protocol configuration.
|
||||||
SubscribeCustomMessages(ctx context.Context, in *SubscribeCustomMessagesRequest, opts ...grpc.CallOption) (Lightning_SubscribeCustomMessagesClient, error)
|
SubscribeCustomMessages(ctx context.Context, in *SubscribeCustomMessagesRequest, opts ...grpc.CallOption) (Lightning_SubscribeCustomMessagesClient, error)
|
||||||
// lncli: `listaliases`
|
// lncli: `listaliases`
|
||||||
// ListAliases returns the set of all aliases that have ever existed with
|
// ListAliases returns the set of all aliases that have ever existed with
|
||||||
@@ -1687,6 +1691,10 @@ type LightningServer interface {
|
|||||||
// lncli: `subscribecustom`
|
// lncli: `subscribecustom`
|
||||||
// SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
// SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
||||||
// messages.
|
// messages.
|
||||||
|
//
|
||||||
|
// To include messages with type outside of the custom range (>= 32768) lnd
|
||||||
|
// needs to be compiled with the `dev` build tag, and the message type to
|
||||||
|
// override should be specified in lnd's experimental protocol configuration.
|
||||||
SubscribeCustomMessages(*SubscribeCustomMessagesRequest, Lightning_SubscribeCustomMessagesServer) error
|
SubscribeCustomMessages(*SubscribeCustomMessagesRequest, Lightning_SubscribeCustomMessagesServer) error
|
||||||
// lncli: `listaliases`
|
// lncli: `listaliases`
|
||||||
// ListAliases returns the set of all aliases that have ever existed with
|
// ListAliases returns the set of all aliases that have ever existed with
|
||||||
|
|||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package itest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lntest"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// testCustomMessage tests sending and receiving of overridden custom message
|
||||||
|
// types (within the message type range usually reserved for protocol messages)
|
||||||
|
// via the send and subscribe custom message APIs.
|
||||||
|
func testCustomMessage(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
// At the end of our test, cancel our context and wait for all
|
||||||
|
// goroutines to exit.
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
wg.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
|
var (
|
||||||
|
overrideType1 uint32 = 554
|
||||||
|
overrideType2 uint32 = 555
|
||||||
|
msgOverrideArg = "--protocol.custom-message=%v"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update Alice to accept custom protocol messages with type 1 but do
|
||||||
|
// not allow Bob to handle them yet.
|
||||||
|
net.Alice.Cfg.ExtraArgs = append(
|
||||||
|
net.Alice.Cfg.ExtraArgs,
|
||||||
|
fmt.Sprintf(msgOverrideArg, overrideType1),
|
||||||
|
)
|
||||||
|
require.NoError(t.t, net.RestartNode(net.Alice, nil, nil))
|
||||||
|
|
||||||
|
// Wait for Alice's server to be active after the restart before we
|
||||||
|
// try to subscribe to our message stream.
|
||||||
|
require.NoError(t.t, net.Alice.WaitUntilServerActive())
|
||||||
|
|
||||||
|
// Subscribe Alice to custom messages before we send any, so that we
|
||||||
|
// don't miss any.
|
||||||
|
msgClient, err := net.Alice.LightningClient.SubscribeCustomMessages(
|
||||||
|
ctx, &lnrpc.SubscribeCustomMessagesRequest{},
|
||||||
|
)
|
||||||
|
require.NoError(t.t, err, "alice could not subscribe")
|
||||||
|
|
||||||
|
// Create a channel to receive custom messages on.
|
||||||
|
messages := make(chan *lnrpc.CustomMessage)
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
for {
|
||||||
|
// If we fail to receive, just exit. The test should
|
||||||
|
// fail elsewhere if it doesn't get a message that it
|
||||||
|
// was expecting.
|
||||||
|
msg, err := msgClient.Recv()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deliver the message into our channel or exit if the
|
||||||
|
// test is shutting down.
|
||||||
|
select {
|
||||||
|
case messages <- msg:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Connect alice and bob so that they can exchange messages.
|
||||||
|
net.EnsureConnected(t.t, net.Alice, net.Bob)
|
||||||
|
|
||||||
|
// Create a custom message that is within our allowed range.
|
||||||
|
msgType := uint32(lnwire.CustomTypeStart + 1)
|
||||||
|
msgData := []byte{1, 2, 3}
|
||||||
|
|
||||||
|
// Send it from Bob to Alice.
|
||||||
|
ctxt, _ := context.WithTimeout(ctx, defaultTimeout)
|
||||||
|
_, err = net.Bob.LightningClient.SendCustomMessage(
|
||||||
|
ctxt, &lnrpc.SendCustomMessageRequest{
|
||||||
|
Peer: net.Alice.PubKey[:],
|
||||||
|
Type: msgType,
|
||||||
|
Data: msgData,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t.t, err, "bob could not send")
|
||||||
|
|
||||||
|
// Wait for Alice to receive the message. It should come through because
|
||||||
|
// it is within our allowed range.
|
||||||
|
select {
|
||||||
|
case msg := <-messages:
|
||||||
|
// Check our type and data and (sanity) check the peer we got it
|
||||||
|
// from.
|
||||||
|
require.Equal(t.t, msgType, msg.Type, "first msg type wrong")
|
||||||
|
require.Equal(t.t, msgData, msg.Data, "first msg data wrong")
|
||||||
|
require.Equal(t.t, net.Bob.PubKey[:], msg.Peer, "first msg "+
|
||||||
|
"peer wrong")
|
||||||
|
|
||||||
|
case <-time.After(defaultTimeout):
|
||||||
|
t.t.Fatalf("alice did not receive first custom message: %v",
|
||||||
|
msgType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to send a message from Bob to Alice which has a message type
|
||||||
|
// outside of the custom type range and assert that it fails.
|
||||||
|
ctxt, _ = context.WithTimeout(ctx, defaultTimeout)
|
||||||
|
_, err = net.Bob.LightningClient.SendCustomMessage(
|
||||||
|
ctxt, &lnrpc.SendCustomMessageRequest{
|
||||||
|
Peer: net.Alice.PubKey[:],
|
||||||
|
Type: overrideType1,
|
||||||
|
Data: msgData,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.Error(t.t, err, "bob should not be able to send type 1")
|
||||||
|
|
||||||
|
// Now, restart Bob with the ability to send two different custom
|
||||||
|
// protocol messages.
|
||||||
|
net.Bob.Cfg.ExtraArgs = append(
|
||||||
|
net.Bob.Cfg.ExtraArgs,
|
||||||
|
fmt.Sprintf(msgOverrideArg, overrideType1),
|
||||||
|
fmt.Sprintf(msgOverrideArg, overrideType2),
|
||||||
|
)
|
||||||
|
require.NoError(t.t, net.RestartNode(net.Bob, nil, nil))
|
||||||
|
|
||||||
|
// Make sure Bob and Alice are connected after his restart.
|
||||||
|
net.EnsureConnected(t.t, net.Alice, net.Bob)
|
||||||
|
|
||||||
|
// Send a message from Bob to Alice with a type that Bob is allowed to
|
||||||
|
// send, but Alice will not handle as a custom message.
|
||||||
|
ctxt, _ = context.WithTimeout(ctx, defaultTimeout)
|
||||||
|
_, err = net.Bob.LightningClient.SendCustomMessage(
|
||||||
|
ctxt, &lnrpc.SendCustomMessageRequest{
|
||||||
|
Peer: net.Alice.PubKey[:],
|
||||||
|
Type: overrideType2,
|
||||||
|
Data: msgData,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t.t, err, "bob should be able to send type 2")
|
||||||
|
|
||||||
|
// Do a quick check that Alice did not receive this message in her
|
||||||
|
// stream. Note that this is an instant check, so could miss the message
|
||||||
|
// being received. We'll also check below that she didn't get it, this
|
||||||
|
// is just a sanity check.
|
||||||
|
select {
|
||||||
|
case msg := <-messages:
|
||||||
|
t.t.Fatalf("unexpected message: %v", msg)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, send a custom message with a type that Bob is allowed to
|
||||||
|
// send and Alice is configured to receive.
|
||||||
|
ctxt, _ = context.WithTimeout(ctx, defaultTimeout)
|
||||||
|
_, err = net.Bob.LightningClient.SendCustomMessage(
|
||||||
|
ctxt, &lnrpc.SendCustomMessageRequest{
|
||||||
|
Peer: net.Alice.PubKey[:],
|
||||||
|
Type: overrideType1,
|
||||||
|
Data: msgData,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t.t, err, "bob should be able to send type 1")
|
||||||
|
|
||||||
|
// Wait to receive a message from Bob. This check serves to ensure that
|
||||||
|
// our message type 1 was delivered, and assert that the preceding one
|
||||||
|
// was not (we could have missed it in our check above). When we receive
|
||||||
|
// the second message, we know that the first one did not go through,
|
||||||
|
// because we expect our messages to deliver in order.
|
||||||
|
select {
|
||||||
|
case msg := <-messages:
|
||||||
|
// Check our type and data and (sanity) check the peer we got it
|
||||||
|
// from.
|
||||||
|
require.Equal(t.t, overrideType1, msg.Type, "second message "+
|
||||||
|
"type")
|
||||||
|
require.Equal(t.t, msgData, msg.Data, "second message data")
|
||||||
|
require.Equal(t.t, net.Bob.PubKey[:], msg.Peer, "second "+
|
||||||
|
"message peer")
|
||||||
|
|
||||||
|
case <-time.After(defaultTimeout):
|
||||||
|
t.t.Fatalf("alice did not receive second custom message")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -274,4 +274,8 @@ var allTestCases = []*testCase{
|
|||||||
name: "open channel fee policy",
|
name: "open channel fee policy",
|
||||||
test: testOpenChannelUpdateFeePolicy,
|
test: testOpenChannelUpdateFeePolicy,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "custom messaging",
|
||||||
|
test: testCustomMessage,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
+59
-5
@@ -2,13 +2,66 @@ package lnwire
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CustomTypeStart is the start of the custom type range for peer messages as
|
// CustomTypeStart is the start of the custom type range for peer messages as
|
||||||
// defined in BOLT 01.
|
// defined in BOLT 01.
|
||||||
var CustomTypeStart MessageType = 32768
|
const CustomTypeStart MessageType = 32768
|
||||||
|
|
||||||
|
var (
|
||||||
|
// customTypeOverride contains a set of message types < CustomTypeStart
|
||||||
|
// that lnd allows to be treated as custom messages. This allows us to
|
||||||
|
// override messages reserved for the protocol level and treat them as
|
||||||
|
// custom messages. This set of message types is stored as a global so
|
||||||
|
// that we do not need to pass around state when accounting for this
|
||||||
|
// set of messages in message creation.
|
||||||
|
//
|
||||||
|
// Note: This global is protected by the customTypeOverride mutex.
|
||||||
|
customTypeOverride map[MessageType]struct{}
|
||||||
|
|
||||||
|
// customTypeOverrideMtx manages concurrent access to
|
||||||
|
// customTypeOverride.
|
||||||
|
customTypeOverrideMtx sync.RWMutex
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetCustomOverrides validates that the set of override types are outside of
|
||||||
|
// the custom message range (there's no reason to override messages that are
|
||||||
|
// already within the range), and updates the customTypeOverride global to hold
|
||||||
|
// this set of message types. Note that this function will completely overwrite
|
||||||
|
// the set of overrides, so should be called with the full set of types.
|
||||||
|
func SetCustomOverrides(overrideTypes []uint16) error {
|
||||||
|
customTypeOverrideMtx.Lock()
|
||||||
|
defer customTypeOverrideMtx.Unlock()
|
||||||
|
|
||||||
|
customTypeOverride = make(map[MessageType]struct{}, len(overrideTypes))
|
||||||
|
|
||||||
|
for _, t := range overrideTypes {
|
||||||
|
msgType := MessageType(t)
|
||||||
|
|
||||||
|
if msgType >= CustomTypeStart {
|
||||||
|
return fmt.Errorf("can't override type: %v, already "+
|
||||||
|
"in custom range", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
customTypeOverride[msgType] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCustomOverride returns a bool indicating whether the message type is one
|
||||||
|
// of the protocol messages that we override for custom use.
|
||||||
|
func IsCustomOverride(t MessageType) bool {
|
||||||
|
customTypeOverrideMtx.RLock()
|
||||||
|
defer customTypeOverrideMtx.RUnlock()
|
||||||
|
|
||||||
|
_, ok := customTypeOverride[t]
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
// Custom represents an application-defined wire message.
|
// Custom represents an application-defined wire message.
|
||||||
type Custom struct {
|
type Custom struct {
|
||||||
@@ -20,10 +73,11 @@ type Custom struct {
|
|||||||
// interface.
|
// interface.
|
||||||
var _ Message = (*Custom)(nil)
|
var _ Message = (*Custom)(nil)
|
||||||
|
|
||||||
// NewCustom instanties a new custom message.
|
// NewCustom instantiates a new custom message.
|
||||||
func NewCustom(msgType MessageType, data []byte) (*Custom, error) {
|
func NewCustom(msgType MessageType, data []byte) (*Custom, error) {
|
||||||
if msgType < CustomTypeStart {
|
if msgType < CustomTypeStart && !IsCustomOverride(msgType) {
|
||||||
return nil, errors.New("msg type not in custom range")
|
return nil, fmt.Errorf("msg type: %d not in custom range: %v "+
|
||||||
|
"and not overridden", msgType, CustomTypeStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Custom{
|
return &Custom{
|
||||||
|
|||||||
+8
-1
@@ -237,9 +237,16 @@ func makeEmptyMessage(msgType MessageType) (Message, error) {
|
|||||||
case MsgGossipTimestampRange:
|
case MsgGossipTimestampRange:
|
||||||
msg = &GossipTimestampRange{}
|
msg = &GossipTimestampRange{}
|
||||||
default:
|
default:
|
||||||
if msgType < CustomTypeStart {
|
// If the message is not within our custom range and has not
|
||||||
|
// specifically been overridden, return an unknown message.
|
||||||
|
//
|
||||||
|
// Note that we do not allow custom message overrides to replace
|
||||||
|
// known message types, only protocol messages that are not yet
|
||||||
|
// known to lnd.
|
||||||
|
if msgType < CustomTypeStart && !IsCustomOverride(msgType) {
|
||||||
return nil, &UnknownMessage{msgType}
|
return nil, &UnknownMessage{msgType}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = &Custom{
|
msg = &Custom{
|
||||||
Type: msgType,
|
Type: msgType,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user