diff options
Diffstat (limited to 'src')
27 files changed, 145 insertions, 86 deletions
diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index a9a7d035f..5e12fa8ec 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -287,7 +287,7 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck num_rct_outs += blk.miner_tx.vout.size(); int tx_i = 0; crypto::hash tx_hash = crypto::null_hash; - for (const std::pair<transaction, blobdata_ref>& tx : txs) + for (const std::pair<transaction, blobdata>& tx : txs) { tx_hash = blk.tx_hashes[tx_i]; add_transaction(blk_hash, tx, &tx_hash); diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 0aa2aee6f..5f3b495b0 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -897,7 +897,6 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons throw0(DB_ERROR(lmdb_error("Failed to add tx data to db transaction: ", result).c_str())); const cryptonote::blobdata_ref &blob = txp.second; - MDB_val_sized(blobval, blob); unsigned int unprunable_size = tx.unprunable_size; if (unprunable_size == 0) @@ -3190,9 +3189,8 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou uint64_t size = 0; size_t num_txes = 0; MDB_val_copy<uint64_t> key(start_height); - MDB_val k, v, val_tx_id; + MDB_val v, val_tx_id; uint64_t tx_id = ~0; - MDB_cursor_op op = MDB_SET; for (uint64_t h = start_height; h < blockchain_height && blocks.size() < max_block_count && (size < max_size || blocks.size() < min_block_count); ++h) { MDB_cursor_op op = h == start_height ? MDB_SET : MDB_NEXT; @@ -3314,7 +3312,7 @@ bool BlockchainLMDB::get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::h RCURSOR(txs_prunable_hash); MDB_val_set(v, tx_hash); - MDB_val result, val_tx_prunable_hash; + MDB_val result; auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH); if (get_result == 0) { @@ -4311,7 +4309,6 @@ bool BlockchainLMDB::get_output_distribution(uint64_t amount, uint64_t from_heig return false; distribution.resize(db_height - from_height, 0); - bool fret = true; MDB_val_set(k, amount); MDB_val v; MDB_cursor_op op = MDB_SET; @@ -5106,11 +5103,10 @@ void BlockchainLMDB::migrate_0_1() void BlockchainLMDB::migrate_1_2() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - uint64_t i, z; + uint64_t i; int result; mdb_txn_safe txn(false); - MDB_val k, v; - char *ptr; + MDB_val v; MGINFO_YELLOW("Migrating blockchain from DB version 1 to 2 - this may take a while:"); MINFO("updating txs_pruned and txs_prunable tables..."); @@ -5311,7 +5307,6 @@ void BlockchainLMDB::migrate_2_3() if (result) throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_info: ", result).c_str())); if (!i) { - MDB_stat db_stat; result = mdb_stat(txn, m_block_info, &db_stats); if (result) throw0(DB_ERROR(lmdb_error("Failed to query m_block_info: ", result).c_str())); @@ -5443,7 +5438,6 @@ void BlockchainLMDB::migrate_3_4() if (result) throw0(DB_ERROR(lmdb_error("Failed to open a cursor for blocks: ", result).c_str())); if (!i) { - MDB_stat db_stat; result = mdb_stat(txn, m_block_info, &db_stats); if (result) throw0(DB_ERROR(lmdb_error("Failed to query m_block_info: ", result).c_str())); @@ -5597,7 +5591,6 @@ void BlockchainLMDB::migrate_4_5() if (result) throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_info: ", result).c_str())); if (!i) { - MDB_stat db_stat; result = mdb_stat(txn, m_block_info, &db_stats); if (result) throw0(DB_ERROR(lmdb_error("Failed to query m_block_info: ", result).c_str())); diff --git a/src/blockchain_utilities/blockchain_ancestry.cpp b/src/blockchain_utilities/blockchain_ancestry.cpp index 89b932e4f..b1b238427 100644 --- a/src/blockchain_utilities/blockchain_ancestry.cpp +++ b/src/blockchain_utilities/blockchain_ancestry.cpp @@ -149,7 +149,7 @@ struct ancestry_state_t { std::unordered_map<crypto::hash, cryptonote::transaction> old_tx_cache; a & old_tx_cache; - for (const auto i: old_tx_cache) + for (const auto& i: old_tx_cache) tx_cache.insert(std::make_pair(i.first, ::tx_data_t(i.second))); } else @@ -161,7 +161,7 @@ struct ancestry_state_t std::unordered_map<uint64_t, cryptonote::block> old_block_cache; a & old_block_cache; block_cache.resize(old_block_cache.size()); - for (const auto i: old_block_cache) + for (const auto& i: old_block_cache) block_cache[i.first] = i.second; } else @@ -575,7 +575,6 @@ int main(int argc, char* argv[]) { add_ancestry(state.ancestry, txid, ancestor{amount, offset}); // find the tx which created this output - bool found = false; crypto::hash output_txid; if (!get_output_txid(state, db, amount, offset, output_txid)) { @@ -693,7 +692,6 @@ int main(int argc, char* argv[]) add_ancestor(ancestry, amount, offset); // find the tx which created this output - bool found = false; crypto::hash output_txid; if (!get_output_txid(state, db, amount, offset, output_txid)) { diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp index a8197483f..e439895bf 100644 --- a/src/blockchain_utilities/blockchain_blackball.cpp +++ b/src/blockchain_utilities/blockchain_blackball.cpp @@ -47,9 +47,6 @@ namespace po = boost::program_options; using namespace epee; using namespace cryptonote; -static const char zerokey[8] = {0}; -static const MDB_val zerokval = { sizeof(zerokey), (void *)zerokey }; - static uint64_t records_per_sync = 200; static uint64_t db_flags = 0; static MDB_dbi dbi_relative_rings; @@ -703,7 +700,6 @@ static void get_per_amount_outputs(MDB_txn *txn, uint64_t amount, uint64_t &tota int dbr = mdb_cursor_open(txn, dbi_per_amount, &cur); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open cursor for per amount outputs: " + std::string(mdb_strerror(dbr))); MDB_val k, v; - mdb_size_t count = 0; k.mv_size = sizeof(uint64_t); k.mv_data = (void*)&amount; dbr = mdb_cursor_get(cur, &k, &v, MDB_SET); @@ -726,7 +722,6 @@ static void inc_per_amount_outputs(MDB_txn *txn, uint64_t amount, uint64_t total int dbr = mdb_cursor_open(txn, dbi_per_amount, &cur); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open cursor for per amount outputs: " + std::string(mdb_strerror(dbr))); MDB_val k, v; - mdb_size_t count = 0; k.mv_size = sizeof(uint64_t); k.mv_data = (void*)&amount; dbr = mdb_cursor_get(cur, &k, &v, MDB_SET); @@ -1077,7 +1072,6 @@ static std::vector<std::pair<uint64_t, uint64_t>> load_outputs(const std::string s[len - 1] = 0; if (!s[0]) continue; - std::pair<uint64_t, uint64_t> output; uint64_t offset, num_offsets; if (sscanf(s, "@%" PRIu64, &amount) == 1) { @@ -1269,8 +1263,6 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Scanning for spent outputs..."); - size_t done = 0; - const uint64_t start_blackballed_outputs = get_num_spent_outputs(); tools::ringdb ringdb(output_file_path.string(), epee::string_tools::pod_to_hex(get_genesis_block_hash(inputs[0]))); diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 60c069c3b..df2662444 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -227,7 +227,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path return false; } - uint64_t block_first, block_last; + uint64_t block_first; uint64_t start_height = 1, seek_height; if (opt_resume) start_height = core.get_blockchain_storage().get_current_blockchain_height(); diff --git a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp index f8763710e..1a54778a7 100644 --- a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp +++ b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp @@ -66,7 +66,6 @@ static std::map<uint64_t, uint64_t> load_outputs(const std::string &filename) s[len - 1] = 0; if (!s[0]) continue; - std::pair<uint64_t, uint64_t> output; uint64_t offset, num_offsets; if (sscanf(s, "@%" PRIu64, &amount) == 1) { diff --git a/src/blockchain_utilities/blockchain_usage.cpp b/src/blockchain_utilities/blockchain_usage.cpp index 6e87a0974..095e6c503 100644 --- a/src/blockchain_utilities/blockchain_usage.cpp +++ b/src/blockchain_utilities/blockchain_usage.cpp @@ -180,7 +180,6 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Building usage patterns..."); - size_t done = 0; std::unordered_map<output_data, std::list<reference>> outputs; std::unordered_map<uint64_t,uint64_t> indices; @@ -195,7 +194,7 @@ int main(int argc, char* argv[]) { if (opt_rct_only && out.amount) continue; - uint64_t index = indices[out.amount]++; + indices[out.amount]++; output_data od(out.amount, indices[out.amount], coinbase, height); auto itb = outputs.emplace(od, std::list<reference>()); itb.first->first.info(coinbase, height); diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index fcc96883b..1ef6590eb 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -104,7 +104,6 @@ namespace cryptonote uint64_t get_transaction_weight_clawback(const transaction &tx, size_t n_padded_outputs) { - const rct::rctSig &rv = tx.rct_signatures; const uint64_t bp_base = 368; const size_t n_outputs = tx.vout.size(); if (n_padded_outputs <= 2) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 8ec624254..cdad39a2c 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -973,7 +973,7 @@ start: std::pair<bool, uint64_t> Blockchain::check_difficulty_checkpoints() const { uint64_t res = 0; - for (const std::pair<uint64_t, difficulty_type>& i : m_checkpoints.get_difficulty_points()) + for (const std::pair<const uint64_t, difficulty_type>& i : m_checkpoints.get_difficulty_points()) { if (i.first >= m_db->height()) break; @@ -3438,7 +3438,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, bool failed = false; for (size_t i = 0; i < tx.vin.size(); i++) { - const txin_to_key& in_to_key = boost::get<txin_to_key>(tx.vin[i]); if(!failed && !results[i]) failed = true; } diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 12125fb9d..57104fd59 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -630,7 +630,7 @@ namespace cryptonote void operator()(std::uint64_t, epee::span<const block> blocks) const { - for (const block bl : blocks) + for (const block& bl : blocks) cmdline.notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bl)).c_str(), NULL); } }; diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index d059ab78f..a7e96e23a 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -383,7 +383,6 @@ namespace cryptonote bool tx_memory_pool::add_tx(transaction &tx, tx_verification_context& tvc, relay_method tx_relay, bool relayed, uint8_t version) { crypto::hash h = null_hash; - size_t blob_size = 0; cryptonote::blobdata bl; t_serializable_object_to_blob(tx, bl); if (bl.size() == 0 || !get_transaction_hash(tx, h)) @@ -1041,7 +1040,6 @@ namespace cryptonote return true; }, true, category); - txpool_tx_meta_t meta; for (const key_images_container::value_type& kee : m_spent_key_images) { const crypto::key_image& k_image = kee.first; const std::unordered_set<crypto::hash>& kei_image_set = kee.second; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 71d09d08c..c798dbcdb 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1845,10 +1845,8 @@ skip: bool t_cryptonote_protocol_handler<t_core>::should_download_next_span(cryptonote_connection_context& context, bool standby) { std::vector<crypto::hash> hashes; - boost::uuids::uuid span_connection_id; boost::posix_time::ptime request_time; boost::uuids::uuid connection_id; - std::pair<uint64_t, uint64_t> span; bool filled; const uint64_t blockchain_height = m_core.get_current_blockchain_height(); @@ -1874,7 +1872,6 @@ skip: // in standby, be ready to double download early since we're idling anyway // let the fastest peer trigger first - long threshold; const double dl_speed = context.m_max_speed_down; if (standby && dt >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY && dl_speed > 0) { diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 5a7d4dd4e..8194fe642 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1059,7 +1059,6 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash, // Print json if requested if (include_json) { - crypto::hash tx_hash, tx_prefix_hash; cryptonote::transaction tx; cryptonote::blobdata blob; std::string source = as_hex.empty() ? pruned_as_hex + prunable_as_hex : as_hex; diff --git a/src/device/device_io_hid.cpp b/src/device/device_io_hid.cpp index 7c61c3b1a..7aa5b39bf 100644 --- a/src/device/device_io_hid.cpp +++ b/src/device/device_io_hid.cpp @@ -181,7 +181,6 @@ namespace hw { unsigned char padding_buffer[MAX_BLOCK+1]; unsigned int result; int hid_ret; - unsigned int sw_offset; unsigned int remaining; unsigned int offset = 0; diff --git a/src/gen_multisig/gen_multisig.cpp b/src/gen_multisig/gen_multisig.cpp index 15f7e5c0a..4aa21b149 100644 --- a/src/gen_multisig/gen_multisig.cpp +++ b/src/gen_multisig/gen_multisig.cpp @@ -74,8 +74,6 @@ namespace const command_line::arg_descriptor<bool, false> arg_testnet = {"testnet", genms::tr("Create testnet multisig wallets"), false}; const command_line::arg_descriptor<bool, false> arg_stagenet = {"stagenet", genms::tr("Create stagenet multisig wallets"), false}; const command_line::arg_descriptor<bool, false> arg_create_address_file = {"create-address-file", genms::tr("Create an address file for new wallets"), false}; - - const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""}; } static bool generate_multisig(uint32_t threshold, uint32_t total, const std::string &basename, network_type nettype, bool create_address_file) diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index bda18d950..b6bc22a3d 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -194,7 +194,6 @@ namespace { epee::wipeable_string trimmed_words = "", word; - const auto &word_map = language->get_word_map(); const auto &trimmed_word_map = language->get_trimmed_word_map(); const uint32_t unique_prefix_length = language->get_unique_prefix_length(); for (std::vector<epee::wipeable_string>::const_iterator it = word_list.begin(); it != word_list.end(); it++) diff --git a/src/net/socks.cpp b/src/net/socks.cpp index 3463f452c..c2330bd41 100644 --- a/src/net/socks.cpp +++ b/src/net/socks.cpp @@ -48,7 +48,6 @@ namespace socks { namespace { - constexpr const unsigned v4_reply_size = 8; constexpr const std::uint8_t v4_connect_command = 1; constexpr const std::uint8_t v4tor_resolve_command = 0xf0; constexpr const std::uint8_t v4_request_granted = 90; diff --git a/src/ringct/multiexp.cc b/src/ringct/multiexp.cc index f69b4a12c..620f7d0dd 100644 --- a/src/ringct/multiexp.cc +++ b/src/ringct/multiexp.cc @@ -372,7 +372,6 @@ std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<Multiexp if (N == 0) N = data.size(); CHECK_AND_ASSERT_THROW_MES(N <= data.size(), "Bad cache base data"); - ge_cached cached; ge_p1p1 p1; ge_p3 p3; std::shared_ptr<straus_cached_data> cache(new straus_cached_data()); @@ -454,7 +453,6 @@ rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<str std::shared_ptr<straus_cached_data> local_cache = cache == NULL ? straus_init_cache(data) : cache; ge_cached cached; ge_p1p1 p1; - ge_p3 p3; #ifdef TRACK_STRAUS_ZERO_IDENTITY MULTIEXP_PERF(PERF_TIMER_START_UNIT(skip, 1000000)); @@ -587,7 +585,6 @@ std::shared_ptr<pippenger_cached_data> pippenger_init_cache(const std::vector<Mu if (N == 0) N = data.size() - start_offset; CHECK_AND_ASSERT_THROW_MES(N <= data.size() - start_offset, "Bad cache base data"); - ge_cached cached; std::shared_ptr<pippenger_cached_data> cache(new pippenger_cached_data()); cache->size = N; diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 93eb52d4e..f5950c53c 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -725,7 +725,6 @@ namespace rct { CHECK_AND_ASSERT_THROW_MES((kLRki && mscout) || (!kLRki && !mscout), "Only one of kLRki/mscout is present"); keyV tmp(rows + 1); keyV sk(rows + 1); - size_t i; keyM M(cols, tmp); keyV P, C, C_nonzero; @@ -899,7 +898,6 @@ namespace rct { key R; geDsmp P_precomp; geDsmp C_precomp; - geDsmp H_precomp; size_t i = 0; ge_p3 hash8_p3; geDsmp hash_precomp; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index db228dd94..2bb4969e9 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -367,7 +367,6 @@ namespace cryptonote message = "Client signature does not verify for " + rpc; return false; } - crypto::public_key local_client; if (!m_rpc_payment->pay(client, ts, payment, rpc, same_ts, credits)) { message = CORE_RPC_STATUS_PAYMENT_REQUIRED; @@ -1806,7 +1805,6 @@ namespace cryptonote return false; } } - uint64_t seed_height; crypto::hash seed_hash, next_seed_hash; if (!get_block_template(info.address, req.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, b, res.seed_height, seed_hash, next_seed_hash, error_resp)) return false; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 594d79a13..2a3c33f48 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -282,6 +282,7 @@ namespace const char* USAGE_VERSION("version"); const char* USAGE_HELP("help [<command> | all]"); const char* USAGE_APROPOS("apropos <keyword> [<keyword> ...]"); + const char* USAGE_SCAN_TX("scan_tx <txid> [<txid> ...]"); std::string input_line(const std::string& prompt, bool yesno = false) { @@ -1360,7 +1361,7 @@ bool simple_wallet::import_multisig_main(const std::vector<std::string> &args, b size_t n_outputs = m_wallet->import_multisig(info); // Clear line "Height xxx of xxx" std::cout << "\r \r"; - success_msg_writer() << tr("Multisig info imported"); + success_msg_writer() << tr("Multisig info imported. Number of outputs updated: ") << n_outputs; } catch (const std::exception &e) { @@ -3214,6 +3215,45 @@ bool simple_wallet::apropos(const std::vector<std::string> &args) return true; } +bool simple_wallet::scan_tx(const std::vector<std::string> &args) +{ + if (args.empty()) + { + PRINT_USAGE(USAGE_SCAN_TX); + return true; + } + + // Parse and dedup args + std::unordered_set<crypto::hash> txids; + for (const auto &s : args) { + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(s, txid)) { + fail_msg_writer() << tr("Invalid txid specified: ") << s; + return true; + } + txids.insert(txid); + } + std::vector<crypto::hash> txids_v(txids.begin(), txids.end()); + + if (!m_wallet->is_trusted_daemon()) { + message_writer(console_color_red, true) << tr("WARNING: this operation may reveal the txids to the remote node and affect your privacy"); + if (!command_line::is_yes(input_line("Do you want to continue?", true))) { + message_writer() << tr("You have canceled the operation"); + return true; + } + } + + LOCK_IDLE_SCOPE(); + m_in_manual_refresh.store(true); + try { + m_wallet->scan_tx(txids_v); + } catch (const std::exception &e) { + fail_msg_writer() << e.what(); + } + m_in_manual_refresh.store(false); + return true; +} + simple_wallet::simple_wallet() : m_allow_mismatched_daemon_version(false) , m_refresh_progress_reporter(*this) @@ -3764,6 +3804,10 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::on_command, this, &simple_wallet::apropos, _1), tr(USAGE_APROPOS), tr("Search all command descriptions for keyword(s)")); + m_cmd_binder.set_handler("scan_tx", + boost::bind(&simple_wallet::on_command, this, &simple_wallet::scan_tx, _1), + tr(USAGE_SCAN_TX), + tr("Scan the transactions given by <txid>(s), processing them and looking for outputs")); m_cmd_binder.set_unknown_command_handler(boost::bind(&simple_wallet::on_command, this, &simple_wallet::on_unknown_command, _1)); m_cmd_binder.set_empty_command_handler(boost::bind(&simple_wallet::on_empty_command, this)); m_cmd_binder.set_cancel_handler(boost::bind(&simple_wallet::on_cancelled_command, this)); @@ -4520,7 +4564,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) password = *r; welcome = true; // if no block_height is specified, assume its a new account and start it "now" - if(m_wallet->get_refresh_from_block_height() == 0) { + if (command_line::is_arg_defaulted(vm, arg_restore_height)) { { tools::scoped_message_writer wrt = tools::msg_writer(); wrt << tr("No restore height is specified.") << " "; @@ -5938,7 +5982,7 @@ bool simple_wallet::show_balance_unlocked(bool detailed) if (m_wallet->has_multisig_partial_key_images()) extra = tr(" (Some owned outputs have partial key images - import_multisig_info needed)"); else if (m_wallet->has_unknown_key_images()) - extra += tr(" (Some owned outputs have missing key images - import_key_images needed)"); + extra += tr(" (Some owned outputs have missing key images - export_outputs, import_outputs, export_key_images, and import_key_images needed)"); success_msg_writer() << tr("Currently selected account: [") << m_current_subaddress_account << tr("] ") << m_wallet->get_subaddress_label({m_current_subaddress_account, 0}); const std::string tag = m_wallet->get_account_tags().second[m_current_subaddress_account]; success_msg_writer() << tr("Tag: ") << (tag.empty() ? std::string{tr("(No tag assigned)")} : tag); @@ -6469,8 +6513,6 @@ void simple_wallet::check_for_inactivity_lock(bool user) //---------------------------------------------------------------------------------------------------- bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector<std::string>&), const std::vector<std::string> &args) { - const time_t now = time(NULL); - time_t dt = now - m_last_activity_time; m_last_activity_time = time(NULL); m_in_command = true; @@ -7436,7 +7478,6 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_) if (local_args.size() == 3) { crypto::hash payment_id; - crypto::hash8 payment_id8; std::string extra_nonce; if (tools::wallet2::parse_long_payment_id(local_args.back(), payment_id)) { @@ -8616,7 +8657,6 @@ bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vec if (!unlocked) { locked_msg = "locked"; - const uint64_t unlock_time = pd.m_unlock_time; if (pd.m_unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) { uint64_t bh = std::max(pd.m_unlock_time, pd.m_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE); @@ -9481,7 +9521,7 @@ void simple_wallet::print_accounts() { const std::pair<std::map<std::string, std::string>, std::vector<std::string>>& account_tags = m_wallet->get_account_tags(); size_t num_untagged_accounts = m_wallet->get_num_subaddress_accounts(); - for (const std::pair<std::string, std::string>& p : account_tags.first) + for (const std::pair<const std::string, std::string>& p : account_tags.first) { const std::string& tag = p.first; print_accounts(tag); @@ -11195,7 +11235,6 @@ void simple_wallet::mms_next(const std::vector<std::string> &args) void simple_wallet::mms_sync(const std::vector<std::string> &args) { - mms::message_store& ms = m_wallet->get_message_store(); if (args.size() != 0) { fail_msg_writer() << tr("Usage: mms sync"); @@ -11293,7 +11332,6 @@ void simple_wallet::mms_export(const std::vector<std::string> &args) return; } LOCK_IDLE_SCOPE(); - mms::message_store& ms = m_wallet->get_message_store(); mms::message m; bool valid_id = get_message_from_arg(args[0], m); if (valid_id) @@ -11362,7 +11400,6 @@ void simple_wallet::mms_show(const std::vector<std::string> &args) return; } LOCK_IDLE_SCOPE(); - mms::message_store& ms = m_wallet->get_message_store(); mms::message m; bool valid_id = get_message_from_arg(args[0], m); if (valid_id) @@ -11668,4 +11705,3 @@ bool simple_wallet::mms(const std::vector<std::string> &args) return true; } // End MMS ------------------------------------------------------------------------------------------------ - diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 61104c87f..af654e0dd 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -158,6 +158,7 @@ namespace cryptonote bool set_credits_target(const std::vector<std::string> &args = std::vector<std::string>()); bool help(const std::vector<std::string> &args = std::vector<std::string>()); bool apropos(const std::vector<std::string> &args); + bool scan_tx(const std::vector<std::string> &args); bool start_mining(const std::vector<std::string> &args); bool stop_mining(const std::vector<std::string> &args); bool set_daemon(const std::vector<std::string> &args); diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index 303b576c7..87cb75fbf 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -1340,7 +1340,10 @@ bool message_store::check_for_messages(const multisig_wallet_state &state, std:: } } std::vector<transport_message> transport_messages; - bool r = m_transporter.receive_messages(destinations, transport_messages); + if (!m_transporter.receive_messages(destinations, transport_messages)) + { + return false; + } if (!m_run.load(std::memory_order_relaxed)) { // Stop was called, don't waste time processing the messages diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp index dfeb987ca..025a2037f 100644 --- a/src/wallet/ringdb.cpp +++ b/src/wallet/ringdb.cpp @@ -42,9 +42,6 @@ #define V1TAG ((uint64_t)798237759845202) -static const char zerokey[8] = {0}; -static const MDB_val zerokeyval = { sizeof(zerokey), (void *)zerokey }; - static int compare_hash32(const MDB_val *a, const MDB_val *b) { uint32_t *va = (uint32_t*) a->mv_data; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index aef9eaded..e298eca53 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -30,6 +30,7 @@ #include <numeric> #include <tuple> +#include <queue> #include <boost/format.hpp> #include <boost/optional/optional.hpp> #include <boost/algorithm/string/classification.hpp> @@ -344,8 +345,6 @@ std::string get_weight_string(const cryptonote::transaction &tx, size_t blob_siz std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { - namespace ip = boost::asio::ip; - const bool testnet = command_line::get_arg(vm, opts.testnet); const bool stagenet = command_line::get_arg(vm, opts.stagenet); const network_type nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET; @@ -367,7 +366,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl // user specified CA file or fingeprints implies enabled SSL by default epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled; - if (command_line::get_arg(vm, opts.daemon_ssl_allow_any_cert)) + if (daemon_ssl_allow_any_cert) ssl_options.verification = epee::net_utils::ssl_verification_t::none; else if (!daemon_ssl_ca_file.empty() || !daemon_ssl_allowed_fingerprints.empty()) { @@ -1004,9 +1003,6 @@ bool get_pruned_tx(const cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry &entry, namespace tools { -// for now, limit to 30 attempts. TODO: discuss a good number to limit to. -const size_t MAX_SPLIT_ATTEMPTS = 30; - constexpr const std::chrono::seconds wallet2::rpc_timeout; const char* wallet2::tr(const char* str) { return i18n_translate(str, "tools::wallet2"); } @@ -1602,6 +1598,47 @@ std::string wallet2::get_subaddress_label(const cryptonote::subaddress_index& in return m_subaddress_labels[index.major][index.minor]; } //---------------------------------------------------------------------------------------------------- +void wallet2::scan_tx(const std::vector<crypto::hash> &txids) +{ + // Get the transactions from daemon in batches and add them to a priority queue ordered in chronological order + auto cmp_tx_entry = [](const cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry& l, const cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry& r) + { return l.block_height > r.block_height; }; + + std::priority_queue<cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry, std::vector<COMMAND_RPC_GET_TRANSACTIONS::entry>, decltype(cmp_tx_entry)> txq(cmp_tx_entry); + const size_t SLICE_SIZE = 100; // RESTRICTED_TRANSACTIONS_COUNT as defined in rpc/core_rpc_server.cpp, hardcoded in daemon code + for(size_t slice = 0; slice < txids.size(); slice += SLICE_SIZE) { + cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req = AUTO_VAL_INIT(req); + cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res = AUTO_VAL_INIT(res); + req.decode_as_json = false; + req.prune = true; + + size_t ntxes = slice + SLICE_SIZE > txids.size() ? txids.size() - slice : SLICE_SIZE; + for (size_t i = slice; i < slice + ntxes; ++i) + req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txids[i])); + + { + const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex}; + req.client = get_client_signature(); + bool r = epee::net_utils::invoke_http_json("/gettransactions", req, res, *m_http_client, rpc_timeout); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to get transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(res.txs.size() != req.txs_hashes.size(), error::wallet_internal_error, "Failed to get transaction from daemon"); + } + + for (auto& tx_info : res.txs) + txq.push(tx_info); + } + + // Process the transactions in chronologically ascending order + while(!txq.empty()) { + auto& tx_info = txq.top(); + cryptonote::transaction tx; + crypto::hash tx_hash; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(tx_info, tx, tx_hash), error::wallet_internal_error, "Failed to get transaction from daemon (2)"); + process_new_transaction(tx_hash, tx, tx_info.output_indices, tx_info.block_height, 0, tx_info.block_timestamp, false, tx_info.in_pool, tx_info.double_spend_seen, {}, {}); + txq.pop(); + } +} +//---------------------------------------------------------------------------------------------------- void wallet2::set_subaddress_label(const cryptonote::subaddress_index& index, const std::string &label) { THROW_WALLET_EXCEPTION_IF(index.major >= m_subaddress_labels.size(), error::account_index_outofbound); @@ -7992,7 +8029,6 @@ void wallet2::light_wallet_get_outs(std::vector<std::vector<tools::wallet2::get_ // Check if we got enough outputs for each amount for(auto& out: ores.amount_outs) { - const uint64_t out_amount = boost::lexical_cast<uint64_t>(out.amount); THROW_WALLET_EXCEPTION_IF(out.outputs.size() < light_wallet_requested_outputs_count , error::wallet_internal_error, "Not enough outputs for amount: " + boost::lexical_cast<std::string>(out.amount)); MDEBUG(out.outputs.size() << " outputs for amount "+ boost::lexical_cast<std::string>(out.amount) + " received from light wallet node"); } @@ -9786,13 +9822,18 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp TX() : weight(0), needed_fee(0) {} - void add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations) { + /* Add an output to the transaction. + * Returns True if the output was added, False if there are no more available output slots. + */ + bool add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations, size_t max_dsts) { if (merge_destinations) { std::vector<cryptonote::tx_destination_entry>::iterator i; i = std::find_if(dsts.begin(), dsts.end(), [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &de.addr, sizeof(de.addr)); }); if (i == dsts.end()) { + if (dsts.size() >= max_dsts) + return false; dsts.push_back(de); i = dsts.end() - 1; i->amount = 0; @@ -9805,12 +9846,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp std::string("original_output_index too large: ") + std::to_string(original_output_index) + " > " + std::to_string(dsts.size())); if (original_output_index == dsts.size()) { + if (dsts.size() >= max_dsts) + return false; dsts.push_back(de); dsts.back().amount = 0; } THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &de.addr, sizeof(de.addr)), error::wallet_internal_error, "Mismatched destination address"); dsts[original_output_index].amount += amount; } + return true; } }; std::vector<TX> txes; @@ -10080,6 +10124,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // clear any fake outs we'd already gathered, since we'll need a new set outs.clear(); + bool out_slots_exhausted = false; if (adding_fee) { LOG_PRINT_L2("We need more fee, adding it to fee"); @@ -10092,20 +10137,32 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // we can fully pay that destination LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) << " for " << print_money(dsts[0].amount)); - tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations); + if (!tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1)) + { + LOG_PRINT_L2("Didn't pay: ran out of output slots"); + out_slots_exhausted = true; + break; + } available_amount -= dsts[0].amount; dsts[0].amount = 0; pop_index(dsts, 0); ++original_output_index; } - if (available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) { + if (!out_slots_exhausted && available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) { // we can partially fill that destination LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) << " for " << print_money(available_amount) << "/" << print_money(dsts[0].amount)); - tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations); - dsts[0].amount -= available_amount; - available_amount = 0; + if (tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1)) + { + dsts[0].amount -= available_amount; + available_amount = 0; + } + else + { + LOG_PRINT_L2("Didn't pay: ran out of output slots"); + out_slots_exhausted = true; + } } } @@ -10113,8 +10170,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit " << upper_transaction_weight_limit); bool try_tx = false; + + // If the new transaction is full, create it and start a new one + if (out_slots_exhausted) + { + LOG_PRINT_L2("Transaction is full, will create it and start a new tx"); + try_tx = true; + } // if we have preferred picks, but haven't yet used all of them, continue - if (preferred_inputs.empty()) + else if (preferred_inputs.empty()) { if (adding_fee) { @@ -10311,8 +10375,6 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, s { MDEBUG("sanity_check: " << ptx_vector.size() << " txes, " << dsts.size() << " destinations"); - hw::device &hwdev = m_account.get_device(); - THROW_WALLET_EXCEPTION_IF(ptx_vector.empty(), error::wallet_internal_error, "No transactions"); // check every party in there does receive at least the required amount @@ -10349,7 +10411,6 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, s for (const auto &r: required) { const account_public_address &address = r.first; - const crypto::public_key &view_pkey = address.m_view_public_key; uint64_t total_received = 0; for (const auto &ptx: ptx_vector) @@ -13237,7 +13298,6 @@ rct::multisig_kLRki wallet2::get_multisig_composite_kLRki(size_t n, const std::u { CHECK_AND_ASSERT_THROW_MES(n < m_transfers.size(), "Bad transfer index"); - const transfer_details &td = m_transfers[n]; rct::multisig_kLRki kLRki = get_multisig_kLRki(n, rct::skGen()); // pick a L/R pair from every other participant but one diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 2e455c40c..e5a5136a4 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1264,6 +1264,8 @@ private: std::string get_spend_proof(const crypto::hash &txid, const std::string &message); bool check_spend_proof(const crypto::hash &txid, const std::string &message, const std::string &sig_str); + void scan_tx(const std::vector<crypto::hash> &txids); + /*! * \brief Generates a proof that proves the reserve of unspent funds * \param account_minreserve When specified, collect outputs only belonging to the given account and prove the smallest reserve above the given amount diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 13de73f8c..327a189ca 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -687,7 +687,7 @@ namespace tools { if (!m_wallet) return not_open(er); const std::pair<std::map<std::string, std::string>, std::vector<std::string>> account_tags = m_wallet->get_account_tags(); - for (const std::pair<std::string, std::string>& p : account_tags.first) + for (const std::pair<const std::string, std::string>& p : account_tags.first) { res.account_tags.resize(res.account_tags.size() + 1); auto& info = res.account_tags.back(); @@ -1282,7 +1282,6 @@ namespace tools dests.erase(cd.change_dts.addr); } - size_t n_dummy_outputs = 0; for (auto i = dests.begin(); i != dests.end(); ) { if (i->second.second > 0) |