Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using import_multi with a descriptor and a large range returns a socket error, but only on version 0.14 #211

Open
chris-belcher opened this issue Feb 17, 2022 · 6 comments

Comments

@chris-belcher
Copy link

This code works for version 0.13 or below, once I upgrade to 0.14 this error started happening.

Here is code demonstrating the bug

const RPC_CREDENTIALS: Option<(&str, &str)> = Some(("regtestrpcuser", "regtestrpcpass"));

const RPC_HOSTPORT: &str = "localhost:18443";
const RPC_WALLET: &str = "teleport";

const ADDRESS_IMPORT_COUNT: usize = 5000;

use bitcoincore_rpc::json::{
    ImportMultiOptions, ImportMultiRequest, ImportMultiRescanSince,
};
use bitcoincore_rpc::{Client, RpcApi, Auth};


fn main() -> Result<(), bitcoincore_rpc::Error> {

    let descs = [
        "wpkh(tpubDCph6XxkYmXpittC1dKgfNU2wTuq3JbpDNqJRwB1zpEZHJZBgdk1nxtn4p4TiF6ydvJH4BFbPwHMf8gGZ85DSLDfqKGRLtLeyuWs9hBeHvo/0/*)#fymqnm93",
        "wpkh(tpubDCph6XxkYmXpittC1dKgfNU2wTuq3JbpDNqJRwB1zpEZHJZBgdk1nxtn4p4TiF6ydvJH4BFbPwHMf8gGZ85DSLDfqKGRLtLeyuWs9hBeHvo/1/*)#cs7pww4f"
    ];

    let auth = match RPC_CREDENTIALS {
        Some((user, pass)) => Auth::UserPass(user.to_string(), pass.to_string()),
        None => panic!(""),
    };
    let rpc = Client::new(
        &format!("http://{}/wallet/{}", RPC_HOSTPORT, RPC_WALLET),
        auth,
    )?;
    rpc.get_blockchain_info()?;

    let address_label = "somelabel";

    let import_requests = descs 
        .iter()
        .map(|desc| ImportMultiRequest {
            timestamp: ImportMultiRescanSince::Now,
            descriptor: Some(desc),
            range: Some((0, ADDRESS_IMPORT_COUNT - 1)),
            watchonly: Some(true),
            label: Some(&address_label),
            ..Default::default()
        })
        .collect::<Vec<ImportMultiRequest>>();

    let result = rpc.import_multi(
        &import_requests,
        Some(&ImportMultiOptions {
            rescan: Some(false),
        }),
    )?;
    for r in result {
        if !r.success {
            return Err(bitcoincore_rpc::Error::UnexpectedStructure);
        }
    }

    println!("Hello, world!");

    Ok(())
}

This results in an error: Error: JsonRpc(Transport(SocketError(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" })))

The cargo.toml file:

[package]
name = "rpc-bitcoincore-0-14-importmulti"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bitcoincore-rpc = "0.14"

Changing to bitcoincore-rpc = "0.13" or below stops the error from happening.

Reducing the value of ADDRESS_IMPORT_COUNT down to something like 500 or 50 instead of 5000 also makes the error disappear, indicating that the cause is the long runtime of importmulti, possibly version 0.14 reduced a timeout somewhere.

@casey
Copy link
Contributor

casey commented Aug 4, 2022

@chris-belcher I'm getting a similar error:

JsonRpc(Transport(SocketError(Error { kind: TimedOut, message: "connection timed out" })))

I git bisected rust-bitcoincore-rpc and found that it starts happening in this commit, which was made between 0.13 and 0.14. This makes me think they could be related.

I wanted to git bisect with your repro code, to see if that error was introduced in the same commit, but I wasn't able to get it to run. I got this error:

Error: JsonRpc(Rpc(RpcError { code: -4, message: "This type of wallet does not support this command", data: None }))

What command should be run to create the wallet? I tried setting descriptor to true, since I assumed that might be the issue, but wasn't able to run.

Also, I'm getting this error on a mac. What OS are you running?

@casey
Copy link
Contributor

casey commented Aug 4, 2022

That commit also upgraded jsonrpc from 0.11 to 0.12, so the underlying issue could be there.

@casey
Copy link
Contributor

casey commented Aug 6, 2022

I have a very similar issue opened on bitcoin core, but in that case it works with bitcoind installed by homebrew, and fails with bitcoind built from source, so it appears to be unrelated to the version of rust-bitcoincore-rpc.

@casey
Copy link
Contributor

casey commented Aug 10, 2022

Is this possibly the result of the call just being particularly slow, and a timeout being hit?

@chrisguida
Copy link

Hitting this trying to implement scanblocks #317

It seems the underlying jsonrpc crate has a default timeout of 15 seconds... https://docs.rs/jsonrpc/0.14.0/src/jsonrpc/simple_http.rs.html#97

@0xB10C
Copy link
Contributor

0xB10C commented Nov 12, 2023

Hitting this trying to implement scanblocks #317

It seems the underlying jsonrpc crate has a default timeout of 15 seconds... https://docs.rs/jsonrpc/0.14.0/src/jsonrpc/simple_http.rs.html#97

I've worked around this in the past by using a custom client with a custom timeout: https://github.com/0xB10C/miningpool-observer/blob/master/daemon/src/main.rs#L149-L159

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants