mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Fix handleLCL consensus bug:
Consensus::checkLCL can change state_ but it was being called inside timerEntry after a switch on the current state_. In rare cases, this might end up calling stateEstablish even when the state_ was open.
This commit is contained in:
@@ -867,15 +867,18 @@ Consensus<Derived, Traits>::timerEntry (NetClock::time_point const& now)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
// checkLCL may change state_, so it needs to run prior to the
|
||||
// switch (state_) below
|
||||
if(state_ == State::open || state_ == State::establish)
|
||||
checkLCL ();
|
||||
|
||||
switch (state_)
|
||||
{
|
||||
case State::open:
|
||||
checkLCL ();
|
||||
statePreClose ();
|
||||
break;
|
||||
|
||||
case State::establish:
|
||||
checkLCL ();
|
||||
stateEstablish ();
|
||||
break;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
using namespace std::chrono;
|
||||
|
||||
// Run two tests
|
||||
// 1. The slow peer is participating inconsensus
|
||||
// 1. The slow peer is participating in consensus
|
||||
// 2. The slow peer is just observing
|
||||
|
||||
for(auto isParticipant : {true, false})
|
||||
@@ -295,6 +295,43 @@ public:
|
||||
|
||||
}
|
||||
|
||||
// Additional test engineered to switch LCL during the establish phase.
|
||||
// This was added to trigger a scenario that previously crashed, in which
|
||||
// switchLCL switched from establish to open phase, but still processed
|
||||
// the establish phase logic.
|
||||
{
|
||||
using namespace csf;
|
||||
using namespace std::chrono;
|
||||
|
||||
// A mostly disjoint topology
|
||||
std::vector<UNL> unls;
|
||||
unls.push_back({0, 1});
|
||||
unls.push_back({2});
|
||||
unls.push_back({3});
|
||||
unls.push_back({0, 1, 2, 3, 4});
|
||||
std::vector<int> membership = {0, 0, 1, 2, 3};
|
||||
|
||||
TrustGraph tg{unls, membership};
|
||||
|
||||
Sim sim(tg, topology(tg, fixed{round<milliseconds>(
|
||||
0.2 * LEDGER_GRANULARITY)}));
|
||||
|
||||
// initial ground to set prior state
|
||||
sim.run(1);
|
||||
for (auto &p : sim.peers) {
|
||||
// A long delay to acquire a missing ledger from the network
|
||||
p.missingLedgerDelay = 2 * LEDGER_MIN_CLOSE;
|
||||
|
||||
// Everyone sees only their own LCL
|
||||
p.openTxs.insert(Tx(p.id));
|
||||
}
|
||||
// additional rounds to generate wrongLCL and recover
|
||||
sim.run(2);
|
||||
|
||||
// Check all peers recovered
|
||||
for (auto &p : sim.peers)
|
||||
BEAST_EXPECT(p.LCL() == sim.peers[0].LCL());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user