-
Notifications
You must be signed in to change notification settings - Fork 969
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
Introduce "order book not crossed" invariant (for fuzzing only) #2959
Conversation
void | ||
OrderBookIsNotCrossed::resetForFuzzer() | ||
{ | ||
mOrderBook = mRolledBackOrderBook; |
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.
resetForFuzzer
is likely very slow as it's copying a large data structure, yet it's unlikely that offers got changed.
I think we should perform the actual copy as late as possible: probably in OrderBookIsNotCrossed::check
(reset is probably still here though)
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.
Good idea, done.
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 see that you reverted your change. From the looks of it, it was just not correct.
you need to always clear
in resetForFuzzer
(for stability) and CoW
0491449
to
ee37b83
Compare
Alright, I've gone over the inherited files here and made a bunch of changes:
|
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 didn't review the tests yet because I think the implementation is going to change. You should add tests for some of the interesting floating-point edge cases I pointed out.
I've pushed changes to address all comments except on the floating-point reciprocal issue; these changes are small so I figure I may as well make them available for review while I think about the floating-point. |
702bb4b
to
e6181d2
Compare
After much interesting chat about arithmetic, I've pushed a commit to restore the ordering by double arithmetic within the invariant, as it's done in |
@rokopt can you squash+rebase at this point? We've gone through a lot of iterations here, with considerable back-and-forth on changes, and I need to get a clean look at it. |
6ab6a3d
to
639fb29
Compare
Sure, done. |
|
||
namespace stellar | ||
{ | ||
double |
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.
Nitpick: you probably want this in the anonymous namespace or static
.
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've removed uses of static
in favor of either the anonymous namespace or of membership in OrderBookNotCrossed
, depending on whether any members of the latter need the types/functions.
Note: in addition to responding to the latest code review comments, I've also pushed a commit to remove the |
This optimization is restored now, in a corrected form. |
@MonsieurNicolas I just went through and resolved all open comments from me. Should be ready for rebase/squash/merge. Agreed that I'd like to see the fuzzer statistics though. |
This should reduce the chances of the code rotting.
This mechanism will allow for fuzzer-specific invariants that support a mechanism for notifying them when setup has completed and then when each new test starts.
Make the fuzzer call the new InvariantManager snapshot/reset mechanism, as well as calling the existing one for LedgerTxnRoot whenever BUILD_TESTS is configured.
A new invariant which keeps track of the state of the order book as operations are applied, and asserts that it is not crossed. There is currently no mechanism by which an invariant can be informed that an operation application for which its checkOnOperationApply() method had been called is being rolled back. Hence, we can not in general support an invariant such as this which maintains state across method calls. But we will be able to do so when fuzzing, where setup operations are never rolled back and where we can explicitly tell invariants when to snapshot state (that is, after setup completes) and when to reset it to that state (after each fuzz test).
e74eb98
to
dffc55f
Compare
mmm, I do have a question though. Is the "exec speed" really that slow compared to both master and the previous iteration of that PR? I would not expect such a difference as the vast majority of fuzzing should not involve this invariant (it is, after all, unlikely that the fuzzer explores branches with offers). |
{ | ||
updateOrderBook(ltxDelta); | ||
auto assetPairs = extractAssetPairs(ltxDelta); | ||
return assetPairs.size() > 0 ? check(assetPairs) : std::string{}; |
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 that the reason things are super slow is that assetPairs.size() > 0
is always true even when there are no changes to the order book from this operation. In fact we should not perform any work in extractAssetPairs
if the operation didn't touch the order book.
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.
Hmm, why must assetPairs.size()
be > 0
? It looks to me as though if there are no OFFER
s in LedgerTxnDelta
, then it will be 0
, and I put in some logs and they say that it is often 0
.
One thing I mentioned to Jon about performance which I should bring up is that exec speed of fuzzing seems highly variable on my laptop, even from run to run without code changes (unlike stability, for example, which is generally within a fraction of a percent across many runs). Fuzzing does make my laptop fan roar, and I have a suspicion (though no confirmation) that there might be highly variable amounts of CPU-throttling going on depending on I-don't-know-what thermal factors.
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.
meh and I thought my head was straight in the morning :)
yeah this is extracting only from the current txn object so not it
I think I found the bug, let me know if this makes sense @rokopt |
I ran the version with the invariant enabled and without based on the same initial corpus (so no variation because of that) and they performed the same way, so it was probably a fluke with your computer |
we'll merge as soon as master reopens |
r+ dffc55f |
Introduce "order book not crossed" invariant
Resolves #2417
This PR introduces a new invariant which keeps track of the state of the order book as operations are applied, and asserts that it is not crossed.
There is currently no mechanism by which an invariant can be informed that an operation application for which its
checkOnOperationApply()
method had been called is being rolled back. Hence, we can not in general support an invariant such as this which maintains state across method calls. But we can when fuzzing, where setup operations are never rolled back and where we can explicitly tell invariants when to snapshot state (that is, after setup completes) and when to reset it to that state (after each fuzz test).Therefore, this invariant is compiled in when fuzzing is configured, and not otherwise.
This PR updates #2210 to current code, adapting to some changes such as the introduction of
InternalLedgerEntry
and the rearranging of the fuzzing code, and adds support for passive offers.Checklist
clang-format
v8.0.0 (viamake format
or the Visual Studio extension)