From b584f5b4d516e566bdb84331c72a7b65d1672477 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 28 Nov 2022 17:06:13 -0800 Subject: [PATCH] :sparkles: improved Transaction structure --- fbe/user_model.fbe | 4 +-- include/bank.h | 3 +++ include/bank_api.h | 11 ++++++-- include/log.h | 10 ++++++-- include/transaction.h | 14 ++++++++-- src/bank.cpp | 20 ++++++++++++--- src/bank_api.cpp | 16 +++++++++--- src/log.cpp | 59 +++++++++++++++++++++++++++++++++---------- src/transaction.cpp | 2 +- src/user.cpp | 4 +-- 10 files changed, 110 insertions(+), 33 deletions(-) diff --git a/fbe/user_model.fbe b/fbe/user_model.fbe index 59a5c00..374d322 100644 --- a/fbe/user_model.fbe +++ b/fbe/user_model.fbe @@ -2,8 +2,8 @@ package bank_dom struct Transaction { - string from = ""; - string to = ""; + string counterparty = ""; + bool receiving = false; uint32 amount = 0; timestamp time; } diff --git a/include/bank.h b/include/bank.h index d3556de..85f23d0 100644 --- a/include/bank.h +++ b/include/bank.h @@ -45,6 +45,9 @@ public: static BankResponse GetBal(const std::string &name) noexcept; #if MAX_LOG_SIZE > 0 static BankResponse GetLogs(const std::string &name) noexcept; +#if API_VERSION >= 2 + static BankResponse GetLogsV2(const std::string &name) noexcept; +#endif #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; diff --git a/include/bank_api.h b/include/bank_api.h index aa2bf55..cf631f5 100644 --- a/include/bank_api.h +++ b/include/bank_api.h @@ -11,9 +11,11 @@ using namespace drogon; class api : public HttpController { public: -#if API_VERSION >= 1 static void GetBal(req_args, const std::string &name); static void GetLogs(req_args); +#if API_VERSION >= 2 + static void GetLogsV2(req_args); +#endif static void SendFunds(req_args); static void VerifyPassword(req_args); @@ -33,7 +35,6 @@ public: static void AdminAddUser(req_args); static void DelSelf(req_args); static void AdminDelUser(req_args); -#endif METHOD_LIST_BEGIN @@ -41,8 +42,14 @@ public: METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter"); #if MAX_LOG_SIZE > 0 METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter", "UserFilter"); +#if API_VERSION >= 2 + METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter", "UserFilter"); +#endif #else METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter"); +#if API_VERSION >= 2 + METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter"); +#endif #endif METHOD_ADD(api::SendFunds, "/v1/user/transfer", Post, Options, "JsonFilter", "UserFilter"); //expects ["name"](string) and ["amount"](uint32) METHOD_ADD(api::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter", "JsonFilter"); diff --git a/include/log.h b/include/log.h index 11f828e..31a5936 100644 --- a/include/log.h +++ b/include/log.h @@ -12,10 +12,16 @@ struct Log private: ChangeFlag log_flag; std::string log_snapshot = "null"; +#if API_VERSION >= 2 + std::string log_snapshot_v2 = "null"; +#endif public: std::deque data; - std::string GetLogs() noexcept; - void AddTrans(const std::string &from, const std::string &to, uint32_t amount, time_t time) noexcept; + std::string GetLogs(const std::string& name) noexcept; +#if API_VERSION >= 2 + std::string GetLogsV2() noexcept; +#endif + void AddTrans(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept; }; diff --git a/include/transaction.h b/include/transaction.h index c4c5805..0bb43ce 100644 --- a/include/transaction.h +++ b/include/transaction.h @@ -5,10 +5,20 @@ struct Transaction { - std::string from = "", to = ""; + std::string counterparty = ""; + bool receiving = false; uint32_t amount = 0; time_t time = 0; Transaction() noexcept; - Transaction(const std::string &from_str, const std::string &to_str, uint32_t amount, time_t time) noexcept; + Transaction(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept; }; + +/* +TODO: v1 vs v2 functionality +TODO: FBE + +TODO: v2/api +TODO: update stats on run (203 bytes) +TODO: update Docs +*/ \ No newline at end of file diff --git a/src/bank.cpp b/src/bank.cpp index 2fac56a..1089806 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -89,7 +89,19 @@ BankResponse Bank::GetBal(const std::string &name) noexcept BankResponse Bank::GetLogs(const std::string &name) noexcept { BankResponse res; - if (!Bank::users.modify_if(name, [&res](User &u) { res = {k200OK, u.log.GetLogs()}; })) + if (!Bank::users.modify_if(name, [&name, &res](User &u) { res = {k200OK, u.log.GetLogs(name)}; })) + { + return {k404NotFound, "\"User not found\""}; + } + else + { + return res; + } +} +BankResponse Bank::GetLogsV2(const std::string &name) noexcept +{ + BankResponse res; + if (!Bank::users.modify_if(name, [&name, &res](User &u) { res = {k200OK, u.log.GetLogsV2()}; })) { return {k404NotFound, "\"User not found\""}; } @@ -123,7 +135,7 @@ BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_nam if (!Bank::users.modify_if(a_name, [&a_name, &b_name, &res, amount](User &a) #endif { - //if A can afford it + //if "A" can afford it if (a.balance < amount) { res = {k400BadRequest, "\"Insufficient funds\""}; @@ -132,7 +144,7 @@ BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_nam { a.balance -= amount; #if MAX_LOG_SIZE > 0 - a.log.AddTrans(a_name, b_name, amount, current_time); + a.log.AddTrans(b_name, false, amount, current_time); #endif res = {k200OK, std::to_string(a.balance)}; } @@ -145,7 +157,7 @@ BankResponse Bank::SendFunds(const std::string &a_name, const std::string &b_nam #if MAX_LOG_SIZE > 0 Bank::users.modify_if(b_name, [current_time, &a_name, &b_name, amount](User &b) { b.balance += amount; - b.log.AddTrans(a_name, b_name, amount, current_time); + b.log.AddTrans(a_name, true, amount, current_time); }); #else Bank::users.modify_if(b_name, [amount](User &b) { b.balance += amount; }); diff --git a/src/bank_api.cpp b/src/bank_api.cpp index 24e7c99..60ac43b 100644 --- a/src/bank_api.cpp +++ b/src/bank_api.cpp @@ -6,7 +6,7 @@ #define CORS resp->addHeader("Access-Control-Allow-Origin", "*") -static thread_local ondemand::parser parser; +thread_local ondemand::parser parser; #define SIMD_JSON_GEN \ simdjson::padded_string input(req->getBody()); \ ondemand::document doc; @@ -24,8 +24,6 @@ static thread_local ondemand::parser parser; #define NAME_PARAM req->getParameter("name") -#if API_VERSION >= 1 - //Usage void api::GetBal(req_args, const std::string &name) { @@ -42,6 +40,17 @@ void api::GetLogs(req_args) callback(resp); #endif } +void api::GetLogsV2(req_args) +{ +#if MAX_LOG_SIZE > 0 + RESPONSE_PARSE(Bank::GetLogsV2(NAME_PARAM)); +#else + auto resp = HttpResponse::newCustomHttpResponse(BankResponse{k404NotFound, "\"Logs are Disabled\""}); + CORS; + CACHE_FOREVER; + callback(resp); +#endif +} void api::SendFunds(req_args) { SIMD_JSON_GEN; @@ -344,4 +353,3 @@ void api::AdminDelUser(req_args) } RESPONSE_PARSE(std::move(res)); } -#endif diff --git a/src/log.cpp b/src/log.cpp index ec2e8b6..35f4fb7 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -1,22 +1,22 @@ #include "log.h" -void Log::AddTrans(const std::string &from, const std::string &to, uint32_t amount, time_t time) noexcept +void Log::AddTrans(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept { log_flag.SetChangesOn(); if (data.size() == MAX_LOG_SIZE) { data.pop_back(); } - data.emplace_back(from, to, amount, time); + data.emplace_back(counterparty_str, receiving, amount, time); } -std::string Log::GetLogs() noexcept +std::string Log::GetLogs(const std::string& name) noexcept { if (log_flag.GetChangeState() && data.size()) //if there are changes { log_snapshot.resize(0); //re-generate snapshot - size_t predicted_size = ((59 + (2 * max_name_size)) * data.size()) + 1; + size_t predicted_size = ((57 + (2 * max_name_size)) * data.size()) + 1; if (log_snapshot.capacity() < predicted_size) { log_snapshot.reserve(predicted_size); @@ -24,18 +24,49 @@ std::string Log::GetLogs() noexcept log_snapshot = '['; //1 for (size_t i = 0; i < data.size(); ++i) { - log_snapshot += "{\"to\":\""; //8 - log_snapshot += data[i].to; //max_name_size? - log_snapshot += "\",\"from\":\""; //10 - log_snapshot += data[i].from; //max_name_size? - log_snapshot += "\",\"amount\":"; //12 - log_snapshot += std::to_string(data[i].amount); //10? - log_snapshot += ",\"time\":"; //8 - log_snapshot += std::to_string(data[i].time); //10? - log_snapshot += "},"; //2 + log_snapshot += "{\"to\":\""; //7 + log_snapshot += data[i].receiving? name : data[i].counterparty; //max_name_size? + log_snapshot += "\",\"from\":\""; //10 + log_snapshot += data[i].receiving? data[i].counterparty : name; //max_name_size? + log_snapshot += "\",\"amount\":"; //11 + log_snapshot += std::to_string(data[i].amount); //10? + log_snapshot += ",\"time\":"; //8 + log_snapshot += std::to_string(data[i].time); //10? + log_snapshot += "},"; //2 } log_snapshot.back() = ']'; log_flag.SetChangesOff(); } + return log_snapshot; -} \ No newline at end of file +} +std::string Log::GetLogsV2() noexcept +{ + if (log_flag.GetChangeState() && data.size()) //if there are changes + { + log_snapshot_v2.resize(0); + //re-generate snapshot + size_t predicted_size = ((77 + max_name_size) * data.size()) + 1; + if (log_snapshot_v2.capacity() < predicted_size) + { + log_snapshot_v2.reserve(predicted_size); + } + log_snapshot_v2 = '['; //1 + for (size_t i = 0; i < data.size(); ++i) + { + log_snapshot += "{\"counterparty\":\""; //17 + log_snapshot += data[i].counterparty; //max_name_size? + log_snapshot += "\",\"receiving\":\""; //15 + log_snapshot += std::to_string(data[i].receiving); //4 + log_snapshot += "\",\"amount\":"; //11 + log_snapshot += std::to_string(data[i].amount); //10? + log_snapshot += ",\"time\":"; //8 + log_snapshot += std::to_string(data[i].time); //10? + log_snapshot += "},"; //2 + } + log_snapshot_v2.back() = ']'; + log_flag.SetChangesOff(); + } + + return log_snapshot_v2; +} diff --git a/src/transaction.cpp b/src/transaction.cpp index c0c1456..afd5d0e 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -1,4 +1,4 @@ #include "transaction.h" Transaction::Transaction() noexcept {}; -Transaction::Transaction(const std::string &from_str, const std::string &to_str, uint32_t amount, time_t time_val) noexcept : from(from_str), to(to_str), amount(amount), time(time_val) {} +Transaction::Transaction(const std::string &counterparty_str, bool receiving, uint32_t amount, time_t time) noexcept : counterparty(counterparty_str), receiving(receiving), amount(amount), time(time) {} diff --git a/src/user.cpp b/src/user.cpp index 074c13b..b5e1f82 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -29,7 +29,7 @@ User::User(const bank_dom::User &u) noexcept : balance(u.balance), password(u.pa for (; i < u.logs.value().data.size(); ++i) { const bank_dom::Transaction &temp = u.logs.value().data[i]; - log.data.emplace_front(temp.from, temp.to, temp.amount, temp.time); + log.data.emplace_front(temp.counterparty, temp.receiving, temp.amount, temp.time); } } #endif @@ -43,7 +43,7 @@ bank_dom::User User::Encode() const noexcept save_log.data.reserve(this->log.data.size()); for (const Transaction &t : this->log.data) { - save_log.data.emplace_back(t.from, t.to, t.amount, t.time); + save_log.data.emplace_back(t.counterparty, t.receiving, t.amount, t.time); } return bank_dom::User(balance, password, save_log); }