Kuska-ssb / ssb

Secure Scuttlebut library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

InvalidJson error from blobs.has response

mycognosist opened this issue · comments

commented

Hey @adria0, I'm hoping you can help me understand this error.

I've implemented a blobs has request and added it to the Kuska library and example. From the add_has_blob branch of my fork, in /src/api/helper.rs:

/// Send ["blobs","has"] request.
pub async fn blobs_has_req_send(&mut self, blob_id: &str) -> Result<RequestNo> {
    let req_no = self
        .rpc
        .send_request(ApiMethod::BlobsHas.selector(), RpcType::Async, &blob_id)
        .await?;
    Ok(req_no)
}

And the relevant code in example/ssb-cli.rs:

("has", 2) => {
    let blob_id = &args[1];
    let req_id = client.blobs_has_req_send(blob_id).await?;
    let msg = get_async(&mut rpc_reader, req_id, message_res_parse).await?;
    println!("{:?}", msg);
}

I can connect to @pub_cel and send the request as follows:

has &8gKLUcZ85y+K2+xP2p5bDoL13LdRIGBDwZdHWGPiByg=.sha256

This generates an error: Error: InvalidJson. However, if I enable logging output with export RUST_LOG=trace, I see that the remote peer is responding correctly:

[2020-07-28T13:38:37Z TRACE kuska_ssb::rpc::stream] recv Header { req_no: -2, is_stream: false, is_end_or_error: false, body_type: JSON, body_len: 4 } 'true'

In the above example, the remote peer does indeed have the blob and responds with true in the body. So what is the cause of the InvalidJson error? I can see that this error type is defined in src/feed/error.rs and appears to be called from src/feed/message.rs.

Can you help me understand how to avoid this error and return true or false from the response body to the console output?

Thanks for your time and attention.

commented

I looked at this with fresh eyes this morning and found the issue. I was using message_res_parse to parse the blobs has response. The attempt to deserialize a bool into the Message struct was causing the JSON error.

I added a function to the example to parse the blobs has response:

 pub fn blobs_has_res_parse(body: &[u8]) -> Result<bool> {
     Ok(serde_json::from_slice(body)?)
 }

And call it as follows:

("has", 2) => {
    let blob_id = &args[1];
    let req_id = client.blobs_has_req_send(blob_id).await?;
    let msg = get_async(&mut rpc_reader, req_id, blobs_has_res_parse).await?;
    println!("{:?}", msg);
}

Now, when I pass has &8gKLUcZ85y+K2+xP2p5bDoL13LdRIGBDwZdHWGPiByg=.sha256 to a connected remote peer, the console output is either true or false.

Hi @mycognosist, I just see it! Happy to see that you finally got how to fix it :)
If you want to do a PR, I'll merge it.