diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 38184fb51..3f192b11b 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -209,38 +209,6 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback // TODO; } - // Light wallet callbacks - virtual void on_lw_new_block(uint64_t height) - { - if (m_listener) { - m_listener->newBlock(height); - } - } - - virtual void on_lw_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) - { - if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); - m_listener->moneyReceived(tx_hash, amount); - } - } - - virtual void on_lw_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) - { - if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); - m_listener->unconfirmedMoneyReceived(tx_hash, amount); - } - } - - virtual void on_lw_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount) - { - if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); - m_listener->moneySpent(tx_hash, amount); - } - } - virtual void on_device_button_request(uint64_t code) { if (m_listener) { @@ -950,42 +918,11 @@ string WalletImpl::keysFilename() const bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transaction_size_limit, const std::string &daemon_username, const std::string &daemon_password, bool use_ssl, bool lightWallet, const std::string &proxy_address) { clearStatus(); - m_wallet->set_light_wallet(lightWallet); if(daemon_username != "") m_daemon_login.emplace(daemon_username, daemon_password); return doInit(daemon_address, proxy_address, upper_transaction_size_limit, use_ssl); } -bool WalletImpl::lightWalletLogin(bool &isNewWallet) const -{ - return m_wallet->light_wallet_login(isNewWallet); -} - -bool WalletImpl::lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) -{ - try - { - tools::COMMAND_RPC_IMPORT_WALLET_REQUEST::response response; - if(!m_wallet->light_wallet_import_wallet_request(response)){ - setStatusError(tr("Failed to send import wallet request")); - return false; - } - fee = response.import_fee; - payment_id = response.payment_id; - new_request = response.new_request; - request_fulfilled = response.request_fulfilled; - payment_address = response.payment_address; - status = response.status; - } - catch (const std::exception &e) - { - LOG_ERROR("Error sending import wallet request: " << e.what()); - setStatusError(e.what()); - return false; - } - return true; -} - void WalletImpl::setRefreshFromBlockHeight(uint64_t refresh_from_block_height) { m_wallet->set_refresh_from_block_height(refresh_from_block_height); @@ -1018,9 +955,6 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const uint64_t WalletImpl::blockChainHeight() const { - if(m_wallet->light_wallet()) { - return m_wallet->get_light_wallet_scanned_block_height(); - } return m_wallet->get_blockchain_current_height(); } uint64_t WalletImpl::approximateBlockChainHeight() const @@ -1035,9 +969,6 @@ uint64_t WalletImpl::estimateBlockChainHeight() const uint64_t WalletImpl::daemonBlockChainHeight() const { - if(m_wallet->light_wallet()) { - return m_wallet->get_light_wallet_scanned_block_height(); - } if (!m_is_connected) return 0; std::string err; @@ -1054,9 +985,6 @@ uint64_t WalletImpl::daemonBlockChainHeight() const uint64_t WalletImpl::daemonBlockChainTargetHeight() const { - if(m_wallet->light_wallet()) { - return m_wallet->get_light_wallet_blockchain_height(); - } if (!m_is_connected) return 0; std::string err; @@ -2177,13 +2105,12 @@ Wallet::ConnectionStatus WalletImpl::connected() const m_is_connected = m_wallet->check_connection(&version, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS, &wallet_is_outdated, &daemon_is_outdated); if (!m_is_connected) { - if (!m_wallet->light_wallet() && (wallet_is_outdated || daemon_is_outdated)) + if (wallet_is_outdated || daemon_is_outdated) return Wallet::ConnectionStatus_WrongVersion; else return Wallet::ConnectionStatus_Disconnected; } - // Version check is not implemented in light wallets nodes/wallets - if (!m_wallet->light_wallet() && (version >> 16) != CORE_RPC_VERSION_MAJOR) + if ((version >> 16) != CORE_RPC_VERSION_MAJOR) return Wallet::ConnectionStatus_WrongVersion; return Wallet::ConnectionStatus_Connected; } @@ -2277,7 +2204,7 @@ void WalletImpl::doRefresh() LOG_PRINT_L3(__FUNCTION__ << ": doRefresh, rescan = "<light_wallet() || daemonSynced()) { + if (daemonSynced()) { if(rescan) m_wallet->rescan_blockchain(false); m_wallet->refresh(trustedDaemon()); @@ -2368,7 +2295,6 @@ bool WalletImpl::doInit(const string &daemon_address, const std::string &proxy_a // in case new wallet, this will force fast-refresh (pulling hashes instead of blocks) // If daemon isn't synced a calculated block height will be used instead - //TODO: Handle light wallet scenario where block height = 0. if (isNewWallet() && daemonSynced()) { LOG_PRINT_L2(__FUNCTION__ << ":New Wallet - fast refresh until " << daemonBlockChainHeight()); m_wallet->set_refresh_from_block_height(daemonBlockChainHeight()); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index c44d05968..d1bf4f759 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -208,8 +208,6 @@ public: virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector &unknown_parameters, std::string &error) override; virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const override; virtual std::string getDefaultDataDir() const override; - virtual bool lightWalletLogin(bool &isNewWallet) const override; - virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override; virtual bool blackballOutputs(const std::vector &outputs, bool add) override; virtual bool blackballOutput(const std::string &amount, const std::string &offset) override; virtual bool unblackballOutput(const std::string &amount, const std::string &offset) override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index a363636df..ab3d9732e 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -541,7 +541,7 @@ struct Wallet * \param upper_transaction_size_limit * \param daemon_username * \param daemon_password - * \param lightWallet - start wallet in light mode, connect to a openmonero compatible server. + * \param lightWallet - deprecated * \param proxy_address - set proxy address, empty string to disable * \return - true on success */ @@ -1065,12 +1065,6 @@ struct Wallet //! secondary key reuse mitigation virtual void keyReuseMitigation2(bool mitigation) = 0; - //! Light wallet authenticate and login - virtual bool lightWalletLogin(bool &isNewWallet) const = 0; - - //! Initiates a light wallet import wallet request - virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) = 0; - //! locks/unlocks the keys file; returns true on success virtual bool lockKeysFile() = 0; virtual bool unlockKeysFile() = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 41dbf70e8..378fccfab 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1198,12 +1198,6 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std m_account_public_address{crypto::null_pkey, crypto::null_pkey}, m_subaddress_lookahead_major(SUBADDRESS_LOOKAHEAD_MAJOR), m_subaddress_lookahead_minor(SUBADDRESS_LOOKAHEAD_MINOR), - m_light_wallet(false), - m_light_wallet_scanned_block_height(0), - m_light_wallet_blockchain_height(0), - m_light_wallet_connected(false), - m_light_wallet_balance(0), - m_light_wallet_unlocked_balance(0), m_original_keys_available(false), m_message_store(http_client_factory->create()), m_key_device_type(hw::device::device_type::SOFTWARE), @@ -3605,38 +3599,6 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo return; } - if(m_light_wallet) { - - // MyMonero get_address_info needs to be called occasionally to trigger wallet sync. - // This call is not really needed for other purposes and can be removed if mymonero changes their backend. - tools::COMMAND_RPC_GET_ADDRESS_INFO::response res; - - // Get basic info - if(light_wallet_get_address_info(res)) { - // Last stored block height - uint64_t prev_height = m_light_wallet_blockchain_height; - // Update lw heights - m_light_wallet_scanned_block_height = res.scanned_block_height; - m_light_wallet_blockchain_height = res.blockchain_height; - // If new height - call new_block callback - if(m_light_wallet_blockchain_height != prev_height) - { - MDEBUG("new block since last time!"); - m_callback->on_lw_new_block(m_light_wallet_blockchain_height - 1); - } - m_light_wallet_connected = true; - MDEBUG("lw scanned block height: " << m_light_wallet_scanned_block_height); - MDEBUG("lw blockchain height: " << m_light_wallet_blockchain_height); - MDEBUG(m_light_wallet_blockchain_height-m_light_wallet_scanned_block_height << " blocks behind"); - // TODO: add wallet created block info - - light_wallet_get_address_txs(); - } else - m_light_wallet_connected = false; - - // Lighwallet refresh done - return; - } received_money = false; blocks_fetched = 0; uint64_t added_blocks = 0; @@ -5576,16 +5538,6 @@ bool wallet2::check_connection(uint32_t *version, bool *ssl, uint32_t timeout, b return false; } - // TODO: Add light wallet version check. - if(m_light_wallet) { - m_rpc_version = 0; - if (version) - *version = 0; - if (ssl) - *ssl = m_light_wallet_connected; // light wallet is always SSL - return m_light_wallet_connected; - } - { boost::lock_guard lock(m_daemon_rpc_mutex); if(!m_http_client->is_connected(ssl)) @@ -6111,8 +6063,6 @@ boost::optional wallet2::get_cache_file_data(const epe uint64_t wallet2::balance(uint32_t index_major, bool strict) const { uint64_t amount = 0; - if(m_light_wallet) - return m_light_wallet_balance; for (const auto& i : balance_per_subaddress(index_major, strict)) amount += i.second; return amount; @@ -6125,8 +6075,6 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t * *blocks_to_unlock = 0; if (time_to_unlock) *time_to_unlock = 0; - if(m_light_wallet) - return m_light_wallet_unlocked_balance; for (const auto& i : unlocked_balance_per_subaddress(index_major, strict)) { amount += i.second.first; @@ -6661,43 +6609,25 @@ crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const void wallet2::commit_tx(pending_tx& ptx) { using namespace cryptonote; - - if(m_light_wallet) + + // Normal submit + COMMAND_RPC_SEND_RAW_TX::request req; + req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); + req.do_not_relay = false; + req.do_sanity_checks = true; + COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp; + { - cryptonote::COMMAND_RPC_SUBMIT_RAW_TX::request oreq; - cryptonote::COMMAND_RPC_SUBMIT_RAW_TX::response ores; - oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - oreq.tx = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); - { - const boost::lock_guard lock{m_daemon_rpc_mutex}; - bool r = epee::net_utils::invoke_http_json("/submit_raw_tx", oreq, ores, *m_http_client, rpc_timeout, "POST"); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "submit_raw_tx"); - // MyMonero and OpenMonero use different status strings - THROW_WALLET_EXCEPTION_IF(ores.status != "OK" && ores.status != "success" , error::tx_rejected, ptx.tx, get_rpc_status(ores.status), ores.error); - } + const boost::lock_guard lock{m_daemon_rpc_mutex}; + bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, *m_http_client, rpc_timeout); + THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_send_resp, "sendrawtransaction", error::tx_rejected, ptx.tx, get_rpc_status(daemon_send_resp.status), get_text_reason(daemon_send_resp)); } - else + + // sanity checks + for (size_t idx: ptx.selected_transfers) { - // Normal submit - COMMAND_RPC_SEND_RAW_TX::request req; - req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); - req.do_not_relay = false; - req.do_sanity_checks = true; - COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp; - - { - const boost::lock_guard lock{m_daemon_rpc_mutex}; - bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, *m_http_client, rpc_timeout); - THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_send_resp, "sendrawtransaction", error::tx_rejected, ptx.tx, get_rpc_status(daemon_send_resp.status), get_text_reason(daemon_send_resp)); - } - - // sanity checks - for (size_t idx: ptx.selected_transfers) - { - THROW_WALLET_EXCEPTION_IF(idx >= m_transfers.size(), error::wallet_internal_error, - "Bad output index in selected transfers: " + boost::lexical_cast(idx)); - } + THROW_WALLET_EXCEPTION_IF(idx >= m_transfers.size(), error::wallet_internal_error, + "Bad output index in selected transfers: " + boost::lexical_cast(idx)); } crypto::hash txid; @@ -7670,13 +7600,6 @@ uint64_t wallet2::get_dynamic_base_fee_estimate() //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_base_fee() { - if(m_light_wallet) - { - if (use_fork_rules(HF_VERSION_PER_BYTE_FEE)) - return m_light_wallet_per_kb_fee / 1024; - else - return m_light_wallet_per_kb_fee; - } bool use_dyn_fee = use_fork_rules(HF_VERSION_DYNAMIC_FEE, -30 * 1); if (!use_dyn_fee) return FEE_PER_KB; @@ -7720,10 +7643,6 @@ uint64_t wallet2::get_base_fee(uint32_t priority) //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_fee_quantization_mask() { - if(m_light_wallet) - { - return 1; // TODO - } bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0); if (!use_per_byte_fee) return 1; @@ -8198,113 +8117,6 @@ bool wallet2::tx_add_fake_output(std::vector> &outs, const std::vector &selected_transfers, size_t fake_outputs_count) { - - MDEBUG("LIGHTWALLET - Getting random outs"); - - tools::COMMAND_RPC_GET_RANDOM_OUTS::request oreq; - tools::COMMAND_RPC_GET_RANDOM_OUTS::response ores; - - size_t light_wallet_requested_outputs_count = (size_t)((fake_outputs_count + 1) * 1.5 + 1); - - // Amounts to ask for - // MyMonero api handle amounts and fees as strings - for(size_t idx: selected_transfers) { - const uint64_t ask_amount = m_transfers[idx].is_rct() ? 0 : m_transfers[idx].amount(); - std::ostringstream amount_ss; - amount_ss << ask_amount; - oreq.amounts.push_back(amount_ss.str()); - } - - oreq.count = light_wallet_requested_outputs_count; - - { - const boost::lock_guard lock{m_daemon_rpc_mutex}; - bool r = epee::net_utils::invoke_http_json("/get_random_outs", oreq, ores, *m_http_client, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_random_outs"); - THROW_WALLET_EXCEPTION_IF(ores.amount_outs.empty() , error::wallet_internal_error, "No outputs received from light wallet node. Error: " + ores.Error); - } - - // Check if we got enough outputs for each amount - for(auto& out: ores.amount_outs) { - THROW_WALLET_EXCEPTION_IF(out.outputs.size() < light_wallet_requested_outputs_count , error::wallet_internal_error, "Not enough outputs for amount: " + boost::lexical_cast(out.amount)); - MDEBUG(out.outputs.size() << " outputs for amount "+ boost::lexical_cast(out.amount) + " received from light wallet node"); - } - - MDEBUG("selected transfers size: " << selected_transfers.size()); - - std::unordered_set valid_public_keys_cache; - for(size_t idx: selected_transfers) - { - // Create new index - outs.push_back(std::vector()); - outs.back().reserve(fake_outputs_count + 1); - - // add real output first - const transfer_details &td = m_transfers[idx]; - const uint64_t amount = td.is_rct() ? 0 : td.amount(); - outs.back().push_back(std::make_tuple(td.m_global_output_index, td.get_public_key(), rct::commit(td.amount(), td.m_mask))); - MDEBUG("added real output " << string_tools::pod_to_hex(td.get_public_key())); - - // Even if the lightwallet server returns random outputs, we pick them randomly. - std::vector order; - order.resize(light_wallet_requested_outputs_count); - for (size_t n = 0; n < order.size(); ++n) - order[n] = n; - std::shuffle(order.begin(), order.end(), crypto::random_device{}); - - - LOG_PRINT_L2("Looking for " << (fake_outputs_count+1) << " outputs with amounts " << print_money(td.is_rct() ? 0 : td.amount())); - MDEBUG("OUTS SIZE: " << outs.back().size()); - for (size_t o = 0; o < light_wallet_requested_outputs_count && outs.back().size() < fake_outputs_count + 1; ++o) - { - // Random pick - size_t i = order[o]; - - // Find which random output key to use - bool found_amount = false; - size_t amount_key; - for(amount_key = 0; amount_key < ores.amount_outs.size(); ++amount_key) - { - if(boost::lexical_cast(ores.amount_outs[amount_key].amount) == amount) { - found_amount = true; - break; - } - } - THROW_WALLET_EXCEPTION_IF(!found_amount , error::wallet_internal_error, "Outputs for amount " + boost::lexical_cast(ores.amount_outs[amount_key].amount) + " not found" ); - - LOG_PRINT_L2("Index " << i << "/" << light_wallet_requested_outputs_count << ": idx " << ores.amount_outs[amount_key].outputs[i].global_index << " (real " << td.m_global_output_index << "), unlocked " << "(always in light)" << ", key " << ores.amount_outs[0].outputs[i].public_key); - - // Convert light wallet string data to proper data structures - crypto::public_key tx_public_key; - rct::key mask = AUTO_VAL_INIT(mask); // decrypted mask - not used here - rct::key rct_commit = AUTO_VAL_INIT(rct_commit); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, ores.amount_outs[amount_key].outputs[i].public_key), error::wallet_internal_error, "Invalid public_key"); - string_tools::hex_to_pod(ores.amount_outs[amount_key].outputs[i].public_key, tx_public_key); - const uint64_t global_index = ores.amount_outs[amount_key].outputs[i].global_index; - if(!light_wallet_parse_rct_str(ores.amount_outs[amount_key].outputs[i].rct, tx_public_key, 0, mask, rct_commit, false)) - rct_commit = rct::zeroCommit(td.amount()); - - if (tx_add_fake_output(outs, global_index, tx_public_key, rct_commit, td.m_global_output_index, true, valid_public_keys_cache)) { - MDEBUG("added fake output " << ores.amount_outs[amount_key].outputs[i].public_key); - MDEBUG("index " << global_index); - } - } - - THROW_WALLET_EXCEPTION_IF(outs.back().size() < fake_outputs_count + 1 , error::wallet_internal_error, "Not enough fake outputs found" ); - - // Real output is the first. Shuffle outputs - MTRACE(outs.back().size() << " outputs added. Sorting outputs by index:"); - std::sort(outs.back().begin(), outs.back().end(), [](const get_outs_entry &a, const get_outs_entry &b) { return std::get<0>(a) < std::get<0>(b); }); - - // Print output order - for(auto added_out: outs.back()) - MTRACE(std::get<0>(added_out)); - - } -} - std::pair, size_t> outs_unique(const std::vector> &outs) { std::set unique; @@ -8355,11 +8167,6 @@ void wallet2::get_outs(std::vector> LOG_PRINT_L2("fake_outputs_count: " << fake_outputs_count); outs.clear(); - if(m_light_wallet && fake_outputs_count > 0) { - light_wallet_get_outs(outs, selected_transfers, fake_outputs_count); - return; - } - if (fake_outputs_count > 0) { uint64_t segregation_fork_height = get_segregation_fork_height(); @@ -9619,476 +9426,6 @@ static uint32_t get_count_above(const std::vector &tr return count; } -bool wallet2::light_wallet_login(bool &new_address) -{ - MDEBUG("Light wallet login request"); - m_light_wallet_connected = false; - tools::COMMAND_RPC_LOGIN::request request; - tools::COMMAND_RPC_LOGIN::response response; - request.address = get_account().get_public_address_str(m_nettype); - request.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - // Always create account if it doesn't exist. - request.create_account = true; - m_daemon_rpc_mutex.lock(); - bool connected = invoke_http_json("/login", request, response, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - // MyMonero doesn't send any status message. OpenMonero does. - m_light_wallet_connected = connected && (response.status.empty() || response.status == "success"); - new_address = response.new_address; - MDEBUG("Status: " << response.status); - MDEBUG("Reason: " << response.reason); - MDEBUG("New wallet: " << response.new_address); - if(m_light_wallet_connected) - { - // Clear old data on successful login. - // m_transfers.clear(); - // m_payments.clear(); - // m_unconfirmed_payments.clear(); - } - return m_light_wallet_connected; -} - -bool wallet2::light_wallet_import_wallet_request(tools::COMMAND_RPC_IMPORT_WALLET_REQUEST::response &response) -{ - MDEBUG("Light wallet import wallet request"); - tools::COMMAND_RPC_IMPORT_WALLET_REQUEST::request oreq; - oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - m_daemon_rpc_mutex.lock(); - bool r = invoke_http_json("/import_wallet_request", oreq, response, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "import_wallet_request"); - - - return true; -} - -void wallet2::light_wallet_get_unspent_outs() -{ - MDEBUG("Getting unspent outs"); - - tools::COMMAND_RPC_GET_UNSPENT_OUTS::request oreq; - tools::COMMAND_RPC_GET_UNSPENT_OUTS::response ores; - - oreq.amount = "0"; - oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - // openMonero specific - oreq.dust_threshold = boost::lexical_cast(::config::DEFAULT_DUST_THRESHOLD); - // below are required by openMonero api - but are not used. - oreq.mixin = 0; - oreq.use_dust = true; - - - m_daemon_rpc_mutex.lock(); - bool r = invoke_http_json("/get_unspent_outs", oreq, ores, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_unspent_outs"); - THROW_WALLET_EXCEPTION_IF(ores.status == "error", error::wallet_internal_error, ores.reason); - - m_light_wallet_per_kb_fee = ores.per_kb_fee; - - std::unordered_map transfers_txs; - for(const auto &t: m_transfers) - transfers_txs.emplace(t.m_txid,t.m_spent); - - MDEBUG("FOUND " << ores.outputs.size() <<" outputs"); - - // return if no outputs found - if(ores.outputs.empty()) - return; - - // Clear old outputs - m_transfers.clear(); - - for (const auto &o: ores.outputs) { - bool spent = false; - bool add_transfer = true; - crypto::key_image unspent_key_image; - crypto::public_key tx_public_key = AUTO_VAL_INIT(tx_public_key); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - string_tools::hex_to_pod(o.tx_pub_key, tx_public_key); - - for (const std::string &ski: o.spend_key_images) { - spent = false; - - // Check if key image is ours - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, ski), error::wallet_internal_error, "Invalid key image"); - string_tools::hex_to_pod(ski, unspent_key_image); - if(light_wallet_key_image_is_ours(unspent_key_image, tx_public_key, o.index)){ - MTRACE("Output " << o.public_key << " is spent. Key image: " << ski); - spent = true; - break; - } { - MTRACE("Unspent output found. " << o.public_key); - } - } - - // Check if tx already exists in m_transfers. - crypto::hash txid; - crypto::public_key tx_pub_key; - crypto::public_key public_key; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_hash), error::wallet_internal_error, "Invalid tx_hash field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.public_key), error::wallet_internal_error, "Invalid public_key field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - string_tools::hex_to_pod(o.tx_hash, txid); - string_tools::hex_to_pod(o.public_key, public_key); - string_tools::hex_to_pod(o.tx_pub_key, tx_pub_key); - - for(auto &t: m_transfers){ - if(t.get_public_key() == public_key) { - t.m_spent = spent; - add_transfer = false; - break; - } - } - - if(!add_transfer) - continue; - - m_transfers.push_back(transfer_details{}); - transfer_details& td = m_transfers.back(); - - td.m_block_height = o.height; - td.m_global_output_index = o.global_index; - td.m_txid = txid; - - // Add to extra - add_tx_pub_key_to_extra(td.m_tx, tx_pub_key); - - td.m_key_image = unspent_key_image; - td.m_key_image_known = !m_watch_only && !m_multisig; - td.m_key_image_request = false; - td.m_key_image_partial = m_multisig; - td.m_amount = o.amount; - td.m_pk_index = 0; - td.m_internal_output_index = o.index; - td.m_spent = spent; - td.m_frozen = false; - - tx_out txout; - txout.target = txout_to_key(public_key); - txout.amount = td.m_amount; - - td.m_tx.vout.resize(td.m_internal_output_index + 1); - td.m_tx.vout[td.m_internal_output_index] = txout; - - // Add unlock time and coinbase bool got from get_address_txs api call - std::unordered_map::const_iterator found = m_light_wallet_address_txs.find(txid); - THROW_WALLET_EXCEPTION_IF(found == m_light_wallet_address_txs.end(), error::wallet_internal_error, "Lightwallet: tx not found in m_light_wallet_address_txs"); - bool miner_tx = found->second.m_coinbase; - td.m_tx.unlock_time = found->second.m_unlock_time; - - if (!o.rct.empty()) - { - // Coinbase tx's - if(miner_tx) - { - td.m_mask = rct::identity(); - } - else - { - // rct txs - // decrypt rct mask, calculate commit hash and compare against blockchain commit hash - rct::key rct_commit; - light_wallet_parse_rct_str(o.rct, tx_pub_key, td.m_internal_output_index, td.m_mask, rct_commit, true); - bool valid_commit = (rct_commit == rct::commit(td.amount(), td.m_mask)); - if(!valid_commit) - { - MDEBUG("output index: " << o.global_index); - MDEBUG("mask: " + string_tools::pod_to_hex(td.m_mask)); - MDEBUG("calculated commit: " + string_tools::pod_to_hex(rct::commit(td.amount(), td.m_mask))); - MDEBUG("expected commit: " + string_tools::pod_to_hex(rct_commit)); - MDEBUG("amount: " << td.amount()); - } - THROW_WALLET_EXCEPTION_IF(!valid_commit, error::wallet_internal_error, "Lightwallet: rct commit hash mismatch!"); - } - td.m_rct = true; - } - else - { - td.m_mask = rct::identity(); - td.m_rct = false; - } - if(!spent) - set_unspent(m_transfers.size()-1); - m_key_images[td.m_key_image] = m_transfers.size()-1; - m_pub_keys[td.get_public_key()] = m_transfers.size()-1; - } -} - -bool wallet2::light_wallet_get_address_info(tools::COMMAND_RPC_GET_ADDRESS_INFO::response &response) -{ - MTRACE(__FUNCTION__); - - tools::COMMAND_RPC_GET_ADDRESS_INFO::request request; - - request.address = get_account().get_public_address_str(m_nettype); - request.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - m_daemon_rpc_mutex.lock(); - bool r = invoke_http_json("/get_address_info", request, response, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_address_info"); - // TODO: Validate result - return true; -} - -void wallet2::light_wallet_get_address_txs() -{ - MDEBUG("Refreshing light wallet"); - - tools::COMMAND_RPC_GET_ADDRESS_TXS::request ireq; - tools::COMMAND_RPC_GET_ADDRESS_TXS::response ires; - - ireq.address = get_account().get_public_address_str(m_nettype); - ireq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - m_daemon_rpc_mutex.lock(); - bool r = invoke_http_json("/get_address_txs", ireq, ires, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_address_txs"); - //OpenMonero sends status=success, Mymonero doesn't. - THROW_WALLET_EXCEPTION_IF((!ires.status.empty() && ires.status != "success"), error::no_connection_to_daemon, "get_address_txs"); - - - // Abort if no transactions - if(ires.transactions.empty()) - return; - - // Create searchable vectors - std::vector payments_txs; - for(const auto &p: m_payments) - payments_txs.push_back(p.second.m_tx_hash); - std::vector unconfirmed_payments_txs; - for(const auto &up: m_unconfirmed_payments) - unconfirmed_payments_txs.push_back(up.second.m_pd.m_tx_hash); - - // for balance calculation - uint64_t wallet_total_sent = 0; - // txs in pool - std::vector pool_txs; - - for (const auto &t: ires.transactions) { - const uint64_t total_received = t.total_received; - uint64_t total_sent = t.total_sent; - - // Check key images - subtract fake outputs from total_sent - for(const auto &so: t.spent_outputs) - { - crypto::public_key tx_public_key; - crypto::key_image key_image; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, so.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, so.key_image), error::wallet_internal_error, "Invalid key_image field"); - string_tools::hex_to_pod(so.tx_pub_key, tx_public_key); - string_tools::hex_to_pod(so.key_image, key_image); - - if(!light_wallet_key_image_is_ours(key_image, tx_public_key, so.out_index)) { - THROW_WALLET_EXCEPTION_IF(so.amount > t.total_sent, error::wallet_internal_error, "Lightwallet: total sent is negative!"); - total_sent -= so.amount; - } - } - - // Do not add tx if empty. - if(total_sent == 0 && total_received == 0) - continue; - - crypto::hash payment_id = null_hash; - crypto::hash tx_hash; - - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, t.payment_id), error::wallet_internal_error, "Invalid payment_id field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, t.hash), error::wallet_internal_error, "Invalid hash field"); - string_tools::hex_to_pod(t.payment_id, payment_id); - string_tools::hex_to_pod(t.hash, tx_hash); - - // lightwallet specific info - bool incoming = (total_received > total_sent); - address_tx address_tx; - address_tx.m_tx_hash = tx_hash; - address_tx.m_incoming = incoming; - address_tx.m_amount = incoming ? total_received - total_sent : total_sent - total_received; - address_tx.m_fee = 0; // TODO - address_tx.m_block_height = t.height; - address_tx.m_unlock_time = t.unlock_time; - address_tx.m_timestamp = t.timestamp; - address_tx.m_coinbase = t.coinbase; - address_tx.m_mempool = t.mempool; - m_light_wallet_address_txs.emplace(tx_hash,address_tx); - - // populate data needed for history (m_payments, m_unconfirmed_payments, m_confirmed_txs) - // INCOMING transfers - if(total_received > total_sent) { - payment_details payment; - payment.m_tx_hash = tx_hash; - payment.m_amount = total_received - total_sent; - payment.m_fee = 0; // TODO - payment.m_block_height = t.height; - payment.m_unlock_time = t.unlock_time; - payment.m_timestamp = t.timestamp; - payment.m_coinbase = t.coinbase; - - if (t.mempool) { - if (std::find(unconfirmed_payments_txs.begin(), unconfirmed_payments_txs.end(), tx_hash) == unconfirmed_payments_txs.end()) { - pool_txs.push_back(tx_hash); - // assume false as we don't get that info from the light wallet server - crypto::hash payment_id; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::hex_to_pod(t.payment_id, payment_id), - error::wallet_internal_error, "Failed to parse payment id"); - emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, false}); - if (0 != m_callback) { - m_callback->on_lw_unconfirmed_money_received(t.height, payment.m_tx_hash, payment.m_amount); - } - } - } else { - if (std::find(payments_txs.begin(), payments_txs.end(), tx_hash) == payments_txs.end()) { - m_payments.emplace(tx_hash, payment); - if (0 != m_callback) { - m_callback->on_lw_money_received(t.height, payment.m_tx_hash, payment.m_amount); - } - } - } - // Outgoing transfers - } else { - uint64_t amount_sent = total_sent - total_received; - cryptonote::transaction dummy_tx; // not used by light wallet - // increase wallet total sent - wallet_total_sent += total_sent; - if (t.mempool) - { - // Handled by add_unconfirmed_tx in commit_tx - // If sent from another wallet instance we need to add it - if(m_unconfirmed_txs.find(tx_hash) == m_unconfirmed_txs.end()) - { - unconfirmed_transfer_details utd; - utd.m_amount_in = amount_sent; - utd.m_amount_out = amount_sent; - utd.m_change = 0; - utd.m_payment_id = payment_id; - utd.m_timestamp = t.timestamp; - utd.m_state = wallet2::unconfirmed_transfer_details::pending; - m_unconfirmed_txs.emplace(tx_hash,utd); - } - } - else - { - // Only add if new - auto confirmed_tx = m_confirmed_txs.find(tx_hash); - if(confirmed_tx == m_confirmed_txs.end()) { - // tx is added to m_unconfirmed_txs - move to confirmed - if(m_unconfirmed_txs.find(tx_hash) != m_unconfirmed_txs.end()) - { - process_unconfirmed(tx_hash, dummy_tx, t.height); - } - // Tx sent by another wallet instance - else - { - confirmed_transfer_details ctd; - ctd.m_amount_in = amount_sent; - ctd.m_amount_out = amount_sent; - ctd.m_change = 0; - ctd.m_payment_id = payment_id; - ctd.m_block_height = t.height; - ctd.m_timestamp = t.timestamp; - m_confirmed_txs.emplace(tx_hash,ctd); - } - if (0 != m_callback) - { - m_callback->on_lw_money_spent(t.height, tx_hash, amount_sent); - } - } - // If not new - check the amount and update if necessary. - // when sending a tx to same wallet the receiving amount has to be credited - else - { - if(confirmed_tx->second.m_amount_in != amount_sent || confirmed_tx->second.m_amount_out != amount_sent) - { - MDEBUG("Adjusting amount sent/received for tx: <" + t.hash + ">. Is tx sent to own wallet? " << print_money(amount_sent) << " != " << print_money(confirmed_tx->second.m_amount_in)); - confirmed_tx->second.m_amount_in = amount_sent; - confirmed_tx->second.m_amount_out = amount_sent; - confirmed_tx->second.m_change = 0; - } - } - } - } - } - // TODO: purge old unconfirmed_txs - remove_obsolete_pool_txs(pool_txs, false); - - // Calculate wallet balance - m_light_wallet_balance = ires.total_received-wallet_total_sent; - // MyMonero doesn't send unlocked balance - if(ires.total_received_unlocked > 0) - m_light_wallet_unlocked_balance = ires.total_received_unlocked-wallet_total_sent; - else - m_light_wallet_unlocked_balance = m_light_wallet_balance; -} - -bool wallet2::light_wallet_parse_rct_str(const std::string& rct_string, const crypto::public_key& tx_pub_key, uint64_t internal_output_index, rct::key& decrypted_mask, rct::key& rct_commit, bool decrypt) const -{ - // rct string is empty if output is non RCT - if (rct_string.empty()) - return false; - // rct_string is a string with length 64+64+64 ( + + ) - rct::key encrypted_mask; - std::string rct_commit_str = rct_string.substr(0,64); - std::string encrypted_mask_str = rct_string.substr(64,64); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, rct_commit_str), error::wallet_internal_error, "Invalid rct commit hash: " + rct_commit_str); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, encrypted_mask_str), error::wallet_internal_error, "Invalid rct mask: " + encrypted_mask_str); - string_tools::hex_to_pod(rct_commit_str, rct_commit); - string_tools::hex_to_pod(encrypted_mask_str, encrypted_mask); - if (decrypt) { - // Decrypt the mask - crypto::key_derivation derivation; - bool r = generate_key_derivation(tx_pub_key, get_account().get_keys().m_view_secret_key, derivation); - THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); - crypto::secret_key scalar; - crypto::derivation_to_scalar(derivation, internal_output_index, scalar); - sc_sub(decrypted_mask.bytes,encrypted_mask.bytes,rct::hash_to_scalar(rct::sk2rct(scalar)).bytes); - } - return true; -} - -bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image, const crypto::public_key& tx_public_key, uint64_t out_index) -{ - // Lookup key image from cache - serializable_map index_keyimage_map; - serializable_unordered_map >::const_iterator found_pub_key = m_key_image_cache.find(tx_public_key); - if(found_pub_key != m_key_image_cache.end()) { - // pub key found. key image for index cached? - index_keyimage_map = found_pub_key->second; - std::map::const_iterator index_found = index_keyimage_map.find(out_index); - if(index_found != index_keyimage_map.end()) - return key_image == index_found->second; - } - - // Not in cache - calculate key image - crypto::key_image calculated_key_image; - cryptonote::keypair in_ephemeral; - - // Subaddresses aren't supported in mymonero/openmonero yet. Roll out the original scheme: - // compute D = a*R - // compute P = Hs(D || i)*G + B - // compute x = Hs(D || i) + b (and check if P==x*G) - // compute I = x*Hp(P) - const account_keys& ack = get_account().get_keys(); - crypto::key_derivation derivation; - bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, derivation); - CHECK_AND_ASSERT_MES(r, false, "failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")"); - - r = crypto::derive_public_key(derivation, out_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub); - CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key (" << derivation << ", " << out_index << ", " << ack.m_account_address.m_spend_public_key << ")"); - - crypto::derive_secret_key(derivation, out_index, ack.m_spend_secret_key, in_ephemeral.sec); - crypto::public_key out_pkey_test; - r = crypto::secret_key_to_public_key(in_ephemeral.sec, out_pkey_test); - CHECK_AND_ASSERT_MES(r, false, "failed to secret_key_to_public_key(" << in_ephemeral.sec << ")"); - CHECK_AND_ASSERT_MES(in_ephemeral.pub == out_pkey_test, false, "derived secret key doesn't match derived public key"); - - crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, calculated_key_image); - - index_keyimage_map.emplace(out_index, calculated_key_image); - m_key_image_cache.emplace(tx_public_key, index_keyimage_map); - return key_image == calculated_key_image; -} - // Another implementation of transaction creation that is hopefully better // While there is anything left to pay, it goes through random outputs and tries // to fill the next destination/amount. If it fully fills it, it will use the @@ -10113,10 +9450,6 @@ std::vector wallet2::create_transactions_2(std::vector>> unused_transfers_indices_per_subaddr; std::vector>> unused_dust_indices_per_subaddr; uint64_t needed_money; @@ -11179,9 +10512,6 @@ void wallet2::get_hard_fork_info(uint8_t version, uint64_t &earliest_height) //---------------------------------------------------------------------------------------------------- bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks) { - // TODO: How to get fork rule info from light wallet node? - if(m_light_wallet) - return true; uint64_t height, earliest_height; boost::optional result = m_node_rpc_proxy.get_height(height); THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get height"); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d5737a5bd..5e922494b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -70,7 +70,6 @@ #include "common/password.h" #include "node_rpc_proxy.h" #include "message_store.h" -#include "wallet_light_rpc.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "wallet.wallet2" @@ -143,11 +142,6 @@ private: virtual void on_money_spent(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx, const cryptonote::subaddress_index& subaddr_index) {} virtual void on_skip_transaction(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx) {} virtual boost::optional on_get_password(const char *reason) { return boost::none; } - // Light wallet callbacks - virtual void on_lw_new_block(uint64_t height) {} - virtual void on_lw_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) {} - virtual void on_lw_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) {} - virtual void on_lw_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount) {} // Device callbacks virtual void on_device_button_request(uint64_t code) {} virtual void on_device_button_pressed() {} @@ -981,14 +975,6 @@ private: bool is_deterministic() const; bool get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase = epee::wipeable_string()) const; - /*! - * \brief Checks if light wallet. A light wallet sends view key to a server where the blockchain is scanned. - */ - bool light_wallet() const { return m_light_wallet; } - void set_light_wallet(bool light_wallet) { m_light_wallet = light_wallet; } - uint64_t get_light_wallet_scanned_block_height() const { return m_light_wallet_scanned_block_height; } - uint64_t get_light_wallet_blockchain_height() const { return m_light_wallet_blockchain_height; } - /*! * \brief Gets the seed language */ @@ -1104,7 +1090,7 @@ private: void get_unconfirmed_payments_out(std::list>& unconfirmed_payments, const boost::optional& subaddr_account = boost::none, const std::set& subaddr_indices = {}) const; void get_unconfirmed_payments(std::list>& unconfirmed_payments, const boost::optional& subaddr_account = boost::none, const std::set& subaddr_indices = {}) const; - uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); } + uint64_t get_blockchain_current_height() const { return m_blockchain.size(); } void rescan_spent(); void rescan_blockchain(bool hard, bool refresh = true, bool keep_key_images = false); bool is_transfer_unlocked(const transfer_details& td); @@ -1537,23 +1523,6 @@ private: std::pair estimate_tx_size_and_weight(bool use_rct, int n_inputs, int ring_size, int n_outputs, size_t extra_size); - // Light wallet specific functions - // fetch unspent outs from lw node and store in m_transfers - void light_wallet_get_unspent_outs(); - // fetch txs and store in m_payments - void light_wallet_get_address_txs(); - // get_address_info - bool light_wallet_get_address_info(tools::COMMAND_RPC_GET_ADDRESS_INFO::response &response); - // Login. new_address is true if address hasn't been used on lw node before. - bool light_wallet_login(bool &new_address); - // Send an import request to lw node. returns info about import fee, address and payment_id - bool light_wallet_import_wallet_request(tools::COMMAND_RPC_IMPORT_WALLET_REQUEST::response &response); - // get random outputs from light wallet server - void light_wallet_get_outs(std::vector> &outs, const std::vector &selected_transfers, size_t fake_outputs_count); - // Parse rct string - bool light_wallet_parse_rct_str(const std::string& rct_string, const crypto::public_key& tx_pub_key, uint64_t internal_output_index, rct::key& decrypted_mask, rct::key& rct_commit, bool decrypt) const; - // check if key image is ours - bool light_wallet_key_image_is_ours(const crypto::key_image& key_image, const crypto::public_key& tx_public_key, uint64_t out_index); /* * "attributes" are a mechanism to store an arbitrary number of string values @@ -1861,20 +1830,6 @@ private: // Aux transaction data from device serializable_unordered_map m_tx_device; - // Light wallet - bool m_light_wallet; /* sends view key to daemon for scanning */ - uint64_t m_light_wallet_scanned_block_height; - uint64_t m_light_wallet_blockchain_height; - uint64_t m_light_wallet_per_kb_fee = FEE_PER_KB; - bool m_light_wallet_connected; - uint64_t m_light_wallet_balance; - uint64_t m_light_wallet_unlocked_balance; - // Light wallet info needed to populate m_payment requires 2 separate api calls (get_address_txs and get_unspent_outs) - // We save the info from the first call in m_light_wallet_address_txs for easier lookup. - std::unordered_map m_light_wallet_address_txs; - // store calculated key image for faster lookup - serializable_unordered_map > m_key_image_cache; - std::string m_ring_database; bool m_ring_history_saved; std::unique_ptr m_ringdb; diff --git a/src/wallet/wallet_light_rpc.h b/src/wallet/wallet_light_rpc.h deleted file mode 100644 index bae3a05f7..000000000 --- a/src/wallet/wallet_light_rpc.h +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (c) 2014-2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once -#include "cryptonote_basic/cryptonote_basic.h" -#include "crypto/hash.h" - -namespace tools -{ - //----------------------------------------------- - struct COMMAND_RPC_GET_ADDRESS_TXS - { - struct request_t - { - std::string address; - std::string view_key; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(view_key) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct spent_output { - uint64_t amount; - std::string key_image; - std::string tx_pub_key; - uint64_t out_index; - uint32_t mixin; - - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(key_image) - KV_SERIALIZE(tx_pub_key) - KV_SERIALIZE(out_index) - KV_SERIALIZE(mixin) - END_KV_SERIALIZE_MAP() - }; - - struct transaction - { - uint64_t id; - std::string hash; - uint64_t timestamp; - uint64_t total_received; - uint64_t total_sent; - uint64_t unlock_time; - uint64_t height; - std::list spent_outputs; - std::string payment_id; - bool coinbase; - bool mempool; - uint32_t mixin; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(id) - KV_SERIALIZE(hash) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(total_received) - KV_SERIALIZE(total_sent) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(height) - KV_SERIALIZE(spent_outputs) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(coinbase) - KV_SERIALIZE(mempool) - KV_SERIALIZE(mixin) - END_KV_SERIALIZE_MAP() - }; - - - struct response_t - { - //std::list txs_as_json; - uint64_t total_received; - uint64_t total_received_unlocked = 0; // OpenMonero only - uint64_t scanned_height; - std::vector transactions; - uint64_t blockchain_height; - uint64_t scanned_block_height; - std::string status; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_received) - KV_SERIALIZE(total_received_unlocked) - KV_SERIALIZE(scanned_height) - KV_SERIALIZE(transactions) - KV_SERIALIZE(blockchain_height) - KV_SERIALIZE(scanned_block_height) - KV_SERIALIZE(status) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - //----------------------------------------------- - struct COMMAND_RPC_GET_ADDRESS_INFO - { - struct request_t - { - std::string address; - std::string view_key; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(view_key) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct spent_output - { - uint64_t amount; - std::string key_image; - std::string tx_pub_key; - uint64_t out_index; - uint32_t mixin; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(key_image) - KV_SERIALIZE(tx_pub_key) - KV_SERIALIZE(out_index) - KV_SERIALIZE(mixin) - END_KV_SERIALIZE_MAP() - }; - - struct response_t - { - uint64_t locked_funds; - uint64_t total_received; - uint64_t total_sent; - uint64_t scanned_height; - uint64_t scanned_block_height; - uint64_t start_height; - uint64_t transaction_height; - uint64_t blockchain_height; - std::list spent_outputs; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(locked_funds) - KV_SERIALIZE(total_received) - KV_SERIALIZE(total_sent) - KV_SERIALIZE(scanned_height) - KV_SERIALIZE(scanned_block_height) - KV_SERIALIZE(start_height) - KV_SERIALIZE(transaction_height) - KV_SERIALIZE(blockchain_height) - KV_SERIALIZE(spent_outputs) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - //----------------------------------------------- - struct COMMAND_RPC_GET_UNSPENT_OUTS - { - struct request_t - { - std::string amount; - std::string address; - std::string view_key; - // OpenMonero specific - uint64_t mixin; - bool use_dust; - std::string dust_threshold; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(address) - KV_SERIALIZE(view_key) - KV_SERIALIZE(mixin) - KV_SERIALIZE(use_dust) - KV_SERIALIZE(dust_threshold) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - - struct output { - uint64_t amount; - std::string public_key; - uint64_t index; - uint64_t global_index; - std::string rct; - std::string tx_hash; - std::string tx_pub_key; - std::string tx_prefix_hash; - std::vector spend_key_images; - uint64_t timestamp; - uint64_t height; - - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(public_key) - KV_SERIALIZE(index) - KV_SERIALIZE(global_index) - KV_SERIALIZE(rct) - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_pub_key) - KV_SERIALIZE(tx_prefix_hash) - KV_SERIALIZE(spend_key_images) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(height) - END_KV_SERIALIZE_MAP() - }; - - struct response_t - { - uint64_t amount; - std::list outputs; - uint64_t per_kb_fee; - std::string status; - std::string reason; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(outputs) - KV_SERIALIZE(per_kb_fee) - KV_SERIALIZE(status) - KV_SERIALIZE(reason) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - //----------------------------------------------- - struct COMMAND_RPC_LOGIN - { - struct request_t - { - std::string address; - std::string view_key; - bool create_account; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(view_key) - KV_SERIALIZE(create_account) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - std::string status; - std::string reason; - bool new_address; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - KV_SERIALIZE(reason) - KV_SERIALIZE(new_address) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - //----------------------------------------------- - struct COMMAND_RPC_IMPORT_WALLET_REQUEST - { - struct request_t - { - std::string address; - std::string view_key; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(view_key) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - std::string payment_id; - uint64_t import_fee; - bool new_request; - bool request_fulfilled; - std::string payment_address; - std::string status; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) - KV_SERIALIZE(import_fee) - KV_SERIALIZE(new_request) - KV_SERIALIZE(request_fulfilled) - KV_SERIALIZE(payment_address) - KV_SERIALIZE(status) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - //----------------------------------------------- - struct COMMAND_RPC_GET_RANDOM_OUTS - { - struct request_t - { - std::vector amounts; - uint32_t count; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amounts) - KV_SERIALIZE(count) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct output { - std::string public_key; - uint64_t global_index; - std::string rct; // 64+64+64 characters long ( + + ) - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(public_key) - KV_SERIALIZE(global_index) - KV_SERIALIZE(rct) - END_KV_SERIALIZE_MAP() - }; - - struct amount_out { - uint64_t amount; - std::vector outputs; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(outputs) - END_KV_SERIALIZE_MAP() - }; - - struct response_t - { - std::vector amount_outs; - std::string Error; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount_outs) - KV_SERIALIZE(Error) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - //----------------------------------------------- -}