public bool ValidatePiece(IPeer peer, BlockInfo request, out bool pieceComplete, out IList <IPeer> peersInvolved) { int pIndex = requests.BinarySearch(IndexComparer, request.PieceIndex); pieceComplete = false; peersInvolved = null; if (pIndex < 0) { logger.InfoFormatted("Piece validation failed: {0}-{1}. {2} No piece.", request.PieceIndex, request.StartOffset, peer); return(false); } var primaryPiece = requests[pIndex]; var result = ValidateRequestWithPiece(peer, request, primaryPiece, out pieceComplete, out peersInvolved); // If there are no duplicate requests, exit early! Otherwise we'll need to do book keeping to // ensure our received piece is not re-requested again. if (!duplicates.TryGetValue(request.PieceIndex, out List <Piece> extraPieces)) { if (pieceComplete) { requests.RemoveAt(pIndex); } return(result); } // We have duplicate requests and have, so far, failed to validate the block. Try to validate it now. if (!result) { for (int i = 0; i < extraPieces.Count && !result; i++) { if ((result = ValidateRequestWithPiece(peer, request, extraPieces[i], out pieceComplete, out peersInvolved))) { break; } } } // If we successfully validated the block using *any* version of the request, update the primary piece and // all duplicates to reflect this. This will implicitly cancel any outstanding requests from other peers. if (result) { primaryPiece.Blocks[request.StartOffset / Piece.BlockSize].TrySetReceived(peer); for (int i = 0; i < extraPieces.Count; i++) { extraPieces[i].Blocks[request.StartOffset / Piece.BlockSize].TrySetReceived(peer); } } // If the piece is complete then remove it, and any dupes, from the picker. if (pieceComplete) { requests.RemoveAt(pIndex); duplicates.Remove(primaryPiece.Index); return(result); } return(result); }
public override bool ValidatePiece(PeerId id, int pieceIndex, int startOffset, int length, out Piece piece) { Comparer.Index = pieceIndex; int pIndex = requests.BinarySearch(null, Comparer); if (pIndex < 0) { piece = null; Logger.Log(null, "Validating: {0} - {1}: ", pieceIndex, startOffset); Logger.Log(null, "No piece"); return(false); } piece = requests[pIndex]; // Pick out the block that this piece message belongs to int blockIndex = Block.IndexOf(piece.Blocks, startOffset, length); if (blockIndex == -1 || !id.Equals(piece.Blocks[blockIndex].RequestedOff)) { Logger.Log(null, "Validating: {0} - {1}: ", pieceIndex, startOffset); Logger.Log(null, "no block"); return(false); } if (piece.Blocks[blockIndex].Received) { Logger.Log(null, "Validating: {0} - {1}: ", pieceIndex, startOffset); Logger.Log(null, "received"); return(false); } if (!piece.Blocks[blockIndex].Requested) { Logger.Log(null, "Validating: {0} - {1}: ", pieceIndex, startOffset); Logger.Log(null, "not requested"); return(false); } id.AmRequestingPiecesCount--; piece.Blocks[blockIndex].Received = true; if (piece.AllBlocksReceived) { requests.RemoveAt(pIndex); } return(true); }
public override bool ValidatePiece(IPieceRequester peer, int pieceIndex, int startOffset, int length, out Piece piece) { int pIndex = requests.BinarySearch(IndexComparer, pieceIndex); if (pIndex < 0) { piece = null; logger.InfoFormatted("Piece validation failed: {0} - {1}. No piece.", pieceIndex, startOffset); return(false); } piece = requests[pIndex]; // Pick out the block that this piece message belongs to int blockIndex = Block.IndexOf(piece.Blocks, startOffset, length); if (blockIndex == -1 || !peer.Equals(piece.Blocks[blockIndex].RequestedOff)) { logger.InfoFormatted("Piece validation failed: {0} - {1}. No block ", pieceIndex, startOffset); return(false); } if (piece.Blocks[blockIndex].Received) { logger.InfoFormatted("Piece validation failed: {0} - {1}. Already received.", pieceIndex, startOffset); return(false); } if (!piece.Blocks[blockIndex].Requested) { logger.InfoFormatted("Piece validation failed: {0} - {1}. Not requested.", pieceIndex, startOffset); return(false); } peer.AmRequestingPiecesCount--; piece.Blocks[blockIndex].Received = true; if (piece.AllBlocksReceived) { requests.RemoveAt(pIndex); } return(true); }