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;
|
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_)
|
switch (state_)
|
||||||
{
|
{
|
||||||
case State::open:
|
case State::open:
|
||||||
checkLCL ();
|
|
||||||
statePreClose ();
|
statePreClose ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State::establish:
|
case State::establish:
|
||||||
checkLCL ();
|
|
||||||
stateEstablish ();
|
stateEstablish ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user