diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/api/transaction_history.cpp | 2 | ||||
-rw-r--r-- | src/wallet/message_store.cpp | 14 | ||||
-rw-r--r-- | src/wallet/message_transporter.cpp | 61 | ||||
-rw-r--r-- | src/wallet/message_transporter.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 4 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 4 |
7 files changed, 47 insertions, 41 deletions
diff --git a/src/wallet/api/transaction_history.cpp b/src/wallet/api/transaction_history.cpp index f4ad8b1f6..ad7029a3c 100644 --- a/src/wallet/api/transaction_history.cpp +++ b/src/wallet/api/transaction_history.cpp @@ -181,7 +181,7 @@ void TransactionHistoryImpl::refresh() // single output transaction might contain multiple transfers for (const auto &d: pd.m_dests) { - ti->m_transfers.push_back({d.amount, get_account_address_as_str(m_wallet->m_wallet->nettype(), d.is_subaddress, d.addr)}); + ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)}); } m_history.push_back(ti); } diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index 7381005c1..96d4ef3ce 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -397,10 +397,9 @@ void message_store::stop_auto_config() for (uint32_t i = 0; i < m_num_authorized_signers; ++i) { authorized_signer &m = m_signers[i]; - if (!m.me && !m.auto_config_transport_address.empty()) + if (!m.auto_config_transport_address.empty()) { - // Try to delete those "unused API" addresses in PyBitmessage, especially since - // it seems it's not possible to delete them interactively, only to "disable" them + // Try to delete the chan that was used for auto-config m_transporter.delete_transport_address(m.auto_config_transport_address); } m.auto_config_token.clear(); @@ -429,14 +428,7 @@ void message_store::setup_signer_for_auto_config(uint32_t index, const std::stri m.auto_config_token = token; crypto::hash_to_scalar(token.data(), token.size(), m.auto_config_secret_key); crypto::secret_key_to_public_key(m.auto_config_secret_key, m.auto_config_public_key); - if (receiving) - { - m.auto_config_transport_address = m_transporter.derive_and_receive_transport_address(m.auto_config_token); - } - else - { - m.auto_config_transport_address = m_transporter.derive_transport_address(m.auto_config_token); - } + m.auto_config_transport_address = m_transporter.derive_transport_address(m.auto_config_token); } bool message_store::get_signer_index_by_monero_address(const cryptonote::account_public_address &monero_address, uint32_t &index) const diff --git a/src/wallet/message_transporter.cpp b/src/wallet/message_transporter.cpp index 2f8188a3c..cf9b45b37 100644 --- a/src/wallet/message_transporter.cpp +++ b/src/wallet/message_transporter.cpp @@ -192,47 +192,47 @@ bool message_transporter::delete_message(const std::string &transport_id) return true; } -// Deterministically derive a transport / Bitmessage address from 'seed' (the 10-hex-digits -// auto-config token will be used), but do not set it up for receiving in PyBitmessage as -// well, because it's possible the address will only ever be used to SEND auto-config data +// Deterministically derive a new transport address from 'seed' (the 10-hex-digits auto-config +// token will be used) and set it up for sending and receiving +// In a first attempt a normal Bitmessage address was used here, but it turned out the +// key exchange necessary to put it into service could take a long time or even did not +// work out at all sometimes. Also there were problems when deleting those temporary +// addresses again after auto-config. Now a chan is used which avoids all these drawbacks +// quite nicely. std::string message_transporter::derive_transport_address(const std::string &seed) { + // Don't use the seed directly as chan name; that would be too dangerous, e.g. in the + // case of a PyBitmessage instance used by multiple unrelated people + // If an auto-config token gets hashed in another context use different salt instead of "chan" + std::string salted_seed = seed + "chan"; + std::string chan_name = epee::string_tools::pod_to_hex(crypto::cn_fast_hash(salted_seed.data(), salted_seed.size())); + + // Calculate the Bitmessage address that the chan will get for being able to + // use 'joinChain', as 'createChan' will fail and not tell the address if the chan + // already exists (which it can if all auto-config participants share a PyBitmessage + // instance). 'joinChan' will also fail in that case, but that won't matter. std::string request; start_xml_rpc_cmd(request, "getDeterministicAddress"); - add_xml_rpc_base64_param(request, seed); + add_xml_rpc_base64_param(request, chan_name); add_xml_rpc_integer_param(request, 4); // addressVersionNumber add_xml_rpc_integer_param(request, 1); // streamNumber end_xml_rpc_cmd(request); std::string answer; post_request(request, answer); std::string address = get_str_between_tags(answer, "<string>", "</string>"); - return address; -} - -// Derive a transport address and configure it for receiving in PyBitmessage, typically -// for receiving auto-config messages by the wallet of the auto-config organizer -std::string message_transporter::derive_and_receive_transport_address(const std::string &seed) -{ - // We need to call both "get_deterministic_address" AND "createDeterministicAddresses" - // because we won't get back the address from the latter call if it exists already - std::string address = derive_transport_address(seed); - std::string request; - start_xml_rpc_cmd(request, "createDeterministicAddresses"); - add_xml_rpc_base64_param(request, seed); - add_xml_rpc_integer_param(request, 1); // numberOfAddresses - add_xml_rpc_integer_param(request, 4); // addressVersionNumber + start_xml_rpc_cmd(request, "joinChan"); + add_xml_rpc_base64_param(request, chan_name); + add_xml_rpc_string_param(request, address); end_xml_rpc_cmd(request); - std::string answer; post_request(request, answer); - return address; } bool message_transporter::delete_transport_address(const std::string &transport_address) { std::string request; - start_xml_rpc_cmd(request, "deleteAddress"); + start_xml_rpc_cmd(request, "leaveChan"); add_xml_rpc_string_param(request, transport_address); end_xml_rpc_cmd(request); std::string answer; @@ -270,7 +270,22 @@ bool message_transporter::post_request(const std::string &request, std::string & std::string string_value = get_str_between_tags(answer, "<string>", "</string>"); if ((string_value.find("API Error") == 0) || (string_value.find("RPC ") == 0)) { - THROW_WALLET_EXCEPTION(tools::error::bitmessage_api_error, string_value); + if ((string_value.find("API Error 0021") == 0) && (request.find("joinChan") != std::string::npos)) + { + // Error that occurs if one tries to join an already joined chan, which can happen + // if several auto-config participants share one PyBitmessage instance: As a little + // hack simply ignore the error. (A clean solution would be to check for the chan + // with 'listAddresses2', but parsing the returned array is much more complicated.) + } + else if ((string_value.find("API Error 0013") == 0) && (request.find("leaveChan") != std::string::npos)) + { + // Error that occurs if one tries to leave an already left / deleted chan, which can happen + // if several auto-config participants share one PyBitmessage instance: Also ignore. + } + else + { + THROW_WALLET_EXCEPTION(tools::error::bitmessage_api_error, string_value); + } } return r; diff --git a/src/wallet/message_transporter.h b/src/wallet/message_transporter.h index 736fc9b63..28c099d87 100644 --- a/src/wallet/message_transporter.h +++ b/src/wallet/message_transporter.h @@ -91,7 +91,6 @@ public: bool delete_message(const std::string &transport_id); void stop() { m_run.store(false, std::memory_order_relaxed); } std::string derive_transport_address(const std::string &seed); - std::string derive_and_receive_transport_address(const std::string &seed); bool delete_transport_address(const std::string &transport_address); private: diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 117ad4ea8..9782e4b1e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -11607,10 +11607,10 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle return tx_pub_key; } -bool wallet2::export_key_images(const std::string &filename) const +bool wallet2::export_key_images(const std::string &filename, bool all) const { PERF_TIMER(export_key_images); - std::pair<size_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(); + std::pair<size_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all); std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; const uint32_t offset = ski.first; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index a6d042297..c2e34dd76 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1175,7 +1175,7 @@ private: void import_payments_out(const std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>> &confirmed_payments); std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> export_blockchain() const; void import_blockchain(const std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> &bc); - bool export_key_images(const std::string &filename) const; + bool export_key_images(const std::string &filename, bool all = false) const; std::pair<size_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> export_key_images(bool all = false) const; uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true); uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 844ecf90c..c64b662f3 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -352,7 +352,7 @@ namespace tools entry.destinations.push_back(wallet_rpc::transfer_destination()); wallet_rpc::transfer_destination &td = entry.destinations.back(); td.amount = d.amount; - td.address = d.original.empty() ? get_account_address_as_str(m_wallet->nettype(), d.is_subaddress, d.addr) : d.original; + td.address = d.address(m_wallet->nettype(), pd.m_payment_id); } entry.type = "out"; @@ -382,7 +382,7 @@ namespace tools entry.destinations.push_back(wallet_rpc::transfer_destination()); wallet_rpc::transfer_destination &td = entry.destinations.back(); td.amount = d.amount; - td.address = d.original.empty() ? get_account_address_as_str(m_wallet->nettype(), d.is_subaddress, d.addr) : d.original; + td.address = d.address(m_wallet->nettype(), pd.m_payment_id); } entry.type = is_failed ? "failed" : "pending"; |