1
0
Fork 0
forked from lthn/blockchain

Implemented multiple map rpc processing(lets chain RPC processing to different handlers maps in different objects)

This commit is contained in:
cryptozoidberg 2023-05-24 23:43:44 +02:00
parent a9bbfdcf82
commit 3fec14f95e
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
7 changed files with 118 additions and 13 deletions

View file

@ -29,6 +29,7 @@
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage_template_helper.h"
#include "http_base.h"
#include "net/net_utils_base.h"
template<typename request_t, typename response_t>
bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference)
@ -51,6 +52,20 @@ bool auto_doc(const std::string& prefix_name, std::string& generate_reference)
return auto_doc_t<typename command_type_t::request, typename command_type_t::response>(prefix_name, generate_reference);
}
namespace epee {
namespace net_utils {
namespace http {
struct i_chain_handler
{
virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response_info,
epee::net_utils::connection_context_base& m_conn_context, bool& call_found, std::string& generate_reference) = 0;
};
}
}
}
#define CHAIN_HTTP_TO_MAP2(context_type) bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, \
epee::net_utils::http::http_response_info& response, \
@ -73,6 +88,13 @@ bool auto_doc(const std::string& prefix_name, std::string& generate_reference)
call_found = false; \
if(false) return true; //just a stub to have "else if"
#define BEGIN_URI_MAP2_VIRTUAL() virtual bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \
epee::net_utils::http::http_response_info& response_info, \
epee::net_utils::connection_context_base& m_conn_context, bool& call_found, std::string& generate_reference) { \
call_found = false; \
if(false) return true; //just a stub to have "else if"
#define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, m_conn_context);
#define MAP_URI_AUTO_XML2(s_pattern, callback_f, command_type) //TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
@ -117,6 +139,8 @@ bool auto_doc(const std::string& prefix_name, std::string& generate_reference)
LOG_PRINT( "[HTTP/BIN][" << epee::string_tools::get_ip_string_from_int32(m_conn_context.m_remote_ip ) << "][" << query_info.m_URI << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2); \
}
#define CHAIN_TO_PHANDLER(pi_chain_handler) else if (pi_chain_handler && pi_chain_handler->handle_http_request_map(query_info, response_info, m_conn_context, call_found, generate_reference) && call_found) { return true;}
#define CHAIN_URI_MAP2(callback) else {callback(query_info, response_info, m_conn_context);call_found = true;}
#define END_URI_MAP2() return true;}
@ -287,6 +311,7 @@ struct json_command_type_t
#define MAP_JON_RPC_WE(method_name, callback_f, command_type) \
else if(auto_doc<json_command_type_t<command_type>>("[" method_name "]", generate_reference) && callback_name == method_name) \
{ \
call_found = true; \
PREPARE_OBJECTS_FROM_JSON(command_type) \
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
fail_resp.jsonrpc = "2.0"; \
@ -304,6 +329,7 @@ struct json_command_type_t
#define MAP_JON_RPC_WERI(method_name, callback_f, command_type) \
else if(auto_doc<json_command_type_t<command_type>>("[" method_name "]", generate_reference) && callback_name == method_name) \
{ \
call_found = true; \
PREPARE_OBJECTS_FROM_JSON(command_type) \
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
fail_resp.jsonrpc = "2.0"; \
@ -321,6 +347,7 @@ struct json_command_type_t
#define MAP_JON_RPC(method_name, callback_f, command_type) \
else if(auto_doc<json_command_type_t<command_type>>(std::string("[") + method_name + "]", generate_reference) && callback_name == method_name) \
{ \
call_found = true; \
PREPARE_OBJECTS_FROM_JSON(command_type) \
if(!callback_f(req.params, resp.result, m_conn_context)) \
{ \

View file

@ -84,6 +84,8 @@ namespace epee
template<typename t_proxy_object, typename t_proxy_lock_time_watching_policy>
friend class locked_object_proxy;
public:
typedef std::shared_ptr<locked_object_proxy<t_object, lock_time_watching_policy>> lock_shared_ptr;
std::shared_ptr<locked_object_proxy<t_object, lock_time_watching_policy>> lock()
{
std::shared_ptr<locked_object_proxy<t_object, lock_time_watching_policy>> res;

View file

@ -37,6 +37,7 @@ namespace currency
static void init_options(boost::program_options::options_description& desc);
bool init(const boost::program_options::variables_map& vm);
void set_rpc_chain_handler(epee::net_utils::http::i_chain_handler* prpc_chain_handler) { m_prpc_chain_handler = prpc_chain_handler; }
bool on_get_blocks_direct(const COMMAND_RPC_GET_BLOCKS_DIRECT::request& req, COMMAND_RPC_GET_BLOCKS_DIRECT::response& res, connection_context& cntx);
@ -149,7 +150,9 @@ namespace currency
MAP_JON_RPC ("get_current_core_tx_expiration_median", on_get_current_core_tx_expiration_median, COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN)
//
MAP_JON_RPC_WE("marketplace_global_get_offers_ex", on_get_offers_ex, COMMAND_RPC_GET_OFFERS_EX)
CHAIN_TO_PHANDLER(m_prpc_chain_handler)
END_JSON_RPC_MAP()
CHAIN_TO_PHANDLER(m_prpc_chain_handler)
END_URI_MAP2()
private:
@ -170,6 +173,7 @@ namespace currency
std::string m_port;
std::string m_bind_ip;
bool m_ignore_status;
epee::net_utils::http::i_chain_handler* m_prpc_chain_handler = nullptr;
};
}

View file

@ -59,13 +59,14 @@ namespace tools
}
//------------------------------------------------------------------------------------------------------------------------------
wallet_rpc_server::wallet_rpc_server(std::shared_ptr<wallet2> wptr):
m_pwallet_provider(new wallet_provider_simple(wptr))
m_pwallet_provider_sh_ptr(new wallet_provider_simple(wptr))
, m_pwallet_provider(m_pwallet_provider_sh_ptr.get())
, m_do_mint(false)
, m_deaf(false)
, m_last_wallet_store_height(0)
{}
//------------------------------------------------------------------------------------------------------------------------------
wallet_rpc_server::wallet_rpc_server(std::shared_ptr<i_wallet_provider> provider_ptr):
wallet_rpc_server::wallet_rpc_server(i_wallet_provider* provider_ptr):
m_pwallet_provider(provider_ptr)
, m_do_mint(false)
, m_deaf(false)

View file

@ -26,14 +26,15 @@ namespace tools
struct wallet_rpc_locker
{
wallet_rpc_locker(std::shared_ptr<i_wallet_provider> wallet_provider) :m_pwallet_provider(wallet_provider)
wallet_rpc_locker(i_wallet_provider* wallet_provider) :m_pwallet_provider(wallet_provider)
{
m_wallet_ptr = get_wallet();
m_pwallet_provider->lock();
m_wallet_ptr = m_pwallet_provider->get_wallet();
if (!m_wallet_ptr.get())
{
throw std::runtime_error("Wallet object closed");
}
m_pwallet_provider->lock();
}
std::shared_ptr<wallet2> get_wallet() { return m_wallet_ptr; }
@ -45,7 +46,7 @@ namespace tools
private:
std::shared_ptr<wallet2> m_wallet_ptr;
std::shared_ptr<i_wallet_provider> m_pwallet_provider;
i_wallet_provider* m_pwallet_provider;
};
@ -66,13 +67,13 @@ namespace tools
/************************************************************************/
/* */
/************************************************************************/
class wallet_rpc_server : public epee::http_server_impl_base<wallet_rpc_server>
class wallet_rpc_server : public epee::http_server_impl_base<wallet_rpc_server>, public epee::net_utils::http::i_chain_handler
{
public:
typedef epee::net_utils::connection_context_base connection_context;
wallet_rpc_server(std::shared_ptr<wallet2> wptr);
wallet_rpc_server(std::shared_ptr<i_wallet_provider> provider_ptr);
wallet_rpc_server(i_wallet_provider* provider_ptr);
const static command_line::arg_descriptor<std::string> arg_rpc_bind_port;
const static command_line::arg_descriptor<std::string> arg_rpc_bind_ip;
@ -85,7 +86,7 @@ namespace tools
bool run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address);
bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context);
BEGIN_URI_MAP2()
BEGIN_URI_MAP2_VIRTUAL()
BEGIN_JSON_RPC_MAP("/json_rpc")
MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_public::COMMAND_RPC_GET_BALANCE)
MAP_JON_RPC_WE("getaddress", on_getaddress, wallet_public::COMMAND_RPC_GET_ADDRESS)
@ -199,7 +200,8 @@ namespace tools
bool handle_command_line(const boost::program_options::variables_map& vm);
private:
std::shared_ptr<i_wallet_provider> m_pwallet_provider;
std::shared_ptr<i_wallet_provider> m_pwallet_provider_sh_ptr;
i_wallet_provider* m_pwallet_provider;
std::string m_port;
std::string m_bind_ip;
bool m_do_mint;

View file

@ -73,6 +73,7 @@ wallets_manager::wallets_manager():m_pview(&m_view_stub),
m_rpc_server(m_ccore, m_p2psrv, m_offers_service),
m_rpc_proxy(new tools::core_fast_rpc_proxy(m_rpc_server)),
m_offers_service(nullptr),
m_wallet_rpc_server(this),
#else
m_rpc_proxy(new tools::default_http_core_proxy()),
#endif
@ -545,6 +546,11 @@ bool wallets_manager::init_local_daemon()
CHECK_AND_ASSERT_AND_SET_GUI(res, "Failed to initialize core rpc server.");
LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << m_rpc_server.get_binded_port(), LOG_LEVEL_0);
//chain calls to rpc server
m_prpc_chain_handler = &m_wallet_rpc_server;
m_rpc_server.set_rpc_chain_handler(this);
LOG_PRINT_L0("Starting core rpc server...");
//dsi.text_state = "Starting core rpc server";
m_pview->update_daemon_status(dsi);
@ -2043,12 +2049,51 @@ bool wallets_manager::on_mw_select_wallet(uint64_t wallet_id)
auto it = m_wallets.find(wallet_id);
if (it == m_wallets.end())
return false;
auto& wo = it->second;
//m_wallet_rpc_server.reset_active_wallet(wo.w);
m_rpc_selected_wallet_id = wallet_id;
return false;
}
bool wallets_manager::on_mw_get_wallets(const tools::wallet_public::COMMAND_MW_GET_WALLETS::request& req, tools::wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, epee::net_utils::connection_context_base& cntx)
{
this->on_mw_get_wallets(res.wallets);
return true;
}
bool wallets_manager::on_mw_select_wallet(const tools::wallet_public::COMMAND_MW_SELECT_WALLET::request& req, tools::wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, epee::net_utils::connection_context_base& cntx)
{
this->on_mw_select_wallet(req.wallet_id);
return true;
}
void wallets_manager::lock()
{
{
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock);
auto it = m_wallets.find(m_rpc_selected_wallet_id);
if (it == m_wallets.end())
{
throw std::runtime_error("Wallet not selected");
}
m_current_wallet_locked_object = it->second.w.lock();
}
}
void wallets_manager::unlock()
{
m_current_wallet_locked_object.reset();
}
std::shared_ptr<tools::wallet2> wallets_manager::get_wallet()
{
if (!m_current_wallet_locked_object.get())
{
throw std::runtime_error("Wallet is not locked for get_wallet() call");
}
return **m_current_wallet_locked_object;
}
void wallets_manager::wallet_vs_options::worker_func()
{
LOG_PRINT_GREEN("[WALLET_HANDLER] Wallet handler thread started, addr: " << w->get()->get_account().get_public_address_str(), LOG_LEVEL_0);

View file

@ -47,7 +47,7 @@ struct wallet_lock_time_watching_policy
};
class wallets_manager : public i_backend_wallet_callback
class wallets_manager : public i_backend_wallet_callback, public tools::i_wallet_provider, epee::net_utils::http::i_chain_handler
{
public:
@ -55,6 +55,7 @@ public:
{
currency::core_runtime_config core_conf;
epee::locked_object<std::shared_ptr<tools::wallet2>, wallet_lock_time_watching_policy> w;
typedef epee::locked_object<std::shared_ptr<tools::wallet2>, wallet_lock_time_watching_policy>::lock_shared_ptr wallet_lock_object;
std::shared_ptr<tools::wallet_rpc_server> rpc_wrapper; //500 bytes of extra data, we can afford it, to have rpc-like invoke map
std::atomic<bool> do_mining;
std::atomic<bool> major_stop;
@ -196,8 +197,27 @@ private:
virtual void on_mw_get_wallets(std::vector<tools::wallet_public::wallet_entry_info>& wallets) override;
virtual bool on_mw_select_wallet(uint64_t wallet_id) override;
//----- i_wallet_provider ------
virtual void lock();
virtual void unlock();
virtual std::shared_ptr<tools::wallet2> get_wallet();
//--------
BEGIN_URI_MAP2_VIRTUAL()
BEGIN_JSON_RPC_MAP("/json_rpc")
//MULTIWALLET APIs
MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, tools::wallet_public::COMMAND_MW_GET_WALLETS)
MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, tools::wallet_public::COMMAND_MW_SELECT_WALLET)
CHAIN_TO_PHANDLER(m_prpc_chain_handler)
END_JSON_RPC_MAP()
CHAIN_TO_PHANDLER(m_prpc_chain_handler)
END_URI_MAP2()
bool on_mw_get_wallets(const tools::wallet_public::COMMAND_MW_GET_WALLETS::request& req, tools::wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, epee::net_utils::connection_context_base& cntx);
bool on_mw_select_wallet(const tools::wallet_public::COMMAND_MW_SELECT_WALLET::request& req, tools::wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, epee::net_utils::connection_context_base& cntx);
epee::net_utils::http::i_chain_handler* m_prpc_chain_handler = nullptr;
std::thread m_main_worker_thread;
std::atomic<bool> m_stop_singal_sent;
@ -228,6 +248,10 @@ private:
currency::t_currency_protocol_handler<currency::core> m_cprotocol;
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > m_p2psrv;
currency::core_rpc_server m_rpc_server;
tools::wallet_rpc_server m_wallet_rpc_server;
wallet_vs_options::wallet_lock_object m_current_wallet_locked_object;
uint64_t m_rpc_selected_wallet_id = 0;
#endif
bool m_remote_node_mode;