aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cryptonote_core/blockchain.cpp19
-rw-r--r--src/cryptonote_core/blockchain.h2
-rw-r--r--src/cryptonote_core/blockchain_storage.cpp19
-rw-r--r--src/cryptonote_core/blockchain_storage.h1
-rw-r--r--src/daemon/command_parser_executor.cpp18
-rw-r--r--src/daemon/command_parser_executor.h2
-rw-r--r--src/daemon/command_server.cpp5
-rw-r--r--src/daemon/rpc_command_executor.cpp30
-rw-r--r--src/daemon/rpc_command_executor.h2
-rw-r--r--src/rpc/core_rpc_server.cpp54
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h21
12 files changed, 175 insertions, 0 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index b27927c0a..bf17544fc 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2386,6 +2386,25 @@ void Blockchain::return_tx_to_pool(const std::vector<transaction> &txs)
}
}
//------------------------------------------------------------------
+bool Blockchain::flush_txes_from_pool(const std::list<crypto::hash> &txids)
+{
+ bool res = true;
+ for (const auto &txid: txids)
+ {
+ cryptonote::transaction tx;
+ size_t blob_size;
+ uint64_t fee;
+ bool relayed;
+ LOG_PRINT_L1("Removing txid " << txid << " from the pool");
+ if(!m_tx_pool.take_tx(txid, tx, blob_size, fee, relayed))
+ {
+ LOG_PRINT_L0("Failed to remove txid " << txid << " from the pool");
+ res = false;
+ }
+ }
+ return res;
+}
+//------------------------------------------------------------------
// Needs to validate the block and acquire each transaction from the
// transaction mem_pool, then pass the block and transactions to
// m_db->add_block()
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 87c8a2454..ecabf5376 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -164,6 +164,8 @@ namespace cryptonote
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 flush_txes_from_pool(const std::list<crypto::hash> &txids);
+
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;
bool for_all_transactions(std::function<bool(const crypto::hash&, const cryptonote::transaction&)>) const;
diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp
index f656f938b..e1b89f887 100644
--- a/src/cryptonote_core/blockchain_storage.cpp
+++ b/src/cryptonote_core/blockchain_storage.cpp
@@ -1892,6 +1892,25 @@ void blockchain_storage::set_enforce_dns_checkpoints(bool enforce_checkpoints)
m_enforce_dns_checkpoints = enforce_checkpoints;
}
//------------------------------------------------------------------
+bool blockchain_storage::flush_txes_from_pool(const std::list<crypto::hash> &txids)
+{
+ bool res = true;
+ for (const auto &txid: txids)
+ {
+ cryptonote::transaction tx;
+ size_t blob_size;
+ uint64_t fee;
+ bool relayed;
+ LOG_PRINT_L1("Removing txid " << txid << " from the pool");
+ if(!m_tx_pool->take_tx(txid, tx, blob_size, fee, relayed))
+ {
+ LOG_PRINT_L0("Failed to remove txid " << txid << " from the pool");
+ res = false;
+ }
+ }
+ return res;
+}
+//------------------------------------------------------------------
bool blockchain_storage::for_all_key_images(std::function<bool(const crypto::key_image&)> f) const
{
for (key_images_container::const_iterator i = m_spent_keys.begin(); i != m_spent_keys.end(); ++i) {
diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h
index cb5e17cdb..878202cf1 100644
--- a/src/cryptonote_core/blockchain_storage.h
+++ b/src/cryptonote_core/blockchain_storage.h
@@ -130,6 +130,7 @@ namespace cryptonote
bool is_storing_blockchain()const{return m_is_blockchain_storing;}
uint64_t block_difficulty(size_t i) const;
double get_avg_block_size( size_t count) const;
+ bool flush_txes_from_pool(const std::list<crypto::hash> &txids);
template<class t_ids_container, class t_blocks_container, class t_missed_container>
bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) const
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index d1d48b6da..0b42257e7 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -421,5 +421,23 @@ bool t_command_parser_executor::unban(const std::vector<std::string>& args)
return m_executor.unban(ip);
}
+bool t_command_parser_executor::flush_txpool(const std::vector<std::string>& args)
+{
+ if (args.size() > 1) return false;
+
+ std::string txid;
+ if (args.size() == 1)
+ {
+ crypto::hash hash;
+ if (!parse_hash256(args[0], hash))
+ {
+ std::cout << "failed to parse tx id" << std::endl;
+ return true;
+ }
+ txid = args[0];
+ }
+ return m_executor.flush_txpool(txid);
+}
+
} // namespace daemonize
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index 2d9315df8..51c55a8c0 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -112,6 +112,8 @@ public:
bool ban(const std::vector<std::string>& args);
bool unban(const std::vector<std::string>& args);
+
+ bool flush_txpool(const std::vector<std::string>& args);
};
} // namespace daemonize
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index f99b0844a..206de9d4a 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -209,6 +209,11 @@ t_command_server::t_command_server(
, std::bind(&t_command_parser_executor::unban, &m_parser, p::_1)
, "Unban a given IP"
);
+ m_command_lookup.set_handler(
+ "flush_txpool"
+ , std::bind(&t_command_parser_executor::flush_txpool, &m_parser, p::_1)
+ , "Flush a transaction from the tx pool by its txid, or the whole tx pool"
+ );
}
bool t_command_server::process_command_str(const std::string& cmd)
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 6809f68b9..1ab1c8ed8 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -1161,4 +1161,34 @@ bool t_rpc_command_executor::unban(const std::string &ip)
return true;
}
+bool t_rpc_command_executor::flush_txpool(const std::string &txid)
+{
+ cryptonote::COMMAND_RPC_FLUSH_TRANSACTION_POOL::request req;
+ cryptonote::COMMAND_RPC_FLUSH_TRANSACTION_POOL::response res;
+ std::string fail_message = "Unsuccessful";
+ epee::json_rpc::error error_resp;
+
+ if (!txid.empty())
+ req.txids.push_back(txid);
+
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->json_rpc_request(req, res, "flush_txpool", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_flush_txpool(req, res, error_resp))
+ {
+ tools::fail_msg_writer() << fail_message.c_str();
+ return true;
+ }
+ }
+
+ return true;
+}
+
+
}// namespace daemonize
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index 9589dff64..bc3f2d5c5 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -130,6 +130,8 @@ public:
bool ban(const std::string &ip, time_t seconds);
bool unban(const std::string &ip);
+
+ bool flush_txpool(const std::string &txid);
};
} // namespace daemonize
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 4a6f8e671..3ce4e6006 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -984,6 +984,60 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp)
+ {
+ if(!check_core_busy())
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;
+ error_resp.message = "Core is busy.";
+ return false;
+ }
+
+ bool failed = false;
+ std::list<crypto::hash> txids;
+ if (req.txids.empty())
+ {
+ std::list<transaction> pool_txs;
+ bool r = m_core.get_pool_transactions(pool_txs);
+ if (!r)
+ {
+ res.status = "Failed to get txpool contents";
+ return true;
+ }
+ for (const auto &tx: pool_txs)
+ {
+ txids.push_back(cryptonote::get_transaction_hash(tx));
+ }
+ }
+ else
+ {
+ for (const auto &str: req.txids)
+ {
+ cryptonote::blobdata txid_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(str, txid_data))
+ {
+ failed = true;
+ }
+ crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
+ txids.push_back(txid);
+ }
+ }
+ if (!m_core.get_blockchain_storage().flush_txes_from_pool(txids))
+ {
+ res.status = "Failed to remove one more tx";
+ return false;
+ }
+
+ if (failed)
+ {
+ res.status = "Failed to parse txid";
+ return false;
+ }
+
+ res.status = CORE_RPC_STATUS_OK;
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_fast_exit(const COMMAND_RPC_FAST_EXIT::request& req, COMMAND_RPC_FAST_EXIT::response& res)
{
cryptonote::core::set_fast_exit();
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 4ff6cc8ab..f79087030 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -108,6 +108,7 @@ namespace cryptonote
MAP_JON_RPC_WE("hard_fork_info", on_hard_fork_info, COMMAND_RPC_HARD_FORK_INFO)
MAP_JON_RPC_WE("setbans", on_set_bans, COMMAND_RPC_SETBANS)
MAP_JON_RPC_WE("getbans", on_get_bans, COMMAND_RPC_GETBANS)
+ MAP_JON_RPC_WE("flush_txpool", on_flush_txpool, COMMAND_RPC_FLUSH_TRANSACTION_POOL)
END_JSON_RPC_MAP()
END_URI_MAP2()
@@ -147,6 +148,7 @@ namespace cryptonote
bool on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp);
bool on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp);
bool on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp);
+ bool on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp);
//-----------------------
private:
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 772d1d942..72e399ec4 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -965,5 +965,26 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
};
+
+ struct COMMAND_RPC_FLUSH_TRANSACTION_POOL
+ {
+ struct request
+ {
+ std::list<std::string> txids;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(txids)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct response
+ {
+ std::string status;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(status)
+ END_KV_SERIALIZE_MAP()
+ };
+ };
}