Skip to content

Commit

Permalink
node/object/put: push first and previous parts to chain
Browse files Browse the repository at this point in the history
A first object has its own OID to simplify detection of such objects by indexed
meta-information. Closes #2935.

Signed-off-by: Pavel Karpy <[email protected]>
  • Loading branch information
carpawell committed Dec 25, 2024
1 parent 5f01f0e commit 2aff7cd
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
16 changes: 13 additions & 3 deletions pkg/core/object/replicate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ const (
networkMagicKey = "network"

// optional
deletedKey = "deleted"
lockedKey = "locked"
firstPartKey = "firstPart"
previousPartKey = "previousPart"
deletedKey = "deleted"
lockedKey = "locked"
)

// EncodeReplicationMetaInfo uses NEO's map (strict order) serialized format as a raw
Expand All @@ -31,11 +33,13 @@ const (
// "size": payload size
// "validUntil": last valid block number for meta information
// "network": network magic
// "firstPart": [OPTIONAL] _raw_ object ID (32 bytes)
// "previousPart": [OPTIONAL] _raw_ object ID (32 bytes)
// "deleted": [OPTIONAL] array of _raw_ object IDs
// "locked": [OPTIONAL] array of _raw_ object IDs
//
// Last valid epoch is object's creation epoch + 10.
func EncodeReplicationMetaInfo(cID cid.ID, oID oid.ID, pSize uint64,
func EncodeReplicationMetaInfo(cID cid.ID, oID, firstPart, previousPart oid.ID, pSize uint64,
deleted, locked []oid.ID, vub uint64, magicNumber uint32) []byte {
kvs := []stackitem.MapElement{
kv(cidKey, cID[:]),
Expand All @@ -45,6 +49,12 @@ func EncodeReplicationMetaInfo(cID cid.ID, oID oid.ID, pSize uint64,
kv(networkMagicKey, magicNumber),
}

if !firstPart.IsZero() {
kvs = append(kvs, kv(firstPartKey, firstPart[:]))
}
if !previousPart.IsZero() {
kvs = append(kvs, kv(previousPartKey, previousPart[:]))
}
if len(deleted) > 0 {
kvs = append(kvs, oidsKV(deletedKey, deleted))
}
Expand Down
18 changes: 13 additions & 5 deletions pkg/core/object/replicate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ func TestMetaInfo(t *testing.T) {
oID := oidtest.ID()
cID := cidtest.ID()
size := rand.Uint64()
first := oidtest.ID()
prev := oidtest.ID()
deleted := oidtest.IDs(10)
locked := oidtest.IDs(10)
validUntil := rand.Uint64()

raw := EncodeReplicationMetaInfo(cID, oID, size, deleted, locked, validUntil, network)
raw := EncodeReplicationMetaInfo(cID, oID, first, prev, size, deleted, locked, validUntil, network)
item, err := stackitem.Deserialize(raw)
require.NoError(t, err)

Expand All @@ -44,11 +46,17 @@ func TestMetaInfo(t *testing.T) {
require.Equal(t, networkMagicKey, string(mm[4].Key.Value().([]byte)))
require.Equal(t, network, uint32(mm[4].Value.Value().(*big.Int).Uint64()))

require.Equal(t, deletedKey, string(mm[5].Key.Value().([]byte)))
require.Equal(t, deleted, stackItemToOIDs(t, mm[5].Value))
require.Equal(t, firstPartKey, string(mm[5].Key.Value().([]byte)))
require.Equal(t, first[:], mm[5].Value.Value().([]byte))

require.Equal(t, lockedKey, string(mm[6].Key.Value().([]byte)))
require.Equal(t, locked, stackItemToOIDs(t, mm[6].Value))
require.Equal(t, previousPartKey, string(mm[6].Key.Value().([]byte)))
require.Equal(t, prev[:], mm[6].Value.Value().([]byte))

require.Equal(t, deletedKey, string(mm[7].Key.Value().([]byte)))
require.Equal(t, deleted, stackItemToOIDs(t, mm[7].Value))

require.Equal(t, lockedKey, string(mm[8].Key.Value().([]byte)))
require.Equal(t, locked, stackItemToOIDs(t, mm[8].Value))
}

func stackItemToOIDs(t *testing.T, value stackitem.Item) []oid.ID {
Expand Down
13 changes: 10 additions & 3 deletions pkg/network/transport/object/grpc/replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ func objectFromMessage(gMsg *objectGRPC.Object) (*object.Object, error) {
}

func (s *Server) metaInfoSignature(o object.Object) ([]byte, error) {
firstObj := o.GetFirstID()
if o.HasParent() && firstObj.IsZero() && o.SplitID() == nil {
// object itself is the first one
firstObj = o.GetID()
}
prevObj := o.GetPreviousID()

var deleted []oid.ID
var locked []oid.ID
switch o.Type() {
Expand Down Expand Up @@ -235,9 +242,9 @@ func (s *Server) metaInfoSignature(o object.Object) ([]byte, error) {
secondBlock := firstBlock + currentEpochDuration
thirdBlock := secondBlock + currentEpochDuration

firstMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), o.PayloadSize(), deleted, locked, firstBlock, s.mNumber)
secondMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), o.PayloadSize(), deleted, locked, secondBlock, s.mNumber)
thirdMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), o.PayloadSize(), deleted, locked, thirdBlock, s.mNumber)
firstMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), firstObj, prevObj, o.PayloadSize(), deleted, locked, firstBlock, s.mNumber)
secondMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), firstObj, prevObj, o.PayloadSize(), deleted, locked, secondBlock, s.mNumber)
thirdMeta := objectcore.EncodeReplicationMetaInfo(o.GetContainerID(), o.GetID(), firstObj, prevObj, o.PayloadSize(), deleted, locked, thirdBlock, s.mNumber)

var firstSig neofscrypto.Signature
var secondSig neofscrypto.Signature
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/transport/object/grpc/replication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func TestServer_Replicate(t *testing.T) {

require.Equal(t, signer.PublicKeyBytes, sig.PublicKeyBytes())
require.True(t, sig.Verify(objectcore.EncodeReplicationMetaInfo(
o.GetContainerID(), o.GetID(), o.PayloadSize(), nil, nil,
o.GetContainerID(), o.GetID(), o.GetFirstID(), o.GetPreviousID(), o.PayloadSize(), nil, nil,
uint64((123+1+i)*240), mNumber)))

sigsRaw = sigsRaw[:4+l]
Expand Down
9 changes: 8 additions & 1 deletion pkg/services/object/put/distributed.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ func (t *distributedTarget) Close() (oid.ID, error) {
t.encodedObject.b = nil
}()

firstObj := t.obj.GetFirstID()
if t.obj.HasParent() && firstObj.IsZero() && t.obj.SplitID() == nil {
// object itself is the first one
firstObj = t.obj.GetID()
}
prevObj := t.obj.GetPreviousID()

t.obj.SetPayload(t.encodedObject.b[t.encodedObject.pldOff:])

tombOrLink := t.obj.Type() == objectSDK.TypeLink || t.obj.Type() == objectSDK.TypeTombstone
Expand Down Expand Up @@ -152,7 +159,7 @@ func (t *distributedTarget) Close() (oid.ID, error) {
}

expectedVUB := (uint64(t.currentBlock)/t.currentEpochDuration + 2) * t.currentEpochDuration
t.objSharedMeta = object.EncodeReplicationMetaInfo(t.obj.GetContainerID(), t.obj.GetID(), t.obj.PayloadSize(), deletedObjs,
t.objSharedMeta = object.EncodeReplicationMetaInfo(t.obj.GetContainerID(), t.obj.GetID(), firstObj, prevObj, t.obj.PayloadSize(), deletedObjs,
lockedObjs, expectedVUB, t.networkMagicNumber)
id := t.obj.GetID()
err := t.placementIterator.iterateNodesForObject(id, t.sendObject)
Expand Down

0 comments on commit 2aff7cd

Please sign in to comment.