[#PK2] Error: "Missing Field: `interval`" only when run on test server, but not missing it when run locally

Hi,

If I run “Announce extension support #pk2” locally with any of the three provided test links, my code works and I’m receiving a full response which includes the field interval. I’ve included debug output below.

./your_bittorrent.sh magnet_handshake "magnet:?xt=urn:btih:c5fb9894bdaba464811b088d806bdd611ba490af&dn=magnet3.gif&tr=http%3A%2F%2Fbittorrent-test-tracker.codecrafters.io%2Fannounce"
req = http://bittorrent-test-tracker.codecrafters.io/announce/?info_hash=%C5%FB%98%94%BD%AB%A4d%81%1B%08%8D%80k%DDa%1B%A4%90%AF
redirecting 'http://bittorrent-test-tracker.codecrafters.io/announce/?info_hash=%C5%FB%98%94%BD%AB%A4d%81%1B%08%8D%80k%DDa%1B%A4%90%AF&peer_id=AAA3AAAAAAA7AAAABAAA&port=6881&uploaded=0&downloaded=0&left=999&compact=1' to 'http://bittorrent-test-tracker.codecrafters.io/announce?info_hash=%C5%FB%98%94%BD%AB%A4d%81%1B%08%8D%80k%DDa%1B%A4%90%AF&peer_id=AAA3AAAAAAA7AAAABAAA&port=6881&uploaded=0&downloaded=0&left=999&compact=1'
resp = b"d8:completei3e10:incompletei1e8:intervali60e12:min intervali60e5:peers18:\xa7G\x8f6\xc8\xe2\xa5\xe8#\x8b\xc8\xef\x8b;\xb8\xff\xc90e"
Peer ID: 2d524e302e302e302de33db7666c49ec504ffdcb

But, if I run codecrafters test with the same code, the interval field is missing:

[tester::#PK2] Running tests for Stage #PK2 (Magnet Links - Announce extension support)
[tester::#PK2] Running ./your_bittorrent.sh magnet_handshake "magnet:?xt=urn:btih:c5fb9894bdaba464811b088d806bdd611ba490af&dn=magnet3.gif&tr=http%3A%2F%2F127.0.0.1:36787%2Fannounce"
[your_program] req = http://127.0.0.1:36787/announce/?info_hash=%C5%FB%98%94%BD%AB%A4d%81%1B%08%8D%80k%DDa%1B%A4%90%AF
[your_program] resp = b"d8:completei1e10:incompletei0e11:minintervali1800e5:peers6:\x7f\0\0\x01\xa7\xcfe"
[your_program] Error: "Missing Field: `interval`"
[tester::#PK2] Application didn't terminate successfully without errors. Expected 0 as exit code, got: 1

Do you have any idea about why this is happening?

I can’t pass the test, even though my code works if I run it locally.

Hi @ivanbgd, I haven’t done this stage yet, but maybe we can pair-debugging.

Do you know which part of your code is throwing Error: "Missing Field: interval?

I tried searching in your repo but couldn’t find anything relevant.

OK, I found it:

Hi @andy1li ,

Thank you for your reply.

I believe it’s coming from this line:

let response: TrackerResponse = serde_bencode::from_bytes(&resp)?;

which is located in bittorrent_starter_rust::magnet::get_peers().

Namely, code has debug lines:

let resp = client.get(&req).query(&query).send().await?.bytes().await?;
eprintln!("resp 1 = {resp:?}"); 
let resp = Vec::from(resp);
eprintln!("resp 2 = {resp:?}"); 
let response: TrackerResponse = serde_bencode::from_bytes(&resp)?;
eprintln!("resp 3 = {resp:?}"); 

But the execution only gets this far:

[your_program] req = http://127.0.0.1:46833/announce/?info_hash=%3F%99J%83%5E%09%028%874%98ck%98%A3%E7%8D%1C4%CA
[your_program] resp 1 = b"d8:completei1e10:incompletei0e11:minintervali1800e5:peers6:\x7f\0\0\x01\x9f\xade"
[your_program] resp 2 = [100, 56, 58, 99, 111, 109, 112, 108, 101, 116, 101, 105, 49, 101, 49, 48, 58, 105, 110, 99, 111, 109, 112, 108, 101, 116, 101, 105, 48, 101, 49, 49, 58, 109, 105, 110, 105, 110, 116, 101, 114, 118, 97, 108, 105, 49, 56, 48, 48, 101, 53, 58, 112, 101, 101, 114, 115, 54, 58, 127, 0, 0, 1, 159, 173, 101]
[your_program] Error: "Missing Field: `interval`"

So, resp 3 is not executed.

My code most probably just passes that error from serde_bencode::from_bytes().

Actually, yes, it does:

serde_bencode::error::Error

pub enum Error {
    IoError(Error),
    InvalidType(String),
    InvalidValue(String),
    InvalidLength(String),
    UnknownVariant(String),
    UnknownField(String),
    MissingField(String),
    DuplicateField(String),
    Custom(String),
    EndOfStream,
}

You beat me to it. :smiley:

Thanks for the detailed explanation! To be honest, I’m not sure interval is strictly required.

One potential workaround could be to manually modify resp to include a dummy interval.

I’ll check with the team to see if there’s anything that needs to be adjusted on our end.

Hey @andy1li ,

Alright, thanks!

I suppose I can try that, although that’s a hack. :smiley:

From the official BitTorrent specification, it is a required field:

https://www.bittorrent.org/beps/bep_0003.html

Tracker responses are bencoded dictionaries. If a tracker response has a key failure reason, then that maps to a human readable string which explains why the query failed, and no other keys are required. Otherwise, it must have two keys: interval, which maps to the number of seconds the downloader should wait between regular rerequests, and peers.

The challenge text at “Discover peers #FI9” says that it’s not required during the challenge, though.

But I’m wondering how come other people didn’t face this problem. Has something maybe changed on your side in the last couple of days, related to this stage and magnet links, peers, etc?

1 Like

I’m not aware of any significant changes recently. My best guess is that most people are likely still using their own hand-rolled bencode implementations.

1 Like

Hi! I think the "Missing Field: `interval`" error comes from serde, and it because it is expecting the field in TrackerResponse and since it does not comes there, is gives the error. Since for the challenge is no required, you could try to make interval: Option<your_type> and see if it works.

2 Likes

Hi @ragranados and thank you for your reply!

You are right - this solved the problem, and what’s good is that no additional error handling was required.

1 Like

We fixed the issue in this PR. Thanks again for highlighting it. @ivanbgd

2 Likes

Sure, no problem! Thanks for looking into it. @andy1li

1 Like

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