mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 11:32:09 +00:00
cebb62997d
* Add AFL third_party libraries * add beacon state fuzzing, add afl fuzz bundle * rm fuzzing engine * fix and lint * Check for array out of bounds when calculating proposer delta * failing test * fix * Checkpoint progress * Add requirement that inclusion distance is not zero, add regression test * No need for HTR since that is covered in process slots * Removing some fuzzit logic, old fuzz tests * Add ssz encoder test and fix * Fuzzing checkpoint, adding fuzzing to the p2p layer * ignore some libfuzzer files * Full testing of p2p processing of blocks, with some mocked stuff * use tmpdir and always process blocks * use checkptr * Update ethereumapis * go mod tidy * benchmarks for ferran's fast ssz hash tree root * Update fastssz * fmt * gaz * goimports * Fix * fix ethereumapis * fix again * kafka * fix gen file * fix compute signing root * gofmt * checkpoint progress * progress * checkpoint * updates * updates * merge fix * WIP * merge * fix build * fix merge related issues * cleanup * revert unrelated * lint * lint * lint * manual tags for fuzz * Commentary on upload script * some import fixes, but not all * fix //fuzz:fuzz_tests * rm unused test * update generated ssz * Set // +build libfuzzer * remove debug code * A bit of refactoring ot explain why there is a committee_disabled file Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
103 lines
3.3 KiB
Markdown
103 lines
3.3 KiB
Markdown
# Prysm Fuzz Testing
|
|
|
|
[![fuzzit](https://app.fuzzit.dev/badge?org_id=prysmaticlabs-gh)](https://app.fuzzit.dev/orgs/prysmaticlabs-gh/dashboard)
|
|
|
|
## Adding a fuzz test
|
|
|
|
Fuzz testing attempts to find crash level bugs within the tested code paths, but could also be used
|
|
as a sanity check certain logic.
|
|
|
|
### 1) Determining an ideal target
|
|
|
|
A fuzz test inputs pseudo-random data to a given method and attempts to find input data that tests
|
|
as many code branches as possible. When choosing a target to test, consider that the method under
|
|
test should be as stateless as possible. While stateful methods (i.e. methods that use a cache),
|
|
can be tested, they are often hard to reproduce in a regression test. Consider disabling any caches
|
|
or persistence layers if possible.
|
|
|
|
### 2) Writing a fuzz test
|
|
|
|
First, you need to determine in your input data. The current test suite uses SSZ encoded bytes to
|
|
deserialize to input objects.
|
|
|
|
_Example: Block header input data_
|
|
|
|
```go
|
|
type InputBlockWithPrestate struct {
|
|
StateID uint16
|
|
Block *ethpb.BeaconBlock
|
|
}
|
|
```
|
|
|
|
You'll also want to add that struct to `//fuzz:ssz_generated_files` to generate the custom fast SSZ
|
|
methods for serialization to improve test performance.
|
|
|
|
Your fuzz test must accept a single argument of type `[]byte`. The return types are ignored by
|
|
libfuzzer, but might be useful for other applications such as
|
|
[beacon-fuzz](https://github.com/sigp/beacon-fuzz). Be sure to name your test file with the
|
|
`_fuzz.go` suffix for consistency.
|
|
|
|
```go
|
|
func MyExampleFuzz(b []byte) {
|
|
input := &MyFuzzInputData{}
|
|
if err := ssz.Unmarshal(b, input); err != nil {
|
|
return // Input bytes doesn't serialize to input object.
|
|
}
|
|
|
|
result, err := somePackage.MethodUnderTest(input)
|
|
if err != nil {
|
|
// Input was invalid for processing, but the method didn't panic so that's OK.
|
|
return
|
|
}
|
|
// Optional: sanity check the resulting data.
|
|
if result < 0 {
|
|
panic("MethodUnderTest should never return a negative number") // Fail!
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3) Add your fuzz target to fuzz/BUILD.bazel
|
|
|
|
Since we are using some custom rules to generate the fuzz test instrumentation and appropriate
|
|
libfuzz testing suite, we cannot rely on gazelle to generate these targets for us.
|
|
|
|
```starlark
|
|
go_fuzz_test(
|
|
name = "example_fuzz_test",
|
|
srcs = [
|
|
"example_fuzz.go",
|
|
] + COMMON_SRCS, # common and input type files.
|
|
corpus = "example_corpus",
|
|
corpus_path = "fuzz/example_corpus", # Path from root of project
|
|
func = "MyExampleFuzz",
|
|
importpath = IMPORT_PATH,
|
|
deps = [
|
|
# Deps used in your fuzz test.
|
|
] + COMMON_DEPS,
|
|
)
|
|
```
|
|
|
|
Be sure to add your target to the test suite at `//fuzz:fuzz_tests`.
|
|
|
|
### 4) Run your fuzz test
|
|
|
|
To run your fuzz test you must manually target it with bazel test and run with the config flag
|
|
`--config=fuzz`.
|
|
|
|
```
|
|
bazel test //fuzz:example_fuzz_test --config=fuzz
|
|
```
|
|
|
|
## Running fuzzit regression tests
|
|
|
|
To run fuzzit regression tests, you can run the fuzz test suite with the 1--config=fuzzit`
|
|
configuration flag. Note: This requires docker installed on your machine. See
|
|
[fuzzitdev/fuzzit#58](https://github.com/fuzzitdev/fuzzit/issues/58).
|
|
|
|
```
|
|
bazel test //fuzz:fuzz_tests --config=fuzzit
|
|
```
|
|
|
|
If the same command above is run with the FUZZIT_API_KEY environment variable set, then the fuzzit
|
|
test targets will be uploaded and restarted at https://app.fuzzit.dev.
|