123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837 |
- package lnwire
- import (
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "github.com/lightningnetwork/lnd/tlv"
- )
- var (
- // ErrFeaturePairExists signals an error in feature vector construction
- // where the opposing bit in a feature pair has already been set.
- ErrFeaturePairExists = errors.New("feature pair exists")
- // ErrFeatureStandard is returned when attempts to modify LND's known
- // set of features are made.
- ErrFeatureStandard = errors.New("feature is used in standard " +
- "protocol set")
- // ErrFeatureBitMaximum is returned when a feature bit exceeds the
- // maximum allowable value.
- ErrFeatureBitMaximum = errors.New("feature bit exceeds allowed maximum")
- )
- // FeatureBit represents a feature that can be enabled in either a local or
- // global feature vector at a specific bit position. Feature bits follow the
- // "it's OK to be odd" rule, where features at even bit positions must be known
- // to a node receiving them from a peer while odd bits do not. In accordance,
- // feature bits are usually assigned in pairs, first being assigned an odd bit
- // position which may later be changed to the preceding even position once
- // knowledge of the feature becomes required on the network.
- type FeatureBit uint16
- const (
- // DataLossProtectRequired is a feature bit that indicates that a peer
- // *requires* the other party know about the data-loss-protect optional
- // feature. If the remote peer does not know of such a feature, then
- // the sending peer SHOULD disconnect them. The data-loss-protect
- // feature allows a peer that's lost partial data to recover their
- // settled funds of the latest commitment state.
- DataLossProtectRequired FeatureBit = 0
- // DataLossProtectOptional is an optional feature bit that indicates
- // that the sending peer knows of this new feature and can activate it
- // it. The data-loss-protect feature allows a peer that's lost partial
- // data to recover their settled funds of the latest commitment state.
- DataLossProtectOptional FeatureBit = 1
- // InitialRoutingSync is a local feature bit meaning that the receiving
- // node should send a complete dump of routing information when a new
- // connection is established.
- InitialRoutingSync FeatureBit = 3
- // UpfrontShutdownScriptRequired is a feature bit which indicates that a
- // peer *requires* that the remote peer accept an upfront shutdown script to
- // which payout is enforced on cooperative closes.
- UpfrontShutdownScriptRequired FeatureBit = 4
- // UpfrontShutdownScriptOptional is an optional feature bit which indicates
- // that the peer will accept an upfront shutdown script to which payout is
- // enforced on cooperative closes.
- UpfrontShutdownScriptOptional FeatureBit = 5
- // GossipQueriesRequired is a feature bit that indicates that the
- // receiving peer MUST know of the set of features that allows nodes to
- // more efficiently query the network view of peers on the network for
- // reconciliation purposes.
- GossipQueriesRequired FeatureBit = 6
- // GossipQueriesOptional is an optional feature bit that signals that
- // the setting peer knows of the set of features that allows more
- // efficient network view reconciliation.
- GossipQueriesOptional FeatureBit = 7
- // TLVOnionPayloadRequired is a feature bit that indicates a node is
- // able to decode the new TLV information included in the onion packet.
- TLVOnionPayloadRequired FeatureBit = 8
- // TLVOnionPayloadOptional is an optional feature bit that indicates a
- // node is able to decode the new TLV information included in the onion
- // packet.
- TLVOnionPayloadOptional FeatureBit = 9
- // StaticRemoteKeyRequired is a required feature bit that signals that
- // within one's commitment transaction, the key used for the remote
- // party's non-delay output should not be tweaked.
- StaticRemoteKeyRequired FeatureBit = 12
- // StaticRemoteKeyOptional is an optional feature bit that signals that
- // within one's commitment transaction, the key used for the remote
- // party's non-delay output should not be tweaked.
- StaticRemoteKeyOptional FeatureBit = 13
- // PaymentAddrRequired is a required feature bit that signals that a
- // node requires payment addresses, which are used to mitigate probing
- // attacks on the receiver of a payment.
- PaymentAddrRequired FeatureBit = 14
- // PaymentAddrOptional is an optional feature bit that signals that a
- // node supports payment addresses, which are used to mitigate probing
- // attacks on the receiver of a payment.
- PaymentAddrOptional FeatureBit = 15
- // MPPRequired is a required feature bit that signals that the receiver
- // of a payment requires settlement of an invoice with more than one
- // HTLC.
- MPPRequired FeatureBit = 16
- // MPPOptional is an optional feature bit that signals that the receiver
- // of a payment supports settlement of an invoice with more than one
- // HTLC.
- MPPOptional FeatureBit = 17
- // WumboChannelsRequired is a required feature bit that signals that a
- // node is willing to accept channels larger than 2^24 satoshis.
- WumboChannelsRequired FeatureBit = 18
- // WumboChannelsOptional is an optional feature bit that signals that a
- // node is willing to accept channels larger than 2^24 satoshis.
- WumboChannelsOptional FeatureBit = 19
- // AnchorsRequired is a required feature bit that signals that the node
- // requires channels to be made using commitments having anchor
- // outputs.
- AnchorsRequired FeatureBit = 20
- // AnchorsOptional is an optional feature bit that signals that the
- // node supports channels to be made using commitments having anchor
- // outputs.
- AnchorsOptional FeatureBit = 21
- // AnchorsZeroFeeHtlcTxRequired is a required feature bit that signals
- // that the node requires channels having zero-fee second-level HTLC
- // transactions, which also imply anchor commitments.
- AnchorsZeroFeeHtlcTxRequired FeatureBit = 22
- // AnchorsZeroFeeHtlcTxOptional is an optional feature bit that signals
- // that the node supports channels having zero-fee second-level HTLC
- // transactions, which also imply anchor commitments.
- AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
- // RouteBlindingRequired is a required feature bit that signals that
- // the node supports blinded payments.
- RouteBlindingRequired FeatureBit = 24
- // RouteBlindingOptional is an optional feature bit that signals that
- // the node supports blinded payments.
- RouteBlindingOptional FeatureBit = 25
- // ShutdownAnySegwitRequired is an required feature bit that signals
- // that the sender is able to properly handle/parse segwit witness
- // programs up to version 16. This enables utilization of Taproot
- // addresses for cooperative closure addresses.
- ShutdownAnySegwitRequired FeatureBit = 26
- // ShutdownAnySegwitOptional is an optional feature bit that signals
- // that the sender is able to properly handle/parse segwit witness
- // programs up to version 16. This enables utilization of Taproot
- // addresses for cooperative closure addresses.
- ShutdownAnySegwitOptional FeatureBit = 27
- // AMPRequired is a required feature bit that signals that the receiver
- // of a payment supports accepts spontaneous payments, i.e.
- // sender-generated preimages according to BOLT XX.
- AMPRequired FeatureBit = 30
- // AMPOptional is an optional feature bit that signals that the receiver
- // of a payment supports accepts spontaneous payments, i.e.
- // sender-generated preimages according to BOLT XX.
- AMPOptional FeatureBit = 31
- // ExplicitChannelTypeRequired is a required bit that denotes that a
- // connection established with this node is to use explicit channel
- // commitment types for negotiation instead of the existing implicit
- // negotiation methods. With this bit, there is no longer a "default"
- // implicit channel commitment type, allowing a connection to
- // open/maintain types of several channels over its lifetime.
- ExplicitChannelTypeRequired = 44
- // ExplicitChannelTypeOptional is an optional bit that denotes that a
- // connection established with this node is to use explicit channel
- // commitment types for negotiation instead of the existing implicit
- // negotiation methods. With this bit, there is no longer a "default"
- // implicit channel commitment type, allowing a connection to
- // TODO: Decide on actual feature bit value.
- ExplicitChannelTypeOptional = 45
- // ScidAliasRequired is a required feature bit that signals that the
- // node requires understanding of ShortChannelID aliases in the TLV
- // segment of the channel_ready message.
- ScidAliasRequired FeatureBit = 46
- // ScidAliasOptional is an optional feature bit that signals that the
- // node understands ShortChannelID aliases in the TLV segment of the
- // channel_ready message.
- ScidAliasOptional FeatureBit = 47
- // PaymentMetadataRequired is a required bit that denotes that if an
- // invoice contains metadata, it must be passed along with the payment
- // htlc(s).
- PaymentMetadataRequired = 48
- // PaymentMetadataOptional is an optional bit that denotes that if an
- // invoice contains metadata, it may be passed along with the payment
- // htlc(s).
- PaymentMetadataOptional = 49
- // ZeroConfRequired is a required feature bit that signals that the
- // node requires understanding of the zero-conf channel_type.
- ZeroConfRequired FeatureBit = 50
- // ZeroConfOptional is an optional feature bit that signals that the
- // node understands the zero-conf channel type.
- ZeroConfOptional FeatureBit = 51
- // KeysendRequired is a required bit that indicates that the node is
- // able and willing to accept keysend payments.
- KeysendRequired = 54
- // KeysendOptional is an optional bit that indicates that the node is
- // able and willing to accept keysend payments.
- KeysendOptional = 55
- // ScriptEnforcedLeaseRequired is a required feature bit that signals
- // that the node requires channels having zero-fee second-level HTLC
- // transactions, which also imply anchor commitments, along with an
- // additional CLTV constraint of a channel lease's expiration height
- // applied to all outputs that pay directly to the channel initiator.
- //
- // TODO: Decide on actual feature bit value.
- ScriptEnforcedLeaseRequired FeatureBit = 2022
- // ScriptEnforcedLeaseOptional is an optional feature bit that signals
- // that the node requires channels having zero-fee second-level HTLC
- // transactions, which also imply anchor commitments, along with an
- // additional CLTV constraint of a channel lease's expiration height
- // applied to all outputs that pay directly to the channel initiator.
- //
- // TODO: Decide on actual feature bit value.
- ScriptEnforcedLeaseOptional FeatureBit = 2023
- // SimpleTaprootChannelsRequiredFinal is a required bit that indicates
- // the node is able to create taproot-native channels. This is the
- // final feature bit to be used once the channel type is finalized.
- SimpleTaprootChannelsRequiredFinal = 80
- // SimpleTaprootChannelsOptionalFinal is an optional bit that indicates
- // the node is able to create taproot-native channels. This is the
- // final feature bit to be used once the channel type is finalized.
- SimpleTaprootChannelsOptionalFinal = 81
- // SimpleTaprootChannelsRequiredStaging is a required bit that indicates
- // the node is able to create taproot-native channels. This is a
- // feature bit used in the wild while the channel type is still being
- // finalized.
- SimpleTaprootChannelsRequiredStaging = 180
- // SimpleTaprootChannelsOptionalStaging is an optional bit that
- // indicates the node is able to create taproot-native channels. This
- // is a feature bit used in the wild while the channel type is still
- // being finalized.
- SimpleTaprootChannelsOptionalStaging = 181
- // Bolt11BlindedPathsRequired is a required feature bit that indicates
- // that the node is able to understand the blinded path tagged field in
- // a BOLT 11 invoice.
- Bolt11BlindedPathsRequired = 262
- // Bolt11BlindedPathsOptional is an optional feature bit that indicates
- // that the node is able to understand the blinded path tagged field in
- // a BOLT 11 invoice.
- Bolt11BlindedPathsOptional = 263
- // MaxBolt11Feature is the maximum feature bit value allowed in bolt 11
- // invoices.
- //
- // The base 32 encoded tagged fields in invoices are limited to 10 bits
- // to express the length of the field's data.
- //nolint:lll
- // See: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#tagged-fields
- //
- // With a maximum length field of 1023 (2^10 -1) and 5 bit encoding,
- // the highest feature bit that can be expressed is:
- // 1023 * 5 - 1 = 5114.
- MaxBolt11Feature = 5114
- )
- // IsRequired returns true if the feature bit is even, and false otherwise.
- func (b FeatureBit) IsRequired() bool {
- return b&0x01 == 0x00
- }
- // Features is a mapping of known feature bits to a descriptive name. All known
- // feature bits must be assigned a name in this mapping, and feature bit pairs
- // must be assigned together for correct behavior.
- var Features = map[FeatureBit]string{
- DataLossProtectRequired: "data-loss-protect",
- DataLossProtectOptional: "data-loss-protect",
- InitialRoutingSync: "initial-routing-sync",
- UpfrontShutdownScriptRequired: "upfront-shutdown-script",
- UpfrontShutdownScriptOptional: "upfront-shutdown-script",
- GossipQueriesRequired: "gossip-queries",
- GossipQueriesOptional: "gossip-queries",
- TLVOnionPayloadRequired: "tlv-onion",
- TLVOnionPayloadOptional: "tlv-onion",
- StaticRemoteKeyOptional: "static-remote-key",
- StaticRemoteKeyRequired: "static-remote-key",
- PaymentAddrOptional: "payment-addr",
- PaymentAddrRequired: "payment-addr",
- MPPOptional: "multi-path-payments",
- MPPRequired: "multi-path-payments",
- AnchorsRequired: "anchor-commitments",
- AnchorsOptional: "anchor-commitments",
- AnchorsZeroFeeHtlcTxRequired: "anchors-zero-fee-htlc-tx",
- AnchorsZeroFeeHtlcTxOptional: "anchors-zero-fee-htlc-tx",
- WumboChannelsRequired: "wumbo-channels",
- WumboChannelsOptional: "wumbo-channels",
- AMPRequired: "amp",
- AMPOptional: "amp",
- PaymentMetadataOptional: "payment-metadata",
- PaymentMetadataRequired: "payment-metadata",
- ExplicitChannelTypeOptional: "explicit-commitment-type",
- ExplicitChannelTypeRequired: "explicit-commitment-type",
- KeysendOptional: "keysend",
- KeysendRequired: "keysend",
- ScriptEnforcedLeaseRequired: "script-enforced-lease",
- ScriptEnforcedLeaseOptional: "script-enforced-lease",
- ScidAliasRequired: "scid-alias",
- ScidAliasOptional: "scid-alias",
- ZeroConfRequired: "zero-conf",
- ZeroConfOptional: "zero-conf",
- RouteBlindingRequired: "route-blinding",
- RouteBlindingOptional: "route-blinding",
- ShutdownAnySegwitRequired: "shutdown-any-segwit",
- ShutdownAnySegwitOptional: "shutdown-any-segwit",
- SimpleTaprootChannelsRequiredFinal: "simple-taproot-chans",
- SimpleTaprootChannelsOptionalFinal: "simple-taproot-chans",
- SimpleTaprootChannelsRequiredStaging: "simple-taproot-chans-x",
- SimpleTaprootChannelsOptionalStaging: "simple-taproot-chans-x",
- Bolt11BlindedPathsOptional: "bolt-11-blinded-paths",
- Bolt11BlindedPathsRequired: "bolt-11-blinded-paths",
- }
- // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A
- // RawFeatureVector itself just stores a set of bit flags but can be used to
- // construct a FeatureVector which binds meaning to each bit. Feature vectors
- // can be serialized and deserialized to/from a byte representation that is
- // transmitted in Lightning network messages.
- type RawFeatureVector struct {
- features map[FeatureBit]struct{}
- }
- // NewRawFeatureVector creates a feature vector with all of the feature bits
- // given as arguments enabled.
- func NewRawFeatureVector(bits ...FeatureBit) *RawFeatureVector {
- fv := &RawFeatureVector{features: make(map[FeatureBit]struct{})}
- for _, bit := range bits {
- fv.Set(bit)
- }
- return fv
- }
- // IsEmpty returns whether the feature vector contains any feature bits.
- func (fv RawFeatureVector) IsEmpty() bool {
- return len(fv.features) == 0
- }
- // OnlyContains determines whether only the specified feature bits are found.
- func (fv RawFeatureVector) OnlyContains(bits ...FeatureBit) bool {
- if len(bits) != len(fv.features) {
- return false
- }
- for _, bit := range bits {
- if !fv.IsSet(bit) {
- return false
- }
- }
- return true
- }
- // Equals determines whether two features vectors contain exactly the same
- // features.
- func (fv RawFeatureVector) Equals(other *RawFeatureVector) bool {
- if len(fv.features) != len(other.features) {
- return false
- }
- for bit := range fv.features {
- if _, ok := other.features[bit]; !ok {
- return false
- }
- }
- return true
- }
- // Merges sets all feature bits in other on the receiver's feature vector.
- func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error {
- for bit := range other.features {
- err := fv.SafeSet(bit)
- if err != nil {
- return err
- }
- }
- return nil
- }
- // ValidateUpdate checks whether a feature vector can safely be updated to the
- // new feature vector provided, checking that it does not alter any of the
- // "standard" features that are defined by LND. The new feature vector should
- // be inclusive of all features in the original vector that it still wants to
- // advertise, setting and unsetting updates as desired. Features in the vector
- // are also checked against a maximum inclusive value, as feature vectors in
- // different contexts have different maximum values.
- func (fv *RawFeatureVector) ValidateUpdate(other *RawFeatureVector,
- maximumValue FeatureBit) error {
- // Run through the new set of features and check that we're not adding
- // any feature bits that are defined but not set in LND.
- for feature := range other.features {
- if fv.IsSet(feature) {
- continue
- }
- if feature > maximumValue {
- return fmt.Errorf("can't set feature bit %d: %w %v",
- feature, ErrFeatureBitMaximum,
- maximumValue)
- }
- if name, known := Features[feature]; known {
- return fmt.Errorf("can't set feature "+
- "bit %d (%v): %w", feature, name,
- ErrFeatureStandard)
- }
- }
- // Check that the new feature vector for this set does not unset any
- // features that are standard in LND by comparing the features in our
- // current set to the omitted values in the new set.
- for feature := range fv.features {
- if other.IsSet(feature) {
- continue
- }
- if name, known := Features[feature]; known {
- return fmt.Errorf("can't unset feature "+
- "bit %d (%v): %w", feature, name,
- ErrFeatureStandard)
- }
- }
- return nil
- }
- // ValidatePairs checks each feature bit in a raw vector to ensure that the
- // opposing bit is not set, validating that the vector has either the optional
- // or required bit set, not both.
- func (fv *RawFeatureVector) ValidatePairs() error {
- for feature := range fv.features {
- if _, ok := fv.features[feature^1]; ok {
- return ErrFeaturePairExists
- }
- }
- return nil
- }
- // Clone makes a copy of a feature vector.
- func (fv *RawFeatureVector) Clone() *RawFeatureVector {
- newFeatures := NewRawFeatureVector()
- for bit := range fv.features {
- newFeatures.Set(bit)
- }
- return newFeatures
- }
- // IsSet returns whether a particular feature bit is enabled in the vector.
- func (fv *RawFeatureVector) IsSet(feature FeatureBit) bool {
- _, ok := fv.features[feature]
- return ok
- }
- // Set marks a feature as enabled in the vector.
- func (fv *RawFeatureVector) Set(feature FeatureBit) {
- fv.features[feature] = struct{}{}
- }
- // SafeSet sets the chosen feature bit in the feature vector, but returns an
- // error if the opposing feature bit is already set. This ensures both that we
- // are creating properly structured feature vectors, and in some cases, that
- // peers are sending properly encoded ones, i.e. it can't be both optional and
- // required.
- func (fv *RawFeatureVector) SafeSet(feature FeatureBit) error {
- if _, ok := fv.features[feature^1]; ok {
- return ErrFeaturePairExists
- }
- fv.Set(feature)
- return nil
- }
- // Unset marks a feature as disabled in the vector.
- func (fv *RawFeatureVector) Unset(feature FeatureBit) {
- delete(fv.features, feature)
- }
- // SerializeSize returns the number of bytes needed to represent feature vector
- // in byte format.
- func (fv *RawFeatureVector) SerializeSize() int {
- // We calculate byte-length via the largest bit index.
- return fv.serializeSize(8)
- }
- // SerializeSize32 returns the number of bytes needed to represent feature
- // vector in base32 format.
- func (fv *RawFeatureVector) SerializeSize32() int {
- // We calculate base32-length via the largest bit index.
- return fv.serializeSize(5)
- }
- // serializeSize returns the number of bytes required to encode the feature
- // vector using at most width bits per encoded byte.
- func (fv *RawFeatureVector) serializeSize(width int) int {
- // Find the largest feature bit index
- max := -1
- for feature := range fv.features {
- index := int(feature)
- if index > max {
- max = index
- }
- }
- if max == -1 {
- return 0
- }
- return max/width + 1
- }
- // Encode writes the feature vector in byte representation. Every feature
- // encoded as a bit, and the bit vector is serialized using the least number of
- // bytes. Since the bit vector length is variable, the first two bytes of the
- // serialization represent the length.
- func (fv *RawFeatureVector) Encode(w io.Writer) error {
- // Write length of feature vector.
- var l [2]byte
- length := fv.SerializeSize()
- binary.BigEndian.PutUint16(l[:], uint16(length))
- if _, err := w.Write(l[:]); err != nil {
- return err
- }
- return fv.encode(w, length, 8)
- }
- // EncodeBase256 writes the feature vector in base256 representation. Every
- // feature is encoded as a bit, and the bit vector is serialized using the least
- // number of bytes.
- func (fv *RawFeatureVector) EncodeBase256(w io.Writer) error {
- length := fv.SerializeSize()
- return fv.encode(w, length, 8)
- }
- // EncodeBase32 writes the feature vector in base32 representation. Every feature
- // is encoded as a bit, and the bit vector is serialized using the least number of
- // bytes.
- func (fv *RawFeatureVector) EncodeBase32(w io.Writer) error {
- length := fv.SerializeSize32()
- return fv.encode(w, length, 5)
- }
- // encode writes the feature vector
- func (fv *RawFeatureVector) encode(w io.Writer, length, width int) error {
- // Generate the data and write it.
- data := make([]byte, length)
- for feature := range fv.features {
- byteIndex := int(feature) / width
- bitIndex := int(feature) % width
- data[length-byteIndex-1] |= 1 << uint(bitIndex)
- }
- _, err := w.Write(data)
- return err
- }
- // Decode reads the feature vector from its byte representation. Every feature
- // is encoded as a bit, and the bit vector is serialized using the least number
- // of bytes. Since the bit vector length is variable, the first two bytes of the
- // serialization represent the length.
- func (fv *RawFeatureVector) Decode(r io.Reader) error {
- // Read the length of the feature vector.
- var l [2]byte
- if _, err := io.ReadFull(r, l[:]); err != nil {
- return err
- }
- length := binary.BigEndian.Uint16(l[:])
- return fv.decode(r, int(length), 8)
- }
- // DecodeBase256 reads the feature vector from its base256 representation. Every
- // feature encoded as a bit, and the bit vector is serialized using the least
- // number of bytes.
- func (fv *RawFeatureVector) DecodeBase256(r io.Reader, length int) error {
- return fv.decode(r, length, 8)
- }
- // DecodeBase32 reads the feature vector from its base32 representation. Every
- // feature encoded as a bit, and the bit vector is serialized using the least
- // number of bytes.
- func (fv *RawFeatureVector) DecodeBase32(r io.Reader, length int) error {
- return fv.decode(r, length, 5)
- }
- // decode reads a feature vector from the next length bytes of the io.Reader,
- // assuming each byte has width feature bits encoded per byte.
- func (fv *RawFeatureVector) decode(r io.Reader, length, width int) error {
- // Read the feature vector data.
- data := make([]byte, length)
- if _, err := io.ReadFull(r, data); err != nil {
- return err
- }
- // Set feature bits from parsed data.
- bitsNumber := len(data) * width
- for i := 0; i < bitsNumber; i++ {
- byteIndex := int(i / width)
- bitIndex := uint(i % width)
- if (data[length-byteIndex-1]>>bitIndex)&1 == 1 {
- fv.Set(FeatureBit(i))
- }
- }
- return nil
- }
- // sizeFunc returns the length required to encode the feature vector.
- func (fv *RawFeatureVector) sizeFunc() uint64 {
- return uint64(fv.SerializeSize())
- }
- // Record returns a TLV record that can be used to encode/decode raw feature
- // vectors. Note that the length of the feature vector is not included, because
- // it is covered by the TLV record's length field.
- func (fv *RawFeatureVector) Record(recordType tlv.Type) tlv.Record {
- return tlv.MakeDynamicRecord(
- recordType, fv, fv.sizeFunc, rawFeatureEncoder,
- rawFeatureDecoder,
- )
- }
- // rawFeatureEncoder is a custom TLV encoder for raw feature vectors.
- func rawFeatureEncoder(w io.Writer, val interface{}, _ *[8]byte) error {
- if f, ok := val.(*RawFeatureVector); ok {
- return f.encode(w, f.SerializeSize(), 8)
- }
- return tlv.NewTypeForEncodingErr(val, "*lnwire.RawFeatureVector")
- }
- // rawFeatureDecoder is a custom TLV decoder for raw feature vectors.
- func rawFeatureDecoder(r io.Reader, val interface{}, _ *[8]byte,
- l uint64) error {
- if f, ok := val.(*RawFeatureVector); ok {
- return f.decode(r, int(l), 8)
- }
- return tlv.NewTypeForEncodingErr(val, "*lnwire.RawFeatureVector")
- }
- // FeatureVector represents a set of enabled features. The set stores
- // information on enabled flags and metadata about the feature names. A feature
- // vector is serializable to a compact byte representation that is included in
- // Lightning network messages.
- type FeatureVector struct {
- *RawFeatureVector
- featureNames map[FeatureBit]string
- }
- // NewFeatureVector constructs a new FeatureVector from a raw feature vector
- // and mapping of feature definitions. If the feature vector argument is nil, a
- // new one will be constructed with no enabled features.
- func NewFeatureVector(featureVector *RawFeatureVector,
- featureNames map[FeatureBit]string) *FeatureVector {
- if featureVector == nil {
- featureVector = NewRawFeatureVector()
- }
- return &FeatureVector{
- RawFeatureVector: featureVector,
- featureNames: featureNames,
- }
- }
- // EmptyFeatureVector returns a feature vector with no bits set.
- func EmptyFeatureVector() *FeatureVector {
- return NewFeatureVector(nil, Features)
- }
- // Record implements the RecordProducer interface for FeatureVector. Note that
- // it uses a zero-value type is used to produce the record, as we expect this
- // type value to be overwritten when used in generic TLV record production.
- // This allows a single Record function to serve in the many different contexts
- // in which feature vectors are encoded. This record wraps the encoding/
- // decoding for our raw feature vectors so that we can directly parse fully
- // formed feature vector types.
- func (fv *FeatureVector) Record() tlv.Record {
- return tlv.MakeDynamicRecord(0, fv, fv.sizeFunc,
- func(w io.Writer, val interface{}, buf *[8]byte) error {
- if f, ok := val.(*FeatureVector); ok {
- return rawFeatureEncoder(
- w, f.RawFeatureVector, buf,
- )
- }
- return tlv.NewTypeForEncodingErr(
- val, "*lnwire.FeatureVector",
- )
- },
- func(r io.Reader, val interface{}, buf *[8]byte,
- l uint64) error {
- if f, ok := val.(*FeatureVector); ok {
- features := NewFeatureVector(nil, Features)
- err := rawFeatureDecoder(
- r, features.RawFeatureVector, buf, l,
- )
- if err != nil {
- return err
- }
- *f = *features
- return nil
- }
- return tlv.NewTypeForDecodingErr(
- val, "*lnwire.FeatureVector", l, l,
- )
- },
- )
- }
- // HasFeature returns whether a particular feature is included in the set. The
- // feature can be seen as set either if the bit is set directly OR the queried
- // bit has the same meaning as its corresponding even/odd bit, which is set
- // instead. The second case is because feature bits are generally assigned in
- // pairs where both the even and odd position represent the same feature.
- func (fv *FeatureVector) HasFeature(feature FeatureBit) bool {
- return fv.IsSet(feature) ||
- (fv.isFeatureBitPair(feature) && fv.IsSet(feature^1))
- }
- // RequiresFeature returns true if the referenced feature vector *requires*
- // that the given required bit be set. This method can be used with both
- // optional and required feature bits as a parameter.
- func (fv *FeatureVector) RequiresFeature(feature FeatureBit) bool {
- // If we weren't passed a required feature bit, then we'll flip the
- // lowest bit to query for the required version of the feature. This
- // lets callers pass in both the optional and required bits.
- if !feature.IsRequired() {
- feature ^= 1
- }
- return fv.IsSet(feature)
- }
- // UnknownRequiredFeatures returns a list of feature bits set in the vector
- // that are unknown and in an even bit position. Feature bits with an even
- // index must be known to a node receiving the feature vector in a message.
- func (fv *FeatureVector) UnknownRequiredFeatures() []FeatureBit {
- var unknown []FeatureBit
- for feature := range fv.features {
- if feature%2 == 0 && !fv.IsKnown(feature) {
- unknown = append(unknown, feature)
- }
- }
- return unknown
- }
- // UnknownFeatures returns a boolean if a feature vector contains *any*
- // unknown features (even if they are odd).
- func (fv *FeatureVector) UnknownFeatures() bool {
- for feature := range fv.features {
- if !fv.IsKnown(feature) {
- return true
- }
- }
- return false
- }
- // Name returns a string identifier for the feature represented by this bit. If
- // the bit does not represent a known feature, this returns a string indicating
- // as such.
- func (fv *FeatureVector) Name(bit FeatureBit) string {
- name, known := fv.featureNames[bit]
- if !known {
- return "unknown"
- }
- return name
- }
- // IsKnown returns whether this feature bit represents a known feature.
- func (fv *FeatureVector) IsKnown(bit FeatureBit) bool {
- _, known := fv.featureNames[bit]
- return known
- }
- // isFeatureBitPair returns whether this feature bit and its corresponding
- // even/odd bit both represent the same feature. This may often be the case as
- // bits are generally assigned in pairs, first being assigned an odd bit
- // position then being promoted to an even bit position once the network is
- // ready.
- func (fv *FeatureVector) isFeatureBitPair(bit FeatureBit) bool {
- name1, known1 := fv.featureNames[bit]
- name2, known2 := fv.featureNames[bit^1]
- return known1 && known2 && name1 == name2
- }
- // Features returns the set of raw features contained in the feature vector.
- func (fv *FeatureVector) Features() map[FeatureBit]struct{} {
- fs := make(map[FeatureBit]struct{}, len(fv.RawFeatureVector.features))
- for b := range fv.RawFeatureVector.features {
- fs[b] = struct{}{}
- }
- return fs
- }
- // Clone copies a feature vector, carrying over its feature bits. The feature
- // names are not copied.
- func (fv *FeatureVector) Clone() *FeatureVector {
- features := fv.RawFeatureVector.Clone()
- return NewFeatureVector(features, fv.featureNames)
- }
|