forked from TrueCloudLab/frostfs-contract
[#242] container: allow to fetch total amount of countainers
There are 2 approaches: 1. Use `storage.Find` to enumerate all containers. 2. Store a counter by a separate key. Here we implemented 1, because this method is readonly (thus GAS cost it not a problem) and simpler to implement. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
335b04d9a6
commit
f1f2101dc6
3 changed files with 49 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
||||||
name: "NeoFS Container"
|
name: "NeoFS Container"
|
||||||
safemethods: ["get", "owner", "list", "eACL", "getContainerSize", "listContainerSizes", "version"]
|
safemethods: ["count", "get", "owner", "list", "eACL", "getContainerSize", "listContainerSizes", "version"]
|
||||||
permissions:
|
permissions:
|
||||||
- methods: ["update", "addKey", "transferX",
|
- methods: ["update", "addKey", "transferX",
|
||||||
"addRoot", "register", "addRecord", "deleteRecords"]
|
"addRoot", "register", "addRecord", "deleteRecords"]
|
||||||
|
|
|
@ -387,6 +387,21 @@ func Owner(containerID []byte) []byte {
|
||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count method returns the number of registered containers.
|
||||||
|
func Count() int {
|
||||||
|
count := 0
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
it := storage.Find(ctx, []byte{}, storage.KeysOnly)
|
||||||
|
for iterator.Next(it) {
|
||||||
|
key := iterator.Value(it).([]byte)
|
||||||
|
// V2 format
|
||||||
|
if len(key) == containerIDSize {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
// List method returns a list of all container IDs owned by the specified owner.
|
// List method returns a list of all container IDs owned by the specified owner.
|
||||||
func List(owner []byte) [][]byte {
|
func List(owner []byte) [][]byte {
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
|
|
@ -79,6 +79,39 @@ func dummyContainer(owner neotest.Signer) testContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContainerCount(t *testing.T) {
|
||||||
|
c, cBal, _ := newContainerInvoker(t)
|
||||||
|
|
||||||
|
checkCount := func(t *testing.T, expected int64) {
|
||||||
|
s, err := c.TestInvoke(t, "count")
|
||||||
|
require.NoError(t, err)
|
||||||
|
bi := s.Pop().BigInt()
|
||||||
|
require.True(t, bi.IsInt64())
|
||||||
|
require.Equal(t, int64(expected), bi.Int64())
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCount(t, 0)
|
||||||
|
acc1, cnt1 := addContainer(t, c, cBal)
|
||||||
|
checkCount(t, 1)
|
||||||
|
|
||||||
|
_, cnt2 := addContainer(t, c, cBal)
|
||||||
|
checkCount(t, 2)
|
||||||
|
|
||||||
|
// Same owner.
|
||||||
|
cnt3 := dummyContainer(acc1)
|
||||||
|
balanceMint(t, cBal, acc1, containerFee*1, []byte{})
|
||||||
|
c.Invoke(t, stackitem.Null{}, "put", cnt3.value, cnt3.sig, cnt3.pub, cnt3.token)
|
||||||
|
|
||||||
|
c.Invoke(t, stackitem.Null{}, "delete", cnt1.id[:], cnt1.sig, cnt1.token)
|
||||||
|
checkCount(t, 2)
|
||||||
|
|
||||||
|
c.Invoke(t, stackitem.Null{}, "delete", cnt2.id[:], cnt2.sig, cnt2.token)
|
||||||
|
checkCount(t, 1)
|
||||||
|
|
||||||
|
c.Invoke(t, stackitem.Null{}, "delete", cnt3.id[:], cnt3.sig, cnt3.token)
|
||||||
|
checkCount(t, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func TestContainerPut(t *testing.T) {
|
func TestContainerPut(t *testing.T) {
|
||||||
c, cBal, _ := newContainerInvoker(t)
|
c, cBal, _ := newContainerInvoker(t)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue