From 63c8d6e9ea914d46bd3ccfec3cafd1a029a8dac9 Mon Sep 17 00:00:00 2001
From: Leonard Lyubich <leonard@nspcc.ru>
Date: Mon, 31 Aug 2020 11:15:46 +0300
Subject: [PATCH] [#128] sdk: Use owner ID instead of NEO3Wallet

Replace owner.NEO3Wallet usage with owner.ID usage. Functions that process
the wallet address convert it to the owner identifier through the public
method.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
---
 pkg/client/accounting.go   | 20 +++++++-------
 pkg/client/container.go    | 33 ++++++++++++------------
 pkg/container/container.go |  6 +----
 pkg/container/opts.go      | 18 ++++++++++---
 pkg/owner/id.go            | 12 ++++-----
 pkg/owner/id_test.go       |  3 +--
 pkg/owner/wallet.go        | 53 ++++++++++++++++++++++++++++++++++++++
 pkg/refs/neo_wallet.go     | 45 --------------------------------
 8 files changed, 101 insertions(+), 89 deletions(-)
 create mode 100644 pkg/owner/wallet.go
 delete mode 100644 pkg/refs/neo_wallet.go

diff --git a/pkg/client/accounting.go b/pkg/client/accounting.go
index 6f34154..4642c9d 100644
--- a/pkg/client/accounting.go
+++ b/pkg/client/accounting.go
@@ -4,24 +4,26 @@ import (
 	"context"
 
 	"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
-	"github.com/nspcc-dev/neofs-api-go/pkg/refs"
+	"github.com/nspcc-dev/neofs-api-go/pkg/owner"
 	v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting"
 	"github.com/nspcc-dev/neofs-api-go/v2/client"
-	v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
 	v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
 	"github.com/pkg/errors"
 )
 
 func (c Client) GetSelfBalance(ctx context.Context, opts ...CallOption) (*accounting.Decimal, error) {
-	owner, err := refs.NEO3WalletFromPublicKey(&c.key.PublicKey)
+	w, err := owner.NEO3WalletFromPublicKey(&c.key.PublicKey)
 	if err != nil {
 		return nil, err
 	}
 
-	return c.GetBalance(ctx, owner, opts...)
+	ownerID := new(owner.ID)
+	ownerID.SetNeo3Wallet(w)
+
+	return c.GetBalance(ctx, ownerID, opts...)
 }
 
-func (c Client) GetBalance(ctx context.Context, owner refs.NEO3Wallet, opts ...CallOption) (*accounting.Decimal, error) {
+func (c Client) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) {
 	// check remote node version
 	switch c.remoteNode.Version.Major {
 	case 2:
@@ -31,19 +33,15 @@ func (c Client) GetBalance(ctx context.Context, owner refs.NEO3Wallet, opts ...C
 	}
 }
 
-func (c Client) getBalanceV2(ctx context.Context, owner refs.NEO3Wallet, opts ...CallOption) (*accounting.Decimal, error) {
+func (c Client) getBalanceV2(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) {
 	// apply all available options
 	callOptions := defaultCallOptions()
 	for i := range opts {
 		opts[i].apply(&callOptions)
 	}
 
-	// create V2 unified structures
-	v2Owner := new(v2refs.OwnerID)
-	v2Owner.SetValue(owner[:])
-
 	reqBody := new(v2accounting.BalanceRequestBody)
-	reqBody.SetOwnerID(v2Owner)
+	reqBody.SetOwnerID(owner.ToV2())
 
 	req := new(v2accounting.BalanceRequest)
 	req.SetBody(reqBody)
diff --git a/pkg/client/container.go b/pkg/client/container.go
index 5e98f08..ef72a83 100644
--- a/pkg/client/container.go
+++ b/pkg/client/container.go
@@ -4,11 +4,11 @@ import (
 	"context"
 
 	"github.com/nspcc-dev/neofs-api-go/pkg/container"
-	"github.com/nspcc-dev/neofs-api-go/pkg/refs"
+	"github.com/nspcc-dev/neofs-api-go/pkg/owner"
 	"github.com/nspcc-dev/neofs-api-go/util/signature"
 	"github.com/nspcc-dev/neofs-api-go/v2/client"
 	v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
-	v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
+	"github.com/nspcc-dev/neofs-api-go/v2/refs"
 	v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
 	"github.com/pkg/errors"
 )
@@ -31,7 +31,7 @@ func (c Client) GetContainer(ctx context.Context, id *container.ID, opts ...Call
 	}
 }
 
-func (c Client) ListContainers(ctx context.Context, owner refs.NEO3Wallet, opts ...CallOption) ([]*container.ID, error) {
+func (c Client) ListContainers(ctx context.Context, owner *owner.ID, opts ...CallOption) ([]*container.ID, error) {
 	switch c.remoteNode.Version.Major {
 	case 2:
 		return c.listContainerV2(ctx, owner, opts...)
@@ -41,12 +41,15 @@ func (c Client) ListContainers(ctx context.Context, owner refs.NEO3Wallet, opts
 }
 
 func (c Client) ListSelfContainers(ctx context.Context, opts ...CallOption) ([]*container.ID, error) {
-	owner, err := refs.NEO3WalletFromPublicKey(&c.key.PublicKey)
+	w, err := owner.NEO3WalletFromPublicKey(&c.key.PublicKey)
 	if err != nil {
 		return nil, err
 	}
 
-	return c.ListContainers(ctx, owner, opts...)
+	ownerID := new(owner.ID)
+	ownerID.SetNeo3Wallet(w)
+
+	return c.ListContainers(ctx, ownerID, opts...)
 }
 
 func (c Client) DeleteContainer(ctx context.Context, id *container.ID, opts ...CallOption) error {
@@ -73,14 +76,15 @@ func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, op
 
 	// if container owner is not set, then use client key as owner
 	if cnr.GetOwnerID() == nil {
-		owner, err := refs.NEO3WalletFromPublicKey(&c.key.PublicKey)
+		w, err := owner.NEO3WalletFromPublicKey(&c.key.PublicKey)
 		if err != nil {
 			return nil, err
 		}
 
-		v2Owner := new(v2refs.OwnerID)
-		v2Owner.SetValue(owner[:])
-		cnr.SetOwnerID(v2Owner)
+		ownerID := new(owner.ID)
+		ownerID.SetNeo3Wallet(w)
+
+		cnr.SetOwnerID(ownerID.ToV2())
 	}
 
 	reqBody := new(v2container.PutRequestBody)
@@ -89,7 +93,7 @@ func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, op
 	// sign container
 	signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
 	err := signature.SignDataWithHandler(c.key, signWrapper, func(key []byte, sig []byte) {
-		containerSignature := new(v2refs.Signature)
+		containerSignature := new(refs.Signature)
 		containerSignature.SetKey(key)
 		containerSignature.SetSign(sig)
 		reqBody.SetSignature(containerSignature)
@@ -181,18 +185,15 @@ func (c Client) getContainerV2(ctx context.Context, id *container.ID, opts ...Ca
 	}
 }
 
-func (c Client) listContainerV2(ctx context.Context, owner refs.NEO3Wallet, opts ...CallOption) ([]*container.ID, error) {
+func (c Client) listContainerV2(ctx context.Context, owner *owner.ID, opts ...CallOption) ([]*container.ID, error) {
 	// apply all available options
 	callOptions := defaultCallOptions()
 	for i := range opts {
 		opts[i].apply(&callOptions)
 	}
 
-	v2owner := new(v2refs.OwnerID)
-	v2owner.SetValue(owner[:])
-
 	reqBody := new(v2container.ListRequestBody)
-	reqBody.SetOwnerID(v2owner)
+	reqBody.SetOwnerID(owner.ToV2())
 
 	req := new(v2container.ListRequest)
 	req.SetBody(reqBody)
@@ -249,7 +250,7 @@ func (c Client) delContainerV2(ctx context.Context, id *container.ID, opts ...Ca
 	// sign container
 	signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainerID()}
 	err := signature.SignDataWithHandler(c.key, signWrapper, func(key []byte, sig []byte) {
-		containerSignature := new(v2refs.Signature)
+		containerSignature := new(refs.Signature)
 		containerSignature.SetKey(key)
 		containerSignature.SetSign(sig)
 		reqBody.SetSignature(containerSignature)
diff --git a/pkg/container/container.go b/pkg/container/container.go
index d142d3e..5626af6 100644
--- a/pkg/container/container.go
+++ b/pkg/container/container.go
@@ -2,7 +2,6 @@ package container
 
 import (
 	"github.com/nspcc-dev/neofs-api-go/v2/container"
-	"github.com/nspcc-dev/neofs-api-go/v2/refs"
 )
 
 type Container struct {
@@ -24,10 +23,7 @@ func New(opts ...NewOption) (*Container, error) {
 	}
 
 	if cnrOptions.owner != nil {
-		owner := new(refs.OwnerID)
-		owner.SetValue(cnrOptions.owner[:])
-
-		cnr.SetOwnerID(owner)
+		cnr.SetOwnerID(cnrOptions.owner.ToV2())
 	}
 
 	attributes := make([]*container.Attribute, len(cnrOptions.attributes))
diff --git a/pkg/container/opts.go b/pkg/container/opts.go
index 507c988..52f663d 100644
--- a/pkg/container/opts.go
+++ b/pkg/container/opts.go
@@ -3,7 +3,7 @@ package container
 import (
 	"github.com/google/uuid"
 	"github.com/nspcc-dev/neofs-api-go/pkg/acl"
-	"github.com/nspcc-dev/neofs-api-go/pkg/refs"
+	"github.com/nspcc-dev/neofs-api-go/pkg/owner"
 )
 
 type (
@@ -20,7 +20,7 @@ type (
 		acl        uint32
 		policy     string
 		attributes []attribute
-		owner      *refs.NEO3Wallet
+		owner      *owner.ID
 		nonce      uuid.UUID
 	}
 )
@@ -75,9 +75,19 @@ func WithNonce(nonce uuid.UUID) NewOption {
 	})
 }
 
-func WithOwner(owner refs.NEO3Wallet) NewOption {
+func WithOwnerID(id *owner.ID) NewOption {
 	return newFuncContainerOption(func(option *containerOptions) {
-		option.owner = &owner
+		option.owner = id
+	})
+}
+
+func WithNEO3Wallet(w *owner.NEO3Wallet) NewOption {
+	return newFuncContainerOption(func(option *containerOptions) {
+		if option.owner == nil {
+			option.owner = new(owner.ID)
+		}
+
+		option.owner.SetNeo3Wallet(w)
 	})
 }
 
diff --git a/pkg/owner/id.go b/pkg/owner/id.go
index d00cd9e..abed3a7 100644
--- a/pkg/owner/id.go
+++ b/pkg/owner/id.go
@@ -3,8 +3,7 @@ package owner
 import (
 	"crypto/sha256"
 
-	"github.com/nspcc-dev/neofs-api-go/pkg/refs"
-	refsV2 "github.com/nspcc-dev/neofs-api-go/v2/refs"
+	"github.com/nspcc-dev/neofs-api-go/v2/refs"
 	"github.com/pkg/errors"
 )
 
@@ -15,16 +14,16 @@ type ID struct {
 }
 
 // SetNeo3Wallet sets owner identifier value to NEO3 wallet address.
-func (id *ID) SetNeo3Wallet(v *refs.NEO3Wallet) {
+func (id *ID) SetNeo3Wallet(v *NEO3Wallet) {
 	if id != nil {
 		id.val = v.Bytes()
 	}
 }
 
 // ToV2 returns the v2 owner ID message.
-func (id *ID) ToV2() *refsV2.OwnerID {
+func (id *ID) ToV2() *refs.OwnerID {
 	if id != nil {
-		idV2 := new(refsV2.OwnerID)
+		idV2 := new(refs.OwnerID)
 		idV2.SetValue(id.val)
 
 		return idV2
@@ -33,7 +32,8 @@ func (id *ID) ToV2() *refsV2.OwnerID {
 	return nil
 }
 
-func IDFromV2(idV2 *refsV2.OwnerID) (*ID, error) {
+// IDFromV2 converts owner ID v2 structure to ID.
+func IDFromV2(idV2 *refs.OwnerID) (*ID, error) {
 	if idV2 == nil {
 		return nil, nil
 	}
diff --git a/pkg/owner/id_test.go b/pkg/owner/id_test.go
index 56c39a6..e7f9ef9 100644
--- a/pkg/owner/id_test.go
+++ b/pkg/owner/id_test.go
@@ -4,14 +4,13 @@ import (
 	"crypto/rand"
 	"testing"
 
-	"github.com/nspcc-dev/neofs-api-go/pkg/refs"
 	"github.com/stretchr/testify/require"
 )
 
 func TestIDV2(t *testing.T) {
 	id := new(ID)
 
-	wallet := new(refs.NEO3Wallet)
+	wallet := new(NEO3Wallet)
 
 	_, err := rand.Read(wallet.Bytes())
 	require.NoError(t, err)
diff --git a/pkg/owner/wallet.go b/pkg/owner/wallet.go
new file mode 100644
index 0000000..80fb889
--- /dev/null
+++ b/pkg/owner/wallet.go
@@ -0,0 +1,53 @@
+package owner
+
+import (
+	"crypto/ecdsa"
+
+	"github.com/mr-tron/base58"
+	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
+	crypto "github.com/nspcc-dev/neofs-crypto"
+	"github.com/pkg/errors"
+)
+
+// NEO3Wallet represents NEO3 wallet address.
+type NEO3Wallet [25]byte
+
+// NEO3WalletFromPublicKey converts public key to NEO3 wallet address.
+func NEO3WalletFromPublicKey(key *ecdsa.PublicKey) (*NEO3Wallet, error) {
+	if key == nil {
+		return nil, crypto.ErrEmptyPublicKey
+	}
+
+	neoPublicKey := keys.PublicKey{
+		X: key.X,
+		Y: key.Y,
+	}
+
+	d, err := base58.Decode(neoPublicKey.Address())
+	if err != nil {
+		return nil, errors.Wrap(err, "can't decode neo3 address from key")
+	}
+
+	w := new(NEO3Wallet)
+
+	copy(w.Bytes(), d)
+
+	return w, nil
+}
+
+func (w *NEO3Wallet) String() string {
+	if w != nil {
+		return base58.Encode(w[:])
+	}
+
+	return ""
+}
+
+// Bytes returns slice of NEO3 wallet address bytes.
+func (w *NEO3Wallet) Bytes() []byte {
+	if w != nil {
+		return w[:]
+	}
+
+	return nil
+}
diff --git a/pkg/refs/neo_wallet.go b/pkg/refs/neo_wallet.go
deleted file mode 100644
index 58f64a8..0000000
--- a/pkg/refs/neo_wallet.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package refs
-
-import (
-	"crypto/ecdsa"
-
-	"github.com/mr-tron/base58"
-	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
-	"github.com/pkg/errors"
-)
-
-type (
-	NEO3Wallet [25]byte
-)
-
-func NEO3WalletFromPublicKey(key *ecdsa.PublicKey) (owner NEO3Wallet, err error) {
-	if key == nil {
-		return owner, errors.New("nil public key")
-	}
-
-	neoPublicKey := keys.PublicKey{
-		X: key.X,
-		Y: key.Y,
-	}
-
-	d, err := base58.Decode(neoPublicKey.Address())
-	if err != nil {
-		return owner, errors.Wrap(err, "can't decode neo3 address from key")
-	}
-
-	copy(owner[:], d)
-
-	return owner, nil
-}
-
-func (w NEO3Wallet) String() string {
-	return base58.Encode(w[:])
-}
-
-func (w *NEO3Wallet) Bytes() []byte {
-	if w != nil {
-		return w[:]
-	}
-
-	return nil
-}