mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Fallback to normal sync if fast loading is not possible:
If fast loading is enabled but the last persisted ledger is not entirely on disk, the server would fail to start without manual intervention by the server operator. This commit allows the server to detect this scenario and attempt to automatically recover.
This commit is contained in:
committed by
Nik Bougalis
parent
8f82b62e0d
commit
c0cb389b20
@@ -774,7 +774,7 @@ Ledger::walkLedger(beast::Journal j, bool parallel) const
|
||||
else
|
||||
{
|
||||
if (parallel)
|
||||
stateMap_->walkMapParallel(missingNodes1, 32);
|
||||
return stateMap_->walkMapParallel(missingNodes1, 32);
|
||||
else
|
||||
stateMap_->walkMap(missingNodes1, 32);
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ public:
|
||||
|
||||
void
|
||||
walkMap(std::vector<SHAMapMissingNode>& missingNodes, int maxMissing) const;
|
||||
void
|
||||
bool
|
||||
walkMapParallel(
|
||||
std::vector<SHAMapMissingNode>& missingNodes,
|
||||
int maxMissing) const;
|
||||
|
||||
@@ -290,13 +290,13 @@ SHAMap::walkMap(std::vector<SHAMapMissingNode>& missingNodes, int maxMissing)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
SHAMap::walkMapParallel(
|
||||
std::vector<SHAMapMissingNode>& missingNodes,
|
||||
int maxMissing) const
|
||||
{
|
||||
if (!root_->isInner()) // root_ is only node, and we have it
|
||||
return;
|
||||
return false;
|
||||
|
||||
using StackEntry = std::shared_ptr<SHAMapInnerNode>;
|
||||
std::array<std::shared_ptr<SHAMapTreeNode>, 16> topChildren;
|
||||
@@ -311,6 +311,8 @@ SHAMap::walkMapParallel(
|
||||
}
|
||||
std::vector<std::thread> workers;
|
||||
workers.reserve(16);
|
||||
std::vector<SHAMapMissingNode> exceptions;
|
||||
exceptions.reserve(16);
|
||||
|
||||
std::array<std::stack<StackEntry, std::vector<StackEntry>>, 16> nodeStacks;
|
||||
|
||||
@@ -329,45 +331,62 @@ SHAMap::walkMapParallel(
|
||||
|
||||
JLOG(journal_.debug()) << "starting worker " << rootChildIndex;
|
||||
workers.push_back(std::thread(
|
||||
[&m, &missingNodes, &maxMissing, this](
|
||||
[&m, &missingNodes, &maxMissing, &exceptions, this](
|
||||
std::stack<StackEntry, std::vector<StackEntry>> nodeStack) {
|
||||
while (!nodeStack.empty())
|
||||
try
|
||||
{
|
||||
std::shared_ptr<SHAMapInnerNode> node =
|
||||
std::move(nodeStack.top());
|
||||
assert(node);
|
||||
nodeStack.pop();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
while (!nodeStack.empty())
|
||||
{
|
||||
if (node->isEmptyBranch(i))
|
||||
continue;
|
||||
std::shared_ptr<SHAMapTreeNode> nextNode =
|
||||
descendNoStore(node, i);
|
||||
std::shared_ptr<SHAMapInnerNode> node =
|
||||
std::move(nodeStack.top());
|
||||
assert(node);
|
||||
nodeStack.pop();
|
||||
|
||||
if (nextNode)
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
if (nextNode->isInner())
|
||||
nodeStack.push(
|
||||
std::static_pointer_cast<SHAMapInnerNode>(
|
||||
nextNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard l{m};
|
||||
missingNodes.emplace_back(
|
||||
type_, node->getChildHash(i));
|
||||
if (--maxMissing <= 0)
|
||||
return;
|
||||
if (node->isEmptyBranch(i))
|
||||
continue;
|
||||
std::shared_ptr<SHAMapTreeNode> nextNode =
|
||||
descendNoStore(node, i);
|
||||
|
||||
if (nextNode)
|
||||
{
|
||||
if (nextNode->isInner())
|
||||
nodeStack.push(std::static_pointer_cast<
|
||||
SHAMapInnerNode>(nextNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard l{m};
|
||||
missingNodes.emplace_back(
|
||||
type_, node->getChildHash(i));
|
||||
if (--maxMissing <= 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SHAMapMissingNode const& e)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
exceptions.push_back(e);
|
||||
}
|
||||
},
|
||||
std::move(nodeStacks[rootChildIndex])));
|
||||
}
|
||||
|
||||
for (std::thread& worker : workers)
|
||||
worker.join();
|
||||
|
||||
std::lock_guard l(m);
|
||||
if (exceptions.empty())
|
||||
return true;
|
||||
std::stringstream ss;
|
||||
ss << "Exception(s) in ledger load: ";
|
||||
for (auto const& e : exceptions)
|
||||
ss << e.what() << ", ";
|
||||
JLOG(journal_.error()) << ss.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
Reference in New Issue
Block a user