Skip to content

Commit

Permalink
Try running multiple "blockchain.scripthash.subscribe" RPCs concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
romanz committed Oct 29, 2021
1 parent 563d8b7 commit 6dfe16d
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions src/electrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,16 @@ impl Rpc {
}

fn handle_calls(&self, client: &mut Client, calls: Result<Calls, Value>) -> Value {
let calls: Calls = match calls {
Ok(calls) => calls,
Err(response) => return response, // JSON parsing failed - the response does not contain request id
};

match calls {
Ok(Calls::Batch(batch)) => {
Calls::Batch(batch) => {
if let Some(result) = self.try_multi_call(client, &batch) {
return json!(result);
}
json!(batch
.into_iter()
.map(|result| match result {
Expand All @@ -461,14 +469,47 @@ impl Rpc {
})
.collect::<Vec<Value>>())
}
Ok(Calls::Single(result)) => match result {
Calls::Single(result) => match result {
Ok(call) => self.single_call(client, &call),
Err(response) => response, // JSON parsing may fail - the response contains request id
},
Err(response) => response, // JSON parsing may fail - the response does not contain request id
}
}

fn try_multi_call(
&self,
client: &mut Client,
calls: &[Result<Call, Value>],
) -> Option<Vec<Value>> {
// exit if any call failed to parse
let valid_calls = calls
.iter()
.map(|result| -> Option<&Call> { result.as_ref().ok() })
.collect::<Option<Vec<&Call>>>()?;

// only "blockchain.scripthashes.subscribe" are supported
let scripthashes: Vec<ScriptHash> = valid_calls
.iter()
.map(|call| -> Option<ScriptHash> {
match &call.params {
Params::ScriptHashSubscribe((scripthash,)) => Some(*scripthash),
_ => None, // exit if any of the calls is not supported
}
})
.collect::<Option<Vec<ScriptHash>>>()?;

let results = self
.rpc_duration
.observe_duration("blockchain.scripthash.subscribe:multi", || {
self.scripthashes_subscribe(client, &scripthashes)
});
let responses = valid_calls
.iter()
.zip(results)
.map(|(call, result)| call.response(result));
Some(responses.collect::<Vec<Value>>())
}

fn single_call(&self, client: &mut Client, call: &Call) -> Value {
self.rpc_duration.observe_duration(&call.method, || {
let result = match &call.params {
Expand Down

0 comments on commit 6dfe16d

Please sign in to comment.