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

refactor new_peak_timelord #16881

Merged
merged 31 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
15987ca
refactor new_peak_timelord
almogdepaz Nov 20, 2023
019f7e4
fix test
almogdepaz Nov 20, 2023
f3f929e
improve test assertions
almogdepaz Nov 22, 2023
41dd423
lint
almogdepaz Nov 22, 2023
fe1a065
return after skipping peak
almogdepaz Nov 30, 2023
9a18571
improve comments
almogdepaz Dec 4, 2023
e157e21
limit condition to a diff of one block
almogdepaz Dec 4, 2023
90cd222
remove log
almogdepaz Dec 4, 2023
9a18f0c
refactor test
almogdepaz Dec 4, 2023
9b377c0
better conditions
almogdepaz Dec 6, 2023
91654e7
Merge branch 'main' into refactor_new_peak_timelord
almogdepaz Dec 6, 2023
e90249d
pre commit
almogdepaz Dec 6, 2023
195710d
test with overflow
almogdepaz Dec 11, 2023
200805a
add test for EOS case
almogdepaz Feb 8, 2024
2400f4f
Merge branch 'main' into refactor_new_peak_timelord
almogdepaz Feb 8, 2024
5aacf1b
lint
almogdepaz Feb 8, 2024
20bc277
comment
almogdepaz Feb 8, 2024
eb565b2
prefer lower iterations peaks
almogdepaz Feb 14, 2024
16adbc7
test full node receiving same weight lower iterations
almogdepaz Feb 20, 2024
91d46dc
lint
almogdepaz Feb 20, 2024
c4e973c
fix reorg test, lint
almogdepaz Feb 26, 2024
ee5098c
fix block tools bug
almogdepaz Feb 26, 2024
3233b3d
use signage point param in test
almogdepaz Feb 26, 2024
155d6fb
use signage point param for overflows as well
almogdepaz Mar 4, 2024
fb23f5f
remove unused case
almogdepaz Mar 11, 2024
7d15254
fix block_tools condition
almogdepaz Mar 13, 2024
f8c52f1
Merge branch 'main' into refactor_new_peak_timelord
almogdepaz Mar 25, 2024
cf246f1
lint
almogdepaz Mar 25, 2024
c605b94
lint
almogdepaz Mar 25, 2024
9173620
Merge remote-tracking branch 'origin/main' into refactor_new_peak_tim…
emlowe Jul 24, 2024
6ac100b
Add check for peak not none in test
emlowe Jul 24, 2024
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: 4 additions & 1 deletion chia/consensus/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,12 @@ async def _reconsider_peak(
return [], None

if peak is not None:
if block_record.weight <= peak.weight:
if block_record.weight < peak.weight:
# This is not a heavier block than the heaviest we have seen, so we don't change the coin set
return [], None
if block_record.weight == peak.weight and peak.total_iters <= block_record.total_iters:
# this is an equal weight block but our peak has lower iterations, so we dont change the coin set
return [], None

if block_record.prev_hash != peak.header_hash:
for coin_record in await self.coin_store.rollback_to_block(fork_info.fork_height):
Expand Down
14 changes: 13 additions & 1 deletion chia/simulator/block_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,8 @@ def get_consecutive_blocks(
force_plot_id: Optional[bytes32] = None,
dummy_block_references: bool = False,
include_transactions: bool = False,
skip_overflow: bool = False,
min_signage_point: int = -1,
) -> List[FullBlock]:
assert num_blocks > 0
if block_list_input is not None:
Expand Down Expand Up @@ -732,6 +734,10 @@ def get_consecutive_blocks(
# Ignore this signage_point because it's in the past
continue

if signage_point_index <= min_signage_point:
# start farming blocks after min_signage_point
continue

signage_point: SignagePoint = get_signage_point(
constants,
BlockCache(blocks),
Expand Down Expand Up @@ -1073,7 +1079,13 @@ def get_consecutive_blocks(
blocks_added_this_sub_slot = 0 # Sub slot ended, overflows are in next sub slot

# Handle overflows: No overflows on new epoch or sub-epoch
if new_sub_slot_iters is None and num_empty_slots_added >= skip_slots and not pending_ses:

if (
new_sub_slot_iters is None
and num_empty_slots_added >= skip_slots
and not pending_ses
and not skip_overflow
):
for signage_point_index in range(
fchirica marked this conversation as resolved.
Show resolved Hide resolved
constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA,
constants.NUM_SPS_SUB_SLOT,
Expand Down
66 changes: 40 additions & 26 deletions chia/timelord/timelord_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
from typing import Optional

from chia.protocols import timelord_protocol
from chia.protocols.timelord_protocol import NewPeakTimelord
from chia.rpc.rpc_server import StateChangedProtocol
from chia.timelord.iters_from_block import iters_from_block
from chia.timelord.timelord import Timelord
from chia.timelord.types import Chain, IterationType, StateType
from chia.timelord.types import Chain, IterationType
from chia.util.api_decorators import api_request
from chia.util.ints import uint64

Expand Down Expand Up @@ -38,40 +39,53 @@ async def new_peak_timelord(self, new_peak: timelord_protocol.NewPeakTimelord) -
return None
self.timelord.max_allowed_inactivity_time = 60

# if there is a heavier unfinished block from a diff chain, skip
if self.timelord.last_state.state_type == StateType.PEAK:
for unf_block in self.timelord.unfinished_blocks:
if unf_block.reward_chain_block.total_iters > new_peak.reward_chain_block.total_iters:
found = False
for rc, total_iters in new_peak.previous_reward_challenges:
if rc == unf_block.rc_prev:
found = True
break

if not found:
log.info(
"there is a heavier unfinished block that does not belong to this chain- skip peak"
)
return None

if new_peak.reward_chain_block.weight > self.timelord.last_state.get_weight():
if self.timelord.last_state.peak is None:
# no known peak
log.info("no last known peak, switching to new peak")
self.timelord.new_peak = new_peak
self.timelord.state_changed("new_peak", {"height": new_peak.reward_chain_block.height})
return

if self.timelord.last_state.get_weight() < new_peak.reward_chain_block.weight:
# if there is an unfinished block with less iterations, skip so we dont orphan it
if (
new_peak.reward_chain_block.height == self.timelord.last_state.last_height + 1
and self.check_orphaned_unfinished_block(new_peak) is True
):
log.info("there is an unfinished block that this peak would orphan - " "skip peak")
self.timelord.state_changed("skipping_peak", {"height": new_peak.reward_chain_block.height})
return

log.info("Not skipping peak, don't have. Maybe we are not the fastest timelord")
log.info(
f"New peak: height: {new_peak.reward_chain_block.height} weight: "
f"{new_peak.reward_chain_block.weight} "
)
self.timelord.new_peak = new_peak
self.timelord.state_changed("new_peak", {"height": new_peak.reward_chain_block.height})
elif (
self.timelord.last_state.peak is not None
and self.timelord.last_state.peak.reward_chain_block == new_peak.reward_chain_block
):
return

if self.timelord.last_state.peak.reward_chain_block.get_hash() == new_peak.reward_chain_block.get_hash():
log.info("Skipping peak, already have.")
self.timelord.state_changed("skipping_peak", {"height": new_peak.reward_chain_block.height})
else:
log.warning("block that we don't have, changing to it.")
self.timelord.new_peak = new_peak
self.timelord.state_changed("new_peak", {"height": new_peak.reward_chain_block.height})
log.info("Skipping peak, block has equal or lower weight then our peak.")
log.debug(
f"new peak height {new_peak.reward_chain_block.height} "
f"weight {new_peak.reward_chain_block.weight}"
)

self.timelord.state_changed("skipping_peak", {"height": new_peak.reward_chain_block.height})

def check_orphaned_unfinished_block(self, new_peak: NewPeakTimelord):
for unf_block in self.timelord.unfinished_blocks:
if unf_block.reward_chain_block.total_iters <= new_peak.reward_chain_block.total_iters:
# there is an unfinished block that would be orphaned by this peak
return True
for unf_block in self.timelord.overflow_blocks:
if unf_block.reward_chain_block.total_iters <= new_peak.reward_chain_block.total_iters:
# there is an unfinished block (overflow) that would be orphaned by this peak
return True
return False

@api_request()
async def new_unfinished_block_timelord(self, new_unfinished_block: timelord_protocol.NewUnfinishedBlockTimelord):
Expand Down
9 changes: 8 additions & 1 deletion tests/blockchain/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -3509,8 +3509,15 @@ async def test_reorg_new_ref(empty_blockchain, bt):
fork_info: Optional[ForkInfo] = None
if i < 10:
expected = AddBlockResult.ALREADY_HAVE_BLOCK
elif i < 20:
elif i < 19:
expected = AddBlockResult.ADDED_AS_ORPHAN
elif i == 19:
# same height as peak decide by iterations
peak = b.get_peak()
if block.total_iters < peak.total_iters:
expected = AddBlockResult.NEW_PEAK
else:
expected = AddBlockResult.ADDED_AS_ORPHAN
fchirica marked this conversation as resolved.
Show resolved Hide resolved
else:
expected = AddBlockResult.NEW_PEAK
if fork_info is None:
Expand Down
Loading
Loading