diff --git a/pkg/neofs/client-plant.go b/pkg/neofs/client-plant.go deleted file mode 100644 index 6cf4d900..00000000 --- a/pkg/neofs/client-plant.go +++ /dev/null @@ -1,39 +0,0 @@ -package neofs - -import ( - "context" - "crypto/ecdsa" - - "github.com/nspcc-dev/neofs-api-go/pkg/client" - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - "github.com/nspcc-dev/neofs-api-go/pkg/token" - "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" -) - -// ClientPlant provides connections to NeoFS nodes from pool and allows to -// get local owner ID. -type ClientPlant interface { - ConnectionArtifacts() (client.Client, *token.SessionToken, error) - OwnerID() *owner.ID -} - -type neofsClientPlant struct { - key *ecdsa.PrivateKey - ownerID *owner.ID - pool pool.Pool -} - -// ConnectionArtifacts returns connection from pool. -func (cp *neofsClientPlant) ConnectionArtifacts() (client.Client, *token.SessionToken, error) { - return cp.pool.ConnectionArtifacts() -} - -// OwnerID returns plant's owner ID. -func (cp *neofsClientPlant) OwnerID() *owner.ID { - return cp.ownerID -} - -// NewClientPlant creates new ClientPlant from given context, pool and credentials. -func NewClientPlant(ctx context.Context, pool pool.Pool, creds Credentials) (ClientPlant, error) { - return &neofsClientPlant{key: creds.PrivateKey(), ownerID: creds.Owner(), pool: pool}, nil -} diff --git a/pkg/neofs/credentials.go b/pkg/neofs/credentials.go deleted file mode 100644 index c229468d..00000000 --- a/pkg/neofs/credentials.go +++ /dev/null @@ -1,78 +0,0 @@ -package neofs - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "math/big" - - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - crypto "github.com/nspcc-dev/neofs-crypto" -) - -type ( - // Credentials contains methods that needed to work with NeoFS. - Credentials interface { - Owner() *owner.ID - PublicKey() *ecdsa.PublicKey - PrivateKey() *ecdsa.PrivateKey - } - - credentials struct { - key *ecdsa.PrivateKey - ownerID *owner.ID - } -) - -// NewCredentials creates an instance of Credentials through string -// representation of secret. It allows passing WIF, path, hex-encoded and others. -func NewCredentials(secret string) (Credentials, error) { - key, err := crypto.LoadPrivateKey(secret) - if err != nil { - return nil, err - } - return setFromPrivateKey(key) -} - -// NewEphemeralCredentials creates new private key and Credentials based on that -// key. -func NewEphemeralCredentials() (Credentials, error) { - c := elliptic.P256() - priv, x, y, err := elliptic.GenerateKey(c, rand.Reader) - if err != nil { - return nil, err - } - key := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: c, - X: x, - Y: y, - }, - D: new(big.Int).SetBytes(priv), - } - return setFromPrivateKey(key) -} - -// PrivateKey returns ecdsa.PrivateKey. -func (c *credentials) PrivateKey() *ecdsa.PrivateKey { - return c.key -} - -// PublicKey returns ecdsa.PublicKey. -func (c *credentials) PublicKey() *ecdsa.PublicKey { - return &c.key.PublicKey -} - -// Owner returns owner.ID. -func (c *credentials) Owner() *owner.ID { - return c.ownerID -} - -func setFromPrivateKey(key *ecdsa.PrivateKey) (*credentials, error) { - wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) - if err != nil { - return nil, err - } - ownerID := owner.NewIDFromNeo3Wallet(wallet) - return &credentials{key: key, ownerID: ownerID}, nil -} diff --git a/pkg/pool/key.go b/pkg/pool/key.go new file mode 100644 index 00000000..b7982c75 --- /dev/null +++ b/pkg/pool/key.go @@ -0,0 +1,27 @@ +package pool + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "math/big" +) + +// NewEphemeralKey creates new private key used for NeoFS session. It'll be +// removed after refactoring to use neo-go crypto library. +func NewEphemeralKey() (*ecdsa.PrivateKey, error) { + c := elliptic.P256() + priv, x, y, err := elliptic.GenerateKey(c, rand.Reader) + if err != nil { + return nil, err + } + key := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: c, + X: x, + Y: y, + }, + D: new(big.Int).SetBytes(priv), + } + return key, nil +} diff --git a/pkg/pool/pool.go b/pkg/pool/pool.go index 7dd12212..3aacc469 100644 --- a/pkg/pool/pool.go +++ b/pkg/pool/pool.go @@ -10,6 +10,7 @@ import ( "time" "github.com/nspcc-dev/neofs-api-go/pkg/client" + "github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/token" "google.golang.org/grpc" "google.golang.org/grpc/keepalive" @@ -77,12 +78,13 @@ func (pb *Builder) Build(ctx context.Context, options *BuilderOptions) (Pool, er } options.weights = pb.weights options.connections = cons - return new(ctx, options) + return newPool(ctx, options) } // Pool is an interface providing connection artifacts on request. type Pool interface { - ConnectionArtifacts() (client.Client, *token.SessionToken, error) + Connection() (client.Client, *token.SessionToken, error) + OwnerID() *owner.ID } type clientPack struct { @@ -94,10 +96,11 @@ type clientPack struct { type pool struct { lock sync.RWMutex sampler *Sampler + owner *owner.ID clientPacks []*clientPack } -func new(ctx context.Context, options *BuilderOptions) (Pool, error) { +func newPool(ctx context.Context, options *BuilderOptions) (Pool, error) { clientPacks := make([]*clientPack, len(options.weights)) for i, con := range options.connections { c, err := client.New(client.WithDefaultPrivateKey(options.Key), client.WithGRPCConnection(con)) @@ -116,7 +119,13 @@ func new(ctx context.Context, options *BuilderOptions) (Pool, error) { } source := rand.NewSource(time.Now().UnixNano()) sampler := NewSampler(options.weights, source) - pool := &pool{sampler: sampler, clientPacks: clientPacks} + wallet, err := owner.NEO3WalletFromPublicKey(&options.Key.PublicKey) + if err != nil { + return nil, err + } + ownerID := owner.NewIDFromNeo3Wallet(wallet) + + pool := &pool{sampler: sampler, owner: ownerID, clientPacks: clientPacks} go func() { ticker := time.NewTimer(options.ClientRebalanceInterval) for range ticker.C { @@ -139,7 +148,7 @@ func new(ctx context.Context, options *BuilderOptions) (Pool, error) { return pool, nil } -func (p *pool) ConnectionArtifacts() (client.Client, *token.SessionToken, error) { +func (p *pool) Connection() (client.Client, *token.SessionToken, error) { p.lock.RLock() defer p.lock.RUnlock() if len(p.clientPacks) == 1 { @@ -158,3 +167,7 @@ func (p *pool) ConnectionArtifacts() (client.Client, *token.SessionToken, error) } return nil, nil, errors.New("no healthy client") } + +func (p *pool) OwnerID() *owner.ID { + return p.owner +}