void InProcessNode::getPoolSymmetricDifferenceAsync(std::vector<Crypto::Hash>&& knownPoolTxIds, Crypto::Hash knownBlockId, bool& isBcActual, std::vector<std::unique_ptr<ITransactionReader>>& newTxs, std::vector<Crypto::Hash>& deletedTxIds, const Callback& callback) { std::error_code ec = std::error_code(); std::vector<TransactionPrefixInfo> added; isBcActual = core.getPoolChangesLite(knownBlockId, knownPoolTxIds, added, deletedTxIds); try { for (const auto& tx: added) { newTxs.push_back(createTransactionPrefix(tx.txPrefix, tx.txHash)); } } catch (std::system_error& ex) { ec = ex.code(); } catch (std::exception&) { ec = make_error_code(std::errc::invalid_argument); } callback(ec); }
void BlockchainSynchronizer::processBlocks(GetBlocksResponse& response) { uint32_t newHeight = response.startHeight + static_cast<uint32_t>(response.newBlocks.size()); BlockchainInterval interval; interval.startHeight = response.startHeight; std::vector<CompleteBlock> blocks; for (auto& block : response.newBlocks) { if (checkIfShouldStop()) { break; } CompleteBlock completeBlock; completeBlock.blockHash = block.blockHash; interval.blocks.push_back(completeBlock.blockHash); if (block.hasBlock) { completeBlock.block = std::move(block.block); completeBlock.transactions.push_back(createTransactionPrefix(completeBlock.block->baseTransaction)); try { for (const auto& txShortInfo : block.txsShortInfo) { completeBlock.transactions.push_back(createTransactionPrefix(txShortInfo.txPrefix, reinterpret_cast<const Hash&>(txShortInfo.txId))); } } catch (std::exception&) { setFutureStateIf(State::idle, std::bind( [](State futureState) -> bool { return futureState != State::stopped; }, std::ref(m_futureState))); m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, std::make_error_code(std::errc::invalid_argument)); return; } } blocks.push_back(std::move(completeBlock)); } if (!checkIfShouldStop()) { response.newBlocks.clear(); std::unique_lock<std::mutex> lk(m_consumersMutex); auto result = updateConsumers(interval, blocks); lk.unlock(); switch (result) { case UpdateConsumersResult::errorOccured: if (setFutureStateIf(State::idle, std::bind( [](State futureState) -> bool { return futureState != State::stopped; }, std::ref(m_futureState)))) { m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, std::make_error_code(std::errc::invalid_argument)); } break; case UpdateConsumersResult::nothingChanged: if (m_node.getLastKnownBlockHeight() != m_node.getLastLocalBlockHeight()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } else { break; } case UpdateConsumersResult::addedNewBlocks: setFutureState(State::blockchainSync); m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationProgressUpdated, newHeight, std::max(m_node.getKnownBlockCount(), m_node.getLocalBlockCount())); break; } if (!blocks.empty()) { lastBlockId = blocks.back().blockHash; } } if (checkIfShouldStop()) { //Sic! m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, std::make_error_code(std::errc::interrupted)); } }