bool core::handle_incoming_block(const Block& b, block_verification_context& bvc, bool control_miner, bool relay_block) { if (control_miner) { pause_mining(); } m_blockchain_storage.add_new_block(b, bvc); if (control_miner) { update_block_template_and_resume_mining(); } if (relay_block && bvc.m_added_to_main_chain) { std::list<crypto::hash> missed_txs; std::list<Transaction> txs; m_blockchain_storage.get_transactions(b.txHashes, txs, missed_txs); if (!missed_txs.empty() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) { logger(INFO) << "Block added, but it seems that reorganize just happened after that, do not relay this block"; } else { if (!(txs.size() == b.txHashes.size() && missed_txs.empty())) { logger(ERROR, BRIGHT_RED) << "can't find some transactions in found block:" << get_block_hash(b) << " txs.size()=" << txs.size() << ", b.txHashes.size()=" << b.txHashes.size() << ", missed_txs.size()" << missed_txs.size(); return false; } NOTIFY_NEW_BLOCK::request arg; arg.hop = 0; arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height(); bool r = block_to_blob(b, arg.b.block); if (!(r)) { logger(ERROR, BRIGHT_RED) << "failed to serialize block"; return false; } for (auto& tx : txs) { arg.b.txs.push_back(t_serializable_object_to_blob(tx)); } m_pprotocol->relay_block(arg); } } return true; }
//----------------------------------------------------------------------------------------------- bool core::handle_incoming_block(const Block& b, block_verification_context& bvc, bool control_miner, bool relay_block) { if (control_miner) { pause_mining(); } m_blockchain_storage.add_new_block(b, bvc); if (control_miner) { update_block_template_and_resume_mining(); } if (relay_block && bvc.m_added_to_main_chain) { std::list<crypto::hash> missed_txs; std::list<Transaction> txs; m_blockchain_storage.get_transactions(b.txHashes, txs, missed_txs); if (!missed_txs.empty() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) { LOG_PRINT_L0("Block added, but it seems that reorganize just happened after that, do not relay this block"); } else { CHECK_AND_ASSERT_MES(txs.size() == b.txHashes.size() && missed_txs.empty(), false, "can't find some transactions in found block:" << get_block_hash(b) << " txs.size()=" << txs.size() << ", b.txHashes.size()=" << b.txHashes.size() << ", missed_txs.size()" << missed_txs.size()); NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg); arg.hop = 0; arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height(); bool r = block_to_blob(b, arg.b.block); CHECK_AND_ASSERT_MES(r, false, "failed to serialize block"); for (auto& tx : txs) { arg.b.txs.push_back(t_serializable_object_to_blob(tx)); } cryptonote_connection_context exclude_context = boost::value_initialized<cryptonote_connection_context>(); m_pprotocol->relay_block(arg, exclude_context); } } return true; }
bool core::queryBlocks(const std::list<crypto::hash>& knownBlockIds, uint64_t timestamp, uint64_t& resStartHeight, uint64_t& resCurrentHeight, uint64_t& resFullOffset, std::list<BlockFullInfo>& entries) { LockedBlockchainStorage lbs(m_blockchain_storage); uint64_t currentHeight = lbs->get_current_blockchain_height(); uint64_t startOffset = 0; if (!lbs->find_blockchain_supplement(knownBlockIds, startOffset)) { return false; } uint64_t startFullOffset = 0; if (!lbs->getLowerBound(timestamp, startOffset, startFullOffset)) startFullOffset = startOffset; resFullOffset = startFullOffset; if (startOffset != startFullOffset) { std::list<crypto::hash> blockIds; if (!lbs->getBlockIds(startOffset, std::min(uint64_t(BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT), startFullOffset - startOffset), blockIds)) { return false; } for (const auto& id : blockIds) { entries.push_back(BlockFullInfo()); entries.back().block_id = id; } } auto blocksLeft = std::min(BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT - entries.size(), size_t(BLOCKS_SYNCHRONIZING_DEFAULT_COUNT)); if (blocksLeft) { std::list<Block> blocks; lbs->get_blocks(startFullOffset, blocksLeft, blocks); for (auto& b : blocks) { BlockFullInfo item; item.block_id = get_block_hash(b); if (b.timestamp >= timestamp) { // query transactions std::list<Transaction> txs; std::list<crypto::hash> missedTxs; lbs->get_transactions(b.txHashes, txs, missedTxs); // fill data block_complete_entry& completeEntry = item; completeEntry.block = block_to_blob(b); for (auto& tx : txs) { completeEntry.txs.push_back(tx_to_blob(tx)); } } entries.push_back(std::move(item)); } } resCurrentHeight = currentHeight; resStartHeight = startOffset; return true; }