forked from TrueCloudLab/frostfs-sdk-go
[#170] oid, cid: Refactor and document package functionality
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
24d6c2221f
commit
f7172adf18
49 changed files with 831 additions and 439 deletions
|
@ -75,20 +75,29 @@ func (r *Result) ForEpoch(epoch uint64) {
|
|||
// Container returns identifier of the container with which the data audit Result
|
||||
// is associated.
|
||||
//
|
||||
// Returns nil if container is not specified. Zero Result has nil container.
|
||||
// Return value MUST NOT be mutated: to do this, first make a copy.
|
||||
// Returns zero ID if container is not specified. Zero Result has zero container.
|
||||
//
|
||||
// See also ForContainer.
|
||||
func (r Result) Container() *cid.ID {
|
||||
return cid.NewFromV2(r.v2.GetContainerID())
|
||||
func (r Result) Container() cid.ID {
|
||||
var cID cid.ID
|
||||
|
||||
cidV2 := r.v2.GetContainerID()
|
||||
if cidV2 != nil {
|
||||
_ = cID.ReadFromV2(*cidV2)
|
||||
}
|
||||
|
||||
// ForContainer returns identifier of the container with which the data audit Result
|
||||
return cID
|
||||
}
|
||||
|
||||
// ForContainer sets identifier of the container with which the data audit Result
|
||||
// is associated.
|
||||
//
|
||||
// See also Container.
|
||||
func (r *Result) ForContainer(cnr cid.ID) {
|
||||
r.v2.SetContainerID(cnr.ToV2())
|
||||
var cidV2 refs.ContainerID
|
||||
cnr.WriteToV2(&cidV2)
|
||||
|
||||
r.v2.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// AuditorKey returns public key of the auditing NeoFS Inner Ring node in
|
||||
|
@ -174,8 +183,12 @@ func (r *Result) SetRetriesPoR(v uint32) {
|
|||
func (r Result) IteratePassedStorageGroups(f func(oid.ID) bool) {
|
||||
r2 := r.v2.GetPassSG()
|
||||
|
||||
var id oid.ID
|
||||
|
||||
for i := range r2 {
|
||||
if !f(*oid.NewIDFromV2(&r2[i])) {
|
||||
_ = id.ReadFromV2(r2[i])
|
||||
|
||||
if !f(id) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +199,10 @@ func (r Result) IteratePassedStorageGroups(f func(oid.ID) bool) {
|
|||
//
|
||||
// See also IteratePassedStorageGroups.
|
||||
func (r *Result) SubmitPassedStorageGroup(sg oid.ID) {
|
||||
r.v2.SetPassSG(append(r.v2.GetPassSG(), *sg.ToV2()))
|
||||
var idV2 refs.ObjectID
|
||||
sg.WriteToV2(&idV2)
|
||||
|
||||
r.v2.SetPassSG(append(r.v2.GetPassSG(), idV2))
|
||||
}
|
||||
|
||||
// IterateFailedStorageGroups is similar to IteratePassedStorageGroups but for failed groups.
|
||||
|
@ -194,9 +210,11 @@ func (r *Result) SubmitPassedStorageGroup(sg oid.ID) {
|
|||
// See also SubmitFailedStorageGroup.
|
||||
func (r Result) IterateFailedStorageGroups(f func(oid.ID) bool) {
|
||||
v := r.v2.GetFailSG()
|
||||
var id oid.ID
|
||||
|
||||
for i := range v {
|
||||
if !f(*oid.NewIDFromV2(&v[i])) {
|
||||
_ = id.ReadFromV2(v[i])
|
||||
if !f(id) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +224,10 @@ func (r Result) IterateFailedStorageGroups(f func(oid.ID) bool) {
|
|||
//
|
||||
// See also IterateFailedStorageGroups.
|
||||
func (r *Result) SubmitFailedStorageGroup(sg oid.ID) {
|
||||
r.v2.SetFailSG(append(r.v2.GetFailSG(), *sg.ToV2()))
|
||||
var idV2 refs.ObjectID
|
||||
sg.WriteToV2(&idV2)
|
||||
|
||||
r.v2.SetFailSG(append(r.v2.GetFailSG(), idV2))
|
||||
}
|
||||
|
||||
// Hits returns number of sampled objects under audit placed
|
||||
|
|
|
@ -66,7 +66,7 @@ func TestResultData(t *testing.T) {
|
|||
countFailNodes := func(f func([]byte)) int { return countNodes(false, f) }
|
||||
|
||||
require.Zero(t, r.Epoch())
|
||||
require.Nil(t, r.Container())
|
||||
require.True(t, r.Container().Empty())
|
||||
require.Nil(t, r.AuditorKey())
|
||||
require.False(t, r.Completed())
|
||||
require.Zero(t, r.RequestsPoR())
|
||||
|
@ -81,7 +81,7 @@ func TestResultData(t *testing.T) {
|
|||
require.Equal(t, epoch, r.Epoch())
|
||||
|
||||
cnr := cidtest.ID()
|
||||
r.ForContainer(*cnr)
|
||||
r.ForContainer(cnr)
|
||||
require.Equal(t, cnr, r.Container())
|
||||
|
||||
key := []byte{1, 2, 3}
|
||||
|
@ -99,32 +99,32 @@ func TestResultData(t *testing.T) {
|
|||
r.SetRetriesPoR(retries)
|
||||
require.Equal(t, retries, r.RetriesPoR())
|
||||
|
||||
passSG1, passSG2 := *oidtest.ID(), *oidtest.ID()
|
||||
passSG1, passSG2 := oidtest.ID(), oidtest.ID()
|
||||
r.SubmitPassedStorageGroup(passSG1)
|
||||
r.SubmitPassedStorageGroup(passSG2)
|
||||
|
||||
called1, called2 := false, false
|
||||
|
||||
require.EqualValues(t, 2, countPassSG(func(id oid.ID) {
|
||||
if id.Equal(&passSG1) {
|
||||
if id.Equals(passSG1) {
|
||||
called1 = true
|
||||
} else if id.Equal(&passSG2) {
|
||||
} else if id.Equals(passSG2) {
|
||||
called2 = true
|
||||
}
|
||||
}))
|
||||
require.True(t, called1)
|
||||
require.True(t, called2)
|
||||
|
||||
failSG1, failSG2 := *oidtest.ID(), *oidtest.ID()
|
||||
failSG1, failSG2 := oidtest.ID(), oidtest.ID()
|
||||
r.SubmitFailedStorageGroup(failSG1)
|
||||
r.SubmitFailedStorageGroup(failSG2)
|
||||
|
||||
called1, called2 = false, false
|
||||
|
||||
require.EqualValues(t, 2, countFailSG(func(id oid.ID) {
|
||||
if id.Equal(&failSG1) {
|
||||
if id.Equals(failSG1) {
|
||||
called1 = true
|
||||
} else if id.Equal(&failSG2) {
|
||||
} else if id.Equals(failSG2) {
|
||||
called2 = true
|
||||
}
|
||||
}))
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
func Result() *audit.Result {
|
||||
var x audit.Result
|
||||
|
||||
x.ForContainer(*cidtest.ID())
|
||||
x.ForContainer(cidtest.ID())
|
||||
x.SetAuditorKey([]byte("key"))
|
||||
x.Complete()
|
||||
x.ForEpoch(44)
|
||||
|
@ -27,10 +27,10 @@ func Result() *audit.Result {
|
|||
[]byte("node3"),
|
||||
[]byte("node4"),
|
||||
})
|
||||
x.SubmitPassedStorageGroup(*oidtest.ID())
|
||||
x.SubmitPassedStorageGroup(*oidtest.ID())
|
||||
x.SubmitFailedStorageGroup(*oidtest.ID())
|
||||
x.SubmitFailedStorageGroup(*oidtest.ID())
|
||||
x.SubmitPassedStorageGroup(oidtest.ID())
|
||||
x.SubmitPassedStorageGroup(oidtest.ID())
|
||||
x.SubmitFailedStorageGroup(oidtest.ID())
|
||||
x.SubmitFailedStorageGroup(oidtest.ID())
|
||||
|
||||
return &x
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
|
@ -121,7 +122,17 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
|
|||
}
|
||||
cc.result = func(r responseV2) {
|
||||
resp := r.(*v2container.PutResponse)
|
||||
res.setID(cid.NewFromV2(resp.GetBody().GetContainerID()))
|
||||
var cID *cid.ID
|
||||
|
||||
cidV2 := resp.GetBody().GetContainerID()
|
||||
if cidV2 != nil {
|
||||
var c cid.ID
|
||||
_ = c.ReadFromV2(*cidV2)
|
||||
|
||||
cID = &c
|
||||
}
|
||||
|
||||
res.setID(cID)
|
||||
}
|
||||
|
||||
// process call
|
||||
|
@ -187,9 +198,12 @@ func (c *Client) ContainerGet(ctx context.Context, prm PrmContainerGet) (*ResCon
|
|||
panic(panicMsgMissingContainer)
|
||||
}
|
||||
|
||||
var cidV2 refs.ContainerID
|
||||
prm.id.WriteToV2(&cidV2)
|
||||
|
||||
// form request body
|
||||
reqBody := new(v2container.GetRequestBody)
|
||||
reqBody.SetContainerID(prm.id.ToV2())
|
||||
reqBody.SetContainerID(&cidV2)
|
||||
|
||||
// form request
|
||||
var req v2container.GetRequest
|
||||
|
@ -322,7 +336,7 @@ func (c *Client) ContainerList(ctx context.Context, prm PrmContainerList) (*ResC
|
|||
ids := make([]cid.ID, len(resp.GetBody().GetContainerIDs()))
|
||||
|
||||
for i, cidV2 := range resp.GetBody().GetContainerIDs() {
|
||||
ids[i] = *cid.NewFromV2(&cidV2)
|
||||
_ = ids[i].ReadFromV2(cidV2)
|
||||
}
|
||||
|
||||
res.setContainers(ids)
|
||||
|
@ -400,9 +414,12 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
|
|||
panic(panicMsgMissingContainer)
|
||||
}
|
||||
|
||||
var cidV2 refs.ContainerID
|
||||
prm.id.WriteToV2(&cidV2)
|
||||
|
||||
// form request body
|
||||
reqBody := new(v2container.DeleteRequestBody)
|
||||
reqBody.SetContainerID(prm.id.ToV2())
|
||||
reqBody.SetContainerID(&cidV2)
|
||||
|
||||
signWrapper := delContainerSignWrapper{body: reqBody}
|
||||
|
||||
|
@ -504,9 +521,12 @@ func (c *Client) ContainerEACL(ctx context.Context, prm PrmContainerEACL) (*ResC
|
|||
panic(panicMsgMissingContainer)
|
||||
}
|
||||
|
||||
var cidV2 refs.ContainerID
|
||||
prm.id.WriteToV2(&cidV2)
|
||||
|
||||
// form request body
|
||||
reqBody := new(v2container.GetExtendedACLRequestBody)
|
||||
reqBody.SetContainerID(prm.id.ToV2())
|
||||
reqBody.SetContainerID(&cidV2)
|
||||
|
||||
// form request
|
||||
var req v2container.GetExtendedACLRequest
|
||||
|
|
|
@ -52,13 +52,19 @@ func (x *PrmObjectDelete) WithBearerToken(t bearer.Token) {
|
|||
// FromContainer specifies NeoFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectDelete) FromContainer(id cid.ID) {
|
||||
x.addr.SetContainerID(id.ToV2())
|
||||
var cidV2 v2refs.ContainerID
|
||||
id.WriteToV2(&cidV2)
|
||||
|
||||
x.addr.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectDelete) ByID(id oid.ID) {
|
||||
x.addr.SetObjectID(id.ToV2())
|
||||
var idV2 v2refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
x.addr.SetObjectID(&idV2)
|
||||
}
|
||||
|
||||
// UseKey specifies private key to sign the requests.
|
||||
|
@ -91,7 +97,7 @@ type ResObjectDelete struct {
|
|||
// Returns false if ID is missing (not read).
|
||||
func (x ResObjectDelete) ReadTombstoneID(dst *oid.ID) bool {
|
||||
if x.idTomb != nil {
|
||||
*dst = *oid.NewIDFromV2(x.idTomb) // need smth better
|
||||
_ = dst.ReadFromV2(*x.idTomb)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,10 @@ type prmObjectRead struct {
|
|||
bearer bearer.Token
|
||||
|
||||
cnrSet bool
|
||||
cnr cid.ID
|
||||
cnrID cid.ID
|
||||
|
||||
objSet bool
|
||||
obj oid.ID
|
||||
objID oid.ID
|
||||
}
|
||||
|
||||
func (x prmObjectRead) writeToMetaHeader(h *v2session.RequestMetaHeader) {
|
||||
|
@ -94,14 +94,14 @@ func (x *prmObjectRead) WithBearerToken(t bearer.Token) {
|
|||
// FromContainer specifies NeoFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *prmObjectRead) FromContainer(id cid.ID) {
|
||||
x.cnr = id
|
||||
x.cnrID = id
|
||||
x.cnrSet = true
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *prmObjectRead) ByID(id oid.ID) {
|
||||
x.obj = id
|
||||
x.objID = id
|
||||
x.objSet = true
|
||||
}
|
||||
|
||||
|
@ -318,10 +318,17 @@ func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectRe
|
|||
panic("missing object")
|
||||
}
|
||||
|
||||
var addr v2refs.Address
|
||||
var (
|
||||
addr v2refs.Address
|
||||
oidV2 v2refs.ObjectID
|
||||
cidV2 v2refs.ContainerID
|
||||
)
|
||||
|
||||
addr.SetContainerID(prm.cnr.ToV2())
|
||||
addr.SetObjectID(prm.obj.ToV2())
|
||||
prm.objID.WriteToV2(&oidV2)
|
||||
prm.cnrID.WriteToV2(&cidV2)
|
||||
|
||||
addr.SetContainerID(&cidV2)
|
||||
addr.SetObjectID(&oidV2)
|
||||
|
||||
// form request body
|
||||
var body v2object.GetRequestBody
|
||||
|
@ -411,7 +418,7 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
|
|||
objv2.SetSignature(x.hdr.GetSignature())
|
||||
|
||||
obj := object.NewFromV2(&objv2)
|
||||
obj.SetID(&x.idObj)
|
||||
obj.SetID(x.idObj)
|
||||
|
||||
*dst = *obj
|
||||
|
||||
|
@ -449,16 +456,23 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
|||
panic("missing object")
|
||||
}
|
||||
|
||||
var addr v2refs.Address
|
||||
var (
|
||||
addrV2 v2refs.Address
|
||||
oidV2 v2refs.ObjectID
|
||||
cidV2 v2refs.ContainerID
|
||||
)
|
||||
|
||||
addr.SetContainerID(prm.cnr.ToV2())
|
||||
addr.SetObjectID(prm.obj.ToV2())
|
||||
prm.objID.WriteToV2(&oidV2)
|
||||
prm.cnrID.WriteToV2(&cidV2)
|
||||
|
||||
addrV2.SetContainerID(&cidV2)
|
||||
addrV2.SetObjectID(&oidV2)
|
||||
|
||||
// form request body
|
||||
var body v2object.HeadRequestBody
|
||||
|
||||
body.SetRaw(prm.raw)
|
||||
body.SetAddress(&addr)
|
||||
body.SetAddress(&addrV2)
|
||||
|
||||
// form meta header
|
||||
var meta v2session.RequestMetaHeader
|
||||
|
@ -478,7 +492,7 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
|||
res ResObjectHead
|
||||
)
|
||||
|
||||
res.idObj = prm.obj
|
||||
res.idObj = prm.objID
|
||||
|
||||
if prm.keySet {
|
||||
c.initCallContextWithoutKey(&cc)
|
||||
|
@ -715,10 +729,17 @@ func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*Obje
|
|||
panic("zero range length")
|
||||
}
|
||||
|
||||
var addr v2refs.Address
|
||||
var (
|
||||
addrV2 v2refs.Address
|
||||
oidV2 v2refs.ObjectID
|
||||
cidV2 v2refs.ContainerID
|
||||
)
|
||||
|
||||
addr.SetContainerID(prm.cnr.ToV2())
|
||||
addr.SetObjectID(prm.obj.ToV2())
|
||||
prm.objID.WriteToV2(&oidV2)
|
||||
prm.cnrID.WriteToV2(&cidV2)
|
||||
|
||||
addrV2.SetContainerID(&cidV2)
|
||||
addrV2.SetObjectID(&oidV2)
|
||||
|
||||
var rng v2object.Range
|
||||
|
||||
|
@ -729,7 +750,7 @@ func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*Obje
|
|||
var body v2object.GetRangeRequestBody
|
||||
|
||||
body.SetRaw(prm.raw)
|
||||
body.SetAddress(&addr)
|
||||
body.SetAddress(&addrV2)
|
||||
body.SetRange(&rng)
|
||||
|
||||
// form meta header
|
||||
|
|
|
@ -55,13 +55,19 @@ func (x *PrmObjectHash) WithBearerToken(t bearer.Token) {
|
|||
// FromContainer specifies NeoFS container of the object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectHash) FromContainer(id cid.ID) {
|
||||
x.addr.SetContainerID(id.ToV2())
|
||||
var cidV2 v2refs.ContainerID
|
||||
id.WriteToV2(&cidV2)
|
||||
|
||||
x.addr.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// ByID specifies identifier of the requested object.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectHash) ByID(id oid.ID) {
|
||||
x.addr.SetObjectID(id.ToV2())
|
||||
var idV2 v2refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
x.addr.SetObjectID(&idV2)
|
||||
}
|
||||
|
||||
// SetRangeList sets list of ranges in (offset, length) pair format.
|
||||
|
|
|
@ -37,7 +37,7 @@ func (x *ResObjectPut) ReadStoredObjectID(id *oid.ID) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
*id = *oid.NewIDFromV2(idv2) // need smth better
|
||||
_ = id.ReadFromV2(*idv2)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ type PrmObjectSearch struct {
|
|||
bearer bearer.Token
|
||||
|
||||
cnrSet bool
|
||||
cnr cid.ID
|
||||
cnrID cid.ID
|
||||
|
||||
filters object.SearchFilters
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (x *PrmObjectSearch) WithBearerToken(t bearer.Token) {
|
|||
// InContainer specifies the container in which to look for objects.
|
||||
// Required parameter.
|
||||
func (x *PrmObjectSearch) InContainer(id cid.ID) {
|
||||
x.cnr = id
|
||||
x.cnrID = id
|
||||
x.cnrSet = true
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ func (x *ObjectListReader) Read(buf []oid.ID) (int, bool) {
|
|||
}
|
||||
|
||||
for i := 0; i < read; i++ {
|
||||
buf[i] = *oid.NewIDFromV2(&x.tail[i]) // need smth better
|
||||
_ = buf[i].ReadFromV2(x.tail[i])
|
||||
}
|
||||
|
||||
x.tail = x.tail[read:]
|
||||
|
@ -165,7 +165,7 @@ func (x *ObjectListReader) Read(buf []oid.ID) (int, bool) {
|
|||
}
|
||||
|
||||
for i = 0; i < ln; i++ {
|
||||
buf[read+i] = *oid.NewIDFromV2(&ids[i]) // need smth better
|
||||
_ = buf[read+i].ReadFromV2(ids[i])
|
||||
}
|
||||
|
||||
read += ln
|
||||
|
@ -244,10 +244,15 @@ func (c *Client) ObjectSearchInit(ctx context.Context, prm PrmObjectSearch) (*Ob
|
|||
}
|
||||
|
||||
// form request body
|
||||
var body v2object.SearchRequestBody
|
||||
var (
|
||||
body v2object.SearchRequestBody
|
||||
cidV2 v2refs.ContainerID
|
||||
)
|
||||
|
||||
prm.cnrID.WriteToV2(&cidV2)
|
||||
|
||||
body.SetVersion(1)
|
||||
body.SetContainerID(prm.cnr.ToV2())
|
||||
body.SetContainerID(&cidV2)
|
||||
body.SetFilters(prm.filters.ToV2())
|
||||
|
||||
// form meta header
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
func TestObjectSearch(t *testing.T) {
|
||||
ids := make([]oid.ID, 20)
|
||||
for i := range ids {
|
||||
ids[i] = *oidtest.ID()
|
||||
ids[i] = oidtest.ID()
|
||||
}
|
||||
|
||||
resp, setID := testListReaderResponse(t)
|
||||
|
@ -88,7 +88,7 @@ func TestObjectSearch(t *testing.T) {
|
|||
func TestObjectIterate(t *testing.T) {
|
||||
ids := make([]oid.ID, 3)
|
||||
for i := range ids {
|
||||
ids[i] = *oidtest.ID()
|
||||
ids[i] = oidtest.ID()
|
||||
}
|
||||
|
||||
t.Run("iterate all sequence", func(t *testing.T) {
|
||||
|
@ -176,8 +176,11 @@ func testListReaderResponse(t *testing.T) (*ObjectListReader, func(id []oid.ID)
|
|||
resp.SetBody(new(object.SearchResponseBody))
|
||||
|
||||
v2id := make([]refs.ObjectID, len(id))
|
||||
var oidV2 refs.ObjectID
|
||||
|
||||
for i := range id {
|
||||
v2id[i] = *id[i].ToV2()
|
||||
id[i].WriteToV2(&oidV2)
|
||||
v2id[i] = oidV2
|
||||
}
|
||||
resp.GetBody().SetIDList(v2id)
|
||||
err := signatureV2.SignServiceMessage(&p.PrivateKey, resp)
|
||||
|
|
|
@ -2,6 +2,7 @@ package container
|
|||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/container"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
|
@ -38,15 +39,25 @@ func (a *UsedSpaceAnnouncement) SetEpoch(epoch uint64) {
|
|||
}
|
||||
|
||||
// ContainerID of the announcement.
|
||||
func (a *UsedSpaceAnnouncement) ContainerID() *cid.ID {
|
||||
return cid.NewFromV2(
|
||||
(*container.UsedSpaceAnnouncement)(a).GetContainerID(),
|
||||
)
|
||||
func (a *UsedSpaceAnnouncement) ContainerID() (cID cid.ID) {
|
||||
v2 := (*container.UsedSpaceAnnouncement)(a)
|
||||
|
||||
cidV2 := v2.GetContainerID()
|
||||
if cidV2 == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = cID.ReadFromV2(*cidV2)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetContainerID sets announcement container value.
|
||||
func (a *UsedSpaceAnnouncement) SetContainerID(cid *cid.ID) {
|
||||
(*container.UsedSpaceAnnouncement)(a).SetContainerID(cid.ToV2())
|
||||
func (a *UsedSpaceAnnouncement) SetContainerID(cnr cid.ID) {
|
||||
var cidV2 refs.ContainerID
|
||||
cnr.WriteToV2(&cidV2)
|
||||
|
||||
(*container.UsedSpaceAnnouncement)(a).SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// UsedSpace in container.
|
||||
|
|
|
@ -46,9 +46,12 @@ func TestAnnouncement(t *testing.T) {
|
|||
|
||||
newA := container.NewAnnouncementFromV2(v2)
|
||||
|
||||
var cID cid.ID
|
||||
_ = cID.ReadFromV2(*newCID)
|
||||
|
||||
require.Equal(t, newEpoch, newA.Epoch())
|
||||
require.Equal(t, newUsedSpace, newA.UsedSpace())
|
||||
require.Equal(t, cid.NewFromV2(newCID), newA.ContainerID())
|
||||
require.Equal(t, cID, newA.ContainerID())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -79,7 +82,7 @@ func TestUsedSpaceAnnouncement_ToV2(t *testing.T) {
|
|||
// check initial values
|
||||
require.Zero(t, announcement.Epoch())
|
||||
require.Zero(t, announcement.UsedSpace())
|
||||
require.Nil(t, announcement.ContainerID())
|
||||
require.True(t, announcement.ContainerID().Empty())
|
||||
|
||||
// convert to v2 message
|
||||
announcementV2 := announcement.ToV2()
|
||||
|
|
|
@ -87,13 +87,13 @@ func NewContainerFromV2(c *container.Container) *Container {
|
|||
|
||||
// CalculateID calculates container identifier
|
||||
// based on its structure.
|
||||
func CalculateID(c *Container) *cid.ID {
|
||||
func CalculateID(c *Container) cid.ID {
|
||||
data, err := c.ToV2().StableMarshal(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
id := cid.New()
|
||||
var id cid.ID
|
||||
id.SetSHA256(sha256.Sum256(data))
|
||||
|
||||
return id
|
||||
|
|
8
container/id/doc.go
Normal file
8
container/id/doc.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
Package cid provides primitives to work with container identification in NeoFS.
|
||||
|
||||
Using package types in an application is recommended to potentially work with
|
||||
different protocol versions with which these types are compatible.
|
||||
|
||||
*/
|
||||
package cid
|
|
@ -1,90 +1,120 @@
|
|||
package cid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
)
|
||||
|
||||
// ID represents v2-compatible container identifier.
|
||||
type ID refs.ContainerID
|
||||
|
||||
// NewFromV2 wraps v2 ContainerID message to ID.
|
||||
// ID represents NeoFS container identifier.
|
||||
//
|
||||
// Nil refs.ContainerID converts to nil.
|
||||
func NewFromV2(idV2 *refs.ContainerID) *ID {
|
||||
return (*ID)(idV2)
|
||||
}
|
||||
|
||||
// New creates and initializes blank ID.
|
||||
// ID is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/refs.ContainerID
|
||||
// message. See ReadFromV2 / WriteToV2 methods.
|
||||
//
|
||||
// Defaults:
|
||||
// - value: nil.
|
||||
func New() *ID {
|
||||
return NewFromV2(new(refs.ContainerID))
|
||||
}
|
||||
|
||||
// SetSHA256 sets container identifier value to SHA256 checksum of container body.
|
||||
func (id *ID) SetSHA256(v [sha256.Size]byte) {
|
||||
(*refs.ContainerID)(id).SetValue(v[:])
|
||||
}
|
||||
|
||||
// ToV2 returns the v2 container ID message.
|
||||
// Instances can be created using built-in var declaration.
|
||||
//
|
||||
// Nil ID converts to nil.
|
||||
func (id *ID) ToV2() *refs.ContainerID {
|
||||
return (*refs.ContainerID)(id)
|
||||
}
|
||||
// Note that direct typecast is not safe and may result in loss of compatibility:
|
||||
// _ = ID([32]byte) // not recommended
|
||||
type ID [sha256.Size]byte
|
||||
|
||||
// Equal returns true if identifiers are identical.
|
||||
func (id *ID) Equal(id2 *ID) bool {
|
||||
return bytes.Equal(
|
||||
(*refs.ContainerID)(id).GetValue(),
|
||||
(*refs.ContainerID)(id2).GetValue(),
|
||||
)
|
||||
}
|
||||
|
||||
// Parse parses string representation of ID.
|
||||
// ReadFromV2 reads ID from the refs.ContainerID message.
|
||||
// Returns an error if the message is malformed according
|
||||
// to the NeoFS API V2 protocol.
|
||||
//
|
||||
// Returns error if s is not a base58 encoded
|
||||
// ID data.
|
||||
func (id *ID) Parse(s string) error {
|
||||
data, err := base58.Decode(s)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(data) != sha256.Size {
|
||||
return errors.New("incorrect format of the string container ID")
|
||||
// See also WriteToV2.
|
||||
func (id *ID) ReadFromV2(m refs.ContainerID) error {
|
||||
return id.Decode(m.GetValue())
|
||||
}
|
||||
|
||||
(*refs.ContainerID)(id).SetValue(data)
|
||||
// WriteToV2 writes ID to the refs.ContainerID message.
|
||||
// The message must not be nil.
|
||||
//
|
||||
// See also ReadFromV2.
|
||||
func (id ID) WriteToV2(m *refs.ContainerID) {
|
||||
m.SetValue(id[:])
|
||||
}
|
||||
|
||||
// Encode encodes ID into 32 bytes of dst. Panics if
|
||||
// dst length is less than 32.
|
||||
//
|
||||
// Zero ID is all zeros.
|
||||
//
|
||||
// See also Decode.
|
||||
func (id ID) Encode(dst []byte) {
|
||||
if l := len(dst); l < sha256.Size {
|
||||
panic(fmt.Sprintf("destination length is less than %d bytes: %d", sha256.Size, l))
|
||||
}
|
||||
|
||||
copy(dst, id[:])
|
||||
}
|
||||
|
||||
// Decode decodes src bytes into ID.
|
||||
//
|
||||
// Decode expects that src has 32 bytes length. If the input is malformed,
|
||||
// Decode returns an error describing format violation. In this case ID
|
||||
// remains unchanged.
|
||||
//
|
||||
// Decode doesn't mutate src.
|
||||
//
|
||||
// See also Encode.
|
||||
func (id *ID) Decode(src []byte) error {
|
||||
if len(src) != sha256.Size {
|
||||
return fmt.Errorf("invalid length %d", len(src))
|
||||
}
|
||||
|
||||
copy(id[:], src)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns base58 string representation of ID.
|
||||
func (id *ID) String() string {
|
||||
return base58.Encode((*refs.ContainerID)(id).GetValue())
|
||||
// SetSHA256 sets container identifier value to SHA256 checksum of container structure.
|
||||
func (id *ID) SetSHA256(v [sha256.Size]byte) {
|
||||
copy(id[:], v[:])
|
||||
}
|
||||
|
||||
// Marshal marshals ID into a protobuf binary form.
|
||||
func (id *ID) Marshal() ([]byte, error) {
|
||||
return (*refs.ContainerID)(id).StableMarshal(nil)
|
||||
// Equals defines a comparison relation between two ID instances.
|
||||
//
|
||||
// Note that comparison using '==' operator is not recommended since it MAY result
|
||||
// in loss of compatibility.
|
||||
func (id ID) Equals(id2 ID) bool {
|
||||
return id == id2
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals protobuf binary representation of ID.
|
||||
func (id *ID) Unmarshal(data []byte) error {
|
||||
return (*refs.ContainerID)(id).Unmarshal(data)
|
||||
// EncodeToString encodes ID into NeoFS API protocol string.
|
||||
//
|
||||
// Zero ID is base58 encoding of 32 zeros.
|
||||
//
|
||||
// See also DecodeString.
|
||||
func (id ID) EncodeToString() string {
|
||||
return base58.Encode(id[:])
|
||||
}
|
||||
|
||||
// MarshalJSON encodes ID to protobuf JSON format.
|
||||
func (id *ID) MarshalJSON() ([]byte, error) {
|
||||
return (*refs.ContainerID)(id).MarshalJSON()
|
||||
// DecodeString decodes string into ID according to NeoFS API protocol. Returns
|
||||
// an error if s is malformed.
|
||||
//
|
||||
// See also DecodeString.
|
||||
func (id *ID) DecodeString(s string) error {
|
||||
data, err := base58.Decode(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode base58: %w", err)
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes ID from protobuf JSON format.
|
||||
func (id *ID) UnmarshalJSON(data []byte) error {
|
||||
return (*refs.ContainerID)(id).UnmarshalJSON(data)
|
||||
return id.Decode(data)
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
//
|
||||
// String is designed to be human-readable, and its format MAY differ between
|
||||
// SDK versions. String MAY return same result as EncodeToString. String MUST NOT
|
||||
// be used to encode ID into NeoFS protocol string.
|
||||
func (id ID) String() string {
|
||||
return id.EncodeToString()
|
||||
}
|
||||
|
||||
// Empty returns true if it is called on
|
||||
// zero container ID.
|
||||
func (id ID) Empty() bool {
|
||||
return id == ID{}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||
|
@ -16,30 +17,32 @@ func randSHA256Checksum() (cs [sha256.Size]byte) {
|
|||
return
|
||||
}
|
||||
|
||||
const emptyID = "11111111111111111111111111111111"
|
||||
|
||||
func TestID_ToV2(t *testing.T) {
|
||||
t.Run("non-nil", func(t *testing.T) {
|
||||
t.Run("non-zero", func(t *testing.T) {
|
||||
checksum := randSHA256Checksum()
|
||||
|
||||
id := cidtest.IDWithChecksum(checksum)
|
||||
|
||||
idV2 := id.ToV2()
|
||||
var idV2 refs.ContainerID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
require.Equal(t, id, cid.NewFromV2(idV2))
|
||||
var newID cid.ID
|
||||
require.NoError(t, newID.ReadFromV2(idV2))
|
||||
|
||||
require.Equal(t, id, newID)
|
||||
require.Equal(t, checksum[:], idV2.GetValue())
|
||||
})
|
||||
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
var x *cid.ID
|
||||
t.Run("zero", func(t *testing.T) {
|
||||
var (
|
||||
x cid.ID
|
||||
v2 refs.ContainerID
|
||||
)
|
||||
|
||||
require.Nil(t, x.ToV2())
|
||||
})
|
||||
|
||||
t.Run("default values", func(t *testing.T) {
|
||||
id := cid.New()
|
||||
|
||||
// convert to v2 message
|
||||
cidV2 := id.ToV2()
|
||||
require.Nil(t, cidV2.GetValue())
|
||||
x.WriteToV2(&v2)
|
||||
require.Equal(t, emptyID, base58.Encode(v2.GetValue()))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -49,57 +52,57 @@ func TestID_Equal(t *testing.T) {
|
|||
id1 := cidtest.IDWithChecksum(cs)
|
||||
id2 := cidtest.IDWithChecksum(cs)
|
||||
|
||||
require.True(t, id1.Equal(id2))
|
||||
require.True(t, id1.Equals(id2))
|
||||
|
||||
id3 := cidtest.ID()
|
||||
|
||||
require.False(t, id1.Equal(id3))
|
||||
require.False(t, id1.Equals(id3))
|
||||
}
|
||||
|
||||
func TestID_String(t *testing.T) {
|
||||
t.Run("Parse/String", func(t *testing.T) {
|
||||
t.Run("DecodeString/EncodeToString", func(t *testing.T) {
|
||||
id := cidtest.ID()
|
||||
id2 := cid.New()
|
||||
var id2 cid.ID
|
||||
|
||||
require.NoError(t, id2.Parse(id.String()))
|
||||
require.NoError(t, id2.DecodeString(id.String()))
|
||||
require.Equal(t, id, id2)
|
||||
})
|
||||
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
id := cid.New()
|
||||
t.Run("zero", func(t *testing.T) {
|
||||
var id cid.ID
|
||||
|
||||
require.Empty(t, id.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestContainerIDEncoding(t *testing.T) {
|
||||
id := cidtest.ID()
|
||||
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
data, err := id.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
id2 := cid.New()
|
||||
require.NoError(t, id2.Unmarshal(data))
|
||||
|
||||
require.Equal(t, id, id2)
|
||||
})
|
||||
|
||||
t.Run("json", func(t *testing.T) {
|
||||
data, err := id.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
|
||||
a2 := cid.New()
|
||||
require.NoError(t, a2.UnmarshalJSON(data))
|
||||
|
||||
require.Equal(t, id, a2)
|
||||
require.Equal(t, emptyID, id.EncodeToString())
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewFromV2(t *testing.T) {
|
||||
t.Run("from nil", func(t *testing.T) {
|
||||
var x *refs.ContainerID
|
||||
t.Run("from zero", func(t *testing.T) {
|
||||
var (
|
||||
x cid.ID
|
||||
v2 refs.ContainerID
|
||||
)
|
||||
|
||||
require.Nil(t, cid.NewFromV2(x))
|
||||
require.Error(t, x.ReadFromV2(v2))
|
||||
})
|
||||
}
|
||||
|
||||
func TestID_Encode(t *testing.T) {
|
||||
var id cid.ID
|
||||
|
||||
t.Run("panic", func(t *testing.T) {
|
||||
dst := make([]byte, sha256.Size-1)
|
||||
|
||||
require.Panics(t, func() {
|
||||
id.Encode(dst)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("correct", func(t *testing.T) {
|
||||
dst := make([]byte, sha256.Size)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
id.Encode(dst)
|
||||
})
|
||||
require.Equal(t, emptyID, id.EncodeToString())
|
||||
})
|
||||
}
|
||||
|
|
13
container/id/test/doc.go
Normal file
13
container/id/test/doc.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
Package cidtest provides functions for convenient testing of cid package API.
|
||||
|
||||
Note that importing the package into source files is highly discouraged.
|
||||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
import cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||
|
||||
cid := cidtest.ID()
|
||||
// test the value
|
||||
|
||||
*/
|
||||
package cidtest
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// ID returns random cid.ID.
|
||||
func ID() *cid.ID {
|
||||
func ID() cid.ID {
|
||||
checksum := [sha256.Size]byte{}
|
||||
|
||||
rand.Read(checksum[:])
|
||||
|
@ -18,8 +18,8 @@ func ID() *cid.ID {
|
|||
|
||||
// IDWithChecksum returns cid.ID initialized
|
||||
// with specified checksum.
|
||||
func IDWithChecksum(cs [sha256.Size]byte) *cid.ID {
|
||||
id := cid.New()
|
||||
func IDWithChecksum(cs [sha256.Size]byte) cid.ID {
|
||||
var id cid.ID
|
||||
id.SetSHA256(cs)
|
||||
|
||||
return id
|
||||
|
|
|
@ -112,12 +112,12 @@ func (r *Record) AddObjectVersionFilter(m Match, v *version.Version) {
|
|||
}
|
||||
|
||||
// AddObjectIDFilter adds filter by object ID.
|
||||
func (r *Record) AddObjectIDFilter(m Match, id *oid.ID) {
|
||||
func (r *Record) AddObjectIDFilter(m Match, id oid.ID) {
|
||||
r.addObjectReservedFilter(m, fKeyObjID, id)
|
||||
}
|
||||
|
||||
// AddObjectContainerIDFilter adds filter by object container ID.
|
||||
func (r *Record) AddObjectContainerIDFilter(m Match, id *cid.ID) {
|
||||
func (r *Record) AddObjectContainerIDFilter(m Match, id cid.ID) {
|
||||
r.addObjectReservedFilter(m, fKeyObjContainerID, id)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,19 @@ import (
|
|||
// Table is compatible with v2 acl.EACLTable message.
|
||||
type Table struct {
|
||||
version version.Version
|
||||
cid *cid.ID
|
||||
cid cid.ID
|
||||
token *session.Token
|
||||
sig *signature.Signature
|
||||
records []Record
|
||||
}
|
||||
|
||||
// CID returns identifier of the container that should use given access control rules.
|
||||
func (t Table) CID() *cid.ID {
|
||||
func (t Table) CID() cid.ID {
|
||||
return t.cid
|
||||
}
|
||||
|
||||
// SetCID sets identifier of the container that should use given access control rules.
|
||||
func (t *Table) SetCID(cid *cid.ID) {
|
||||
func (t *Table) SetCID(cid cid.ID) {
|
||||
t.cid = cid
|
||||
}
|
||||
|
||||
|
@ -85,9 +85,11 @@ func (t *Table) ToV2() *v2acl.Table {
|
|||
}
|
||||
|
||||
v2 := new(v2acl.Table)
|
||||
var cidV2 refs.ContainerID
|
||||
|
||||
if t.cid != nil {
|
||||
v2.SetContainerID(t.cid.ToV2())
|
||||
if !t.cid.Empty() {
|
||||
t.cid.WriteToV2(&cidV2)
|
||||
v2.SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
if t.records != nil {
|
||||
|
@ -124,7 +126,7 @@ func NewTable() *Table {
|
|||
// CreateTable creates, initializes with parameters and returns Table instance.
|
||||
func CreateTable(cid cid.ID) *Table {
|
||||
t := NewTable()
|
||||
t.SetCID(&cid)
|
||||
t.SetCID(cid)
|
||||
|
||||
return t
|
||||
}
|
||||
|
@ -148,8 +150,8 @@ func NewTableFromV2(table *v2acl.Table) *Table {
|
|||
|
||||
// set container id
|
||||
if id := table.GetContainerID(); id != nil {
|
||||
if t.cid == nil {
|
||||
t.cid = new(cid.ID)
|
||||
if t.cid.Empty() {
|
||||
t.cid = cid.ID{}
|
||||
}
|
||||
|
||||
var h [sha256.Size]byte
|
||||
|
@ -205,7 +207,7 @@ func (t *Table) UnmarshalJSON(data []byte) error {
|
|||
|
||||
// EqualTables compares Table with each other.
|
||||
func EqualTables(t1, t2 Table) bool {
|
||||
if !t1.CID().Equal(t2.CID()) ||
|
||||
if !t1.CID().Equals(t2.CID()) ||
|
||||
!t1.Version().Equal(t2.Version()) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestTable(t *testing.T) {
|
|||
t.Run("create table", func(t *testing.T) {
|
||||
id := cidtest.ID()
|
||||
|
||||
table := eacl.CreateTable(*id)
|
||||
table := eacl.CreateTable(id)
|
||||
require.Equal(t, id, table.CID())
|
||||
require.Equal(t, version.Current(), table.Version())
|
||||
})
|
||||
|
@ -124,7 +124,7 @@ func TestTable_ToV2(t *testing.T) {
|
|||
// check initial values
|
||||
require.Equal(t, version.Current(), table.Version())
|
||||
require.Nil(t, table.Records())
|
||||
require.Nil(t, table.CID())
|
||||
require.True(t, table.CID().Empty())
|
||||
require.Nil(t, table.SessionToken())
|
||||
require.Nil(t, table.Signature())
|
||||
|
||||
|
|
14
ns/dns.go
14
ns/dns.go
|
@ -16,20 +16,20 @@ type DNS struct{}
|
|||
// Otherwise, returns an error.
|
||||
//
|
||||
// See also net.LookupTXT.
|
||||
func (x *DNS) ResolveContainerName(name string) (*cid.ID, error) {
|
||||
func (x *DNS) ResolveContainerName(name string) (id cid.ID, err error) {
|
||||
records, err := net.LookupTXT(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
|
||||
var id cid.ID
|
||||
|
||||
for i := range records {
|
||||
err = id.Parse(records[i])
|
||||
err = id.DecodeString(records[i])
|
||||
if err == nil {
|
||||
return &id, nil
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errNotFound
|
||||
err = errNotFound
|
||||
|
||||
return
|
||||
}
|
||||
|
|
20
ns/nns.go
20
ns/nns.go
|
@ -114,7 +114,7 @@ func (n *NNS) Dial(address string) error {
|
|||
// ResolveContainerName MUST NOT be called before successful Dial.
|
||||
//
|
||||
// See also https://docs.neo.org/docs/en-us/reference/nns.html.
|
||||
func (n *NNS) ResolveContainerName(name string) (*cid.ID, error) {
|
||||
func (n *NNS) ResolveContainerName(name string) (cid.ID, error) {
|
||||
res, err := n.neoClient.call(n.nnsContract, "resolve", []smartcontract.Parameter{
|
||||
{
|
||||
Type: smartcontract.StringType,
|
||||
|
@ -126,25 +126,25 @@ func (n *NNS) ResolveContainerName(name string) (*cid.ID, error) {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invoke NNS contract: %w", err)
|
||||
return cid.ID{}, fmt.Errorf("invoke NNS contract: %w", err)
|
||||
}
|
||||
|
||||
if res.State != vm.HaltState.String() {
|
||||
return nil, fmt.Errorf("NNS contract fault exception: %s", res.FaultException)
|
||||
return cid.ID{}, fmt.Errorf("NNS contract fault exception: %s", res.FaultException)
|
||||
} else if len(res.Stack) == 0 {
|
||||
return nil, errors.New("empty stack in invocation result")
|
||||
return cid.ID{}, errors.New("empty stack in invocation result")
|
||||
}
|
||||
|
||||
itemArr, err := res.Stack[len(res.Stack)-1].Convert(stackitem.ArrayT) // top stack element is last in the array
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("convert stack item to %s", stackitem.ArrayT)
|
||||
return cid.ID{}, fmt.Errorf("convert stack item to %s", stackitem.ArrayT)
|
||||
}
|
||||
|
||||
if _, ok := itemArr.(stackitem.Null); !ok {
|
||||
arr, ok := itemArr.Value().([]stackitem.Item)
|
||||
if !ok {
|
||||
// unexpected for types from stackitem package
|
||||
return nil, errors.New("invalid cast to stack item slice")
|
||||
return cid.ID{}, errors.New("invalid cast to stack item slice")
|
||||
}
|
||||
|
||||
var id cid.ID
|
||||
|
@ -152,15 +152,15 @@ func (n *NNS) ResolveContainerName(name string) (*cid.ID, error) {
|
|||
for i := range arr {
|
||||
bs, err := arr[i].TryBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("convert array item to byte slice: %w", err)
|
||||
return cid.ID{}, fmt.Errorf("convert array item to byte slice: %w", err)
|
||||
}
|
||||
|
||||
err = id.Parse(string(bs))
|
||||
err = id.DecodeString(string(bs))
|
||||
if err == nil {
|
||||
return &id, nil
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errNotFound
|
||||
return cid.ID{}, errNotFound
|
||||
}
|
||||
|
|
|
@ -45,41 +45,61 @@ func (a *Address) ToV2() *refs.Address {
|
|||
}
|
||||
|
||||
// ContainerID returns container identifier.
|
||||
func (a *Address) ContainerID() *cid.ID {
|
||||
return cid.NewFromV2(
|
||||
(*refs.Address)(a).GetContainerID())
|
||||
func (a *Address) ContainerID() (v cid.ID) {
|
||||
var cID cid.ID
|
||||
v2 := (*refs.Address)(a)
|
||||
|
||||
cidV2 := v2.GetContainerID()
|
||||
if cidV2 != nil {
|
||||
_ = cID.ReadFromV2(*cidV2)
|
||||
}
|
||||
|
||||
return cID
|
||||
}
|
||||
|
||||
// SetContainerID sets container identifier.
|
||||
func (a *Address) SetContainerID(id *cid.ID) {
|
||||
(*refs.Address)(a).SetContainerID(id.ToV2())
|
||||
func (a *Address) SetContainerID(id cid.ID) {
|
||||
var cidV2 refs.ContainerID
|
||||
id.WriteToV2(&cidV2)
|
||||
|
||||
(*refs.Address)(a).SetContainerID(&cidV2)
|
||||
}
|
||||
|
||||
// ObjectID returns object identifier.
|
||||
func (a *Address) ObjectID() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*refs.Address)(a).GetObjectID())
|
||||
func (a *Address) ObjectID() (v oid.ID) {
|
||||
var id oid.ID
|
||||
v2 := (*refs.Address)(a)
|
||||
|
||||
oidV2 := v2.GetObjectID()
|
||||
if oidV2 != nil {
|
||||
_ = id.ReadFromV2(*oidV2)
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
// SetObjectID sets object identifier.
|
||||
func (a *Address) SetObjectID(id *oid.ID) {
|
||||
(*refs.Address)(a).SetObjectID(id.ToV2())
|
||||
func (a *Address) SetObjectID(id oid.ID) {
|
||||
var oidV2 refs.ObjectID
|
||||
id.WriteToV2(&oidV2)
|
||||
|
||||
(*refs.Address)(a).SetObjectID(&oidV2)
|
||||
}
|
||||
|
||||
// Parse converts base58 string representation into Address.
|
||||
func (a *Address) Parse(s string) error {
|
||||
var (
|
||||
err error
|
||||
oid = oid.NewID()
|
||||
id = cid.New()
|
||||
oid oid.ID
|
||||
id cid.ID
|
||||
parts = strings.Split(s, addressSeparator)
|
||||
)
|
||||
|
||||
if len(parts) != addressParts {
|
||||
return errInvalidAddressString
|
||||
} else if err = id.Parse(parts[0]); err != nil {
|
||||
} else if err = id.DecodeString(parts[0]); err != nil {
|
||||
return err
|
||||
} else if err = oid.Parse(parts[1]); err != nil {
|
||||
} else if err = oid.DecodeString(parts[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -107,8 +107,8 @@ func TestNewAddress(t *testing.T) {
|
|||
a := NewAddress()
|
||||
|
||||
// check initial values
|
||||
require.Nil(t, a.ContainerID())
|
||||
require.Nil(t, a.ObjectID())
|
||||
require.True(t, a.ContainerID().Empty())
|
||||
require.True(t, a.ObjectID().Empty())
|
||||
|
||||
// convert to v2 message
|
||||
aV2 := a.ToV2()
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||
sigutil "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
||||
)
|
||||
|
||||
|
@ -55,13 +55,13 @@ func VerifyPayloadChecksum(obj *Object) error {
|
|||
}
|
||||
|
||||
// CalculateID calculates identifier for the object.
|
||||
func CalculateID(obj *Object) (*oid.ID, error) {
|
||||
func CalculateID(obj *Object) (oid.ID, error) {
|
||||
data, err := obj.ToV2().GetHeader().StableMarshal(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return oid.ID{}, err
|
||||
}
|
||||
|
||||
id := oid.NewID()
|
||||
var id oid.ID
|
||||
id.SetSHA256(sha256.Sum256(data))
|
||||
|
||||
return id, nil
|
||||
|
@ -88,43 +88,45 @@ func VerifyID(obj *Object) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if !id.Equal(obj.ID()) {
|
||||
if !id.Equals(obj.ID()) {
|
||||
return errIncorrectID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CalculateIDSignature(key *ecdsa.PrivateKey, id *oid.ID) (*signature.Signature, error) {
|
||||
return sigutil.SignData(
|
||||
key,
|
||||
signatureV2.StableMarshalerWrapper{
|
||||
SM: id.ToV2(),
|
||||
})
|
||||
}
|
||||
|
||||
func CalculateAndSetSignature(key *ecdsa.PrivateKey, obj *Object) error {
|
||||
sig, err := CalculateIDSignature(key, obj.ID())
|
||||
// CalculateAndSetSignature signs id with provided key and sets that signature to
|
||||
// the object.
|
||||
func CalculateAndSetSignature(key ecdsa.PrivateKey, obj *Object) error {
|
||||
sig, err := obj.ID().CalculateIDSignature(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obj.SetSignature(sig)
|
||||
obj.SetSignature(&sig)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func VerifyIDSignature(obj *Object) error {
|
||||
return sigutil.VerifyData(
|
||||
// VerifyIDSignature verifies object ID signature.
|
||||
func (o *Object) VerifyIDSignature() bool {
|
||||
var idV2 refs.ObjectID
|
||||
o.ID().WriteToV2(&idV2)
|
||||
|
||||
sig := o.Signature()
|
||||
|
||||
err := sigutil.VerifyData(
|
||||
signatureV2.StableMarshalerWrapper{
|
||||
SM: obj.ID().ToV2(),
|
||||
SM: &idV2,
|
||||
},
|
||||
obj.Signature(),
|
||||
sig,
|
||||
)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// SetIDWithSignature sets object identifier and signature.
|
||||
func SetIDWithSignature(key *ecdsa.PrivateKey, obj *Object) error {
|
||||
func SetIDWithSignature(key ecdsa.PrivateKey, obj *Object) error {
|
||||
if err := CalculateAndSetID(obj); err != nil {
|
||||
return fmt.Errorf("could not set identifier: %w", err)
|
||||
}
|
||||
|
@ -137,7 +139,7 @@ func SetIDWithSignature(key *ecdsa.PrivateKey, obj *Object) error {
|
|||
}
|
||||
|
||||
// SetVerificationFields calculates and sets all verification fields of the object.
|
||||
func SetVerificationFields(key *ecdsa.PrivateKey, obj *Object) error {
|
||||
func SetVerificationFields(key ecdsa.PrivateKey, obj *Object) error {
|
||||
CalculateAndSetPayloadChecksum(obj)
|
||||
|
||||
return SetIDWithSignature(key, obj)
|
||||
|
@ -156,10 +158,12 @@ func CheckVerificationFields(obj *Object) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var errInvalidSignature = errors.New("invalid signature")
|
||||
|
||||
// CheckHeaderVerificationFields checks all verification fields except payload.
|
||||
func CheckHeaderVerificationFields(obj *Object) error {
|
||||
if err := VerifyIDSignature(obj); err != nil {
|
||||
return fmt.Errorf("invalid signature: %w", err)
|
||||
if !obj.VerifyIDSignature() {
|
||||
return errInvalidSignature
|
||||
}
|
||||
|
||||
if err := VerifyID(obj); err != nil {
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestVerificationFields(t *testing.T) {
|
|||
|
||||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, SetVerificationFields(&p.PrivateKey, obj))
|
||||
require.NoError(t, SetVerificationFields(p.PrivateKey, obj))
|
||||
|
||||
require.NoError(t, CheckVerificationFields(obj))
|
||||
|
||||
|
@ -45,10 +45,10 @@ func TestVerificationFields(t *testing.T) {
|
|||
},
|
||||
{
|
||||
corrupt: func() {
|
||||
obj.ID().ToV2().GetValue()[0]++
|
||||
obj.ToV2().GetObjectID().GetValue()[0]++
|
||||
},
|
||||
restore: func() {
|
||||
obj.ID().ToV2().GetValue()[0]--
|
||||
obj.ToV2().GetObjectID().GetValue()[0]--
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
8
object/id/doc.go
Normal file
8
object/id/doc.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
Package oid provides primitives to work with object identification in NeoFS.
|
||||
|
||||
Using package types in an application is recommended to potentially work with
|
||||
different protocol versions with which these types are compatible.
|
||||
|
||||
*/
|
||||
package oid
|
193
object/id/id.go
193
object/id/id.go
|
@ -1,92 +1,177 @@
|
|||
package oid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||
sigutil "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
||||
)
|
||||
|
||||
// ID represents v2-compatible object identifier.
|
||||
type ID refs.ObjectID
|
||||
|
||||
var errInvalidIDString = errors.New("incorrect format of the string object ID")
|
||||
|
||||
// NewIDFromV2 wraps v2 ObjectID message to ID.
|
||||
// ID represents NeoFS object identifier in a container.
|
||||
//
|
||||
// Nil refs.ObjectID converts to nil.
|
||||
func NewIDFromV2(idV2 *refs.ObjectID) *ID {
|
||||
return (*ID)(idV2)
|
||||
}
|
||||
|
||||
// NewID creates and initializes blank ID.
|
||||
// ID is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/refs.ObjectID
|
||||
// message. See ReadFromV2 / WriteToV2 methods.
|
||||
//
|
||||
// Works similar as NewIDFromV2(new(ObjectID)).
|
||||
// Instances can be created using built-in var declaration.
|
||||
//
|
||||
// Defaults:
|
||||
// - value: nil.
|
||||
func NewID() *ID {
|
||||
return NewIDFromV2(new(refs.ObjectID))
|
||||
}
|
||||
// Note that direct typecast is not safe and may result in loss of compatibility:
|
||||
// _ = ObjectID([32]byte{}) // not recommended
|
||||
type ID [sha256.Size]byte
|
||||
|
||||
// SetSHA256 sets object identifier value to SHA256 checksum.
|
||||
func (id *ID) SetSHA256(v [sha256.Size]byte) {
|
||||
(*refs.ObjectID)(id).SetValue(v[:])
|
||||
}
|
||||
|
||||
// Equal returns true if identifiers are identical.
|
||||
func (id *ID) Equal(id2 *ID) bool {
|
||||
return bytes.Equal(
|
||||
(*refs.ObjectID)(id).GetValue(),
|
||||
(*refs.ObjectID)(id2).GetValue(),
|
||||
)
|
||||
}
|
||||
|
||||
// ToV2 converts ID to v2 ObjectID message.
|
||||
// ReadFromV2 reads ID from the refs.ObjectID message. Returns an error if
|
||||
// the message is malformed according to the NeoFS API V2 protocol.
|
||||
//
|
||||
// Nil ID converts to nil.
|
||||
func (id *ID) ToV2() *refs.ObjectID {
|
||||
return (*refs.ObjectID)(id)
|
||||
// See also WriteToV2.
|
||||
func (id *ID) ReadFromV2(m refs.ObjectID) error {
|
||||
return id.Decode(m.GetValue())
|
||||
}
|
||||
|
||||
// Parse converts base58 string representation into ID.
|
||||
func (id *ID) Parse(s string) error {
|
||||
data, err := base58.Decode(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse object.ID from string: %w", err)
|
||||
} else if len(data) != sha256.Size {
|
||||
return errInvalidIDString
|
||||
// WriteToV2 writes ID to the refs.ObjectID message.
|
||||
// The message must not be nil.
|
||||
//
|
||||
// See also ReadFromV2.
|
||||
func (id ID) WriteToV2(m *refs.ObjectID) {
|
||||
m.SetValue(id[:])
|
||||
}
|
||||
|
||||
(*refs.ObjectID)(id).SetValue(data)
|
||||
// Encode encodes ID into 32 bytes of dst. Panics if
|
||||
// dst length is less than 32.
|
||||
//
|
||||
// Zero ID is all zeros.
|
||||
//
|
||||
// See also Decode.
|
||||
func (id ID) Encode(dst []byte) {
|
||||
if l := len(dst); l < sha256.Size {
|
||||
panic(fmt.Sprintf("destination length is less than %d bytes: %d", sha256.Size, l))
|
||||
}
|
||||
|
||||
copy(dst, id[:])
|
||||
}
|
||||
|
||||
// Decode decodes src bytes into ID.
|
||||
//
|
||||
// Decode expects that src has 32 bytes length. If the input is malformed,
|
||||
// Decode returns an error describing format violation. In this case ID
|
||||
// remains unchanged.
|
||||
//
|
||||
// Decode doesn't mutate src.
|
||||
//
|
||||
// See also Encode.
|
||||
func (id *ID) Decode(src []byte) error {
|
||||
if len(src) != 32 {
|
||||
return fmt.Errorf("invalid length %d", len(src))
|
||||
}
|
||||
|
||||
copy(id[:], src)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns base58 string representation of ID.
|
||||
func (id *ID) String() string {
|
||||
return base58.Encode((*refs.ObjectID)(id).GetValue())
|
||||
// SetSHA256 sets object identifier value to SHA256 checksum.
|
||||
func (id *ID) SetSHA256(v [sha256.Size]byte) {
|
||||
copy(id[:], v[:])
|
||||
}
|
||||
|
||||
// Equals defines a comparison relation between two ID instances.
|
||||
//
|
||||
// Note that comparison using '==' operator is not recommended since it MAY result
|
||||
// in loss of compatibility.
|
||||
func (id ID) Equals(id2 ID) bool {
|
||||
return id == id2
|
||||
}
|
||||
|
||||
// EncodeToString encodes ID into NeoFS API protocol string.
|
||||
//
|
||||
// Zero ID is base58 encoding of 32 zeros.
|
||||
//
|
||||
// See also DecodeString.
|
||||
func (id ID) EncodeToString() string {
|
||||
return base58.Encode(id[:])
|
||||
}
|
||||
|
||||
// DecodeString decodes string into ID according to NeoFS API protocol. Returns
|
||||
// an error if s is malformed.
|
||||
//
|
||||
// See also DecodeString.
|
||||
func (id *ID) DecodeString(s string) error {
|
||||
data, err := base58.Decode(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode base58: %w", err)
|
||||
}
|
||||
|
||||
return id.Decode(data)
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
//
|
||||
// String is designed to be human-readable, and its format MAY differ between
|
||||
// SDK versions. String MAY return same result as EncodeToString. String MUST NOT
|
||||
// be used to encode ID into NeoFS protocol string.
|
||||
func (id ID) String() string {
|
||||
return id.EncodeToString()
|
||||
}
|
||||
|
||||
// CalculateIDSignature signs object id with provided key.
|
||||
func (id ID) CalculateIDSignature(key ecdsa.PrivateKey) (signature.Signature, error) {
|
||||
var idV2 refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
sign, err := sigutil.SignData(&key,
|
||||
signatureV2.StableMarshalerWrapper{
|
||||
SM: &idV2,
|
||||
},
|
||||
)
|
||||
|
||||
return *sign, err
|
||||
}
|
||||
|
||||
// Empty returns true if it is called on
|
||||
// zero object ID.
|
||||
func (id ID) Empty() bool {
|
||||
return id == ID{}
|
||||
}
|
||||
|
||||
// Marshal marshals ID into a protobuf binary form.
|
||||
func (id *ID) Marshal() ([]byte, error) {
|
||||
return (*refs.ObjectID)(id).StableMarshal(nil)
|
||||
func (id ID) Marshal() ([]byte, error) {
|
||||
var v2 refs.ObjectID
|
||||
v2.SetValue(id[:])
|
||||
|
||||
return v2.StableMarshal(nil)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals protobuf binary representation of ID.
|
||||
func (id *ID) Unmarshal(data []byte) error {
|
||||
return (*refs.ObjectID)(id).Unmarshal(data)
|
||||
var v2 refs.ObjectID
|
||||
if err := v2.Unmarshal(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
copy(id[:], v2.GetValue())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON encodes ID to protobuf JSON format.
|
||||
func (id *ID) MarshalJSON() ([]byte, error) {
|
||||
return (*refs.ObjectID)(id).MarshalJSON()
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
var v2 refs.ObjectID
|
||||
v2.SetValue(id[:])
|
||||
|
||||
return v2.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes ID from protobuf JSON format.
|
||||
func (id *ID) UnmarshalJSON(data []byte) error {
|
||||
return (*refs.ObjectID)(id).UnmarshalJSON(data)
|
||||
var v2 refs.ObjectID
|
||||
if err := v2.UnmarshalJSON(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
copy(id[:], v2.GetValue())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func randID(t *testing.T) *ID {
|
||||
id := NewID()
|
||||
const emptyID = "11111111111111111111111111111111"
|
||||
|
||||
func randID(t *testing.T) ID {
|
||||
var id ID
|
||||
id.SetSHA256(randSHA256Checksum(t))
|
||||
|
||||
return id
|
||||
|
@ -26,7 +28,7 @@ func randSHA256Checksum(t *testing.T) (cs [sha256.Size]byte) {
|
|||
}
|
||||
|
||||
func TestIDV2(t *testing.T) {
|
||||
id := NewID()
|
||||
var id ID
|
||||
|
||||
checksum := [sha256.Size]byte{}
|
||||
|
||||
|
@ -35,7 +37,8 @@ func TestIDV2(t *testing.T) {
|
|||
|
||||
id.SetSHA256(checksum)
|
||||
|
||||
idV2 := id.ToV2()
|
||||
var idV2 refs.ObjectID
|
||||
id.WriteToV2(&idV2)
|
||||
|
||||
require.Equal(t, checksum[:], idV2.GetValue())
|
||||
}
|
||||
|
@ -43,17 +46,17 @@ func TestIDV2(t *testing.T) {
|
|||
func TestID_Equal(t *testing.T) {
|
||||
cs := randSHA256Checksum(t)
|
||||
|
||||
id1 := NewID()
|
||||
var id1 ID
|
||||
id1.SetSHA256(cs)
|
||||
|
||||
id2 := NewID()
|
||||
var id2 ID
|
||||
id2.SetSHA256(cs)
|
||||
|
||||
id3 := NewID()
|
||||
var id3 ID
|
||||
id3.SetSHA256(randSHA256Checksum(t))
|
||||
|
||||
require.True(t, id1.Equal(id2))
|
||||
require.False(t, id1.Equal(id3))
|
||||
require.True(t, id1.Equals(id2))
|
||||
require.False(t, id1.Equals(id3))
|
||||
}
|
||||
|
||||
func TestID_Parse(t *testing.T) {
|
||||
|
@ -62,10 +65,14 @@ func TestID_Parse(t *testing.T) {
|
|||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
cs := randSHA256Checksum(t)
|
||||
str := base58.Encode(cs[:])
|
||||
oid := NewID()
|
||||
var oid ID
|
||||
|
||||
require.NoError(t, oid.Parse(str))
|
||||
require.Equal(t, cs[:], oid.ToV2().GetValue())
|
||||
require.NoError(t, oid.DecodeString(str))
|
||||
|
||||
var oidV2 refs.ObjectID
|
||||
oid.WriteToV2(&oidV2)
|
||||
|
||||
require.Equal(t, cs[:], oidV2.GetValue())
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -76,18 +83,18 @@ func TestID_Parse(t *testing.T) {
|
|||
t.Run(strconv.Itoa(j), func(t *testing.T) {
|
||||
cs := []byte{1, 2, 3, 4, 5, byte(j)}
|
||||
str := base58.Encode(cs)
|
||||
oid := NewID()
|
||||
var oid ID
|
||||
|
||||
require.Error(t, oid.Parse(str))
|
||||
require.Error(t, oid.DecodeString(str))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestID_String(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
id := NewID()
|
||||
require.Empty(t, id.String())
|
||||
t.Run("zero", func(t *testing.T) {
|
||||
var id ID
|
||||
require.Equal(t, emptyID, id.EncodeToString())
|
||||
})
|
||||
|
||||
t.Run("should be equal", func(t *testing.T) {
|
||||
|
@ -95,9 +102,9 @@ func TestID_String(t *testing.T) {
|
|||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
cs := randSHA256Checksum(t)
|
||||
str := base58.Encode(cs[:])
|
||||
oid := NewID()
|
||||
var oid ID
|
||||
|
||||
require.NoError(t, oid.Parse(str))
|
||||
require.NoError(t, oid.DecodeString(str))
|
||||
require.Equal(t, str, oid.String())
|
||||
})
|
||||
}
|
||||
|
@ -111,7 +118,7 @@ func TestObjectIDEncoding(t *testing.T) {
|
|||
data, err := id.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
id2 := NewID()
|
||||
var id2 ID
|
||||
require.NoError(t, id2.Unmarshal(data))
|
||||
|
||||
require.Equal(t, id, id2)
|
||||
|
@ -121,36 +128,55 @@ func TestObjectIDEncoding(t *testing.T) {
|
|||
data, err := id.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
|
||||
a2 := NewID()
|
||||
require.NoError(t, a2.UnmarshalJSON(data))
|
||||
var id2 ID
|
||||
require.NoError(t, id2.UnmarshalJSON(data))
|
||||
|
||||
require.Equal(t, id, a2)
|
||||
require.Equal(t, id, id2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewIDFromV2(t *testing.T) {
|
||||
t.Run("from nil", func(t *testing.T) {
|
||||
var x *refs.ObjectID
|
||||
t.Run("from zero", func(t *testing.T) {
|
||||
var (
|
||||
x ID
|
||||
v2 refs.ObjectID
|
||||
)
|
||||
|
||||
require.Nil(t, NewIDFromV2(x))
|
||||
require.Error(t, x.ReadFromV2(v2))
|
||||
})
|
||||
}
|
||||
|
||||
func TestID_ToV2(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
var x *ID
|
||||
t.Run("zero to v2", func(t *testing.T) {
|
||||
var (
|
||||
x ID
|
||||
v2 refs.ObjectID
|
||||
)
|
||||
|
||||
require.Nil(t, x.ToV2())
|
||||
x.WriteToV2(&v2)
|
||||
|
||||
require.Equal(t, sha256.Size, len(v2.GetValue()))
|
||||
require.Equal(t, emptyID, base58.Encode(v2.GetValue()))
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewID(t *testing.T) {
|
||||
t.Run("default values", func(t *testing.T) {
|
||||
id := NewID()
|
||||
func TestID_Encode(t *testing.T) {
|
||||
var id ID
|
||||
|
||||
// convert to v2 message
|
||||
idV2 := id.ToV2()
|
||||
t.Run("panic", func(t *testing.T) {
|
||||
dst := make([]byte, sha256.Size-1)
|
||||
|
||||
require.Nil(t, idV2.GetValue())
|
||||
require.Panics(t, func() {
|
||||
id.Encode(dst)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("correct", func(t *testing.T) {
|
||||
dst := make([]byte, sha256.Size)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
id.Encode(dst)
|
||||
})
|
||||
require.Equal(t, emptyID, id.EncodeToString())
|
||||
})
|
||||
}
|
||||
|
|
13
object/id/test/doc.go
Normal file
13
object/id/test/doc.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
Package oidtest provides functions for convenient testing of oid package API.
|
||||
|
||||
Note that importing the package into source files is highly discouraged.
|
||||
|
||||
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||
import oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||
|
||||
dec := oidtest.ID()
|
||||
// test the value
|
||||
|
||||
*/
|
||||
package oidtest
|
|
@ -1,4 +1,4 @@
|
|||
package test
|
||||
package oidtest
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// ID returns random object.ID.
|
||||
func ID() *oid.ID {
|
||||
func ID() oid.ID {
|
||||
checksum := [sha256.Size]byte{}
|
||||
|
||||
rand.Read(checksum[:])
|
||||
|
@ -18,8 +18,8 @@ func ID() *oid.ID {
|
|||
|
||||
// idWithChecksum returns object.ID initialized
|
||||
// with specified checksum.
|
||||
func idWithChecksum(cs [sha256.Size]byte) *oid.ID {
|
||||
id := oid.NewID()
|
||||
func idWithChecksum(cs [sha256.Size]byte) oid.ID {
|
||||
var id oid.ID
|
||||
id.SetSHA256(cs)
|
||||
|
||||
return id
|
||||
|
|
|
@ -41,8 +41,8 @@ func (x Lock) NumberOfMembers() int {
|
|||
func (x Lock) ReadMembers(buf []oid.ID) {
|
||||
var i int
|
||||
|
||||
(*v2object.Lock)(&x).IterateMembers(func(id refs.ObjectID) {
|
||||
buf[i] = *oid.NewIDFromV2(&id) // need smth better
|
||||
(*v2object.Lock)(&x).IterateMembers(func(idV2 refs.ObjectID) {
|
||||
_ = buf[i].ReadFromV2(idV2)
|
||||
i++
|
||||
})
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ func (x *Lock) WriteMembers(ids []oid.ID) {
|
|||
members = make([]refs.ObjectID, len(ids))
|
||||
|
||||
for i := range ids {
|
||||
members[i] = *ids[i].ToV2() // need smth better
|
||||
ids[i].WriteToV2(&members[i])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
116
object/object.go
116
object/object.go
|
@ -34,7 +34,7 @@ type RequiredFields struct {
|
|||
// InitCreation initializes the object instance with minimum set of required fields.
|
||||
// Object is expected (but not required) to be blank. Object must not be nil.
|
||||
func InitCreation(dst *Object, rf RequiredFields) {
|
||||
dst.SetContainerID(&rf.Container)
|
||||
dst.SetContainerID(rf.Container)
|
||||
dst.SetOwnerID(&rf.Owner)
|
||||
}
|
||||
|
||||
|
@ -86,17 +86,24 @@ func (o *Object) setSplitFields(setter func(*object.SplitHeader)) {
|
|||
}
|
||||
|
||||
// ID returns object identifier.
|
||||
func (o *Object) ID() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*object.Object)(o).
|
||||
GetObjectID(),
|
||||
)
|
||||
func (o *Object) ID() oid.ID {
|
||||
var v oid.ID
|
||||
|
||||
v2 := (*object.Object)(o)
|
||||
if id := v2.GetObjectID(); id != nil {
|
||||
_ = v.ReadFromV2(*v2.GetObjectID())
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// SetID sets object identifier.
|
||||
func (o *Object) SetID(v *oid.ID) {
|
||||
func (o *Object) SetID(v oid.ID) {
|
||||
var v2 refs.ObjectID
|
||||
v.WriteToV2(&v2)
|
||||
|
||||
(*object.Object)(o).
|
||||
SetObjectID(v.ToV2())
|
||||
SetObjectID(&v2)
|
||||
}
|
||||
|
||||
// Signature returns signature of the object identifier.
|
||||
|
@ -154,18 +161,25 @@ func (o *Object) SetPayloadSize(v uint64) {
|
|||
}
|
||||
|
||||
// ContainerID returns identifier of the related container.
|
||||
func (o *Object) ContainerID() *cid.ID {
|
||||
return cid.NewFromV2(
|
||||
(*object.Object)(o).
|
||||
GetHeader().
|
||||
GetContainerID(),
|
||||
)
|
||||
func (o *Object) ContainerID() cid.ID {
|
||||
var cID cid.ID
|
||||
v2 := (*object.Object)(o)
|
||||
|
||||
cidV2 := v2.GetHeader().GetContainerID()
|
||||
if cidV2 != nil {
|
||||
_ = cID.ReadFromV2(*cidV2)
|
||||
}
|
||||
|
||||
return cID
|
||||
}
|
||||
|
||||
// SetContainerID sets identifier of the related container.
|
||||
func (o *Object) SetContainerID(v *cid.ID) {
|
||||
func (o *Object) SetContainerID(v cid.ID) {
|
||||
var cidV2 refs.ContainerID
|
||||
v.WriteToV2(&cidV2)
|
||||
|
||||
o.setHeaderField(func(h *object.Header) {
|
||||
h.SetContainerID(v.ToV2())
|
||||
h.SetContainerID(&cidV2)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -290,33 +304,41 @@ func (o *Object) SetAttributes(v ...Attribute) {
|
|||
}
|
||||
|
||||
// PreviousID returns identifier of the previous sibling object.
|
||||
func (o *Object) PreviousID() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*object.Object)(o).
|
||||
GetHeader().
|
||||
GetSplit().
|
||||
GetPrevious(),
|
||||
)
|
||||
func (o *Object) PreviousID() oid.ID {
|
||||
var v oid.ID
|
||||
v2 := (*object.Object)(o)
|
||||
|
||||
v2Prev := v2.GetHeader().GetSplit().GetPrevious()
|
||||
if v2Prev != nil {
|
||||
_ = v.ReadFromV2(*v2Prev)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// SetPreviousID sets identifier of the previous sibling object.
|
||||
func (o *Object) SetPreviousID(v *oid.ID) {
|
||||
func (o *Object) SetPreviousID(v oid.ID) {
|
||||
var v2 refs.ObjectID
|
||||
v.WriteToV2(&v2)
|
||||
|
||||
o.setSplitFields(func(split *object.SplitHeader) {
|
||||
split.SetPrevious(v.ToV2())
|
||||
split.SetPrevious(&v2)
|
||||
})
|
||||
}
|
||||
|
||||
// Children return list of the identifiers of the child objects.
|
||||
func (o *Object) Children() []oid.ID {
|
||||
ids := (*object.Object)(o).
|
||||
GetHeader().
|
||||
GetSplit().
|
||||
GetChildren()
|
||||
v2 := (*object.Object)(o)
|
||||
ids := v2.GetHeader().GetSplit().GetChildren()
|
||||
|
||||
res := make([]oid.ID, len(ids))
|
||||
var (
|
||||
id oid.ID
|
||||
res = make([]oid.ID, len(ids))
|
||||
)
|
||||
|
||||
for i := range ids {
|
||||
res[i] = *oid.NewIDFromV2(&ids[i])
|
||||
_ = id.ReadFromV2(ids[i])
|
||||
res[i] = id
|
||||
}
|
||||
|
||||
return res
|
||||
|
@ -324,10 +346,14 @@ func (o *Object) Children() []oid.ID {
|
|||
|
||||
// SetChildren sets list of the identifiers of the child objects.
|
||||
func (o *Object) SetChildren(v ...oid.ID) {
|
||||
ids := make([]refs.ObjectID, len(v))
|
||||
var (
|
||||
v2 refs.ObjectID
|
||||
ids = make([]refs.ObjectID, len(v))
|
||||
)
|
||||
|
||||
for i := range v {
|
||||
ids[i] = *v[i].ToV2()
|
||||
v[i].WriteToV2(&v2)
|
||||
ids[i] = v2
|
||||
}
|
||||
|
||||
o.setSplitFields(func(split *object.SplitHeader) {
|
||||
|
@ -406,19 +432,25 @@ func (o *Object) SetSplitID(id *SplitID) {
|
|||
}
|
||||
|
||||
// ParentID returns identifier of the parent object.
|
||||
func (o *Object) ParentID() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*object.Object)(o).
|
||||
GetHeader().
|
||||
GetSplit().
|
||||
GetParent(),
|
||||
)
|
||||
func (o *Object) ParentID() oid.ID {
|
||||
var v oid.ID
|
||||
v2 := (*object.Object)(o)
|
||||
|
||||
v2Par := v2.GetHeader().GetSplit().GetParent()
|
||||
if v2Par != nil {
|
||||
_ = v.ReadFromV2(*v2Par)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// SetParentID sets identifier of the parent object.
|
||||
func (o *Object) SetParentID(v *oid.ID) {
|
||||
func (o *Object) SetParentID(v oid.ID) {
|
||||
var v2 refs.ObjectID
|
||||
v.WriteToV2(&v2)
|
||||
|
||||
o.setSplitFields(func(split *object.SplitHeader) {
|
||||
split.SetParent(v.ToV2())
|
||||
split.SetParent(&v2)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
func TestInitCreation(t *testing.T) {
|
||||
var o object.Object
|
||||
cnr := *cidtest.ID()
|
||||
cnr := cidtest.ID()
|
||||
own := *ownertest.ID()
|
||||
|
||||
object.InitCreation(&o, object.RequiredFields{
|
||||
|
@ -19,6 +19,6 @@ func TestInitCreation(t *testing.T) {
|
|||
Owner: own,
|
||||
})
|
||||
|
||||
require.Equal(t, &cnr, o.ContainerID())
|
||||
require.Equal(t, cnr, o.ContainerID())
|
||||
require.Equal(t, &own, o.OwnerID())
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func randID(t *testing.T) *oid.ID {
|
||||
id := oid.NewID()
|
||||
func randID(t *testing.T) oid.ID {
|
||||
var id oid.ID
|
||||
id.SetSHA256(randSHA256Checksum(t))
|
||||
|
||||
return id
|
||||
|
@ -177,9 +177,9 @@ func TestObject_SetChildren(t *testing.T) {
|
|||
id1 := randID(t)
|
||||
id2 := randID(t)
|
||||
|
||||
obj.SetChildren(*id1, *id2)
|
||||
obj.SetChildren(id1, id2)
|
||||
|
||||
require.Equal(t, []oid.ID{*id1, *id2}, obj.Children())
|
||||
require.Equal(t, []oid.ID{id1, id2}, obj.Children())
|
||||
}
|
||||
|
||||
func TestObject_SetSplitID(t *testing.T) {
|
||||
|
@ -280,7 +280,7 @@ func TestObject_ResetRelations(t *testing.T) {
|
|||
|
||||
obj.ResetRelations()
|
||||
|
||||
require.Nil(t, obj.PreviousID())
|
||||
require.True(t, obj.PreviousID().Empty())
|
||||
}
|
||||
|
||||
func TestObject_HasParent(t *testing.T) {
|
||||
|
|
|
@ -220,7 +220,7 @@ func (f *SearchFilters) AddObjectVersionFilter(op SearchMatchType, v *version.Ve
|
|||
f.addReservedFilter(op, fKeyVersion, v)
|
||||
}
|
||||
|
||||
func (f *SearchFilters) AddObjectContainerIDFilter(m SearchMatchType, id *cid.ID) {
|
||||
func (f *SearchFilters) AddObjectContainerIDFilter(m SearchMatchType, id cid.ID) {
|
||||
f.addReservedFilter(m, fKeyContainerID, id)
|
||||
}
|
||||
|
||||
|
@ -261,12 +261,12 @@ func (f *SearchFilters) AddPhyFilter() {
|
|||
}
|
||||
|
||||
// AddParentIDFilter adds filter by parent identifier.
|
||||
func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id *oid.ID) {
|
||||
func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id oid.ID) {
|
||||
f.addReservedFilter(m, fKeyParent, id)
|
||||
}
|
||||
|
||||
// AddObjectIDFilter adds filter by object identifier.
|
||||
func (f *SearchFilters) AddObjectIDFilter(m SearchMatchType, id *oid.ID) {
|
||||
func (f *SearchFilters) AddObjectIDFilter(m SearchMatchType, id oid.ID) {
|
||||
f.addReservedFilter(m, fKeyObjectID, id)
|
||||
}
|
||||
|
||||
|
|
|
@ -100,12 +100,12 @@ func TestSearchFilters_AddPhyFilter(t *testing.T) {
|
|||
require.Equal(t, "", f.Value())
|
||||
}
|
||||
|
||||
func testOID() *oid.ID {
|
||||
func testOID() oid.ID {
|
||||
cs := [sha256.Size]byte{}
|
||||
|
||||
rand.Read(cs[:])
|
||||
|
||||
id := oid.NewID()
|
||||
var id oid.ID
|
||||
id.SetSHA256(cs)
|
||||
|
||||
return id
|
||||
|
|
|
@ -2,6 +2,7 @@ package object
|
|||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
)
|
||||
|
||||
|
@ -40,22 +41,42 @@ func (s *SplitInfo) SetSplitID(v *SplitID) {
|
|||
(*object.SplitInfo)(s).SetSplitID(v.ToV2())
|
||||
}
|
||||
|
||||
func (s *SplitInfo) LastPart() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*object.SplitInfo)(s).GetLastPart())
|
||||
func (s SplitInfo) LastPart() oid.ID {
|
||||
var id oid.ID
|
||||
v2 := (object.SplitInfo)(s)
|
||||
|
||||
lpV2 := v2.GetLastPart()
|
||||
if lpV2 != nil {
|
||||
_ = id.ReadFromV2(*lpV2)
|
||||
}
|
||||
|
||||
func (s *SplitInfo) SetLastPart(v *oid.ID) {
|
||||
(*object.SplitInfo)(s).SetLastPart(v.ToV2())
|
||||
return id
|
||||
}
|
||||
|
||||
func (s *SplitInfo) Link() *oid.ID {
|
||||
return oid.NewIDFromV2(
|
||||
(*object.SplitInfo)(s).GetLink())
|
||||
func (s *SplitInfo) SetLastPart(v oid.ID) {
|
||||
var idV2 refs.ObjectID
|
||||
v.WriteToV2(&idV2)
|
||||
|
||||
(*object.SplitInfo)(s).SetLastPart(&idV2)
|
||||
}
|
||||
|
||||
func (s *SplitInfo) SetLink(v *oid.ID) {
|
||||
(*object.SplitInfo)(s).SetLink(v.ToV2())
|
||||
func (s SplitInfo) Link() oid.ID {
|
||||
var id oid.ID
|
||||
v2 := (object.SplitInfo)(s)
|
||||
|
||||
linkV2 := v2.GetLink()
|
||||
if linkV2 != nil {
|
||||
_ = id.ReadFromV2(*linkV2)
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
func (s *SplitInfo) SetLink(v oid.ID) {
|
||||
var idV2 refs.ObjectID
|
||||
v.WriteToV2(&idV2)
|
||||
|
||||
(*object.SplitInfo)(s).SetLink(&idV2)
|
||||
}
|
||||
|
||||
func (s *SplitInfo) Marshal() ([]byte, error) {
|
||||
|
|
|
@ -45,11 +45,11 @@ func TestSplitInfo(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func generateID() *oid.ID {
|
||||
func generateID() oid.ID {
|
||||
var buf [32]byte
|
||||
_, _ = rand.Read(buf[:])
|
||||
|
||||
id := oid.NewID()
|
||||
var id oid.ID
|
||||
id.SetSHA256(buf)
|
||||
|
||||
return id
|
||||
|
@ -77,8 +77,8 @@ func TestNewSplitInfo(t *testing.T) {
|
|||
|
||||
// check initial values
|
||||
require.Nil(t, si.SplitID())
|
||||
require.Nil(t, si.LastPart())
|
||||
require.Nil(t, si.Link())
|
||||
require.True(t, si.LastPart().Empty())
|
||||
require.True(t, si.Link().Empty())
|
||||
|
||||
// convert to v2 message
|
||||
siV2 := si.ToV2()
|
||||
|
|
|
@ -57,7 +57,7 @@ func generate(withParent bool) *object.Object {
|
|||
x.SetCreationEpoch(222)
|
||||
x.SetPreviousID(oidtest.ID())
|
||||
x.SetParentID(oidtest.ID())
|
||||
x.SetChildren(*oidtest.ID(), *oidtest.ID())
|
||||
x.SetChildren(oidtest.ID(), oidtest.ID())
|
||||
x.SetAttributes(*Attribute(), *Attribute())
|
||||
x.SetSplitID(SplitID())
|
||||
x.SetPayloadChecksum(checksumtest.Checksum())
|
||||
|
@ -88,7 +88,7 @@ func Tombstone() *object.Tombstone {
|
|||
|
||||
x.SetSplitID(SplitID())
|
||||
x.SetExpirationEpoch(13)
|
||||
x.SetMembers([]oid.ID{*oidtest.ID(), *oidtest.ID()})
|
||||
x.SetMembers([]oid.ID{oidtest.ID(), oidtest.ID()})
|
||||
|
||||
return x
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ func SearchFilters() object.SearchFilters {
|
|||
// Lock returns random object.Lock.
|
||||
func Lock() *object.Lock {
|
||||
var l object.Lock
|
||||
l.WriteMembers([]oid.ID{*oidtest.ID(), *oidtest.ID()})
|
||||
l.WriteMembers([]oid.ID{oidtest.ID(), oidtest.ID()})
|
||||
|
||||
return &l
|
||||
}
|
||||
|
|
|
@ -56,17 +56,21 @@ func (t *Tombstone) SetSplitID(v *SplitID) {
|
|||
|
||||
// Members returns list of objects to be deleted.
|
||||
func (t *Tombstone) Members() []oid.ID {
|
||||
msV2 := (*tombstone.Tombstone)(t).
|
||||
GetMembers()
|
||||
v2 := (*tombstone.Tombstone)(t)
|
||||
msV2 := v2.GetMembers()
|
||||
|
||||
if msV2 == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ms := make([]oid.ID, len(msV2))
|
||||
var (
|
||||
ms = make([]oid.ID, len(msV2))
|
||||
id oid.ID
|
||||
)
|
||||
|
||||
for i := range msV2 {
|
||||
ms[i] = *oid.NewIDFromV2(&msV2[i])
|
||||
_ = id.ReadFromV2(msV2[i])
|
||||
ms[i] = id
|
||||
}
|
||||
|
||||
return ms
|
||||
|
@ -86,8 +90,11 @@ func (t *Tombstone) SetMembers(v []oid.ID) {
|
|||
ms = make([]refs.ObjectID, 0, ln)
|
||||
}
|
||||
|
||||
var idV2 refs.ObjectID
|
||||
|
||||
for i := range v {
|
||||
ms = append(ms, *v[i].ToV2())
|
||||
v[i].WriteToV2(&idV2)
|
||||
ms = append(ms, idV2)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ func generateIDList(sz int) []oid.ID {
|
|||
cs := [sha256.Size]byte{}
|
||||
|
||||
for i := 0; i < sz; i++ {
|
||||
res[i] = *oid.NewID()
|
||||
var oID oid.ID
|
||||
|
||||
res[i] = oID
|
||||
rand.Read(cs[:])
|
||||
res[i].SetSHA256(cs)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
)
|
||||
|
@ -43,8 +44,17 @@ func (x *ContainerContext) ToV2() *session.ContainerSessionContext {
|
|||
func (x *ContainerContext) ApplyTo(id *cid.ID) {
|
||||
v2 := (*session.ContainerSessionContext)(x)
|
||||
|
||||
var cidV2 *refs.ContainerID
|
||||
|
||||
if id != nil {
|
||||
var c refs.ContainerID
|
||||
id.WriteToV2(&c)
|
||||
|
||||
cidV2 = &c
|
||||
}
|
||||
|
||||
v2.SetWildcard(id == nil)
|
||||
v2.SetContainerID(id.ToV2())
|
||||
v2.SetContainerID(cidV2)
|
||||
}
|
||||
|
||||
// ApplyToAllContainers is a helper function that conveniently
|
||||
|
@ -65,7 +75,15 @@ func (x *ContainerContext) Container() *cid.ID {
|
|||
return nil
|
||||
}
|
||||
|
||||
return cid.NewFromV2(v2.ContainerID())
|
||||
cidV2 := v2.ContainerID()
|
||||
if cidV2 == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cID cid.ID
|
||||
_ = cID.ReadFromV2(*cidV2)
|
||||
|
||||
return &cID
|
||||
}
|
||||
|
||||
func (x *ContainerContext) forVerb(v session.ContainerSessionVerb) {
|
||||
|
|
|
@ -39,9 +39,9 @@ func TestContainerContext_ApplyTo(t *testing.T) {
|
|||
id := cidtest.ID()
|
||||
|
||||
t.Run("method", func(t *testing.T) {
|
||||
c.ApplyTo(id)
|
||||
c.ApplyTo(&id)
|
||||
|
||||
require.Equal(t, id, c.Container())
|
||||
require.Equal(t, id, *c.Container())
|
||||
|
||||
c.ApplyTo(nil)
|
||||
|
||||
|
@ -49,7 +49,7 @@ func TestContainerContext_ApplyTo(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("helper functions", func(t *testing.T) {
|
||||
c.ApplyTo(id)
|
||||
c.ApplyTo(&id)
|
||||
|
||||
session.ApplyToAllContainers(c)
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ func ContainerContext() *session.ContainerContext {
|
|||
|
||||
setters[rand.Uint32()%uint32(len(setters))]()
|
||||
|
||||
c.ApplyTo(cidtest.ID())
|
||||
cID := cidtest.ID()
|
||||
c.ApplyTo(&cID)
|
||||
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ func (sg *StorageGroup) Members() []oid.ID {
|
|||
m := make([]oid.ID, len(mV2))
|
||||
|
||||
for i := range mV2 {
|
||||
m[i] = *oid.NewIDFromV2(&mV2[i])
|
||||
_ = m[i].ReadFromV2(mV2[i])
|
||||
}
|
||||
|
||||
return m
|
||||
|
@ -115,8 +115,11 @@ func (sg *StorageGroup) SetMembers(members []oid.ID) {
|
|||
mV2 = make([]refs.ObjectID, ln)
|
||||
}
|
||||
|
||||
var oidV2 refs.ObjectID
|
||||
|
||||
for i := 0; i < ln; i++ {
|
||||
mV2[i] = *members[i].ToV2()
|
||||
members[i].WriteToV2(&oidV2)
|
||||
mV2[i] = oidV2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestStorageGroup(t *testing.T) {
|
|||
sg.SetExpirationEpoch(exp)
|
||||
require.Equal(t, exp, sg.ExpirationEpoch())
|
||||
|
||||
members := []oid.ID{*oidtest.ID(), *oidtest.ID()}
|
||||
members := []oid.ID{oidtest.ID(), oidtest.ID()}
|
||||
sg.SetMembers(members)
|
||||
require.Equal(t, members, sg.Members())
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ func StorageGroup() *storagegroup.StorageGroup {
|
|||
x.SetExpirationEpoch(66)
|
||||
x.SetValidationDataSize(322)
|
||||
x.SetValidationDataHash(checksumtest.Checksum())
|
||||
x.SetMembers([]oid.ID{*oidtest.ID(), *oidtest.ID()})
|
||||
x.SetMembers([]oid.ID{oidtest.ID(), oidtest.ID()})
|
||||
|
||||
return x
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue