mirror of
https://github.com/romanz/electrs.git
synced 2024-11-19 09:54:09 +01:00
Allow configuration of JSON-RPC timeout
Following https://github.com/romanz/electrs/issues/495. Also, fix https://github.com/romanz/electrs/issues/443.
This commit is contained in:
parent
492d6aa275
commit
8285cf3fc7
@ -80,6 +80,12 @@ type = "u64"
|
|||||||
doc = "Duration to wait between bitcoind polling"
|
doc = "Duration to wait between bitcoind polling"
|
||||||
default = "10"
|
default = "10"
|
||||||
|
|
||||||
|
[[param]]
|
||||||
|
name = "jsonrpc_timeout_secs"
|
||||||
|
type = "u64"
|
||||||
|
doc = "Duration to wait until bitcoind JSON-RPC timeouts (must be greater than wait_duration_secs)."
|
||||||
|
default = "15"
|
||||||
|
|
||||||
[[param]]
|
[[param]]
|
||||||
name = "index_batch_size"
|
name = "index_batch_size"
|
||||||
type = "usize"
|
type = "usize"
|
||||||
|
@ -130,6 +130,7 @@ pub struct Config {
|
|||||||
pub electrum_rpc_addr: SocketAddr,
|
pub electrum_rpc_addr: SocketAddr,
|
||||||
pub monitoring_addr: SocketAddr,
|
pub monitoring_addr: SocketAddr,
|
||||||
pub wait_duration: Duration,
|
pub wait_duration: Duration,
|
||||||
|
pub jsonrpc_timeout: Duration,
|
||||||
pub index_batch_size: usize,
|
pub index_batch_size: usize,
|
||||||
pub index_lookup_limit: Option<usize>,
|
pub index_lookup_limit: Option<usize>,
|
||||||
pub auto_reindex: bool,
|
pub auto_reindex: bool,
|
||||||
@ -283,6 +284,15 @@ impl Config {
|
|||||||
0 => None,
|
0 => None,
|
||||||
_ => Some(config.index_lookup_limit),
|
_ => Some(config.index_lookup_limit),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if config.jsonrpc_timeout_secs <= config.wait_duration_secs {
|
||||||
|
eprintln!(
|
||||||
|
"Error: jsonrpc_timeout_secs ({}) must be higher than wait_duration_secs ({})",
|
||||||
|
config.jsonrpc_timeout_secs, config.wait_duration_secs
|
||||||
|
);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
network: config.network,
|
network: config.network,
|
||||||
db_path: config.db_dir,
|
db_path: config.db_dir,
|
||||||
@ -293,6 +303,7 @@ impl Config {
|
|||||||
electrum_rpc_addr,
|
electrum_rpc_addr,
|
||||||
monitoring_addr,
|
monitoring_addr,
|
||||||
wait_duration: Duration::from_secs(config.wait_duration_secs),
|
wait_duration: Duration::from_secs(config.wait_duration_secs),
|
||||||
|
jsonrpc_timeout: Duration::from_secs(config.jsonrpc_timeout_secs),
|
||||||
index_batch_size: config.index_batch_size,
|
index_batch_size: config.index_batch_size,
|
||||||
index_lookup_limit,
|
index_lookup_limit,
|
||||||
auto_reindex: config.auto_reindex,
|
auto_reindex: config.auto_reindex,
|
||||||
|
@ -3,10 +3,14 @@ use anyhow::{Context, Result};
|
|||||||
use bitcoin::{
|
use bitcoin::{
|
||||||
consensus::serialize, hashes::hex::ToHex, Amount, Block, BlockHash, Transaction, Txid,
|
consensus::serialize, hashes::hex::ToHex, Amount, Block, BlockHash, Transaction, Txid,
|
||||||
};
|
};
|
||||||
use core_rpc::{json, Auth, Client, RpcApi};
|
use core_rpc::{json, jsonrpc, Auth, Client, RpcApi};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
chain::{Chain, NewHeader},
|
chain::{Chain, NewHeader},
|
||||||
config::Config,
|
config::Config,
|
||||||
@ -48,16 +52,42 @@ fn rpc_poll(client: &mut Client) -> PollResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_cookie(path: &Path) -> Result<(String, String)> {
|
||||||
|
// Load username and password from bitcoind cookie file:
|
||||||
|
// * https://github.com/bitcoin/bitcoin/pull/6388/commits/71cbeaad9a929ba6a7b62d9b37a09b214ae00c1a
|
||||||
|
// * https://bitcoin.stackexchange.com/questions/46782/rpc-cookie-authentication
|
||||||
|
let mut file = File::open(path)
|
||||||
|
.with_context(|| format!("failed to open bitcoind cookie file: {}", path.display()))?;
|
||||||
|
let mut contents = String::new();
|
||||||
|
file.read_to_string(&mut contents)
|
||||||
|
.with_context(|| format!("failed to read bitcoind cookie from {}", path.display()))?;
|
||||||
|
|
||||||
|
let parts: Vec<&str> = contents.splitn(2, ':').collect();
|
||||||
|
ensure!(
|
||||||
|
parts.len() == 2,
|
||||||
|
"failed to parse bitcoind cookie - missing ':' separator"
|
||||||
|
);
|
||||||
|
Ok((parts[0].to_owned(), parts[1].to_owned()))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn rpc_connect(config: &Config) -> Result<Client> {
|
pub(crate) fn rpc_connect(config: &Config) -> Result<Client> {
|
||||||
let rpc_url = format!("http://{}", config.daemon_rpc_addr);
|
let rpc_url = format!("http://{}", config.daemon_rpc_addr);
|
||||||
let auth = config.daemon_auth.get_auth();
|
let mut client = {
|
||||||
if let Auth::CookieFile(ref path) = auth {
|
// Allow `wait_for_new_block` to take a bit longer before timing out.
|
||||||
if !path.exists() {
|
// See https://github.com/romanz/electrs/issues/495 for more details.
|
||||||
bail!("{:?} is missing - is bitcoind running?", path);
|
let builder = jsonrpc::simple_http::SimpleHttpTransport::builder()
|
||||||
}
|
.url(&rpc_url)?
|
||||||
}
|
.timeout(config.jsonrpc_timeout);
|
||||||
let mut client = Client::new(&rpc_url, auth)
|
let builder = match config.daemon_auth.get_auth() {
|
||||||
.with_context(|| format!("failed to connect to RPC: {}", config.daemon_rpc_addr))?;
|
Auth::None => builder,
|
||||||
|
Auth::UserPass(user, pass) => builder.auth(user, Some(pass)),
|
||||||
|
Auth::CookieFile(path) => {
|
||||||
|
let (user, pass) = read_cookie(&path)?;
|
||||||
|
builder.auth(user, Some(pass))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Client::from_jsonrpc(jsonrpc::Client::with_transport(builder.build()))
|
||||||
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match rpc_poll(&mut client) {
|
match rpc_poll(&mut client) {
|
||||||
|
Loading…
Reference in New Issue
Block a user