uplink/piecestore: Check SN piece hash timestamp (#3246)

Uplink must verify that every piece upload to a storage node return a
hash whose timestamp isn't older than the maximum elapsed time allowed
by the Satellite.

We cannot leave this check only to the Satellite site, because if there
is no error reported by this matter, the uplink cuts down the long tail.
When uplink submits the result uploads including these invalid ones, the
Satellite filters out the invalid ones and that can provoke that it gets
less than the optimal threshold amount of valid upload results, so it
rejects the request.

Detecting the error at this stage will allow the uplink to detect these
uploads as invalid and avoid to cut down the long tail prematurely.
This commit is contained in:
Ivan Fraixedes 2019-10-15 16:07:18 +02:00 committed by GitHub
parent 875c7dfe72
commit 9caa3181d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ package piecestore
import ( import (
"bytes" "bytes"
"context" "context"
"time"
"github.com/zeebo/errs" "github.com/zeebo/errs"
@ -14,6 +15,8 @@ import (
"storj.io/storj/pkg/signing" "storj.io/storj/pkg/signing"
) )
const pieceHashExpiration = 2 * time.Hour
var ( var (
// ErrInternal is an error class for internal errors. // ErrInternal is an error class for internal errors.
ErrInternal = errs.Class("internal") ErrInternal = errs.Class("internal")
@ -21,6 +24,8 @@ var (
ErrProtocol = errs.Class("protocol") ErrProtocol = errs.Class("protocol")
// ErrVerifyUntrusted is an error in case there is a trust issue. // ErrVerifyUntrusted is an error in case there is a trust issue.
ErrVerifyUntrusted = errs.Class("untrusted") ErrVerifyUntrusted = errs.Class("untrusted")
// ErrStorageNodeInvalidResponse is an error when a storage node returns a response with invalid data
ErrStorageNodeInvalidResponse = errs.Class("storage node has returned an invalid response")
) )
// VerifyPieceHash verifies piece hash which is sent by peer. // VerifyPieceHash verifies piece hash which is sent by peer.
@ -40,5 +45,11 @@ func (client *Client) VerifyPieceHash(ctx context.Context, peer *identity.PeerId
return ErrVerifyUntrusted.New("invalid hash signature: %v", err) // TODO: report rpc status bad message return ErrVerifyUntrusted.New("invalid hash signature: %v", err) // TODO: report rpc status bad message
} }
if hash.Timestamp.Before(time.Now().Add(-pieceHashExpiration)) {
return ErrStorageNodeInvalidResponse.New("piece has timestamp is too old (%v). Required to be not older than %s",
hash.Timestamp, pieceHashExpiration,
)
}
return nil return nil
} }