aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/perf_timer.h2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp14
-rw-r--r--src/cryptonote_core/cryptonote_core.h5
-rw-r--r--src/cryptonote_core/tx_pool.cpp5
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl3
-rw-r--r--src/daemon/rpc_command_executor.cpp2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h4
-rw-r--r--src/wallet/api/wallet.cpp20
-rw-r--r--src/wallet/wallet2.cpp7
-rw-r--r--src/wallet/wallet2_api.h2
10 files changed, 63 insertions, 1 deletions
diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h
index 3d732012d..5eb5aaaec 100644
--- a/src/common/perf_timer.h
+++ b/src/common/perf_timer.h
@@ -68,7 +68,7 @@ public:
performance_timers->pop_back();
ticks = epee::misc_utils::get_tick_count() - ticks;
char s[12];
- snprintf(s, sizeof(s), "%8lu ", ticks);
+ snprintf(s, sizeof(s), "%8llu ", (unsigned long long)ticks);
LOG_PRINT("PERF " << s << std::string(performance_timers->size() * 2, ' ') << " " << name, level);
if (performance_timers->empty())
{
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index a82d96416..95c49f627 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -709,6 +709,20 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
+ void core::on_transaction_relayed(const cryptonote::blobdata& tx_blob)
+ {
+ std::list<std::pair<crypto::hash, cryptonote::transaction>> txs;
+ cryptonote::transaction tx;
+ crypto::hash tx_hash, tx_prefix_hash;
+ if (!parse_and_validate_tx_from_blob(tx_blob, tx, tx_hash, tx_prefix_hash))
+ {
+ LOG_ERROR("Failed to parse relayed tranasction");
+ return;
+ }
+ txs.push_back(std::make_pair(tx_hash, std::move(tx)));
+ m_mempool.set_relayed(txs);
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce)
{
return m_blockchain_storage.create_block_template(b, adr, diffic, height, ex_nonce);
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index d925a184d..a5a97a5ad 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -180,6 +180,11 @@ namespace cryptonote
*/
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce);
+ /**
+ * @brief called when a transaction is relayed
+ */
+ virtual void on_transaction_relayed(const cryptonote::blobdata& tx);
+
/**
* @brief gets the miner instance
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 178cbda3c..dba05a539 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -387,7 +387,10 @@ namespace cryptonote
{
auto i = m_transactions.find(it->first);
if (i != m_transactions.end())
+ {
+ i->second.relayed = true;
i->second.last_relayed_time = now;
+ }
}
}
//---------------------------------------------------------------------------------
@@ -422,6 +425,8 @@ namespace cryptonote
txi.last_failed_height = txd.last_failed_height;
txi.last_failed_id_hash = epee::string_tools::pod_to_hex(txd.last_failed_id);
txi.receive_time = txd.receive_time;
+ txi.relayed = txd.relayed;
+ txi.last_relayed_time = txd.last_relayed_time;
tx_infos.push_back(txi);
}
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 1d1cd3631..5232d550a 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -780,6 +780,9 @@ namespace cryptonote
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context)
{
+ // no check for success, so tell core they're relayed unconditionally
+ for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end(); ++tx_blob_it)
+ m_core.on_transaction_relayed(*tx_blob_it);
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
}
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 525e87e74..8c6d5dec4 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -734,6 +734,7 @@ bool t_rpc_command_executor::print_transaction_pool_long() {
<< "blob_size: " << tx_info.blob_size << std::endl
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
<< "receive_time: " << tx_info.receive_time << " (" << get_human_time_ago(tx_info.receive_time, now) << ")" << std::endl
+ << "relayed: " << [&](const cryptonote::tx_info &tx_info)->std::string { if (!tx_info.relayed) return "no"; return boost::lexical_cast<std::string>(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")"; } (tx_info) << std::endl
<< "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl
<< "max_used_block_height: " << tx_info.max_used_block_height << std::endl
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
@@ -813,6 +814,7 @@ bool t_rpc_command_executor::print_transaction_pool_short() {
<< "blob_size: " << tx_info.blob_size << std::endl
<< "fee: " << cryptonote::print_money(tx_info.fee) << std::endl
<< "receive_time: " << tx_info.receive_time << " (" << get_human_time_ago(tx_info.receive_time, now) << ")" << std::endl
+ << "relayed: " << [&](const cryptonote::tx_info &tx_info)->std::string { if (!tx_info.relayed) return "no"; return boost::lexical_cast<std::string>(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")"; } (tx_info) << std::endl
<< "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl
<< "max_used_block_height: " << tx_info.max_used_block_height << std::endl
<< "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 64f7ebf5e..85895a71a 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -857,6 +857,8 @@ namespace cryptonote
uint64_t last_failed_height;
std::string last_failed_id_hash;
uint64_t receive_time;
+ bool relayed;
+ uint64_t last_relayed_time;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id_hash)
@@ -869,6 +871,8 @@ namespace cryptonote
KV_SERIALIZE(last_failed_height)
KV_SERIALIZE(last_failed_id_hash)
KV_SERIALIZE(receive_time)
+ KV_SERIALIZE(relayed)
+ KV_SERIALIZE(last_failed_id_hash)
END_KV_SERIALIZE_MAP()
};
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 747263b54..9a9638b40 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -167,6 +167,26 @@ bool Wallet::paymentIdValid(const string &paiment_id)
return false;
}
+bool Wallet::addressValid(const std::string &str, bool testnet)
+{
+ bool has_payment_id;
+ cryptonote::account_public_address address;
+ crypto::hash8 pid;
+ return get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, str);
+}
+
+std::string Wallet::paymentIdFromAddress(const std::string &str, bool testnet)
+{
+ bool has_payment_id;
+ cryptonote::account_public_address address;
+ crypto::hash8 pid;
+ if (!get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, str))
+ return "";
+ if (!has_payment_id)
+ return "";
+ return epee::string_tools::pod_to_hex(pid);
+}
+
uint64_t Wallet::maximumAllowedAmount()
{
return std::numeric_limits<uint64_t>::max();
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index b499f6b24..23e016f7b 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2523,6 +2523,13 @@ void wallet2::commit_tx(pending_tx& ptx)
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "sendrawtransaction");
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status, daemon_send_resp.reason);
+ // sanity checks
+ for (size_t idx: ptx.selected_transfers)
+ {
+ THROW_WALLET_EXCEPTION_IF(idx >= m_transfers.size(), error::wallet_internal_error,
+ "Bad output index in selected transfers: " + boost::lexical_cast<std::string>(idx));
+ }
+
txid = get_transaction_hash(ptx.tx);
crypto::hash payment_id = cryptonote::null_hash;
std::vector<cryptonote::tx_destination_entry> dests;
diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h
index 0f622c26c..8427ba250 100644
--- a/src/wallet/wallet2_api.h
+++ b/src/wallet/wallet2_api.h
@@ -280,6 +280,8 @@ struct Wallet
static uint64_t amountFromDouble(double amount);
static std::string genPaymentId();
static bool paymentIdValid(const std::string &paiment_id);
+ static bool addressValid(const std::string &str, bool testnet);
+ static std::string paymentIdFromAddress(const std::string &str, bool testnet);
static uint64_t maximumAllowedAmount();
/**