forked from lthn/blockchain
plain_wallet api refactored due to ios app crash
This commit is contained in:
parent
b97065beba
commit
9e983b70b2
2 changed files with 108 additions and 34 deletions
|
|
@ -34,5 +34,6 @@
|
|||
#define API_RETURN_CODE_WRONG_SEED "WRONG_SEED"
|
||||
#define API_RETURN_CODE_GENESIS_MISMATCH "GENESIS_MISMATCH"
|
||||
#define API_RETURN_CODE_DISCONNECTED "DISCONNECTED"
|
||||
#define API_RETURN_CODE_UNINITIALIZED "UNINITIALIZED"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,21 +27,42 @@
|
|||
#define GENERAL_INTERNAL_ERRROR_INIT "Failed to intialize library"
|
||||
|
||||
//TODO: global objects, subject to refactoring
|
||||
wallets_manager gwm;
|
||||
std::atomic<bool> initialized(false);
|
||||
|
||||
std::atomic<uint64_t> gjobs_counter(1);
|
||||
std::map<uint64_t, std::string> gjobs;
|
||||
epee::critical_section gjobs_lock;
|
||||
std::string gconfig_folder;
|
||||
struct plain_wallet_instance
|
||||
{
|
||||
plain_wallet_instance() :initialized(false), gjobs_counter(1)
|
||||
{}
|
||||
wallets_manager gwm;
|
||||
std::atomic<bool> initialized;
|
||||
|
||||
std::atomic<uint64_t> gjobs_counter;
|
||||
std::map<uint64_t, std::string> gjobs;
|
||||
epee::critical_section gjobs_lock;
|
||||
};
|
||||
|
||||
std::shared_ptr<plain_wallet_instance> ginstance_ptr;
|
||||
|
||||
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&]()
|
||||
{
|
||||
std::cout << "[LEAVE HANDLER CALLED]" << ENDL;
|
||||
});
|
||||
|
||||
namespace plain_wallet
|
||||
{
|
||||
typedef epee::json_rpc::response<epee::json_rpc::dummy_result, error> error_response;
|
||||
|
||||
|
||||
std::string get_set_working_dir(bool need_to_set = false, const std::string val = "")
|
||||
{
|
||||
static std::string working_dir;
|
||||
if (need_to_set)
|
||||
working_dir = val;
|
||||
return working_dir;
|
||||
}
|
||||
|
||||
std::string get_bundle_working_dir()
|
||||
{
|
||||
return gconfig_folder;
|
||||
return get_set_working_dir();
|
||||
// #ifdef WIN32
|
||||
// return boost::dll::program_location().parent_path().string();
|
||||
// #elif IOS_BUILD
|
||||
|
|
@ -56,7 +77,7 @@ namespace plain_wallet
|
|||
}
|
||||
void set_bundle_working_dir(const std::string& dir)
|
||||
{
|
||||
gconfig_folder = dir;
|
||||
get_set_working_dir(true, dir);
|
||||
}
|
||||
|
||||
std::string get_wallets_folder()
|
||||
|
|
@ -102,15 +123,33 @@ namespace plain_wallet
|
|||
return "{}";
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
auto local_ptr = std::atomic_load(&ginstance_ptr);
|
||||
if (local_ptr)
|
||||
{
|
||||
std::atomic_store(&ginstance_ptr, std::shared_ptr<plain_wallet_instance>());
|
||||
//wait other callers finish
|
||||
local_ptr->gjobs_lock.lock();
|
||||
local_ptr->gjobs_lock.unlock();
|
||||
local_ptr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
std::string init(const std::string& ip, const std::string& port, const std::string& working_dir, int log_level)
|
||||
{
|
||||
if (initialized)
|
||||
auto local_ptr = std::atomic_load(&ginstance_ptr);
|
||||
if (local_ptr)
|
||||
{
|
||||
LOG_ERROR("Double-initialization in plain_wallet detected.");
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_ALREADY_EXISTS;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::cout << "[INIT PLAIN_WALLET_INSTANCE]" << ENDL;
|
||||
std::shared_ptr<plain_wallet_instance> ptr(new plain_wallet_instance());
|
||||
|
||||
set_bundle_working_dir(working_dir);
|
||||
|
||||
initialize_logs(log_level);
|
||||
|
|
@ -122,13 +161,13 @@ namespace plain_wallet
|
|||
args[1] = const_cast<char*>(argss_1.c_str());
|
||||
args[2] = const_cast<char*>(argss_2.c_str());
|
||||
args[3] = nullptr;
|
||||
if (!gwm.init(3, args, nullptr))
|
||||
if (!ptr->gwm.init(3, args, nullptr))
|
||||
{
|
||||
LOG_ERROR("Failed to init wallets_manager");
|
||||
return GENERAL_INTERNAL_ERRROR_INIT;
|
||||
}
|
||||
|
||||
if(!gwm.start())
|
||||
if(!ptr->gwm.start())
|
||||
{
|
||||
LOG_ERROR("Failed to start wallets_manager");
|
||||
return GENERAL_INTERNAL_ERRROR_INIT;
|
||||
|
|
@ -155,7 +194,7 @@ namespace plain_wallet
|
|||
return epee::serialization::store_t_to_json(err_result);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
std::atomic_store(&ginstance_ptr, ptr);
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
|
|
@ -213,9 +252,21 @@ namespace plain_wallet
|
|||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
|
||||
#define GET_INSTANCE_PTR(ptr_name) \
|
||||
auto ptr_name = std::atomic_load(&ginstance_ptr); \
|
||||
if (!ptr_name) \
|
||||
{ \
|
||||
LOG_ERROR("Core already deinitialised or not initialized yet."); \
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response); \
|
||||
ok_response.result.return_code = API_RETURN_CODE_UNINITIALIZED; \
|
||||
return epee::serialization::store_t_to_json(ok_response); \
|
||||
}
|
||||
|
||||
std::string get_connectivity_status()
|
||||
{
|
||||
return gwm.get_connectivity_status();
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
return inst_ptr->gwm.get_connectivity_status();
|
||||
}
|
||||
|
||||
std::string get_version()
|
||||
|
|
@ -254,16 +305,18 @@ namespace plain_wallet
|
|||
|
||||
std::string open(const std::string& path, const std::string& password)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
std::string full_path = get_wallets_folder() + path;
|
||||
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
std::string rsp = gwm.open_wallet(epee::string_encoding::convert_to_unicode(full_path), password, 20, ok_response.result);
|
||||
std::string rsp = inst_ptr->gwm.open_wallet(epee::string_encoding::convert_to_unicode(full_path), password, 20, ok_response.result);
|
||||
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
ok_response.result.recovered = true;
|
||||
}
|
||||
gwm.run_wallet(ok_response.result.wallet_id);
|
||||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
|
|
@ -271,18 +324,21 @@ namespace plain_wallet
|
|||
err_result.error.code = rsp;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
std::string full_path = get_wallets_folder() + path;
|
||||
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
std::string rsp = gwm.restore_wallet(epee::string_encoding::convert_to_unicode(full_path), password, seed, ok_response.result);
|
||||
std::string rsp = inst_ptr->gwm.restore_wallet(epee::string_encoding::convert_to_unicode(full_path), password, seed, ok_response.result);
|
||||
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
ok_response.result.recovered = true;
|
||||
}
|
||||
gwm.run_wallet(ok_response.result.wallet_id);
|
||||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
|
|
@ -292,16 +348,18 @@ namespace plain_wallet
|
|||
|
||||
std::string generate(const std::string& path, const std::string& password)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
std::string full_path = get_wallets_folder() + path;
|
||||
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
std::string rsp = gwm.generate_wallet(epee::string_encoding::convert_to_unicode(full_path), password, ok_response.result);
|
||||
std::string rsp = inst_ptr->gwm.generate_wallet(epee::string_encoding::convert_to_unicode(full_path), password, ok_response.result);
|
||||
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
ok_response.result.recovered = true;
|
||||
}
|
||||
gwm.run_wallet(ok_response.result.wallet_id);
|
||||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
|
|
@ -311,34 +369,44 @@ namespace plain_wallet
|
|||
|
||||
std::string close_wallet(hwallet h)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
std::string r = "{\"response\": \"";
|
||||
r += gwm.close_wallet(h);
|
||||
r += inst_ptr->gwm.close_wallet(h);
|
||||
r += "\"}";
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string get_wallet_status(hwallet h)
|
||||
{
|
||||
return gwm.get_wallet_status(h);
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
return inst_ptr->gwm.get_wallet_status(h);
|
||||
}
|
||||
|
||||
std::string invoke(hwallet h, const std::string& params)
|
||||
{
|
||||
return gwm.invoke(h, params);
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
return inst_ptr->gwm.invoke(h, params);
|
||||
}
|
||||
|
||||
void put_result(uint64_t job_id, const std::string& res)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(gjobs_lock);
|
||||
gjobs[job_id] = res;
|
||||
auto inst_ptr = std::atomic_load(&ginstance_ptr);
|
||||
if (!inst_ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CRITICAL_REGION_LOCAL(inst_ptr->gjobs_lock);
|
||||
inst_ptr->gjobs[job_id] = res;
|
||||
LOG_PRINT_L2("[ASYNC_CALL]: Finished(result put), job id: " << job_id);
|
||||
}
|
||||
|
||||
|
||||
std::string async_call(const std::string& method_name, uint64_t instance_id, const std::string& params)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
std::function<void()> async_callback;
|
||||
|
||||
uint64_t job_id = gjobs_counter++;
|
||||
uint64_t job_id = inst_ptr->gjobs_counter++;
|
||||
if (method_name == "close")
|
||||
{
|
||||
async_callback = [job_id, instance_id]()
|
||||
|
|
@ -413,17 +481,22 @@ namespace plain_wallet
|
|||
|
||||
std::string try_pull_result(uint64_t job_id)
|
||||
{
|
||||
//TODO: need refactoring
|
||||
CRITICAL_REGION_LOCAL(gjobs_lock);
|
||||
auto it = gjobs.find(job_id);
|
||||
if (it == gjobs.end())
|
||||
{
|
||||
return "{\"delivered\": false}";
|
||||
auto inst_ptr = std::atomic_load(&ginstance_ptr);
|
||||
if (!inst_ptr)
|
||||
{
|
||||
return "{\"status\": \"canceled\"}";
|
||||
}
|
||||
std::string res = "{\"delivered\": true, \"result\": ";
|
||||
//TODO: need refactoring
|
||||
CRITICAL_REGION_LOCAL(inst_ptr->gjobs_lock);
|
||||
auto it = inst_ptr->gjobs.find(job_id);
|
||||
if (it == inst_ptr->gjobs.end())
|
||||
{
|
||||
return "{\"status\": \"idle\"}";
|
||||
}
|
||||
std::string res = "{\"status\": \"delivered\", \"result\": ";
|
||||
res += it->second;
|
||||
res += " }";
|
||||
gjobs.erase(it);
|
||||
inst_ptr->gjobs.erase(it);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue