[#787] util/attributes: Return consistent list of attributes

Attributes are linked to each other through parents, so they can
be returned in any order. However, it will be better to return
the list in consistent order to reduce entropy.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-08-31 18:39:04 +03:00 committed by Alex Vanin
parent d8a04726ad
commit 2d7e9f0c40
2 changed files with 18 additions and 5 deletions

View file

@ -28,6 +28,7 @@ func ParseV2Attributes(attrs []string, excl []string) ([]*netmap.NodeAttribute,
} }
cache := make(map[string]*netmap.NodeAttribute, len(attrs)) cache := make(map[string]*netmap.NodeAttribute, len(attrs))
result := make([]*netmap.NodeAttribute, 0, len(attrs))
for i := range attrs { for i := range attrs {
line := strings.Trim(attrs[i], pairSeparator) line := strings.Trim(attrs[i], pairSeparator)
@ -67,6 +68,7 @@ func ParseV2Attributes(attrs []string, excl []string) ([]*netmap.NodeAttribute,
attribute.SetValue(value) attribute.SetValue(value)
cache[key] = attribute cache[key] = attribute
result = append(result, attribute)
} }
if parentKey != "" { if parentKey != "" {
@ -80,11 +82,6 @@ func ParseV2Attributes(attrs []string, excl []string) ([]*netmap.NodeAttribute,
} }
} }
result := make([]*netmap.NodeAttribute, 0, len(cache))
for _, v := range cache {
result = append(result, v)
}
return result, nil return result, nil
} }

View file

@ -94,4 +94,20 @@ func TestParseV2Attributes(t *testing.T) {
} }
require.True(t, flag) require.True(t, flag)
}) })
t.Run("consistent order in chain", func(t *testing.T) {
from := []string{"/a:1/b:2/c:3"}
for i := 0; i < 10000; i++ {
attrs, err := attributes.ParseV2Attributes(from, nil)
require.NoError(t, err)
require.Equal(t, attrs[0].Key(), "a")
require.Equal(t, attrs[0].Value(), "1")
require.Equal(t, attrs[1].Key(), "b")
require.Equal(t, attrs[1].Value(), "2")
require.Equal(t, attrs[2].Key(), "c")
require.Equal(t, attrs[2].Value(), "3")
}
})
} }