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

undo BlockRecord cache insert, when DB fails #16909

Merged
merged 3 commits into from
Jan 23, 2024
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
10 changes: 9 additions & 1 deletion chia/consensus/block_body_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ def include_spends(self, npc_result: Optional[NPCResult], block: FullBlock, head
assert coin.name() not in self.additions_since_fork
self.additions_since_fork[coin.name()] = ForkAdd(coin, uint32(block.height), uint64(timestamp), None, True)

def rollback(self, header_hash: bytes32, height: int) -> None:
assert height <= self.peak_height
self.peak_height = height
self.peak_hash = header_hash
self.additions_since_fork = {k: v for k, v in self.additions_since_fork.items() if v.confirmed_height <= height}
self.removals_since_fork = {k: v for k, v in self.removals_since_fork.items() if v.height <= height}


async def validate_block_body(
constants: ConsensusConstants,
Expand Down Expand Up @@ -401,6 +408,7 @@ async def validate_block_body(
# and coins created after fork (additions_since_fork)
if rem in fork_info.removals_since_fork:
# This coin was spent in the fork
log.error(f"Err.DOUBLE_SPEND_IN_FORK {fork_info.removals_since_fork[rem]}")
return Err.DOUBLE_SPEND_IN_FORK, None
removals_from_db.append(rem)

Expand Down Expand Up @@ -433,7 +441,7 @@ async def validate_block_body(
# This coin is not in the current heaviest chain, so it must be in the fork
if rem not in fork_info.additions_since_fork:
# Check for spending a coin that does not exist in this fork
log.error(f"Err.UNKNOWN_UNSPENT: COIN ID: {rem} NPC RESULT: {npc_result}")
log.error(f"Err.UNKNOWN_UNSPENT: COIN ID: {rem} fork_info: {fork_info}")
return Err.UNKNOWN_UNSPENT, None
addition: ForkAdd = fork_info.additions_since_fork[rem]
new_coin_record: CoinRecord = CoinRecord(
Expand Down
7 changes: 7 additions & 0 deletions chia/consensus/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,13 @@ async def add_block(
self._peak_height = block_record.height

except BaseException as e:
# depending on exactly when the failure of adding the block
# happened, we may not have added it to the block record cache
try:
self.remove_block_record(header_hash)
except KeyError:
pass
fork_info.rollback(header_hash, -1 if previous_peak_height is None else previous_peak_height)
self.block_store.rollback_cache_block(header_hash)
self._peak_height = previous_peak_height
log.error(
Expand Down
Loading