diff --git a/pkg/core/object/replicate.go b/pkg/core/object/replicate.go index 9be82c3c20..0d0f3ee955 100644 --- a/pkg/core/object/replicate.go +++ b/pkg/core/object/replicate.go @@ -9,17 +9,16 @@ import ( ) const ( - currentVersion = 7 // it is also a number of fields -) - -const ( - networkMagicKey = "network" + // required fields. cidKey = "cid" oidKey = "oid" sizeKey = "size" - deletedKey = "deleted" - lockedKey = "locked" validUntilKey = "validUntil" + networkMagicKey = "network" + + // optional fields. + deletedKey = "deleted" + lockedKey = "locked" ) // EncodeReplicationMetaInfo uses NEO's map (strict order) serialized format as a raw @@ -27,23 +26,28 @@ const ( // // This (ordered) format is used (keys are strings): // -// "network": network magic // "cid": _raw_ container ID (32 bytes) // "oid": _raw_ object ID (32 bytes) // "size": payload size -// "deleted": array of _raw_ object IDs -// "locked": array of _raw_ object IDs // "validUntil": last valid block number for meta information +// "network": network magic +// "deleted": [OPTIONAL] array of _raw_ object IDs +// "locked": [OPTIONAL] array of _raw_ object IDs func EncodeReplicationMetaInfo(cID cid.ID, oID oid.ID, pSize uint64, deleted, locked []oid.ID, vub uint64, magicNumber uint32) []byte { kvs := []stackitem.MapElement{ - kv(networkMagicKey, magicNumber), kv(cidKey, cID[:]), kv(oidKey, oID[:]), kv(sizeKey, pSize), - oidsKV(deletedKey, deleted), - oidsKV(lockedKey, locked), kv(validUntilKey, vub), + kv(networkMagicKey, magicNumber), + } + + if len(deleted) > 0 { + kvs = append(kvs, oidsKV(deletedKey, deleted)) + } + if len(locked) > 0 { + kvs = append(kvs, oidsKV(lockedKey, locked)) } result, err := stackitem.Serialize(stackitem.NewMapWithValue(kvs)) diff --git a/pkg/core/object/replicate_test.go b/pkg/core/object/replicate_test.go index 22ad851916..0bf9351bf4 100644 --- a/pkg/core/object/replicate_test.go +++ b/pkg/core/object/replicate_test.go @@ -6,22 +6,50 @@ import ( "testing" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test" "github.com/stretchr/testify/require" ) +type m struct { + cID cid.ID + oID oid.ID + size uint64 + vub uint64 + magic uint32 + + deleted []oid.ID + locked []oid.ID +} + func TestMetaInfo(t *testing.T) { - network := rand.Uint32() - oID := oidtest.ID() - cID := cidtest.ID() - size := rand.Uint64() - deleted := oidtest.IDs(10) - locked := oidtest.IDs(10) - validUntil := rand.Uint64() - - raw := EncodeReplicationMetaInfo(cID, oID, size, deleted, locked, validUntil, network) + meta := m{ + cID: cidtest.ID(), + oID: oidtest.ID(), + size: rand.Uint64(), + vub: rand.Uint64(), + magic: rand.Uint32(), + deleted: oidtest.IDs(10), + locked: oidtest.IDs(10), + } + + t.Run("full", func(t *testing.T) { + testMeta(t, meta, true) + }) + + t.Run("no optional", func(t *testing.T) { + meta.deleted = nil + meta.deleted = nil + meta.locked = nil + + testMeta(t, meta, false) + }) +} + +func testMeta(t *testing.T, m m, full bool) { + raw := EncodeReplicationMetaInfo(m.cID, m.oID, m.size, m.deleted, m.locked, m.vub, m.magic) item, err := stackitem.Deserialize(raw) require.NoError(t, err) @@ -29,28 +57,31 @@ func TestMetaInfo(t *testing.T) { mm, ok := item.Value().([]stackitem.MapElement) require.True(t, ok) - require.Len(t, mm, currentVersion) + require.Equal(t, cidKey, string(mm[0].Key.Value().([]byte))) + require.Equal(t, m.cID[:], mm[0].Value.Value().([]byte)) - require.Equal(t, networkMagicKey, string(mm[0].Key.Value().([]byte))) - require.Equal(t, network, uint32(mm[0].Value.Value().(*big.Int).Uint64())) + require.Equal(t, oidKey, string(mm[1].Key.Value().([]byte))) + require.Equal(t, m.oID[:], mm[1].Value.Value().([]byte)) - require.Equal(t, cidKey, string(mm[1].Key.Value().([]byte))) - require.Equal(t, cID[:], mm[1].Value.Value().([]byte)) + require.Equal(t, sizeKey, string(mm[2].Key.Value().([]byte))) + require.Equal(t, m.size, mm[2].Value.Value().(*big.Int).Uint64()) - require.Equal(t, oidKey, string(mm[2].Key.Value().([]byte))) - require.Equal(t, oID[:], mm[2].Value.Value().([]byte)) + require.Equal(t, validUntilKey, string(mm[3].Key.Value().([]byte))) + require.Equal(t, m.vub, mm[3].Value.Value().(*big.Int).Uint64()) - require.Equal(t, sizeKey, string(mm[3].Key.Value().([]byte))) - require.Equal(t, size, mm[3].Value.Value().(*big.Int).Uint64()) + require.Equal(t, networkMagicKey, string(mm[4].Key.Value().([]byte))) + require.Equal(t, m.magic, uint32(mm[4].Value.Value().(*big.Int).Uint64())) - require.Equal(t, deletedKey, string(mm[4].Key.Value().([]byte))) - require.Equal(t, deleted, stackItemToOIDs(t, mm[4].Value)) + if !full { + require.Len(t, mm, 5) + return + } - require.Equal(t, lockedKey, string(mm[5].Key.Value().([]byte))) - require.Equal(t, locked, stackItemToOIDs(t, mm[5].Value)) + require.Equal(t, deletedKey, string(mm[5].Key.Value().([]byte))) + require.Equal(t, m.deleted, stackItemToOIDs(t, mm[5].Value)) - require.Equal(t, validUntilKey, string(mm[6].Key.Value().([]byte))) - require.Equal(t, validUntil, mm[6].Value.Value().(*big.Int).Uint64()) + require.Equal(t, lockedKey, string(mm[6].Key.Value().([]byte))) + require.Equal(t, m.locked, stackItemToOIDs(t, mm[6].Value)) } func stackItemToOIDs(t *testing.T, value stackitem.Item) []oid.ID {