Skip to content

Conversation

@abi87
Copy link
Contributor

@abi87 abi87 commented Mar 28, 2023

Why this should be merged

This PR introduces property testing for the P-chain stakers state management, increasing test coverage for state package from 42.2% to 50.3%.

The PR does also introduces minor production code changes:

  1. it removes an accidental difference among state.Diff and state.State around stakers removal, thus marginally reducing complexity. Property tests now ensures that state.Diff and state.State are really interchangeable.
  2. it allows staker addition and immediate removal.

The second invariants is not strictly required since it can't happen in prod (would require a zero-lenght staker which is forbidden). Still it makes testing easier and, more importantly, it goes in the directions of making P-chain stakers state much less reliant on txs validation and more aligned with what one may expect from a DB.

How this works

This PR introduced property testing to avalanchego.
Property testing allow devs to specify only relevent input attributes in a test and let other attributes be randomly generated by the testing framework. This avoids tests overfitting and allows exploration of input domain in different test runs.
Also property testing forces dev to describe more precisely properties that should be asserted on outputs or subjets-under-test, since dev does not fully control input anymore.

How this was tested

New property tests + CI

@patrick-ogrady patrick-ogrady added vm This involves virtual machines testing This primarily focuses on testing labels Mar 29, 2023
@abi87 abi87 self-assigned this Mar 29, 2023
s.addedStakers = btree.NewG(defaultTreeDegree, (*Staker).Less)
}
s.addedStakers.ReplaceOrInsert(staker)
delete(s.deletedStakers, staker.TxID)
Copy link
Contributor Author

@abi87 abi87 Mar 30, 2023

Choose a reason for hiding this comment

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

I would like to assert the property that "it's fine deleting a validator not yet inserted, and then inserting it".
Our dbs have this property, state.State has this property, but state.Diff currently does not.
The change above brings the property to state.Diff.
Note that without the line inserted, a deleted-than-added staker would be marked as deleted, not added, in lower layer diff when diff.Apply is called. This is because diff.Apply implementation loops first among added stakers then among deleted ones.

Note that in our system it does not currently happen that a staker is deleted then inserted (we'll be able to update it in near future, but still no insert-and-delete).
Still having state.State and state.Diff behave uniformly, without accidental differences, even on currently unexposed situation reduces the whole complexity.

validatorDiff.addedDelegators = btree.NewG(defaultTreeDegree, (*Staker).Less)
}
validatorDiff.addedDelegators.ReplaceOrInsert(staker)
delete(validatorDiff.deletedDelegators, staker.TxID)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

see comment for delete-than-insert staker on validator

s.addedStakers = btree.NewG(defaultTreeDegree, (*Staker).Less)
}
s.addedStakers.ReplaceOrInsert(staker)
delete(s.deletedStakers, staker.TxID)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

see comment for delete-than-insert staker on validator

@abi87 abi87 marked this pull request as ready for review March 30, 2023 10:34
@abi87 abi87 requested review from gyuho and joshua-kim as code owners April 7, 2023 13:58
@abi87 abi87 changed the base branch from master to dev April 7, 2023 13:59
@abi87 abi87 requested a review from coffeeavax as a code owner April 13, 2023 14:22
@github-actions
Copy link

This PR has become stale because it has been open for 30 days with no activity. Adding the lifecycle/frozen label will cause this PR to ignore lifecycle events.

@github-actions github-actions bot added the lifecycle/stale Inactive for 60 days label Mar 31, 2024
powerslider added a commit that referenced this pull request Dec 2, 2025
… engine-driven target updates

- Add Coordinator to orchestrate dynamic state sync, enforce pivot cadence, and manage queue execution.
- Introduce engine hook OnEngineAccept to enqueue accepted blocks and advance the sync target.
- Implement pivot policy (every N blocks) and idempotence (skip behind/equal, allow same-height reorgs).

resolves #1259

Signed-off-by: Tsvetan Dimitrov ([email protected])
powerslider added a commit that referenced this pull request Dec 2, 2025
When UpdateSyncTarget is called, remove all queued blocks with height <=
new target height since they will never be executed. This prevents
processing blocks that the sync has already advanced past.

- Add RemoveBlocksBelowHeight method to blockQueue to filter stale blocks.
- Call RemoveBlocksBelowHeight in UpdateSyncTarget after pivot check.
- Support accept/reject/verify operations in block queue.
- Add OnEngineReject and OnEngineVerify handlers to sync client.
- Propagate context through ApplyQueuedBatch for proper cancellation.
- Remove unnecessary defer vm.versiondb.Abort() from Accept.
- Prevent recursion during batch execution via state check.
- Make dequeueBatch private to reduce API surface.

resolves #1259
Signed-off-by: Tsvetan Dimitrov ([email protected])
powerslider added a commit that referenced this pull request Dec 2, 2025
- Add context parameter to finishSync() and propagate through stateSyncStatic/Dynamic
- Add context parameter to FinalizeVM callback in Coordinator
- Add context parameter to ProcessQueuedBlockOperations (renamed from ApplyQueuedBatch)
- Add context parameter to executeBlockOperationBatch (moved from blockQueue)
- Propagate context through ProcessQueue operations
- Add cancellation checks before expensive operations in finishSync() using declarative
  operation list pattern with runWithCancellationCheck helper.
- Add cancellation checks in ProcessQueuedBlockOperations before state transitions.
- Add cancellation checks in executeBlockOperationBatch loop using select pattern.
- Improve error messages to include operation index and type for better debugging.

Refactoring:
- Move block operation processing logic from blockQueue to Coordinator
  (executeBlockOperationBatch) for better separation of concerns.
- Simplify blockQueue to be a pure data structure (enqueue, dequeueBatch, removeBelowHeight).
- Rename pivot.go to pivot_policy.go for clarity.
- Remove cancel function from Coordinator struct, pass as parameter to finish().

Pivot Policy:
- Add defaultPivotInterval constant (10000 blocks) in pivot_policy.go.
- Apply default pivot interval when WithPivotInterval is not explicitly called.
- Update newPivotPolicy to use default when interval is 0.

This change enables graceful shutdown of state sync operations and ensures
that cancellation signals propagate correctly through all layers of the
dynamic state sync orchestration.

resolves #1259

Signed-off-by: Tsvetan Dimitrov ([email protected])
maru-ava pushed a commit that referenced this pull request Dec 3, 2025
maru-ava pushed a commit that referenced this pull request Dec 3, 2025
Enabled all proof tests, which discovered an introduced bug when
MaybePersisted was introduced. The node being returned was the wrong
one, which caused some proof errors when constructing proofs, notably
the wrong node was being returned if the node wasn't yet persisted.

Since the tests run with unpersisted but hashed nodes, this caused some
failures when the tests were re-enabled.

Some tests still do not work with ethhash enabled. Created #1261 for tracking.

Also restructured the tests. Proof tests are separated now from range
proof tests.

Range proof tests were moved but not enabled in this PR (will be done
next).
powerslider added a commit that referenced this pull request Dec 3, 2025
… engine-driven target updates

- Add Coordinator to orchestrate dynamic state sync, enforce pivot cadence, and manage queue execution.
- Introduce engine hook OnEngineAccept to enqueue accepted blocks and advance the sync target.
- Implement pivot policy (every N blocks) and idempotence (skip behind/equal, allow same-height reorgs).

resolves #1259

Signed-off-by: Tsvetan Dimitrov ([email protected])
powerslider added a commit that referenced this pull request Dec 3, 2025
When UpdateSyncTarget is called, remove all queued blocks with height <=
new target height since they will never be executed. This prevents
processing blocks that the sync has already advanced past.

- Add RemoveBlocksBelowHeight method to blockQueue to filter stale blocks.
- Call RemoveBlocksBelowHeight in UpdateSyncTarget after pivot check.
- Support accept/reject/verify operations in block queue.
- Add OnEngineReject and OnEngineVerify handlers to sync client.
- Propagate context through ApplyQueuedBatch for proper cancellation.
- Remove unnecessary defer vm.versiondb.Abort() from Accept.
- Prevent recursion during batch execution via state check.
- Make dequeueBatch private to reduce API surface.

resolves #1259
Signed-off-by: Tsvetan Dimitrov ([email protected])
powerslider added a commit that referenced this pull request Dec 3, 2025
- Add context parameter to finishSync() and propagate through stateSyncStatic/Dynamic
- Add context parameter to FinalizeVM callback in Coordinator
- Add context parameter to ProcessQueuedBlockOperations (renamed from ApplyQueuedBatch)
- Add context parameter to executeBlockOperationBatch (moved from blockQueue)
- Propagate context through ProcessQueue operations
- Add cancellation checks before expensive operations in finishSync() using declarative
  operation list pattern with runWithCancellationCheck helper.
- Add cancellation checks in ProcessQueuedBlockOperations before state transitions.
- Add cancellation checks in executeBlockOperationBatch loop using select pattern.
- Improve error messages to include operation index and type for better debugging.

Refactoring:
- Move block operation processing logic from blockQueue to Coordinator
  (executeBlockOperationBatch) for better separation of concerns.
- Simplify blockQueue to be a pure data structure (enqueue, dequeueBatch, removeBelowHeight).
- Rename pivot.go to pivot_policy.go for clarity.
- Remove cancel function from Coordinator struct, pass as parameter to finish().

Pivot Policy:
- Add defaultPivotInterval constant (10000 blocks) in pivot_policy.go.
- Apply default pivot interval when WithPivotInterval is not explicitly called.
- Update newPivotPolicy to use default when interval is 0.

This change enables graceful shutdown of state sync operations and ensures
that cancellation signals propagate correctly through all layers of the
dynamic state sync orchestration.

resolves #1259

Signed-off-by: Tsvetan Dimitrov ([email protected])
@JonathanOppenheimer JonathanOppenheimer added acp236 Continuous Staking and removed continuous staking labels Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acp236 Continuous Staking lifecycle/stale Inactive for 60 days testing This primarily focuses on testing vm This involves virtual machines

Projects

Archived in project
Status: In Review 👀

Development

Successfully merging this pull request may close these issues.

Continuous Staking

8 participants