Skip to content

Commit

Permalink
Fix consensus quorum comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
bachase committed Jul 13, 2017
1 parent 4229ed6 commit 1f5917b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/ripple/consensus/Consensus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ checkConsensusReached(

std::size_t currentPercentage = (agreeing * 100) / total;

return currentPercentage > minConsensusPct;
return currentPercentage >= minConsensusPct;
}

ConsensusState
Expand Down
44 changes: 28 additions & 16 deletions src/test/consensus/Consensus_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,27 +175,28 @@ class Consensus_test : public beast::unit_test::suite
}

void
testSlowPeer()
testSlowPeers()
{
using namespace csf;
using namespace std::chrono;

// Run two tests
// 1. The slow peer is participating in consensus
// 2. The slow peer is just observing
// 1. The slow peers are participating in consensus
// 2. The slow peers are just observing

for (auto isParticipant : {true, false})
{
ConsensusParms parms;
auto tg = TrustGraph::makeComplete(5);
auto tg = TrustGraph::makeComplete(6);

Sim sim(parms, tg, topology(tg, [&](PeerID i, PeerID j) {
auto delayFactor = (i == 0 || j == 0) ? 1.1 : 0.2;
auto delayFactor = (i <= 1 || j <= 1) ? 1.1 : 0.2;
return round<milliseconds>(
delayFactor * parms.ledgerGRANULARITY);
}));

sim.peers[0].proposing_ = sim.peers[0].validating_ = isParticipant;
sim.peers[1].proposing_ = sim.peers[1].validating_ = isParticipant;

// All peers submit their own ID as a transaction and relay it to
// peers
Expand All @@ -217,30 +218,41 @@ class Consensus_test : public beast::unit_test::suite
if (isParticipant)
{
BEAST_EXPECT(p.prevProposers() == sim.peers.size() - 1);
// Peer 0 closes first because it sees a quorum of agreeing
// positions from all other peers in one hop (1->0, 2->0,
// ..) The other peers take an extra timer period before
// they find that Peer 0 agrees with them ( 1->0->1,
// 2->0->2, ...)
if (p.id != 0)
// Due to the network link delay settings
// Peer 0 initially proposes {0}
// Peer 1 initially proposes {1}
// Peers 2-5 initially propose {2,3,4,5}
// Since peers 2-5 agree, 4/6 > the initial 50% threshold
// on disputed transactions, so Peer 0 and 1 change their
// position to match peers 2-5 and declare consensus now that
// 5/6 proposed positions match (themselves and peers 2-5).
//
// Peers 2-5 do not change position, since tx 0 or tx 1 have
// less than the 50% initial threshold. They also cannot
// declare consensus, since 4/6 < 80% threshold agreement on
// current positions. Instead, they have to wait an
// additional timerEntry call for the updated peer 0 and
// peer 1 positions to arrive. Once they do, now peers 2-5
// see complete agreement and declare consensus
if (p.id > 1)
BEAST_EXPECT(
p.prevRoundTime() > sim.peers[0].prevRoundTime());
}
else // peer 0 is not participating
{
auto const proposers = p.prevProposers();
if (p.id == 0)
BEAST_EXPECT(proposers == sim.peers.size() - 1);
else
if (p.id <= 1)
BEAST_EXPECT(proposers == sim.peers.size() - 2);
else
BEAST_EXPECT(proposers == sim.peers.size() - 3);

// so all peers should have closed together
BEAST_EXPECT(
p.prevRoundTime() == sim.peers[0].prevRoundTime());
}

BEAST_EXPECT(lgrID.txs.find(Tx{0}) == lgrID.txs.end());
for (std::uint32_t i = 1; i < sim.peers.size(); ++i)
for (std::uint32_t i = 2; i < sim.peers.size(); ++i)
BEAST_EXPECT(lgrID.txs.find(Tx{i}) != lgrID.txs.end());
// Matches peer 0 ledger
BEAST_EXPECT(lgrID.txs == sim.peers[0].prevLedgerID().txs);
Expand Down Expand Up @@ -618,7 +630,7 @@ class Consensus_test : public beast::unit_test::suite

testStandalone();
testPeersAgree();
testSlowPeer();
testSlowPeers();
testCloseTimeDisagree();
testWrongLCL();
testFork();
Expand Down

0 comments on commit 1f5917b

Please sign in to comment.