Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/release-notes/release-notes-0.22.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
the close transaction is actually broadcast, and
`WaitingCloseChannel.ClosingTx` is never empty.

* [Fixed a bug](https://github.com/lightningnetwork/lnd/pull/10888) where
configuring a `protocol.custom-init` or `protocol.custom-nodeann` feature bit
that lnd already advertises by default caused startup to fail with a
`feature bit: X already set` error. Such a duplicate now yields an identical
feature vector and is treated as a no-op.

# New Features

## Functional Enhancements
Expand Down Expand Up @@ -89,3 +95,4 @@

* Boris Nagaev
* Erick Cestari
* Lrifton92
10 changes: 8 additions & 2 deletions feature/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,15 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
set, set.Maximum())
}

// If the feature bit is already advertised in lnd's
// default feature vector, configuring it as a custom
// feature produces an identical vector. Treat this as a
// no-op rather than failing startup (see #10883).
// Genuine conflicts between the optional and required
// variants of a feature are still caught by SafeSet
// below.
if raw.IsSet(custom) {
return nil, fmt.Errorf("feature bit: %v "+
"already set", custom)
continue
}

if err := raw.SafeSet(custom); err != nil {
Expand Down
30 changes: 30 additions & 0 deletions feature/manager_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,33 @@ func TestUpdateFeatureSets(t *testing.T) {
})
}
}

// TestManagerCustomFeatureAlreadyDefault asserts that configuring a custom
// feature bit which lnd already advertises by default does not prevent the
// feature manager from initializing. The resulting feature vector is identical,
// so the duplicate must be treated as a no-op rather than a fatal error.
//
// See: https://github.com/lightningnetwork/lnd/issues/10883
func TestManagerCustomFeatureAlreadyDefault(t *testing.T) {
t.Parallel()

// TLVOnionPayloadRequired is advertised by default in the Init set per
// testSetDesc, so configuring it as a custom feature for the same set
// duplicates an already-set bit. This previously failed startup with a
// "feature bit: ... already set" error.
cfg := Config{
CustomFeatures: map[Set][]lnwire.FeatureBit{
SetInit: {lnwire.TLVOnionPayloadRequired},
},
}

m, err := newManager(cfg, testSetDesc)
require.NoError(t, err)

// The required bit must still be advertised, and the duplicate must not
// have introduced its optional variant (which would form an invalid
// pairing). Check the exact bits via the raw vector.
rawInit := m.GetRaw(SetInit)
require.True(t, rawInit.IsSet(lnwire.TLVOnionPayloadRequired))
require.False(t, rawInit.IsSet(lnwire.TLVOnionPayloadOptional))
}
Loading