I’m stuck on Stage #fi9
According to me, my code is working fine, but the tests themselves are failing. I suppose that the IP of the peers is changing and the tests aren’t updated. Can someone confirm if the tests are fine?
Here are my logs:
$ ./Debug/bittorrent.exe peers sample.torrent
165.232.41.73:51556
232.41.73.201:25765
41.73.201.100:42472
Here are the test logs
remote:
remote: [tester::#FI9] Running tests for Stage #FI9 (Discover peers)
remote: [tester::#FI9] Running ./your_bittorrent.sh peers /tmp/torrents1422977794/test.torrent
remote: [your_program] 188.119.61.177:6881
remote: [your_program] 119.61.177.26:57671
remote: [your_program] 61.177.26.225:18400
remote: [your_program] 177.26.225.71:57344
remote: [your_program] 26.225.71.224:29
remote: [your_program] 225.71.224.0:7624
remote: [your_program] 71.224.0.29:51414
remote: [your_program] 224.0.29.200:54846
remote: [your_program] 0.29.200.214:16025
remote: [tester::#FI9] Expected stdout to contain "62.153.208.98:3652", got: "188.119.61.177:6881\n119.61.177.26:57671\n61.177.26.225:18400\n177.26.225.71:57344\n26.225.71.224:29\n225.71.224.0:7624\n71.224.0.29:51414\n224.0.29.200:54846\n0.29.200.214:16025\n"
remote: [tester::#FI9] Test failed (try setting 'debug: true' in your codecrafters.yml to see more details)
remote:
And here’s a snippet of my code:
std::vector<uint8_t> convert_string_to_bytes(const std::string& pieceHashes) {
// std::cout << "hash size: " << pieceHashes.size() << "\n";
std::vector<uint8_t> byteList(pieceHashes.size());
int idx = 0;
for (char c : pieceHashes) {
byteList[idx++] = c;
}
return std::move(byteList);
}
main(){
if (command == "peers") {
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " peers <path/to/torrent/file>" << std::endl;
return 1;
}
std::string torrent_path = argv[2];
json decoded_value = parse_torrent_file(torrent_path);
std::string tracker_url;
decoded_value["announce"].get_to(tracker_url);
std::string domain = tracker_url.substr(0, tracker_url.find_last_of('/'));
std::string endpoint = tracker_url.substr(tracker_url.find_last_of('/'));
httplib::Client cli(domain);
std::string infoHash = getInfoHash(decoded_value["info"]);
std::string httpEncodedHash = "";
for (int i = 0; i < infoHash.size(); i += 2) {
httpEncodedHash += '%' + infoHash.substr(i, 2);
}
std::string peer_id = "hahahahahahahahahaha";
int uploaded = 0;
int downloaded = 0;
int left = decoded_value["info"]["length"];
int compact = 1;
httplib::Params params{
{"peer_id", peer_id},
{"port", "6881"},
{"uploaded", "0"},
{"downloaded", "0"},
{"left", std::to_string(left)},
{"compact", "1"}
};
httplib::Headers headers{};
auto res = cli.Get(endpoint + "?info_hash=" + httpEncodedHash, params, headers);
json responseJson = decode_bencoded_value(res->body);
//std::cout << responseJson["interval"];
const auto peers = responseJson["peers"];
auto peerBytes = convert_string_to_bytes(peers);
const int numPeers = peerBytes.size() / 6; //size of each peer is 6 bytes. First 4 bytes are the IP, last 2 are the port
std::vector<std::string> out(numPeers);
for (int i = 0; i < numPeers; i++) {
std::ostringstream os;
const std::string ipAddr = std::to_string(peerBytes[i]) + "." + std::to_string(peerBytes[i+1]) + "." + std::to_string(peerBytes[i+2]) + "." + std::to_string(peerBytes[i+3]);
const int port = ((int)peerBytes[i + 4] << 8) + (int)peerBytes[i + 5];
os << ipAddr << ":" << port;
out[i] = os.str();
std::cout << out[i]<<'\n';
}
}
}