Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sign multipart objects in the gate #1001

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions api/layer/multipart_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,15 @@ func (n *layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
if nBts > 0 {
prm.Payload = bytes.NewReader((*chunk)[:nBts])
prm.PayloadSize = uint64(nBts)
prm.Multipart.PayloadHash = sha256.New()
prm.Multipart.PayloadHash.Write((*chunk)[:nBts])

id, _, err = n.objectPutAndHash(ctx, prm, bktInfo)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
prm.Multipart.HomoHash.Write((*chunk)[:nBts])
}

id, err = n.multipartObjectPut(ctx, prm, bktInfo)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -496,11 +503,16 @@ func (n *layer) uploadZeroPart(ctx context.Context, multipartInfo *data.Multipar
Multipart: &Multipart{
MultipartHashes: objHashes,
HeaderObject: &hashlessHeaderObject,
PayloadHash: sha256.New(),
},
Payload: bytes.NewBuffer(nil),
}

id, _, err := n.objectPutAndHash(ctx, prm, bktInfo)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
}

id, err := n.multipartObjectPut(ctx, prm, bktInfo)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -822,11 +834,16 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
SplitFirstID: &splitFirstID,
SplitPreviousID: &splitPreviousID,
HeaderObject: header,
PayloadHash: sha256.New(),
},
Payload: bytes.NewBuffer(nil),
}

lastPartObjID, _, err := n.objectPutAndHash(ctx, prm, p.Info.Bkt)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
}

lastPartObjID, err := n.multipartObjectPut(ctx, prm, p.Info.Bkt)
if err != nil {
return nil, nil, err
}
Expand All @@ -852,7 +869,7 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
},
}

_, _, err = n.objectPutAndHash(ctx, prm, p.Info.Bkt)
_, err = n.multipartObjectPut(ctx, prm, p.Info.Bkt)
if err != nil {
return nil, nil, err
}
Expand Down
4 changes: 4 additions & 0 deletions api/layer/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ type Multipart struct {
HeaderObject *object.Object
// Link contains info for linking object.
Link *object.Link
// PayloadHash contains precalculated hash for object.
PayloadHash hash.Hash
// HomoHash contains precalculated homomorphic hash for object if enabled.
HomoHash hash.Hash
}

// PrmObjectDelete groups parameters of NeoFS.DeleteObject operation.
Expand Down
18 changes: 16 additions & 2 deletions api/layer/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,20 @@ func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktIn
hash := sha256.New()
prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
hash.Write(buf)
})
id, err := n.neoFS.CreateObject(ctx, prm)
if err != nil {
return oid.ID{}, nil, err
}
return id, hash.Sum(nil), nil
}

// multipartObjectPut writes only Multipart hash collection.
// It doesn't calculate hash from payload, it already calculated in prm.Multipart.PayloadHash, if required.
func (n *layer) multipartObjectPut(ctx context.Context, prm PrmObjectCreate, bktInfo *data.BucketInfo) (oid.ID, error) {
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)

prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
if prm.Multipart != nil {
for _, h := range prm.Multipart.MultipartHashes {
h.Write(buf)
Expand All @@ -496,9 +510,9 @@ func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktIn
})
id, err := n.neoFS.CreateObject(ctx, prm)
if err != nil {
return oid.ID{}, nil, err
return oid.ID{}, err
}
return id, hash.Sum(nil), nil
return id, nil
}

// ListObjectsV1 returns objects in a bucket for requests of Version 1.
Expand Down
31 changes: 31 additions & 0 deletions internal/neofs/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/container"
"github.com/nspcc-dev/neofs-sdk-go/container/acl"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
Expand Down Expand Up @@ -246,6 +247,19 @@ func (x *NeoFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.C
return nil
}

func (x *NeoFS) signMultipartObject(obj *object.Object, signer neofscrypto.Signer, payloadHash, homoHash hash.Hash) error {
obj.SetPayloadChecksum(checksum.NewFromHash(checksum.SHA256, payloadHash))
if homoHash != nil {
obj.SetPayloadHomomorphicHash(checksum.NewFromHash(checksum.TillichZemor, homoHash))
}

if err := obj.SetIDWithSignature(signer); err != nil {
return fmt.Errorf("set id with signature: %w", err)
}

return nil
}

// CreateObject implements neofs.NeoFS interface method.
func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
attrNum := len(prm.Attributes) + 1 // + creation time
Expand Down Expand Up @@ -310,9 +324,26 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi
prm.Payload = bytes.NewReader(obj.Payload())
obj.SetPayloadSize(uint64(len(obj.Payload())))

prm.Multipart.PayloadHash = sha256.New()
prm.Multipart.PayloadHash.Write(obj.Payload())

if x.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
prm.Multipart.HomoHash.Write(obj.Payload())
}

// Link object should never have a previous one.
obj.ResetPreviousID()
}

if err := x.signMultipartObject(
&obj,
x.signer(ctx),
prm.Multipart.PayloadHash,
prm.Multipart.HomoHash,
); err != nil {
return oid.ID{}, errors.New("failed to sign object")
}
}

if len(prm.Locks) > 0 {
Expand Down
Loading