Receiving all zeroes for the file in stage ND2

I’m stuck on Stage #ND2.

I am getting all zeroes as output from the peer and the hash is not matching

And here’s a snippet of my code:

waitForRequestedPiece(client) {
        return new Promise((resolve, reject) => {
            client.on("data", onData)
            client.on("error", onError)

            let buffer = Buffer.alloc(0)
            function onData(chunk) {
                buffer = Buffer.concat([buffer, chunk])

                while (buffer.length >= 4) {
                    const msgLength = buffer.readInt32BE(0)

                    if (msgLength === 0) {
                        console.log("Got keep alive ;)")
                        buffer = buffer.subarray(4)
                        continue
                    }

                    if (buffer.length < msgLength + 4) {
                        console.log("waiting for data")
                        return
                    }

                    const msg = buffer.subarray(4, 4 + msgLength)
                    buffer = buffer.subarray(4 + msgLength)

                    const msgId = msg.readUInt8(0)

                    if (msgId === 7){
                        console.log(`Received piece index`) 

                        const pieceIndex = msg.readInt32BE(1)
                        const begin = msg.readInt32BE(5)
                        const blockData = msg.readInt32BE(9)
                        cleanup()
                        return resolve({pieceIndex, begin, blockData})
                    }
                    else {
                        console.log(`Got msg ID ${msgId}, ignoring...`)
                    }
                }
            }

            function onError(err) {
                cleanup()
                return reject(err)
            }

            function cleanup() {
                client.removeListener("data", onData)
                client.removeListener("error", onError)
            }
        });
    }


async downloadPieces(pieceIndex, outFile) {
        const peers = await this.torrent.getPeers()
        const {client, response} = await this.initiateHandShake(peers[0]);
        try {
            this.sendInterested(client)
            await this.waitForUnchoke(client);
            const pieceLength = this.torrent.getPieceLength()
            const fileLength = this.torrent.getFileLength()
    
            
            const indexPieceLength = (pieceIndex  === Math.floor(fileLength/pieceLength)) ? fileLength % pieceLength : pieceLength ;    
            
            const piece = Buffer.alloc(indexPieceLength)
    
            const sixteenKb = 16 * 1024
            let offset = 0;
            while (offset < indexPieceLength) {
                const requestedBlocks = []
                for (let count = 0; count < 5 && offset < indexPieceLength ; count++){
                    const length = Math.min(sixteenKb, indexPieceLength - offset)
                    this.sendPieceRequest(pieceIndex, offset, length, client)
                    requestedBlocks.push(this.waitForRequestedPiece(client))
                    offset += sixteenKb
                }
                const responses = await Promise.all(requestedBlocks)
                for (const {pieceIndex, offset, blockData} of responses){
                    piece[offset] = blockData
                }
            }
    
            const pieceHashes = this.torrent.getPieces()
            const hash = pieceHashes.slice(pieceIndex * 40, pieceIndex * 40 + 40)
            const recievedHash = crypto
                                .createHash("sha1")
                                .update(piece)
                                .digest("hex")
            if (recievedHash !== hash) {
                throw new Error('Piece Hash mismatch')
            }

            fs.writeFileSync(outFile, piece)
        }
        finally {
            client.end()
            client.destroy()
        }

        // console.log(piece.toString("hex"))
    }


Hey @abhishek-7901, could you push the latest version of your code to our server? Right now, I can only see your submission from over a week ago. Let me know once it’s up!

Yes, done, please have a look :slight_smile:

@abhishek-7901 There could be multiple issues at play. First, the received chunks don’t match the assumed size (16k + overhead):

Also, I wasn’t quite sure about the arbitrary 5 here:

I tried changing it to 1 and reran the test:

Now, most chunks were around 16k, but in some cases, a block could still arrive in two or three chunks.

You’ll need to be able to handle partial chunks and reassemble the full block before processing it.

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or start a new discussion!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.