-
Notifications
You must be signed in to change notification settings - Fork 16
IBFT Persistence Issue Test #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Hi @zivkovicmilos. Happy to see the persistence test. A couple of comments on the PR that we can discuss. First, we avoid on the same PR to refactor the business logic (i.e. add a test to detect the persistence liveness) of the consensus and clean the arquitecture (i.e. move test utilities on separated files), specially if new files are being created. This is because the review UI in Github gets tricky and it is easy to miss stuff. Second, you hit the point that we discussed over PR-22. Complex situations that coordinate multiple nodes get a bit convoluted when done in unit tests. This is why we follow a layered test arquitecture on this repo: unit tests (single node state machine, no async calls, no concept of network), integration tests (multi node state machine, with async calls and "simulated network"), fuzz testing (random integration tests). Though we can argue if the frameworks we provide for each layer are good or not (or could be more optimal), as it is right now, your |
|
Hey @ferranbt, Sorry for the late reply concerning this PR. There are a couple of points I’d like to address here:
Completely agree with this 👍 The changes that have been made are really concerning just helper test logic that was contained in It's no problem to make sure we don't pollute the PR code changes with cleanup in future PRs 💯
What do you find complex in the test outlined in this PR? The PR adds support for setting up a mock PBFT cluster, and for setting hooks for the backend of each individual node - something that was already present in the codebase, but underutilized. This is powerful, not just for the test that I’ve introduced, but also for existing tests - some of which I’ve changed to use this simple hook logic for the backend. For each backend operation you want executed within a state, you can attach a hook to execute, for each of the nodes. It gives the test maker complete control over the testing environment, as should always be the case. The flow map that you introduced in the liveness test is considered convoluted because you need to cherry pick and carefully construct gossip omitance paths - not to mention that there is practically no way to define Byzantine messages using that approach, something which is possible to achieve by using the hook implementation for your backend, that you can override on a test by test and (more importantly) on a node to node basis.
I get your point - there are some times when you want to just set up a cluster and let it run in the background, and do checking after it goes through all of the states. The persistence test introduced in the mentioned paper (and the liveness test too) require very careful scene setup for each of the states of the consensus process. These states should to be checked before and after you run each state, to make sure:
There is no need for the persistence test (and liveness test) to run for 5mins and make us rely on logs in the output because of a general lack of assert statements.
|
|
Kudos, SonarCloud Quality Gate passed!
|








Description
This PR aims to add support for the Persistence Analysis issue proof from the
IBFT Analysispaper:Section 5 Persistence Analysis, Lemma 9 Proof
Essentially, it aims to prove that for any given proposal
Pat sequenceS, there can be a series of events that would cause 2 honest validators to insert a sealed proposalPandP'respectively, for sequenceS, whereP!=P'.The series of steps is simulated by using state machine snapshots from the PBFT implementation, where only the
Backendinterface is mocked, and all states are simulated as they would actually run.Test in quesiton is
TestPBFT_Persistence.Terminology
N-total number of nodesF- number of tolerated faulty nodesv- random validator from the set validator setW- all validator nodes, apart fromv, including the Byzantine nodesWhonest- all honest validator nodes inWPrerequisites
The persistence problem is present for
N >= 4andF >= 1.vis not a proposer for any proposal.Assumptions
The following assumptions are present in the
TestPbft_Persistencetest:N = 5F = 1v = Node 2W = [Node 0, Node 1, Node 3, Node 4]Whonest = [Node 0, Node 1, Node 3]Byzantine Node = Node 4Steps outlined in the paper
Node 0) sends out a PREPREPARE message to all other nodes (Wandv) for proposalP, and moves toValidate statePREPAREmessages, receive enough and move toValidate stateValidate state, all honest nodes (Whonestandv) gossipCOMMITmessages, and lock on proposalPNode 4) sends a validCOMMITmessage tov(Node 2), but a malformedCOMMITmessage to all nodes inWhonest*v(Node 2) receives QuorumCOMMITmessages and moves toCommit stateto insert the proposal to the backendvgoes intoDone stateafter inserting the proposal, finishes the cycleWhonest(Node 0,Node 1,Node 3) receive a malformedCOMMITmessage, and trigger aROUND CHANGEmessage, moving to theRound Change state*Whonest, as well as the byzantine node (Node 4) agree to move toround 1in theRound Change stateNode 1Node 1sends out aPREPREPAREmessage to all other nodes, for proposalP', and moves toValidate stateWgossip aPREPAREmessage and move toValidate stateWgossipCOMMITmessages, receive enough and lock on proposalP'Wsuccessfully validate the proposal (the byzantine node doesn't send any malformed messages in round 1)Wsuccessfully insert proposalP'to the backendAt this point,
Node 2(v) has inserted proposalPfor sequenceS, and nodesNode 0, Node 1, Node 3, Node 4have inserted proposalP'for sequenceS, thus causing a persistence problem.* There is no need to simulate a malformed gossipped commit message in the test,
since. This part of the test was just mocked so thepbft-consensusdoesn't handle commit message verification, and leaves it up to theBackendinterface to verify everything duringCommit stateBackendinterface failed to insert the proposal for nodes inW(simulating an invalid commit signature error for example).EDIT:
Following @ferranbt's PR which was merged out in the meantime,
pbft-consensusactually has the ability to verify commit messages with the backend. This test can be changed to override the verify commit message handler for theBackendinterface, so it's more closer to the original paper steps.Additional changes
The PR also moves out test helper code that was previously present in
consensus_test.gotoconsensus_testing.goand instate_test.gotostate_testing.go, respectively.