mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
Add a new protocol option, protocol.onion-msg-relay-all, that controls
whether incoming onion messages are required to come from peers with a
fully open channel. The default is false, which preserves the existing
behavior: the channel-presence gate drops messages from peers with no
channel before the rate limiters are consulted, so a new no-cost
identity cannot burn any per-peer byte budget and saturate the global
bucket. Setting the flag to true skips the gate so that onion messages
from any peer are admitted into the per-peer + global IngressLimiter
pipeline.
The flag is plumbed through ProtocolOptions in both the default and
integration build variants of lncfg/protocol*.go, threaded into the
peer subsystem as peer.Config.OnionRelayAll, and wired by the server
from s.cfg.ProtocolOptions.OnionMsgRelayAll alongside the existing
OnionLimiter field. allowOnionMessage gains a relayAll bool parameter;
the gate check becomes "if \!relayAll && \!hasChannel { drop }" so the
semantics of hasChannel stay pure — it still means "this peer has a
channel" — and the policy toggle lives entirely in the caller's
configuration rather than being spread across gate-state and flag
state.
sample-lnd.conf gains a commented-out entry for the new option with
the default value and an operator-facing note that enabling it trades
the Sybil-resistance property of the gate for reachability to peers
with whom we have no channel.
A new TestAllowOnionMessageRelayAll unit test exercises the four
(hasChannel, relayAll) combinations at the helper level, including
the key new behavior — a peer with hasChannel=false being rejected
under relayAll=false and admitted into the limiter under
relayAll=true — and the nil-limiter path under relayAll=true, which
must still accept. The existing allowOnionMessage tests were
extended with the new parameter set to false so they continue to
assert the gate semantics unchanged.
225 lines
11 KiB
Go
225 lines
11 KiB
Go
//go:build !integration
|
|
|
|
package lncfg
|
|
|
|
import (
|
|
"github.com/lightningnetwork/lnd/feature"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
// ProtocolOptions is a struct that we use to be able to test backwards
|
|
// compatibility of protocol additions, while defaulting to the latest within
|
|
// lnd, or to enable experimental protocol changes.
|
|
//
|
|
//nolint:ll
|
|
type ProtocolOptions struct {
|
|
// LegacyProtocol is a sub-config that houses all the legacy protocol
|
|
// options. These are mostly used for integration tests as most modern
|
|
// nodes should always run with them on by default.
|
|
LegacyProtocol `group:"legacy" namespace:"legacy"`
|
|
|
|
// ExperimentalProtocol is a sub-config that houses any experimental
|
|
// protocol features that also require a build-tag to activate.
|
|
ExperimentalProtocol
|
|
|
|
// WumboChans should be set if we want to enable support for wumbo
|
|
// (channels larger than 0.16 BTC) channels, which is the opposite of
|
|
// mini.
|
|
WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"`
|
|
|
|
// TaprootChans should be set if we want to enable support for the
|
|
// experimental simple taproot chans commitment type.
|
|
TaprootChans bool `long:"simple-taproot-chans" description:"if set, then lnd will create and accept requests for channels using the simple taproot commitment type"`
|
|
|
|
// TaprootOverlayChans should be set if we want to enable support for
|
|
// the experimental taproot overlay chan type.
|
|
TaprootOverlayChans bool `long:"simple-taproot-overlay-chans" description:"if set, then lnd will create and accept requests for channels using the taproot overlay commitment type"`
|
|
|
|
// RbfCoopClose should be set if we want to signal that we support for
|
|
// the new experimental RBF coop close feature.
|
|
RbfCoopClose bool `long:"rbf-coop-close" description:"if set, then lnd will signal that it supports the new RBF based coop close protocol"`
|
|
|
|
// NoAnchors should be set if we don't want to support opening or accepting
|
|
// channels having the anchor commitment type.
|
|
NoAnchors bool `long:"no-anchors" description:"disable support for anchor commitments"`
|
|
|
|
// NoScriptEnforcedLease should be set if we don't want to support
|
|
// opening or accepting channels having the script enforced commitment
|
|
// type for leased channel.
|
|
NoScriptEnforcedLease bool `long:"no-script-enforced-lease" description:"disable support for script enforced lease commitments"`
|
|
|
|
// OptionScidAlias should be set if we want to signal the
|
|
// option-scid-alias feature bit. This allows scid aliases and the
|
|
// option-scid-alias channel-type.
|
|
OptionScidAlias bool `long:"option-scid-alias" description:"enable support for option_scid_alias channels"`
|
|
|
|
// OptionZeroConf should be set if we want to signal the zero-conf
|
|
// feature bit.
|
|
OptionZeroConf bool `long:"zero-conf" description:"enable support for zero-conf channels, must have option-scid-alias set also"`
|
|
|
|
// NoOptionAnySegwit should be set to true if we don't want to use any
|
|
// Taproot (and beyond) addresses for co-op closing.
|
|
NoOptionAnySegwit bool `long:"no-any-segwit" description:"disallow using any segwit witness version as a co-op close address"`
|
|
|
|
// NoTimestampQueryOption should be set to true if we don't want our
|
|
// syncing peers to also send us the timestamps of announcement messages
|
|
// when we send them a channel range query. Setting this to true will
|
|
// also mean that we won't respond with timestamps if requested by our
|
|
// peers.
|
|
NoTimestampQueryOption bool `long:"no-timestamp-query-option" description:"do not query syncing peers for announcement timestamps and do not respond with timestamps if requested"`
|
|
|
|
// NoRouteBlindingOption disables forwarding of payments in blinded routes.
|
|
NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"`
|
|
|
|
// NoOnionMessagesOption disables onion message forwarding.
|
|
NoOnionMessagesOption bool `long:"no-onion-messages" description:"disable support for onion messaging"`
|
|
|
|
// OnionMsgPeerKbps is the maximum sustained onion message ingress
|
|
// bandwidth, in decimal kilobits per second (1 Kbps = 1000 bits/s),
|
|
// that will be accepted from any single peer. Setting this to zero,
|
|
// together with a zero burst, disables the per-peer onion message
|
|
// rate limiter.
|
|
OnionMsgPeerKbps uint64 `long:"onion-msg-peer-kbps" description:"max onion message ingress rate from a single peer, in decimal kilobits per second; set both this and onion-msg-peer-burst-bytes to 0 to disable the per-peer limiter"`
|
|
|
|
// OnionMsgPeerBurstBytes is the token bucket depth, in bytes, used
|
|
// by the per-peer onion message rate limiter. A value of zero,
|
|
// paired with a zero rate, disables the per-peer limiter.
|
|
OnionMsgPeerBurstBytes uint64 `long:"onion-msg-peer-burst-bytes" description:"token bucket burst for the per-peer onion message limiter, in bytes; set both this and onion-msg-peer-kbps to 0 to disable the per-peer limiter"`
|
|
|
|
// OnionMsgGlobalKbps is the maximum sustained onion message ingress
|
|
// bandwidth, in decimal kilobits per second, that will be accepted
|
|
// across all peers combined. Setting this to zero, together with a
|
|
// zero burst, disables the global onion message rate limiter.
|
|
OnionMsgGlobalKbps uint64 `long:"onion-msg-global-kbps" description:"max onion message ingress rate across all peers combined, in decimal kilobits per second; set both this and onion-msg-global-burst-bytes to 0 to disable the global limiter"`
|
|
|
|
// OnionMsgGlobalBurstBytes is the token bucket depth, in bytes, used
|
|
// by the global onion message rate limiter. A value of zero, paired
|
|
// with a zero rate, disables the global limiter.
|
|
OnionMsgGlobalBurstBytes uint64 `long:"onion-msg-global-burst-bytes" description:"token bucket burst for the global onion message limiter, in bytes; set both this and onion-msg-global-kbps to 0 to disable the global limiter"`
|
|
|
|
// OnionMsgRelayAll disables the channel-presence gate on the onion
|
|
// message ingress path. When false (the default), incoming onion
|
|
// messages from peers that do not have at least one fully open
|
|
// channel with us are dropped before the rate limiters are
|
|
// consulted: without a funded channel, a new peer identity is free
|
|
// and the global rate limiter alone is easy to saturate. Setting
|
|
// this to true admits onion messages from any peer into the
|
|
// limiter pipeline, at the cost of that Sybil-resistance property.
|
|
OnionMsgRelayAll bool `long:"onion-msg-relay-all" description:"accept incoming onion messages from peers with no fully open channel; by default only peers with at least one active channel are admitted to the onion message ingress path"`
|
|
|
|
// NoExperimentalAccountabilityOption disables experimental accountability.
|
|
NoExperimentalAccountabilityOption bool `long:"no-experimental-accountability" description:"do not forward experimental accountability signals"`
|
|
|
|
// NoExperimentalEndorsementOption is the deprecated name for
|
|
// NoExperimentalAccountabilityOption. It is hidden and will be removed
|
|
// in a future release.
|
|
NoExperimentalEndorsementOption bool `long:"no-experimental-endorsement" hidden:"true" description:"deprecated: use no-experimental-accountability instead"`
|
|
|
|
// CustomMessage allows the custom message APIs to handle messages with
|
|
// the provided protocol numbers, which fall outside the custom message
|
|
// number range.
|
|
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."`
|
|
|
|
// CustomInit specifies feature bits to advertise in the node's init
|
|
// message.
|
|
CustomInit []uint16 `long:"custom-init" description:"custom feature bits — numbers defined in BOLT 9 — to advertise in the node's init message"`
|
|
|
|
// CustomNodeAnn specifies custom feature bits to advertise in the
|
|
// node's announcement message.
|
|
CustomNodeAnn []uint16 `long:"custom-nodeann" description:"custom feature bits — numbers defined in BOLT 9 — to advertise in the node's announcement message"`
|
|
|
|
// CustomInvoice specifies custom feature bits to advertise in the
|
|
// node's invoices.
|
|
CustomInvoice []uint16 `long:"custom-invoice" description:"custom feature bits — numbers defined in BOLT 9 — to advertise in the node's invoices"`
|
|
}
|
|
|
|
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo
|
|
// channels.
|
|
func (l *ProtocolOptions) Wumbo() bool {
|
|
return l.WumboChans
|
|
}
|
|
|
|
// NoAnchorCommitments returns true if we have disabled support for the anchor
|
|
// commitment type.
|
|
func (l *ProtocolOptions) NoAnchorCommitments() bool {
|
|
return l.NoAnchors
|
|
}
|
|
|
|
// NoScriptEnforcementLease returns true if we have disabled support for the
|
|
// script enforcement commitment type for leased channels.
|
|
func (l *ProtocolOptions) NoScriptEnforcementLease() bool {
|
|
return l.NoScriptEnforcedLease
|
|
}
|
|
|
|
// ScidAlias returns true if we have enabled the option-scid-alias feature bit.
|
|
func (l *ProtocolOptions) ScidAlias() bool {
|
|
return l.OptionScidAlias
|
|
}
|
|
|
|
// ZeroConf returns true if we have enabled the zero-conf feature bit.
|
|
func (l *ProtocolOptions) ZeroConf() bool {
|
|
return l.OptionZeroConf
|
|
}
|
|
|
|
// NoAnySegwit returns true if we don't signal that we understand other newer
|
|
// segwit witness versions for co-op close addresses.
|
|
func (l *ProtocolOptions) NoAnySegwit() bool {
|
|
return l.NoOptionAnySegwit
|
|
}
|
|
|
|
// NoTimestampsQuery returns true if we should not ask our syncing peers to also
|
|
// send us the timestamps of announcement messages when we send them a channel
|
|
// range query, and it also means that we will not respond with timestamps if
|
|
// requested by our peer.
|
|
func (l *ProtocolOptions) NoTimestampsQuery() bool {
|
|
return l.NoTimestampQueryOption
|
|
}
|
|
|
|
// NoRouteBlinding returns true if forwarding of blinded payments is disabled.
|
|
func (l *ProtocolOptions) NoRouteBlinding() bool {
|
|
return l.NoRouteBlindingOption
|
|
}
|
|
|
|
// NoOnionMessages returns true if onion messaging is disabled.
|
|
func (l *ProtocolOptions) NoOnionMessages() bool {
|
|
return l.NoOnionMessagesOption
|
|
}
|
|
|
|
// NoExpAccountability returns true if experimental accountability should be
|
|
// disabled. It also checks the deprecated NoExperimentalEndorsementOption for
|
|
// backwards compatibility.
|
|
func (l *ProtocolOptions) NoExpAccountability() bool {
|
|
return l.NoExperimentalAccountabilityOption ||
|
|
l.NoExperimentalEndorsementOption
|
|
}
|
|
|
|
// NoQuiescence returns true if quiescence is disabled.
|
|
func (l *ProtocolOptions) NoQuiescence() bool {
|
|
return false
|
|
}
|
|
|
|
// CustomMessageOverrides returns the set of protocol messages that we override
|
|
// to allow custom handling.
|
|
func (p ProtocolOptions) CustomMessageOverrides() []uint16 {
|
|
return p.CustomMessage
|
|
}
|
|
|
|
// CustomFeatures returns a custom set of feature bits to advertise.
|
|
func (p ProtocolOptions) CustomFeatures() map[feature.Set][]lnwire.FeatureBit {
|
|
customFeatures := make(map[feature.Set][]lnwire.FeatureBit)
|
|
|
|
setFeatures := func(set feature.Set, bits []uint16) {
|
|
for _, customFeature := range bits {
|
|
customFeatures[set] = append(
|
|
customFeatures[set],
|
|
lnwire.FeatureBit(customFeature),
|
|
)
|
|
}
|
|
}
|
|
|
|
setFeatures(feature.SetInit, p.CustomInit)
|
|
setFeatures(feature.SetNodeAnn, p.CustomNodeAnn)
|
|
setFeatures(feature.SetInvoice, p.CustomInvoice)
|
|
|
|
return customFeatures
|
|
}
|