Skip to content

Commit 952e147

Browse files
committed
minimize diffs
1 parent aa51352 commit 952e147

File tree

1 file changed

+121
-101
lines changed

1 file changed

+121
-101
lines changed

chia/consensus/blockchain.py

Lines changed: 121 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from chia.consensus.block_body_validation import ForkInfo, validate_block_body
2828
from chia.consensus.block_header_validation import validate_unfinished_header_block
29-
from chia.consensus.consensus_store_protocol import ConsensusStoreProtocol
29+
from chia.consensus.consensus_store_protocol import ConsensusStoreProtocol, ConsensusStoreWriteProtocol
3030
from chia.consensus.cost_calculator import NPCResult
3131
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
3232
from chia.consensus.find_fork_point import lookup_fork_chain
@@ -510,117 +510,135 @@ async def _reconsider_peak(
510510
and the new chain, or returns None if there was no update to the heaviest chain.
511511
"""
512512

513+
if genesis and self.get_peak() is not None:
514+
return [], None
515+
516+
async with self.consensus_store.writer() as writer:
517+
records_to_add, state_summary = await self._perform_db_operations_for_peak(
518+
writer, block_record, genesis, fork_info
519+
)
520+
521+
# Changes the peak to be the new peak
522+
await writer.set_peak(block_record.header_hash)
523+
524+
return records_to_add, state_summary
525+
526+
async def _perform_db_operations_for_peak(
527+
self,
528+
writer: ConsensusStoreWriteProtocol,
529+
block_record: BlockRecord,
530+
genesis: bool,
531+
fork_info: ForkInfo,
532+
) -> tuple[list[BlockRecord], Optional[StateChangeSummary]]:
533+
"""
534+
Perform database operations to consider a new peak.
535+
Creates and returns the records to add and the complete StateChangeSummary.
536+
"""
513537
peak = self.get_peak()
514538
rolled_back_state: dict[bytes32, CoinRecord] = {}
515539

516-
if genesis and peak is not None:
517-
return [], None
540+
if peak is not None:
541+
if block_record.weight < peak.weight:
542+
# This is not a heavier block than the heaviest we have seen, so we don't change the coin set
543+
return [], None
544+
if block_record.weight == peak.weight and peak.total_iters <= block_record.total_iters:
545+
# this is an equal weight block but our peak has lower iterations, so we dont change the coin set
546+
return [], None
547+
if block_record.weight == peak.weight:
548+
log.info(
549+
f"block has equal weight as our peak ({peak.weight}), but fewer "
550+
f"total iterations {block_record.total_iters} "
551+
f"peak: {peak.total_iters} "
552+
f"peak-hash: {peak.header_hash}"
553+
)
518554

519-
async with self.consensus_store.writer() as writer:
520-
if peak is not None:
521-
if block_record.weight < peak.weight:
522-
# This is not a heavier block than the heaviest we have seen, so we don't change the coin set
523-
return [], None
524-
if block_record.weight == peak.weight and peak.total_iters <= block_record.total_iters:
525-
# this is an equal weight block but our peak has lower iterations, so we dont change the coin set
526-
return [], None
527-
if block_record.weight == peak.weight:
555+
if block_record.prev_hash != peak.header_hash:
556+
rolled_back_state = await writer.rollback_to_block(fork_info.fork_height)
557+
if self._log_coins and len(rolled_back_state) > 0:
558+
log.info(f"rolled back {len(rolled_back_state)} coins, to fork height {fork_info.fork_height}")
528559
log.info(
529-
f"block has equal weight as our peak ({peak.weight}), but fewer "
530-
f"total iterations {block_record.total_iters} "
531-
f"peak: {peak.total_iters} "
532-
f"peak-hash: {peak.header_hash}"
560+
"removed: %s",
561+
",".join(
562+
[
563+
name.hex()[0:6]
564+
for name, state in rolled_back_state.items()
565+
if state.confirmed_block_index == 0
566+
]
567+
),
533568
)
534-
535-
if block_record.prev_hash != peak.header_hash:
536-
rolled_back_state = await writer.rollback_to_block(fork_info.fork_height)
537-
if self._log_coins and len(rolled_back_state) > 0:
538-
log.info(f"rolled back {len(rolled_back_state)} coins, to fork height {fork_info.fork_height}")
539-
log.info(
540-
"removed: %s",
541-
",".join(
542-
[
543-
name.hex()[0:6]
544-
for name, state in rolled_back_state.items()
545-
if state.confirmed_block_index == 0
546-
]
547-
),
548-
)
549-
log.info(
550-
"unspent: %s",
551-
",".join(
552-
[
553-
name.hex()[0:6]
554-
for name, state in rolled_back_state.items()
555-
if state.confirmed_block_index != 0
556-
]
557-
),
558-
)
559-
560-
# Collects all blocks from fork point to new peak
561-
records_to_add: list[BlockRecord] = []
562-
563-
if genesis:
564-
records_to_add = [block_record]
565-
elif fork_info.block_hashes == [block_record.header_hash]:
566-
# in the common case, we just add a block on top of the chain. Check
567-
# for that here to avoid an unnecessary database lookup.
568-
records_to_add = [block_record]
569-
else:
570-
records_to_add = await self.consensus_store.get_block_records_by_hash(fork_info.block_hashes)
571-
572-
for fetched_block_record in records_to_add:
573-
if not fetched_block_record.is_transaction_block:
574-
# Coins are only created in TX blocks so there are no state updates for this block
575-
continue
576-
577-
height = fetched_block_record.height
578-
# We need to recompute the additions and removals, since they are
579-
# not stored on DB. We have all the additions and removals in the
580-
# fork_info object, we just need to pick the ones belonging to each
581-
# individual block height
582-
583-
# Apply the coin store changes for each block that is now in the blockchain
584-
included_reward_coins = [
585-
fork_add.coin
586-
for fork_add in fork_info.additions_since_fork.values()
587-
if fork_add.confirmed_height == height and fork_add.is_coinbase
588-
]
589-
tx_additions = [
590-
(coin_id, fork_add.coin, fork_add.same_as_parent)
591-
for coin_id, fork_add in fork_info.additions_since_fork.items()
592-
if fork_add.confirmed_height == height and not fork_add.is_coinbase
593-
]
594-
tx_removals = [
595-
coin_id for coin_id, fork_rem in fork_info.removals_since_fork.items() if fork_rem.height == height
596-
]
597-
assert fetched_block_record.timestamp is not None
598-
await writer.new_block(
599-
height,
600-
fetched_block_record.timestamp,
601-
included_reward_coins,
602-
tx_additions,
603-
tx_removals,
604-
)
605-
if self._log_coins and (len(tx_removals) > 0 or len(tx_additions) > 0):
606569
log.info(
607-
f"adding new block to coin_store "
608-
f"(hh: {fetched_block_record.header_hash} "
609-
f"height: {fetched_block_record.height}), {len(tx_removals)} spends"
570+
"unspent: %s",
571+
",".join(
572+
[
573+
name.hex()[0:6]
574+
for name, state in rolled_back_state.items()
575+
if state.confirmed_block_index != 0
576+
]
577+
),
610578
)
611-
log.info("rewards: %s", ",".join([add.name().hex()[0:6] for add in included_reward_coins]))
612-
log.info("additions: %s", ",".join([add[0].hex()[0:6] for add in tx_additions]))
613-
log.info("removals: %s", ",".join([f"{rem}"[0:6] for rem in tx_removals]))
614579

615-
# we made it to the end successfully
616-
# Rollback sub_epoch_summaries
617-
await writer.rollback(fork_info.fork_height)
618-
await writer.set_in_chain([(br.header_hash,) for br in records_to_add])
580+
# Collects all blocks from fork point to new peak
581+
records_to_add: list[BlockRecord] = []
619582

620-
# Changes the peak to be the new peak
621-
await writer.set_peak(block_record.header_hash)
583+
if genesis:
584+
records_to_add = [block_record]
585+
elif fork_info.block_hashes == [block_record.header_hash]:
586+
# in the common case, we just add a block on top of the chain. Check
587+
# for that here to avoid an unnecessary database lookup.
588+
records_to_add = [block_record]
589+
else:
590+
records_to_add = await self.consensus_store.get_block_records_by_hash(fork_info.block_hashes)
591+
592+
for fetched_block_record in records_to_add:
593+
if not fetched_block_record.is_transaction_block:
594+
# Coins are only created in TX blocks so there are no state updates for this block
595+
continue
596+
597+
height = fetched_block_record.height
598+
# We need to recompute the additions and removals, since they are
599+
# not stored on DB. We have all the additions and removals in the
600+
# fork_info object, we just need to pick the ones belonging to each
601+
# individual block height
602+
603+
# Apply the coin store changes for each block that is now in the blockchain
604+
included_reward_coins = [
605+
fork_add.coin
606+
for fork_add in fork_info.additions_since_fork.values()
607+
if fork_add.confirmed_height == height and fork_add.is_coinbase
608+
]
609+
tx_additions = [
610+
(coin_id, fork_add.coin, fork_add.same_as_parent)
611+
for coin_id, fork_add in fork_info.additions_since_fork.items()
612+
if fork_add.confirmed_height == height and not fork_add.is_coinbase
613+
]
614+
tx_removals = [
615+
coin_id for coin_id, fork_rem in fork_info.removals_since_fork.items() if fork_rem.height == height
616+
]
617+
assert fetched_block_record.timestamp is not None
618+
await writer.new_block(
619+
height,
620+
fetched_block_record.timestamp,
621+
included_reward_coins,
622+
tx_additions,
623+
tx_removals,
624+
)
625+
if self._log_coins and (len(tx_removals) > 0 or len(tx_additions) > 0):
626+
log.info(
627+
f"adding new block to coin_store "
628+
f"(hh: {fetched_block_record.header_hash} "
629+
f"height: {fetched_block_record.height}), {len(tx_removals)} spends"
630+
)
631+
log.info("rewards: %s", ",".join([add.name().hex()[0:6] for add in included_reward_coins]))
632+
log.info("additions: %s", ",".join([add[0].hex()[0:6] for add in tx_additions]))
633+
log.info("removals: %s", ",".join([f"{rem}"[0:6] for rem in tx_removals]))
634+
635+
# we made it to the end successfully
636+
# Rollback sub_epoch_summaries
637+
await writer.rollback(fork_info.fork_height)
638+
await writer.set_in_chain([(br.header_hash,) for br in records_to_add])
622639

623-
return records_to_add, StateChangeSummary(
640+
# Create and return the complete StateChangeSummary
641+
state_summary = StateChangeSummary(
624642
block_record,
625643
uint32(max(fork_info.fork_height, 0)),
626644
list(rolled_back_state.values()),
@@ -633,6 +651,8 @@ async def _reconsider_peak(
633651
[fork_add.coin for fork_add in fork_info.additions_since_fork.values() if fork_add.is_coinbase],
634652
)
635653

654+
return records_to_add, state_summary
655+
636656
def get_next_sub_slot_iters_and_difficulty(self, header_hash: bytes32, new_slot: bool) -> tuple[uint64, uint64]:
637657
curr = self.try_block_record(header_hash)
638658
assert curr is not None

0 commit comments

Comments
 (0)