aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--contrib/epee/include/int-util.h3
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl2
-rw-r--r--contrib/epee/src/CMakeLists.txt3
-rw-r--r--contrib/epee/src/int-util.cpp48
m---------external/randomx0
-rw-r--r--src/crypto/rx-slow-hash.c106
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.cpp7
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/cryptonote_core/blockchain.cpp60
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp1
-rw-r--r--src/cryptonote_core/tx_pool.cpp57
-rw-r--r--src/cryptonote_core/tx_pool.h5
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_defs.h2
-rw-r--r--src/daemon/command_server.cpp2
-rw-r--r--src/daemon/rpc_command_executor.cpp1
-rw-r--r--src/p2p/net_node.inl3
-rw-r--r--src/rpc/core_rpc_server.cpp1
-rw-r--r--src/simplewallet/simplewallet.cpp9
-rw-r--r--tests/unit_tests/mul_div.cpp116
20 files changed, 325 insertions, 104 deletions
diff --git a/README.md b/README.md
index e74a025eb..e465d1ccc 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ Our researchers are available on IRC in [#monero-research-lab on Freenode](https
- You can subscribe to an [announcement listserv](https://lists.getmonero.org) to get critical announcements from the Monero core team. The announcement list can be very helpful for knowing when software updates are needed.
## Translations
-The CLI wallet is available in different languages. If you want to help translate it, see our self-hosted localization platform, Pootle, on [translate.getmonero.org](https://translate.getmonero.org/projects/CLI/). Every translation *must* be uploaded on the platform, pull requests directly editing the code in this repository will be closed. If you need help with Pootle, you can find a guide with screenshots [here](https://github.com/monero-ecosystem/monero-translations/blob/master/pootle.md).
+The CLI wallet is available in different languages. If you want to help translate it, see our self-hosted localization platform, Weblate, on [translate.getmonero.org](https://translate.getmonero.org/projects/CLI/). Every translation *must* be uploaded on the platform, pull requests directly editing the code in this repository will be closed. If you need help with Weblate, you can find a guide with screenshots [here](https://github.com/monero-ecosystem/monero-translations/blob/master/weblate.md).
 
If you need help/support/info about translations, contact the localization workgroup. You can find the complete list of contacts on the repository of the workgroup: [monero-translations](https://github.com/monero-ecosystem/monero-translations#contacts).
diff --git a/contrib/epee/include/int-util.h b/contrib/epee/include/int-util.h
index 8ef5be40a..939c018ea 100644
--- a/contrib/epee/include/int-util.h
+++ b/contrib/epee/include/int-util.h
@@ -129,6 +129,9 @@ static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uin
return remainder;
}
+// Long divisor with 2^64 base
+void div128_64(uint64_t dividend_hi, uint64_t dividend_lo, uint64_t divisor, uint64_t* quotient_hi, uint64_t *quotient_lo, uint64_t *remainder_hi, uint64_t *remainder_lo);
+
#define IDENT16(x) ((uint16_t) (x))
#define IDENT32(x) ((uint32_t) (x))
#define IDENT64(x) ((uint64_t) (x))
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index c52535dcd..e1777b1c4 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -1522,7 +1522,7 @@ POP_WARNINGS
}
- LOG_ERROR("Trying connect to " << adr << ":" << port << ", bind_ip = " << bind_ip_to_use);
+ MDEBUG("Trying to connect to " << adr << ":" << port << ", bind_ip = " << bind_ip_to_use);
//boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port);
boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 9b9fa5a47..5201f59c2 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -27,7 +27,8 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
add_library(epee STATIC byte_slice.cpp hex.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp
- levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp)
+ levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
+ int-util.cpp)
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
add_library(epee_readline STATIC readline_buffer.cpp)
diff --git a/contrib/epee/src/int-util.cpp b/contrib/epee/src/int-util.cpp
new file mode 100644
index 000000000..e9d0822e0
--- /dev/null
+++ b/contrib/epee/src/int-util.cpp
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <boost/multiprecision/cpp_int.hpp>
+
+void div128_64(uint64_t dividend_hi, uint64_t dividend_lo, uint64_t divisor, uint64_t* quotient_hi, uint64_t *quotient_lo, uint64_t *remainder_hi, uint64_t *remainder_lo)
+{
+ typedef boost::multiprecision::uint128_t uint128_t;
+
+ uint128_t dividend = dividend_hi;
+ dividend <<= 64;
+ dividend |= dividend_lo;
+
+ uint128_t q, r;
+ divide_qr(dividend, uint128_t(divisor), q, r);
+
+ *quotient_hi = ((q >> 64) & 0xffffffffffffffffull).convert_to<uint64_t>();
+ *quotient_lo = (q & 0xffffffffffffffffull).convert_to<uint64_t>();
+ if (remainder_hi)
+ *remainder_hi = ((r >> 64) & 0xffffffffffffffffull).convert_to<uint64_t>();
+ if (remainder_lo)
+ *remainder_lo = (r & 0xffffffffffffffffull).convert_to<uint64_t>();
+}
diff --git a/external/randomx b/external/randomx
-Subproject 298cc77095c8992e30ecdd4ca0aa09a969a62bc
+Subproject b53f0ed145c1a51df6ca0708a215089b76d0c05
diff --git a/src/crypto/rx-slow-hash.c b/src/crypto/rx-slow-hash.c
index 59bd89d13..a7a459ad3 100644
--- a/src/crypto/rx-slow-hash.c
+++ b/src/crypto/rx-slow-hash.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <limits.h>
#include "randomx.h"
#include "c_threads.h"
@@ -74,84 +75,41 @@ static void local_abort(const char *msg)
#endif
}
-/**
- * @brief uses cpuid to determine if the CPU supports the AES instructions
- * @return true if the CPU supports AES, false otherwise
- */
+static inline int disabled_flags(void) {
+ static int flags = -1;
-static inline int force_software_aes(void)
-{
- static int use = -1;
-
- if (use != -1)
- return use;
+ if (flags != -1) {
+ return flags;
+ }
- const char *env = getenv("MONERO_USE_SOFTWARE_AES");
+ const char *env = getenv("MONERO_RANDOMX_UMASK");
if (!env) {
- use = 0;
- }
- else if (!strcmp(env, "0") || !strcmp(env, "no")) {
- use = 0;
+ flags = 0;
}
else {
- use = 1;
+ char* endptr;
+ long int value = strtol(env, &endptr, 0);
+ if (endptr != env && value >= 0 && value < INT_MAX) {
+ flags = value;
+ }
+ else {
+ flags = 0;
+ }
}
- return use;
-}
-static void cpuid(int CPUInfo[4], int InfoType)
-{
-#if defined(__x86_64__)
- __asm __volatile__
- (
- "cpuid":
- "=a" (CPUInfo[0]),
- "=b" (CPUInfo[1]),
- "=c" (CPUInfo[2]),
- "=d" (CPUInfo[3]) :
- "a" (InfoType), "c" (0)
- );
-#endif
+ return flags;
}
-static inline int check_aes_hw(void)
-{
-#if defined(__x86_64__)
- int cpuid_results[4];
- static int supported = -1;
- if(supported >= 0)
- return supported;
+static inline int enabled_flags(void) {
+ static int flags = -1;
- cpuid(cpuid_results,1);
- return supported = cpuid_results[2] & (1 << 25);
-#else
- return 0;
-#endif
-}
-
-static volatile int use_rx_jit_flag = -1;
-
-static inline int use_rx_jit(void)
-{
-#if defined(__x86_64__)
+ if (flags != -1) {
+ return flags;
+ }
- if (use_rx_jit_flag != -1)
- return use_rx_jit_flag;
+ flags = randomx_get_flags();
- const char *env = getenv("MONERO_USE_RX_JIT");
- if (!env) {
- use_rx_jit_flag = 1;
- }
- else if (!strcmp(env, "0") || !strcmp(env, "no")) {
- use_rx_jit_flag = 0;
- }
- else {
- use_rx_jit_flag = 1;
- }
- return use_rx_jit_flag;
-#else
- return 0;
-#endif
+ return flags;
}
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
@@ -236,7 +194,7 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
char *hash, int miners, int is_alt) {
uint64_t s_height = rx_seedheight(mainheight);
int toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) != 0;
- randomx_flags flags = RANDOMX_FLAG_DEFAULT;
+ randomx_flags flags = enabled_flags() & ~disabled_flags();
rx_state *rx_sp;
randomx_cache *cache;
@@ -263,8 +221,6 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
cache = rx_sp->rs_cache;
if (cache == NULL) {
- if (use_rx_jit())
- flags |= RANDOMX_FLAG_JIT;
if (cache == NULL) {
cache = randomx_alloc_cache(flags | RANDOMX_FLAG_LARGE_PAGES);
if (cache == NULL) {
@@ -282,14 +238,12 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
memcpy(rx_sp->rs_hash, seedhash, HASH_SIZE);
}
if (rx_vm == NULL) {
- randomx_flags flags = RANDOMX_FLAG_DEFAULT;
- if (use_rx_jit()) {
- flags |= RANDOMX_FLAG_JIT;
- if (!miners)
- flags |= RANDOMX_FLAG_SECURE;
+ if ((flags & RANDOMX_FLAG_JIT) && !miners) {
+ flags |= RANDOMX_FLAG_SECURE & ~disabled_flags();
+ }
+ if (miners && (disabled_flags() & RANDOMX_FLAG_FULL_MEM)) {
+ miners = 0;
}
- if(!force_software_aes() && check_aes_hw())
- flags |= RANDOMX_FLAG_HARD_AES;
if (miners) {
CTHR_MUTEX_LOCK(rx_dataset_mutex);
if (rx_dataset == NULL) {
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp
index d8de65b81..9bafcfc86 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.cpp
+++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp
@@ -110,9 +110,6 @@ namespace cryptonote {
return false;
}
- assert(median_weight < std::numeric_limits<uint32_t>::max());
- assert(current_block_weight < std::numeric_limits<uint32_t>::max());
-
uint64_t product_hi;
// BUGFIX: 32-bit saturation bug (e.g. ARM7), the result was being
// treated as 32-bit by default.
@@ -122,8 +119,8 @@ namespace cryptonote {
uint64_t reward_hi;
uint64_t reward_lo;
- div128_32(product_hi, product_lo, static_cast<uint32_t>(median_weight), &reward_hi, &reward_lo);
- div128_32(reward_hi, reward_lo, static_cast<uint32_t>(median_weight), &reward_hi, &reward_lo);
+ div128_64(product_hi, product_lo, median_weight, &reward_hi, &reward_lo, NULL, NULL);
+ div128_64(reward_hi, reward_lo, median_weight, &reward_hi, &reward_lo, NULL, NULL);
assert(0 == reward_hi);
assert(reward_lo < base_reward);
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 69551934a..86e6c99d1 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -165,6 +165,7 @@
#define HF_VERSION_SAME_MIXIN 12
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 12
#define HF_VERSION_ENFORCE_MIN_AGE 12
+#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 12
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index e3450491b..b7e9f4ca2 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -1176,9 +1176,18 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
}
}
- std::vector<uint64_t> last_blocks_weights;
- get_last_n_blocks_weights(last_blocks_weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW);
- if (!get_block_reward(epee::misc_utils::median(last_blocks_weights), cumulative_block_weight, already_generated_coins, base_reward, version))
+ uint64_t median_weight;
+ if (version >= HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY)
+ {
+ median_weight = m_current_block_cumul_weight_median;
+ }
+ else
+ {
+ std::vector<uint64_t> last_blocks_weights;
+ get_last_n_blocks_weights(last_blocks_weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW);
+ median_weight = epee::misc_utils::median(last_blocks_weights);
+ }
+ if (!get_block_reward(median_weight, cumulative_block_weight, already_generated_coins, base_reward, version))
{
MERROR_VER("block weight " << cumulative_block_weight << " is bigger than allowed for this blockchain");
return false;
@@ -1694,7 +1703,8 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
// Check the block's hash against the difficulty target for its alt chain
difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei);
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
- crypto::hash proof_of_work = null_hash;
+ crypto::hash proof_of_work;
+ memset(proof_of_work.data, 0xff, sizeof(proof_of_work.data));
if (b.major_version >= RX_BLOCK_VERSION)
{
crypto::hash seedhash = null_hash;
@@ -1750,6 +1760,34 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
}
bei.cumulative_difficulty += current_diff;
+ bei.block_cumulative_weight = cryptonote::get_transaction_weight(b.miner_tx);
+ for (const crypto::hash &txid: b.tx_hashes)
+ {
+ cryptonote::tx_memory_pool::tx_details td;
+ cryptonote::blobdata blob;
+ if (m_tx_pool.get_transaction_info(txid, td))
+ {
+ bei.block_cumulative_weight += td.weight;
+ }
+ else if (m_db->get_pruned_tx_blob(txid, blob))
+ {
+ cryptonote::transaction tx;
+ if (!cryptonote::parse_and_validate_tx_base_from_blob(blob, tx))
+ {
+ MERROR_VER("Block with id: " << epee::string_tools::pod_to_hex(id) << " (as alternative) refers to unparsable transaction hash " << txid << ".");
+ bvc.m_verifivation_failed = true;
+ return false;
+ }
+ bei.block_cumulative_weight += cryptonote::get_pruned_transaction_weight(tx);
+ }
+ else
+ {
+ // we can't determine the block weight, set it to 0 and break out of the loop
+ bei.block_cumulative_weight = 0;
+ break;
+ }
+ }
+
// add block to alternate blocks storage,
// as well as the current "alt chain" container
CHECK_AND_ASSERT_MES(!m_db->get_alt_block(id, NULL, NULL), false, "insertion of new alternative block returned as it already exists");
@@ -3319,8 +3357,8 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
if (version >= HF_VERSION_PER_BYTE_FEE)
{
lo = mul128(block_reward, DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT, &hi);
- div128_32(hi, lo, min_block_weight, &hi, &lo);
- div128_32(hi, lo, median_block_weight, &hi, &lo);
+ div128_64(hi, lo, min_block_weight, &hi, &lo, NULL, NULL);
+ div128_64(hi, lo, median_block_weight, &hi, &lo, NULL, NULL);
assert(hi == 0);
lo /= 5;
return lo;
@@ -3330,12 +3368,7 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
uint64_t unscaled_fee_base = (fee_base * min_block_weight / median_block_weight);
lo = mul128(unscaled_fee_base, block_reward, &hi);
- static_assert(DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD % 1000000 == 0, "DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD must be divisible by 1000000");
- static_assert(DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD / 1000000 <= std::numeric_limits<uint32_t>::max(), "DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD is too large");
-
- // divide in two steps, since the divisor must be 32 bits, but DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD isn't
- div128_32(hi, lo, DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD / 1000000, &hi, &lo);
- div128_32(hi, lo, 1000000, &hi, &lo);
+ div128_64(hi, lo, DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD, &hi, &lo, NULL, NULL);
assert(hi == 0);
// quantize fee up to 8 decimals
@@ -3702,7 +3735,8 @@ leave:
TIME_MEASURE_START(longhash_calculating_time);
- crypto::hash proof_of_work = null_hash;
+ crypto::hash proof_of_work;
+ memset(proof_of_work.data, 0xff, sizeof(proof_of_work.data));
// Formerly the code below contained an if loop with the following condition
// !m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_height())
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index b831cc9ff..eed5317e1 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1367,6 +1367,7 @@ namespace cryptonote
{
block_complete_entry bce;
bce.block = cryptonote::block_to_blob(b);
+ bce.block_weight = 0; // we can leave it to 0, those txes aren't pruned
for (const auto &tx_hash: b.tx_hashes)
{
cryptonote::blobdata txblob;
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 3a6a3833d..0d70f2992 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -259,7 +259,7 @@ namespace cryptonote
m_blockchain.add_txpool_tx(id, blob, meta);
if (!insert_key_images(tx, id, kept_by_block))
return false;
- m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
+ m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
lock.commit();
}
catch (const std::exception &e)
@@ -305,7 +305,7 @@ namespace cryptonote
m_blockchain.add_txpool_tx(id, blob, meta);
if (!insert_key_images(tx, id, kept_by_block))
return false;
- m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
+ m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
lock.commit();
}
catch (const std::exception &e)
@@ -518,6 +518,59 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
+ bool tx_memory_pool::get_transaction_info(const crypto::hash &txid, tx_details &td) const
+ {
+ PERF_TIMER(get_transaction_info);
+ CRITICAL_REGION_LOCAL(m_transactions_lock);
+ CRITICAL_REGION_LOCAL1(m_blockchain);
+
+ try
+ {
+ LockedTXN lock(m_blockchain);
+ txpool_tx_meta_t meta;
+ if (!m_blockchain.get_txpool_tx_meta(txid, meta))
+ {
+ MERROR("Failed to find tx in txpool");
+ return false;
+ }
+ cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid);
+ auto ci = m_parsed_tx_cache.find(txid);
+ if (ci != m_parsed_tx_cache.end())
+ {
+ td.tx = ci->second;
+ }
+ else if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(txblob, td.tx) : parse_and_validate_tx_from_blob(txblob, td.tx)))
+ {
+ MERROR("Failed to parse tx from txpool");
+ return false;
+ }
+ else
+ {
+ td.tx.set_hash(txid);
+ }
+ td.blob_size = txblob.size();
+ td.weight = meta.weight;
+ td.fee = meta.fee;
+ td.max_used_block_id = meta.max_used_block_id;
+ td.max_used_block_height = meta.max_used_block_height;
+ td.kept_by_block = meta.kept_by_block;
+ td.last_failed_height = meta.last_failed_height;
+ td.last_failed_id = meta.last_failed_id;
+ td.receive_time = meta.receive_time;
+ td.last_relayed_time = meta.last_relayed_time;
+ td.relayed = meta.relayed;
+ td.do_not_relay = meta.do_not_relay;
+ td.double_spend_seen = meta.double_spend_seen;
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to get tx from txpool: " << e.what());
+ return false;
+ }
+
+ return true;
+ }
+ //---------------------------------------------------------------------------------
void tx_memory_pool::on_idle()
{
m_remove_stuck_tx_interval.do_call([this](){return remove_stuck_transactions();});
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 99182cd0d..dec7e3cd9 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -429,6 +429,11 @@ namespace cryptonote
bool double_spend_seen; //!< true iff another tx was seen double spending this one
};
+ /**
+ * @brief get infornation about a single transaction
+ */
+ bool get_transaction_info(const crypto::hash &txid, tx_details &td) const;
+
private:
/**
diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h
index 3d594bf83..dcd108626 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_defs.h
+++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h
@@ -160,7 +160,7 @@ namespace cryptonote
}
END_KV_SERIALIZE_MAP()
- block_complete_entry(): pruned(false) {}
+ block_complete_entry(): pruned(false), block_weight(0) {}
};
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 757e072a4..e44ce9137 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -65,7 +65,7 @@ t_command_server::t_command_server(
m_command_lookup.set_handler(
"print_pl"
, std::bind(&t_command_parser_executor::print_peer_list, &m_parser, p::_1)
- , "print_pl [white] [gray] [<limit>]"
+ , "print_pl [white] [gray] [pruned] [publicrpc] [<limit>]"
, "Print the current peer list."
);
m_command_lookup.set_handler(
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 014865730..75c54d048 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -92,6 +92,7 @@ namespace {
<< "depth: " << boost::lexical_cast<std::string>(header.depth) << std::endl
<< "hash: " << header.hash << std::endl
<< "difficulty: " << header.wide_difficulty << std::endl
+ << "cumulative difficulty: " << header.wide_cumulative_difficulty << std::endl
<< "POW hash: " << header.pow_hash << std::endl
<< "block size: " << header.block_size << std::endl
<< "block weight: " << header.block_weight << std::endl
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 5fccdca5a..9150ebb1b 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -604,11 +604,13 @@ namespace nodetool
full_addrs.insert("163.172.182.165:28080");
full_addrs.insert("195.154.123.123:28080");
full_addrs.insert("212.83.172.165:28080");
+ full_addrs.insert("192.110.160.146:28080");
}
else if (nettype == cryptonote::STAGENET)
{
full_addrs.insert("162.210.173.150:38080");
full_addrs.insert("162.210.173.151:38080");
+ full_addrs.insert("192.110.160.146:38080");
}
else if (nettype == cryptonote::FAKECHAIN)
{
@@ -623,6 +625,7 @@ namespace nodetool
full_addrs.insert("198.74.231.92:18080");
full_addrs.insert("195.154.123.123:18080");
full_addrs.insert("212.83.172.165:18080");
+ full_addrs.insert("192.110.160.146:18080");
}
return full_addrs;
}
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 6f5f912cd..dfc4d4cf3 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1951,7 +1951,6 @@ namespace cryptonote
error_resp.message = "Internal error: can't produce valid response.";
return false;
}
- res.miner_tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(blk.miner_tx));
for (size_t n = 0; n < blk.tx_hashes.size(); ++n)
{
res.tx_hashes.push_back(epee::string_tools::pod_to_hex(blk.tx_hashes[n]));
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 0174104be..6a54c24fb 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -144,6 +144,7 @@ namespace
const command_line::arg_descriptor<std::string> arg_mnemonic_language = {"mnemonic-language", sw::tr("Language for mnemonic"), ""};
const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", sw::tr("Specify Electrum seed for wallet recovery/creation"), ""};
const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using Electrum-style mnemonic seed"), false};
+ const command_line::arg_descriptor<bool> arg_restore_from_seed = {"restore-from-seed", sw::tr("alias for --restore-deterministic-wallet"), false};
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_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false};
@@ -4280,7 +4281,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json);
m_mnemonic_language = command_line::get_arg(vm, arg_mnemonic_language);
m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed);
- m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
+ m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet) || command_line::get_arg(vm, arg_restore_from_seed);
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_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version);
@@ -5131,7 +5132,7 @@ void simple_wallet::on_money_received(uint64_t height, const crypto::hash &txid,
tr("WARNING: this transaction uses an unencrypted payment ID: these are obsolete and ignored. Use subaddresses instead.");
}
}
- if (unlock_time)
+ if (unlock_time && !cryptonote::is_coinbase(tx))
message_writer() << tr("NOTE: This transaction is locked, see details with: show_transfer ") + epee::string_tools::pod_to_hex(txid);
if (m_auto_refresh_refreshing)
m_cmd_binder.print_prompt();
@@ -5334,6 +5335,9 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo
fail_msg_writer() << tr("refresh failed: ") << ss.str() << ". " << tr("Blocks received: ") << fetched_blocks;
}
+ // prevent it from triggering the idle screen due to waiting for a foreground refresh
+ m_last_activity_time = time(NULL);
+
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -9713,6 +9717,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_command);
command_line::add_arg(desc_params, arg_restore_deterministic_wallet );
+ command_line::add_arg(desc_params, arg_restore_from_seed );
command_line::add_arg(desc_params, arg_restore_multisig_wallet );
command_line::add_arg(desc_params, arg_non_deterministic );
command_line::add_arg(desc_params, arg_electrum_seed );
diff --git a/tests/unit_tests/mul_div.cpp b/tests/unit_tests/mul_div.cpp
index b11f715cd..e3f7c34f3 100644
--- a/tests/unit_tests/mul_div.cpp
+++ b/tests/unit_tests/mul_div.cpp
@@ -130,6 +130,19 @@ namespace
// Division by zero is UB, so can be tested correctly
}
+ TEST(div128_64, handles_zero)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(0, 0, 7, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 0);
+ ASSERT_EQ(qlo, 0);
+
+ // Division by zero is UB, so can be tested correctly
+ }
+
TEST(div128_32, handles_one)
{
uint32_t reminder;
@@ -147,6 +160,23 @@ namespace
ASSERT_EQ(lo, 0);
}
+ TEST(div128_64, handles_one)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(0, 7, 1, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 0);
+ ASSERT_EQ(qlo, 7);
+
+ div128_64(7, 0, 1, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 7);
+ ASSERT_EQ(qlo, 0);
+ }
+
TEST(div128_32, handles_if_dividend_less_divider)
{
uint32_t reminder;
@@ -159,6 +189,17 @@ namespace
ASSERT_EQ(lo, 0);
}
+ TEST(div128_64, handles_if_dividend_less_divider)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(0, 1383746, 1645825, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 1383746);
+ ASSERT_EQ(qhi, 0);
+ ASSERT_EQ(qlo, 0);
+ }
+
TEST(div128_32, handles_if_dividend_dwords_less_divider)
{
uint32_t reminder;
@@ -171,6 +212,17 @@ namespace
ASSERT_EQ(lo, 0x9084FC024383E48C);
}
+ TEST(div128_64, handles_if_dividend_dwords_less_divider)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(0x5AD629E441074F28, 0x0DBCAB2B231081F1, 0xFE735CD6, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0xB9C924E9);
+ ASSERT_EQ(qhi, 0x000000005B63C274);
+ ASSERT_EQ(qlo, 0x9084FC024383E48C);
+ }
+
TEST(div128_32, works_correctly)
{
uint32_t reminder;
@@ -202,4 +254,68 @@ namespace
ASSERT_EQ(hi, 0x00000000f812c1f8);
ASSERT_EQ(lo, 0xddf2fdb09bc2e2e9);
}
+
+ TEST(div128_64, works_correctly)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(2, 0, 2, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 1);
+ ASSERT_EQ(qlo, 0);
+
+ div128_64(0xffffffffffffffff, 0, 0xffffffff, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 0x0000000100000001);
+ ASSERT_EQ(qlo, 0);
+
+ div128_64(0xffffffffffffffff, 5846, 0xffffffff, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 5846);
+ ASSERT_EQ(qhi, 0x0000000100000001);
+ ASSERT_EQ(qlo, 0);
+
+ div128_64(0xffffffffffffffff - 1, 0, 0xffffffff, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0xfffffffe);
+ ASSERT_EQ(qhi, 0x0000000100000000);
+ ASSERT_EQ(qlo, 0xfffffffefffffffe);
+
+ div128_64(0x2649372534875028, 0xaedbfedc5adbc739, 0x27826534, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0x1a6dc2e5);
+ ASSERT_EQ(qhi, 0x00000000f812c1f8);
+ ASSERT_EQ(qlo, 0xddf2fdb09bc2e2e9);
+ }
+
+ TEST(div128_64, divisor_above_32_bit)
+ {
+ uint64_t qhi, qlo, rhi, rlo;
+
+ div128_64(0, 0xffffffff, (uint64_t)0x100000000, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0xffffffff);
+ ASSERT_EQ(qhi, 0);
+ ASSERT_EQ(qlo, 0);
+
+ div128_64(0, 65, 4, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 1);
+ ASSERT_EQ(qhi, 0);
+ ASSERT_EQ(qlo, 16);
+
+ div128_64(405997335029502627ull, 2552775575832427192ull, 489327483788363ull, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 198332080500810ull);
+ ASSERT_EQ(qhi, 829ull);
+ ASSERT_EQ(qlo, 13000245803763621514ull);
+
+ div128_64(405997335029502627ull, 2552775575832427192ull, 1ull, &qhi, &qlo, &rhi, &rlo);
+ ASSERT_EQ(rhi, 0);
+ ASSERT_EQ(rlo, 0);
+ ASSERT_EQ(qhi, 405997335029502627ull);
+ ASSERT_EQ(qlo, 2552775575832427192ull);
+ }
}