mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-24 10:05:29 -05:00
Refactor BlockHeightMap Creation to Decouple It from Blockchain (#19711)
Create `BlockHeightMap` outside of `Blockchain` so `chia.consensus` doesn't have to depend on a specific storage mechanism.
This commit is contained in:
@@ -16,6 +16,7 @@ from chia_rs.sized_ints import uint32
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.consensus.get_block_generator import get_block_generator
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.types.blockchain_format.serialized_program import SerializedProgram
|
||||
@@ -68,7 +69,8 @@ async def main(db_path: Path) -> None:
|
||||
start_time = monotonic()
|
||||
# make configurable
|
||||
reserved_cores = 4
|
||||
blockchain = await Blockchain.create(coin_store, block_store, DEFAULT_CONSTANTS, db_path.parent, reserved_cores)
|
||||
height_map = await BlockHeightMap.create(db_path.parent, db_wrapper)
|
||||
blockchain = await Blockchain.create(coin_store, block_store, height_map, DEFAULT_CONSTANTS, reserved_cores)
|
||||
|
||||
peak = blockchain.get_peak()
|
||||
assert peak is not None
|
||||
|
||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
||||
from chia_rs import ConsensusConstants
|
||||
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.util.db_wrapper import DBWrapper2
|
||||
@@ -21,7 +22,8 @@ async def create_ram_blockchain(
|
||||
async with DBWrapper2.managed(database=uri, uri=True, reader_count=1, db_version=2) as db_wrapper:
|
||||
block_store = await BlockStore.create(db_wrapper)
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
blockchain = await Blockchain.create(coin_store, block_store, consensus_constants, Path("."), 2)
|
||||
height_map = await BlockHeightMap.create(Path("."), db_wrapper)
|
||||
blockchain = await Blockchain.create(coin_store, block_store, height_map, consensus_constants, 2)
|
||||
try:
|
||||
yield db_wrapper, blockchain
|
||||
finally:
|
||||
|
||||
@@ -22,6 +22,7 @@ from chia.consensus.block_body_validation import ForkInfo
|
||||
from chia.consensus.blockchain import AddBlockResult, Blockchain
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.consensus.full_block_to_block_record import header_block_to_sub_block_record
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.full_node.full_block_utils import GeneratorBlockInfo
|
||||
@@ -72,7 +73,8 @@ async def test_block_store(tmp_dir: Path, db_version: int, bt: BlockTools, use_c
|
||||
# Use a different file for the blockchain
|
||||
coin_store_2 = await CoinStore.create(db_wrapper_2)
|
||||
store_2 = await BlockStore.create(db_wrapper_2, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, height_map, bt.constants, 2)
|
||||
|
||||
store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
await BlockStore.create(db_wrapper_2)
|
||||
@@ -147,7 +149,8 @@ async def test_get_full_blocks_at(
|
||||
# Use a different file for the blockchain
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
|
||||
count = 0
|
||||
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
||||
@@ -174,7 +177,8 @@ async def test_get_block_records_in_range(
|
||||
# Use a different file for the blockchain
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
|
||||
count = 0
|
||||
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
||||
@@ -203,8 +207,8 @@ async def test_get_block_bytes_in_range_in_main_chain(
|
||||
# Use a different file for the blockchain
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
count = 0
|
||||
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
||||
for b1, b2 in zip(blocks, alt_blocks):
|
||||
@@ -232,7 +236,8 @@ async def test_deadlock(tmp_dir: Path, db_version: int, bt: BlockTools, use_cach
|
||||
store = await BlockStore.create(wrapper, use_cache=use_cache)
|
||||
coin_store_2 = await CoinStore.create(wrapper_2)
|
||||
store_2 = await BlockStore.create(wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, height_map, bt.constants, 2)
|
||||
block_records = []
|
||||
for block in blocks:
|
||||
await _validate_and_add_block(bc, block)
|
||||
@@ -262,7 +267,8 @@ async def test_rollback(bt: BlockTools, tmp_dir: Path, use_cache: bool, default_
|
||||
# Use a different file for the blockchain
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
|
||||
# insert all blocks
|
||||
count = 0
|
||||
@@ -324,7 +330,8 @@ async def test_count_compactified_blocks(bt: BlockTools, tmp_dir: Path, db_versi
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
|
||||
count = await block_store.count_compactified_blocks()
|
||||
assert count == 0
|
||||
@@ -344,7 +351,8 @@ async def test_count_uncompactified_blocks(bt: BlockTools, tmp_dir: Path, db_ver
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
|
||||
count = await block_store.count_uncompactified_blocks()
|
||||
assert count == 0
|
||||
@@ -377,7 +385,8 @@ async def test_replace_proof(bt: BlockTools, tmp_dir: Path, db_version: int, use
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
block_store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store, block_store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, bt.constants, 2)
|
||||
for block in blocks:
|
||||
await _validate_and_add_block(bc, block)
|
||||
|
||||
@@ -457,7 +466,8 @@ async def test_get_blocks_by_hash(tmp_dir: Path, bt: BlockTools, db_version: int
|
||||
# Use a different file for the blockchain
|
||||
coin_store_2 = await CoinStore.create(db_wrapper_2)
|
||||
store_2 = await BlockStore.create(db_wrapper_2, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, height_map, bt.constants, 2)
|
||||
|
||||
store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
await BlockStore.create(db_wrapper_2)
|
||||
@@ -496,7 +506,8 @@ async def test_get_block_bytes_in_range(tmp_dir: Path, bt: BlockTools, db_versio
|
||||
# Use a different file for the blockchain
|
||||
coin_store_2 = await CoinStore.create(db_wrapper_2)
|
||||
store_2 = await BlockStore.create(db_wrapper_2, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, height_map, bt.constants, 2)
|
||||
|
||||
await BlockStore.create(db_wrapper_2)
|
||||
|
||||
@@ -568,7 +579,8 @@ async def test_get_prev_hash(tmp_dir: Path, bt: BlockTools, db_version: int, use
|
||||
# Use a different file for the blockchain
|
||||
coin_store_2 = await CoinStore.create(db_wrapper_2)
|
||||
store_2 = await BlockStore.create(db_wrapper_2, use_cache=use_cache)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper_2)
|
||||
bc = await Blockchain.create(coin_store_2, store_2, height_map, bt.constants, 2)
|
||||
|
||||
store = await BlockStore.create(db_wrapper, use_cache=use_cache)
|
||||
await BlockStore.create(db_wrapper_2)
|
||||
|
||||
@@ -19,6 +19,7 @@ from chia.consensus.block_body_validation import ForkInfo
|
||||
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
||||
from chia.consensus.blockchain import AddBlockResult, Blockchain
|
||||
from chia.consensus.coinbase import create_farmer_coin, create_pool_coin
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.full_node.hint_store import HintStore
|
||||
@@ -314,7 +315,8 @@ async def test_basic_reorg(tmp_dir: Path, db_version: int, bt: BlockTools) -> No
|
||||
blocks = bt.get_consecutive_blocks(initial_block_count)
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
store = await BlockStore.create(db_wrapper)
|
||||
b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
b: Blockchain = await Blockchain.create(coin_store, store, height_map, bt.constants, 2)
|
||||
try:
|
||||
records: list[Optional[CoinRecord]] = []
|
||||
|
||||
@@ -380,7 +382,8 @@ async def test_get_puzzle_hash(tmp_dir: Path, db_version: int, bt: BlockTools) -
|
||||
)
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
store = await BlockStore.create(db_wrapper)
|
||||
b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
b: Blockchain = await Blockchain.create(coin_store, store, height_map, bt.constants, 2)
|
||||
for block in blocks:
|
||||
await _validate_and_add_block(b, block)
|
||||
peak = b.get_peak()
|
||||
|
||||
@@ -12,6 +12,7 @@ from chia.cmds.db_upgrade_func import convert_v1_to_v2
|
||||
from chia.consensus.block_body_validation import ForkInfo
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.consensus.multiprocess_validation import PreValidationResult
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.full_node.hint_store import HintStore
|
||||
@@ -67,7 +68,8 @@ async def test_blocks(default_1000_blocks, with_hints: bool):
|
||||
for h in hints:
|
||||
await hint_store1.add_hints([(h[0], h[1])])
|
||||
|
||||
bc = await Blockchain.create(coin_store1, block_store1, test_constants, Path("."), reserved_cores=0)
|
||||
height_map = await BlockHeightMap.create(Path("."), db_wrapper1)
|
||||
bc = await Blockchain.create(coin_store1, block_store1, height_map, test_constants, reserved_cores=0)
|
||||
sub_slot_iters = test_constants.SUB_SLOT_ITERS_STARTING
|
||||
for block in blocks:
|
||||
if block.height != 0 and len(block.finished_sub_slots) > 0:
|
||||
|
||||
@@ -17,6 +17,7 @@ from chia.consensus.block_body_validation import ForkInfo
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.consensus.multiprocess_validation import PreValidationResult
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.simulator.block_tools import test_constants
|
||||
@@ -143,8 +144,9 @@ async def make_db(db_file: Path, blocks: list[FullBlock]) -> None:
|
||||
|
||||
block_store = await BlockStore.create(db_wrapper)
|
||||
coin_store = await CoinStore.create(db_wrapper)
|
||||
height_map = await BlockHeightMap.create(Path("."), db_wrapper)
|
||||
|
||||
bc = await Blockchain.create(coin_store, block_store, test_constants, Path("."), reserved_cores=0)
|
||||
bc = await Blockchain.create(coin_store, block_store, height_map, test_constants, reserved_cores=0)
|
||||
sub_slot_iters = test_constants.SUB_SLOT_ITERS_STARTING
|
||||
for block in blocks:
|
||||
if block.height != 0 and len(block.finished_sub_slots) > 0:
|
||||
|
||||
@@ -11,6 +11,7 @@ from chia_rs import ConsensusConstants, FullBlock
|
||||
from chia_rs.sized_ints import uint64
|
||||
|
||||
from chia.consensus.blockchain import Blockchain
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
from chia.simulator.block_tools import BlockTools
|
||||
@@ -26,7 +27,9 @@ async def create_blockchain(
|
||||
async with DBWrapper2.managed(database=db_uri, uri=True, reader_count=1, db_version=db_version) as wrapper:
|
||||
coin_store = await CoinStore.create(wrapper)
|
||||
store = await BlockStore.create(wrapper)
|
||||
bc1 = await Blockchain.create(coin_store, store, constants, Path("."), 2, single_threaded=True, log_coins=True)
|
||||
path = Path(".")
|
||||
height_map = await BlockHeightMap.create(path, wrapper)
|
||||
bc1 = await Blockchain.create(coin_store, store, height_map, constants, 3, single_threaded=True, log_coins=True)
|
||||
try:
|
||||
assert bc1.get_peak() is None
|
||||
yield bc1, wrapper
|
||||
|
||||
@@ -7,7 +7,6 @@ import logging
|
||||
import traceback
|
||||
from concurrent.futures import Executor, ThreadPoolExecutor
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, cast
|
||||
|
||||
from chia_rs import (
|
||||
@@ -124,13 +123,12 @@ class Blockchain:
|
||||
async def create(
|
||||
coin_store: CoinStore,
|
||||
block_store: BlockStore,
|
||||
height_map: BlockHeightMap,
|
||||
consensus_constants: ConsensusConstants,
|
||||
blockchain_dir: Path,
|
||||
reserved_cores: int,
|
||||
*,
|
||||
single_threaded: bool = False,
|
||||
log_coins: bool = False,
|
||||
selected_network: Optional[str] = None,
|
||||
) -> Blockchain:
|
||||
"""
|
||||
Initializes a blockchain with the BlockRecords from disk, assuming they have all been
|
||||
@@ -158,7 +156,7 @@ class Blockchain:
|
||||
self.coin_store = coin_store
|
||||
self.block_store = block_store
|
||||
self._shut_down = False
|
||||
await self._load_chain_from_store(blockchain_dir, selected_network)
|
||||
await self._load_chain_from_store(height_map)
|
||||
self._seen_compact_proofs = set()
|
||||
return self
|
||||
|
||||
@@ -166,11 +164,11 @@ class Blockchain:
|
||||
self._shut_down = True
|
||||
self.pool.shutdown(wait=True)
|
||||
|
||||
async def _load_chain_from_store(self, blockchain_dir: Path, selected_network: Optional[str] = None) -> None:
|
||||
async def _load_chain_from_store(self, height_map: BlockHeightMap) -> None:
|
||||
"""
|
||||
Initializes the state of the Blockchain class from the database.
|
||||
"""
|
||||
self.__height_map = await BlockHeightMap.create(blockchain_dir, self.block_store.db_wrapper, selected_network)
|
||||
self.__height_map = height_map
|
||||
self.__block_records = {}
|
||||
self.__heights_in_cache = {}
|
||||
block_records, peak = await self.block_store.get_block_records_close_to_peak(self.constants.BLOCKS_CACHE_SIZE)
|
||||
|
||||
@@ -48,6 +48,7 @@ from chia.consensus.make_sub_epoch_summary import next_sub_epoch_summary
|
||||
from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_block
|
||||
from chia.consensus.pot_iterations import calculate_sp_iters
|
||||
from chia.consensus.signage_point import SignagePoint
|
||||
from chia.full_node.block_height_map import BlockHeightMap
|
||||
from chia.full_node.block_store import BlockStore
|
||||
from chia.full_node.check_fork_next_block import check_fork_next_block
|
||||
from chia.full_node.coin_store import CoinStore
|
||||
@@ -263,15 +264,16 @@ class FullNode:
|
||||
log_coins = self.config.get("log_coins", False)
|
||||
multiprocessing_start_method = process_config_start_method(config=self.config, log=self.log)
|
||||
self.multiprocessing_context = multiprocessing.get_context(method=multiprocessing_start_method)
|
||||
selected_network = self.config.get("selected_network")
|
||||
height_map = await BlockHeightMap.create(self.db_path.parent, self._db_wrapper, selected_network)
|
||||
self._blockchain = await Blockchain.create(
|
||||
coin_store=self.coin_store,
|
||||
block_store=self.block_store,
|
||||
consensus_constants=self.constants,
|
||||
blockchain_dir=self.db_path.parent,
|
||||
height_map=height_map,
|
||||
reserved_cores=reserved_cores,
|
||||
single_threaded=single_threaded,
|
||||
log_coins=log_coins,
|
||||
selected_network=self.config.get("selected_network"),
|
||||
)
|
||||
|
||||
self._mempool_manager = MempoolManager(
|
||||
|
||||
Reference in New Issue
Block a user