diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/common/perf_timer.h | 4 | ||||
-rw-r--r-- | src/common/threadpool.cpp | 31 | ||||
-rw-r--r-- | src/common/threadpool.h | 5 | ||||
-rw-r--r-- | src/crypto/blake256.c | 9 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 7 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 1 | ||||
-rw-r--r-- | src/rpc/daemon_handler.cpp | 16 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 2 | ||||
-rw-r--r-- | src/wallet/CMakeLists.txt | 65 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 18 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 45 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 45 |
15 files changed, 191 insertions, 67 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f332af3d3..d45363e24 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,12 +113,10 @@ add_subdirectory(lmdb) add_subdirectory(multisig) add_subdirectory(net) add_subdirectory(hardforks) -if(NOT IOS) - add_subdirectory(blockchain_db) -endif() +add_subdirectory(blockchain_db) add_subdirectory(mnemonics) +add_subdirectory(rpc) if(NOT IOS) - add_subdirectory(rpc) add_subdirectory(serialization) endif() add_subdirectory(wallet) diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index ea2237348..29a37e655 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -84,7 +84,7 @@ void set_performance_timer_log_level(el::Level level); #define PERF_TIMER_START_UNIT(name, unit) std::unique_ptr<tools::LoggingPerformanceTimer> PERF_TIMER_NAME(name)(new tools::LoggingPerformanceTimer(#name, "perf." MONERO_DEFAULT_LOG_CATEGORY, unit, el::Level::Info)) #define PERF_TIMER_START(name) PERF_TIMER_START_UNIT(name, 1000000) #define PERF_TIMER_STOP(name) do { PERF_TIMER_NAME(name).reset(NULL); } while(0) -#define PERF_TIMER_PAUSE(name) PERF_TIMER_NAME(name)->pause() -#define PERF_TIMER_RESUME(name) PERF_TIMER_NAME(name)->resume() +#define PERF_TIMER_PAUSE(name) PERF_TIMER_NAME(name).pause() +#define PERF_TIMER_RESUME(name) PERF_TIMER_NAME(name).resume() } diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 2748c798c..18204eeee 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -37,16 +37,14 @@ static __thread bool is_leaf = false; namespace tools { threadpool::threadpool(unsigned int max_threads) : running(true), active(0) { - boost::thread::attributes attrs; - attrs.set_stack_size(THREAD_STACK_SIZE); - max = max_threads ? max_threads : tools::get_max_concurrency(); - size_t i = max ? max - 1 : 0; - while(i--) { - threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false))); - } + create(max_threads); } threadpool::~threadpool() { + destroy(); +} + +void threadpool::destroy() { try { const boost::unique_lock<boost::mutex> lock(mutex); @@ -64,6 +62,23 @@ threadpool::~threadpool() { try { threads[i].join(); } catch (...) { /* ignore */ } } + threads.clear(); +} + +void threadpool::recycle() { + destroy(); + create(max); +} + +void threadpool::create(unsigned int max_threads) { + boost::thread::attributes attrs; + attrs.set_stack_size(THREAD_STACK_SIZE); + max = max_threads ? max_threads : tools::get_max_concurrency(); + size_t i = max ? max - 1 : 0; + running = true; + while(i--) { + threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false))); + } } void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) { @@ -145,7 +160,7 @@ void threadpool::run(bool flush) { if (!running) break; active++; - e = queue.front(); + e = std::move(queue.front()); queue.pop_front(); lock.unlock(); ++depth; diff --git a/src/common/threadpool.h b/src/common/threadpool.h index 5e490ee7d..a49d0e14f 100644 --- a/src/common/threadpool.h +++ b/src/common/threadpool.h @@ -69,12 +69,17 @@ public: // task to finish. void submit(waiter *waiter, std::function<void()> f, bool leaf = false); + // destroy and recreate threads + void recycle(); + unsigned int get_max_concurrency() const; ~threadpool(); private: threadpool(unsigned int max_threads = 0); + void destroy(); + void create(unsigned int max_threads); typedef struct entry { waiter *wo; std::function<void()> f; diff --git a/src/crypto/blake256.c b/src/crypto/blake256.c index 1e305b3a6..bb2c5fb40 100644 --- a/src/crypto/blake256.c +++ b/src/crypto/blake256.c @@ -40,6 +40,7 @@ #include <string.h> #include <stdio.h> #include <stdint.h> +#include <memwipe.h> #include "blake256.h" #define U8TO32(p) \ @@ -277,7 +278,7 @@ void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { } blake256_update(&S->outer, pad, 512); - memset(keyhash, 0, 32); + memwipe(keyhash, sizeof(keyhash)); } // keylen = number of bytes @@ -307,7 +308,7 @@ void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { } blake224_update(&S->outer, pad, 512); - memset(keyhash, 0, 32); + memwipe(keyhash, sizeof(keyhash)); } // datalen = number of bits @@ -327,7 +328,7 @@ void hmac_blake256_final(hmac_state *S, uint8_t *digest) { blake256_final(&S->inner, ihash); blake256_update(&S->outer, ihash, 256); blake256_final(&S->outer, digest); - memset(ihash, 0, 32); + memwipe(ihash, sizeof(ihash)); } void hmac_blake224_final(hmac_state *S, uint8_t *digest) { @@ -335,7 +336,7 @@ void hmac_blake224_final(hmac_state *S, uint8_t *digest) { blake224_final(&S->inner, ihash); blake224_update(&S->outer, ihash, 224); blake224_final(&S->outer, digest); - memset(ihash, 0, 32); + memwipe(ihash, sizeof(ihash)); } // keylen = number of bytes; inlen = number of bytes diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 7357e44d0..5070cc169 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -5079,7 +5079,12 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get return; } const size_t size_needed = 4 + nblocks * (sizeof(crypto::hash) * 2); - if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && checkpoints.size() >= size_needed) + if(checkpoints.size() != size_needed) + { + MERROR("Failed to load hashes - unexpected data size"); + return; + } + else if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP) { p += sizeof(uint32_t); m_blocks_hash_of_hashes.reserve(nblocks); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 5dab251b5..72edddf77 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1884,6 +1884,7 @@ namespace nodetool --i; continue; } + local_peerlist[i].last_seen = 0; #ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED be.pruning_seed = tools::make_pruning_seed(1 + (be.adr.as<epee::net_utils::ipv4_network_address>().ip()) % (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES); diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 0b6cd6c7a..24800ff20 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -311,42 +311,42 @@ namespace rpc if (tvc.m_double_spend) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "double spend"; + res.error_details += "double spend"; } if (tvc.m_invalid_input) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "invalid input"; + res.error_details += "invalid input"; } if (tvc.m_invalid_output) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "invalid output"; + res.error_details += "invalid output"; } if (tvc.m_too_big) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "too big"; + res.error_details += "too big"; } if (tvc.m_overspend) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "overspend"; + res.error_details += "overspend"; } if (tvc.m_fee_too_low) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "fee too low"; + res.error_details += "fee too low"; } if (tvc.m_not_rct) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "tx is not ringct"; + res.error_details += "tx is not ringct"; } if (tvc.m_too_few_outputs) { if (!res.error_details.empty()) res.error_details += " and "; - res.error_details = "too few outputs"; + res.error_details += "too few outputs"; } if (res.error_details.empty()) { diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index a35ee40ae..87bbf62d3 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -4346,7 +4346,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (std::cin.eof() || !command_line::is_yes(confirm)) CHECK_AND_ASSERT_MES(false, false, tr("account creation aborted")); - m_wallet->set_refresh_from_block_height(m_wallet->estimate_blockchain_height()); + m_wallet->set_refresh_from_block_height(m_wallet->estimate_blockchain_height() > 0 ? m_wallet->estimate_blockchain_height() - 1 : 0); m_wallet->explicit_refresh_from_block_height(true); m_restore_height = m_wallet->get_refresh_from_block_height(); } diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 3be1a6f6b..a0a166a93 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -77,42 +77,43 @@ target_link_libraries(wallet PRIVATE ${EXTRA_LIBRARIES}) -set(wallet_rpc_sources - wallet_rpc_server.cpp) +if(NOT IOS) + set(wallet_rpc_sources + wallet_rpc_server.cpp) -set(wallet_rpc_headers) + set(wallet_rpc_headers) -set(wallet_rpc_private_headers - wallet_rpc_server.h) + set(wallet_rpc_private_headers + wallet_rpc_server.h) -monero_private_headers(wallet_rpc_server - ${wallet_rpc_private_headers}) -monero_add_executable(wallet_rpc_server - ${wallet_rpc_sources} - ${wallet_rpc_headers} - ${wallet_rpc_private_headers}) - -target_link_libraries(wallet_rpc_server - PRIVATE - wallet - rpc_base - cryptonote_core - cncrypto - common - version - daemonizer - ${EPEE_READLINE} - ${Boost_CHRONO_LIBRARY} - ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_THREAD_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${EXTRA_LIBRARIES}) -set_property(TARGET wallet_rpc_server - PROPERTY - OUTPUT_NAME "monero-wallet-rpc") -install(TARGETS wallet_rpc_server DESTINATION bin) + monero_private_headers(wallet_rpc_server + ${wallet_rpc_private_headers}) + monero_add_executable(wallet_rpc_server + ${wallet_rpc_sources} + ${wallet_rpc_headers} + ${wallet_rpc_private_headers}) + target_link_libraries(wallet_rpc_server + PRIVATE + wallet + rpc_base + cryptonote_core + cncrypto + common + version + daemonizer + ${EPEE_READLINE} + ${Boost_CHRONO_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) + set_property(TARGET wallet_rpc_server + PROPERTY + OUTPUT_NAME "monero-wallet-rpc") + install(TARGETS wallet_rpc_server DESTINATION bin) +endif() # build and install libwallet_merged only if we building for GUI if (BUILD_GUI_DEPS) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ea556ec45..4d2ec5103 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13619,4 +13619,22 @@ std::vector<cryptonote::public_node> wallet2::get_public_nodes(bool white_only) std::copy(res.gray.begin(), res.gray.end(), std::back_inserter(nodes)); return nodes; } +//---------------------------------------------------------------------------------------------------- +std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, int n_inputs, int ring_size, int n_outputs, size_t extra_size) +{ + THROW_WALLET_EXCEPTION_IF(n_inputs <= 0, tools::error::wallet_internal_error, "Invalid n_inputs"); + THROW_WALLET_EXCEPTION_IF(n_outputs < 0, tools::error::wallet_internal_error, "Invalid n_outputs"); + THROW_WALLET_EXCEPTION_IF(ring_size < 0, tools::error::wallet_internal_error, "Invalid ring size"); + + if (ring_size == 0) + ring_size = get_min_ring_size(); + if (n_outputs == 1) + n_outputs = 2; // extra dummy output + + const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0); + size_t size = estimate_tx_size(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof); + uint64_t weight = estimate_tx_weight(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof); + return std::make_pair(size, weight); +} +//---------------------------------------------------------------------------------------------------- } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index b6f72c7e1..8f840a42d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1254,6 +1254,8 @@ private: bool is_unattended() const { return m_unattended; } + std::pair<size_t, uint64_t> estimate_tx_size_and_weight(bool use_rct, int n_inputs, int ring_size, int n_outputs, size_t extra_size); + bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie); bool daemon_requires_payment(); bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index de501f056..eb89a96e9 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -550,9 +550,29 @@ namespace tools if (!m_wallet) return not_open(er); try { - m_wallet->add_subaddress(req.account_index, req.label); - res.address_index = m_wallet->get_num_subaddresses(req.account_index) - 1; - res.address = m_wallet->get_subaddress_as_str({req.account_index, res.address_index}); + if (req.count < 1 || req.count > 64) { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Count must be between 1 and 64."; + return false; + } + + std::vector<std::string> addresses; + std::vector<uint32_t> address_indices; + + addresses.reserve(req.count); + address_indices.reserve(req.count); + + for (uint32_t i = 0; i < req.count; i++) { + m_wallet->add_subaddress(req.account_index, req.label); + uint32_t new_address_index = m_wallet->get_num_subaddresses(req.account_index) - 1; + address_indices.push_back(new_address_index); + addresses.push_back(m_wallet->get_subaddress_as_str({req.account_index, new_address_index})); + } + + res.address = addresses[0]; + res.address_index = address_indices[0]; + res.addresses = addresses; + res.address_indices = address_indices; } catch (const std::exception& e) { @@ -4291,6 +4311,25 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_estimate_tx_size_and_weight(const wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::request& req, wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + try + { + size_t extra_size = 34 /* pubkey */ + 10 /* encrypted payment id */; // typical makeup + const std::pair<size_t, uint64_t> sw = m_wallet->estimate_tx_size_and_weight(req.rct, req.n_inputs, req.ring_size, req.n_outputs, extra_size); + res.size = sw.first; + res.weight = sw.second; + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Failed to determine size and weight"; + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.version = WALLET_RPC_VERSION; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index b2b5e7116..41f6879ef 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -154,6 +154,7 @@ namespace tools MAP_JON_RPC_WE("set_daemon", on_set_daemon, wallet_rpc::COMMAND_RPC_SET_DAEMON) MAP_JON_RPC_WE("set_log_level", on_set_log_level, wallet_rpc::COMMAND_RPC_SET_LOG_LEVEL) MAP_JON_RPC_WE("set_log_categories", on_set_log_categories, wallet_rpc::COMMAND_RPC_SET_LOG_CATEGORIES) + MAP_JON_RPC_WE("estimate_tx_size_and_weight", on_estimate_tx_size_and_weight, wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT) MAP_JON_RPC_WE("get_version", on_get_version, wallet_rpc::COMMAND_RPC_GET_VERSION) END_JSON_RPC_MAP() END_URI_MAP2() @@ -240,6 +241,7 @@ namespace tools bool on_set_daemon(const wallet_rpc::COMMAND_RPC_SET_DAEMON::request& req, wallet_rpc::COMMAND_RPC_SET_DAEMON::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_set_log_level(const wallet_rpc::COMMAND_RPC_SET_LOG_LEVEL::request& req, wallet_rpc::COMMAND_RPC_SET_LOG_LEVEL::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_set_log_categories(const wallet_rpc::COMMAND_RPC_SET_LOG_CATEGORIES::request& req, wallet_rpc::COMMAND_RPC_SET_LOG_CATEGORIES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_estimate_tx_size_and_weight(const wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::request& req, wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); //json rpc v2 diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 0c86f404d..8d601b050 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -47,7 +47,7 @@ // advance which version they will stop working with // Don't go over 32767 for any of these #define WALLET_RPC_VERSION_MAJOR 1 -#define WALLET_RPC_VERSION_MINOR 16 +#define WALLET_RPC_VERSION_MINOR 17 #define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools @@ -182,11 +182,13 @@ namespace wallet_rpc { struct request_t { - uint32_t account_index; + uint32_t account_index; + uint32_t count; std::string label; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(account_index) + KV_SERIALIZE_OPT(count, 1U) KV_SERIALIZE(label) END_KV_SERIALIZE_MAP() }; @@ -194,12 +196,16 @@ namespace wallet_rpc struct response_t { - std::string address; - uint32_t address_index; + std::string address; + uint32_t address_index; + std::vector<std::string> addresses; + std::vector<uint32_t> address_indices; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(address) KV_SERIALIZE(address_index) + KV_SERIALIZE(addresses) + KV_SERIALIZE(address_indices) END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init<response_t> response; @@ -2580,5 +2586,36 @@ namespace wallet_rpc typedef epee::misc_utils::struct_init<response_t> response; }; + struct COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT + { + struct request_t + { + uint32_t n_inputs; + uint32_t n_outputs; + uint32_t ring_size; + bool rct; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(n_inputs) + KV_SERIALIZE(n_outputs) + KV_SERIALIZE_OPT(ring_size, 0u) + KV_SERIALIZE_OPT(rct, true) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<request_t> request; + + struct response_t + { + uint64_t size; + uint64_t weight; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(size) + KV_SERIALIZE(weight) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<response_t> response; + }; + } } |