prysm-pulse/fuzz
Preston Van Loon 49a0d3caf0
Refactor dependencies, make Prysm "go gettable" (#6053)
* Fix a few deps to work with go.mod, check in generated files

* Update Gossipsub to 1.1 (#5998)

* update libs

* add new validators

* add new deps

* new set of deps

* tls

* further fix gossip update

* get everything to build

* clean up

* gaz

* fix build

* fix all tests

* add deps to images

* imports

Co-authored-by: rauljordan <raul@prysmaticlabs.com>

* Beacon chain builds with go build

* fix bazel

* fix dep

* lint

* Add github action for testing go

* on PR for any branch

* fix libp2p test failure

* Fix TestProcessBlock_PassesProcessingConditions by updating the proposer index in test

* Revert "Fix TestProcessBlock_PassesProcessingConditions by updating the proposer index in test"

This reverts commit 43676894ab01f03fe90a9b8ee3ecfbc2ec1ec4e4.

* Compute and set proposer index instead of hard code

* Add back go mod/sum, fix deps

* go build ./...

* Temporarily skip two tests

* Fix kafka confluent patch

* Fix kafka confluent patch

* fix kafka build

* fix kafka

* Add info in DEPENDENCIES. Added a stub link for Why Bazel? until https://github.com/prysmaticlabs/documentation/issues/138

* Update fuzz ssz files as well

* Update fuzz ssz files as well

* getting closer

* rollback rules_go and gazelle

* fix gogo protobuf

* install librdkafka-dev as part of github actions

* Update kafka to a recent version where librkafkfa is not required for go modules

* clarify comment

* fix kafka build

* disable go tests

* comment

* Fix geth dependencies for end to end

* rename word

* lint

* fix docker

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: rauljordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-05-31 14:44:34 +08:00
..
deposit_corpus libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
rpc_status_corpus libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
testing External slashing protection (#5895) 2020-05-20 10:23:22 -05:00
voluntary_exit_corpus libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
attestation_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
attester_slashing_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
block_fuzz.go Load chain config from file (#5694) 2020-05-05 20:58:07 +03:00
block_header_fuzz.go Load chain config from file (#5694) 2020-05-05 20:58:07 +03:00
BUILD.bazel Refactor dependencies, make Prysm "go gettable" (#6053) 2020-05-31 14:44:34 +08:00
common.go Load chain config from file (#5694) 2020-05-05 20:58:07 +03:00
deposit_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
generated.ssz.go Refactor dependencies, make Prysm "go gettable" (#6053) 2020-05-31 14:44:34 +08:00
inputs.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
proposer_slashing_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
README.md libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
rpc_status_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
ssz_cache_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
voluntary_exit_fuzz.go libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00

Prysm Fuzz Testing

fuzzit

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

type InputBlockHeader 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. Be sure to name your test file with the _fuzz.go suffix for consistency.

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.

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.

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.