-
Notifications
You must be signed in to change notification settings - Fork 14
test: Add invariant tests for SumTree structure in PDPVerifier #166
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
base: main
Are you sure you want to change the base?
test: Add invariant tests for SumTree structure in PDPVerifier #166
Conversation
test/PDPVerifier.t.sol
Outdated
| } | ||
| } | ||
|
|
||
| function testSumTreeInvariantAfterAddsAndRemovals() public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge with latest master
run forge fmt
|
@Hany-Almnaem please see the above comment - this needs a merge from master (or rebase) plus a |
- Resolve conflict in test/PDPVerifier.t.sol - Fix failing SumTreeEnhancedTest tests - Apply forge fmt formatting
|
@rvagg |
|
Thanks @Hany-Almnaem . I'm going to have to personally put off reviewing this for now because it's a large-enough context switch for me to do it and I have a lot on my plate currently. Maybe @ZenGround0 gets inspired to come have a look, his head is more full of the details here than mine. |
ZenGround0
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the core of this PR is good once we stop swallowing underflow errors. It just needs to be cleaned up and simplified significantly.
| ); | ||
| } | ||
|
|
||
| function assertSumTreeInvariant(uint256 setId) internal view { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not duplicate this entire function from here. Please refactor this somehow, probably with a shared inherited contract, and remove duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking at this further I suggest removing SumTreeEnhancedTest and most of its tests entirely for a smaller test set directly in SumTreeAddTest
| /// @title SumTreeEnhancedTest | ||
| /// @notice Advanced tests for SumTree data structure focusing on stress testing, performance, and edge cases | ||
| /// @dev Tagged with [ADVANCED] to distinguish from basic tests | ||
| contract SumTreeEnhancedTest is MockFVMTest, PieceHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use a separate contract here with a duplicated setup? Why not add these tests to SumTreeAddTest contract? That would solve the duplicated assertSumTreeInvariant problem too.
| uint256 height = pdpVerifier.getTestHeightFromIndex(index); | ||
| uint256 range = 1 << height; | ||
|
|
||
| if (index + 1 < range) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely not be swallowing these errors! If something is this wrong with either the sumtree or the test then we need to fail and fix what is broken.
| } | ||
|
|
||
| uint256 expectedSum = 0; | ||
| for (uint256 j = index + 1 - range; j <= index; j++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks correct ✅
| assertSumTreeInvariant(testSetId); | ||
| } | ||
|
|
||
| function testAdvancedSumTreeInvariant() public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: testSumTreeInvariantAddsAndRemovals2
| uint256 numRounds = 5; | ||
| uint256 piecesPerRound = 8; | ||
|
|
||
| for (uint256 round = 0; round < numRounds; round++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is so similar to this test I would suggest just replacing the single round version there with this multi round version. I don't see a lot of value in having both tests.
| } | ||
|
|
||
| /// @notice [ADVANCED] Tests SumTree behavior with edge case sizes and patterns | ||
| function testSumTreeEdgeCases() public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this is "edge cases". Again this seems like something we could remove without losing any conceptual coverage at all.
| } | ||
| } | ||
|
|
||
| function testSumTreeWithValues(uint256[3] memory values) internal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and createFreshDataSet are not used consistently throughout testing. I suggest sticking to one way of setting things up, either directly as you do here or refactoring things to make use of helper functions like this and createFreshDataSet. Probably it will be clearer if you forego these helper functions but I leave that up to you.
| } | ||
|
|
||
| /// @notice [ADVANCED] Tests SumTree performance with large numbers of operations | ||
| function testSumTreePerformance() public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a large number of operations. Also unfortunately gas measured via solidity tests is ~ meaningless in the filecoin context as our gas model is quite different. Please delete this.
| } | ||
|
|
||
| /// @notice [ADVANCED] Tests SumTree with alternating add/remove pattern | ||
| function testSumTreeAlternatingPattern() public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is different enough that it can stay.
|
@Hany-Almnaem : thank you for your work here, and apologies for the delay for having maintainers to engage. Do you think you'll be able to incorporate comments so we can get this merged soon while the context is fresh? |
Summary
This PR introduces a suite of tests to validate the correctness and stability of the
sumTreeCountsstructure in thePDPVerifiersmart contract.The tests ensure that each node in the SumTree maintains the invariant:
sumTreeCounts[setId][index] == sum of rootLeafCounts[setId][j]for the correct range derived from the node’s height.This directly addresses and resolves issue: #45
Summary of Changes
Core Tests (Basic Coverage)
testSumTreeInvariantAfterAddsAndRemovals()assertSumTreeInvariant(uint256 setId)testAdvancedSumTreeInvariant()testFuzzedSumTreeInvariant(uint256 seed)Advanced Suite (Tagged
[ADVANCED])Implemented in a separate
SumTreeEnhancedTestcontract:testSumTreeStressTest()testSumTreeEdgeCases()testSumTreePerformance()testSumTreeRandomized(uint256 seed)assertSumTreeInvariant()with more detailed error messaging for diagnostics.Benefits
Notes
forge testPlease let me know if you prefer these broken into separate PRs or test files.