I have this code but after 12 hours of running it only found 5 infohashes.
What can I do to increase this number?
import DHT from 'bittorrent-dht';
import magnet from 'magnet-uri';
import WebTorrent from 'webtorrent';
import redis from 'redis';
const dht = new DHT();
const client = new WebTorrent();
// Create Redis client
const redisClient = redis.createClient({
host: 'localhost', // Update with your Redis server configuration
port: 6379
});
redisClient.on('error', function(error) {
console.error(error);
});
// Seed nodes - Replace with actual seed nodes
const seedNodes = ['router.bittorrent.com:6881', 'dht.transmissionbt.com:6881'];
const knownTorrents = []; // store in db
const torrentQueue = []; // Queue to manage torrent fetching
const torrentFetchInterval = 10000; // Time interval between fetching torrents (in milliseconds)
client.on('torrent', (torrent) => {
console.log(`Torrent added: ${torrent.infoHash}`);
console.log(`Files: ${torrent.files.map((file) => file.name).join(', ')}`);
});
client.on('error', (err) => {
console.error('Error in WebTorrent client:', err);
});
// Example of using Redis for shared state
function updateSharedTorrentState(torrent) {
// Storing torrent data in Redis
redisClient.set(torrent.infoHash, JSON.stringify(torrent), redis.print);
// Retrieving torrent data from Redis
redisClient.get(torrent.infoHash, (err, reply) => {
if (err) {
console.error(err);
return;
}
const sharedTorrent = JSON.parse(reply);
console.log(sharedTorrent); // Do something with the shared torrent data
});
}
function processTorrentQueue() {
if (torrentQueue.length > 0) {
const infoHashBuffer = torrentQueue.shift(); // Get the next torrent from the queue
indexTorrent(infoHashBuffer);
}
setTimeout(processTorrentQueue, torrentFetchInterval);
}
function indexTorrent(infoHashBuffer) {
const infoHash = infoHashBuffer.toString('hex');
console.log('Torrent found:', infoHash);
// Create a magnet URI using the info hash
const magnetURI = `magnet:?xt=urn:btih:${infoHash}`;
// Check if the torrent is already being tracked
if (client.get(magnetURI)) {
console.log(`Torrent with infoHash ${infoHash} is already being tracked.`);
return; // Exit the function if the torrent is already added
}
// Fetch metadata using the WebTorrent client
client.add(magnetURI, (torrent) => {
console.log('Torrent metadata fetched:', torrent.name);
// Add or update the torrent in the knownTorrents array
const index = knownTorrents.findIndex((t) => t.infoHash === infoHash);
if (index > -1) {
knownTorrents[index] = {
...knownTorrents[index],
name: torrent.name // Update only specific properties
};
} else {
knownTorrents.push({
infoHash,
name: torrent.name,
seeders: 0, // Initialize seeders and leechers
leechers: 0
});
}
// The 'tracker' event provides data from trackers
torrent.on('tracker', (data) => {
console.log(`Trackers for ${torrent.name} report: ${data.announce}`);
console.log(`Seeders: ${data.complete}, Leechers: ${data.incomplete}`);
// Update seeders and leechers in the knownTorrents array
const torrentIndex = knownTorrents.findIndex((t) => t.infoHash === infoHash);
if (torrentIndex > -1) {
knownTorrents[torrentIndex] = {
...knownTorrents[torrentIndex],
seeders: data.complete,
leechers: data.incomplete
};
}
});
// Removing the torrent after a short delay, as we only want the tracker info
setTimeout(() => client.remove(magnetURI), 60000); // Adjust the delay as needed
});
// ...
}
// Function to add and query nodes
function joinAndTestDHTNetwork(seedNodes) {
console.log('Joining DHT network...');
seedNodes.forEach((seed) => {
const [host, port] = seed.split(':');
dht.addNode({ host, port: parseInt(port) });
});
// Test querying nodes after joining
setTimeout(() => {
console.log('Testing DHT network by querying nodes...');
dht.nodes.toArray().forEach((node) => {
dht.lookup(node.id, (err, n) => {
if (err) {
console.error(`Error querying node ${node.id}:`, err);
} else {
console.log(`Node ${node.id.toString('hex')} queried successfully. Found ${n} nodes.`);
}
});
});
}, 5000); // Delay to allow time for initial network join
}
// Handling announce events
dht.on('announce', (peer, infoHashBuffer) => {
// Add the torrent to the queue instead of processing it immediately
torrentQueue.push(infoHashBuffer);
});
// Handling new node discovery
dht.on('node', (node) => {
console.log(`New node discovered: ${node.host}:${node.port}`);
// Perform a lookup for a random info hash to discover more nodes and peers
dht.lookup(generateRandomInfoHash());
});
// Periodically perform lookups for random info hashes
setInterval(() => {
dht.lookup(generateRandomInfoHash());
}, 10000); // Every 10 seconds, adjust as needed
// Generate a random info hash for lookup
function generateRandomInfoHash() {
let infoHash = '';
for (let i = 0; i < 40; i++) {
infoHash += Math.floor(Math.random() * 16).toString(16);
}
return infoHash;
}
setInterval(() => {
knownTorrents.forEach((torrent) => {
indexTorrent(Buffer.from(torrent.infoHash, 'hex'));
});
}, 3600000);
// Example usage
processTorrentQueue();
joinAndTestDHTNetwork(seedNodes);
dht.listen(20000, () => {
console.log('DHT listening on port 20000');
});
Also it seems the torrent.on('tracker')
never fires, nor does client.add(magnetURI, (torrent)
2
Answers
You are very unlikely to find an active infohash through brute force alone as sha1 has a lot of permutations.
Use a tool like DHTSpider to get active infohashes instead: https://github.com/alanyang/dhtspider
You’re only getting infohashes that other nodes directly announce to yours. That is only a tiny fraction of the keyspace of the bittorrent DHT.
To get a wider view you’ll have to implement BEP 51 (some implementation notes on that)
And DHT-downloaded torrents never contain trackers since the trackers are stored outside the info dictionary and the outer part is never sent over the DHT.