Do not depend on old accumulator objects #24721
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR gets rid of the dependency to the need to read old accumulator objects. This is necessary since we may not always have access to old accumulator objects due to pruning.
In order to do this, we introduce a new primitive in the writeback cache (
get_latest_account_amount). This function reads the latest balance of the specified accumulator object, together with its current version. The implementation guarantees that the version is accurate. This is easy to do if the object exists, as we can just get its version, but in the case if the object does not exist, in order to get its current version, we must derive it from the root accumulator object. To deal with potential data races where the root is being mutated, we have to make sure that we read the root version before and after the read of the accumulator object, and only return if they are the same. This leads to a loop. In practice, this loop should not run more than a few times as the read of these objects should all be cached and are very fast.With the primitive above, when we initialize an account in the eager scheduler, we know exactly the version of it. This is recorded in the account state. When we settle funds, if the version being settled is prior to the last updated version, we can just ignore the settlement; we only apply the settlement if it's actually newer.
We also skip schedule if the version of the accumulator object is newer than the withdraw.
To make the logic cleaner and more obvious, the account state and pending withdraw impls are refactored out to separate files.
Test plan
Added more unit tests and integration tests.
Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.