[#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>
remotes/fyrchik/meta-pebble
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))
result := make([]*netmap.NodeAttribute, 0, len(attrs))
for i := range attrs {
line := strings.Trim(attrs[i], pairSeparator)
@ -67,6 +68,7 @@ func ParseV2Attributes(attrs []string, excl []string) ([]*netmap.NodeAttribute,
attribute.SetValue(value)
cache[key] = attribute
result = append(result, attribute)
}
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
}

View File

@ -94,4 +94,20 @@ func TestParseV2Attributes(t *testing.T) {
}
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")
}
})
}