mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
019127c4f4
Base 32 encoded bolt 11 invoices only allow 10 bits to express the length of the feature vector in a tagged field, so there is a much lower limit on the values invoice custom features can hold. Other places in the protocol are theoretically limited by the maximum message size, but since we express a feature bit as u16 we don't need to be concerned about this. The decision is made to track maximum per-set in the feature manager, which is conceptually aware of sets and then validate in lnwire/features against some arbitrary maximum value provided to the caller to keep the base features package unaware of sets.
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package feature
|
|
|
|
import (
|
|
"math"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
// Set is an enum identifying various feature sets, which separates the single
|
|
// feature namespace into distinct categories depending what context a feature
|
|
// vector is being used.
|
|
type Set uint8
|
|
|
|
const (
|
|
// SetInit identifies features that should be sent in an Init message to
|
|
// a remote peer.
|
|
SetInit Set = iota
|
|
|
|
// SetLegacyGlobal 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.
|
|
SetLegacyGlobal
|
|
|
|
// SetNodeAnn identifies features that should be advertised on node
|
|
// announcements.
|
|
SetNodeAnn
|
|
|
|
// SetInvoice identifies features that should be advertised on invoices
|
|
// generated by the daemon.
|
|
SetInvoice
|
|
|
|
// SetInvoiceAmp identifies the features that should be advertised on
|
|
// AMP invoices generated by the daemon.
|
|
SetInvoiceAmp
|
|
|
|
// setSentinel is used to mark the end of our known sets. This enum
|
|
// member must *always* be the last item in the iota list to ensure
|
|
// that validation works as expected.
|
|
setSentinel
|
|
)
|
|
|
|
// valid returns a boolean indicating whether a set value is one of our
|
|
// predefined feature sets.
|
|
func (s Set) valid() bool {
|
|
return s < setSentinel
|
|
}
|
|
|
|
// String returns a human-readable description of a Set.
|
|
func (s Set) String() string {
|
|
switch s {
|
|
case SetInit:
|
|
return "SetInit"
|
|
case SetLegacyGlobal:
|
|
return "SetLegacyGlobal"
|
|
case SetNodeAnn:
|
|
return "SetNodeAnn"
|
|
case SetInvoice:
|
|
return "SetInvoice"
|
|
case SetInvoiceAmp:
|
|
return "SetInvoiceAmp"
|
|
default:
|
|
return "SetUnknown"
|
|
}
|
|
}
|
|
|
|
// Maximum returns the maximum allowable value for a feature bit in the context
|
|
// of a set. The maximum feature value we can express differs by set context
|
|
// because the amount of space available varies between protocol messages. In
|
|
// practice this should never be a problem (reasonably one would never hit
|
|
// these high ranges), but we enforce these maximums for the sake of sane
|
|
// validation.
|
|
func (s Set) Maximum() lnwire.FeatureBit {
|
|
switch s {
|
|
case SetInvoice, SetInvoiceAmp:
|
|
return lnwire.MaxBolt11Feature
|
|
|
|
// The space available in other sets is > math.MaxUint16, so we just
|
|
// return the maximum value our expression of a feature bit allows so
|
|
// that any value will pass.
|
|
default:
|
|
return math.MaxUint16
|
|
}
|
|
}
|