void BlockchainSynchronizer::startPoolSync() { std::unordered_set<Crypto::Hash> unionPoolHistory; std::unordered_set<Crypto::Hash> intersectedPoolHistory; getPoolUnionAndIntersection(unionPoolHistory, intersectedPoolHistory); GetPoolRequest unionRequest; unionRequest.knownTxIds.assign(unionPoolHistory.begin(), unionPoolHistory.end()); unionRequest.lastKnownBlock = lastBlockId; GetPoolResponse unionResponse; unionResponse.isLastKnownBlockActual = false; std::error_code ec = getPoolSymmetricDifferenceSync(std::move(unionRequest), unionResponse); if (ec) { setFutureStateIf(State::idle, [this] { return m_futureState != State::stopped; }); m_observerManager.notify(&IBlockchainSynchronizerObserver::synchronizationCompleted, ec); } else { //get union ok if (!unionResponse.isLastKnownBlockActual) { //bc outdated setFutureState(State::blockchainSync); } else { if (unionPoolHistory == intersectedPoolHistory) { //usual case, start pool processing m_observerManager.notify(&IBlockchainSynchronizerObserver::synchronizationCompleted, processPoolTxs(unionResponse)); } else { GetPoolRequest intersectionRequest; intersectionRequest.knownTxIds.assign(intersectedPoolHistory.begin(), intersectedPoolHistory.end()); intersectionRequest.lastKnownBlock = lastBlockId; GetPoolResponse intersectionResponse; intersectionResponse.isLastKnownBlockActual = false; std::error_code ec2 = getPoolSymmetricDifferenceSync(std::move(intersectionRequest), intersectionResponse); if (ec2) { setFutureStateIf(State::idle, [this] { return m_futureState != State::stopped; }); m_observerManager.notify(&IBlockchainSynchronizerObserver::synchronizationCompleted, ec2); } else { //get intersection ok if (!intersectionResponse.isLastKnownBlockActual) { //bc outdated setFutureState(State::blockchainSync); } else { intersectionResponse.deletedTxIds.assign(unionResponse.deletedTxIds.begin(), unionResponse.deletedTxIds.end()); std::error_code ec3 = processPoolTxs(intersectionResponse); //notify about error, or success m_observerManager.notify(&IBlockchainSynchronizerObserver::synchronizationCompleted, ec3); } } } } } }
void BlockchainSynchronizer::startPoolSync() { GetPoolResponse unionResponse; GetPoolRequest unionRequest = getUnionPoolHistory(); asyncOperationCompleted = std::promise<std::error_code>(); asyncOperationWaitFuture = asyncOperationCompleted.get_future(); unionResponse.isLastKnownBlockActual = false; m_node.getPoolSymmetricDifference(std::move(unionRequest.knownTxIds), std::move(unionRequest.lastKnownBlock), unionResponse.isLastKnownBlockActual, unionResponse.newTxs, unionResponse.deletedTxIds, std::bind(&BlockchainSynchronizer::onGetPoolChanges, this, std::placeholders::_1)); std::error_code ec = asyncOperationWaitFuture.get(); if (ec) { setFutureStateIf(State::idle, std::bind( [](State futureState) -> bool { return futureState != State::stopped; }, std::ref(m_futureState))); m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, ec); } else { //get union ok if (!unionResponse.isLastKnownBlockActual) { //bc outdated setFutureState(State::blockchainSync); } else { if (!shouldSyncConsumersPool) { //usual case, start pool processing m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, processPoolTxs(unionResponse)); } else {// first launch, we should sync consumers' pools, so let's ask for intersection GetPoolResponse intersectionResponse; GetPoolRequest intersectionRequest = getIntersectedPoolHistory(); asyncOperationCompleted = std::promise<std::error_code>(); asyncOperationWaitFuture = asyncOperationCompleted.get_future(); intersectionResponse.isLastKnownBlockActual = false; m_node.getPoolSymmetricDifference(std::move(intersectionRequest.knownTxIds), std::move(intersectionRequest.lastKnownBlock), intersectionResponse.isLastKnownBlockActual, intersectionResponse.newTxs, intersectionResponse.deletedTxIds, std::bind(&BlockchainSynchronizer::onGetPoolChanges, this, std::placeholders::_1)); std::error_code ec2 = asyncOperationWaitFuture.get(); if (ec2) { setFutureStateIf(State::idle, std::bind( [](State futureState) -> bool { return futureState != State::stopped; }, std::ref(m_futureState))); m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, ec2); } else { //get intersection ok if (!intersectionResponse.isLastKnownBlockActual) { //bc outdated setFutureState(State::blockchainSync); } else { intersectionResponse.deletedTxIds.assign(unionResponse.deletedTxIds.begin(), unionResponse.deletedTxIds.end()); std::error_code ec3 = processPoolTxs(intersectionResponse); //notify about error, or success m_observerManager.notify( &IBlockchainSynchronizerObserver::synchronizationCompleted, ec3); if (!ec3) { shouldSyncConsumersPool = false; } } } } } } }