void INodeTrivialRefreshStub::doGetNewBlocks(std::list<crypto::hash> knownBlockIds, std::list<cryptonote::block_complete_entry>& newBlocks, uint64_t& startHeight, const Callback& callback) { auto& blockchain = m_blockchainGenerator.getBlockchain(); startHeight = m_lastHeight; for (; m_lastHeight < blockchain.size(); ++m_lastHeight) { cryptonote::block_complete_entry e; e.block = cryptonote::t_serializable_object_to_blob(blockchain[m_lastHeight]); for (auto hash : blockchain[m_lastHeight].txHashes) { cryptonote::Transaction tx; if (!m_blockchainGenerator.getTransactionByHash(hash, tx)) continue; e.txs.push_back(t_serializable_object_to_blob(tx)); } newBlocks.push_back(e); } m_lastHeight = blockchain.size() - 1; callback(std::error_code()); }
//----------------------------------------------------------------------------------------------- bool core::add_new_tx(const Transaction& tx, tx_verification_context& tvc, bool keeped_by_block) { crypto::hash tx_hash = get_transaction_hash(tx); crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx); blobdata bl; t_serializable_object_to_blob(tx, bl); return add_new_tx(tx, tx_hash, tx_prefix_hash, bl.size(), tvc, keeped_by_block); }
bool get_block_hashing_blob(const Block& b, blobdata& blob) { if (!t_serializable_object_to_blob(static_cast<const BlockHeader&>(b), blob)) { return false; } crypto::hash tree_root_hash = get_tx_tree_hash(b); blob.append(reinterpret_cast<const char*>(&tree_root_hash), sizeof(tree_root_hash)); blob.append(tools::get_varint_data(b.txHashes.size() + 1)); return true; }
bool append_mm_tag_to_extra(std::vector<uint8_t>& tx_extra, const tx_extra_merge_mining_tag& mm_tag) { blobdata blob; if (!t_serializable_object_to_blob(mm_tag, blob)) { return false; } tx_extra.push_back(TX_EXTRA_MERGE_MINING_TAG); std::copy(reinterpret_cast<const uint8_t*>(blob.data()), reinterpret_cast<const uint8_t*>(blob.data() + blob.size()), std::back_inserter(tx_extra)); return true; }
static bool submitBlock(epee::net_utils::http::http_simple_client& client, const std::string& address, const cryptonote::block& block) { cryptonote::COMMAND_RPC_SUBMITBLOCK::request request; request.push_back(epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(block))); cryptonote::COMMAND_RPC_SUBMITBLOCK::response response; bool result = epee::net_utils::invoke_http_json_rpc(address + "/json_rpc", "submitblock", request, response, client); if (!result || (!response.status.empty() && response.status != CORE_RPC_STATUS_OK)) { return false; } return true; }
//------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er) { if(req.transfer_type.compare("all") != 0 && req.transfer_type.compare("available") != 0 && req.transfer_type.compare("unavailable") != 0) { er.code = WALLET_RPC_ERROR_CODE_TRANSFER_TYPE; er.message = "Transfer type must be one of: all, available, or unavailable"; return false; } bool filter = false; bool available = false; if (req.transfer_type.compare("available") == 0) { filter = true; available = true; } else if (req.transfer_type.compare("unavailable") == 0) { filter = true; available = false; } wallet2::transfer_container transfers; m_wallet.get_transfers(transfers); bool transfers_found = false; for (const auto& td : transfers) { if (!filter || available != td.m_spent) { if (!transfers_found) { transfers_found = true; } auto txBlob = t_serializable_object_to_blob(td.m_tx); wallet_rpc::transfer_details rpc_transfers; rpc_transfers.amount = td.amount(); rpc_transfers.spent = td.m_spent; rpc_transfers.global_index = td.m_global_output_index; rpc_transfers.tx_hash = boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(td.m_tx)); rpc_transfers.tx_size = txBlob.size(); res.transfers.push_back(rpc_transfers); } } if (!transfers_found) { return false; } return true; }
void INodeTrivialRefreshStub::doGetNewBlocks(std::list<crypto::hash> knownBlockIds, std::list<cryptonote::block_complete_entry>& newBlocks, uint64_t& startHeight, const Callback& callback) { ContextCounterHolder counterHolder(m_asyncCounter); std::unique_lock<std::mutex> lock(m_multiWalletLock); auto& blockchain = m_blockchainGenerator.getBlockchain(); std::vector<cryptonote::Block>::iterator start = blockchain.end(); for (const auto& id : knownBlockIds) { start = std::find_if(blockchain.begin(), blockchain.end(), [&id](cryptonote::Block& block) { return get_block_hash(block) == id; }); if (start != blockchain.end()) break; } if (start == blockchain.end()) { callback(std::error_code()); return; } m_lastHeight = std::distance(blockchain.begin(), start); startHeight = m_lastHeight; for (; m_lastHeight < blockchain.size(); ++m_lastHeight) { cryptonote::block_complete_entry e; e.block = cryptonote::t_serializable_object_to_blob(blockchain[m_lastHeight]); for (auto hash : blockchain[m_lastHeight].txHashes) { cryptonote::Transaction tx; if (!m_blockchainGenerator.getTransactionByHash(hash, tx)) continue; e.txs.push_back(t_serializable_object_to_blob(tx)); } newBlocks.push_back(e); if (newBlocks.size() >= m_getMaxBlocks) { break; } } m_lastHeight = startHeight + newBlocks.size(); // m_lastHeight = startHeight + blockchain.size() - 1; callback(std::error_code()); }
bool get_block_hash(const Block& b, crypto::hash& res) { blobdata blob; if (!get_block_hashing_blob(b, blob)) { return false; } if (BLOCK_MAJOR_VERSION_2 <= b.majorVersion) { blobdata parent_blob; auto serializer = makeParentBlockSerializer(b, true, false); if (!t_serializable_object_to_blob(serializer, parent_blob)) return false; blob.append(parent_blob); } return get_object_hash(blob, res); }
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; }
//----------------------------------------------------------------------- std::string getAccountAddressAsStr(uint64_t prefix, const AccountPublicAddress& adr) { blobdata blob; bool r = t_serializable_object_to_blob(adr, blob); assert(r); return tools::base58::encode_addr(prefix, blob); }
bool tx_to_blob(const Transaction& tx, blobdata& b_blob) { return t_serializable_object_to_blob(tx, b_blob); }
blobdata tx_to_blob(const Transaction& tx) { return t_serializable_object_to_blob(tx); }
bool block_to_blob(const Block& b, blobdata& b_blob) { return t_serializable_object_to_blob(b, b_blob); }
blobdata block_to_blob(const Block& b) { return t_serializable_object_to_blob(b); }
bool get_parent_block_hashing_blob(const Block& b, blobdata& blob) { auto serializer = makeParentBlockSerializer(b, true, true); return t_serializable_object_to_blob(serializer, blob); }