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:
parent
a9bbfdcf82
commit
3fec14f95e
7 changed files with 118 additions and 13 deletions
|
|
@ -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)) \
|
||||
{ \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue