From c6f7ab3ef1bfa1dd92913efdbd3149eb65f2be3d Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Wed, 4 May 2022 20:11:22 +0300 Subject: [PATCH] [#399] container: Support homomorphic hash disabling Container could now have "__NEOFS__DISABLE_HOMOMORPHIC_HASHING" well-known attribute. Setting that to "true" means disabling homomorphic hashing for objects that belong to that container, any other cases mean that homomorphic hashing is enabled. Signed-off-by: Pavel Karpy --- container/attributes.go | 57 ++++++++++++++++++++++++++++++++++ container/attributes_test.go | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 container/attributes_test.go diff --git a/container/attributes.go b/container/attributes.go index 9f90edb..062e624 100644 --- a/container/attributes.go +++ b/container/attributes.go @@ -12,7 +12,64 @@ const ( // SysAttributeZone is a string of zone for container name. SysAttributeZone = SysAttributePrefix + "ZONE" + + // SysAttributeHomomorphicHashing is a container's homomorphic hashing state. + SysAttributeHomomorphicHashing = SysAttributePrefix + "DISABLE_HOMOMORPHIC_HASHING" ) // SysAttributeZoneDefault is a default value for SysAttributeZone attribute. const SysAttributeZoneDefault = "container" + +const disabledHomomorphicHashingValue = "true" + +// HomomorphicHashingState returns container's homomorphic +// hashing state: +// * true if hashing is enabled; +// * false if hashing is disabled. +// +// All container's attributes must be unique, otherwise behavior +// is undefined. +// +// See also SetHomomorphicHashingState. +func (c Container) HomomorphicHashingState() bool { + for i := range c.attr { + if c.attr[i].GetKey() == SysAttributeHomomorphicHashing { + return c.attr[i].GetValue() != disabledHomomorphicHashingValue + } + } + + return true +} + +// SetHomomorphicHashingState sets homomorphic hashing state for +// container. +// +// All container's attributes must be unique, otherwise behavior +// is undefined. +// +// See also HomomorphicHashingState. +func (c *Container) SetHomomorphicHashingState(enable bool) { + for i := range c.attr { + if c.attr[i].GetKey() == SysAttributeHomomorphicHashing { + if enable { + // approach without allocation/waste + // coping works since the attributes + // order is not important + c.attr[i] = c.attr[len(c.attr)-1] + c.attr = c.attr[:len(c.attr)-1] + } else { + c.attr[i].SetValue(disabledHomomorphicHashingValue) + } + + return + } + } + + if !enable { + attr := Attribute{} + attr.SetKey(SysAttributeHomomorphicHashing) + attr.SetValue(disabledHomomorphicHashingValue) + + c.attr = append(c.attr, attr) + } +} diff --git a/container/attributes_test.go b/container/attributes_test.go new file mode 100644 index 0000000..823445d --- /dev/null +++ b/container/attributes_test.go @@ -0,0 +1,59 @@ +package container_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/v2/container" + containertest "github.com/nspcc-dev/neofs-api-go/v2/container/test" + "github.com/stretchr/testify/require" +) + +func TestContainer_HomomorphicHashingDisabled(t *testing.T) { + cnr := containertest.GenerateContainer(false) + + t.Run("defaults", func(t *testing.T) { + require.True(t, cnr.HomomorphicHashingState()) + }) + + t.Run("disabled", func(t *testing.T) { + attr := container.Attribute{} + attr.SetKey(container.SysAttributeHomomorphicHashing) + attr.SetValue("NOT_true") + + cnr.SetAttributes(append(cnr.GetAttributes(), attr)) + require.True(t, cnr.HomomorphicHashingState()) + + attr.SetValue("true") + + cnr.SetAttributes([]container.Attribute{attr}) + require.False(t, cnr.HomomorphicHashingState()) + }) +} + +func TestContainer_SetHomomorphicHashingState(t *testing.T) { + cnr := containertest.GenerateContainer(false) + attrs := cnr.GetAttributes() + attrLen := len(attrs) + + cnr.SetHomomorphicHashingState(true) + + // enabling hashing should not add any new attributes + require.Equal(t, attrLen, len(cnr.GetAttributes())) + require.True(t, cnr.HomomorphicHashingState()) + + cnr.SetHomomorphicHashingState(false) + + // disabling hashing should add exactly one attribute + require.Equal(t, attrLen+1, len(cnr.GetAttributes())) + require.False(t, cnr.HomomorphicHashingState()) + + cnr.SetHomomorphicHashingState(true) + + // enabling hashing should remove 1 attribute if + // hashing was disabled before + require.Equal(t, attrLen, len(cnr.GetAttributes())) + require.True(t, cnr.HomomorphicHashingState()) + + // hashing operations should not change any other attributes + require.ElementsMatch(t, attrs, cnr.GetAttributes()) +}