mirror of
https://git.wownero.com/wownero/wownero.git
synced 2025-01-06 20:48:53 +00:00
commit
6b05e7f45d
@ -33,6 +33,7 @@
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include "string_tools.h"
|
||||
#endif
|
||||
|
||||
// On Windows there is a problem with non-ASCII characters in path and file names
|
||||
@ -72,11 +73,9 @@ namespace file_io_utils
|
||||
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
|
||||
{
|
||||
#ifdef WIN32
|
||||
WCHAR wide_path[1000];
|
||||
int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
|
||||
if (chars == 0)
|
||||
return false;
|
||||
HANDLE file_handle = CreateFileW(wide_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD bytes_written;
|
||||
@ -128,18 +127,16 @@ namespace file_io_utils
|
||||
|
||||
|
||||
inline
|
||||
bool load_file_to_string(const std::string& path_to_file, std::string& target_str)
|
||||
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
|
||||
{
|
||||
#ifdef WIN32
|
||||
WCHAR wide_path[1000];
|
||||
int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
|
||||
if (chars == 0)
|
||||
return false;
|
||||
HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
DWORD file_size = GetFileSize(file_handle, NULL);
|
||||
if ((file_size == INVALID_FILE_SIZE) || (file_size > 1000000000)) {
|
||||
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
|
||||
CloseHandle(file_handle);
|
||||
return false;
|
||||
}
|
||||
@ -159,7 +156,7 @@ namespace file_io_utils
|
||||
|
||||
std::ifstream::pos_type file_size = fstream.tellg();
|
||||
|
||||
if(file_size > 1000000000)
|
||||
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
|
||||
return false;//don't go crazy
|
||||
size_t file_size_t = static_cast<size_t>(file_size);
|
||||
|
||||
@ -202,11 +199,9 @@ namespace file_io_utils
|
||||
bool get_file_size(const std::string& path_to_file, uint64_t &size)
|
||||
{
|
||||
#ifdef WIN32
|
||||
WCHAR wide_path[1000];
|
||||
int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000);
|
||||
if (chars == 0)
|
||||
return false;
|
||||
HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
std::wstring wide_path;
|
||||
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
|
||||
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
LARGE_INTEGER file_size;
|
||||
|
@ -652,13 +652,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
m_timer.cancel();
|
||||
boost::system::error_code ignored_ec;
|
||||
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
m_was_shutdown = true;
|
||||
m_protocol_handler.release_protocol();
|
||||
if (!m_host.empty())
|
||||
{
|
||||
host_count(m_host, -1);
|
||||
m_host = "";
|
||||
}
|
||||
m_was_shutdown = true;
|
||||
m_protocol_handler.release_protocol();
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -1029,7 +1029,8 @@ POP_WARNINGS
|
||||
void boosted_tcp_server<t_protocol_handler>::handle_accept(const boost::system::error_code& e)
|
||||
{
|
||||
MDEBUG("handle_accept");
|
||||
TRY_ENTRY();
|
||||
try
|
||||
{
|
||||
if (!e)
|
||||
{
|
||||
if (m_connection_type == e_connection_type_RPC) {
|
||||
@ -1047,11 +1048,25 @@ POP_WARNINGS
|
||||
|
||||
conn->start(true, 1 < m_threads_count);
|
||||
conn->save_dbg_log();
|
||||
}else
|
||||
{
|
||||
_erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count);
|
||||
return;
|
||||
}
|
||||
CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::handle_accept", void());
|
||||
else
|
||||
{
|
||||
MERROR("Error in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e);
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
MERROR("Exception in boosted_tcp_server<t_protocol_handler>::handle_accept: " << e.what());
|
||||
}
|
||||
|
||||
// error path, if e or exception
|
||||
_erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count);
|
||||
misc_utils::sleep_no_w(100);
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type));
|
||||
acceptor_.async_accept(new_connection_->socket(),
|
||||
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
|
@ -48,7 +48,7 @@ namespace epee
|
||||
|
||||
if( (ip | 0xffffff00) == 0xffffffac)
|
||||
{
|
||||
uint32_t second_num = (ip << 8) & 0xff000000;
|
||||
uint32_t second_num = (ip >> 8) & 0xff;
|
||||
if(second_num >= 16 && second_num <= 31 )
|
||||
return true;
|
||||
}
|
||||
|
@ -381,6 +381,41 @@ POP_WARNINGS
|
||||
res = str.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
inline std::wstring utf8_to_utf16(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
|
||||
if (wstr_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::wstring wstr(wstr_size, wchar_t{});
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
inline std::string utf16_to_utf8(const std::wstring& wstr)
|
||||
{
|
||||
if (wstr.empty())
|
||||
return {};
|
||||
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
|
||||
if (str_size == 0)
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
std::string str(str_size, char{});
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
|
||||
{
|
||||
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif //_STRING_TOOLS_H_
|
||||
|
@ -47,6 +47,7 @@ using namespace epee;
|
||||
static std::string generate_log_filename(const char *base)
|
||||
{
|
||||
std::string filename(base);
|
||||
static unsigned int fallback_counter = 0;
|
||||
char tmp[200];
|
||||
struct tm tm;
|
||||
time_t now = time(NULL);
|
||||
@ -56,7 +57,7 @@ static std::string generate_log_filename(const char *base)
|
||||
#else
|
||||
(!gmtime_r(&now, &tm))
|
||||
#endif
|
||||
strcpy(tmp, "unknown");
|
||||
snprintf(tmp, sizeof(tmp), "part-%u", ++fallback_counter);
|
||||
else
|
||||
strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", &tm);
|
||||
tmp[sizeof(tmp) - 1] = 0;
|
||||
|
@ -148,6 +148,7 @@ struct txpool_tx_meta_t
|
||||
uint8_t relayed;
|
||||
uint8_t do_not_relay;
|
||||
uint8_t double_spend_seen: 1;
|
||||
uint8_t bf_padding: 7;
|
||||
|
||||
uint8_t padding[76]; // till 192 bytes
|
||||
};
|
||||
|
@ -440,10 +440,15 @@ std::string get_nix_version_display_string()
|
||||
|
||||
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
|
||||
{
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL);
|
||||
std::string folder_name(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL);
|
||||
return folder_name;
|
||||
try
|
||||
{
|
||||
return string_tools::utf16_to_utf8(psz_path);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
MERROR("utf16_to_utf8 failed: " << e.what());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path.");
|
||||
@ -504,18 +509,20 @@ std::string get_nix_version_display_string()
|
||||
int code;
|
||||
#if defined(WIN32)
|
||||
// Maximizing chances for success
|
||||
WCHAR wide_replacement_name[1000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000);
|
||||
WCHAR wide_replaced_name[1000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000);
|
||||
std::wstring wide_replacement_name;
|
||||
try { wide_replacement_name = string_tools::utf8_to_utf16(replacement_name); }
|
||||
catch (...) { return std::error_code(GetLastError(), std::system_category()); }
|
||||
std::wstring wide_replaced_name;
|
||||
try { wide_replaced_name = string_tools::utf8_to_utf16(replaced_name); }
|
||||
catch (...) { return std::error_code(GetLastError(), std::system_category()); }
|
||||
|
||||
DWORD attributes = ::GetFileAttributesW(wide_replaced_name);
|
||||
DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str());
|
||||
if (INVALID_FILE_ATTRIBUTES != attributes)
|
||||
{
|
||||
::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY));
|
||||
::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY));
|
||||
}
|
||||
|
||||
bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING);
|
||||
bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING);
|
||||
code = ok ? 0 : static_cast<int>(::GetLastError());
|
||||
#else
|
||||
bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str());
|
||||
@ -657,6 +664,13 @@ std::string get_nix_version_display_string()
|
||||
|
||||
bool is_local_address(const std::string &address)
|
||||
{
|
||||
// always assume Tor/I2P addresses to be untrusted by default
|
||||
if (boost::ends_with(address, ".onion") || boost::ends_with(address, ".i2p"))
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is Tor/I2P, non local");
|
||||
return false;
|
||||
}
|
||||
|
||||
// extract host
|
||||
epee::net_utils::http::url_content u_c;
|
||||
if (!epee::net_utils::parse_url(address, u_c))
|
||||
@ -750,4 +764,22 @@ std::string get_nix_version_display_string()
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str)
|
||||
{
|
||||
auto pos = str.find(":");
|
||||
bool r = pos != std::string::npos;
|
||||
uint32_t major;
|
||||
r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos));
|
||||
uint32_t minor;
|
||||
r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1));
|
||||
if (r)
|
||||
{
|
||||
return std::make_pair(major, minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <system_error>
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
@ -212,4 +213,6 @@ namespace tools
|
||||
|
||||
bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash);
|
||||
bool sha256sum(const std::string &filename, crypto::hash &hash);
|
||||
|
||||
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
|
||||
}
|
||||
|
@ -905,10 +905,35 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INLINE void* aligned_malloc(size_t size, size_t align)
|
||||
{
|
||||
void *result;
|
||||
#ifdef _MSC_VER
|
||||
result = _aligned_malloc(size, align);
|
||||
#else
|
||||
if (posix_memalign(&result, align, size)) result = NULL;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
STATIC INLINE void aligned_free(void *ptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
|
||||
{
|
||||
RDATA_ALIGN16 uint8_t expandedKey[240];
|
||||
|
||||
#ifndef FORCE_USE_HEAP
|
||||
RDATA_ALIGN16 uint8_t hp_state[MEMORY];
|
||||
#else
|
||||
uint8_t *hp_state = (uint8_t *)aligned_malloc(MEMORY,16);
|
||||
#endif
|
||||
|
||||
uint8_t text[INIT_SIZE_BYTE];
|
||||
RDATA_ALIGN16 uint64_t a[2];
|
||||
@ -993,6 +1018,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
memcpy(state.init, text, INIT_SIZE_BYTE);
|
||||
hash_permutation(&state.hs);
|
||||
extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
|
||||
|
||||
#ifdef FORCE_USE_HEAP
|
||||
aligned_free(hp_state);
|
||||
#endif
|
||||
}
|
||||
#else /* aarch64 && crypto */
|
||||
|
||||
@ -1127,8 +1156,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
#ifndef FORCE_USE_HEAP
|
||||
uint8_t long_state[MEMORY];
|
||||
#else
|
||||
uint8_t *long_state = NULL;
|
||||
long_state = (uint8_t *)malloc(MEMORY);
|
||||
uint8_t *long_state = (uint8_t *)malloc(MEMORY);
|
||||
#endif
|
||||
|
||||
if (prehashed) {
|
||||
@ -1294,7 +1322,12 @@ union cn_slow_hash_state {
|
||||
#pragma pack(pop)
|
||||
|
||||
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) {
|
||||
#ifndef FORCE_USE_HEAP
|
||||
uint8_t long_state[MEMORY];
|
||||
#else
|
||||
uint8_t *long_state = (uint8_t *)malloc(MEMORY);
|
||||
#endif
|
||||
|
||||
union cn_slow_hash_state state;
|
||||
uint8_t text[INIT_SIZE_BYTE];
|
||||
uint8_t a[AES_BLOCK_SIZE];
|
||||
@ -1370,6 +1403,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
/*memcpy(hash, &state, 32);*/
|
||||
extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
|
||||
oaes_free((OAES_CTX **) &aes_ctx);
|
||||
|
||||
#ifdef FORCE_USE_HEAP
|
||||
free(long_state);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -157,7 +157,7 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
void account_base::create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey)
|
||||
{
|
||||
crypto::secret_key fake;
|
||||
memset(&fake, 0, sizeof(fake));
|
||||
memset(&unwrap(fake), 0, sizeof(fake));
|
||||
create_from_keys(address, fake, viewkey);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
@ -409,7 +409,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
|
||||
m_db->block_txn_stop();
|
||||
|
||||
uint64_t num_popped_blocks = 0;
|
||||
while (true)
|
||||
while (!m_db->is_read_only())
|
||||
{
|
||||
const uint64_t top_height = m_db->height() - 1;
|
||||
const crypto::hash top_id = m_db->top_block_hash();
|
||||
@ -1942,14 +1942,21 @@ bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMA
|
||||
|
||||
res.outs.clear();
|
||||
res.outs.reserve(req.outputs.size());
|
||||
for (const auto &i: req.outputs)
|
||||
try
|
||||
{
|
||||
// get tx_hash, tx_out_index from DB
|
||||
const output_data_t od = m_db->get_output_key(i.amount, i.index);
|
||||
tx_out_index toi = m_db->get_output_tx_and_index(i.amount, i.index);
|
||||
bool unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first));
|
||||
for (const auto &i: req.outputs)
|
||||
{
|
||||
// get tx_hash, tx_out_index from DB
|
||||
const output_data_t od = m_db->get_output_key(i.amount, i.index);
|
||||
tx_out_index toi = m_db->get_output_tx_and_index(i.amount, i.index);
|
||||
bool unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first));
|
||||
|
||||
res.outs.push_back({od.pubkey, od.commitment, unlocked, od.height, toi.first});
|
||||
res.outs.push_back({od.pubkey, od.commitment, unlocked, od.height, toi.first});
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -676,6 +676,7 @@ namespace cryptonote
|
||||
bool core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
|
||||
|
||||
struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; };
|
||||
std::vector<result> results(tx_blobs.size());
|
||||
|
@ -239,6 +239,7 @@ namespace cryptonote
|
||||
meta.relayed = relayed;
|
||||
meta.do_not_relay = do_not_relay;
|
||||
meta.double_spend_seen = have_tx_keyimges_as_spent(tx);
|
||||
meta.bf_padding = 0;
|
||||
memset(meta.padding, 0, sizeof(meta.padding));
|
||||
try
|
||||
{
|
||||
@ -278,6 +279,7 @@ namespace cryptonote
|
||||
meta.relayed = relayed;
|
||||
meta.do_not_relay = do_not_relay;
|
||||
meta.double_spend_seen = false;
|
||||
meta.bf_padding = 0;
|
||||
memset(meta.padding, 0, sizeof(meta.padding));
|
||||
|
||||
try
|
||||
|
@ -262,6 +262,9 @@ int main(int argc, char const * argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_READLINE
|
||||
rdln::suspend_readline pause_readline;
|
||||
#endif
|
||||
std::cerr << "Unknown command: " << command.front() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -973,7 +973,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() {
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&res.pool_stats, 0, sizeof(res.pool_stats));
|
||||
res.pool_stats = {};
|
||||
if (!m_rpc_server->on_get_transaction_pool_stats(req, res, false) || res.status != CORE_RPC_STATUS_OK)
|
||||
{
|
||||
tools::fail_msg_writer() << make_error(fail_message, res.status);
|
||||
|
@ -1554,6 +1554,8 @@ namespace cryptonote
|
||||
std::vector<txpool_histo> histo;
|
||||
uint32_t num_double_spends;
|
||||
|
||||
txpool_stats(): bytes_total(0), bytes_min(0), bytes_max(0), bytes_med(0), fee_total(0), oldest(0), txs_total(0), num_failing(0), num_10m(0), num_not_relayed(0), histo_98pc(0), num_double_spends(0) {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(bytes_total)
|
||||
KV_SERIALIZE(bytes_min)
|
||||
|
@ -104,6 +104,10 @@ bool ZmqServer::addTCPSocket(std::string address, std::string port)
|
||||
|
||||
rep_socket->setsockopt(ZMQ_RCVTIMEO, &DEFAULT_RPC_RECV_TIMEOUT_MS, sizeof(DEFAULT_RPC_RECV_TIMEOUT_MS));
|
||||
|
||||
if (address.empty())
|
||||
address = "*";
|
||||
if (port.empty())
|
||||
port = "*";
|
||||
std::string bind_address = addr_prefix + address + std::string(":") + port;
|
||||
rep_socket->bind(bind_address.c_str());
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ namespace
|
||||
const command_line::arg_descriptor<bool> arg_restore_multisig_wallet = {"restore-multisig-wallet", sw::tr("Recover multisig wallet using Electrum-style mnemonic seed"), false};
|
||||
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false};
|
||||
const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false};
|
||||
const command_line::arg_descriptor<bool> arg_untrusted_daemon = {"untrusted-daemon", sw::tr("Disable commands which rely on a trusted daemon"), false};
|
||||
const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false};
|
||||
const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0};
|
||||
const command_line::arg_descriptor<bool> arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the wownero network"), false};
|
||||
@ -376,21 +377,10 @@ namespace
|
||||
|
||||
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str)
|
||||
{
|
||||
auto pos = str.find(":");
|
||||
bool r = pos != std::string::npos;
|
||||
uint32_t major;
|
||||
r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos));
|
||||
uint32_t minor;
|
||||
r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1));
|
||||
if (r)
|
||||
{
|
||||
return std::make_pair(major, minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto r = tools::parse_subaddress_lookahead(str);
|
||||
if (!r)
|
||||
fail_msg_writer() << tr("invalid format for subaddress lookahead; must be <major>:<minor>");
|
||||
return {};
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void handle_transfer_exception(const std::exception_ptr &e, bool trusted_daemon)
|
||||
@ -1060,7 +1050,7 @@ bool simple_wallet::import_multisig(const std::vector<std::string> &args)
|
||||
fail_msg_writer() << tr("Failed to import multisig info: ") << e.what();
|
||||
return true;
|
||||
}
|
||||
if (m_trusted_daemon)
|
||||
if (is_daemon_trusted())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1212,7 +1202,7 @@ bool simple_wallet::submit_multisig(const std::vector<std::string> &args)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -1989,7 +1979,7 @@ simple_wallet::simple_wallet()
|
||||
tr("Stop mining in the daemon."));
|
||||
m_cmd_binder.set_handler("set_daemon",
|
||||
boost::bind(&simple_wallet::set_daemon, this, _1),
|
||||
tr("set_daemon <host>[:<port>]"),
|
||||
tr("set_daemon <host>[:<port>] [trusted|untrusted]"),
|
||||
tr("Set another daemon to connect to."));
|
||||
m_cmd_binder.set_handler("save_bc",
|
||||
boost::bind(&simple_wallet::save_bc, this, _1),
|
||||
@ -3078,18 +3068,22 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
return false;
|
||||
}
|
||||
|
||||
// set --trusted-daemon if local
|
||||
try
|
||||
{
|
||||
if (tools::is_local_address(m_wallet->get_daemon_address()))
|
||||
{
|
||||
MINFO(tr("Daemon is local, assuming trusted"));
|
||||
m_trusted_daemon = true;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e) { }
|
||||
|
||||
// set --trusted-daemon if local and not overridden
|
||||
if (!m_trusted_daemon)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_trusted_daemon = false;
|
||||
if (tools::is_local_address(m_wallet->get_daemon_address()))
|
||||
{
|
||||
MINFO(tr("Daemon is local, assuming trusted"));
|
||||
m_trusted_daemon = true;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e) { }
|
||||
}
|
||||
|
||||
if (!is_daemon_trusted())
|
||||
message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str();
|
||||
|
||||
if (m_wallet->get_ring_database().empty())
|
||||
@ -3123,7 +3117,10 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
|
||||
m_restore_multisig_wallet = command_line::get_arg(vm, arg_restore_multisig_wallet);
|
||||
m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
|
||||
m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) || !command_line::is_arg_defaulted(vm, arg_untrusted_daemon))
|
||||
m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon) && !command_line::get_arg(vm, arg_untrusted_daemon);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) && !command_line::is_arg_defaulted(vm, arg_untrusted_daemon))
|
||||
message_writer() << tr("--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted");
|
||||
m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version);
|
||||
m_restore_height = command_line::get_arg(vm, arg_restore_height);
|
||||
m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay);
|
||||
@ -3612,7 +3609,7 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::start_mining(const std::vector<std::string>& args)
|
||||
{
|
||||
if (!m_trusted_daemon)
|
||||
if (!is_daemon_trusted())
|
||||
{
|
||||
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
|
||||
return true;
|
||||
@ -3723,6 +3720,33 @@ bool simple_wallet::set_daemon(const std::vector<std::string>& args)
|
||||
}
|
||||
LOCK_IDLE_SCOPE();
|
||||
m_wallet->init(daemon_url);
|
||||
|
||||
if (args.size() == 2)
|
||||
{
|
||||
if (args[1] == "trusted")
|
||||
m_trusted_daemon = true;
|
||||
else if (args[1] == "untrusted")
|
||||
m_trusted_daemon = false;
|
||||
else
|
||||
{
|
||||
fail_msg_writer() << tr("Expected trusted or untrusted, got ") << args[1] << ": assuming untrusted";
|
||||
m_trusted_daemon = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trusted_daemon = false;
|
||||
try
|
||||
{
|
||||
if (tools::is_local_address(m_wallet->get_daemon_address()))
|
||||
{
|
||||
MINFO(tr("Daemon is local, assuming trusted"));
|
||||
m_trusted_daemon = true;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e) { }
|
||||
}
|
||||
success_msg_writer() << boost::format("Daemon set to %s, %s") % daemon_url % (*m_trusted_daemon ? tr("trusted") : tr("untrusted"));
|
||||
} else {
|
||||
fail_msg_writer() << tr("This does not seem to be a valid daemon URL.");
|
||||
}
|
||||
@ -4108,7 +4132,7 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::rescan_spent(const std::vector<std::string> &args)
|
||||
{
|
||||
if (!m_trusted_daemon)
|
||||
if (!is_daemon_trusted())
|
||||
{
|
||||
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
|
||||
return true;
|
||||
@ -4439,16 +4463,16 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
return true;
|
||||
}
|
||||
unlock_block = bc_height + locked_blocks;
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon);
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted());
|
||||
break;
|
||||
case TransferNew:
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon);
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted());
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown transfer method, using original");
|
||||
/* FALLTHRU */
|
||||
case TransferOriginal:
|
||||
ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_trusted_daemon);
|
||||
ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4607,7 +4631,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -4644,7 +4668,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_unmixable_sweep_transactions(m_trusted_daemon);
|
||||
auto ptx_vector = m_wallet->create_unmixable_sweep_transactions(is_daemon_trusted());
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@ -4713,9 +4737,23 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
|
||||
commit_or_save(ptx_vector, m_do_not_relay);
|
||||
}
|
||||
}
|
||||
catch (const tools::error::not_enough_unlocked_money& e)
|
||||
{
|
||||
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
||||
std::string accepted = input_line((boost::format(tr("Discarding %s of unmixable outputs that cannot be spent, which can be undone by \"rescan_spent\". Is this okay? (Y/Yes/N/No): ")) % print_money(e.available())).str());
|
||||
if (std::cin.eof())
|
||||
return true;
|
||||
if (command_line::is_yes(accepted))
|
||||
{
|
||||
try
|
||||
{
|
||||
m_wallet->discard_unmixable_outputs(is_daemon_trusted());
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -4846,7 +4884,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon);
|
||||
auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted());
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@ -4930,7 +4968,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -5045,7 +5083,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_trusted_daemon);
|
||||
auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted());
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@ -5115,7 +5153,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -5420,7 +5458,7 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_trusted_daemon);
|
||||
handle_transfer_exception(std::current_exception(), is_daemon_trusted());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -7008,7 +7046,7 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
|
||||
fail_msg_writer() << tr("command not supported by HW wallet");
|
||||
return true;
|
||||
}
|
||||
if (!m_trusted_daemon)
|
||||
if (!is_daemon_trusted())
|
||||
{
|
||||
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
|
||||
return true;
|
||||
@ -7394,6 +7432,7 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_non_deterministic );
|
||||
command_line::add_arg(desc_params, arg_electrum_seed );
|
||||
command_line::add_arg(desc_params, arg_trusted_daemon);
|
||||
command_line::add_arg(desc_params, arg_untrusted_daemon);
|
||||
command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version);
|
||||
command_line::add_arg(desc_params, arg_restore_height);
|
||||
command_line::add_arg(desc_params, arg_do_not_relay);
|
||||
|
@ -228,6 +228,7 @@ namespace cryptonote
|
||||
bool print_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr);
|
||||
std::string get_prompt() const;
|
||||
bool print_seed(bool encrypted);
|
||||
bool is_daemon_trusted() const { return *m_trusted_daemon; }
|
||||
|
||||
/*!
|
||||
* \brief Prints the seed with a nice message
|
||||
@ -330,7 +331,7 @@ namespace cryptonote
|
||||
bool m_restore_deterministic_wallet; // recover flag
|
||||
bool m_restore_multisig_wallet; // recover flag
|
||||
bool m_non_deterministic; // old 2-random generation
|
||||
bool m_trusted_daemon;
|
||||
boost::optional<bool> m_trusted_daemon;
|
||||
bool m_allow_mismatched_daemon_version;
|
||||
bool m_restoring; // are we restoring, by whatever method?
|
||||
uint64_t m_restore_height; // optional
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_MONERO_VERSION "0.2.1.0-master"
|
||||
#define DEF_MONERO_VERSION "0.2.2.0-master"
|
||||
#define DEF_MONERO_RELEASE_NAME "Busty Brazzers"
|
||||
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
|
||||
|
||||
|
@ -938,6 +938,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
|
||||
}
|
||||
m_subaddress_labels.resize(index.major + 1, {"Untitled account"});
|
||||
m_subaddress_labels[index.major].resize(index.minor + 1);
|
||||
get_account_tags();
|
||||
}
|
||||
else if (m_subaddress_labels[index.major].size() <= index.minor)
|
||||
{
|
||||
@ -1308,20 +1309,20 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index);
|
||||
}
|
||||
}
|
||||
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount)
|
||||
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx_scan_info[o].amount)
|
||||
{
|
||||
LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first)
|
||||
<< " from received " << print_money(tx.vout[o].amount) << " output already exists with "
|
||||
<< " from received " << print_money(tx_scan_info[o].amount) << " output already exists with "
|
||||
<< (m_transfers[kit->second].m_spent ? "spent" : "unspent") << " "
|
||||
<< print_money(m_transfers[kit->second].amount()) << ", received output ignored");
|
||||
<< print_money(m_transfers[kit->second].amount()) << " in tx " << m_transfers[kit->second].m_txid << ", received output ignored");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first)
|
||||
<< " from received " << print_money(tx.vout[o].amount) << " output already exists with "
|
||||
<< " from received " << print_money(tx_scan_info[o].amount) << " output already exists with "
|
||||
<< print_money(m_transfers[kit->second].amount()) << ", replacing with new output");
|
||||
// The new larger output replaced a previous smaller one
|
||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx.vout[o].amount;
|
||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount;
|
||||
|
||||
if (!pool)
|
||||
{
|
||||
@ -3257,6 +3258,12 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p
|
||||
cryptonote::block b;
|
||||
generate_genesis(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
if (m_subaddress_lookahead_major == SUBADDRESS_LOOKAHEAD_MAJOR && m_subaddress_lookahead_minor == SUBADDRESS_LOOKAHEAD_MINOR)
|
||||
{
|
||||
// the default lookahead setting (50:200) is clearly too much for hardware wallet
|
||||
m_subaddress_lookahead_major = 5;
|
||||
m_subaddress_lookahead_minor = 20;
|
||||
}
|
||||
add_subaddress_account(tr("Primary account"));
|
||||
if (!wallet_.empty()) {
|
||||
store();
|
||||
@ -3769,7 +3776,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||
{
|
||||
wallet2::cache_file_data cache_file_data;
|
||||
std::string buf;
|
||||
bool r = epee::file_io_utils::load_file_to_string(m_wallet_file, buf);
|
||||
bool r = epee::file_io_utils::load_file_to_string(m_wallet_file, buf, std::numeric_limits<size_t>::max());
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file);
|
||||
|
||||
// try to read it as an encrypted cache
|
||||
@ -8238,6 +8245,16 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
|
||||
|
||||
return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>(), trusted_daemon);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::discard_unmixable_outputs(bool trusted_daemon)
|
||||
{
|
||||
// may throw
|
||||
std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs(trusted_daemon);
|
||||
for (size_t idx : unmixable_outputs)
|
||||
{
|
||||
m_transfers[idx].m_spent = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const
|
||||
{
|
||||
@ -9516,7 +9533,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
|
||||
std::unordered_set<crypto::hash> spent_txids; // For each spent key image, search for a tx in m_transfers that uses it as input.
|
||||
std::vector<size_t> swept_transfers; // If such a spending tx wasn't found in m_transfers, this means the spending tx
|
||||
// was created by sweep_all, so we can't know the spent height and other detailed info.
|
||||
for(size_t i = 0; i < m_transfers.size(); ++i)
|
||||
for(size_t i = 0; i < signed_key_images.size(); ++i)
|
||||
{
|
||||
transfer_details &td = m_transfers[i];
|
||||
uint64_t amount = td.amount();
|
||||
|
@ -706,6 +706,7 @@ namespace tools
|
||||
bool sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto::hash> &txids);
|
||||
bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std::string &filename, std::vector<crypto::hash> &txids);
|
||||
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
|
||||
void discard_unmixable_outputs(bool trusted_daemon);
|
||||
bool check_connection(uint32_t *version = NULL, uint32_t timeout = 200000);
|
||||
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
|
||||
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
|
||||
|
@ -179,6 +179,10 @@ namespace wallet_args
|
||||
{
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
}
|
||||
else if (!log_to_console)
|
||||
{
|
||||
mlog_set_categories("");
|
||||
}
|
||||
|
||||
if (notice)
|
||||
Print(print) << notice << ENDL;
|
||||
|
@ -362,6 +362,7 @@ namespace tools
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(req.account_index >= m_wallet->get_num_subaddress_accounts(), error::account_index_outofbound);
|
||||
res.addresses.clear();
|
||||
std::vector<uint32_t> req_address_index;
|
||||
if (req.address_index.empty())
|
||||
@ -377,6 +378,7 @@ namespace tools
|
||||
m_wallet->get_transfers(transfers);
|
||||
for (uint32_t i : req_address_index)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(i >= m_wallet->get_num_subaddresses(req.account_index), error::address_index_outofbound);
|
||||
res.addresses.resize(res.addresses.size() + 1);
|
||||
auto& info = res.addresses.back();
|
||||
const cryptonote::subaddress_index index = {req.account_index, i};
|
||||
@ -500,6 +502,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -518,6 +521,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
m_wallet->set_account_tag(req.accounts, req.tag);
|
||||
@ -532,6 +536,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
m_wallet->set_account_tag(req.accounts, "");
|
||||
@ -546,6 +551,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
m_wallet->set_account_tag_description(req.tag, req.description);
|
||||
@ -2054,6 +2060,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
std::string error;
|
||||
std::string uri = m_wallet->make_uri(req.address, req.payment_id, req.amount, req.tx_description, req.recipient_name, error);
|
||||
if (uri.empty())
|
||||
@ -2267,6 +2274,7 @@ namespace tools
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
cryptonote::COMMAND_RPC_STOP_MINING::request daemon_req;
|
||||
cryptonote::COMMAND_RPC_STOP_MINING::response daemon_res;
|
||||
bool r = m_wallet->invoke_http_json("/stop_mining", daemon_req, daemon_res);
|
||||
|
Loading…
Reference in New Issue
Block a user