Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix updating of sub-epoch-summary map #10486

Merged
merged 1 commit into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions chia/full_node/block_height_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ async def _load_blocks_from(self, height: uint32, prev_hash: bytes32):
):
return
self.__sub_epoch_summaries[height] = entry[2]
elif height in self.__sub_epoch_summaries:
# if the database file was swapped out and the existing
# cache doesn't represent any of it at all, a missing sub
# epoch summary needs to be removed from the cache too
del self.__sub_epoch_summaries[height]
self.__set_hash(height, prev_hash)
prev_hash = entry[1]

Expand Down
40 changes: 37 additions & 3 deletions tests/core/full_node/test_block_height_map.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import pytest
import struct
from chia.full_node.block_height_map import BlockHeightMap
from chia.full_node.block_height_map import BlockHeightMap, SesCache
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
from chia.util.db_wrapper import DBWrapper

from tests.util.db_connection import DBConnection
from chia.types.blockchain_format.sized_bytes import bytes32
from typing import Optional
from chia.util.ints import uint8

# from tests.conftest import tmp_dir
from chia.util.files import write_file_async


def gen_block_hash(height: int) -> bytes32:
Expand Down Expand Up @@ -189,6 +188,41 @@ async def test_save_restore(self, tmp_dir, db_version):
with pytest.raises(KeyError) as _:
height_map.get_ses(height)

@pytest.mark.asyncio
async def test_restore_entire_chain(self, tmp_dir, db_version):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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:

Note that you need to fix some mypy issues and import Path if you apply this.


# 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
async with DBConnection(db_version) as db_wrapper:

heights = bytearray(900 * 32)
for i in range(900):
idx = i * 32
heights[idx : idx + 32] = bytes([i % 256] * 32)

await write_file_async(tmp_dir / "height-to-hash", heights)

ses_cache = []
for i in range(0, 900, 19):
ses_cache.append((i, gen_ses(i + 9999)))

await write_file_async(tmp_dir / "sub-epoch-summaries", bytes(SesCache(ses_cache)))

await setup_db(db_wrapper)
await setup_chain(db_wrapper, 10000, ses_every=20)

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)
if (height % 20) == 0:
assert height_map.get_ses(height) == gen_ses(height)
else:
with pytest.raises(KeyError) as _:
height_map.get_ses(height)

@pytest.mark.asyncio
async def test_restore_extend(self, tmp_dir, db_version):

Expand Down