From 13ef60b035057e26ce2daee4a479537bcf830716 Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Tue, 24 Dec 2024 00:50:00 +0300 Subject: [PATCH 1/4] container/meta: make `validuntil` camel-cased Follows https://github.com/nspcc-dev/neofs-node/pull/3063. Signed-off-by: Pavel Karpy --- contracts/container/contract.go | 2 +- contracts/container/contract.nef | Bin 9078 -> 9078 bytes tests/container_test.go | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/container/contract.go b/contracts/container/contract.go index 178225ca..2f578897 100644 --- a/contracts/container/contract.go +++ b/contracts/container/contract.go @@ -276,7 +276,7 @@ func SubmitObjectPut(metaInformation []byte, sigs [][]interop.Signature) { panic("incorrect " + std.Itoa10(i) + " locked object") } } - vub := getFromMap(metaMap, "validuntil").(int) + vub := getFromMap(metaMap, "validUntil").(int) if vub <= ledger.CurrentIndex() { panic("incorrect vub: exceeded") } diff --git a/contracts/container/contract.nef b/contracts/container/contract.nef index 4ea96d7262a33b1cec6cd1504f0f467d74089018..14d7ff4d02464ab46191f026b54caec456c4c1fb 100755 GIT binary patch delta 19 bcmez7_RVdBBoAZgW+|QsahC7(m!<#!PSXd> delta 19 acmez7_RVdBBoAZhW+|QsaTfc;kJ|xFS_fDF diff --git a/tests/container_test.go b/tests/container_test.go index f2007dc2..5e4ff019 100644 --- a/tests/container_test.go +++ b/tests/container_test.go @@ -876,7 +876,7 @@ func TestPutMeta(t *testing.T) { testFunc("size") testFunc("deleted") testFunc("locked") - testFunc("validuntil") + testFunc("validUntil") }) t.Run("incorrect values", func(t *testing.T) { @@ -893,7 +893,7 @@ func TestPutMeta(t *testing.T) { testFunc("network", netmode.UnitTestNet+1) testFunc("deleted", []any{[]byte{1}}) testFunc("locked", []any{[]byte{1}}) - testFunc("validuntil", 1) // tested chain will have some blocks for sure + testFunc("validUntil", 1) // tested chain will have some blocks for sure }) }) } @@ -907,6 +907,6 @@ func testMeta(cid, oid []byte) *stackitem.Map { {Key: stackitem.Make("size"), Value: stackitem.Make(123)}, {Key: stackitem.Make("deleted"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, {Key: stackitem.Make("locked"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, - {Key: stackitem.Make("validuntil"), Value: stackitem.Make(math.MaxInt)}, + {Key: stackitem.Make("validUntil"), Value: stackitem.Make(math.MaxInt)}, }) } From 9be399409c84204d55f8235ecf3b8599d17cc5de Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Tue, 24 Dec 2024 00:48:27 +0300 Subject: [PATCH 2/4] container/meta: support metadata with for "big" objects Follows https://github.com/nspcc-dev/neofs-node/pull/3063. Signed-off-by: Pavel Karpy --- contracts/container/contract.go | 8 ++++++++ contracts/container/contract.nef | Bin 9078 -> 9264 bytes contracts/container/manifest.json | 2 +- tests/container_test.go | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/contracts/container/contract.go b/contracts/container/contract.go index 2f578897..75a321b5 100644 --- a/contracts/container/contract.go +++ b/contracts/container/contract.go @@ -259,6 +259,14 @@ func SubmitObjectPut(metaInformation []byte, sigs [][]interop.Signature) { if len(oID) != interop.Hash256Len { panic("incorrect object ID") } + firstPart := getFromMap(metaMap, "firstPart").(interop.Hash256) + if len(firstPart) != interop.Hash256Len && len(firstPart) != 0 { + panic("incorrect first part object ID") + } + previousPart := getFromMap(metaMap, "previousPart").(interop.Hash256) + if len(previousPart) != interop.Hash256Len && len(previousPart) != 0 { + panic("incorrect previousPart part object ID") + } magic := getFromMap(metaMap, "network").(int) if magic != runtime.GetNetwork() { panic("incorrect network magic") diff --git a/contracts/container/contract.nef b/contracts/container/contract.nef index 14d7ff4d02464ab46191f026b54caec456c4c1fb..36fe7164f8074c5451d601beaf9285f003112d64 100755 GIT binary patch delta 532 zcmez7w!veA8584|&E`x$*ctgJ8*qs-@i0$z=W1taW}19~%b=b!EwiY&Bp|VoExl_C!c5XEp91B?#W-d z&6#=gc_-`h1o83laQcITB%rh;pKo(NPaz}M)^Gp+mvd&CcK_JS#V5tcvEs-7|5>JW z-#6>&ep6 zvl$gOZXyv?9C(TeZbWfXc${gesVU*ta}U~ zTft_PbL4YCOmp-q=L8$amCuFKxO~pZ>v_zXx%0UvzvKzxxLSuD-T0 Qn}|K0KC4ErT_o{ diff --git a/contracts/container/manifest.json b/contracts/container/manifest.json index dac86e23..0824e27f 100755 --- a/contracts/container/manifest.json +++ b/contracts/container/manifest.json @@ -1 +1 @@ -{"name":"NeoFS Container","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":83,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"addNextEpochNodes","offset":4717,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"},{"name":"publicKeys","type":"Array"}],"returntype":"Void","safe":false},{"name":"alias","offset":4427,"parameters":[{"name":"cid","type":"ByteArray"}],"returntype":"String","safe":true},{"name":"commitContainerListUpdate","offset":5483,"parameters":[{"name":"cID","type":"Hash256"},{"name":"replicas","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"containersOf","offset":4567,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"InteropInterface","safe":true},{"name":"count","offset":4522,"parameters":[],"returntype":"Integer","safe":true},{"name":"delete","offset":3924,"parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"eACL","offset":6419,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"get","offset":4314,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"getContainerSize","offset":6679,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"iterateAllContainerSizes","offset":7052,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"iterateContainerSizes","offset":6954,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"list","offset":4621,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listContainerSizes","offset":6793,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"newEpoch","offset":7104,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"nodes","offset":6042,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"onNEP11Payment","offset":1647,"parameters":[{"name":"a","type":"Hash160"},{"name":"b","type":"Integer"},{"name":"c","type":"ByteArray"},{"name":"d","type":"Any"}],"returntype":"Void","safe":false},{"name":"owner","offset":4376,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"put","offset":2753,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"putContainerSize","offset":6477,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"usedSize","type":"Integer"},{"name":"pubKey","type":"PublicKey"}],"returntype":"Void","safe":false},{"name":"put","offset":2690,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"},{"name":"metaOnChain","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"putNamed","offset":2783,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"put","offset":2769,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"replicasNumbers","offset":5944,"parameters":[{"name":"cID","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"setEACL","offset":6166,"parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"startContainerEstimation","offset":7127,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"stopContainerEstimation","offset":7201,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"submitObjectPut","offset":2038,"parameters":[{"name":"metaInformation","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Void","safe":false},{"name":"update","offset":1905,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"verifyPlacementSignatures","offset":5315,"parameters":[{"name":"cid","type":"Hash256"},{"name":"msg","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Boolean","safe":true},{"name":"version","offset":7274,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"PutSuccess","parameters":[{"name":"containerID","type":"Hash256"},{"name":"publicKey","type":"PublicKey"}]},{"name":"DeleteSuccess","parameters":[{"name":"containerID","type":"ByteArray"}]},{"name":"SetEACLSuccess","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"publicKey","type":"PublicKey"}]},{"name":"StartEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"StopEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"NodesUpdate","parameters":[{"name":"ContainerID","type":"Hash256"}]},{"name":"ObjectPut","parameters":[{"name":"ContainerID","type":"Hash256"},{"name":"ObjectID","type":"Hash256"},{"name":"Meta","type":"Map"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","addKey","transferX","register","registerTLD","addRecord","deleteRecords","subscribeForNewEpoch"]}],"supportedstandards":[],"trusts":[],"extra":null} \ No newline at end of file +{"name":"NeoFS Container","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":83,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"addNextEpochNodes","offset":4903,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"},{"name":"publicKeys","type":"Array"}],"returntype":"Void","safe":false},{"name":"alias","offset":4613,"parameters":[{"name":"cid","type":"ByteArray"}],"returntype":"String","safe":true},{"name":"commitContainerListUpdate","offset":5669,"parameters":[{"name":"cID","type":"Hash256"},{"name":"replicas","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"containersOf","offset":4753,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"InteropInterface","safe":true},{"name":"count","offset":4708,"parameters":[],"returntype":"Integer","safe":true},{"name":"delete","offset":4110,"parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"eACL","offset":6605,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"get","offset":4500,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"getContainerSize","offset":6865,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"iterateAllContainerSizes","offset":7238,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"iterateContainerSizes","offset":7140,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"list","offset":4807,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listContainerSizes","offset":6979,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"newEpoch","offset":7290,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"nodes","offset":6228,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"onNEP11Payment","offset":1647,"parameters":[{"name":"a","type":"Hash160"},{"name":"b","type":"Integer"},{"name":"c","type":"ByteArray"},{"name":"d","type":"Any"}],"returntype":"Void","safe":false},{"name":"owner","offset":4562,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"put","offset":2939,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"putContainerSize","offset":6663,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"usedSize","type":"Integer"},{"name":"pubKey","type":"PublicKey"}],"returntype":"Void","safe":false},{"name":"put","offset":2876,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"},{"name":"metaOnChain","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"putNamed","offset":2969,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"put","offset":2955,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"replicasNumbers","offset":6130,"parameters":[{"name":"cID","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"setEACL","offset":6352,"parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"startContainerEstimation","offset":7313,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"stopContainerEstimation","offset":7387,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"submitObjectPut","offset":2038,"parameters":[{"name":"metaInformation","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Void","safe":false},{"name":"update","offset":1905,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"verifyPlacementSignatures","offset":5501,"parameters":[{"name":"cid","type":"Hash256"},{"name":"msg","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Boolean","safe":true},{"name":"version","offset":7460,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"PutSuccess","parameters":[{"name":"containerID","type":"Hash256"},{"name":"publicKey","type":"PublicKey"}]},{"name":"DeleteSuccess","parameters":[{"name":"containerID","type":"ByteArray"}]},{"name":"SetEACLSuccess","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"publicKey","type":"PublicKey"}]},{"name":"StartEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"StopEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"NodesUpdate","parameters":[{"name":"ContainerID","type":"Hash256"}]},{"name":"ObjectPut","parameters":[{"name":"ContainerID","type":"Hash256"},{"name":"ObjectID","type":"Hash256"},{"name":"Meta","type":"Map"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","addKey","transferX","register","registerTLD","addRecord","deleteRecords","subscribeForNewEpoch"]}],"supportedstandards":[],"trusts":[],"extra":null} \ No newline at end of file diff --git a/tests/container_test.go b/tests/container_test.go index 5e4ff019..8389207a 100644 --- a/tests/container_test.go +++ b/tests/container_test.go @@ -872,6 +872,8 @@ func TestPutMeta(t *testing.T) { testFunc("cid") testFunc("oid") + testFunc("firstPart") + testFunc("previousPart") testFunc("network") testFunc("size") testFunc("deleted") @@ -890,6 +892,8 @@ func TestPutMeta(t *testing.T) { testFunc("cid", []byte{1}) testFunc("oid", []byte{1}) + testFunc("firstPart", []byte{1}) + testFunc("previousPart", []byte{1}) testFunc("network", netmode.UnitTestNet+1) testFunc("deleted", []any{[]byte{1}}) testFunc("locked", []any{[]byte{1}}) @@ -904,6 +908,8 @@ func testMeta(cid, oid []byte) *stackitem.Map { {Key: stackitem.Make("network"), Value: stackitem.Make(netmode.UnitTestNet)}, {Key: stackitem.Make("cid"), Value: stackitem.Make(cid)}, {Key: stackitem.Make("oid"), Value: stackitem.Make(oid)}, + {Key: stackitem.Make("firstPart"), Value: stackitem.Make(oid)}, + {Key: stackitem.Make("previousPart"), Value: stackitem.Make(oid)}, {Key: stackitem.Make("size"), Value: stackitem.Make(123)}, {Key: stackitem.Make("deleted"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, {Key: stackitem.Make("locked"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, From cd9ea5af8f377aa9aa28e2b4eee9459d6add7ba2 Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Wed, 25 Dec 2024 18:31:36 +0300 Subject: [PATCH 3/4] container/meta: allow skipping unnecessary meta fields They are: first and previous parts in object split chains for small objects; locked, deleted objects for REGULAR objects. Signed-off-by: Pavel Karpy --- contracts/container/contract.go | 73 ++++++++++++++++++++---------- contracts/container/contract.nef | Bin 9264 -> 9293 bytes contracts/container/manifest.json | 2 +- tests/container_test.go | 13 ++---- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/contracts/container/contract.go b/contracts/container/contract.go index 75a321b5..d64f1f69 100644 --- a/contracts/container/contract.go +++ b/contracts/container/contract.go @@ -248,45 +248,59 @@ func Update(script []byte, manifest []byte, data any) { // created using [Put] ([PutMeta]) with enabled meta-on-chain option. func SubmitObjectPut(metaInformation []byte, sigs [][]interop.Signature) { metaMap := std.Deserialize(metaInformation).(map[string]any) - cID := getFromMap(metaMap, "cid").(interop.Hash256) + + // required + + cID := requireMapValue(metaMap, "cid").(interop.Hash256) if len(cID) != interop.Hash256Len { panic("incorrect container ID") } if storage.Get(storage.GetContext(), append([]byte{containersWithMetaPrefix}, cID...)) == nil { panic("container does not support meta-on-chain") } - oID := getFromMap(metaMap, "oid").(interop.Hash256) + oID := requireMapValue(metaMap, "oid").(interop.Hash256) if len(oID) != interop.Hash256Len { panic("incorrect object ID") } - firstPart := getFromMap(metaMap, "firstPart").(interop.Hash256) - if len(firstPart) != interop.Hash256Len && len(firstPart) != 0 { - panic("incorrect first part object ID") - } - previousPart := getFromMap(metaMap, "previousPart").(interop.Hash256) - if len(previousPart) != interop.Hash256Len && len(previousPart) != 0 { - panic("incorrect previousPart part object ID") + _ = requireMapValue(metaMap, "size").(int) + vub := requireMapValue(metaMap, "validUntil").(int) + if vub <= ledger.CurrentIndex() { + panic("incorrect vub: exceeded") } - magic := getFromMap(metaMap, "network").(int) + magic := requireMapValue(metaMap, "network").(int) if magic != runtime.GetNetwork() { panic("incorrect network magic") } - _ = getFromMap(metaMap, "size").(int) - deleted := getFromMap(metaMap, "deleted").([]interop.Hash256) - for i, d := range deleted { - if len(d) != interop.Hash256Len { - panic("incorrect " + std.Itoa10(i) + " deleted object") + + // optional + + if v, ok := getFromMap(metaMap, "firstPart"); ok { + firstPart := v.(interop.Hash256) + if len(firstPart) != interop.Hash256Len { + panic("incorrect first part object ID") } } - locked := getFromMap(metaMap, "locked").([]interop.Hash256) - for i, l := range locked { - if len(l) != interop.Hash256Len { - panic("incorrect " + std.Itoa10(i) + " locked object") + if v, ok := getFromMap(metaMap, "previousPart"); ok { + previousPart := v.(interop.Hash256) + if len(previousPart) != interop.Hash256Len { + panic("incorrect previous part object ID") } } - vub := getFromMap(metaMap, "validUntil").(int) - if vub <= ledger.CurrentIndex() { - panic("incorrect vub: exceeded") + if v, ok := getFromMap(metaMap, "locked"); ok { + locked := v.([]interop.Hash256) + for i, l := range locked { + if len(l) != interop.Hash256Len { + panic("incorrect " + std.Itoa10(i) + " locked object") + } + } + } + if v, ok := getFromMap(metaMap, "deleted"); ok { + deleted := v.([]interop.Hash256) + for i, d := range deleted { + if len(d) != interop.Hash256Len { + panic("incorrect " + std.Itoa10(i) + " deleted object") + } + } } if !VerifyPlacementSignatures(cID, metaInformation, sigs) { @@ -296,12 +310,21 @@ func SubmitObjectPut(metaInformation []byte, sigs [][]interop.Signature) { runtime.Notify("ObjectPut", cID, oID, metaMap) } -func getFromMap(m map[string]any, key string) any { - if !neogointernal.Opcode2("HASKEY", m, key).(bool) { // https://github.com/nspcc-dev/neo-go/issues/3716 +func requireMapValue(m map[string]any, key string) any { + v, ok := getFromMap(m, key) + if !ok { panic("'" + key + "'" + " not found") } - return m[key] + return v +} + +func getFromMap(m map[string]any, key string) (any, bool) { + if neogointernal.Opcode2("HASKEY", m, key).(bool) { // https://github.com/nspcc-dev/neo-go/issues/3716 + return m[key], true + } + + return nil, false } // PutMeta is the same as [Put] and [PutNamed] (and exposed as put from diff --git a/contracts/container/contract.nef b/contracts/container/contract.nef index 36fe7164f8074c5451d601beaf9285f003112d64..4ebc2c0687c10dfcaf181622b1be4aae29da38ed 100755 GIT binary patch delta 630 zcmY+8O=#0#7=ZJoUDKprf7jN{&9&WT^rCjMhz<{_SltrD=#(lRq_!E&+U4uov}vax zcp4Oi@u7Gaf(H){#6iHzCW6DuWbMHnRy>N}U}yCf)5)k_-oyJoJkPs2xiz_Zh9v#N z##!4K8IscK3=;?8wX zS^@9ENPiAes;ud#l$SWry;kP%mTTlBJ)@M$nv^bS61N8kqN-DfV$Z8WJ8tRYx)V8t zozb4nVSCa?MDdtw{NXbT(`lVS49g?>0CXYOKj3i|#uPP!N+mg?MT;f5s-Q|aTC_S* zbZ@q^oVqxXgN_2qE$sh(&nBq15Wr z+&cESPl#biU)_IKs%R)IC7uG5=2IkDt4rgt;=HoL_Cs*2-mpdkGEo(2(HT@xvyF)y zpCT;mGfO#Z^(IfdjI#SOpr8LVO`TRa)!6V10IKoZG-tWA@!h)yzy^Nle-B*7-N2#^ zJTiWS)=BWmc-7~z#oq0i=KY0wE%>2wN7!L|l90$ZsyTJ;qj0UYJvB6`5857eN#myE>-`N@YCmV2yGV)AzG)M3RG_-hBGxL)3 zi;7Z{OB4!nr zKA5~ua4)0A<{F_6X2$uOS;h7+F+SRSNP>@<@$%%0((;TMlRrw&VN}@MC*#c|bn4~* z{}~klrsr807#zYG8BKRiel6$8m_ON6ej>-D=l}l$1(_!|$SZDsFTb0aaoyzA%JWzh IGs~U<0J?U{z5oCK diff --git a/contracts/container/manifest.json b/contracts/container/manifest.json index 0824e27f..9afa1c14 100755 --- a/contracts/container/manifest.json +++ b/contracts/container/manifest.json @@ -1 +1 @@ -{"name":"NeoFS Container","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":83,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"addNextEpochNodes","offset":4903,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"},{"name":"publicKeys","type":"Array"}],"returntype":"Void","safe":false},{"name":"alias","offset":4613,"parameters":[{"name":"cid","type":"ByteArray"}],"returntype":"String","safe":true},{"name":"commitContainerListUpdate","offset":5669,"parameters":[{"name":"cID","type":"Hash256"},{"name":"replicas","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"containersOf","offset":4753,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"InteropInterface","safe":true},{"name":"count","offset":4708,"parameters":[],"returntype":"Integer","safe":true},{"name":"delete","offset":4110,"parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"eACL","offset":6605,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"get","offset":4500,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"getContainerSize","offset":6865,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"iterateAllContainerSizes","offset":7238,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"iterateContainerSizes","offset":7140,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"list","offset":4807,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listContainerSizes","offset":6979,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"newEpoch","offset":7290,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"nodes","offset":6228,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"onNEP11Payment","offset":1647,"parameters":[{"name":"a","type":"Hash160"},{"name":"b","type":"Integer"},{"name":"c","type":"ByteArray"},{"name":"d","type":"Any"}],"returntype":"Void","safe":false},{"name":"owner","offset":4562,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"put","offset":2939,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"putContainerSize","offset":6663,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"usedSize","type":"Integer"},{"name":"pubKey","type":"PublicKey"}],"returntype":"Void","safe":false},{"name":"put","offset":2876,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"},{"name":"metaOnChain","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"putNamed","offset":2969,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"put","offset":2955,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"replicasNumbers","offset":6130,"parameters":[{"name":"cID","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"setEACL","offset":6352,"parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"startContainerEstimation","offset":7313,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"stopContainerEstimation","offset":7387,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"submitObjectPut","offset":2038,"parameters":[{"name":"metaInformation","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Void","safe":false},{"name":"update","offset":1905,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"verifyPlacementSignatures","offset":5501,"parameters":[{"name":"cid","type":"Hash256"},{"name":"msg","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Boolean","safe":true},{"name":"version","offset":7460,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"PutSuccess","parameters":[{"name":"containerID","type":"Hash256"},{"name":"publicKey","type":"PublicKey"}]},{"name":"DeleteSuccess","parameters":[{"name":"containerID","type":"ByteArray"}]},{"name":"SetEACLSuccess","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"publicKey","type":"PublicKey"}]},{"name":"StartEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"StopEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"NodesUpdate","parameters":[{"name":"ContainerID","type":"Hash256"}]},{"name":"ObjectPut","parameters":[{"name":"ContainerID","type":"Hash256"},{"name":"ObjectID","type":"Hash256"},{"name":"Meta","type":"Map"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","addKey","transferX","register","registerTLD","addRecord","deleteRecords","subscribeForNewEpoch"]}],"supportedstandards":[],"trusts":[],"extra":null} \ No newline at end of file +{"name":"NeoFS Container","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":83,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"addNextEpochNodes","offset":4932,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"},{"name":"publicKeys","type":"Array"}],"returntype":"Void","safe":false},{"name":"alias","offset":4642,"parameters":[{"name":"cid","type":"ByteArray"}],"returntype":"String","safe":true},{"name":"commitContainerListUpdate","offset":5698,"parameters":[{"name":"cID","type":"Hash256"},{"name":"replicas","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"containersOf","offset":4782,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"InteropInterface","safe":true},{"name":"count","offset":4737,"parameters":[],"returntype":"Integer","safe":true},{"name":"delete","offset":4139,"parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"eACL","offset":6634,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"get","offset":4529,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"getContainerSize","offset":6894,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"iterateAllContainerSizes","offset":7267,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"iterateContainerSizes","offset":7169,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"list","offset":4836,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listContainerSizes","offset":7008,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"newEpoch","offset":7319,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"nodes","offset":6257,"parameters":[{"name":"cID","type":"Hash256"},{"name":"placementVector","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"onNEP11Payment","offset":1647,"parameters":[{"name":"a","type":"Hash160"},{"name":"b","type":"Integer"},{"name":"c","type":"ByteArray"},{"name":"d","type":"Any"}],"returntype":"Void","safe":false},{"name":"owner","offset":4591,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"put","offset":2968,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"putContainerSize","offset":6692,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"usedSize","type":"Integer"},{"name":"pubKey","type":"PublicKey"}],"returntype":"Void","safe":false},{"name":"put","offset":2905,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"},{"name":"metaOnChain","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"putNamed","offset":2998,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"put","offset":2984,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"replicasNumbers","offset":6159,"parameters":[{"name":"cID","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"setEACL","offset":6381,"parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"startContainerEstimation","offset":7342,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"stopContainerEstimation","offset":7416,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"submitObjectPut","offset":2038,"parameters":[{"name":"metaInformation","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Void","safe":false},{"name":"update","offset":1905,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"verifyPlacementSignatures","offset":5530,"parameters":[{"name":"cid","type":"Hash256"},{"name":"msg","type":"ByteArray"},{"name":"sigs","type":"Array"}],"returntype":"Boolean","safe":true},{"name":"version","offset":7489,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"PutSuccess","parameters":[{"name":"containerID","type":"Hash256"},{"name":"publicKey","type":"PublicKey"}]},{"name":"DeleteSuccess","parameters":[{"name":"containerID","type":"ByteArray"}]},{"name":"SetEACLSuccess","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"publicKey","type":"PublicKey"}]},{"name":"StartEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"StopEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"NodesUpdate","parameters":[{"name":"ContainerID","type":"Hash256"}]},{"name":"ObjectPut","parameters":[{"name":"ContainerID","type":"Hash256"},{"name":"ObjectID","type":"Hash256"},{"name":"Meta","type":"Map"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","addKey","transferX","register","registerTLD","addRecord","deleteRecords","subscribeForNewEpoch"]}],"supportedstandards":[],"trusts":[],"extra":null} \ No newline at end of file diff --git a/tests/container_test.go b/tests/container_test.go index 8389207a..02fc5312 100644 --- a/tests/container_test.go +++ b/tests/container_test.go @@ -861,7 +861,7 @@ func TestPutMeta(t *testing.T) { c.InvokeFail(t, "invalid type", "submitObjectPut", []byte{1}, nil) }) - t.Run("missing values", func(t *testing.T) { + t.Run("missing required values", func(t *testing.T) { testFunc := func(key string) { meta := testMeta(cnt.id[:], oid) meta.Drop(meta.Index(stackitem.Make(key))) @@ -872,13 +872,9 @@ func TestPutMeta(t *testing.T) { testFunc("cid") testFunc("oid") - testFunc("firstPart") - testFunc("previousPart") - testFunc("network") testFunc("size") - testFunc("deleted") - testFunc("locked") testFunc("validUntil") + testFunc("network") }) t.Run("incorrect values", func(t *testing.T) { @@ -892,12 +888,12 @@ func TestPutMeta(t *testing.T) { testFunc("cid", []byte{1}) testFunc("oid", []byte{1}) + testFunc("validUntil", 1) // tested chain will have some blocks for sure + testFunc("network", netmode.UnitTestNet+1) testFunc("firstPart", []byte{1}) testFunc("previousPart", []byte{1}) - testFunc("network", netmode.UnitTestNet+1) testFunc("deleted", []any{[]byte{1}}) testFunc("locked", []any{[]byte{1}}) - testFunc("validUntil", 1) // tested chain will have some blocks for sure }) }) } @@ -909,7 +905,6 @@ func testMeta(cid, oid []byte) *stackitem.Map { {Key: stackitem.Make("cid"), Value: stackitem.Make(cid)}, {Key: stackitem.Make("oid"), Value: stackitem.Make(oid)}, {Key: stackitem.Make("firstPart"), Value: stackitem.Make(oid)}, - {Key: stackitem.Make("previousPart"), Value: stackitem.Make(oid)}, {Key: stackitem.Make("size"), Value: stackitem.Make(123)}, {Key: stackitem.Make("deleted"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, {Key: stackitem.Make("locked"), Value: stackitem.Make([]any{randomBytes(sha256.Size)})}, From dd0efc881742c092c7b91b12aed75356bea323fc Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Wed, 25 Dec 2024 18:46:31 +0300 Subject: [PATCH 4/4] container/meta: add object type optional meta field It is optional since for regular objects it should be omitted as an optimization. Signed-off-by: Pavel Karpy --- contracts/container/contract.go | 8 ++++++++ contracts/container/contract.nef | Bin 9293 -> 9379 bytes contracts/container/manifest.json | 2 +- tests/container_test.go | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/contracts/container/contract.go b/contracts/container/contract.go index d64f1f69..d329a04e 100644 --- a/contracts/container/contract.go +++ b/contracts/container/contract.go @@ -274,6 +274,14 @@ func SubmitObjectPut(metaInformation []byte, sigs [][]interop.Signature) { // optional + if v, ok := getFromMap(metaMap, "type"); ok { + typ := v.(int) + switch typ { + case 0, 1, 2, 3, 4: // regular, tombstone, storage group, lock, link + default: + panic("incorrect object type") + } + } if v, ok := getFromMap(metaMap, "firstPart"); ok { firstPart := v.(interop.Hash256) if len(firstPart) != interop.Hash256Len { diff --git a/contracts/container/contract.nef b/contracts/container/contract.nef index 4ebc2c0687c10dfcaf181622b1be4aae29da38ed..8cd3ae1c2cd296d900ebabb632b2cf526c49a22a 100755 GIT binary patch delta 482 zcmX@>vDkBi853jrW^<+=?2J;A4Y))Zb0)iSbud1je4fifW)%|ygV#+(6_(qIt{FUB zWr;bNDWQ2KnK=Qb{gais%^AZdM|11fvy@a8qz0I}167xmv*)v`Ipslhm2>2CcnNG) z5%UtIlT zKw?ozfayC%28MFZa;|(XHQRhnubT!y2N{%e=W~1AP+>i#G0B-uTuiv-bRjIXDWRTC)}%@XXmIi>7YA#Q$d{OW3#dVS@>iY!K1m)&^W#UQ9yaFaQ6~s0c7U&%(gq5YEVG v>NfecoF~(t7n9B8CveC=|NkE-$~?J2UUBn#`Q6Nn){|E&&ttjr!cYeQcqEa%GSQgg`Xgh_Dcb5D-uadhM<=gsF;i^%8ky6FJa;ZV+(&*ybY zz}wr%(W{(a$k+Q^xj?>v*9{fcQ%WqZ0t^ZoYCK$-dCB=jMXAXp3i0yaf7Uv#nouN0%mWN+R8J~19n|D-IS2?3=g`C^+_^0qK? z&iMBKe>rESY2IcterZPb?jQgEXPG8$ju6<*$ar|Nh|pdZZlH?E4@Go0GYLm9Gd69G z7Td$bcyzObBp);5w#n);@=V^ZCws`uW@3J``KgQ-lhE3i|Nm!H1el&@VPJ3wXJj;; jGuctzlPT!s