benchmark for blockchain.get_block_generator() (#9999)

This commit is contained in:
Arvid Norberg 2022-02-04 01:09:04 +01:00 committed by GitHub
parent e0aa80b428
commit 6872e75a48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 3 deletions

100
benchmarks/block_ref.py Normal file
View File

@ -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.

View File

@ -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]

View File

@ -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