mirror of
https://github.com/Expand-sys/CCash
synced 2025-12-15 15:52:13 +11:00
✨ improved Transaction structure
This commit is contained in:
parent
ab27971d8e
commit
b584f5b4d5
10 changed files with 110 additions and 33 deletions
|
|
@ -2,8 +2,8 @@ package bank_dom
|
|||
|
||||
struct Transaction
|
||||
{
|
||||
string from = "";
|
||||
string to = "";
|
||||
string counterparty = "";
|
||||
bool receiving = false;
|
||||
uint32 amount = 0;
|
||||
timestamp time;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ using namespace drogon;
|
|||
class api : public HttpController<api>
|
||||
{
|
||||
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<false>");
|
||||
#if MAX_LOG_SIZE > 0
|
||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||
#if API_VERSION >= 2
|
||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>", "UserFilter<true, false>");
|
||||
#endif
|
||||
#else
|
||||
METHOD_ADD(api::GetLogs, "/v1/user/log", Get, Options, "JsonFilter<false>");
|
||||
#if API_VERSION >= 2
|
||||
METHOD_ADD(api::GetLogsV2, "/v2/user/log", Get, Options, "JsonFilter<false>");
|
||||
#endif
|
||||
#endif
|
||||
METHOD_ADD(api::SendFunds, "/v1/user/transfer", Post, Options, "JsonFilter<true>", "UserFilter<true, false>"); //expects ["name"](string) and ["amount"](uint32)
|
||||
METHOD_ADD(api::VerifyPassword, "/v1/user/verify_password", Post, Options, "UserFilter<false, false>", "JsonFilter<false>");
|
||||
|
|
|
|||
|
|
@ -12,10 +12,16 @@ struct Log
|
|||
private:
|
||||
ChangeFlag<true> log_flag;
|
||||
std::string log_snapshot = "null";
|
||||
#if API_VERSION >= 2
|
||||
std::string log_snapshot_v2 = "null";
|
||||
#endif
|
||||
|
||||
public:
|
||||
std::deque<Transaction> 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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
20
src/bank.cpp
20
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; });
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
47
src/log.cpp
47
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,11 +24,11 @@ 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 += "{\"to\":\""; //7
|
||||
log_snapshot += data[i].receiving? name : data[i].counterparty; //max_name_size?
|
||||
log_snapshot += "\",\"from\":\""; //10
|
||||
log_snapshot += data[i].from; //max_name_size?
|
||||
log_snapshot += "\",\"amount\":"; //12
|
||||
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?
|
||||
|
|
@ -37,5 +37,36 @@ std::string Log::GetLogs() noexcept
|
|||
log_snapshot.back() = ']';
|
||||
log_flag.SetChangesOff();
|
||||
}
|
||||
|
||||
return log_snapshot;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue