fe566e1755
This commit introduces a feature.Manager, which derives feature vectors for various contexts within the daemon. The sets can be described via a staticly compiled format, which makes any runtime adjustments to the feature sets when the manager is initialized.
129 lines
2.5 KiB
Go
129 lines
2.5 KiB
Go
package feature
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
type managerTest struct {
|
|
name string
|
|
cfg Config
|
|
}
|
|
|
|
const unknownFeature lnwire.FeatureBit = 30
|
|
|
|
var testSetDesc = setDesc{
|
|
lnwire.DataLossProtectRequired: {
|
|
SetNodeAnn: {}, // I
|
|
},
|
|
lnwire.TLVOnionPayloadOptional: {
|
|
SetInit: {}, // I
|
|
SetNodeAnn: {}, // N
|
|
},
|
|
lnwire.StaticRemoteKeyOptional: {
|
|
SetInit: {}, // I
|
|
SetNodeAnn: {}, // N
|
|
},
|
|
}
|
|
|
|
var managerTests = []managerTest{
|
|
{
|
|
name: "default",
|
|
cfg: Config{},
|
|
},
|
|
{
|
|
name: "no tlv",
|
|
cfg: Config{
|
|
NoTLVOnion: true,
|
|
},
|
|
},
|
|
{
|
|
name: "no static remote key",
|
|
cfg: Config{
|
|
NoStaticRemoteKey: true,
|
|
},
|
|
},
|
|
{
|
|
name: "no tlv or static remote key",
|
|
cfg: Config{
|
|
NoTLVOnion: true,
|
|
NoStaticRemoteKey: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
// TestManager asserts basic initialazation and operation of a feature manager,
|
|
// including that the proper features are removed in response to config changes.
|
|
func TestManager(t *testing.T) {
|
|
for _, test := range managerTests {
|
|
test := test
|
|
t.Run(test.name, func(t *testing.T) {
|
|
testManager(t, test)
|
|
})
|
|
}
|
|
}
|
|
|
|
func testManager(t *testing.T, test managerTest) {
|
|
m, err := newManager(test.cfg, testSetDesc)
|
|
if err != nil {
|
|
t.Fatalf("unable to create feature manager: %v", err)
|
|
}
|
|
|
|
sets := []Set{
|
|
SetInit,
|
|
SetLegacyGlobal,
|
|
SetNodeAnn,
|
|
SetInvoice,
|
|
}
|
|
|
|
for _, set := range sets {
|
|
raw := m.GetRaw(set)
|
|
fv := m.Get(set)
|
|
|
|
fv2 := lnwire.NewFeatureVector(raw, lnwire.Features)
|
|
|
|
if !reflect.DeepEqual(fv, fv2) {
|
|
t.Fatalf("mismatch Get vs GetRaw, raw: %v vs fv: %v",
|
|
fv2, fv)
|
|
}
|
|
|
|
assertUnset := func(bit lnwire.FeatureBit) {
|
|
hasBit := fv.HasFeature(bit) || fv.HasFeature(bit^1)
|
|
if hasBit {
|
|
t.Fatalf("bit %v or %v is set", bit, bit^1)
|
|
}
|
|
}
|
|
|
|
// Assert that the manager properly unset the configured feature
|
|
// bits from all sets.
|
|
if test.cfg.NoTLVOnion {
|
|
assertUnset(lnwire.TLVOnionPayloadOptional)
|
|
}
|
|
if test.cfg.NoStaticRemoteKey {
|
|
assertUnset(lnwire.StaticRemoteKeyOptional)
|
|
}
|
|
|
|
assertUnset(unknownFeature)
|
|
}
|
|
|
|
// Do same basic sanity checks on features that are always present.
|
|
nodeFeatures := m.Get(SetNodeAnn)
|
|
|
|
assertSet := func(bit lnwire.FeatureBit) {
|
|
has := nodeFeatures.HasFeature(bit)
|
|
if !has {
|
|
t.Fatalf("node features don't advertised %v", bit)
|
|
}
|
|
}
|
|
|
|
assertSet(lnwire.DataLossProtectOptional)
|
|
if !test.cfg.NoTLVOnion {
|
|
assertSet(lnwire.TLVOnionPayloadRequired)
|
|
}
|
|
if !test.cfg.NoStaticRemoteKey {
|
|
assertSet(lnwire.StaticRemoteKeyOptional)
|
|
}
|
|
}
|