diff options
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r-- | src/wallet/wallet2.cpp | 148 |
1 files changed, 110 insertions, 38 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 09ca8efe1..323a3a7fe 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3457,12 +3457,15 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal return true; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::get_fee_multiplier(uint32_t priority, int fee_algorithm) const +uint64_t wallet2::get_fee_multiplier(uint32_t priority, int fee_algorithm) { static const uint64_t old_multipliers[3] = {1, 2, 3}; static const uint64_t new_multipliers[3] = {1, 20, 166}; static const uint64_t newer_multipliers[4] = {1, 4, 20, 166}; + if (fee_algorithm == -1) + fee_algorithm = get_fee_algorithm(); + // 0 -> default (here, x1 till fee algorithm 2, x4 from it) if (priority == 0) priority = m_default_priority; @@ -5098,6 +5101,9 @@ uint64_t wallet2::get_approximate_blockchain_height() const const int seconds_per_block = DIFFICULTY_TARGET_V2; // Calculated blockchain height uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block; + // testnet got some huge rollbacks, so the estimation is way off + if (m_testnet && approx_blockchain_height > 105000) + approx_blockchain_height -= 105000; LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height); return approx_blockchain_height; } @@ -5330,7 +5336,7 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent) +uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent, bool check_spent) { COMMAND_RPC_IS_KEY_IMAGE_SPENT::request req = AUTO_VAL_INIT(req); COMMAND_RPC_IS_KEY_IMAGE_SPENT::response daemon_resp = AUTO_VAL_INIT(daemon_resp); @@ -5379,34 +5385,88 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag m_transfers[n].m_key_image_known = true; } - m_daemon_rpc_mutex.lock(); - bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::is_key_image_spent_error, daemon_resp.status); - THROW_WALLET_EXCEPTION_IF(daemon_resp.spent_status.size() != signed_key_images.size(), error::wallet_internal_error, - "daemon returned wrong response for is_key_image_spent, wrong amounts count = " + - std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(signed_key_images.size())); - + if(check_spent) + { + m_daemon_rpc_mutex.lock(); + bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout); + m_daemon_rpc_mutex.unlock(); + THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent"); + THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); + THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::is_key_image_spent_error, daemon_resp.status); + THROW_WALLET_EXCEPTION_IF(daemon_resp.spent_status.size() != signed_key_images.size(), error::wallet_internal_error, + "daemon returned wrong response for is_key_image_spent, wrong amounts count = " + + std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(signed_key_images.size())); + for (size_t n = 0; n < daemon_resp.spent_status.size(); ++n) + { + transfer_details &td = m_transfers[n]; + td.m_spent = daemon_resp.spent_status[n] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT; + } + } spent = 0; unspent = 0; - for (size_t n = 0; n < daemon_resp.spent_status.size(); ++n) + for(size_t i = 0; i < m_transfers.size(); ++i) { - transfer_details &td = m_transfers[n]; + transfer_details &td = m_transfers[i]; uint64_t amount = td.amount(); - td.m_spent = daemon_resp.spent_status[n] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT; if (td.m_spent) spent += amount; else unspent += amount; - LOG_PRINT_L2("Transfer " << n << ": " << print_money(amount) << " (" << td.m_global_output_index << "): " - << (td.m_spent ? "spent" : "unspent") << " (key image " << req.key_images[n] << ")"); + LOG_PRINT_L2("Transfer " << i << ": " << print_money(amount) << " (" << td.m_global_output_index << "): " + << (td.m_spent ? "spent" : "unspent") << " (key image " << req.key_images[i] << ")"); } - LOG_PRINT_L1("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); - + MDEBUG("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); return m_transfers[signed_key_images.size() - 1].m_block_height; } +wallet2::payment_container wallet2::export_payments() const +{ + payment_container payments; + for (auto const &p : m_payments) + { + payments.emplace(p); + } + return payments; +} +void wallet2::import_payments(const payment_container &payments) +{ + m_payments.clear(); + for (auto const &p : payments) + { + m_payments.emplace(p); + } +} +void wallet2::import_payments_out(const std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>> &confirmed_payments) +{ + m_confirmed_txs.clear(); + for (auto const &p : confirmed_payments) + { + m_confirmed_txs.emplace(p); + } +} + +std::vector<crypto::hash> wallet2::export_blockchain() const +{ + std::vector<crypto::hash> bc; + for (auto const &b : m_blockchain) + { + bc.push_back(b); + } + return bc; +} + +void wallet2::import_blockchain(const std::vector<crypto::hash> &bc) +{ + m_blockchain.clear(); + for (auto const &b : bc) + { + m_blockchain.push_back(b); + } + cryptonote::block genesis; + generate_genesis(genesis); + crypto::hash genesis_hash = get_block_hash(genesis); + check_genesis(genesis_hash); + m_local_bc_height = m_blockchain.size(); +} //---------------------------------------------------------------------------------------------------- std::vector<tools::wallet2::transfer_details> wallet2::export_outputs() const { @@ -5747,10 +5807,14 @@ bool wallet2::is_synced() const return get_blockchain_current_height() >= height; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::estimate_backlog(uint64_t blob_size, uint64_t fee) +std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees) { - THROW_WALLET_EXCEPTION_IF(blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); - THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee"); + THROW_WALLET_EXCEPTION_IF(min_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); + THROW_WALLET_EXCEPTION_IF(max_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); + for (uint64_t fee: fees) + { + THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee"); + } // get txpool backlog epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request> req = AUTO_VAL_INIT(req); @@ -5776,27 +5840,35 @@ uint64_t wallet2::estimate_backlog(uint64_t blob_size, uint64_t fee) THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); + uint64_t full_reward_zone = resp_t.result.block_size_limit / 2; - double our_fee_byte = fee / (double)blob_size; - uint64_t priority_size = 0; - for (const auto &i: res.result.backlog) + std::vector<std::pair<uint64_t, uint64_t>> blocks; + for (uint64_t fee: fees) { - if (i.blob_size == 0) + double our_fee_byte_min = fee / (double)min_blob_size, our_fee_byte_max = fee / (double)max_blob_size; + uint64_t priority_size_min = 0, priority_size_max = 0; + for (const auto &i: res.result.backlog) { - MWARNING("Got 0 sized blob from txpool, ignored"); - continue; + if (i.blob_size == 0) + { + MWARNING("Got 0 sized blob from txpool, ignored"); + continue; + } + double this_fee_byte = i.fee / (double)i.blob_size; + if (this_fee_byte >= our_fee_byte_min) + priority_size_min += i.blob_size; + if (this_fee_byte >= our_fee_byte_max) + priority_size_max += i.blob_size; } - double this_fee_byte = i.fee / (double)i.blob_size; - if (this_fee_byte < our_fee_byte) - continue; - priority_size += i.blob_size; - } - uint64_t full_reward_zone = resp_t.result.block_size_limit / 2; - uint64_t nblocks = (priority_size + full_reward_zone - 1) / full_reward_zone; - MDEBUG("estimate_backlog: priority_size " << priority_size << " for " << our_fee_byte << " (" << our_fee_byte << " piconero fee/byte), " - << nblocks << " blocks at block size " << full_reward_zone); - return nblocks; + uint64_t nblocks_min = (priority_size_min + full_reward_zone - 1) / full_reward_zone; + uint64_t nblocks_max = (priority_size_max + full_reward_zone - 1) / full_reward_zone; + MDEBUG("estimate_backlog: priority_size " << priority_size_min << " - " << priority_size_max << " for " << fee + << " (" << our_fee_byte_min << " - " << our_fee_byte_max << " piconero byte fee), " + << nblocks_min << " - " << nblocks_max << " blocks at block size " << full_reward_zone); + blocks.push_back(std::make_pair(nblocks_min, nblocks_max)); + } + return blocks; } //---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) { |