diff options
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r-- | src/wallet/wallet2.cpp | 137 |
1 files changed, 63 insertions, 74 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5ab1ff85e..81472687d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -846,6 +846,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s td.m_key_image = ki[o]; td.m_key_image_known = !m_watch_only; td.m_amount = tx.vout[o].amount; + td.m_pk_index = pk_index - 1; if (td.m_amount == 0) { td.m_mask = mask[o]; @@ -894,6 +895,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s td.m_tx = (const cryptonote::transaction_prefix&)tx; td.m_txid = txid(); td.m_amount = tx.vout[o].amount; + td.m_pk_index = pk_index - 1; if (td.m_amount == 0) { td.m_mask = mask[o]; @@ -1573,35 +1575,12 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re std::list<cryptonote::block_complete_entry> blocks; std::vector<COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> o_indices; - std::string daemon_height_err = ""; - uint64_t daemon_bc_height = get_daemon_blockchain_height(daemon_height_err); - if(daemon_height_err.size() > 0) { - throw std::runtime_error(daemon_height_err); - } - // pull the first set of blocks get_short_chain_history(short_chain_history); m_run.store(true, std::memory_order_relaxed); if (start_height > m_blockchain.size() || m_refresh_from_block_height > m_blockchain.size()) { - - // even target_height can be zero if the daemon just started and hasn't gotten some sync - // data back from peers .. hmmm, what to do ... O.o (you can see him thinking) - // i'm going with infiniti loop until i get something bigger than zero or err ... moneromoo don't kill me - std::string daemon_target_err = ""; - uint64_t daemon_target_height = 0; - - while(daemon_target_height == 0) - { - daemon_target_height = get_daemon_blockchain_target_height(daemon_target_err); - if(daemon_target_err.size() > 0) { - daemon_target_height = get_approximate_blockchain_height(); // - x? - } - } - - if (m_refresh_from_block_height > daemon_target_height) m_refresh_from_block_height = daemon_target_height - 1; - if (!start_height) start_height = m_refresh_from_block_height; - if (start_height >= daemon_bc_height) start_height = daemon_bc_height - 1; - + if (!start_height) + start_height = m_refresh_from_block_height; // we can shortcut by only pulling hashes up to the start_height fast_refresh(start_height, blocks_start_height, short_chain_history); // regenerate the history now that we've got a full set of hashes @@ -1611,56 +1590,53 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re // and then fall through to regular refresh processing } - if(!(m_refresh_from_block_height >= daemon_bc_height)) - { - pull_blocks(start_height, blocks_start_height, short_chain_history, blocks, o_indices); - // always reset start_height to 0 to force short_chain_ history to be used on - // subsequent pulls in this refresh. - start_height = 0; + pull_blocks(start_height, blocks_start_height, short_chain_history, blocks, o_indices); + // always reset start_height to 0 to force short_chain_ history to be used on + // subsequent pulls in this refresh. + start_height = 0; - while(m_run.load(std::memory_order_relaxed)) + while(m_run.load(std::memory_order_relaxed)) + { + try { - try - { - // pull the next set of blocks while we're processing the current one - uint64_t next_blocks_start_height; - std::list<cryptonote::block_complete_entry> next_blocks; - std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> next_o_indices; - bool error = false; - pull_thread = boost::thread([&]{pull_next_blocks(start_height, next_blocks_start_height, short_chain_history, blocks, next_blocks, next_o_indices, error);}); - - process_blocks(blocks_start_height, blocks, o_indices, added_blocks); - blocks_fetched += added_blocks; - pull_thread.join(); - if(!added_blocks) - break; + // pull the next set of blocks while we're processing the current one + uint64_t next_blocks_start_height; + std::list<cryptonote::block_complete_entry> next_blocks; + std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> next_o_indices; + bool error = false; + pull_thread = boost::thread([&]{pull_next_blocks(start_height, next_blocks_start_height, short_chain_history, blocks, next_blocks, next_o_indices, error);}); + + process_blocks(blocks_start_height, blocks, o_indices, added_blocks); + blocks_fetched += added_blocks; + pull_thread.join(); + if(!added_blocks) + break; - // switch to the new blocks from the daemon - blocks_start_height = next_blocks_start_height; - blocks = next_blocks; - o_indices = next_o_indices; + // switch to the new blocks from the daemon + blocks_start_height = next_blocks_start_height; + blocks = next_blocks; + o_indices = next_o_indices; - // handle error from async fetching thread - if (error) - { - throw std::runtime_error("proxy exception in refresh thread"); - } + // handle error from async fetching thread + if (error) + { + throw std::runtime_error("proxy exception in refresh thread"); } - catch (const std::exception&) + } + catch (const std::exception&) + { + blocks_fetched += added_blocks; + if (pull_thread.joinable()) + pull_thread.join(); + if(try_count < 3) { - blocks_fetched += added_blocks; - if (pull_thread.joinable()) - pull_thread.join(); - if(try_count < 3) - { - LOG_PRINT_L1("Another try pull_blocks (try_count=" << try_count << ")..."); - ++try_count; - } - else - { - LOG_ERROR("pull_blocks failed, try_count=" << try_count); - throw; - } + LOG_PRINT_L1("Another try pull_blocks (try_count=" << try_count << ")..."); + ++try_count; + } + else + { + LOG_ERROR("pull_blocks failed, try_count=" << try_count); + throw; } } } @@ -3623,7 +3599,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent real_oe.second.dest = rct::pk2rct(boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key); real_oe.second.mask = rct::commit(td.amount(), td.m_mask); *it_to_replace = real_oe; - src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx); + src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx, td.m_pk_index); src.real_output = it_to_replace - src.outputs.begin(); src.real_output_in_tx_index = td.m_internal_output_index; detail::print_source_entry(src); @@ -3699,6 +3675,9 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry uint64_t upper_transaction_size_limit = get_upper_tranaction_size_limit(); uint64_t needed_money = fee; LOG_PRINT_L2("transfer: starting with fee " << print_money (needed_money)); + LOG_PRINT_L0("selected transfers: "); + for (auto t: selected_transfers) + LOG_PRINT_L2(" " << t); // calculate total amount being sent to all destinations // throw if total amount overflows uint64_t @@ -3759,7 +3738,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry real_oe.second.dest = rct::pk2rct(boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key); real_oe.second.mask = rct::commit(td.amount(), td.m_mask); *it_to_replace = real_oe; - src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx); + src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx, td.m_pk_index); src.real_output = it_to_replace - src.outputs.begin(); src.real_output_in_tx_index = td.m_internal_output_index; src.mask = td.m_mask; @@ -3770,12 +3749,22 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry // we still keep a copy, since we want to keep dsts free of change for user feedback purposes std::vector<cryptonote::tx_destination_entry> splitted_dsts = dsts; cryptonote::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts); - if (needed_money < found_money) + change_dts.amount = found_money - needed_money; + if (change_dts.amount == 0) + { + // If the change is 0, send it to a random address, to avoid confusing + // the sender with a 0 amount output. We send a 0 amount in order to avoid + // letting the destination be able to work out which of the inputs is the + // real one in our rings + cryptonote::account_base dummy; + dummy.generate(); + change_dts.addr = dummy.get_keys().m_account_address; + } + else { change_dts.addr = m_account.get_keys().m_account_address; - change_dts.amount = found_money - needed_money; - splitted_dsts.push_back(change_dts); } + splitted_dsts.push_back(change_dts); crypto::secret_key tx_key; bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), sources, splitted_dsts, extra, tx, unlock_time, tx_key, true); |