mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2025-01-08 10:25:24 +03:00
Annotate test_block_height_map.py (#16181)
Annotate test_block_height_map.py.
This commit is contained in:
parent
fd541bd40d
commit
a07a565096
@ -90,7 +90,6 @@ tests.core.full_node.full_sync.test_full_sync
|
||||
tests.core.full_node.stores.test_hint_store
|
||||
tests.core.full_node.stores.test_sync_store
|
||||
tests.core.full_node.test_address_manager
|
||||
tests.core.full_node.test_block_height_map
|
||||
tests.core.full_node.test_conditions
|
||||
tests.core.full_node.test_full_node
|
||||
tests.core.full_node.test_node_load
|
||||
|
@ -11,7 +11,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
|
||||
from chia.util.db_wrapper import DBWrapper2
|
||||
from chia.util.files import write_file_async
|
||||
from chia.util.ints import uint8
|
||||
from chia.util.ints import uint8, uint32
|
||||
from tests.util.db_connection import DBConnection
|
||||
|
||||
|
||||
@ -26,13 +26,8 @@ def gen_ses(height: int) -> SubEpochSummary:
|
||||
|
||||
|
||||
async def new_block(
|
||||
db: DBWrapper2,
|
||||
block_hash: bytes32,
|
||||
parent: bytes32,
|
||||
height: int,
|
||||
is_peak: bool,
|
||||
ses: Optional[SubEpochSummary],
|
||||
):
|
||||
db: DBWrapper2, block_hash: bytes32, parent: bytes32, height: int, is_peak: bool, ses: Optional[SubEpochSummary]
|
||||
) -> None:
|
||||
async with db.writer_maybe_transaction() as conn:
|
||||
cursor = await conn.execute(
|
||||
"INSERT INTO full_blocks VALUES(?, ?, ?, ?)",
|
||||
@ -50,7 +45,7 @@ async def new_block(
|
||||
await cursor.close()
|
||||
|
||||
|
||||
async def setup_db(db: DBWrapper2):
|
||||
async def setup_db(db: DBWrapper2) -> None:
|
||||
async with db.writer_maybe_transaction() as conn:
|
||||
await conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS full_blocks("
|
||||
@ -69,8 +64,8 @@ async def setup_db(db: DBWrapper2):
|
||||
# and the chain_id will be mixed in to the hashes, to form a separate chain at
|
||||
# the same heights as the main chain
|
||||
async def setup_chain(
|
||||
db: DBWrapper2, length: int, *, chain_id: int = 0, ses_every: Optional[int] = None, start_height=0
|
||||
):
|
||||
db: DBWrapper2, length: int, *, chain_id: int = 0, ses_every: Optional[int] = None, start_height: int = 0
|
||||
) -> None:
|
||||
height = start_height
|
||||
peak_hash = gen_block_hash(height + chain_id * 65536)
|
||||
parent_hash = bytes32([0] * 32)
|
||||
@ -90,22 +85,22 @@ async def setup_chain(
|
||||
|
||||
class TestBlockHeightMap:
|
||||
@pytest.mark.asyncio
|
||||
async def test_height_to_hash(self, tmp_dir, db_version):
|
||||
async def test_height_to_hash(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
assert not height_map.contains_height(11)
|
||||
assert not height_map.contains_height(uint32(11))
|
||||
for height in reversed(range(10)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
|
||||
for height in reversed(range(10)):
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_height_to_hash_long_chain(self, tmp_dir, db_version):
|
||||
async def test_height_to_hash_long_chain(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10000)
|
||||
@ -113,13 +108,13 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in reversed(range(1000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
|
||||
for height in reversed(range(10000)):
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_save_restore(self, tmp_dir, db_version):
|
||||
async def test_save_restore(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10000, ses_every=20)
|
||||
@ -127,13 +122,13 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in reversed(range(10000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
if (height % 20) == 0:
|
||||
assert height_map.get_ses(height) == gen_ses(height)
|
||||
assert height_map.get_ses(uint32(height)) == gen_ses(height)
|
||||
else:
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(height)
|
||||
height_map.get_ses(uint32(height))
|
||||
|
||||
await height_map.maybe_flush()
|
||||
|
||||
@ -151,16 +146,16 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in reversed(range(10000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
if (height % 20) == 0:
|
||||
assert height_map.get_ses(height) == gen_ses(height)
|
||||
assert height_map.get_ses(uint32(height)) == gen_ses(height)
|
||||
else:
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(height)
|
||||
height_map.get_ses(uint32(height))
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_restore_entire_chain(self, tmp_dir, db_version):
|
||||
async def test_restore_entire_chain(self, tmp_dir: Path, db_version: int) -> None:
|
||||
# this is a test where the height-to-hash and height-to-ses caches are
|
||||
# entirely unrelated to the database. Make sure they can both be fully
|
||||
# replaced
|
||||
@ -174,7 +169,7 @@ class TestBlockHeightMap:
|
||||
|
||||
ses_cache = []
|
||||
for i in range(0, 900, 19):
|
||||
ses_cache.append((i, gen_ses(i + 9999)))
|
||||
ses_cache.append((uint32(i), bytes(gen_ses(i + 9999))))
|
||||
|
||||
await write_file_async(tmp_dir / "sub-epoch-summaries", bytes(SesCache(ses_cache)))
|
||||
|
||||
@ -184,16 +179,16 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in reversed(range(10000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
if (height % 20) == 0:
|
||||
assert height_map.get_ses(height) == gen_ses(height)
|
||||
assert height_map.get_ses(uint32(height)) == gen_ses(height)
|
||||
else:
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(height)
|
||||
height_map.get_ses(uint32(height))
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_restore_extend(self, tmp_dir, db_version):
|
||||
async def test_restore_extend(self, tmp_dir: Path, db_version: int) -> None:
|
||||
# test the case where the cache has fewer blocks than the DB, and that
|
||||
# we correctly load all the missing blocks from the DB to update the
|
||||
# cache
|
||||
@ -204,13 +199,13 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in reversed(range(2000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
if (height % 20) == 0:
|
||||
assert height_map.get_ses(height) == gen_ses(height)
|
||||
assert height_map.get_ses(uint32(height)) == gen_ses(height)
|
||||
else:
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(height)
|
||||
height_map.get_ses(uint32(height))
|
||||
|
||||
await height_map.maybe_flush()
|
||||
|
||||
@ -224,16 +219,16 @@ class TestBlockHeightMap:
|
||||
|
||||
# now make sure we have the complete chain, height 0 -> 4000
|
||||
for height in reversed(range(4000)):
|
||||
assert height_map.contains_height(height)
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.contains_height(uint32(height))
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
if (height % 20) == 0:
|
||||
assert height_map.get_ses(height) == gen_ses(height)
|
||||
assert height_map.get_ses(uint32(height)) == gen_ses(height)
|
||||
else:
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(height)
|
||||
height_map.get_ses(uint32(height))
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_height_to_hash_with_orphans(self, tmp_dir, db_version):
|
||||
async def test_height_to_hash_with_orphans(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10)
|
||||
@ -245,10 +240,10 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in range(10):
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_height_to_hash_update(self, tmp_dir, db_version):
|
||||
async def test_height_to_hash_update(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10)
|
||||
@ -259,17 +254,17 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
for height in range(10):
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
|
||||
height_map.update_height(10, gen_block_hash(100), None)
|
||||
height_map.update_height(uint32(10), gen_block_hash(100), None)
|
||||
|
||||
for height in range(9):
|
||||
assert height_map.get_hash(height) == gen_block_hash(height)
|
||||
assert height_map.get_hash(uint32(height)) == gen_block_hash(height)
|
||||
|
||||
assert height_map.get_hash(10) == gen_block_hash(100)
|
||||
assert height_map.get_hash(uint32(10)) == gen_block_hash(100)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_ses(self, tmp_dir, db_version):
|
||||
async def test_update_ses(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10)
|
||||
@ -280,104 +275,104 @@ class TestBlockHeightMap:
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(10)
|
||||
height_map.get_ses(uint32(10))
|
||||
|
||||
height_map.update_height(10, gen_block_hash(10), gen_ses(10))
|
||||
height_map.update_height(uint32(10), gen_block_hash(10), gen_ses(10))
|
||||
|
||||
assert height_map.get_ses(10) == gen_ses(10)
|
||||
assert height_map.get_hash(10) == gen_block_hash(10)
|
||||
assert height_map.get_ses(uint32(10)) == gen_ses(10)
|
||||
assert height_map.get_hash(uint32(10)) == gen_block_hash(10)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_height_to_ses(self, tmp_dir, db_version):
|
||||
async def test_height_to_ses(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10, ses_every=2)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
assert height_map.get_ses(0) == gen_ses(0)
|
||||
assert height_map.get_ses(2) == gen_ses(2)
|
||||
assert height_map.get_ses(4) == gen_ses(4)
|
||||
assert height_map.get_ses(6) == gen_ses(6)
|
||||
assert height_map.get_ses(8) == gen_ses(8)
|
||||
assert height_map.get_ses(uint32(0)) == gen_ses(0)
|
||||
assert height_map.get_ses(uint32(2)) == gen_ses(2)
|
||||
assert height_map.get_ses(uint32(4)) == gen_ses(4)
|
||||
assert height_map.get_ses(uint32(6)) == gen_ses(6)
|
||||
assert height_map.get_ses(uint32(8)) == gen_ses(8)
|
||||
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(1)
|
||||
height_map.get_ses(uint32(1))
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(3)
|
||||
height_map.get_ses(uint32(3))
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(5)
|
||||
height_map.get_ses(uint32(5))
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(7)
|
||||
height_map.get_ses(uint32(7))
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(9)
|
||||
height_map.get_ses(uint32(9))
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rollback(self, tmp_dir, db_version):
|
||||
async def test_rollback(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10, ses_every=2)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
assert height_map.get_ses(0) == gen_ses(0)
|
||||
assert height_map.get_ses(2) == gen_ses(2)
|
||||
assert height_map.get_ses(4) == gen_ses(4)
|
||||
assert height_map.get_ses(6) == gen_ses(6)
|
||||
assert height_map.get_ses(8) == gen_ses(8)
|
||||
assert height_map.get_ses(uint32(0)) == gen_ses(0)
|
||||
assert height_map.get_ses(uint32(2)) == gen_ses(2)
|
||||
assert height_map.get_ses(uint32(4)) == gen_ses(4)
|
||||
assert height_map.get_ses(uint32(6)) == gen_ses(6)
|
||||
assert height_map.get_ses(uint32(8)) == gen_ses(8)
|
||||
|
||||
assert height_map.get_hash(5) == gen_block_hash(5)
|
||||
assert height_map.get_hash(uint32(5)) == gen_block_hash(5)
|
||||
|
||||
height_map.rollback(5)
|
||||
assert height_map.contains_height(0)
|
||||
assert height_map.contains_height(1)
|
||||
assert height_map.contains_height(2)
|
||||
assert height_map.contains_height(3)
|
||||
assert height_map.contains_height(4)
|
||||
assert height_map.contains_height(5)
|
||||
assert not height_map.contains_height(6)
|
||||
assert not height_map.contains_height(7)
|
||||
assert not height_map.contains_height(8)
|
||||
assert height_map.get_hash(5) == gen_block_hash(5)
|
||||
assert height_map.contains_height(uint32(0))
|
||||
assert height_map.contains_height(uint32(1))
|
||||
assert height_map.contains_height(uint32(2))
|
||||
assert height_map.contains_height(uint32(3))
|
||||
assert height_map.contains_height(uint32(4))
|
||||
assert height_map.contains_height(uint32(5))
|
||||
assert not height_map.contains_height(uint32(6))
|
||||
assert not height_map.contains_height(uint32(7))
|
||||
assert not height_map.contains_height(uint32(8))
|
||||
assert height_map.get_hash(uint32(5)) == gen_block_hash(5)
|
||||
|
||||
assert height_map.get_ses(0) == gen_ses(0)
|
||||
assert height_map.get_ses(2) == gen_ses(2)
|
||||
assert height_map.get_ses(4) == gen_ses(4)
|
||||
assert height_map.get_ses(uint32(0)) == gen_ses(0)
|
||||
assert height_map.get_ses(uint32(2)) == gen_ses(2)
|
||||
assert height_map.get_ses(uint32(4)) == gen_ses(4)
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(6)
|
||||
height_map.get_ses(uint32(6))
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(8)
|
||||
height_map.get_ses(uint32(8))
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rollback2(self, tmp_dir, db_version):
|
||||
async def test_rollback2(self, tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
await setup_chain(db_wrapper, 10, ses_every=2)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
assert height_map.get_ses(0) == gen_ses(0)
|
||||
assert height_map.get_ses(2) == gen_ses(2)
|
||||
assert height_map.get_ses(4) == gen_ses(4)
|
||||
assert height_map.get_ses(6) == gen_ses(6)
|
||||
assert height_map.get_ses(8) == gen_ses(8)
|
||||
assert height_map.get_ses(uint32(0)) == gen_ses(0)
|
||||
assert height_map.get_ses(uint32(2)) == gen_ses(2)
|
||||
assert height_map.get_ses(uint32(4)) == gen_ses(4)
|
||||
assert height_map.get_ses(uint32(6)) == gen_ses(6)
|
||||
assert height_map.get_ses(uint32(8)) == gen_ses(8)
|
||||
|
||||
assert height_map.get_hash(6) == gen_block_hash(6)
|
||||
assert height_map.get_hash(uint32(6)) == gen_block_hash(6)
|
||||
|
||||
height_map.rollback(6)
|
||||
assert height_map.contains_height(6)
|
||||
assert not height_map.contains_height(7)
|
||||
assert height_map.contains_height(uint32(6))
|
||||
assert not height_map.contains_height(uint32(7))
|
||||
|
||||
assert height_map.get_hash(6) == gen_block_hash(6)
|
||||
assert height_map.get_hash(uint32(6)) == gen_block_hash(6)
|
||||
with pytest.raises(AssertionError) as _:
|
||||
height_map.get_hash(7)
|
||||
height_map.get_hash(uint32(7))
|
||||
|
||||
assert height_map.get_ses(0) == gen_ses(0)
|
||||
assert height_map.get_ses(2) == gen_ses(2)
|
||||
assert height_map.get_ses(4) == gen_ses(4)
|
||||
assert height_map.get_ses(6) == gen_ses(6)
|
||||
assert height_map.get_ses(uint32(0)) == gen_ses(0)
|
||||
assert height_map.get_ses(uint32(2)) == gen_ses(2)
|
||||
assert height_map.get_ses(uint32(4)) == gen_ses(4)
|
||||
assert height_map.get_ses(uint32(6)) == gen_ses(6)
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(8)
|
||||
height_map.get_ses(uint32(8))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -388,21 +383,21 @@ async def test_unsupported_version(tmp_dir: Path) -> None:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_empty_chain(tmp_dir, db_version):
|
||||
async def test_empty_chain(tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(0)
|
||||
height_map.get_ses(uint32(0))
|
||||
|
||||
with pytest.raises(AssertionError) as _:
|
||||
height_map.get_hash(0)
|
||||
height_map.get_hash(uint32(0))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_peak_only_chain(tmp_dir, db_version):
|
||||
async def test_peak_only_chain(tmp_dir: Path, db_version: int) -> None:
|
||||
async with DBConnection(db_version) as db_wrapper:
|
||||
await setup_db(db_wrapper)
|
||||
|
||||
@ -415,7 +410,7 @@ async def test_peak_only_chain(tmp_dir, db_version):
|
||||
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
||||
|
||||
with pytest.raises(KeyError) as _:
|
||||
height_map.get_ses(0)
|
||||
height_map.get_ses(uint32(0))
|
||||
|
||||
with pytest.raises(AssertionError) as _:
|
||||
height_map.get_hash(0)
|
||||
height_map.get_hash(uint32(0))
|
||||
|
Loading…
Reference in New Issue
Block a user