ChorusOne / solido

Lido for Solana is a Lido-DAO governed liquid staking protocol for the Solana blockchain.
https://chorusone.github.io/solido/
GNU General Public License v3.0
101 stars 44 forks source link

Fuzzing-based property-based testing #71

Open ruuda opened 3 years ago

ruuda commented 3 years ago

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 in cargo-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.

joncinque commented 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

ruuda commented 3 years ago

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:

joncinque commented 3 years ago

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

ruuda commented 3 years ago

So I’ve been thinking some more about this, and I don’t think it is something we can do at this point.

There are a few narrow use cases where fuzzing is a good fit: