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 get block generator #16335

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft

Conversation

almogdepaz
Copy link
Contributor

Purpose:

Current Behavior:

New Behavior:

Testing Notes:

@almogdepaz almogdepaz added full_node tech-debt Fixed Required label for PR that categorizes merge commit message as "Fixed" for changelog labels Sep 14, 2023
chia/consensus/blockchain.py Show resolved Hide resolved
chia/consensus/blockchain.py Outdated Show resolved Hide resolved
tests/blockchain/blockchain_test_utils.py Outdated Show resolved Hide resolved
pass fork_point_with_peak
pr fixes
Comment on lines -921 to -935
if self.contains_block(curr.prev_header_hash) and peak is not None:
# Then we look up blocks up to fork point one at a time, backtracking
previous_block_hash = curr.prev_header_hash
prev_block_record = await self.block_store.get_block_record(previous_block_hash)
prev_block = await self.block_store.get_full_block(previous_block_hash)
assert prev_block is not None
assert prev_block_record is not None
fork = find_fork_point_in_chain(self, peak, prev_block_record)
curr_2: Optional[FullBlock] = prev_block
assert curr_2 is not None and isinstance(curr_2, FullBlock)
reorg_chain[curr_2.height] = curr_2
while curr_2.height > fork and curr_2.height > 0:
curr_2 = await self.block_store.get_full_block(curr_2.prev_header_hash)
assert curr_2 is not None
reorg_chain[curr_2.height] = curr_2
Copy link
Contributor

Choose a reason for hiding this comment

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

we still need, at least, the height-to-hash mapping that reorg_chain provides. I don't think you can remove this whole seciont

Copy link
Contributor Author

@almogdepaz almogdepaz Oct 2, 2023

Choose a reason for hiding this comment

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

ok think i get what wrong here.

we traverse all the heights in the end anyway and fetch the missing blocks from db but we do that by height so might get the wrong one, so i just need the mapping to get the hashes this code still redundant, we dont need all the full blocks up to the fork we only need the referenced ones

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think what confused me is the if statement, we assume curr would be in the current chain ?
after that i get that we would get the blocks from the reorg_chain but why would we even get into the if, we dont expect block_records to contain blocks from the reorg

Copy link
Contributor

@arvidn arvidn Oct 5, 2023

Choose a reason for hiding this comment

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

by block_records, you mean the Blockchain object, right? The self. It has access to all blocks, including orphaned blocks and other forks. If we're in a reorg, those blocks are in the Blockchain object as well.

I think the intention of that if-statement, if self.contains_block(curr.prev_header_hash) was to ask if we know of that block, not if we happen to have it in the cache right now. If we assume the intention was the latter, there's another block of code missing here to do the same thing but pull the block hashes from the database.

the additional_blocks is just the current batch of block's we're validating. It does not contain the whole fork. The fork is still only stored in the database at this point, that's where we need to get the generators from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

then i dont get the point of this check, im pretty sure the initial intention was to see if its in the chain

otherwise we are just checking the store to contain something that we expect to be there, in that case i would have expected an assert or some exception being thrown, what is the case then when the block not in blockchain.blockrecords ?

@github-actions github-actions bot added the merge_conflict Branch has conflicts that prevent merge to main label Oct 2, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Oct 2, 2023

This pull request has conflicts, please resolve those before we can evaluate the pull request.

# Conflicts:
#	tests/core/full_node/stores/test_full_node_store.py
fix assertion in block body validation
@github-actions github-actions bot removed merge_conflict Branch has conflicts that prevent merge to main labels Oct 3, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2023

Conflicts have been resolved. A maintainer will review the pull request shortly.

1 similar comment
@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2023

Conflicts have been resolved. A maintainer will review the pull request shortly.

Copy link
Contributor

@arvidn arvidn left a comment

Choose a reason for hiding this comment

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

we use two different representations for fork-height in the code base. one is Optional[uint32], where None either means the chains don't share any blocks, or it means we don't know what the fork height is. The other is int, where -1 means the chains don't share any blocks.

In the case of Optional, I think there's a risk of confusion what None really means. The case of int makes arithmetic simpler, because -1 naturally fits in to comparing heights.

I think it would be good to get some clarity on exactly what semantics the code ascribes to the different values of fork height, and maybe try to unify them.

@@ -42,7 +42,7 @@ async def validate_block_body(
height: uint32,
npc_result: Optional[NPCResult],
fork_point_with_peak: int,
get_block_generator: Callable[[BlockInfo, uint32], Awaitable[Optional[BlockGenerator]]],
get_block_generator: Callable[[BlockInfo, int, Dict[uint32, FullBlock]], Awaitable[Optional[BlockGenerator]]],
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should bundle the fork_height and this height->block map into a class. We'll need to extend this with passing in the unspent coin set of the fork as well.

Also, I would worry about storing all the FullNode objects in memory. We're not likely to actually need all of that, and it can take up a lot of space

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what do you mean by "FullNode" objects?

@github-actions github-actions bot added the merge_conflict Branch has conflicts that prevent merge to main label Oct 26, 2023
@github-actions
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Copy link
Contributor

This PR has been flagged as stale due to no activity for over 60 days. It will not be automatically closed, but it has been given a stale-pr label and should be manually reviewed by the relevant parties.

@github-actions github-actions bot added the stale-pr Flagged as stale and in need of manual review label Dec 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed Required label for PR that categorizes merge commit message as "Fixed" for changelog full_node merge_conflict Branch has conflicts that prevent merge to main stale-pr Flagged as stale and in need of manual review tech-debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants