aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--README.md3
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl2
-rw-r--r--src/cryptonote_config.h3
-rw-r--r--src/cryptonote_core/blockchain.cpp54
-rw-r--r--src/cryptonote_core/blockchain.h3
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp8
-rw-r--r--src/daemon/rpc_command_executor.cpp2
-rw-r--r--src/rpc/core_rpc_server.cpp3
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h50
-rw-r--r--src/simplewallet/simplewallet.cpp38
-rw-r--r--src/wallet/wallet2.cpp4
-rw-r--r--src/wallet/wallet_light_rpc.h47
-rw-r--r--src/wallet/wallet_rpc_server.cpp8
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h6
-rw-r--r--tests/core_tests/block_validation.cpp15
-rw-r--r--tests/core_tests/block_validation.h12
-rw-r--r--tests/core_tests/chaingen_main.cpp1
18 files changed, 165 insertions, 95 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 60fcf130e..e458d8ead 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,6 +34,7 @@ include(CheckCXXCompilerFlag)
include(CheckLinkerFlag)
include(CheckLibraryExists)
include(CheckFunctionExists)
+include(FindPythonInterp)
if (IOS)
INCLUDE(CmakeLists_IOS.txt)
diff --git a/README.md b/README.md
index e2413e1ab..322f6e783 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,9 @@ Portions Copyright (c) 2012-2013 The Cryptonote developers.
- [Release staging schedule and protocol](#release-staging-schedule-and-protocol)
- [Compiling Monero from source](#compiling-monero-from-source)
- [Dependencies](#dependencies)
+ - [Internationalization](#Internationalization)
+ - [Using Tor](#Using Tor)
+ - [Debugging](#Debugging)
- [Known issues](#known-issues)
## Development resources
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 12a87071a..8d96e4a84 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -154,7 +154,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}
else
{
- const auto ip_{remote_ep.address().to_v6()};
+ const auto ip_ = remote_ep.address().to_v6();
return start(is_income, is_multithreaded, ipv6_network_address{ip_, remote_ep.port()});
}
CATCH_ENTRY_L0("connection<t_protocol_handler>::start()", false);
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 173b454f6..4147b48ee 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -160,6 +160,9 @@
#define HF_VERSION_SMALLER_BP 10
#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT 10
#define HF_VERSION_MIN_2_OUTPUTS 12
+#define HF_VERSION_MIN_V2_COINBASE_TX 12
+#define HF_VERSION_SAME_MIXIN 12
+#define HF_VERSION_REJECT_SIGS_IN_COINBASE 12
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 8ed0e526a..798a73c4f 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -616,7 +616,7 @@ bool Blockchain::deinit()
// It starts a batch and calls private method pop_block_from_blockchain().
void Blockchain::pop_blocks(uint64_t nblocks)
{
- uint64_t i;
+ uint64_t i = 0;
CRITICAL_REGION_LOCAL(m_tx_pool);
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
@@ -627,9 +627,10 @@ void Blockchain::pop_blocks(uint64_t nblocks)
const uint64_t blockchain_height = m_db->height();
if (blockchain_height > 0)
nblocks = std::min(nblocks, blockchain_height - 1);
- for (i=0; i < nblocks; ++i)
+ while (i < nblocks)
{
pop_block_from_blockchain();
+ ++i;
}
}
catch (const std::exception& e)
@@ -1201,11 +1202,19 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
// one input, of type txin_gen, with height set to the block's height
// correct miner tx unlock time
// a non-overflowing tx amount (dubious necessity on this check)
-bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height)
+bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, uint8_t hf_version)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 1, false, "coinbase transaction in the block has no inputs");
CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type");
+ CHECK_AND_ASSERT_MES(b.miner_tx.version > 1 || hf_version < HF_VERSION_MIN_V2_COINBASE_TX, false, "Invalid coinbase transaction version");
+
+ // for v2 txes (ringct), we only accept empty rct signatures for miner transactions,
+ if (hf_version >= HF_VERSION_REJECT_SIGS_IN_COINBASE && b.miner_tx.version >= 2)
+ {
+ CHECK_AND_ASSERT_MES(b.miner_tx.rct_signatures.type == rct::RCTTypeNull, false, "RingCT signatures not allowed in coinbase transactions");
+ }
+
if(boost::get<txin_gen>(b.miner_tx.vin[0]).height != height)
{
MWARNING("The miner transaction in block has invalid height: " << boost::get<txin_gen>(b.miner_tx.vin[0]).height << ", expected: " << height);
@@ -1712,6 +1721,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
}
// this is a cheap test
+ const uint8_t hf_version = m_hardfork->get_ideal_version(block_height);
if (!m_hardfork->check_for_height(b, block_height))
{
LOG_PRINT_L1("Block with id: " << id << std::endl << "has old version for height " << block_height);
@@ -1770,7 +1780,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
return false;
}
- if(!prevalidate_miner_transaction(b, bei.height))
+ if(!prevalidate_miner_transaction(b, bei.height, hf_version))
{
MERROR_VER("Block with id: " << epee::string_tools::pod_to_hex(id) << " (as alternative) has incorrect miner transaction.");
bvc.m_verifivation_failed = true;
@@ -2858,7 +2868,8 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
if (hf_version >= 2)
{
size_t n_unmixable = 0, n_mixable = 0;
- size_t mixin = std::numeric_limits<size_t>::max();
+ size_t min_actual_mixin = std::numeric_limits<size_t>::max();
+ size_t max_actual_mixin = 0;
const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_10 ? 10 : hf_version >= HF_VERSION_MIN_MIXIN_6 ? 6 : hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2;
for (const auto& txin : tx.vin)
{
@@ -2883,29 +2894,43 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
else
++n_mixable;
}
- if (in_to_key.key_offsets.size() - 1 < mixin)
- mixin = in_to_key.key_offsets.size() - 1;
+ size_t ring_mixin = in_to_key.key_offsets.size() - 1;
+ if (ring_mixin < min_actual_mixin)
+ min_actual_mixin = ring_mixin;
+ if (ring_mixin > max_actual_mixin)
+ max_actual_mixin = ring_mixin;
}
}
+ MDEBUG("Mixin: " << min_actual_mixin << "-" << max_actual_mixin);
- if (((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_10+2 && mixin > 10))
+ if (hf_version >= HF_VERSION_SAME_MIXIN)
{
- MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (mixin + 1) << "), it should be 11");
+ if (min_actual_mixin != max_actual_mixin)
+ {
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has varying ring size (" << (min_actual_mixin + 1) << "-" << (max_actual_mixin + 1) << "), it should be constant");
+ tvc.m_low_mixin = true;
+ return false;
+ }
+ }
+
+ if (((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && min_actual_mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_10+2 && min_actual_mixin > 10))
+ {
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be 11");
tvc.m_low_mixin = true;
return false;
}
- if (mixin < min_mixin)
+ if (min_actual_mixin < min_mixin)
{
if (n_unmixable == 0)
{
- MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (mixin + 1) << "), and no unmixable inputs");
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (min_actual_mixin + 1) << "), and no unmixable inputs");
tvc.m_low_mixin = true;
return false;
}
if (n_mixable > 1)
{
- MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (mixin + 1) << "), and more than one mixable input with unmixable inputs");
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (min_actual_mixin + 1) << "), and more than one mixable input with unmixable inputs");
tvc.m_low_mixin = true;
return false;
}
@@ -3588,9 +3613,10 @@ leave:
}
// this is a cheap test
+ const uint8_t hf_version = get_current_hard_fork_version();
if (!m_hardfork->check(bl))
{
- MERROR_VER("Block with id: " << id << std::endl << "has old version: " << (unsigned)bl.major_version << std::endl << "current: " << (unsigned)m_hardfork->get_current_version());
+ MERROR_VER("Block with id: " << id << std::endl << "has old version: " << (unsigned)bl.major_version << std::endl << "current: " << (unsigned)hf_version);
bvc.m_verifivation_failed = true;
goto leave;
}
@@ -3695,7 +3721,7 @@ leave:
TIME_MEASURE_START(t3);
// sanity check basic miner tx properties;
- if(!prevalidate_miner_transaction(bl, blockchain_height))
+ if(!prevalidate_miner_transaction(bl, blockchain_height, hf_version))
{
MERROR_VER("Block with id: " << id << " failed to pass prevalidation");
bvc.m_verifivation_failed = true;
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index f58059a6d..f32645949 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -1245,10 +1245,11 @@ namespace cryptonote
*
* @param b the block containing the miner transaction
* @param height the height at which the block will be added
+ * @param hf_version the consensus rules to apply
*
* @return false if anything is found wrong with the miner transaction, otherwise true
*/
- bool prevalidate_miner_transaction(const block& b, uint64_t height);
+ bool prevalidate_miner_transaction(const block& b, uint64_t height, uint8_t hf_version);
/**
* @brief validates a miner (coinbase) transaction
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index a3a92ab60..0147bde23 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1630,18 +1630,18 @@ namespace cryptonote
return true;
HardFork::State state = m_blockchain_storage.get_hard_fork_state();
- const el::Level level = el::Level::Warning;
+ el::Level level;
switch (state) {
case HardFork::LikelyForked:
+ level = el::Level::Warning;
MCLOG_RED(level, "global", "**********************************************************************");
MCLOG_RED(level, "global", "Last scheduled hard fork is too far in the past.");
MCLOG_RED(level, "global", "We are most likely forked from the network. Daemon update needed now.");
MCLOG_RED(level, "global", "**********************************************************************");
break;
case HardFork::UpdateNeeded:
- MCLOG_RED(level, "global", "**********************************************************************");
- MCLOG_RED(level, "global", "Last scheduled hard fork time shows a daemon update is needed soon.");
- MCLOG_RED(level, "global", "**********************************************************************");
+ level = el::Level::Info;
+ MCLOG(level, "global", "Last scheduled hard fork time suggests a daemon update will be released within the next couple months.");
break;
default:
break;
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index d4b9434da..014865730 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -578,9 +578,9 @@ bool t_rpc_command_executor::mining_status() {
tools::msg_writer() << "Mining at " << get_mining_speed(mres.speed) << " with " << mres.threads_count << " threads";
}
+ tools::msg_writer() << "PoW algorithm: " << mres.pow_algorithm;
if (mres.active || mres.is_background_mining_enabled)
{
- tools::msg_writer() << "PoW algorithm: " << mres.pow_algorithm;
tools::msg_writer() << "Mining address: " << mres.address;
}
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 7706d2cf7..529cdbf2d 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1050,7 +1050,8 @@ namespace cryptonote
res.block_reward = lMiner.get_block_reward();
}
const account_public_address& lMiningAdr = lMiner.get_mining_address();
- res.address = get_account_address_as_str(nettype(), false, lMiningAdr);
+ if (lMiner.is_mining() || lMiner.get_is_background_mining_enabled())
+ res.address = get_account_address_as_str(nettype(), false, lMiningAdr);
const uint8_t major_version = m_core.get_blockchain_storage().get_current_hard_fork_version();
const unsigned variant = major_version >= 7 ? major_version - 6 : 0;
switch (variant)
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 325ac4343..2f7f22293 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -255,56 +255,6 @@ namespace cryptonote
};
typedef epee::misc_utils::struct_init<response_t> response;
};
-
- //-----------------------------------------------
- struct COMMAND_RPC_GET_RANDOM_OUTS
- {
- struct request_t
- {
- std::vector<std::string> amounts;
- uint32_t count;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(amounts)
- KV_SERIALIZE(count)
- END_KV_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<request_t> request;
-
-
- struct output {
- std::string public_key;
- uint64_t global_index;
- std::string rct; // 64+64+64 characters long (<rct commit> + <encrypted mask> + <rct amount>)
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(public_key)
- KV_SERIALIZE(global_index)
- KV_SERIALIZE(rct)
- END_KV_SERIALIZE_MAP()
- };
-
- struct amount_out {
- uint64_t amount;
- std::vector<output> outputs;
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(amount)
- KV_SERIALIZE(outputs)
- END_KV_SERIALIZE_MAP()
-
- };
-
- struct response_t
- {
- std::vector<amount_out> amount_outs;
- std::string Error;
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(amount_outs)
- KV_SERIALIZE(Error)
- END_KV_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<response_t> response;
- };
//-----------------------------------------------
struct COMMAND_RPC_SUBMIT_RAW_TX
{
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index eee2fa61d..fe384e529 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -2283,9 +2283,16 @@ bool simple_wallet::set_default_ring_size(const std::vector<std::string> &args/*
}
if (ring_size != 0 && ring_size != DEFAULT_MIX+1)
- message_writer() << tr("WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.");
- else if (ring_size == DEFAULT_MIX)
- message_writer() << tr("WARNING: from v8, ring size will be fixed and this setting will be ignored.");
+ {
+ if (m_wallet->use_fork_rules(8, 0))
+ {
+ message_writer() << tr("WARNING: from v8, ring size will be fixed and this setting will be ignored.");
+ }
+ else
+ {
+ message_writer() << tr("WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.");
+ }
+ }
const auto pwd_container = get_and_verify_password();
if (pwd_container)
@@ -4461,7 +4468,7 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
}
success_msg_writer() << "**********************************************************************";
- return std::move(password);
+ return password;
}
//----------------------------------------------------------------------------------------------------
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
@@ -4510,7 +4517,7 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
}
- return std::move(password);
+ return password;
}
//----------------------------------------------------------------------------------------------------
@@ -4553,7 +4560,7 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
return {};
}
- return std::move(password);
+ return password;
}
//----------------------------------------------------------------------------------------------------
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
@@ -4608,7 +4615,7 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
return {};
}
- return std::move(password);
+ return password;
}
//----------------------------------------------------------------------------------------------------
boost::optional<epee::wipeable_string> simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
@@ -4711,7 +4718,7 @@ boost::optional<epee::wipeable_string> simple_wallet::open_wallet(const boost::p
tr("Use the \"help\" command to see the list of available commands.\n") <<
tr("Use \"help <command>\" to see a command's documentation.\n") <<
"**********************************************************************";
- return std::move(password);
+ return password;
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::close_wallet()
@@ -5874,14 +5881,11 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = 0;
+ size_t fake_outs_count = DEFAULT_MIX;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
{
- fake_outs_count = m_wallet->default_mixin();
- if (fake_outs_count == 0)
- fake_outs_count = DEFAULT_MIX;
}
else if (ring_size == 0)
{
@@ -6495,14 +6499,11 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = 0;
+ size_t fake_outs_count = DEFAULT_MIX;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
{
- fake_outs_count = m_wallet->default_mixin();
- if (fake_outs_count == 0)
- fake_outs_count = DEFAULT_MIX;
}
else if (ring_size == 0)
{
@@ -6794,14 +6795,11 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = 0;
+ size_t fake_outs_count = DEFAULT_MIX;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
{
- fake_outs_count = m_wallet->default_mixin();
- if (fake_outs_count == 0)
- fake_outs_count = DEFAULT_MIX;
}
else if (ring_size == 0)
{
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 476c68c74..86169604a 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -7457,8 +7457,8 @@ void wallet2::light_wallet_get_outs(std::vector<std::vector<tools::wallet2::get_
MDEBUG("LIGHTWALLET - Getting random outs");
- cryptonote::COMMAND_RPC_GET_RANDOM_OUTS::request oreq;
- cryptonote::COMMAND_RPC_GET_RANDOM_OUTS::response ores;
+ tools::COMMAND_RPC_GET_RANDOM_OUTS::request oreq;
+ tools::COMMAND_RPC_GET_RANDOM_OUTS::response ores;
size_t light_wallet_requested_outputs_count = (size_t)((fake_outputs_count + 1) * 1.5 + 1);
diff --git a/src/wallet/wallet_light_rpc.h b/src/wallet/wallet_light_rpc.h
index 1d35cec33..c2a7dc021 100644
--- a/src/wallet/wallet_light_rpc.h
+++ b/src/wallet/wallet_light_rpc.h
@@ -317,4 +317,51 @@ namespace tools
typedef epee::misc_utils::struct_init<response_t> response;
};
//-----------------------------------------------
+ struct COMMAND_RPC_GET_RANDOM_OUTS
+ {
+ struct request_t
+ {
+ std::vector<std::string> amounts;
+ uint32_t count;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(amounts)
+ KV_SERIALIZE(count)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ struct output {
+ std::string public_key;
+ uint64_t global_index;
+ std::string rct; // 64+64+64 characters long (<rct commit> + <encrypted mask> + <rct amount>)
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(public_key)
+ KV_SERIALIZE(global_index)
+ KV_SERIALIZE(rct)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct amount_out {
+ uint64_t amount;
+ std::vector<output> outputs;
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(amount)
+ KV_SERIALIZE(outputs)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct response_t
+ {
+ std::vector<amount_out> amount_outs;
+ std::string Error;
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(amount_outs)
+ KV_SERIALIZE(Error)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<response_t> response;
+ };
+ //-----------------------------------------------
}
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 896f8f48e..765a6c24e 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -151,6 +151,7 @@ namespace tools
if (m_wallet)
{
m_wallet->store();
+ m_wallet->deinit();
delete m_wallet;
m_wallet = NULL;
}
@@ -326,6 +327,7 @@ namespace tools
entry.timestamp = pd.m_timestamp;
entry.amount = pd.m_amount;
entry.unlock_time = pd.m_unlock_time;
+ entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
entry.fee = pd.m_fee;
entry.note = m_wallet->get_tx_note(pd.m_tx_hash);
entry.type = pd.m_coinbase ? "block" : "in";
@@ -344,6 +346,7 @@ namespace tools
entry.height = pd.m_block_height;
entry.timestamp = pd.m_timestamp;
entry.unlock_time = pd.m_unlock_time;
+ entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
entry.fee = pd.m_amount_in - pd.m_amount_out;
uint64_t change = pd.m_change == (uint64_t)-1 ? 0 : pd.m_change; // change may not be known
entry.amount = pd.m_amount_in - change - entry.fee;
@@ -377,6 +380,7 @@ namespace tools
entry.fee = pd.m_amount_in - pd.m_amount_out;
entry.amount = pd.m_amount_in - pd.m_change - entry.fee;
entry.unlock_time = pd.m_tx.unlock_time;
+ entry.locked = true;
entry.note = m_wallet->get_tx_note(txid);
for (const auto &d: pd.m_dests) {
@@ -405,6 +409,7 @@ namespace tools
entry.timestamp = pd.m_timestamp;
entry.amount = pd.m_amount;
entry.unlock_time = pd.m_unlock_time;
+ entry.locked = true;
entry.fee = pd.m_fee;
entry.note = m_wallet->get_tx_note(pd.m_tx_hash);
entry.double_spend_seen = ppd.m_double_spend_seen;
@@ -1698,6 +1703,7 @@ namespace tools
rpc_payment.amount = payment.m_amount;
rpc_payment.block_height = payment.m_block_height;
rpc_payment.unlock_time = payment.m_unlock_time;
+ rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height);
rpc_payment.subaddr_index = payment.m_subaddr_index;
rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index);
res.payments.push_back(rpc_payment);
@@ -1727,6 +1733,7 @@ namespace tools
rpc_payment.unlock_time = payment.second.m_unlock_time;
rpc_payment.subaddr_index = payment.second.m_subaddr_index;
rpc_payment.address = m_wallet->get_subaddress_as_str(payment.second.m_subaddr_index);
+ rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.second.m_unlock_time, payment.second.m_block_height);
res.payments.push_back(std::move(rpc_payment));
}
@@ -1781,6 +1788,7 @@ namespace tools
rpc_payment.unlock_time = payment.m_unlock_time;
rpc_payment.subaddr_index = payment.m_subaddr_index;
rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index);
+ rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height);
res.payments.push_back(std::move(rpc_payment));
}
}
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index e9b8b60f5..d70de68be 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 14
+#define WALLET_RPC_VERSION_MINOR 15
#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
@@ -916,6 +916,7 @@ namespace wallet_rpc
uint64_t amount;
uint64_t block_height;
uint64_t unlock_time;
+ bool locked;
cryptonote::subaddress_index subaddr_index;
std::string address;
@@ -925,6 +926,7 @@ namespace wallet_rpc
KV_SERIALIZE(amount)
KV_SERIALIZE(block_height)
KV_SERIALIZE(unlock_time)
+ KV_SERIALIZE(locked)
KV_SERIALIZE(subaddr_index)
KV_SERIALIZE(address)
END_KV_SERIALIZE_MAP()
@@ -1364,6 +1366,7 @@ namespace wallet_rpc
std::list<transfer_destination> destinations;
std::string type;
uint64_t unlock_time;
+ bool locked;
cryptonote::subaddress_index subaddr_index;
std::vector<cryptonote::subaddress_index> subaddr_indices;
std::string address;
@@ -1382,6 +1385,7 @@ namespace wallet_rpc
KV_SERIALIZE(destinations);
KV_SERIALIZE(type);
KV_SERIALIZE(unlock_time)
+ KV_SERIALIZE(locked)
KV_SERIALIZE(subaddr_index);
KV_SERIALIZE(subaddr_indices);
KV_SERIALIZE(address);
diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp
index 566ec1440..55312bc15 100644
--- a/tests/core_tests/block_validation.cpp
+++ b/tests/core_tests/block_validation.cpp
@@ -640,3 +640,18 @@ bool gen_block_invalid_binary_format::check_all_blocks_purged(cryptonote::core&
return true;
}
+
+bool gen_block_late_v1_coinbase_tx::generate(std::vector<test_event_entry>& events) const
+{
+ BLOCK_VALIDATION_INIT_GENERATE();
+
+ block blk_1;
+ generator.construct_block_manually(blk_1, blk_0, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver,
+ HF_VERSION_MIN_V2_COINBASE_TX, HF_VERSION_MIN_V2_COINBASE_TX);
+ events.push_back(blk_1);
+
+ DO_CALLBACK(events, "check_block_purged");
+
+ return true;
+}
diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h
index 4a65b029e..2393e1b01 100644
--- a/tests/core_tests/block_validation.h
+++ b/tests/core_tests/block_validation.h
@@ -206,3 +206,15 @@ struct gen_block_invalid_binary_format : public test_chain_unit_base
private:
size_t m_corrupt_blocks_begin_idx;
};
+
+struct gen_block_late_v1_coinbase_tx : public gen_block_verification_base<1>
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<>
+struct get_test_options<gen_block_late_v1_coinbase_tx> {
+ const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_MIN_V2_COINBASE_TX, 1), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp
index cb35cfde2..4ee71466e 100644
--- a/tests/core_tests/chaingen_main.cpp
+++ b/tests/core_tests/chaingen_main.cpp
@@ -133,6 +133,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_block_has_invalid_tx);
GENERATE_AND_PLAY(gen_block_is_too_big);
GENERATE_AND_PLAY(gen_block_invalid_binary_format); // Takes up to 3 hours, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 500, up to 30 minutes, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 10
+ GENERATE_AND_PLAY(gen_block_late_v1_coinbase_tx);
// Transaction verification tests
GENERATE_AND_PLAY(gen_tx_big_version);