Skip to content

Fuzz testing#2887

Merged
LefterisJP merged 7 commits into
raiden-network:masterfrom
jomuel:fuzz-testing
Nov 26, 2018
Merged

Fuzz testing#2887
LefterisJP merged 7 commits into
raiden-network:masterfrom
jomuel:fuzz-testing

Conversation

@jomuel
Copy link
Copy Markdown
Contributor

@jomuel jomuel commented Oct 25, 2018

This PR contains a first messaging fuzz test (as requested in issue #1155) as a proposal what fuzz tests/property tests for raiden could look like.

Before this test is merged, it will be added to travis in a new job, extended to test more situations and the code will be cleaned up.

Copy link
Copy Markdown
Contributor

@hackaugusto hackaugusto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't write the fuzz test as an integration test, it will be too slow.

@jomuel jomuel force-pushed the fuzz-testing branch 5 times, most recently from 17d19b0 to 86582c8 Compare October 31, 2018 17:22
Comment thread raiden/tests/unit/fuzz/test_initiator_state.py Outdated
Comment thread raiden/tests/unit/fuzz/test_initiator_state.py Outdated
Comment thread raiden/tests/unit/fuzz/test_initiator_state.py Outdated
Comment thread raiden/tests/unit/fuzz/test_state_changes.py
@jomuel jomuel force-pushed the fuzz-testing branch 2 times, most recently from 807770d to 6129ef6 Compare November 15, 2018 12:49
@jomuel jomuel force-pushed the fuzz-testing branch 2 times, most recently from 85a22ee to 825c3fa Compare November 15, 2018 13:15
partner_balance = channel.get_balance(partner_state, our_state)

assert channel.get_amount_locked(our_state) <= our_balance
assert channel.get_amount_locked(partner_state) <= partner_balance
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a nice place to assert for the client invariants:

https://github.com/raiden-network/raiden-contracts/blob/052faf488da140e84bb854272f96a5cdec773b38/raiden_contracts/contracts/TokenNetwork.sol#L636-L649

@loredanacirstea could you please give me a hand, I don't know where these invariants are listed, is it in only in the TokenNetwork.sol file?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hackaugusto , the constraints that we must enforce are listed here: https://raiden-network-specification.readthedocs.io/en/latest/smart_contracts.html#protocol-values-constraints. For both the smart contracts and Raiden client. Is this what you asked for?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you :)

our_deposit = netting_channel.our_total_deposit
our_amount_locked = channel.get_amount_locked(our_state)
our_balance = channel.get_balance(our_state, partner_state)
assert 0 <= our_amount_locked <= our_balance <= our_deposit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct:

  • our_amount_locked may be larger then our_deposit, this happens when we receive a transfer partner, which gives us a balance higher then our deposit.
  • our_balance can too be higher then our deposit, for the same reason

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and as mentioned in https://raiden-network-specification.readthedocs.io/en/latest/smart_contracts.html#protocol-values-constraints, we have the following invariant: (5.1 R) L1 <= AB1, L1 <= TAD, L1 >= 0. Therefore, the above assertion can be split into:

assert 0 <= our_amount_locked <= our_balance
assert our_amount_locked <= our_deposit + partner_deposit  

Note that TAD is actually the total available deposit - if we had the withdraw implemented, we would instead have: assert our_amount_locked <= our_deposit + partner_deposit - out_withdrawn - partner_withdrawn. This MUST be changed at that point, so maybe worth documenting this in the withdraw issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I changed the checks accordingly.

@jomuel jomuel force-pushed the fuzz-testing branch 5 times, most recently from dd2d327 to 1ba4e27 Compare November 15, 2018 17:55
@jomuel jomuel force-pushed the fuzz-testing branch 2 times, most recently from db2d687 to 5f87eac Compare November 16, 2018 10:22
Comment thread raiden/tests/unit/fuzz/test_state_changes.py
@LefterisJP
Copy link
Copy Markdown
Contributor

I have a question though. I thought that the point of fuzz testing was to create state changes with random but valid values and feed them to the state machine and see that it does not break. I am not sure how we are achieving this with this approach. Perhaps I misunderstand how hypothesis works but the test_regression_malicious_secret_request_handled_properly seems to test one specific scenario we know of. What am I missing?

@jomuel
Copy link
Copy Markdown
Contributor Author

jomuel commented Nov 17, 2018

@LefterisJP Yes, test_regression_malicious_secret_request_handled_properly really just replays a single path that used to fail before Paul fixed issue #3000. Its code is mostly generated by Hypothesis.

Notice though that pytest will collect another test from this file, TestInitiator (pyunit-style test class). That is where the real fuzz test happens, it generates 100 randomized paths with randomized input data from the defined @rules.

- wrap hypothesis' event function
- change strategy for secret generation
- add invariant checks
- enable creating multiple channels
If an invalid but authentic secret request is received, we consider the
whole transfer to be failed since the request was likely malicious. A
following valid secret request will thus not be successful anymore.

[no ci integration]
unskip regression test (fixed together with an earlier issue),
correct invariant checks
Copy link
Copy Markdown
Contributor

@LefterisJP LefterisJP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@LefterisJP LefterisJP dismissed hackaugusto’s stale review November 26, 2018 13:51

The last comment by Augusto is addressed and he can't react since he is on vacation

@LefterisJP LefterisJP merged commit 92269e3 into raiden-network:master Nov 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants