storj/pkg/piecestore/psclient/pieceranger.go
Natalie Villasana c3d3f41d30 removes some SignedMessage use (#1258)
Removes most instances of pb.SignedMessage (there's more to take out but they shouldn't hurt anyone as is).

There used to be places in psserver where a PieceID was hmac'd with the SatelliteID, which was gotten from a SignedMessage. This PR makes it so some functions access the SatelliteID from the Payer Bandwidth Allocation instead.

This requires passing a SatelliteID into psserver functions where they weren't before, so the following proto messages have been changed:

 * PieceId - satellite_id field added
   This is so the psserver.Piece function has access to the SatelliteID when it needs to get the namespaced pieceID.
   This proto message should probably be renamed to PieceRequest, or a new PieceRequest message should be created so this isn't misnamed.

 * PieceDelete - satellite_id field added
   This is so the psserver.Delete function has access to the SatelliteID when receiving a request to Delete.
2019-02-19 23:36:08 -06:00

85 lines
2.3 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package psclient
import (
"bytes"
"context"
"io"
"io/ioutil"
"github.com/zeebo/errs"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/ranger"
)
// Error is the error class for pieceRanger
var Error = errs.Class("pieceRanger error")
type pieceRanger struct {
c *PieceStore
id PieceID
size int64
stream pb.PieceStoreRoutes_RetrieveClient
pba *pb.PayerBandwidthAllocation
}
// PieceRanger PieceRanger returns a Ranger from a PieceID.
func PieceRanger(ctx context.Context, c *PieceStore, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, pba *pb.PayerBandwidthAllocation) (ranger.Ranger, error) {
piece, err := c.Meta(ctx, id)
if err != nil {
return nil, err
}
return &pieceRanger{c: c, id: id, size: piece.PieceSize, stream: stream, pba: pba}, nil
}
// PieceRangerSize creates a PieceRanger with known size.
// Use it if you know the piece size. This will safe the extra request for
// retrieving the piece size from the piece storage.
func PieceRangerSize(c *PieceStore, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, size int64, pba *pb.PayerBandwidthAllocation) ranger.Ranger {
return &pieceRanger{c: c, id: id, size: size, stream: stream, pba: pba}
}
// Size implements Ranger.Size
func (r *pieceRanger) Size() int64 {
return r.size
}
// Range implements Ranger.Range
func (r *pieceRanger) Range(ctx context.Context, offset, length int64) (io.ReadCloser, error) {
if offset < 0 {
return nil, Error.New("negative offset")
}
if length < 0 {
return nil, Error.New("negative length")
}
if offset+length > r.size {
return nil, Error.New("range beyond end")
}
if length == 0 {
return ioutil.NopCloser(bytes.NewReader([]byte{})), nil
}
// Making a copy, otherwise there will be a data race
// when another goroutine tries to write the cached size
// of this instance at the same time.
pbaClone := r.pba.Clone()
rba := &pb.RenterBandwidthAllocation{
PayerAllocation: pbaClone,
StorageNodeId: r.c.remoteID,
}
// send piece data
if err := r.stream.Send(&pb.PieceRetrieval{
PieceData: &pb.PieceRetrieval_PieceData{Id: r.id.String(), PieceSize: length, Offset: offset},
BandwidthAllocation: rba,
}); err != nil {
return nil, err
}
return NewStreamReader(r.c, r.stream, rba, r.size), nil
}