From cee957e85a401a4e7c7415737bf526ee8b24f7dd Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Tue, 27 Aug 2024 12:03:05 +0300 Subject: [PATCH] [#105] policy: Add ListChainNames method Signed-off-by: Denis Kirillov --- policy/config.yml | 1 + policy/policy_contract.go | 8 ++++++++ rpcclient/policy/client.go | 14 ++++++++++++++ tests/policy_test.go | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/policy/config.yml b/policy/config.yml index 4e1163b..921d853 100644 --- a/policy/config.yml +++ b/policy/config.yml @@ -7,5 +7,6 @@ safemethods: - "getChain" - "listChainsByPrefix" - "listTargets" + - "listChainNames" - "iteratorChainsByPrefix" - "version" \ No newline at end of file diff --git a/policy/policy_contract.go b/policy/policy_contract.go index 39bb0ce..8959859 100644 --- a/policy/policy_contract.go +++ b/policy/policy_contract.go @@ -256,3 +256,11 @@ func ListTargets(entity Kind) iterator.Iterator { mKey := mapKey(entity, []byte{}) return storage.Find(ctx, mKey, storage.KeysOnly|storage.RemovePrefix) } + +// ListChainNames iterates over chain names for specific target. +func ListChainNames(entity Kind, entityName string) iterator.Iterator { + ctx := storage.GetReadOnlyContext() + id, _ := mapToNumeric(ctx, entity, []byte(entityName)) + keyPrefix := storageKey(entity, id, []byte{}) + return storage.Find(ctx, keyPrefix, storage.KeysOnly|storage.RemovePrefix) +} diff --git a/rpcclient/policy/client.go b/rpcclient/policy/client.go index cffad49..36d1e5f 100644 --- a/rpcclient/policy/client.go +++ b/rpcclient/policy/client.go @@ -80,6 +80,20 @@ func (c *ContractReader) IteratorChainsByPrefixExpanded(entity *big.Int, entityN return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "iteratorChainsByPrefix", _numOfIteratorItems, entity, entityName, prefix)) } +// ListChainNames invokes `listChainNames` method of contract. +func (c *ContractReader) ListChainNames(entity *big.Int, entityName string) (uuid.UUID, result.Iterator, error) { + return unwrap.SessionIterator(c.invoker.Call(c.hash, "listChainNames", entity, entityName)) +} + +// ListChainNamesExpanded is similar to ListChainNames (uses the same contract +// method), but can be useful if the server used doesn't support sessions and +// doesn't expand iterators. It creates a script that will get the specified +// number of result items from the iterator right in the VM and return them to +// you. It's only limited by VM stack and GAS available for RPC invocations. +func (c *ContractReader) ListChainNamesExpanded(entity *big.Int, entityName string, _numOfIteratorItems int) ([]stackitem.Item, error) { + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "listChainNames", _numOfIteratorItems, entity, entityName)) +} + // ListChains invokes `listChains` method of contract. func (c *ContractReader) ListChains(namespace string, container string, name []byte) ([]stackitem.Item, error) { return unwrap.Array(c.invoker.Call(c.hash, "listChains", namespace, container, name)) diff --git a/tests/policy_test.go b/tests/policy_test.go index 6690a1a..1355c5a 100644 --- a/tests/policy_test.go +++ b/tests/policy_test.go @@ -66,6 +66,7 @@ func TestPolicy(t *testing.T) { checkChains(t, e, "mynamespace", "cnr1", "ingress", [][]byte{p1, p2, p33}) // Override chain. checkChainsByPrefix(t, e, policy.Container, "cnr1", "", [][]byte{p2, p33}) checkChainsByPrefix(t, e, policy.IAM, "", "", nil) + checkChainKeys(t, e, policy.Container, "cnr1", []string{"ingress:myrule2", "ingress:myrule3"}) checkChainsIteratorByPrefix(t, e, policy.Container, "cnr1", "ingress:myrule3", [][]byte{p33}) checkChainsIteratorByPrefix(t, e, policy.Container, "cnr1", "ingress", [][]byte{p2, p33}) @@ -151,6 +152,25 @@ func checkChainsIteratorByPrefix(t *testing.T, e *neotest.ContractInvoker, kind } } +func checkChainKeys(t *testing.T, e *neotest.ContractInvoker, kind byte, entityName string, expected []string) { + s, err := e.TestInvoke(t, "listChainNames", kind, entityName) + require.NoError(t, err) + + if s.Len() == 0 { + t.Fatal("Stack is empty") + } + + iteratorItem := s.Pop().Value().(*storage.Iterator) + policys := iteratorToArray(iteratorItem) + require.Equal(t, len(expected), len(policys)) + + for i := range expected { + bytesPolicy, err := policys[i].TryBytes() + require.NoError(t, err) + require.Equal(t, expected[i], string(bytesPolicy)) + } +} + func checksChainsOnStack(t *testing.T, s *vm.Stack, expected [][]byte) { require.Equal(t, 1, s.Len())