| 444 | } |
| 445 | |
| 446 | void backUpdateTxes(const ParserConfigurationBase &config) { |
| 447 | std::vector<OutputLinkData> updates; |
| 448 | |
| 449 | std::cout << "Updating spent outputs" << std::endl; |
| 450 | |
| 451 | { |
| 452 | blocksci::FixedSizeFileMapper<OutputLinkData> linkDataFile(config.txUpdatesFilePath()); |
| 453 | updates.reserve(static_cast<size_t>(linkDataFile.size())); |
| 454 | |
| 455 | for (uint32_t i = 0; i < linkDataFile.size(); i++) { |
| 456 | updates.push_back(*linkDataFile[i]); |
| 457 | } |
| 458 | |
| 459 | std::sort(updates.begin(), updates.end(), [](const auto& a, const auto& b) { |
| 460 | return a.pointer < b.pointer; |
| 461 | }); |
| 462 | } |
| 463 | |
| 464 | { |
| 465 | blocksci::IndexedFileMapper<mio::access_mode::write, blocksci::RawTransaction> txFile(blocksci::ChainAccess::txFilePath(config.dataConfig.chainDirectory())); |
| 466 | auto progressBar = blocksci::makeProgressBar(updates.size(), [=]() {}); |
| 467 | |
| 468 | uint32_t count = 0; |
| 469 | for (auto &update : updates) { |
| 470 | auto tx = txFile.getData(update.pointer.txNum); |
| 471 | auto &output = tx->getOutput(update.pointer.inoutNum); |
| 472 | // Set the forward-reference to the tx number of the tx that contains the spending input |
| 473 | output.setLinkedTxNum(update.txNum); |
| 474 | |
| 475 | count++; |
| 476 | progressBar.update(count); |
| 477 | } |
| 478 | } |
| 479 | filesystem::path{config.txUpdatesFilePath() + ".dat"}.remove_file(); |
| 480 | } |
| 481 | |
| 482 | struct CompletionGuard { |
| 483 | explicit CompletionGuard(std::atomic<bool> &isDone_) : isDone(isDone_) {} |
no test coverage detected