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

remove acceptor queue (part 1) #1334

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

remove acceptor queue (part 1) #1334

wants to merge 5 commits into from

Conversation

darioush
Copy link
Collaborator

@darioush darioush commented Sep 4, 2024

Why this should be merged

Reduces differences with upstream and simplifies code.
Note this does not completely remove the acceptorTip, to avoid issues in case of a version bump during an unclean shutdown. (We can discuss how to handle this case more, but this part can already be removed)

How this works

Removes starting the acceptor queue as a goroutine, instead the same work is done inline during the call to Accept, as it was before the acceptor queue was added.

How this was tested

CI

How is this documented

TBD: remove the related config option from docs

@darioush darioush marked this pull request as ready for review September 4, 2024 22:26
@darioush darioush requested review from ceyonur and a team as code owners September 4, 2024 22:26
@@ -1041,10 +914,10 @@ func (bc *BlockChain) LastConsensusAcceptedBlock() *types.Block {
//
// Note: During initialization, [acceptorTip] is equal to [lastAccepted].
func (bc *BlockChain) LastAcceptedBlock() *types.Block {
bc.acceptorTipLock.Lock()
defer bc.acceptorTipLock.Unlock()
bc.chainmu.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we use a RLock here?

@@ -1041,10 +914,10 @@ func (bc *BlockChain) LastConsensusAcceptedBlock() *types.Block {
//
// Note: During initialization, [acceptorTip] is equal to [lastAccepted].
Copy link
Collaborator

Choose a reason for hiding this comment

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

should comment change here?

@@ -1041,10 +914,10 @@ func (bc *BlockChain) LastConsensusAcceptedBlock() *types.Block {
//
// Note: During initialization, [acceptorTip] is equal to [lastAccepted].
func (bc *BlockChain) LastAcceptedBlock() *types.Block {
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we remove "LastConsensusAcceptedBlock"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

also I think we don't need to hold a lock everywhere we call this. seems we can just directly use the variable. should be careful with that though.

  • CleanBlockRootsAbcoveLastAccepted this function can be removed altogether
  • populateMissingTries
  • warmAcceptedCaches

Copy link
Collaborator Author

@darioush darioush Sep 11, 2024

Choose a reason for hiding this comment

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

CleanBlockRootsAboveLastAccepted is still used in offline pruning (to remove roots of non-accepted blocks), but I inlined the use of the variable in the 3 cases you mentioned

Copy link
Collaborator

Choose a reason for hiding this comment

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

CleanBlockRootsAboveLastAccepted is a bit weird since it refetches the last accepted everytime rather than trying to clean the same block root when called, so I feel there can be a race.

Copy link
Collaborator

Choose a reason for hiding this comment

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

PR here #1339

Copy link
Collaborator

Choose a reason for hiding this comment

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

do we still need to store the latest tip with WriteAcceptorTip? I mean stopping updating the stored value (not to completely remove it).

Copy link
Collaborator

@ceyonur ceyonur Sep 11, 2024

Choose a reason for hiding this comment

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

If I'm not mistaken acceptorTip can only be =< to lastAccepted. So if we decide not to update this we might end up always reprocessing the state.

I wonder after removing the acceptor queue we will ever need to reprocess the state. Maybe we can keep the check bc.HasState(current.Root()).

I also don't fully understand how that reprocessState works. If acceptorTip =< lastAccepted then from what I see it would go back from acceptorTip since we do this current = bc.GetBlockByHash(acceptorTip). what happens to the state between acceptorTip and lastAccepted then? I might be completely wrong though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it is correct that acceptorTip <= lastAccepted or that acceptorTip == common.Hash{}
reprocessState is kind of confusing:

  • If acceptorTip < lastAccepted, execution will start at acceptorTip.
  • Next, we find the block with state present on disk so we can start re-executing (this can be less than acceptorTip/lastAccepted since we only persist roots to disk once per commit interval in pruning mode)
  • When the acceptorTip is reached, from that point we will start processing the snapshot along with the state & also write the tx accepted indexes.
  • We continue up to lastAccepted.

We can stop updating it once it matches lastAccepted, but I would prefer to keep that to the next PR so we get it right. Let me know if you prefer to include stop updating it in this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

no I think it's fine if we remove them altogether in a safer way.

return
// Update last processed and transaction lookup index
if err := bc.writeBlockAcceptedIndices(next); err != nil {
log.Crit("failed to write accepted block effects", "err", err)
Copy link
Collaborator

@ceyonur ceyonur Sep 11, 2024

Choose a reason for hiding this comment

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

should we return errs here instead of just log them? I think we should still keep the logs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it is correct to return the error (I will use fmt.Errorf)

Copy link
Collaborator

Choose a reason for hiding this comment

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

log.Crit uses os.Exit so it seems it should be fine, no?

darioush and others added 4 commits September 11, 2024 07:18
* race-safe block root cleaning

* Revert formatting changes

---------

Signed-off-by: Ceyhun Onur <ceyhun.onur@avalabs.org>
@darioush darioush marked this pull request as draft November 4, 2024 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants