mirror of
https://github.com/monero-project/monero.git
synced 2025-12-10 23:00:54 -08:00
Compare commits
12 Commits
v0.12.3.0
...
release-v0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e631bd2d57 | ||
|
|
bcfb0a72a9 | ||
|
|
517faceb9e | ||
|
|
1f8bfe7ffa | ||
|
|
c6ce8235d8 | ||
|
|
3caa403893 | ||
|
|
58ee1f2bde | ||
|
|
f61cd54465 | ||
|
|
c7bca47b69 | ||
|
|
84a6e81de0 | ||
|
|
46b697feb4 | ||
|
|
cfea525ea3 |
@@ -158,6 +158,7 @@ namespace net_utils
|
||||
std::list<boost::shared_ptr<connection<t_protocol_handler> > > m_self_refs; // add_ref/release support
|
||||
critical_section m_self_refs_lock;
|
||||
critical_section m_chunking_lock; // held while we add small chunks of the big do_send() to small do_send_chunk()
|
||||
critical_section m_shutdown_lock; // held while shutting down
|
||||
|
||||
t_connection_type m_connection_type;
|
||||
|
||||
|
||||
@@ -649,6 +649,10 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
template<class t_protocol_handler>
|
||||
bool connection<t_protocol_handler>::shutdown()
|
||||
{
|
||||
CRITICAL_REGION_BEGIN(m_shutdown_lock);
|
||||
if (m_was_shutdown)
|
||||
return true;
|
||||
m_was_shutdown = true;
|
||||
// Initiate graceful connection closure.
|
||||
m_timer.cancel();
|
||||
boost::system::error_code ignored_ec;
|
||||
@@ -658,7 +662,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
try { host_count(m_host, -1); } catch (...) { /* ignore */ }
|
||||
m_host = "";
|
||||
}
|
||||
m_was_shutdown = true;
|
||||
CRITICAL_REGION_END();
|
||||
m_protocol_handler.release_protocol();
|
||||
return true;
|
||||
}
|
||||
@@ -667,6 +671,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
bool connection<t_protocol_handler>::close()
|
||||
{
|
||||
TRY_ENTRY();
|
||||
auto self = safe_shared_from_this();
|
||||
if(!self)
|
||||
return false;
|
||||
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
|
||||
m_timer.cancel();
|
||||
size_t send_que_size = 0;
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace epee
|
||||
storage_entry load_storage_entry();
|
||||
void read(section& sec);
|
||||
void read(std::string& str);
|
||||
void read(array_entry &ae);
|
||||
private:
|
||||
struct recursuion_limitation_guard
|
||||
{
|
||||
@@ -114,6 +115,7 @@ namespace epee
|
||||
void throwable_buffer_reader::read(t_pod_type& pod_val)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
static_assert(std::is_pod<t_pod_type>::value, "POD type expected");
|
||||
read(&pod_val, sizeof(pod_val));
|
||||
}
|
||||
|
||||
@@ -277,5 +279,11 @@ namespace epee
|
||||
m_ptr+=len;
|
||||
m_count -= len;
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(array_entry &ae)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "Reading array entry is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "parserse_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100
|
||||
|
||||
namespace epee
|
||||
{
|
||||
using namespace misc_utils::parse;
|
||||
@@ -44,8 +46,9 @@ namespace epee
|
||||
ASSERT_MES_AND_THROW("json parse error");
|
||||
}*/
|
||||
template<class t_storage>
|
||||
inline void run_handler(typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg)
|
||||
inline void run_handler(typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg, unsigned int recursion)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(recursion < EPEE_JSON_RECURSION_LIMIT_INTERNAL, "Wrong JSON data: recursion limitation (" << EPEE_JSON_RECURSION_LIMIT_INTERNAL << ") exceeded");
|
||||
|
||||
std::string::const_iterator sub_element_start;
|
||||
std::string name;
|
||||
@@ -157,7 +160,7 @@ namespace epee
|
||||
//sub section here
|
||||
typename t_storage::hsection new_sec = stg.open_section(name, current_section, true);
|
||||
CHECK_AND_ASSERT_THROW_MES(new_sec, "Failed to insert new section in json: " << std::string(it, buf_end));
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
run_handler(new_sec, it, buf_end, stg, recursion + 1);
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(*it == '[')
|
||||
{//array of something
|
||||
@@ -186,7 +189,7 @@ namespace epee
|
||||
typename t_storage::hsection new_sec = nullptr;
|
||||
h_array = stg.insert_first_section(name, new_sec, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec, "failed to create new section");
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
run_handler(new_sec, it, buf_end, stg, recursion + 1);
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_sections;
|
||||
}else if(*it == '"')
|
||||
@@ -260,7 +263,7 @@ namespace epee
|
||||
typename t_storage::hsection new_sec = NULL;
|
||||
bool res = stg.insert_next_section(h_array, new_sec);
|
||||
CHECK_AND_ASSERT_THROW_MES(res&&new_sec, "failed to insert next section");
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
run_handler(new_sec, it, buf_end, stg, recursion + 1);
|
||||
state = match_state_array_after_value;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
@@ -362,7 +365,7 @@ namespace epee
|
||||
std::string::const_iterator sec_buf_begin = buff_json.begin();
|
||||
try
|
||||
{
|
||||
run_handler(nullptr, sec_buf_begin, buff_json.end(), stg);
|
||||
run_handler(nullptr, sec_buf_begin, buff_json.end(), stg, 0);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception& ex)
|
||||
|
||||
@@ -630,7 +630,7 @@ bool simple_wallet::print_seed(bool encrypted)
|
||||
epee::wipeable_string seed_pass;
|
||||
if (encrypted)
|
||||
{
|
||||
auto pwd_container = password_prompter(tr("Enter optional seed encryption passphrase, empty to see raw seed"), true);
|
||||
auto pwd_container = password_prompter(tr("Enter optional seed offset passphrase, empty to see raw seed"), true);
|
||||
if (std::cin.eof() || !pwd_container)
|
||||
return true;
|
||||
seed_pass = pwd_container->password();
|
||||
@@ -2653,7 +2653,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
}
|
||||
}
|
||||
|
||||
auto pwd_container = password_prompter(tr("Enter seed encryption passphrase, empty if none"), false);
|
||||
auto pwd_container = password_prompter(tr("Enter seed offset passphrase, empty if none"), false);
|
||||
if (std::cin.eof() || !pwd_container)
|
||||
return false;
|
||||
epee::wipeable_string seed_pass = pwd_container->password();
|
||||
|
||||
@@ -1106,7 +1106,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
// (that is, the prunable stuff may or may not be included)
|
||||
if (!miner_tx && !pool)
|
||||
process_unconfirmed(txid, tx, height);
|
||||
std::vector<size_t> outs;
|
||||
std::unordered_map<cryptonote::subaddress_index, uint64_t> tx_money_got_in_outs; // per receiving subaddress index
|
||||
crypto::public_key tx_pub_key = null_pkey;
|
||||
|
||||
@@ -1121,8 +1120,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
size_t pk_index = 0;
|
||||
std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size());
|
||||
std::deque<bool> output_found(tx.vout.size(), false);
|
||||
uint64_t total_received_1 = 0;
|
||||
while (!tx.vout.empty())
|
||||
{
|
||||
std::vector<size_t> outs;
|
||||
// if tx.vout is not empty, we loop through all tx pubkeys
|
||||
|
||||
tx_extra_pub_key pub_key_field;
|
||||
@@ -1266,6 +1267,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
+ ", m_transfers.size() is " + boost::lexical_cast<std::string>(m_transfers.size()));
|
||||
if (kit == m_pub_keys.end())
|
||||
{
|
||||
uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount;
|
||||
if (!pool)
|
||||
{
|
||||
m_transfers.push_back(boost::value_initialized<transfer_details>());
|
||||
@@ -1278,14 +1280,13 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
td.m_key_image = tx_scan_info[o].ki;
|
||||
td.m_key_image_known = !m_watch_only && !m_multisig;
|
||||
td.m_key_image_partial = m_multisig;
|
||||
td.m_amount = tx.vout[o].amount;
|
||||
td.m_amount = amount;
|
||||
td.m_pk_index = pk_index - 1;
|
||||
td.m_subaddr_index = tx_scan_info[o].received->index;
|
||||
expand_subaddresses(tx_scan_info[o].received->index);
|
||||
if (td.m_amount == 0)
|
||||
if (tx.vout[o].amount == 0)
|
||||
{
|
||||
td.m_mask = tx_scan_info[o].mask;
|
||||
td.m_amount = tx_scan_info[o].amount;
|
||||
td.m_rct = true;
|
||||
}
|
||||
else if (miner_tx && tx.version == 2)
|
||||
@@ -1313,6 +1314,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
if (0 != m_callback)
|
||||
m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index);
|
||||
}
|
||||
total_received_1 += amount;
|
||||
}
|
||||
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx_scan_info[o].amount)
|
||||
{
|
||||
@@ -1320,6 +1322,9 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
<< " from received " << print_money(tx_scan_info[o].amount) << " output already exists with "
|
||||
<< (m_transfers[kit->second].m_spent ? "spent" : "unspent") << " "
|
||||
<< print_money(m_transfers[kit->second].amount()) << " in tx " << m_transfers[kit->second].m_txid << ", received output ignored");
|
||||
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info[o].received->index] < tx_scan_info[o].amount,
|
||||
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1327,8 +1332,14 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
<< " from received " << print_money(tx_scan_info[o].amount) << " output already exists with "
|
||||
<< print_money(m_transfers[kit->second].amount()) << ", replacing with new output");
|
||||
// The new larger output replaced a previous smaller one
|
||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount;
|
||||
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info[o].received->index] < tx_scan_info[o].amount,
|
||||
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
||||
THROW_WALLET_EXCEPTION_IF(m_transfers[kit->second].amount() > tx_scan_info[o].amount,
|
||||
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= m_transfers[kit->second].amount();
|
||||
|
||||
uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount;
|
||||
uint64_t extra_amount = amount - m_transfers[kit->second].amount();
|
||||
if (!pool)
|
||||
{
|
||||
transfer_details &td = m_transfers[kit->second];
|
||||
@@ -1337,14 +1348,13 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
td.m_global_output_index = o_indices[o];
|
||||
td.m_tx = (const cryptonote::transaction_prefix&)tx;
|
||||
td.m_txid = txid;
|
||||
td.m_amount = tx.vout[o].amount;
|
||||
td.m_amount = amount;
|
||||
td.m_pk_index = pk_index - 1;
|
||||
td.m_subaddr_index = tx_scan_info[o].received->index;
|
||||
expand_subaddresses(tx_scan_info[o].received->index);
|
||||
if (td.m_amount == 0)
|
||||
if (tx.vout[o].amount == 0)
|
||||
{
|
||||
td.m_mask = tx_scan_info[o].mask;
|
||||
td.m_amount = tx_scan_info[o].amount;
|
||||
td.m_rct = true;
|
||||
}
|
||||
else if (miner_tx && tx.version == 2)
|
||||
@@ -1371,6 +1381,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
if (0 != m_callback)
|
||||
m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index);
|
||||
}
|
||||
total_received_1 += extra_amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1444,10 +1455,14 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
}
|
||||
|
||||
// remove change sent to the spending subaddress account from the list of received funds
|
||||
uint64_t sub_change = 0;
|
||||
for (auto i = tx_money_got_in_outs.begin(); i != tx_money_got_in_outs.end();)
|
||||
{
|
||||
if (subaddr_account && i->first.major == *subaddr_account)
|
||||
{
|
||||
sub_change += i->second;
|
||||
i = tx_money_got_in_outs.erase(i);
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
@@ -1494,6 +1509,20 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id);
|
||||
}
|
||||
|
||||
uint64_t total_received_2 = sub_change;
|
||||
for (const auto& i : tx_money_got_in_outs)
|
||||
total_received_2 += i.second;
|
||||
if (total_received_1 != total_received_2)
|
||||
{
|
||||
const el::Level level = el::Level::Warning;
|
||||
MCLOG_RED(level, "global", "**********************************************************************");
|
||||
MCLOG_RED(level, "global", "Consistency failure in amounts received");
|
||||
MCLOG_RED(level, "global", "Check transaction " << txid);
|
||||
MCLOG_RED(level, "global", "**********************************************************************");
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& i : tx_money_got_in_outs)
|
||||
{
|
||||
payment_details payment;
|
||||
|
||||
Reference in New Issue
Block a user