1
0
mirror of https://github.com/romanz/electrs.git synced 2024-11-19 01:43:29 +01:00

Add initial support for JSON-RPC batching

This commit is contained in:
Roman Zeyde 2021-05-21 13:56:04 +03:00
parent 2609caaebc
commit d4559a31e6
3 changed files with 34 additions and 7 deletions

View File

@ -7,13 +7,16 @@ class Client:
self.f = self.s.makefile('r')
self.id = 0
def call(self, method, *args):
req = {
def request(self, method, *args):
self.id += 1
return {
'id': self.id,
'method': method,
'params': list(args),
'jsonrpc': '2.0',
}
msg = json.dumps(req) + '\n'
def call(self, *requests):
msg = json.dumps(requests) + '\n'
self.s.sendall(msg.encode('ascii'))
return json.loads(self.f.readline())

View File

@ -8,13 +8,18 @@ def main():
args = parser.parse_args()
conn = client.Client(("localhost", 50001))
tx = conn.call("blockchain.transaction.get", args.txid, True)["result"]
fee = 0
tx = conn.call(conn.request("blockchain.transaction.get", args.txid, True))[0]["result"]
requests = []
for vin in tx["vin"]:
prev_txid = vin["txid"]
prev_tx = conn.call("blockchain.transaction.get", prev_txid, True)["result"]
requests.append(conn.request("blockchain.transaction.get", prev_txid, True))
fee = 0
for vin, response in zip(tx["vin"], conn.call(*requests)):
prev_tx = response["result"]
txo = prev_tx["vout"][vin["vout"]]
fee += txo["value"]
fee -= sum(vout["value"] for vout in tx["vout"])
print(f'vSize = {tx["vsize"]}, Fee = {1e3 * fee:.2f} mBTC = {1e8 * fee / tx["vsize"]:.2f} sat/vB')

View File

@ -38,6 +38,13 @@ struct Request {
params: Value,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum Requests {
Single(Request),
Batch(Vec<Request>),
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
#[serde(untagged)]
enum Version {
@ -127,12 +134,24 @@ impl Rpc {
}
pub fn handle_request(&self, client: &mut Client, value: Value) -> Result<Value> {
let requests: Requests = from_value(value).context("invalid request")?;
match requests {
Requests::Single(request) => self.handle_single_request(client, request),
Requests::Batch(requests) => requests
.into_iter()
.map(|request| self.handle_single_request(client, request))
.collect::<Result<Vec<_>>>()
.map(|results| json!(results)),
}
}
fn handle_single_request(&self, client: &mut Client, request: Request) -> Result<Value> {
let Request {
id,
jsonrpc,
method,
params,
} = from_value(value).context("invalid request")?;
} = request;
self.rpc_duration.observe_duration(&method, || {
let result = match method.as_str() {
"blockchain.scripthash.get_history" => {