diff --git a/api/auth/center.go b/api/auth/center.go index e83a5807e..c33e07d81 100644 --- a/api/auth/center.go +++ b/api/auth/center.go @@ -17,7 +17,7 @@ import ( "github.com/nspcc-dev/neofs-s3-gw/authmate" "github.com/nspcc-dev/neofs-s3-gw/creds/bearer" "github.com/nspcc-dev/neofs-s3-gw/creds/hcs" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" + "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "go.uber.org/zap" ) @@ -36,7 +36,7 @@ type ( // Params stores node connection parameters. Params struct { - Client sdk.ClientPlant + Pool pool.Pool Logger *zap.Logger Credential hcs.Credentials } @@ -55,9 +55,9 @@ func (p prs) Seek(_ int64, _ int) (int64, error) { var _ io.ReadSeeker = prs(0) // New creates an instance of AuthCenter. -func New(obj sdk.ClientPlant, key hcs.PrivateKey) Center { +func New(conns pool.Pool, key hcs.PrivateKey) Center { return ¢er{ - cli: bearer.New(obj, key), + cli: bearer.New(conns, key), reg: ®expSubmatcher{re: authorizationFieldRegexp}, } } diff --git a/api/layer/container.go b/api/layer/container.go index 524da132d..d6c720c08 100644 --- a/api/layer/container.go +++ b/api/layer/container.go @@ -42,7 +42,7 @@ func (n *layer) containerInfo(ctx context.Context, cid *container.ID) (*BucketIn } ) - conn, _, err := n.cli.ConnectionArtifacts() + conn, _, err := n.pool.Connection() if err != nil { n.log.Error("failed to get connection from the pool", zap.String("request_id", rid), @@ -92,7 +92,7 @@ func (n *layer) containerList(ctx context.Context) ([]*BucketInfo, error) { rid = api.GetRequestID(ctx) ) - conn, _, err := n.cli.ConnectionArtifacts() + conn, _, err := n.pool.Connection() if err != nil { n.log.Error("failed to get connection from the pool", zap.String("request_id", rid), diff --git a/api/layer/layer.go b/api/layer/layer.go index 27bd5907e..ec41bafe4 100644 --- a/api/layer/layer.go +++ b/api/layer/layer.go @@ -2,6 +2,7 @@ package layer import ( "context" + "crypto/ecdsa" "errors" "fmt" "io" @@ -14,8 +15,6 @@ import ( "github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/token" "github.com/nspcc-dev/neofs-s3-gw/api" - "github.com/nspcc-dev/neofs-s3-gw/creds/neofs" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "go.uber.org/zap" "google.golang.org/grpc/codes" @@ -24,16 +23,16 @@ import ( type ( layer struct { - cli sdk.ClientPlant - log *zap.Logger + pool pool.Pool + log *zap.Logger } // Params stores basic API parameters. Params struct { - Pool pool.Pool - Logger *zap.Logger - Timeout time.Duration - Credential neofs.Credentials + Pool pool.Pool + Logger *zap.Logger + Timeout time.Duration + Key *ecdsa.PrivateKey } // GetObjectParams stores object get request parameters. @@ -98,10 +97,10 @@ var ( // NewLayer creates instance of layer. It checks credentials // and establishes gRPC connection with node. -func NewLayer(log *zap.Logger, cli sdk.ClientPlant) Client { +func NewLayer(log *zap.Logger, conns pool.Pool) Client { return &layer{ - cli: cli, - log: log, + pool: conns, + log: log, } } @@ -111,12 +110,12 @@ func (n *layer) Owner(ctx context.Context) *owner.ID { return tkn.Issuer() } - return n.cli.OwnerID() + return n.pool.OwnerID() } // Get NeoFS Object by refs.Address (should be used by auth.Center). func (n *layer) Get(ctx context.Context, address *object.Address) (*object.Object, error) { - conn, tok, err := n.cli.ConnectionArtifacts() + conn, tok, err := n.pool.Connection() if err != nil { return nil, err } diff --git a/api/layer/object.go b/api/layer/object.go index c24e0e86e..8957ea9ea 100644 --- a/api/layer/object.go +++ b/api/layer/object.go @@ -42,7 +42,7 @@ func (n *layer) objectSearch(ctx context.Context, p *findParams) ([]*object.ID, } else if filename != "" { opts.AddFilter(object.AttributeFileName, filename, object.MatchStringEqual) } - conn, _, err := n.cli.ConnectionArtifacts() + conn, _, err := n.pool.Connection() if err != nil { return nil, err } @@ -65,7 +65,7 @@ func (n *layer) objectFindID(ctx context.Context, p *findParams) (*object.ID, er // objectHead returns all object's headers. func (n *layer) objectHead(ctx context.Context, address *object.Address) (*object.Object, error) { - conn, _, err := n.cli.ConnectionArtifacts() + conn, _, err := n.pool.Connection() if err != nil { return nil, err } @@ -75,7 +75,7 @@ func (n *layer) objectHead(ctx context.Context, address *object.Address) (*objec // objectGet and write it into provided io.Reader. func (n *layer) objectGet(ctx context.Context, p *getParams) (*object.Object, error) { - conn, tok, err := n.cli.ConnectionArtifacts() + conn, tok, err := n.pool.Connection() if err != nil { return nil, err } @@ -135,7 +135,7 @@ func (n *layer) objectPut(ctx context.Context, p *PutObjectParams) (*ObjectInfo, raw.SetAttributes(attributes...) r := newDetector(p.Reader) - conn, tok, err := n.cli.ConnectionArtifacts() + conn, tok, err := n.pool.Connection() if err != nil { return nil, err } @@ -165,7 +165,7 @@ func (n *layer) objectPut(ctx context.Context, p *PutObjectParams) (*ObjectInfo, // objectDelete puts tombstone object into neofs. func (n *layer) objectDelete(ctx context.Context, address *object.Address) error { - conn, _, err := n.cli.ConnectionArtifacts() + conn, _, err := n.pool.Connection() if err != nil { return err } diff --git a/authmate/authmate.go b/authmate/authmate.go index e0509d186..445f071d7 100644 --- a/authmate/authmate.go +++ b/authmate/authmate.go @@ -21,8 +21,7 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/policy" "github.com/nspcc-dev/neofs-s3-gw/creds/bearer" "github.com/nspcc-dev/neofs-s3-gw/creds/hcs" - "github.com/nspcc-dev/neofs-s3-gw/creds/neofs" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" + "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "go.uber.org/zap" ) @@ -34,13 +33,13 @@ const ( // Agent contains client communicating with NeoFS and logger. type Agent struct { - cli sdk.ClientPlant - log *zap.Logger + pool pool.Pool + log *zap.Logger } // New creates an object of type Agent that consists of Client and logger. -func New(log *zap.Logger, client sdk.ClientPlant) *Agent { - return &Agent{log: log, cli: client} +func New(log *zap.Logger, conns pool.Pool) *Agent { + return &Agent{log: log, pool: conns} } type ( @@ -48,7 +47,7 @@ type ( IssueSecretOptions struct { ContainerID *container.ID ContainerFriendlyName string - NEOFSCreds neofs.Credentials + NeoFSKey *ecdsa.PrivateKey OwnerPrivateKey hcs.PrivateKey GatesPublicKeys []hcs.PublicKey EACLRules []byte @@ -75,7 +74,7 @@ type ( ) func (a *Agent) checkContainer(ctx context.Context, cid *container.ID, friendlyName string) (*container.ID, error) { - conn, _, err := a.cli.ConnectionArtifacts() + conn, _, err := a.pool.Connection() if err != nil { return nil, err } @@ -143,17 +142,16 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr return fmt.Errorf("failed to build eacl table: %w", err) } - tkn, err := buildBearerToken(options.NEOFSCreds.PrivateKey(), options.NEOFSCreds.Owner(), table) + tkn, err := buildBearerToken(options.NeoFSKey, table) if err != nil { return fmt.Errorf("failed to build bearer token: %w", err) } a.log.Info("store bearer token into NeoFS", - zap.Stringer("owner_key", options.NEOFSCreds.Owner()), zap.Stringer("owner_tkn", tkn.Issuer())) address, err := bearer. - New(a.cli, options.OwnerPrivateKey). + New(a.pool, options.OwnerPrivateKey). Put(ctx, cid, tkn, options.GatesPublicKeys...) if err != nil { return fmt.Errorf("failed to put bearer token: %w", err) @@ -178,7 +176,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr // ObtainSecret receives an existing secret access key from NeoFS and // writes to io.Writer the secret access key. func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error { - bearerCreds := bearer.New(a.cli, options.GatePrivateKey) + bearerCreds := bearer.New(a.pool, options.GatePrivateKey) address := object.NewAddress() if err := address.Parse(options.SecretAddress); err != nil { return fmt.Errorf("failed to parse secret address: %w", err) @@ -258,7 +256,13 @@ func buildEACLTable(cid *container.ID, eaclTable []byte) (*eacl.Table, error) { return table, nil } -func buildBearerToken(key *ecdsa.PrivateKey, oid *owner.ID, table *eacl.Table) (*token.BearerToken, error) { +func buildBearerToken(key *ecdsa.PrivateKey, table *eacl.Table) (*token.BearerToken, error) { + wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) + if err != nil { + return nil, err + } + oid := owner.NewIDFromNeo3Wallet(wallet) + bearerToken := token.NewBearerToken() bearerToken.SetEACLTable(table) bearerToken.SetOwner(oid) diff --git a/cmd/authmate/main.go b/cmd/authmate/main.go index ac444de44..8f2adea52 100644 --- a/cmd/authmate/main.go +++ b/cmd/authmate/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "crypto/ecdsa" "crypto/rand" "encoding/json" "fmt" @@ -11,11 +12,10 @@ import ( "time" "github.com/nspcc-dev/neofs-api-go/pkg/container" + crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-s3-gw/authmate" "github.com/nspcc-dev/neofs-s3-gw/creds/hcs" - "github.com/nspcc-dev/neofs-s3-gw/creds/neofs" "github.com/nspcc-dev/neofs-s3-gw/internal/version" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "github.com/urfave/cli/v2" "go.uber.org/zap" @@ -231,7 +231,7 @@ func issueSecret() *cli.Command { Action: func(c *cli.Context) error { ctx, log := prepare() - neofsCreds, err := neofs.New(neoFSKeyPathFlag) + key, err := crypto.LoadPrivateKey(neoFSKeyPathFlag) if err != nil { return cli.Exit(fmt.Sprintf("failed to load neofs private key: %s", err), 1) } @@ -239,7 +239,7 @@ func issueSecret() *cli.Command { ctx, cancel := context.WithCancel(ctx) defer cancel() - client, err := createSDKClient(ctx, log, neofsCreds, peerAddressFlag) + client, err := createSDKClient(ctx, log, key, peerAddressFlag) if err != nil { return cli.Exit(fmt.Sprintf("failed to create sdk client: %s", err), 2) } @@ -270,7 +270,7 @@ func issueSecret() *cli.Command { issueSecretOptions := &authmate.IssueSecretOptions{ ContainerID: cid, ContainerFriendlyName: containerFriendlyName, - NEOFSCreds: neofsCreds, + NeoFSKey: key, OwnerPrivateKey: owner.PrivateKey(), GatesPublicKeys: gatesPublicKeys, EACLRules: []byte(eaclRulesFlag), @@ -320,7 +320,7 @@ func obtainSecret() *cli.Command { Action: func(c *cli.Context) error { ctx, log := prepare() - neofsCreds, err := neofs.New(neoFSKeyPathFlag) + key, err := crypto.LoadPrivateKey(neoFSKeyPathFlag) if err != nil { return cli.Exit(fmt.Sprintf("failed to load neofs private key: %s", err), 1) } @@ -328,7 +328,7 @@ func obtainSecret() *cli.Command { ctx, cancel := context.WithCancel(ctx) defer cancel() - client, err := createSDKClient(ctx, log, neofsCreds, peerAddressFlag) + client, err := createSDKClient(ctx, log, key, peerAddressFlag) if err != nil { return cli.Exit(fmt.Sprintf("failed to create sdk client: %s", err), 2) } @@ -365,23 +365,16 @@ func fetchHCSCredentials(val string) (hcs.Credentials, error) { return hcs.NewCredentials(val) } -func createSDKClient(ctx context.Context, log *zap.Logger, neofsCreds neofs.Credentials, peerAddress string) (sdk.ClientPlant, error) { +func createSDKClient(ctx context.Context, log *zap.Logger, key *ecdsa.PrivateKey, peerAddress string) (pool.Pool, error) { log.Debug("prepare connection pool") pb := new(pool.Builder) pb.AddNode(peerAddress, 1) opts := &pool.BuilderOptions{ - Key: neofsCreds.PrivateKey(), + Key: key, NodeConnectionTimeout: poolConnectTimeout, NodeRequestTimeout: poolRequestTimeout, } - conns, err := pb.Build(ctx, opts) - if err != nil { - return nil, fmt.Errorf("failed to create connection pool: %w", err) - } - - log.Debug("prepare sdk client") - - return sdk.NewClientPlant(ctx, conns, neofsCreds) + return pb.Build(ctx, opts) } diff --git a/cmd/s3-gw/app.go b/cmd/s3-gw/app.go index 5ec03f896..cd1e4c7d9 100644 --- a/cmd/s3-gw/app.go +++ b/cmd/s3-gw/app.go @@ -2,17 +2,17 @@ package main import ( "context" + "crypto/ecdsa" "math" "net" "net/http" + crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-s3-gw/api" "github.com/nspcc-dev/neofs-s3-gw/api/auth" "github.com/nspcc-dev/neofs-s3-gw/api/handler" "github.com/nspcc-dev/neofs-s3-gw/api/layer" "github.com/nspcc-dev/neofs-s3-gw/creds/hcs" - "github.com/nspcc-dev/neofs-s3-gw/creds/neofs" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "github.com/spf13/viper" "go.uber.org/zap" @@ -21,13 +21,13 @@ import ( type ( // App is the main application structure. App struct { - cli sdk.ClientPlant - ctr auth.Center - log *zap.Logger - cfg *viper.Viper - tls *tlsConfig - obj layer.Client - api api.Handler + pool pool.Pool + ctr auth.Center + log *zap.Logger + cfg *viper.Viper + tls *tlsConfig + obj layer.Client + api api.Handler maxClients api.MaxClients @@ -44,15 +44,14 @@ type ( func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App { var ( conns pool.Pool + key *ecdsa.PrivateKey err error tls *tlsConfig - cli sdk.ClientPlant caller api.Handler ctr auth.Center obj layer.Client hcsCred hcs.Credentials - nfsCred neofs.Credentials poolPeers = fetchPeers(l, v) @@ -87,7 +86,7 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App { reBalance = v } - if nfsCred, err = neofs.New(nfsCredential); err != nil { + if key, err = crypto.LoadPrivateKey(nfsCredential); err != nil { l.Fatal("could not load NeoFS private key") } @@ -107,7 +106,7 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App { zap.String("NeoFS", nfsCredential)) opts := &pool.BuilderOptions{ - Key: nfsCred.PrivateKey(), + Key: key, NodeConnectionTimeout: conTimeout, NodeRequestTimeout: reqTimeout, ClientRebalanceInterval: reBalance, @@ -120,29 +119,25 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App { if err != nil { l.Fatal("failed to create connection pool", zap.Error(err)) } - cli, err = sdk.NewClientPlant(ctx, conns, nfsCred) - if err != nil { - l.Fatal("failed to create neofs client plant") - } // prepare object layer - obj = layer.NewLayer(l, cli) + obj = layer.NewLayer(l, conns) // prepare auth center - ctr = auth.New(cli, hcsCred.PrivateKey()) + ctr = auth.New(conns, hcsCred.PrivateKey()) if caller, err = handler.New(l, obj); err != nil { l.Fatal("could not initialize API handler", zap.Error(err)) } return &App{ - ctr: ctr, - cli: cli, - log: l, - cfg: v, - obj: obj, - tls: tls, - api: caller, + ctr: ctr, + pool: conns, + log: l, + cfg: v, + obj: obj, + tls: tls, + api: caller, webDone: make(chan struct{}, 1), wrkDone: make(chan struct{}, 1), diff --git a/creds/bearer/credentials.go b/creds/bearer/credentials.go index 81556754e..1d6cf60d6 100644 --- a/creds/bearer/credentials.go +++ b/creds/bearer/credentials.go @@ -14,7 +14,7 @@ import ( "github.com/nspcc-dev/neofs-api-go/pkg/token" "github.com/nspcc-dev/neofs-s3-gw/creds/accessbox" "github.com/nspcc-dev/neofs-s3-gw/creds/hcs" - sdk "github.com/nspcc-dev/neofs-sdk-go/pkg/neofs" + "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" ) type ( @@ -25,8 +25,8 @@ type ( } cred struct { - key hcs.PrivateKey - obj sdk.ClientPlant + key hcs.PrivateKey + pool pool.Pool } ) @@ -46,8 +46,8 @@ var bufferPool = sync.Pool{ var _ = New // New creates new Credentials instance using given cli and key. -func New(cli sdk.ClientPlant, key hcs.PrivateKey) Credentials { - return &cred{obj: cli, key: key} +func New(conns pool.Pool, key hcs.PrivateKey) Credentials { + return &cred{pool: conns, key: key} } func (c *cred) acquireBuffer() *bytes.Buffer { @@ -65,7 +65,7 @@ func (c *cred) Get(ctx context.Context, address *object.Address) (*token.BearerT box := accessbox.NewBearerBox(nil) - conn, tok, err := c.obj.ConnectionArtifacts() + conn, tok, err := c.pool.Connection() if err != nil { return nil, err } @@ -107,7 +107,7 @@ func (c *cred) Put(ctx context.Context, cid *container.ID, tkn *token.BearerToke return nil, err } - conn, tok, err := c.obj.ConnectionArtifacts() + conn, tok, err := c.pool.Connection() if err != nil { return nil, err } diff --git a/creds/neofs/credentials.go b/creds/neofs/credentials.go deleted file mode 100644 index fa25864bb..000000000 --- a/creds/neofs/credentials.go +++ /dev/null @@ -1,71 +0,0 @@ -package neofs - -import ( - "crypto/ecdsa" - - "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 { - WIF() string - Owner() *owner.ID - PublicKey() *ecdsa.PublicKey - PrivateKey() *ecdsa.PrivateKey - } - - cred struct { - key *ecdsa.PrivateKey - owner *owner.ID - wif string - } -) - -// New creates an instance of Credentials through string representation of secret. -// It allows passing WIF, path, hex-encoded and others. -func New(secret string) (Credentials, error) { - key, err := crypto.LoadPrivateKey(secret) - if err != nil { - return nil, err - } - - return setFromPrivateKey(key) -} - -// PrivateKey returns ecdsa.PrivateKey. -func (c *cred) PrivateKey() *ecdsa.PrivateKey { - return c.key -} - -// PublicKey returns ecdsa.PublicKey. -func (c *cred) PublicKey() *ecdsa.PublicKey { - return &c.key.PublicKey -} - -// Owner returns owner.ID. -func (c *cred) Owner() *owner.ID { - return c.owner -} - -// WIF returns string representation of WIF. -func (c *cred) WIF() string { - return c.wif -} - -func setFromPrivateKey(key *ecdsa.PrivateKey) (*cred, error) { - wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) - if err != nil { - return nil, err - } - - ownerID := owner.NewIDFromNeo3Wallet(wallet) - - wif, err := crypto.WIFEncode(key) - if err != nil { - return nil, err - } - - return &cred{key: key, owner: ownerID, wif: wif}, nil -} diff --git a/creds/neofs/credentials_test.go b/creds/neofs/credentials_test.go deleted file mode 100644 index 82e15ae1f..000000000 --- a/creds/neofs/credentials_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package neofs - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "testing" - - "github.com/nspcc-dev/neofs-api-go/pkg/owner" - crypto "github.com/nspcc-dev/neofs-crypto" - "github.com/stretchr/testify/require" -) - -func TestNew(t *testing.T) { - t.Run("should fail", func(t *testing.T) { - cred, err := New("") - require.Nil(t, cred) - require.Error(t, err) - }) - - t.Run("should work as expected", func(t *testing.T) { - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err) - - wif, err := crypto.WIFEncode(key) - require.NoError(t, err) - - wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) - require.NoError(t, err) - - own := owner.NewIDFromNeo3Wallet(wallet) - - cred, err := New(wif) - require.NoError(t, err) - require.Equal(t, cred.WIF(), wif) - require.Equal(t, cred.Owner(), own) - require.Equal(t, cred.PrivateKey(), key) - require.Equal(t, cred.PublicKey(), &key.PublicKey) - }) -} diff --git a/go.mod b/go.mod index 37fc5c554..44921250b 100644 --- a/go.mod +++ b/go.mod @@ -22,3 +22,5 @@ require ( golang.org/x/text v0.3.5 // indirect google.golang.org/grpc v1.36.1 ) + +replace github.com/nspcc-dev/neofs-sdk-go => github.com/roman-khimov/neofs-sdk-go v0.0.0-20210528201347-878f2cd855eb diff --git a/go.sum b/go.sum index 388ca1710..9b1945965 100644 --- a/go.sum +++ b/go.sum @@ -342,8 +342,6 @@ github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnB github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw= github.com/nspcc-dev/neofs-node v1.22.0 h1:TJ4d5zopItYYWMEajegVWBgAw8HjZFe12IkNm3Tt+rk= github.com/nspcc-dev/neofs-node v1.22.0/go.mod h1:ecpXrzIe1vcp5FBjPsIaHKVIVvxsv4GVBCw21WYcY3c= -github.com/nspcc-dev/neofs-sdk-go v0.0.0-20210527182636-cbfc17a1a9a2 h1:z8xtKILKi+Dolk3VAyCaFPMroFnT+x8qTqMT/zBRqIc= -github.com/nspcc-dev/neofs-sdk-go v0.0.0-20210527182636-cbfc17a1a9a2/go.mod h1:QZE7VaNQRyNFS+3gsrNEQEiLe+d6AR6EteX1M9geh6A= github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE= github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= @@ -425,6 +423,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/roman-khimov/neofs-sdk-go v0.0.0-20210528201347-878f2cd855eb h1:zRVPiWiS89g8GRLKqvQ/FYGx+qHmWl/UW6ozGRhkHyY= +github.com/roman-khimov/neofs-sdk-go v0.0.0-20210528201347-878f2cd855eb/go.mod h1:QZE7VaNQRyNFS+3gsrNEQEiLe+d6AR6EteX1M9geh6A= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=