Skip to content

Commit 12948b8

Browse files
authored
fix validate_rpcs. Run RPC compute heavy jobs in a thread pool (#19922)
1 parent df45f39 commit 12948b8

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

chia/full_node/full_node_rpc_api.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import asyncio
44
import time
5+
from concurrent.futures import ThreadPoolExecutor
56
from datetime import datetime, timezone
67
from typing import TYPE_CHECKING, Any, ClassVar, Optional, cast
78

@@ -89,6 +90,8 @@ async def get_average_block_time(
8990

9091

9192
class FullNodeRpcApi:
93+
executor: ThreadPoolExecutor
94+
9295
if TYPE_CHECKING:
9396
from chia.rpc.rpc_server import RpcApiProtocol
9497

@@ -98,6 +101,7 @@ def __init__(self, service: FullNode) -> None:
98101
self.service = service
99102
self.service_name = "chia_full_node"
100103
self.cached_blockchain_state: Optional[dict[str, Any]] = None
104+
self.executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="node-rpc-")
101105

102106
def get_routes(self) -> dict[str, Endpoint]:
103107
return {
@@ -485,11 +489,14 @@ async def get_block_spends(self, request: dict[str, Any]) -> EndpointResult:
485489
if block_generator is None: # if block is not a transaction block.
486490
return {"block_spends": []}
487491

488-
spends = get_spends_for_trusted_block(
492+
flags = get_flags_for_height_and_constants(full_block.height, self.service.constants)
493+
spends = await asyncio.get_running_loop().run_in_executor(
494+
self.executor,
495+
get_spends_for_trusted_block,
489496
self.service.constants,
490497
block_generator.program,
491498
block_generator.generator_refs,
492-
get_flags_for_height_and_constants(full_block.height, self.service.constants),
499+
flags,
493500
)
494501

495502
return spends
@@ -506,11 +513,14 @@ async def get_block_spends_with_conditions(self, request: dict[str, Any]) -> End
506513
if block_generator is None: # if block is not a transaction block.
507514
return {"block_spends_with_conditions": []}
508515

509-
spends_with_conditions = get_spends_for_trusted_block_with_conditions(
516+
flags = get_flags_for_height_and_constants(full_block.height, self.service.constants)
517+
spends_with_conditions = await asyncio.get_running_loop().run_in_executor(
518+
self.executor,
519+
get_spends_for_trusted_block_with_conditions,
510520
self.service.constants,
511521
block_generator.program,
512522
block_generator.generator_refs,
513-
get_flags_for_height_and_constants(full_block.height, self.service.constants),
523+
flags,
514524
)
515525
return {"block_spends_with_conditions": spends_with_conditions}
516526

@@ -885,7 +895,7 @@ async def create_block_generator(self, _: dict[str, Any]) -> EndpointResult:
885895
if maybe_gen is not None:
886896
# this also validates the signature
887897
err, conds = await asyncio.get_running_loop().run_in_executor(
888-
self.service.blockchain.pool,
898+
self.executor,
889899
run_block_generator2,
890900
bytes(gen.program),
891901
gen.generator_refs,

tools/validate_rpcs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async def get_height_to_hash_bytes(root_path: Path, config: dict[str, Any]) -> b
4444
return await f.read()
4545

4646

47-
def get_block_hash_from_height(height: int, height_to_hash: bytes) -> bytes32:
47+
def get_block_hash_for_height(height: int, height_to_hash: bytes) -> bytes32:
4848
"""
4949
Get the block header hash from the height-to-hash database.
5050
"""
@@ -235,7 +235,7 @@ async def cli_async(
235235
start_time: float = cycle_start
236236

237237
def add_tasks_for_height(height: int) -> None:
238-
block_header_hash = get_block_hash_from_height(height, height_to_hash_bytes)
238+
block_header_hash = get_block_hash_for_height(height, height_to_hash_bytes)
239239
# Create tasks for each RPC call based on the flags
240240
if spends_with_conditions:
241241
pipeline.add(
@@ -249,7 +249,7 @@ def add_tasks_for_height(height: int) -> None:
249249
for i in range(start_height, end_height + 1):
250250
add_tasks_for_height(height=i)
251251
# Make Status Updates.
252-
if len(pipeline) >= pipeline_depth:
252+
while len(pipeline) >= pipeline_depth:
253253
done, pipeline = await asyncio.wait(pipeline, return_when=asyncio.FIRST_COMPLETED)
254254
completed_requests += len(done)
255255
now = time.monotonic()

0 commit comments

Comments
 (0)