From 7e1954d6513cfea12d186234f91ec40d8b76071c Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Wed, 28 Dec 2022 18:16:56 -0800 Subject: [PATCH 01/25] :memo: --- docs/connected_services/existing_services.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/connected_services/existing_services.md b/docs/connected_services/existing_services.md index 926a9c7..d13be3c 100644 --- a/docs/connected_services/existing_services.md +++ b/docs/connected_services/existing_services.md @@ -6,21 +6,23 @@ | supported | :heavy_check_mark: | | uses deprecated endpoints | ⚠ | | uses defunt endpoints | :no_entry: | +| in development | :hammer: | ## General | author | name | support | image | | :-------------------------------------- | ----------------------------------------------------------- | :----------------: | :-------------------------------------------------------------------------------------------------------------: | -| [Expand](https://github.com/Expand-sys) | [Web Frontend](https://github.com/Expand-sys/ccashfrontend) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/121337724-afe9fe80-c8d1-11eb-8851-23ec5e74cd26.png) | -| [Expand](https://github.com/Expand-sys) | [Discord Bot](https://github.com/Expand-sys/ccashbot) | :heavy_check_mark: | | +| [Expand](https://github.com/Expand-sys) | [Web Frontend](https://github.com/Expand-sys/ccashfrontend) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/121337724-afe9fe80-c8d1-11eb-8851-23ec5e74cd26.png) | | | [ArcNyxx](https://github.com/ArcNyxx) | [CCash CLI](https://github.com/ArcNyxx/ccash_cmd) | ⚠ | | ## Minecraft -| author | name | support | image | -| :------------------------------------------ | --------------------------------------------------------------------------- | :----------------: | :-------------------------------------------------------------------------------------------------------------: | -| [Reactified](https://github.com/Reactified) | [Shop](https://github.com/Reactified/rpm/tree/main/packages/ccash-shop) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/120050327-de163700-bfd1-11eb-9d5a-f75c003e867c.png) | -| [Reactified](https://github.com/Reactified) | [Wallet](https://github.com/Reactified/rpm/tree/main/packages/ccash-wallet) | ⚠ | ![image](https://user-images.githubusercontent.com/31377881/121338034-fb041180-c8d1-11eb-8640-b18c141eb980.png) | -| [Reactified](https://github.com/Reactified) | [ATM](https://github.com/Reactified/rpm/tree/main/packages/ccash-bank) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/121277361-4d6b1100-c885-11eb-87c8-cfebcf58da4f.png) | -| [STBoyden](https://github.com/STBoyden) | Commodities Exchange (in-development) | :heavy_check_mark: | | +| author | name | support | image | +| :------------------------------------------ | ---------------------------------------------------------------------------------------- | :----------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| [Reactified](https://github.com/Reactified) | [Shop](https://github.com/Reactified/rpm/tree/main/packages/ccash-shop) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/120050327-de163700-bfd1-11eb-9d5a-f75c003e867c.png) | +| [Reactified](https://github.com/Reactified) | [Wallet](https://github.com/Reactified/rpm/tree/main/packages/ccash-wallet) | ⚠ | ![image](https://user-images.githubusercontent.com/31377881/121338034-fb041180-c8d1-11eb-8640-b18c141eb980.png) | +| [Reactified](https://github.com/Reactified) | [ATM](https://github.com/Reactified/rpm/tree/main/packages/ccash-bank) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/121277361-4d6b1100-c885-11eb-87c8-cfebcf58da4f.png) | +| [Reactified](https://github.com/Reactified) | [Chunk Loader Shop](https://github.com/Reactified/rpm/tree/main/packages/forceload-shop) | :heavy_check_mark: | ![image](https://user-images.githubusercontent.com/31377881/209894520-f7183f45-bbac-40f3-9f95-043bda3c0097.png) ![image](https://user-images.githubusercontent.com/31377881/209894553-16ef7e04-52e7-4198-8a39-9ad2ada6eaf7.png) | +| [STBoyden](https://github.com/STBoyden) | [Commodities Exchange](https://github.com/STBoyden/ccash-market) | :hammer: | | + ## Desired | idea | description | From 5e996b27059c44fed3369784d4d77d658846981b Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 16:43:54 -0800 Subject: [PATCH 02/25] :sparkles: `ImpactBal` and `SetBal` add a log now --- include/bank.h | 2 +- src/bank.cpp | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/bank.h b/include/bank.h index 4cb8340..952497f 100644 --- a/include/bank.h +++ b/include/bank.h @@ -55,7 +55,7 @@ public: 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, uint32_t amount) noexcept; + static BankResponse SetBal(const std::string &name, int64_t amount) noexcept; static BankResponse ImpactBal(const std::string &name, int64_t amount) noexcept; static bool Contains(const std::string &name) noexcept; diff --git a/src/bank.cpp b/src/bank.cpp index ebbd40b..ad6dd46 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -185,9 +185,15 @@ void Bank::ChangePassword(const std::string &name, const std::string &new_pass) SET_CHANGES_ON; Bank::users.modify_if(name, [&new_pass](User &u) { u.password = xxHashStringGen{}(new_pass); }); } -BankResponse Bank::SetBal(const std::string &name, uint32_t amount) noexcept +BankResponse Bank::SetBal(const std::string &name, int64_t amount) noexcept { - if (ValidUsername(name) && Bank::users.modify_if(name, [amount](User &u) { u.balance = amount; })) + if (ValidUsername(name) && Bank::users.modify_if(name, [&amount](User &u) { + amount -= u.balance; + u.balance -= amount; +#if MAX_LOG_SIZE > 0 + u.log.AddTrans(nullptr, (amount > 0), amount, time(NULL)); +#endif + })) { SET_CHANGES_ON; return {k204NoContent, std::nullopt}; //returns new balance @@ -204,7 +210,13 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept return {k400BadRequest, "\"Amount cannot be 0\""}; } uint32_t bal; - if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, amount](User &u) { bal = (u.balance < (amount * -1) ? u.balance = 0 : u.balance += amount); })) + if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, &amount](User &u) { + amount += (u.balance < (amount * -1)) * (amount + u.balance); + bal = u.balance -= amount; +#if MAX_LOG_SIZE > 0 + u.log.AddTrans(nullptr, (amount > 0), amount, time(NULL)); +#endif + })) { SET_CHANGES_ON; return {k200OK, std::to_string(bal)}; //may return new balance From c659c9b7bd2576a5828ab05d98c55ffed35abbde Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 17:01:14 -0800 Subject: [PATCH 03/25] :bug: `ValidUsername` should allow capitilization --- src/bank.cpp | 2 +- src/user_filter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index ad6dd46..ebe5f8c 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -36,7 +36,7 @@ inline bool ValidUsername(const std::string &name) noexcept } for (char c : name) { - if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_')) + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) { return false; } diff --git a/src/user_filter.cpp b/src/user_filter.cpp index 95d6bad..c5fc5c3 100644 --- a/src/user_filter.cpp +++ b/src/user_filter.cpp @@ -8,7 +8,7 @@ inline bool ValidUsername(const std::string &name) noexcept } for (char c : name) { - if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_')) + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) { return false; } From 0d346b820f8c88e97c9869fd7fa2a2cb49b3724b Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 17:10:41 -0800 Subject: [PATCH 04/25] :bug: fixing last log commit --- src/bank.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index ebe5f8c..0ea5274 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -189,9 +189,9 @@ BankResponse Bank::SetBal(const std::string &name, int64_t amount) noexcept { if (ValidUsername(name) && Bank::users.modify_if(name, [&amount](User &u) { amount -= u.balance; - u.balance -= amount; + u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans(nullptr, (amount > 0), amount, time(NULL)); + u.log.AddTrans("$", (amount > 0), amount, time(NULL)); #endif })) { @@ -212,9 +212,9 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept uint32_t bal; if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, &amount](User &u) { amount += (u.balance < (amount * -1)) * (amount + u.balance); - bal = u.balance -= amount; + bal = u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans(nullptr, (amount > 0), amount, time(NULL)); + u.log.AddTrans("$", (amount > 0), amount, time(NULL)); #endif })) { From 779ab90b8f6a4605676ad69b79145b1c303400d3 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 17:30:25 -0800 Subject: [PATCH 05/25] omega symbol --- src/bank.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index 0ea5274..19069d9 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -191,7 +191,7 @@ BankResponse Bank::SetBal(const std::string &name, int64_t amount) noexcept amount -= u.balance; u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans("$", (amount > 0), amount, time(NULL)); + u.log.AddTrans("Ω", (amount > 0), amount, time(NULL)); #endif })) { @@ -214,7 +214,7 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept amount += (u.balance < (amount * -1)) * (amount + u.balance); bal = u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans("$", (amount > 0), amount, time(NULL)); + u.log.AddTrans("Ω", (amount > 0), amount, time(NULL)); #endif })) { From 8fea062a3f17e46369e2c28076fa07da4790d2d5 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 18:37:40 -0800 Subject: [PATCH 06/25] :bug: fixed --- src/bank.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index 19069d9..ff5e770 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -191,7 +191,7 @@ BankResponse Bank::SetBal(const std::string &name, int64_t amount) noexcept amount -= u.balance; u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans("Ω", (amount > 0), amount, time(NULL)); + u.log.AddTrans("Ω", (amount > 0), std::abs(amount), time(NULL)); #endif })) { @@ -211,10 +211,10 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept } uint32_t bal; if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, &amount](User &u) { - amount += (u.balance < (amount * -1)) * (amount + u.balance); + if (u.balance < (amount * -1)) { amount = -u.balance; }; bal = u.balance += amount; #if MAX_LOG_SIZE > 0 - u.log.AddTrans("Ω", (amount > 0), amount, time(NULL)); + u.log.AddTrans("Ω", (amount > 0), std::abs(amount), time(NULL)); #endif })) { From 370107e3f9dd69de606ec78c43e057f6660beb02 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Mon, 9 Jan 2023 21:13:50 -0800 Subject: [PATCH 07/25] :memo: `ValidUsername` should allow capitilization --- docs/FAQ.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index 82989c3..275e54e 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -4,7 +4,7 @@ You can with [build docs](https://github.com/EntireTwix/CCash/blob/main/docs/building.md) you can build from source or use the Docker package. ### Why is my username invalid Usernames are restricted by minecraft's requirements -* lowercase letters +* letters * numbers * _ * length must be atleast 3 and at most 16 characters. @@ -16,7 +16,5 @@ Because this usecase requires none of the features a database would offer. Consider disabling `ADD_USER_OPEN` in the [build proccess](https://github.com/EntireTwix/CCash/blob/main/docs/building.md). ### My instance is taking up too much storage or RAM Reduce log size and/or use the prune users endpoint to remove dead accounts. -### How do I start an economy -I believe setting up a commodities exchange is the best way to get an economy going initially. ### Why not use an economy mod Speed of operations, CCash being external to MC (and so compatible with any version/configuration), and the API are the main advantages to an economy mod. \ No newline at end of file From 47649d6ccdc4aad253d16daf884683642ed8493e Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Tue, 10 Jan 2023 21:58:05 -0800 Subject: [PATCH 08/25] :sparkles: AdminGetLogs --- include/bank_api.h | 9 +++++++++ src/bank_api.cpp | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/bank_api.h b/include/bank_api.h index 610426e..24a2cf5 100644 --- a/include/bank_api.h +++ b/include/bank_api.h @@ -16,6 +16,7 @@ public: static void GetLogs(req_args); #endif static void GetLogsV2(req_args); + static void AdminGetLogs(req_args, const std::string& name); static void SendFunds(req_args); static void VerifyPassword(req_args); @@ -43,17 +44,25 @@ public: //Usage METHOD_ADD(api::GetBal, "/v1/user/balance?name={name}", Get, Options, "JsonFilter"); + #if MAX_LOG_SIZE > 0 + #if USE_DEPRECATED_ENDPOINTS METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter", "UserFilter"); #endif + METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter", "UserFilter"); + METHOD_ADD(api::AdminGetLogs, "/v1/admin/user/log?name={name}", Get, Options, "JsonFilter", "UserFilter"); #else + #if USE_DEPRECATED_ENDPOINTS METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter"); #endif + METHOD_ADD(api::GetLogsV2, "/v2/user/log", 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::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter", "JsonFilter"); diff --git a/src/bank_api.cpp b/src/bank_api.cpp index 4c4ae9d..c0383d5 100644 --- a/src/bank_api.cpp +++ b/src/bank_api.cpp @@ -54,6 +54,18 @@ void api::GetLogsV2(req_args) #endif } +void api::AdminGetLogs(req_args, const std::string& name) +{ +#if MAX_LOG_SIZE > 0 + RESPONSE_PARSE(Bank::GetLogsV2(name)); +#else + auto resp = HttpResponse::newCustomHttpResponse(BankResponse{k404NotFound, "\"Logs are Disabled\""}); + CORS; + CACHE_FOREVER; + callback(resp); +#endif +} + void api::SendFunds(req_args) { SIMD_JSON_GEN; From 88458de0f046b800efd846494b88fa3202d791fe Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Tue, 10 Jan 2023 21:59:36 -0800 Subject: [PATCH 09/25] :memo: added `AdminGetLogs` and reordered --- docs/connected_services/how_to/endpoints.md | 56 +++++++++++---------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/docs/connected_services/how_to/endpoints.md b/docs/connected_services/how_to/endpoints.md index dd76a7b..c34475d 100644 --- a/docs/connected_services/how_to/endpoints.md +++ b/docs/connected_services/how_to/endpoints.md @@ -20,55 +20,57 @@ | name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | | :------------- | :------: | ------------------------------------------------------------------------------ | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: | | GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | -| GetLog | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| GetLogV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogsV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | | SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `{name}` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | | VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | ### Usage enpoint errors | name | 400 | 401 | 404 | 406 | | :------------- | :----------------: | :----------------: | :----------------: | :----------------: | | GetBal | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | -| GetLog | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| GetLogV2 | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| GetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| GetLogsV2 | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | SendFunds | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | VerifyPassword | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | ### Meta Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :---------: | :----------------------------: | :----------------: | :----------------: | :----------------: | :----------------: | -| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | -| AdminChangePassword | `v2.3.0` | changes the password of a given user `{name}` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| SetBal | `v2.3.0` | sets the balance of a given user `{name}` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| ImpactBal | `v2.3.0` | modifies the user `{name}`'s balance by `{amount}` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :----------------: | +| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | +| AdminChangePassword | `v2.3.0` | changes the password of a given user `{name}` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| SetBal | `v2.3.0` | sets the balance of a given user `{name}` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| ImpactBal | `v2.3.0` | modifies the user `{name}`'s balance by `{amount}` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ### Meta Usage endpoint errors | name | 400 | 401 | 404 | 406 | | :------------------ | :----------------: | :----------------: | :----------------: | :----------------: | -| ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| AdminGetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | AdminChangePassword | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| AdminVerifyAccount | :heavy_check_mark: | :x: | :heavy_check_mark: | | SetBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | ImpactBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ### Sytem Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :----------------- | :------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | -| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: | -| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| Contains | `v2.3.0` | checks wether a user exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | -| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `{time}` (if logs are enabled) and have less money then `{amount}` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: | +| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------ | :------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | +| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: | +| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| Contains | `v2.3.0` | checks wether a user exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | +| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `{time}` (if logs are enabled) and have less money then `{amount}` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: | ### System Usage endpoin errors -| name | 401 | 404 | 406 | -| :----------------- | :----------------: | :----------------: | :----------------: | -| Help | :x: | :x: | :x: | -| Close | :heavy_check_mark: | :x: | :heavy_check_mark: | -| Contains | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| AdminVerifyAccount | :heavy_check_mark: | :x: | :heavy_check_mark: | -| PruneUsers | :heavy_check_mark: | :x: | :heavy_check_mark: | -| ApiProperties | :x: | :x: | :x: | +| name | 401 | 404 | 406 | +| :------------ | :----------------: | :----------------: | :----------------: | +| Help | :x: | :x: | :x: | +| Close | :heavy_check_mark: | :x: | :heavy_check_mark: | +| Contains | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| PruneUsers | :heavy_check_mark: | :x: | :heavy_check_mark: | +| ApiProperties | :x: | :x: | :x: | ### Username Requirements Valid From 6dad3ed0af08bf31640a70e8719cdb704a177dcd Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Tue, 10 Jan 2023 22:13:59 -0800 Subject: [PATCH 10/25] :memo: --- docs/connected_services/how_to/endpoints.md | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/connected_services/how_to/endpoints.md b/docs/connected_services/how_to/endpoints.md index c34475d..79d98cf 100644 --- a/docs/connected_services/how_to/endpoints.md +++ b/docs/connected_services/how_to/endpoints.md @@ -22,7 +22,7 @@ | GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | | GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | | GetLogsV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `{name}` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | | ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | | VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | @@ -37,20 +37,20 @@ | ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | ### Meta Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :----------------: | -| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | -| AdminChangePassword | `v2.3.0` | changes the password of a given user `{name}` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| SetBal | `v2.3.0` | sets the balance of a given user `{name}` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| ImpactBal | `v2.3.0` | modifies the user `{name}`'s balance by `{amount}` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | +| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| AdminChangePassword | `v2.3.0` | changes the password of a given user `"name"` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| SetBal | `v2.3.0` | sets the balance of a given user `"name"` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| ImpactBal | `v2.3.0` | modifies the user `"name"`'s balance by `"amount"` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ### Meta Usage endpoint errors | name | 400 | 401 | 404 | 406 | | :------------------ | :----------------: | :----------------: | :----------------: | :----------------: | | AdminGetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | AdminChangePassword | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| AdminVerifyAccount | :heavy_check_mark: | :x: | :heavy_check_mark: | +| AdminVerifyAccount | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: | | SetBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | ImpactBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | @@ -59,8 +59,8 @@ | :------------ | :------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | | Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: | | Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| Contains | `v2.3.0` | checks wether a user exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | -| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `{time}` (if logs are enabled) and have less money then `{amount}` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| Contains | `v2.3.0` | checks wether a given user `{name}` exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | +| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `"time"` (if logs are enabled) and have less money then `"amount"` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: | ### System Usage endpoin errors @@ -74,7 +74,7 @@ ### Username Requirements Valid -* lowercase letters +* letters * numbers * _ * Length must be atleast 3 and at most 16 characters. @@ -85,7 +85,7 @@ Valid | AddUser | `v2.3.0` | adding a user with a balance of 0 | {"name":string,"pass":string} | api/v1/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | | AdminAddUser | `v2.3.0` | adding a user with an arbitrary balance | {"name":string,"amount":uint32,"pass":string} | api/v1/admin/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | DelSelf | `v2.3.0` | deletes a user | `N/A` | api/v1/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| AdminDelUser | `v2.3.0` | deletes a given user `{name}` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| AdminDelUser | `v2.3.0` | deletes a given user `"name"` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ### User Management endpoint errors | name | 400 | 401 | 404 | 406 | 409 | From 2419641cd094fabcfbddd2c976b7aa99a7cb01ba Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Tue, 10 Jan 2023 22:21:38 -0800 Subject: [PATCH 11/25] :bug: fixed unsigned underflow when negative --- src/bank.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index ff5e770..7f32913 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -179,7 +179,6 @@ bool Bank::VerifyPassword(const std::string &name, const std::string_view &attem Bank::users.if_contains(name, [&res, &attempt](const User &u) { res = (u.password == xxHashStringGen{}(attempt)); }); return res; } - void Bank::ChangePassword(const std::string &name, const std::string &new_pass) noexcept { SET_CHANGES_ON; @@ -211,7 +210,7 @@ BankResponse Bank::ImpactBal(const std::string &name, int64_t amount) noexcept } uint32_t bal; if (ValidUsername(name) && Bank::users.modify_if(name, [&bal, &amount](User &u) { - if (u.balance < (amount * -1)) { amount = -u.balance; }; + if (u.balance < (amount * -1)) { amount = -int64_t(u.balance); }; bal = u.balance += amount; #if MAX_LOG_SIZE > 0 u.log.AddTrans("Ω", (amount > 0), std::abs(amount), time(NULL)); From dda98f346e42e8485d53af9f87b2cd78d2b7806b Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 00:18:42 -0800 Subject: [PATCH 12/25] :sparkles: `GetLogsRange` --- benchmarking.cpp | 15 +-------------- include/bank.h | 2 +- include/bank_api.h | 23 ++++++++++++---------- include/log.h | 1 + src/bank.cpp | 22 +++++++++++++++++++++ src/bank_api.cpp | 12 ++++++++++++ src/log.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 95 insertions(+), 28 deletions(-) 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; +} From 4a41cb1ef46d0ff108c35efea9f7354cee375005 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 00:31:03 -0800 Subject: [PATCH 13/25] :bug: how did this bug go unnoticed for so long --- src/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log.cpp b/src/log.cpp index a87d119..69454c7 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -9,7 +9,7 @@ void Log::AddTrans(const std::string &counterparty_str, bool receiving, uint32_t if (data.size() == MAX_LOG_SIZE) { - data.pop_back(); + data.pop_front(); } data.emplace_back(counterparty_str, receiving, amount, time); } From 6ddcf087974b02520b113084554f00ef8d883e56 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 00:33:35 -0800 Subject: [PATCH 14/25] :memo: `GetLogsRange` --- docs/connected_services/how_to/endpoints.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/connected_services/how_to/endpoints.md b/docs/connected_services/how_to/endpoints.md index 79d98cf..e1dcbea 100644 --- a/docs/connected_services/how_to/endpoints.md +++ b/docs/connected_services/how_to/endpoints.md @@ -17,14 +17,15 @@ ## all error responses have JSON string along with them to describe ### Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------- | :------: | ------------------------------------------------------------------------------ | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: | -| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | -| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| GetLogsV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | -| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | -| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------- | :------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: | +| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | +| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogsV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogsRange | `v2.6.1` | retrieves the logs of a given user, where `{start}` is the 0-indexed first log and `{length}` is the number of logs after that index. | `N/A` | api/v1/user/log_range | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | ### Usage enpoint errors | name | 400 | 401 | 404 | 406 | @@ -32,6 +33,7 @@ | GetBal | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | | GetLogs | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | GetLogsV2 | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| GetLogsRange | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | SendFunds | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | VerifyPassword | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: | | ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | From 01aedef7a30e9c8e05614bc2c50c035fa0194b89 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 00:55:08 -0800 Subject: [PATCH 15/25] :zap: rest of log optimization --- src/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log.cpp b/src/log.cpp index 69454c7..5779caf 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -96,7 +96,7 @@ std::string Log::GetLogsRange(size_t start, size_t length) noexcept ++log_index_n; } size_t log_index_m = log_snapshot_v2.size() - log_index_n; - if (length != MAX_LOG_SIZE) + if ((start + length + 1) != MAX_LOG_SIZE) { log_index_m = 0; while(i < log_snapshot_v2.size()) From cb5d12d4dc8dbafd29b35653aa2464e43182dc18 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 01:05:23 -0800 Subject: [PATCH 16/25] made `GetLogsV2` newest to oldest transaction --- docs/connected_services/how_to/endpoints.md | 58 ++++++++++----------- src/log.cpp | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/connected_services/how_to/endpoints.md b/docs/connected_services/how_to/endpoints.md index e1dcbea..bcab258 100644 --- a/docs/connected_services/how_to/endpoints.md +++ b/docs/connected_services/how_to/endpoints.md @@ -17,15 +17,15 @@ ## all error responses have JSON string along with them to describe ### Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------- | :------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: | -| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | -| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| GetLogsV2 | `v2.5.1` | retrieves the logs of a given user, length varies by server configuration | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| GetLogsRange | `v2.6.1` | retrieves the logs of a given user, where `{start}` is the 0-indexed first log and `{length}` is the number of logs after that index. | `N/A` | api/v1/user/log_range | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | -| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | -| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------- | :---------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------------: | :----------------: | :----------------: | :---: | :----------------: | +| GetBal | `v2.3.0` | retrieving the balance of a given user, `{name}` | `N/A` | api/v1/user/balance?name={name} | `GET` | 200 | uint32 | the user's balance | :heavy_check_mark: | :x: | :x: | :x: | +| GetLogs | `v2.3.0` | retrieves the logs of a given user, length varies by server configuration (oldest to newest transactions) | `N/A` | ⚠ api/v1/user/log | `GET` | 200 | array of objects | [{"to":string, "from":string, "amount":uint32, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogsV2 | `v2.6.1` | retrieves the logs of a given user, length varies by server configuration (newest to oldest transactions) | `N/A` | api/v2/user/log | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| GetLogsRange | `v2.6.1` | retrieves the logs of a given user, where `{start}` is the 0-indexed first log and `{length}` is the number of logs after that index. | `N/A` | api/v1/user/log_range | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| SendFunds | `v2.3.0` | sends funds from the authenticated user to the user `"name"` given in the json | {"name":string, "amount":uint32} | api/v1/user/transfer | `POST` | 200 | uint32 | the user's balance after the transaction | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| ChangePassword | `v2.3.0` | changes the password of the Authenticated user | {"pass":string} | api/v1/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | +| VerifyPassword | `v2.3.0` | verifies the credentials, used for connected services for ease of use | `N/A` | api/v1/user/verify_password | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | ### Usage enpoint errors | name | 400 | 401 | 404 | 406 | @@ -39,13 +39,13 @@ | ChangePassword | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | ### Meta Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------------ | :------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | -| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| AdminChangePassword | `v2.3.0` | changes the password of a given user `"name"` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| SetBal | `v2.3.0` | sets the balance of a given user `"name"` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| ImpactBal | `v2.3.0` | modifies the user `"name"`'s balance by `"amount"` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------------ | :---------: | -------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------- | :---------: | :------------: | :--------------: | :-----------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | +| AdminGetLogs | `v2.6.1` | retreives the logs of a given user `{name}`, length varies by server configuration | `N/A` | api/v1/admin/user/log?name={name} | `GET` | 200 | array of objects | [{"counterparty":string, "amount":int64, "time":int64}] | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| AdminChangePassword | `v2.3.0` | changes the password of a given user `"name"` | {"name":string,"pass":string} | api/v1/admin/user/change_password | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| AdminVerifyAccount | `v2.3.0` | checks wether a user is the admin | `N/A` | api/v1/admin/verify_account | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| SetBal | `v2.3.0` | sets the balance of a given user `"name"` | {"name":string,"amount":uint32} | api/v1/admin/set_balance | `PATCH` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| ImpactBal | `v2.3.0` | modifies the user `"name"`'s balance by `"amount"` if positive itll add, if negative itll subtract | {"name":string,"amount":int64} | api/v1/admin/impact_balance | `POST` | 200 | uint32 | new balance after modification | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ### Meta Usage endpoint errors | name | 400 | 401 | 404 | 406 | @@ -57,13 +57,13 @@ | ImpactBal | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ### Sytem Usage endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :------------ | :------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | -| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: | -| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | -| Contains | `v2.3.0` | checks wether a given user `{name}` exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | -| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `"time"` (if logs are enabled) and have less money then `"amount"` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: | +| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :------------ | :---------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------ | :---------: | :------------: | :---------: | :-----------------------------------------------------------------: | :----------------: | :----------------: | :----------------: | :---: | +| Help | `v2.3.0` | redirects to GitHub projects Docs | `N/A` | api/help | `GET` | 301 | `N/A` | `N/A` | :x: | :x: | :x: | :x: | +| Close | `v2.3.0` | saves & closes the CCash webserver | `N/A` | api/v1/admin/shutdown | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | +| Contains | `v2.3.0` | checks wether a given user `{name}` exists | `N/A` | api/v1/user/exists?name={name} | `GET` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :x: | +| PruneUsers | `v2.3.0` | deletes users with most recent transactions older then `"time"` (if logs are enabled) and have less money then `"amount"` | {"time":int64,"amount":uint32} or just {"amount":uint32} | api/v1/admin/prune_users | `POST` | 200 | uint64 | number of users deleted | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| ApiProperties | `v2.5.1` | properties of the given instance | `N/A` | api/properties | `GET` | 200 | json object | {"max_log":uint64, "add_user_open":boolean, "return_on_del":string} | :heavy_check_mark: | :x: | :x: | :x: | ### System Usage endpoin errors | name | 401 | 404 | 406 | @@ -82,12 +82,12 @@ Valid * Length must be atleast 3 and at most 16 characters. ### User Management endpoints -| name | added on | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | -| :----------- | :------: | --------------------------------------- | --------------------------------------------- | -------------------------- | :---------: | :------------: | :---------: | :----------: | :----------------: | :----------------: | :----------------: | :----------------: | -| AddUser | `v2.3.0` | adding a user with a balance of 0 | {"name":string,"pass":string} | api/v1/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | -| AdminAddUser | `v2.3.0` | adding a user with an arbitrary balance | {"name":string,"amount":uint32,"pass":string} | api/v1/admin/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | -| DelSelf | `v2.3.0` | deletes a user | `N/A` | api/v1/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | -| AdminDelUser | `v2.3.0` | deletes a given user `"name"` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| name | last change | purpose | json input | path | HTTP Method | correct status | return type | return value | Jresp | Jreq | A | U | +| :----------- | :---------: | --------------------------------------- | --------------------------------------------- | -------------------------- | :---------: | :------------: | :---------: | :----------: | :----------------: | :----------------: | :----------------: | :----------------: | +| AddUser | `v2.3.0` | adding a user with a balance of 0 | {"name":string,"pass":string} | api/v1/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | +| AdminAddUser | `v2.3.0` | adding a user with an arbitrary balance | {"name":string,"amount":uint32,"pass":string} | api/v1/admin/user/register | `POST` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | +| DelSelf | `v2.3.0` | deletes a user | `N/A` | api/v1/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | +| AdminDelUser | `v2.3.0` | deletes a given user `"name"` | {"name":string} | api/v1/admin/user/delete | `DELETE` | 204 | `N/A` | `N/A` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ### User Management endpoint errors | name | 400 | 401 | 404 | 406 | 409 | diff --git a/src/log.cpp b/src/log.cpp index 5779caf..72c1d1c 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -59,7 +59,7 @@ std::string Log::GetLogsV2() noexcept log_snapshot_v2.reserve(predicted_size); } log_snapshot_v2 = '['; //1 - for (size_t i = 0; i < data.size(); ++i) + for (size_t i = data.size(); i --> 0;) { log_snapshot_v2 += "{\"counterparty\":\""; //17 log_snapshot_v2 += data[i].counterparty; //max_name_size? From eea9c4b566b9538b330a4bfbf7eebe371ee9a2b7 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 12:26:42 -0800 Subject: [PATCH 17/25] :zap: rest of log optimization --- src/log.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/log.cpp b/src/log.cpp index 72c1d1c..af2e3eb 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -82,6 +82,7 @@ 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(); } + if (length > data.size()) { length = data.size(); } size_t log_index_n = 0, i = 0; while(i < log_snapshot_v2.size()) From 511aa767951be1fb987ade5618c6cd9ab28a9516 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 13:17:54 -0800 Subject: [PATCH 18/25] :bug: correcting last commit --- src/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log.cpp b/src/log.cpp index af2e3eb..d64a0c1 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -82,7 +82,7 @@ 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(); } - if (length > data.size()) { length = data.size(); } + if (length > data.size()) { length = data.size() - start; } size_t log_index_n = 0, i = 0; while(i < log_snapshot_v2.size()) From af551ef8b4db5f5dd725b69d1a56951fd700fad7 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 13:27:53 -0800 Subject: [PATCH 19/25] :bug: correcting last commit --- src/log.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index d64a0c1..817afce 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -82,7 +82,7 @@ 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(); } - if (length > data.size()) { length = data.size() - start; } + if ((start + length + 1) >= data.size()) { length = data.size() - start; } size_t log_index_n = 0, i = 0; while(i < log_snapshot_v2.size()) @@ -97,7 +97,7 @@ std::string Log::GetLogsRange(size_t start, size_t length) noexcept ++log_index_n; } size_t log_index_m = log_snapshot_v2.size() - log_index_n; - if ((start + length + 1) != MAX_LOG_SIZE) + if ((start + length + 1) != data.size()) { log_index_m = 0; while(i < log_snapshot_v2.size()) From f2da8cdbc259cc7d68d4ce8bd80af33f45d4cd09 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 16:29:13 -0800 Subject: [PATCH 20/25] :zap: optimizing `GetLogsRange` --- src/log.cpp | 89 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index 817afce..623cbff 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -82,40 +82,87 @@ 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(); } - if ((start + length + 1) >= data.size()) { length = data.size() - start; } - size_t log_index_n = 0, i = 0; - while(i < log_snapshot_v2.size()) + size_t log_index_n, i; + if (start < (0.5 * MAX_LOG_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 ((start + length + 1) != data.size()) - { - log_index_m = 0; + // std::cout << "a\n"; + i = 0; + log_index_n = 0; while(i < log_snapshot_v2.size()) { - if (log_index_m == length) + if (log_index_n == start) { - log_index_m = i + 1; + log_index_n = i; break; } i += (41 + min_name_size); while (log_snapshot_v2[i] != ',') { ++i; } - ++log_index_m; + ++log_index_n; + } + } + else + { + // std::cout << "b\n"; + i = log_snapshot_v2.size(); + log_index_n = data.size(); + while(i --> 0) + { + if (log_index_n == start) + { + log_index_n = i + 1; + break; + } + i -= (41 + min_name_size); + while (log_snapshot_v2[i] != ',') { --i; } + --log_index_n; } } - std::string res(log_snapshot_v2.substr(log_index_n, log_index_m - log_index_n)); + size_t log_index_m = std::string::npos; + if ((start + length) < data.size()) + { + if (length < (0.5 * MAX_LOG_SIZE)) + { + // std::cout << "c\n"; + 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; + } + } + else + { + // std::cout << "d\n"; + i = log_snapshot_v2.size(); + log_index_m = data.size(); + while(i --> 0) + { + 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; + } + } + + log_index_m -= log_index_n; + } + + std::string res(log_snapshot_v2.substr(log_index_n, log_index_m)); res[0] = '['; - res[log_index_m - log_index_n - 1] = ']'; + res[res.size() - 1] = ']'; + // std::cout << res << '\n'; return res; } From c970b6a42f33dc1d28a50a85113857f48246f203 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 16:33:01 -0800 Subject: [PATCH 21/25] loosened endpoint restrictions --- src/bank.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bank.cpp b/src/bank.cpp index 4463946..3988a87 100644 --- a/src/bank.cpp +++ b/src/bank.cpp @@ -121,11 +121,11 @@ BankResponse Bank::GetLogsRange(const std::string &name, size_t start, size_t le BankResponse res; if (start >= MAX_LOG_SIZE) { - return {k400BadRequest, "\"Invalid starting index\""}; + return {k400BadRequest, "\"Invalid {start} index\""}; } - if (length == 0 || (length + start) > MAX_LOG_SIZE) + if (!length) { - return {k400BadRequest, "\"Invalid length\""}; + return {k400BadRequest, "\"Invalid {length}\""}; } if (!Bank::users.modify_if(name, [&name, &res, start, length](User &u) { res = {k200OK, u.log.GetLogsRange(start, length)}; })) From a98b84955ce817a5e745095c3dcf6202193d4f39 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 12 Jan 2023 16:51:09 -0800 Subject: [PATCH 22/25] start is 0-indexed so == to data.size() is out of bounds --- src/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log.cpp b/src/log.cpp index 623cbff..e690f82 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -79,7 +79,7 @@ std::string Log::GetLogsV2() noexcept std::string Log::GetLogsRange(size_t start, size_t length) noexcept { - if (start > data.size()) { return "[]"; } + if (start >= data.size()) { return "[]"; } if (start == 0 && length == MAX_LOG_SIZE) { return log_snapshot_v2; } if (log_flag_v2.GetChangeState() && data.size()) { GetLogsV2(); } From 32f5f2a2be916af2f6e1caab6069cd42cfa146e0 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Wed, 18 Jan 2023 15:36:49 -0800 Subject: [PATCH 23/25] daemon flag error --- main.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 8d0aa2a..38c819c 100644 --- a/main.cpp +++ b/main.cpp @@ -40,17 +40,17 @@ int main(int argc, char **argv) { std::cerr << "File cannot be created (may already exist)\n"; } - return 0; + return -1; } if (argc < 3) { std::cerr << "Usage: sudo ./bank [daemon flag {default: false}]\n"; - return 0; + return -1; } if (geteuid() != 0) { std::cerr << "ERROR: CCash MUST be ran as root\n"; - return 0; + return -1; } const unsigned long saving_freq = std::stoul(std::string(argv[2])); std::cout @@ -104,6 +104,11 @@ int main(int argc, char **argv) } if (argc == 4 && !strcmp(argv[3], "true")) { app().enableRunAsDaemon(); } + else if (argc == 4 && strcmp(argv[3], "false")) + { + std::cerr << "daemon flag must be \"true\" or \"false\"\n"; + return -1; + } } //destroying setup variables app() From a61a590f3ac0446e093c8d9d57caf109c0492971 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Wed, 18 Jan 2023 15:54:45 -0800 Subject: [PATCH 24/25] cleaned up --- main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 38c819c..30e7786 100644 --- a/main.cpp +++ b/main.cpp @@ -34,13 +34,13 @@ int main(int argc, char **argv) uint8_t temp[16]{16, 0, 0, 0, 4}; users_save.write((char *)temp, 16); users_save.close(); - std::cout << "User save file generated\nUsage: sudo ./bank [daemon flag {default: false}]\n"; + std::cout << "User save file generated\n"; } else { std::cerr << "File cannot be created (may already exist)\n"; + return -1; } - return -1; } if (argc < 3) { @@ -104,7 +104,7 @@ int main(int argc, char **argv) } if (argc == 4 && !strcmp(argv[3], "true")) { app().enableRunAsDaemon(); } - else if (argc == 4 && strcmp(argv[3], "false")) + else if (argc == 4 && strcmp(argv[3], "false")) { std::cerr << "daemon flag must be \"true\" or \"false\"\n"; return -1; From caf1d65e16e4b6ee36c6f93a7a38c8ed7ddc9bd9 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Wed, 18 Jan 2023 17:19:30 -0800 Subject: [PATCH 25/25] :bug: correcting last commit --- main.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index 30e7786..9efba20 100644 --- a/main.cpp +++ b/main.cpp @@ -34,7 +34,8 @@ int main(int argc, char **argv) uint8_t temp[16]{16, 0, 0, 0, 4}; users_save.write((char *)temp, 16); users_save.close(); - std::cout << "User save file generated\n"; + std::cout << "User save file generated\n" << "Usage: sudo ./bank [daemon flag {default: false}]\n"; + return 0; } else { @@ -54,8 +55,8 @@ int main(int argc, char **argv) } const unsigned long saving_freq = std::stoul(std::string(argv[2])); std::cout - << "\nAPI : v2.5.1" - << "\n\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled") + << "\nAPI : v2.6.1\n" + << "\nAVX : " << (__builtin_cpu_supports("avx") ? "enabled" : "disabled") << "\nAVX 2 : " << (__builtin_cpu_supports("avx2") ? "enabled" : "disabled") << "\nSSE 2 : " << (__builtin_cpu_supports("sse2") ? "enabled" : "disabled") << "\nSSE 3 : " << (__builtin_cpu_supports("sse3") ? "enabled" : "disabled") @@ -92,15 +93,14 @@ int main(int argc, char **argv) if (saving_freq) //if saving frequency is 0 then auto saving is turned off { std::thread([saving_freq]() - { - while (1) - { - std::this_thread::sleep_for(std::chrono::minutes(saving_freq)); - std::cout << "Saving " << std::time(0) << "...\n" - << Bank::Save(); - } - }) - .detach(); + { + while (1) + { + std::this_thread::sleep_for(std::chrono::minutes(saving_freq)); + std::cout << "Saving " << std::time(0) << "...\n" << Bank::Save(); + } + }) + .detach(); } if (argc == 4 && !strcmp(argv[3], "true")) { app().enableRunAsDaemon(); }