From 12d203ff93359d80508a17556579bc8c79b88ee1 Mon Sep 17 00:00:00 2001 From: Vladimir Domnich Date: Wed, 2 Aug 2023 11:29:50 +0400 Subject: [PATCH] [#33] Add IterateContainers method Signed-off-by: Vladimir Domnich --- container/config.yml | 2 +- container/container_contract.go | 10 ++++++++++ tests/container_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/container/config.yml b/container/config.yml index 0e885ba..99258b4 100644 --- a/container/config.yml +++ b/container/config.yml @@ -1,5 +1,5 @@ name: "Container" -safemethods: ["count", "containersOf", "get", "owner", "list", "eACL", "getContainerSize", "listContainerSizes", "iterateContainerSizes", "version"] +safemethods: ["count", "containersOf", "get", "owner", "list", "iterateContainers", "eACL", "getContainerSize", "listContainerSizes", "iterateContainerSizes", "version"] permissions: - methods: ["update", "addKey", "transferX", "register", "addRecord", "deleteRecords"] diff --git a/container/container_contract.go b/container/container_contract.go index 5cde579..8270123 100644 --- a/container/container_contract.go +++ b/container/container_contract.go @@ -404,6 +404,16 @@ func List(owner []byte) [][]byte { return list } +// IterateContainers iterates over all containers. Iterator values are structures that contain a +// stable marshaled Container structure, the signature, the public key of the container creator and +// a stable marshaled SessionToken structure if it was provided. +func IterateContainers() iterator.Iterator { + ctx := storage.GetReadOnlyContext() + + key := []byte{containerKeyPrefix} + return storage.Find(ctx, key, storage.ValuesOnly|storage.DeserializeValues) +} + // SetEACL method sets a new extended ACL table related to the contract // if it was invoked by Alphabet nodes of the Inner Ring. // diff --git a/tests/container_test.go b/tests/container_test.go index 9fe8431..ac09f45 100644 --- a/tests/container_test.go +++ b/tests/container_test.go @@ -142,6 +142,7 @@ func checkContainerList(t *testing.T, c *neotest.ContractInvoker, expected [][]b } require.ElementsMatch(t, expected, actual) }) + t.Run("check with `containersOf`", func(t *testing.T) { s, err := c.TestInvoke(t, "containersOf", nil) require.NoError(t, err) @@ -159,6 +160,29 @@ func checkContainerList(t *testing.T, c *neotest.ContractInvoker, expected [][]b require.ElementsMatch(t, expected, actual) }) + t.Run("check with `iterateContainers`", func(t *testing.T) { + s, err := c.TestInvoke(t, "iterateContainers") + require.NoError(t, err) + require.Equal(t, 1, s.Len()) + + iter, ok := s.Top().Value().(*storage.Iterator) + require.True(t, ok) + + // Iterator contains pairs: key + estimation (as stack item), we extract estimations only + actualIds := make([][]byte, 0, len(expected)) + for iter.Next() { + // Parse iterator value into container fields and extract container value which is 1st field + containerFields, ok := iter.Value().Value().([]stackitem.Item) + require.True(t, ok) + require.Len(t, containerFields, 4) + containerValue, err := containerFields[0].TryBytes() + require.NoError(t, err) + + containerId := sha256.Sum256(containerValue) + actualIds = append(actualIds, containerId[:]) + } + require.ElementsMatch(t, expected, actualIds) + }) } func TestContainerPut(t *testing.T) { -- 2.45.2