prysm-pulse/fuzz
Radosław Kapka 12403d249f
[Feature] - API Middleware (#8926)
* HTTP proxy server for Eth2 APIs (#8904)

* Implement API HTTP proxy server

* cleanup + more comments

* gateway will no longer be dependent on beaconv1

* handle error during ErrorJson type assertion

* simplify handling of endpoint data

* fix mux v1 route

* use URL encoding for all requests

* comment fieldProcessor

* fix failing test

* change proxy port to not interfere with e2e

* gzl

* simplify conditional expression

* Move appending custom error header to grpcutils package

* add api-middleware-port flag

* fix documentation for processField

* modify e2e port

* change field processing error message

* better error message for field processing

* simplify base64ToHexProcessor

* fix json structs

* Run several new endpoints through API middleware (#8922)

* Implement API HTTP proxy server

* cleanup + more comments

* gateway will no longer be dependent on beaconv1

* handle error during ErrorJson type assertion

* simplify handling of endpoint data

* fix mux v1 route

* use URL encoding for all requests

* comment fieldProcessor

* fix failing test

* change proxy port to not interfere with e2e

* gzl

* simplify conditional expression

* Move appending custom error header to grpcutils package

* add api-middleware-port flag

* fix documentation for processField

* modify e2e port

* change field processing error message

* better error message for field processing

* simplify base64ToHexProcessor

* fix json structs

* /eth/v1/beacon/states/{state_id}/validators

* /eth/v1/beacon/states/{state_id}/validators/{validator_id}

* /eth/v1/beacon/states/{state_id}/validator_balances

* /eth/v1/beacon/states/{state_id}/committees

* allow skipping base64-encoding for query params

* /eth/v1/beacon/pool/attestations

* replace break with continue

* Remove unused functions (#8924)

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Process SSZ-serialized beacon state through API middleware (#8925)

* update field names

* Process SSZ-serialized beacon state through API middleware

* revert changes to go.mod and go.sum

* Revert "Merge branch '__develop' into feature/api-middleware"

This reverts commit 7c739a8fd71e2c1e3a14be85abd29a59b57ae9b5, reversing
changes made to 2d0f8e012ecb006888ed8e826b45625a3edc2eeb.

* update ethereumapis

* update validator field name

* update deps.bzl

* update json tags (#8942)

* Run `/node/syncing` through API Middleware (#8944)

* add IsSyncing field to grpc response

* run /node/syncing through the middleware

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

* Return HTTP status codes other than 200 and 500 from node and debug endpoints (#8937)

* error codes for node endpoints

* error codes for debug endpoints

* better comment about headers

* gzl

* review comments

* comment on return value

* update fakeChecker used for fuzz tests

* fix failing tests

* Allow to pass URL params literally, without encoding to base64 (#8938)

* Allow to pass URL params literally, without encoding to base64

* fix compile error

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

* Process SSZ-serialized beacon state through API middleware (#8925)

* update field names

* Process SSZ-serialized beacon state through API middleware

* revert changes to go.mod and go.sum

* Revert "Merge branch '__develop' into feature/api-middleware"

This reverts commit 7c739a8fd71e2c1e3a14be85abd29a59b57ae9b5, reversing
changes made to 2d0f8e012ecb006888ed8e826b45625a3edc2eeb.

* update ethereumapis

* update validator field name

* update deps.bzl

* update json tags (#8942)

* Run `/node/syncing` through API Middleware (#8944)

* add IsSyncing field to grpc response

* run /node/syncing through the middleware

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

* Return HTTP status codes other than 200 and 500 from node and debug endpoints (#8937)

* error codes for node endpoints

* error codes for debug endpoints

* better comment about headers

* gzl

* review comments

* comment on return value

* update fakeChecker used for fuzz tests

* fix failing tests

* Allow to pass URL params literally, without encoding to base64 (#8938)

* Allow to pass URL params literally, without encoding to base64

* fix compile error

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

* unused import

* Return correct status codes from beacon endpoints (#8960)

* Various API Middleware fixes (#8963)

* Return correct status codes from `/states` endpoints

* better error messages in debug and node

* better error messages in state

* returning correct error codes from validator endpoints

* correct error codes for getting a block header

* gzl

* fix err variable name

* fix nil block comparison

* test fixes

* make status enum test better

* fix ineffectual assignment

* make PR unstuck

* return proper status codes

* return uppercase keys from /config/spec

* return lowercase validator status

* convert requested enum values to uppercase

* validator fixes

* Implement `/beacon/headers` endpoint (#8966)

* Refactor API Middleware into more manageable code  (#8984)

* move endpoint registration out of shared package

* divide main function into smaller components

* return early on error

* implement hooks

* implement custom handlers and add documentation

* fix test compile error

* restrict package visibility

* remove redundant error checking

* rename file

* API Middleware unit tests (#8998)

* move endpoint registration out of shared package

* divide main function into smaller components

* return early on error

* implement hooks

* implement custom handlers and add documentation

* fix test compile error

* restrict package visibility

* remove redundant error checking

* rename file

* api_middleware_processing

* endpoints

* gzl

* remove gazelle:ignore

* merge

* Implement SSZ version of `/blocks/{block_id}` (#8970)

* Implement SSZ version of `/blocks/{block_id}`

* add dependencies back

* fix indentation in deps.bzl

* parameterize ssz functions

* get block ssz

* update ethereumapis dependency

* gzl

* Do not reuse `Endpoint` structs between API calls (#9007)

* code refactor

* implement endpoint factory

* fix test

* fmt

* include pbs

* gaz

* test naming fixes

* remove unused code

* radek comments

* revert endpoint test

* bring back bytes test case

* move `signedBeaconBlock` to `migration` package

* change `fmt.Errorf` to `errors.Wrap`

* capitalize SSZ

* capitalize URL

* more review feedback

* rename `handleGetBlockSSZ` to `handleGetBeaconBlockSSZ`

* rename `IndexOutOfRangeError` to `ValidatorIndexOutOfRangeError`

* simplify parameter names

* test header

* more corrections

* properly allocate array capacity

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-06-15 10:28:49 -05:00
..
rpc_status_corpus libfuzz based tests (#5095) 2020-05-05 07:22:26 +00:00
testing Rename getter functions to be idiomatic (#8320) 2021-01-25 21:27:30 +00:00
block_fuzz.go [Feature] - API Middleware (#8926) 2021-06-15 10:28:49 -05:00
BUILD.bazel Move EthereumAPIs Into Prysm (#8968) 2021-06-02 18:49:52 -05:00
common.go Fix comments (#8802) 2021-04-23 12:06:05 +00:00
generated.ssz.go Move EthereumAPIs Into Prysm (#8968) 2021-06-02 18:49:52 -05:00
inputs.go Move EthereumAPIs Into Prysm (#8968) 2021-06-02 18:49:52 -05:00
README.md Add beacon state unmarshal fuzzer, afl support (#6625) 2020-09-14 11:42:08 -07:00
rpc_status_fuzz.go Move EthereumAPIs Into Prysm (#8968) 2021-06-02 18:49:52 -05:00
ssz_encoder_attestations_fuzz.go Move EthereumAPIs Into Prysm (#8968) 2021-06-02 18:49:52 -05:00
state_fuzz.go Remove unused functions (#8924) 2021-05-23 09:36:46 +02: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 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. 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.