Open ruuda opened 3 years ago
If it helps, we've found that using both proptest for specific calculations and fuzzing from the top-level gives great coverage
Proptest looks very similar to cargo-fuzz
+ Arbitrary
. If I understand correctly Proptest is not coverage-driven, whereas cargo-fuzz is. It’s a wrapper around LLVM’s libFuzzer, which inserts instrumentation into the program that records coverage, which helps it to explore “interesting” inputs that have a low probability of being generated with QuickCheck-style generators. I’m not sure if libFuzzer will work with Solana, Proptest looks like a good alternative :+1:
They're a bit similar, but they have different intended uses. An analogy could be that proptests are like unit tests, and fuzzing is like integration tests. So for example, to test the fix to the fee calculation, I'll write a proptest.
Separately, honggfuzz and libFuzzer both work with Solana. I've used both of them and preferred honggfuzz only because it doesn't require rust nightly. There's a nice example of using honggfuzz with program-test in the bonfida bot repo: https://github.com/Bonfida/bonfida-bot/tree/main/program/fuzz and an example without program-test using libFuzzer at https://github.com/project-serum/serum-dex/tree/master/dex/fuzz
So I’ve been thinking some more about this, and I don’t think it is something we can do at this point.
solana_program_test
framework. But that one only runs with cargo test-bpf
, which I don’t think is compatible with something like cargo-fuzz
, because they both want control over the rustc and LLVM flags. Aside from that, we have very little invariants in Solido that could be violated. (One I can think of is AccountMap
, which should never store more elements than its configured maximum.) We have pretty nice data structures where every instance in principle is valid, so there are no obvious things to assert.There are a few narrow use cases where fuzzing is a good fit:
Lido
struct manually, roundtripping would be a good thing to fuzz.
This is an idea that was just mentioned during the meeting with the Solana team: property-test some invariants of Lido.
One great way of doing this is to encode every operation in a data structure, derive
Arbitrary
for it, and then run it incargo-fuzz
. This way you get coverage-driven property testing which is very powerful.The thing I’m not sure about is how this would pan out in practice, because not all interactions happen in the Rust program itself, there are interactions with the Solana validator. Perhaps this thing that is also used in tests could be useful here.