benchmark for blockchain.get_block_generator() (#9999)
This commit is contained in:
parent
e0aa80b428
commit
6872e75a48
|
@ -0,0 +1,100 @@
|
|||
import click
|
||||
import aiosqlite
|
||||
import asyncio
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
|
||||
from typing import Optional, List
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.full_node.hint_store import HintStore
|
||||
from chia.types.blockchain_format.program import SerializedProgram
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.db_version import lookup_db_version
|
||||
from chia.util.db_wrapper import DBWrapper
|
||||
from chia.util.ints import uint32
|
||||
|
||||
# the first transaction block. Each byte in transaction_height_delta is the
|
||||
# number of blocks to skip forward to get to the next transaction block
|
||||
transaction_block_heights = []
|
||||
last = 225698
|
||||
file_path = os.path.realpath(__file__)
|
||||
for delta in open(Path(file_path).parent / "transaction_height_delta", "rb").read():
|
||||
new = last + delta
|
||||
transaction_block_heights.append(new)
|
||||
last = new
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BlockInfo:
|
||||
prev_header_hash: bytes32
|
||||
transactions_generator: Optional[SerializedProgram]
|
||||
transactions_generator_ref_list: List[uint32]
|
||||
|
||||
|
||||
def random_refs() -> List[uint32]:
|
||||
ret = random.sample(transaction_block_heights, DEFAULT_CONSTANTS.MAX_GENERATOR_REF_LIST_SIZE)
|
||||
random.shuffle(ret)
|
||||
return [uint32(i) for i in ret]
|
||||
|
||||
|
||||
REPETITIONS = 100
|
||||
|
||||
|
||||
async def main(db_path: Path):
|
||||
|
||||
random.seed(0x213FB154)
|
||||
|
||||
async with aiosqlite.connect(db_path) as connection:
|
||||
await connection.execute("pragma journal_mode=wal")
|
||||
await connection.execute("pragma synchronous=FULL")
|
||||
await connection.execute("pragma query_only=ON")
|
||||
db_version: int = await lookup_db_version(connection)
|
||||
|
||||
db_wrapper = DBWrapper(connection, db_version=db_version)
|
||||
block_store = await BlockStore.create(db_wrapper)
|
||||
hint_store = await HintStore.create(db_wrapper)
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
|
||||
start_time = time.time()
|
||||
# make configurable
|
||||
reserved_cores = 4
|
||||
blockchain = await Blockchain.create(
|
||||
coin_store, block_store, DEFAULT_CONSTANTS, hint_store, db_path.parent, reserved_cores
|
||||
)
|
||||
|
||||
peak = blockchain.get_peak()
|
||||
timing = 0.0
|
||||
for i in range(REPETITIONS):
|
||||
block = BlockInfo(
|
||||
peak.header_hash,
|
||||
SerializedProgram.from_bytes(bytes.fromhex("80")),
|
||||
random_refs(),
|
||||
)
|
||||
|
||||
start_time = time.time()
|
||||
gen = await blockchain.get_block_generator(block)
|
||||
one_call = time.time() - start_time
|
||||
timing += one_call
|
||||
assert gen is not None
|
||||
|
||||
print(f"get_block_generator(): {timing/REPETITIONS:0.3f}s")
|
||||
|
||||
blockchain.shut_down()
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.argument("db-path", type=click.Path())
|
||||
def entry_point(db_path: Path):
|
||||
asyncio.run(main(Path(db_path)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# pylint: disable = no-value-for-parameter
|
||||
entry_point()
|
Binary file not shown.
|
@ -6,7 +6,7 @@ import traceback
|
|||
from concurrent.futures.process import ProcessPoolExecutor
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Set, Tuple, Union
|
||||
from typing import Dict, List, Optional, Set, Tuple
|
||||
|
||||
from clvm.casts import int_from_bytes
|
||||
|
||||
|
@ -47,6 +47,7 @@ from chia.util.errors import ConsensusError, Err
|
|||
from chia.util.generator_tools import get_block_header, tx_removals_and_additions
|
||||
from chia.util.ints import uint16, uint32, uint64, uint128
|
||||
from chia.util.streamable import recurse_jsonify
|
||||
from chia.types.block_protocol import BlockInfo
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -861,7 +862,7 @@ class Blockchain(BlockchainInterface):
|
|||
return False
|
||||
|
||||
async def get_block_generator(
|
||||
self, block: Union[FullBlock, UnfinishedBlock], additional_blocks=None
|
||||
self, block: BlockInfo, additional_blocks: Dict[bytes32, FullBlock] = None
|
||||
) -> Optional[BlockGenerator]:
|
||||
if additional_blocks is None:
|
||||
additional_blocks = {}
|
||||
|
@ -895,7 +896,7 @@ class Blockchain(BlockchainInterface):
|
|||
else:
|
||||
# First tries to find the blocks in additional_blocks
|
||||
reorg_chain: Dict[uint32, FullBlock] = {}
|
||||
curr: Union[FullBlock, UnfinishedBlock] = block
|
||||
curr = block
|
||||
additional_height_dict = {}
|
||||
while curr.prev_header_hash in additional_blocks:
|
||||
prev: FullBlock = additional_blocks[curr.prev_header_hash]
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from typing_extensions import Protocol
|
||||
|
||||
from chia.types.blockchain_format.program import SerializedProgram
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.ints import uint32
|
||||
|
||||
|
||||
class BlockInfo(Protocol):
|
||||
@property
|
||||
def prev_header_hash(self) -> bytes32:
|
||||
pass
|
||||
|
||||
@property
|
||||
def transactions_generator(self) -> Optional[SerializedProgram]:
|
||||
pass
|
||||
|
||||
@property
|
||||
def transactions_generator_ref_list(self) -> List[uint32]:
|
||||
pass
|
Loading…
Reference in New Issue