aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--contrib/epee/include/misc_log_ex.h44
-rw-r--r--src/blockchain_db/berkeleydb/db_bdb.cpp6
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp2
-rw-r--r--src/blockchain_utilities/bootstrap_file.cpp2
-rw-r--r--src/common/scoped_message_writer.h2
-rw-r--r--src/cryptonote_core/blockchain.cpp10
-rw-r--r--src/cryptonote_core/blockchain.h2
-rw-r--r--src/cryptonote_core/hardfork.cpp12
-rw-r--r--src/cryptonote_core/hardfork.h8
-rw-r--r--src/cryptonote_core/miner.cpp2
-rw-r--r--src/daemon/rpc_command_executor.cpp1
-rw-r--r--src/p2p/net_node.inl2
-rw-r--r--src/rpc/core_rpc_server.cpp11
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h4
-rw-r--r--src/simplewallet/simplewallet.cpp2
-rw-r--r--src/wallet/wallet2.cpp37
-rw-r--r--src/wallet/wallet2.h4
18 files changed, 116 insertions, 45 deletions
diff --git a/README.md b/README.md
index c34e0d36c..32485cc7a 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,12 @@ See README.i18n
## Using Tor
-While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, if you add --p2p-bind-ip 127.0.0.1 to the bitmonerod command line.
-Be aware that your DNS use will probably go over clearnet. These come in two flavours: request for checkpoint data, and request for OpenAlias data. The first one is mostly harmless (your ISP can tell you're using monero). The second one leaks information about your transaction recipients, so do not use OpenAlias if you want DNS privacy.
+While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, if you add --p2p-bind-ip 127.0.0.1 to the bitmonerod command line. You also want to set DNS requests to go over TCP, so they'll be routed through Tor, by setting DNS_PUBLIC=tcp. Example:
+
+DNS_PUBLIC=tcp torsocks bitmonerod --p2p-bind-ip 127.0.0.1
+
+## Using readline
+
+While bitmonerod and simplewallet do not use readline directly, most of the functionality can be obtained by running them via rlwrap. This allows command recall, edit capabilities, etc. It does not give autocompletion without an extra completion file, however. To use rlwrap, simply prepend "rlwrap " to the command line, eg:
+rlwrap bin/simplewallet --wallet-file /path/to/wallet
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h
index 2adac7f2f..b4ba4b7e8 100644
--- a/contrib/epee/include/misc_log_ex.h
+++ b/contrib/epee/include/misc_log_ex.h
@@ -1316,52 +1316,52 @@ POP_WARNINGS
#if defined(ENABLE_LOGGING_INTERNAL)
-#define LOG_PRINT_NO_PREFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str() , y, epee::log_space::console_color_default, false, log_name);}}
+#define LOG_PRINT_NO_PREFIX2(log_name, x, y) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str() , y, epee::log_space::console_color_default, false, log_name);}} while(0)
-#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}}
+#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} while(0)
-#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}}
+#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} while(0)
-#define LOG_PRINT2(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}}
+#define LOG_PRINT2(log_name, x, y) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);}} while(0)
-#define LOG_PRINT_COLOR2(log_name, x, y, color) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name);}}
+#define LOG_PRINT_COLOR2(log_name, x, y, color) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name);}} while(0)
-#define LOG_PRINT2_JORNAL(log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
- {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, true, log_name);}}
+#define LOG_PRINT2_JORNAL(log_name, x, y) do {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() )\
+ {std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, true, log_name);}} while(0)
-#define LOG_ERROR2(log_name, x) { \
- std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "ERROR " << __FILE__ << ":" << __LINE__ << " " << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name);LOCAL_ASSERT(0); epee::log_space::log_singletone::get_set_err_count(true, epee::log_space::log_singletone::get_set_err_count()+1);}
+#define LOG_ERROR2(log_name, x) do { \
+ std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "ERROR " << __FILE__ << ":" << __LINE__ << " " << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name);LOCAL_ASSERT(0); epee::log_space::log_singletone::get_set_err_count(true, epee::log_space::log_singletone::get_set_err_count()+1);} while(0)
#define LOG_FRAME2(log_name, x, y) epee::log_space::log_frame frame(x, y, log_name)
#else
-#define LOG_PRINT_NO_PREFIX2(log_name, x, y)
+#define LOG_PRINT_NO_PREFIX2(log_name, x, y) ((void)0)
-#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y)
+#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) ((void)0)
-#define LOG_PRINT_NO_POSTFIX2(log_name, x, y)
+#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) ((void)0)
-#define LOG_PRINT_COLOR2(log_name, x, y, color)
+#define LOG_PRINT_COLOR2(log_name, x, y, color) ((void)0)
-#define LOG_PRINT2_JORNAL(log_name, x, y)
+#define LOG_PRINT2_JORNAL(log_name, x, y) ((void)0)
-#define LOG_PRINT2(log_name, x, y)
+#define LOG_PRINT2(log_name, x, y) ((void)0)
-#define LOG_ERROR2(log_name, x)
+#define LOG_ERROR2(log_name, x) ((void)0)
-#define LOG_FRAME2(log_name, x, y)
+#define LOG_FRAME2(log_name, x, y) ((void)0)
#endif
diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp
index 07cb622a7..236bc4fe6 100644
--- a/src/blockchain_db/berkeleydb/db_bdb.cpp
+++ b/src/blockchain_db/berkeleydb/db_bdb.cpp
@@ -2176,7 +2176,7 @@ uint8_t BlockchainBDB::get_hard_fork_version(uint64_t height) const
void BlockchainBDB::checkpoint_worker() const
{
- LOG_PRINT_L0("Entering BDB checkpoint thread.")
+ LOG_PRINT_L0("Entering BDB checkpoint thread.");
int count = 0;
while(m_run_checkpoint && m_open)
{
@@ -2188,12 +2188,12 @@ void BlockchainBDB::checkpoint_worker() const
count = 0;
if(m_env->txn_checkpoint(0, 0, 0) != 0)
{
- LOG_PRINT_L0("BDB txn_checkpoint failed.")
+ LOG_PRINT_L0("BDB txn_checkpoint failed.");
break;
}
}
}
- LOG_PRINT_L0("Leaving BDB checkpoint thread.")
+ LOG_PRINT_L0("Leaving BDB checkpoint thread.");
}
void BlockchainBDB::fixup()
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index f20e051f3..98480f247 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -515,7 +515,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
simple_core.m_storage.get_db().show_stats();
#endif
- LOG_PRINT_L0("Number of blocks imported: " << num_imported)
+ LOG_PRINT_L0("Number of blocks imported: " << num_imported);
if (h > 0)
// TODO: if there was an error, the last added block is probably at zero-based height h-2
LOG_PRINT_L0("Finished at block: " << h-1 << " total blocks: " << h);
diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp
index d66d2f604..4a9d722e0 100644
--- a/src/blockchain_utilities/bootstrap_file.cpp
+++ b/src/blockchain_utilities/bootstrap_file.cpp
@@ -397,7 +397,7 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file)
throw std::runtime_error("Error in deserialization of bootstrap::file_info");
LOG_PRINT_L0("bootstrap file v" << unsigned(bfi.major_version) << "." << unsigned(bfi.minor_version));
LOG_PRINT_L0("bootstrap magic size: " << sizeof(file_magic));
- LOG_PRINT_L0("bootstrap header size: " << bfi.header_size)
+ LOG_PRINT_L0("bootstrap header size: " << bfi.header_size);
uint64_t full_header_size = sizeof(file_magic) + bfi.header_size;
import_file.seekg(full_header_size);
diff --git a/src/common/scoped_message_writer.h b/src/common/scoped_message_writer.h
index 77ba56200..c4d430c5e 100644
--- a/src/common/scoped_message_writer.h
+++ b/src/common/scoped_message_writer.h
@@ -88,7 +88,7 @@ public:
{
m_flush = false;
- LOG_PRINT(m_oss.str(), m_log_level)
+ LOG_PRINT(m_oss.str(), m_log_level);
if (epee::log_space::console_color_default == m_color)
{
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 45ddc45e9..badccd06f 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -394,7 +394,7 @@ bool Blockchain::deinit()
{
LOG_PRINT_L3("Blockchain::" << __func__);
- LOG_PRINT_L0("Closing IO Service.")
+ LOG_PRINT_L0("Closing IO Service.");
// stop async service
m_async_work_idle.reset();
m_async_pool.join_all();
@@ -2898,7 +2898,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e
crypto::hash tophash = m_db->top_block_hash();
if (block.prev_id != tophash)
{
- LOG_PRINT_L1("Skipping prepare blocks. New blocks don't belong to chain.")
+ LOG_PRINT_L1("Skipping prepare blocks. New blocks don't belong to chain.");
return true;
}
}
@@ -2958,7 +2958,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e
if (blocks_exist)
{
- LOG_PRINT_L0("Skipping prepare blocks. Blocks exist.")
+ LOG_PRINT_L0("Skipping prepare blocks. Blocks exist.");
return true;
}
@@ -3173,9 +3173,9 @@ HardFork::State Blockchain::get_hard_fork_state() const
return m_hardfork->get_state();
}
-bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint8_t &voting) const
+bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
{
- return m_hardfork->get_voting_info(version, window, votes, threshold, voting);
+ return m_hardfork->get_voting_info(version, window, votes, threshold, earliest_height, voting);
}
bool Blockchain::for_all_key_images(std::function<bool(const crypto::key_image&)> f) const
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index e8f5a7e5b..1efc4e394 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -162,7 +162,7 @@ namespace cryptonote
uint8_t get_ideal_hard_fork_version() const { return m_hardfork->get_ideal_version(); }
uint8_t get_ideal_hard_fork_version(uint64_t height) const { return m_hardfork->get_ideal_version(height); }
- bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint8_t &voting) const;
+ bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const;
bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
bool for_all_blocks(std::function<bool(uint64_t, const crypto::hash&, const block&)>) const;
diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_core/hardfork.cpp
index 550047289..9bd4a337c 100644
--- a/src/cryptonote_core/hardfork.cpp
+++ b/src/cryptonote_core/hardfork.cpp
@@ -355,7 +355,16 @@ uint8_t HardFork::get_ideal_version(uint64_t height) const
return original_version;
}
-bool HardFork::get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint8_t &voting) const
+uint64_t HardFork::get_earliest_ideal_height_for_version(uint8_t version) const
+{
+ for (unsigned int n = heights.size() - 1; n > 0; --n) {
+ if (heights[n].version <= version)
+ return heights[n].height;
+ }
+ return 0;
+}
+
+bool HardFork::get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
{
CRITICAL_REGION_LOCAL(lock);
@@ -367,6 +376,7 @@ bool HardFork::get_voting_info(uint8_t version, uint32_t &window, uint32_t &vote
votes += last_versions[n];
threshold = (window * heights[current_version].threshold + 99) / 100;
assert((votes >= threshold) == enabled);
+ earliest_height = get_earliest_ideal_height_for_version(version);
voting = heights.back().version;
return enabled;
}
diff --git a/src/cryptonote_core/hardfork.h b/src/cryptonote_core/hardfork.h
index 6d2a3c55b..d2f701799 100644
--- a/src/cryptonote_core/hardfork.h
+++ b/src/cryptonote_core/hardfork.h
@@ -184,6 +184,11 @@ namespace cryptonote
uint8_t get_current_version() const;
/**
+ * @brief returns the earliest block a given version may activate
+ */
+ uint64_t get_earliest_ideal_height_for_version(uint8_t version) const;
+
+ /**
* @brief returns information about current voting state
*
* returns true if the given version is enabled (ie, the current version
@@ -193,8 +198,9 @@ namespace cryptonote
* @param window the number of blocks considered in voting
* @param votes number of votes for next version
* @param threshold number of votes needed to switch to next version
+ * @param earliest_height earliest height at which the version can take effect
*/
- bool get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint8_t &voting) const;
+ bool get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const;
/**
* @brief returns the size of the voting window in blocks
diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp
index abb74b740..00a474524 100644
--- a/src/cryptonote_core/miner.cpp
+++ b/src/cryptonote_core/miner.cpp
@@ -257,7 +257,7 @@ namespace cryptonote
m_threads.push_back(boost::thread(attrs, boost::bind(&miner::worker_thread, this)));
}
- LOG_PRINT_L0("Mining has started with " << threads_count << " threads, good luck!" )
+ LOG_PRINT_L0("Mining has started with " << threads_count << " threads, good luck!" );
return true;
}
//-----------------------------------------------------------------------------------------------------
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 686af69c2..9e7f3fdc3 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -241,6 +241,7 @@ bool t_rpc_command_executor::show_difficulty() {
}
tools::success_msg_writer() << "BH: " << res.height
+ << ", TH: " << res.top_block_hash
<< ", DIFF: " << res.difficulty
<< ", HR: " << (int) res.difficulty / res.target << " H/s";
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index ef733416d..254c9ae72 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -380,7 +380,7 @@ namespace nodetool
{
boost::thread* th = new boost::thread([=, &dns_results, &addr_str]
{
- LOG_PRINT_L4("dns_threads[" << result_index << "] created for: " << addr_str)
+ LOG_PRINT_L4("dns_threads[" << result_index << "] created for: " << addr_str);
// TODO: care about dnssec avail/valid
bool avail, valid;
std::vector<std::string> addr_list;
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index b566e7318..57d3b0d0b 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -117,7 +117,14 @@ namespace cryptonote
bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res)
{
CHECK_CORE_BUSY();
- res.height = m_core.get_current_blockchain_height();
+ crypto::hash top_hash;
+ if (!m_core.get_blockchain_top(res.height, top_hash))
+ {
+ res.status = "Failed";
+ return false;
+ }
+ ++res.height; // turn top block height into blockchain height
+ res.top_block_hash = string_tools::pod_to_hex(top_hash);
res.target_height = m_core.get_target_blockchain_height();
res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block();
res.target = m_core.get_blockchain_storage().get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET;
@@ -890,7 +897,7 @@ namespace cryptonote
const Blockchain &blockchain = m_core.get_blockchain_storage();
uint8_t version = req.version > 0 ? req.version : blockchain.get_ideal_hard_fork_version();
res.version = blockchain.get_current_hard_fork_version();
- res.enabled = blockchain.get_hard_fork_voting_info(version, res.window, res.votes, res.threshold, res.voting);
+ res.enabled = blockchain.get_hard_fork_voting_info(version, res.window, res.votes, res.threshold, res.earliest_height, res.voting);
res.state = blockchain.get_hard_fork_state();
res.status = CORE_RPC_STATUS_OK;
return true;
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index b70164614..5ad4450d4 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -282,6 +282,7 @@ namespace cryptonote
uint64_t white_peerlist_size;
uint64_t grey_peerlist_size;
bool testnet;
+ std::string top_block_hash;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
@@ -296,6 +297,7 @@ namespace cryptonote
KV_SERIALIZE(white_peerlist_size)
KV_SERIALIZE(grey_peerlist_size)
KV_SERIALIZE(testnet)
+ KV_SERIALIZE(top_block_hash)
END_KV_SERIALIZE_MAP()
};
};
@@ -875,6 +877,7 @@ namespace cryptonote
uint32_t threshold;
uint8_t voting;
uint32_t state;
+ uint64_t earliest_height;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
@@ -885,6 +888,7 @@ namespace cryptonote
KV_SERIALIZE(threshold)
KV_SERIALIZE(voting)
KV_SERIALIZE(state)
+ KV_SERIALIZE(earliest_height)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index d1ff09170..ad4cd5622 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -157,7 +157,7 @@ namespace
{
m_flush = false;
- LOG_PRINT(m_oss.str(), m_log_level)
+ LOG_PRINT(m_oss.str(), m_log_level);
if (epee::log_space::console_color_default == m_color)
{
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 903e70097..d10529194 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2339,9 +2339,44 @@ void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t n
}
//----------------------------------------------------------------------------------------------------
+bool wallet2::use_fork_rules(uint8_t version)
+{
+ cryptonote::COMMAND_RPC_GET_HEIGHT::request req = AUTO_VAL_INIT(req);
+ cryptonote::COMMAND_RPC_GET_HEIGHT::response res = AUTO_VAL_INIT(res);
+ epee::json_rpc::request<cryptonote::COMMAND_RPC_HARD_FORK_INFO::request> req_t = AUTO_VAL_INIT(req_t);
+ epee::json_rpc::response<cryptonote::COMMAND_RPC_HARD_FORK_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
+
+ m_daemon_rpc_mutex.lock();
+ bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/getheight", req, res, m_http_client);
+ m_daemon_rpc_mutex.unlock();
+ CHECK_AND_ASSERT_MES(r, false, "Failed to connect to daemon");
+ CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, false, "Failed to connect to daemon");
+ CHECK_AND_ASSERT_MES(res.status == CORE_RPC_STATUS_OK, false, "Failed to get current blockchain height");
+
+ m_daemon_rpc_mutex.lock();
+ req_t.jsonrpc = "2.0";
+ req_t.id = epee::serialization::storage_entry(0);
+ req_t.method = "hard_fork_info";
+ req_t.params.version = version;
+ r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ m_daemon_rpc_mutex.unlock();
+ CHECK_AND_ASSERT_MES(r, false, "Failed to connect to daemon");
+ CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, false, "Failed to connect to daemon");
+ CHECK_AND_ASSERT_MES(res.status == CORE_RPC_STATUS_OK, false, "Failed to get hard fork status");
+
+ bool close_enough = res.height >= resp_t.result.earliest_height - 10; // start using the rules a bit beforehand
+ if (close_enough)
+ LOG_PRINT_L2("Using HF1 rules");
+ else
+ LOG_PRINT_L2("Not using HF1 rules");
+ return close_enough;
+}
+//----------------------------------------------------------------------------------------------------
std::vector<wallet2::pending_tx> wallet2::create_dust_sweep_transactions()
{
- tx_dust_policy dust_policy(::config::DEFAULT_DUST_THRESHOLD);
+ // From hard fork 1, we don't consider small amounts to be dust anymore
+ const bool hf1_rules = use_fork_rules(2); // first hard fork has version 2
+ tx_dust_policy dust_policy(hf1_rules ? 0 : ::config::DEFAULT_DUST_THRESHOLD);
size_t num_dust_outputs = 0;
for (transfer_container::const_iterator i = m_transfers.begin(); i != m_transfers.end(); ++i)
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index b71705fb8..adb7b13e2 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -372,6 +372,7 @@ namespace tools
crypto::hash get_payment_id(const pending_tx &ptx) const;
void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, uint64_t &money_transfered, bool &error) const;
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
+ bool use_fork_rules(uint8_t version);
cryptonote::account_base m_account;
std::string m_daemon_address;
@@ -555,7 +556,8 @@ namespace tools
// randomly select inputs for transaction
// throw if requested send amount is greater than amount available to send
std::list<transfer_container::iterator> selected_transfers;
- uint64_t found_money = select_transfers(needed_money, 0 == fake_outputs_count, dust_policy.dust_threshold, selected_transfers);
+ const bool add_dust = (0 == fake_outputs_count) && !use_fork_rules(2); // first fork has version 2
+ uint64_t found_money = select_transfers(needed_money, add_dust, dust_policy.dust_threshold, selected_transfers);
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;