Skip to content

Commit

Permalink
rpc: reduce LOCK(cs_min) scope in rest_block
Browse files Browse the repository at this point in the history
In bitcoin#11281, commit ccd8ef6 the `LOCK(cs_main)` scope was reduced for
the wallet. This does the same for the rest API, which is a huge
performance boost for `rest_block` call when used from multiple threads.

My test setup, on an Intel i7 with 6 cores (12 threads), locked to 3.2GHz:

1. start a fully synced bitcoind, with this `bitcoin.conf`:
   ```
   server=1
   rest=1
   rpcport=8332
   rpcthreads=12
   rpcworkqueue=64
   txindex=1
   dbcache=2000
   ```
2. Wait until log message shows `loadblk thread exit`, so that bitcoind
   is idle.
3. Run ApacheBench: 10000 requests, 12 parallel threads, fetching block
   nr. 600000 in binary:
   ```
   ab -n 10000 -c 12 "http://127.0.0.1:8332/rest/block/00000000000000000007316856900e76b4f7a9139cfbfba89842c8d196cd5f91.bin"
   ```
Requests per second:
* 97.434 [ms] (mean) on master
* 20.431 [ms] this branch

So this can process about 5 times as many requests, and saturates all my
cores instead of keeping them idle waiting in the lock.
  • Loading branch information
martinus committed Feb 13, 2021
1 parent 6f883e2 commit 95dccd1
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,11 @@ static bool rest_block(HTTPRequest* req,

if (IsBlockPruned(pblockindex))
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");

if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
}

if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");

switch (rf) {
case RetFormat::BINARY: {
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
Expand Down

0 comments on commit 95dccd1

Please sign in to comment.