diff --git a/benchmarking.cpp b/benchmarking.cpp index 243fe25..a54556a 100644 --- a/benchmarking.cpp +++ b/benchmarking.cpp @@ -96,23 +96,10 @@ int main(int argc, char **argv) #endif Op(Bank::GetLogsV2("twix"), "get logs init (v2): ", 1); Op(Bank::GetLogsV2("twix"), "get logs cached (v2): ", 1000000); + Op(Bank::GetLogsRange("twix", 0, 100), "get logs range: ", 1000000); #endif Op(Bank::PruneUsers(0, 0), "prune users: ", 1); Op(Bank::Save(), "saving: ", 1); - //GetBal scalining test - //std::default_random_engine generator; - //std::uniform_real_distribution distribution(0.0, 1.0); - - // for (size_t i = 0; i < 10000000; ++i) - // { - // Bank::AddUser(std::to_string(i), 100000, "root"); - // if (i % 10000 == 0) - // { - // auto u = std::to_string((int)(distribution(generator) * i)); - // Op(Bank::GetBal(u), std::to_string(i) + ", ", 100000); - // } - // } - return 0; } diff --git a/include/bank.h b/include/bank.h index 952497f..278017a 100644 --- a/include/bank.h +++ b/include/bank.h @@ -49,11 +49,11 @@ public: static BankResponse GetLogs(const std::string &name) noexcept; #endif static BankResponse GetLogsV2(const std::string &name) noexcept; + static BankResponse GetLogsRange(const std::string &name, size_t n, size_t m) noexcept; #endif static BankResponse SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept; static bool VerifyPassword(const std::string &name, const std::string_view &attempt) noexcept; - static void ChangePassword(const std::string &name, const std::string &new_pass) noexcept; static BankResponse SetBal(const std::string &name, int64_t amount) noexcept; static BankResponse ImpactBal(const std::string &name, int64_t amount) noexcept; diff --git a/include/bank_api.h b/include/bank_api.h index 24a2cf5..1b01acb 100644 --- a/include/bank_api.h +++ b/include/bank_api.h @@ -16,19 +16,20 @@ public: static void GetLogs(req_args); #endif static void GetLogsV2(req_args); - static void AdminGetLogs(req_args, const std::string& name); + static void GetLogsRange(req_args, size_t start, size_t length); static void SendFunds(req_args); + static void ChangePassword(req_args); static void VerifyPassword(req_args); - static void ChangePassword(req_args); + static void AdminGetLogs(req_args, const std::string& name); static void AdminChangePassword(req_args); + static void AdminVerifyAccount(req_args); static void SetBal(req_args); static void ImpactBal(req_args); static void Help(req_args); static void Close(req_args); static void Contains(req_args, const std::string &name); - static void AdminVerifyAccount(req_args); static void PruneUsers(req_args); static void ApiProperties(req_args); @@ -39,8 +40,6 @@ public: METHOD_LIST_BEGIN - METHOD_ADD(api::Help, "/help", Get, Options); - METHOD_ADD(api::ApiProperties, "/properties", Get, Options); //Usage METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter"); @@ -52,6 +51,7 @@ public: #endif METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter", "UserFilter"); + METHOD_ADD(api::GetLogsRange, "/v1/user/log_range?start={start}&length={length}", Get, Options, "JsonFilter", "UserFilter"); METHOD_ADD(api::AdminGetLogs, "/v1/admin/user/log?name={name}", Get, Options, "JsonFilter", "UserFilter"); #else @@ -60,26 +60,29 @@ public: #endif METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter"); + METHOD_ADD(api::GetLogsRange, "/v1/user/log_range?start={start}&length={length}", Get, Options, "JsonFilter"); METHOD_ADD(api::AdminGetLogs, "/v1/admin/user/log?name={name}", Get, Options, "JsonFilter"); #endif METHOD_ADD(api::SendFunds, "/v1/user/transfer", Post, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) + METHOD_ADD(api::ChangePassword, "/v1/user/change_password", Patch, Options, "JsonFilter", "UserFilter"); //expects ["pass"](string) METHOD_ADD(api::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter", "JsonFilter"); //Meta Usage - METHOD_ADD(api::ChangePassword, "/v1/user/change_password", Patch, Options, "JsonFilter", "UserFilter"); //expects ["pass"](string) METHOD_ADD(api::AdminChangePassword, "/v1/admin/user/change_password", Patch, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["pass"](string) - METHOD_ADD(api::SetBal, "/v1/admin/set_balance", Patch, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) - METHOD_ADD(api::ImpactBal, "/v1/admin/impact_balance", Post, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) + METHOD_ADD(api::AdminVerifyAccount, "/v1/admin/verify_account", Post, Options, "UserFilter", "JsonFilter"); + METHOD_ADD(api::SetBal, "/v1/admin/set_balance", Patch, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) + METHOD_ADD(api::ImpactBal, "/v1/admin/impact_balance", Post, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) //System Usage + METHOD_ADD(api::Help, "/help", Get, Options); METHOD_ADD(api::Close, "/v1/admin/shutdown", Post, Options, "UserFilter", "JsonFilter"); METHOD_ADD(api::Contains, "/v1/user/exists?name={name}", Get, Options, "JsonFilter"); - METHOD_ADD(api::AdminVerifyAccount, "/v1/admin/verify_account", Post, Options, "UserFilter", "JsonFilter"); METHOD_ADD(api::PruneUsers, "/v1/admin/prune_users", Post, "UserFilter", "JsonFilter"); //expects ["time"](int64) and ["amount"](uint32) + METHOD_ADD(api::ApiProperties, "/properties", Get, Options); //User Managment - METHOD_ADD(api::AddUser, "/v1/user/register", Post, Options); //expects ["name"](string) ["pass"](string) + METHOD_ADD(api::AddUser, "/v1/user/register", Post, Options); //expects ["name"](string) ["pass"](string) METHOD_ADD(api::AdminAddUser, "/v1/admin/user/register", Post, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) ["amount"](uint32) ["pass"](string) METHOD_ADD(api::DelSelf, "/v1/user/delete", Delete, Options, "UserFilter", "JsonFilter"); METHOD_ADD(api::AdminDelUser, "/v1/admin/user/delete", Delete, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) diff --git a/include/log.h b/include/log.h index e49c7a6..b46313e 100644 --- a/include/log.h +++ b/include/log.h @@ -26,5 +26,6 @@ public: std::string GetLogs(const std::string& name) noexcept; #endif std::string GetLogsV2() noexcept; + std::string GetLogsRange(size_t n, size_t m) noexcept; void AddTrans(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept; }; diff --git a/src/bank.cpp b/src/bank.cpp index 7f32913..4463946 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -116,6 +116,28 @@ BankResponse Bank::GetLogsV2(const std::string &name) noexcept } } +BankResponse Bank::GetLogsRange(const std::string &name, size_t start, size_t length) noexcept +{ + BankResponse res; + if (start >= MAX_LOG_SIZE) + { + return {k400BadRequest, "\"Invalid starting index\""}; + } + if (length == 0 || (length + start) > MAX_LOG_SIZE) + { + return {k400BadRequest, "\"Invalid length\""}; + } + + if (!Bank::users.modify_if(name, [&name, &res, start, length](User &u) { res = {k200OK, u.log.GetLogsRange(start, length)}; })) + { + return {k404NotFound, "\"User not found\""}; + } + else + { + return res; + } +} + #endif BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_name, uint32_t amount) noexcept diff --git a/src/bank_api.cpp b/src/bank_api.cpp index c0383d5..b682b26 100644 --- a/src/bank_api.cpp +++ b/src/bank_api.cpp @@ -54,6 +54,18 @@ void api::GetLogsV2(req_args) #endif } +void api::GetLogsRange(req_args, size_t start, size_t length) +{ +#if MAX_LOG_SIZE > 0 + RESPONSE_PARSE(Bank::GetLogsRange(NAME_PARAM, start, length)); +#else + auto resp = HttpResponse::newCustomHttpResponse(BankResponse{k404NotFound, "\"Logs are Disabled\""}); + CORS; + CACHE_FOREVER; + callback(resp); +#endif +} + void api::AdminGetLogs(req_args, const std::string& name) { #if MAX_LOG_SIZE > 0 diff --git a/src/log.cpp b/src/log.cpp index 440f2fc..a87d119 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -17,7 +17,7 @@ void Log::AddTrans(const std::string &counterparty_str, bool receiving, uint32_t #if USE_DEPRECATED_ENDPOINTS std::string Log::GetLogs(const std::string& name) noexcept { - if (log_flag.GetChangeState() && data.size()) //if there are changes + if (log_flag.GetChangeState() && data.size()) // if there are changes { log_snapshot.resize(0); //re-generate snapshot @@ -49,7 +49,7 @@ std::string Log::GetLogs(const std::string& name) noexcept std::string Log::GetLogsV2() noexcept { - if (log_flag_v2.GetChangeState() && data.size()) //if there are changes + if (log_flag_v2.GetChangeState() && data.size()) // if there are changes { log_snapshot_v2.resize(0); //re-generate snapshot @@ -63,7 +63,7 @@ std::string Log::GetLogsV2() noexcept { log_snapshot_v2 += "{\"counterparty\":\""; //17 log_snapshot_v2 += data[i].counterparty; //max_name_size? - log_snapshot_v2 += "\",\"amount\":"; //11 + log_snapshot_v2 += "\",\"amount\":"; //11 if (!data[i].receiving) { log_snapshot_v2 += '-'; } //1 log_snapshot_v2 += std::to_string(data[i].amount); //10? log_snapshot_v2 += ",\"time\":"; //8 @@ -76,3 +76,45 @@ std::string Log::GetLogsV2() noexcept return log_snapshot_v2; } + +std::string Log::GetLogsRange(size_t start, size_t length) noexcept +{ + if (start > data.size()) { return "[]"; } + if (start == 0 && length == MAX_LOG_SIZE) { return log_snapshot_v2; } + if (log_flag_v2.GetChangeState() && data.size()) { GetLogsV2(); } + + size_t log_index_n = 0, i = 0; + while(i < log_snapshot_v2.size()) + { + if (log_index_n == start) + { + log_index_n = i; + break; + } + i += (41 + min_name_size); + while (log_snapshot_v2[i] != ',') { ++i; } + ++log_index_n; + } + size_t log_index_m = log_snapshot_v2.size() - log_index_n; + if (length != MAX_LOG_SIZE) + { + log_index_m = 0; + while(i < log_snapshot_v2.size()) + { + if (log_index_m == length) + { + log_index_m = i + 1; + break; + } + i += (41 + min_name_size); + while (log_snapshot_v2[i] != ',') { ++i; } + ++log_index_m; + } + } + + std::string res(log_snapshot_v2.substr(log_index_n, log_index_m - log_index_n)); + res[0] = '['; + res[log_index_m - log_index_n - 1] = ']'; + + return res; +}