Merge pull request #43 from EntireTwix/transaction_optimization

Transaction Optimization
This commit is contained in:
William 2022-11-28 17:10:24 -08:00 committed by GitHub
commit 244ca2561c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 274 additions and 144 deletions

View file

@ -3,7 +3,7 @@
// Setting to 0 does not compile logging (useful for if disk/memory is very valuable)
#define MAX_LOG_SIZE @MAX_LOG_SIZE_VAL@
//default to minecraft usernames
// Default to minecraft usernames
constexpr unsigned min_name_size = 3;
constexpr unsigned max_name_size = 16;
@ -29,13 +29,13 @@ if false, when frequency is hit save
#define CONSERVATIVE_DISK_SAVE @CONSERVATIVE_DISK_SAVE_VAL@
/*
example, when set to 2
version 1 will not work
e.g when set to 2
version 1 will work
version 2 will work
version 3 will work
version 3 will not work
etc
*/
#define API_VERSION 1
#define API_VERSION 2
#define MULTI_THREADED @MULTI_THREADED_VAL@

View file

@ -2,8 +2,8 @@ package bank_dom
struct Transaction
{
string from = "";
string to = "";
string counterparty = "";
bool receiving = false;
uint32 amount = 0;
timestamp time;
}

View file

@ -1,22 +1,24 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "bank_dom.h"
namespace bank_dom {
Transaction::Transaction()
: from("")
, to("")
: counterparty("")
, receiving(false)
, amount((uint32_t)0ull)
, time((uint64_t)0ull)
{}
Transaction::Transaction(const std::string& arg_from, const std::string& arg_to, uint32_t arg_amount, uint64_t arg_time)
: from(arg_from)
, to(arg_to)
Transaction::Transaction(const std::string& arg_counterparty, bool arg_receiving, uint32_t arg_amount, uint64_t arg_time)
: counterparty(arg_counterparty)
, receiving(arg_receiving)
, amount(arg_amount)
, time(arg_time)
{}
@ -36,8 +38,8 @@ bool Transaction::operator<(const Transaction& other) const noexcept
void Transaction::swap(Transaction& other) noexcept
{
using std::swap;
swap(from, other.from);
swap(to, other.to);
swap(counterparty, other.counterparty);
swap(receiving, other.receiving);
swap(amount, other.amount);
swap(time, other.time);
}
@ -45,8 +47,8 @@ void Transaction::swap(Transaction& other) noexcept
std::ostream& operator<<(std::ostream& stream, const Transaction& value)
{
stream << "Transaction(";
stream << "from="; stream << "\"" << value.from << "\"";
stream << ",to="; stream << "\"" << value.to << "\"";
stream << "counterparty="; stream << "\"" << value.counterparty << "\"";
stream << ",receiving="; stream << (value.receiving ? "true" : "false");
stream << ",amount="; stream << value.amount;
stream << ",time="; stream << value.time;
stream << ")";

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once
@ -27,15 +29,15 @@ namespace bank_dom {
struct Transaction
{
std::string from;
std::string to;
std::string counterparty;
bool receiving;
uint32_t amount;
uint64_t time;
size_t fbe_type() const noexcept { return 1; }
Transaction();
Transaction(const std::string& arg_from, const std::string& arg_to, uint32_t arg_amount, uint64_t arg_time);
Transaction(const std::string& arg_counterparty, bool arg_receiving, uint32_t arg_amount, uint64_t arg_time);
Transaction(const Transaction& other) = default;
Transaction(Transaction&& other) = default;
~Transaction() = default;
@ -60,10 +62,12 @@ struct Transaction
} // namespace bank_dom
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <> struct fmt::formatter<bank_dom::Transaction> : ostream_formatter {};
#endif
template<>
struct hash<bank_dom::Transaction>
struct std::hash<bank_dom::Transaction>
{
typedef bank_dom::Transaction argument_type;
typedef size_t result_type;
@ -75,8 +79,6 @@ struct hash<bank_dom::Transaction>
}
};
} // namespace std
namespace bank_dom {
struct Logs
@ -111,10 +113,12 @@ struct Logs
} // namespace bank_dom
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <> struct fmt::formatter<bank_dom::Logs> : ostream_formatter {};
#endif
template<>
struct hash<bank_dom::Logs>
struct std::hash<bank_dom::Logs>
{
typedef bank_dom::Logs argument_type;
typedef size_t result_type;
@ -126,8 +130,6 @@ struct hash<bank_dom::Logs>
}
};
} // namespace std
namespace bank_dom {
struct User
@ -164,10 +166,12 @@ struct User
} // namespace bank_dom
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <> struct fmt::formatter<bank_dom::User> : ostream_formatter {};
#endif
template<>
struct hash<bank_dom::User>
struct std::hash<bank_dom::User>
{
typedef bank_dom::User argument_type;
typedef size_t result_type;
@ -179,8 +183,6 @@ struct hash<bank_dom::User>
}
};
} // namespace std
namespace bank_dom {
struct Global
@ -216,10 +218,12 @@ struct Global
} // namespace bank_dom
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <> struct fmt::formatter<bank_dom::Global> : ostream_formatter {};
#endif
template<>
struct hash<bank_dom::Global>
struct std::hash<bank_dom::Global>
{
typedef bank_dom::Global argument_type;
typedef size_t result_type;
@ -231,8 +235,6 @@ struct hash<bank_dom::Global>
}
};
} // namespace std
namespace bank_dom {
} // namespace bank_dom

View file

@ -1,15 +1,17 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "bank_dom_final_models.h"
namespace FBE {
FinalModel<::bank_dom::Transaction>::FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, from(buffer, 0)
, to(buffer, 0)
, counterparty(buffer, 0)
, receiving(buffer, 0)
, amount(buffer, 0)
, time(buffer, 0)
{}
@ -17,8 +19,8 @@ FinalModel<::bank_dom::Transaction>::FinalModel(FBEBuffer& buffer, size_t offset
size_t FinalModel<::bank_dom::Transaction>::fbe_allocation_size(const ::bank_dom::Transaction& fbe_value) const noexcept
{
size_t fbe_result = 0
+ from.fbe_allocation_size(fbe_value.from)
+ to.fbe_allocation_size(fbe_value.to)
+ counterparty.fbe_allocation_size(fbe_value.counterparty)
+ receiving.fbe_allocation_size(fbe_value.receiving)
+ amount.fbe_allocation_size(fbe_value.amount)
+ time.fbe_allocation_size(fbe_value.time)
;
@ -38,14 +40,14 @@ size_t FinalModel<::bank_dom::Transaction>::verify_fields() const noexcept
size_t fbe_current_offset = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.verify();
counterparty.fbe_offset(fbe_current_offset);
fbe_field_size = counterparty.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.verify();
receiving.fbe_offset(fbe_current_offset);
fbe_field_size = receiving.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
@ -79,13 +81,13 @@ size_t FinalModel<::bank_dom::Transaction>::get_fields(::bank_dom::Transaction&
size_t fbe_current_size = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.get(fbe_value.from);
counterparty.fbe_offset(fbe_current_offset);
fbe_field_size = counterparty.get(fbe_value.counterparty);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.get(fbe_value.to);
receiving.fbe_offset(fbe_current_offset);
fbe_field_size = receiving.get(fbe_value.receiving);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
@ -116,13 +118,13 @@ size_t FinalModel<::bank_dom::Transaction>::set_fields(const ::bank_dom::Transac
size_t fbe_current_size = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.set(fbe_value.from);
counterparty.fbe_offset(fbe_current_offset);
fbe_field_size = counterparty.set(fbe_value.counterparty);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.set(fbe_value.to);
receiving.fbe_offset(fbe_current_offset);
fbe_field_size = receiving.set(fbe_value.receiving);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once
@ -60,8 +62,8 @@ private:
mutable size_t _offset;
public:
FinalModel<std::string> from;
FinalModel<std::string> to;
FinalModel<std::string> counterparty;
FinalModel<bool> receiving;
FinalModel<uint32_t> amount;
FinalModel<uint64_t> time;
};

View file

@ -1,24 +1,26 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "bank_dom_models.h"
namespace FBE {
FieldModel<::bank_dom::Transaction>::FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, from(buffer, 4 + 4)
, to(buffer, from.fbe_offset() + from.fbe_size())
, amount(buffer, to.fbe_offset() + to.fbe_size())
, counterparty(buffer, 4 + 4)
, receiving(buffer, counterparty.fbe_offset() + counterparty.fbe_size())
, amount(buffer, receiving.fbe_offset() + receiving.fbe_size())
, time(buffer, amount.fbe_offset() + amount.fbe_size())
{}
size_t FieldModel<::bank_dom::Transaction>::fbe_body() const noexcept
{
size_t fbe_result = 4 + 4
+ from.fbe_size()
+ to.fbe_size()
+ counterparty.fbe_size()
+ receiving.fbe_size()
+ amount.fbe_size()
+ time.fbe_size()
;
@ -37,8 +39,8 @@ size_t FieldModel<::bank_dom::Transaction>::fbe_extra() const noexcept
_buffer.shift(fbe_struct_offset);
size_t fbe_result = fbe_body()
+ from.fbe_extra()
+ to.fbe_extra()
+ counterparty.fbe_extra()
+ receiving.fbe_extra()
+ amount.fbe_extra()
+ time.fbe_extra()
;
@ -75,17 +77,17 @@ bool FieldModel<::bank_dom::Transaction>::verify_fields(size_t fbe_struct_size)
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + from.fbe_size()) > fbe_struct_size)
if ((fbe_current_size + counterparty.fbe_size()) > fbe_struct_size)
return true;
if (!from.verify())
if (!counterparty.verify())
return false;
fbe_current_size += from.fbe_size();
fbe_current_size += counterparty.fbe_size();
if ((fbe_current_size + to.fbe_size()) > fbe_struct_size)
if ((fbe_current_size + receiving.fbe_size()) > fbe_struct_size)
return true;
if (!to.verify())
if (!receiving.verify())
return false;
fbe_current_size += to.fbe_size();
fbe_current_size += receiving.fbe_size();
if ((fbe_current_size + amount.fbe_size()) > fbe_struct_size)
return true;
@ -141,17 +143,17 @@ void FieldModel<::bank_dom::Transaction>::get_fields(::bank_dom::Transaction& fb
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + from.fbe_size()) <= fbe_struct_size)
from.get(fbe_value.from, "");
if ((fbe_current_size + counterparty.fbe_size()) <= fbe_struct_size)
counterparty.get(fbe_value.counterparty, "");
else
fbe_value.from = "";
fbe_current_size += from.fbe_size();
fbe_value.counterparty = "";
fbe_current_size += counterparty.fbe_size();
if ((fbe_current_size + to.fbe_size()) <= fbe_struct_size)
to.get(fbe_value.to, "");
if ((fbe_current_size + receiving.fbe_size()) <= fbe_struct_size)
receiving.get(fbe_value.receiving, false);
else
fbe_value.to = "";
fbe_current_size += to.fbe_size();
fbe_value.receiving = false;
fbe_current_size += receiving.fbe_size();
if ((fbe_current_size + amount.fbe_size()) <= fbe_struct_size)
amount.get(fbe_value.amount, (uint32_t)0ull);
@ -203,8 +205,8 @@ void FieldModel<::bank_dom::Transaction>::set(const ::bank_dom::Transaction& fbe
void FieldModel<::bank_dom::Transaction>::set_fields(const ::bank_dom::Transaction& fbe_value) noexcept
{
from.set(fbe_value.from);
to.set(fbe_value.to);
counterparty.set(fbe_value.counterparty);
receiving.set(fbe_value.receiving);
amount.set(fbe_value.amount);
time.set(fbe_value.time);
}

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once
@ -72,8 +74,8 @@ private:
size_t _offset;
public:
FieldModel<std::string> from;
FieldModel<std::string> to;
FieldModel<std::string> counterparty;
FieldModel<bool> receiving;
FieldModel<uint32_t> amount;
FieldModel<uint64_t> time;
};

View file

@ -1,10 +1,24 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "fbe.h"
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <rpc.h>
#undef DELETE
#undef ERROR
#undef HOST_NOT_FOUND
#undef Yield
#undef min
#undef max
#undef uuid_t
#endif
namespace FBE {
std::string buffer_t::base64encode() const

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once
@ -41,7 +43,6 @@
#include <uuid/uuid.h>
#undef HOST_NOT_FOUND
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef DELETE
#undef ERROR
#undef HOST_NOT_FOUND
@ -321,10 +322,20 @@ private:
} // namespace FBE
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <>
struct fmt::formatter<FBE::decimal_t> : formatter<std::string_view>
{
template <typename FormatContext>
auto format(const FBE::decimal_t& value, FormatContext& ctx) const
{
return formatter<string_view>::format((double)value, ctx);
}
};
#endif
template <>
struct hash<FBE::decimal_t>
struct std::hash<FBE::decimal_t>
{
typedef FBE::decimal_t argument_type;
typedef size_t result_type;
@ -337,8 +348,6 @@ struct hash<FBE::decimal_t>
}
};
} // namespace std
namespace FBE {
// Register a new enum-based flags macro
@ -530,10 +539,20 @@ private:
} // namespace FBE
namespace std {
#if defined(FMT_VERSION) && (FMT_VERSION >= 90000)
template <>
struct fmt::formatter<FBE::uuid_t> : formatter<std::string_view>
{
template <typename FormatContext>
auto format(const FBE::uuid_t& value, FormatContext& ctx) const
{
return formatter<string_view>::format(value.string(), ctx);
}
};
#endif
template <>
struct hash<FBE::uuid_t>
struct std::hash<FBE::uuid_t>
{
typedef FBE::uuid_t argument_type;
typedef size_t result_type;
@ -548,8 +567,6 @@ struct hash<FBE::uuid_t>
}
};
} // namespace std
namespace FBE {
// Fast Binary Encoding buffer based on the dynamic byte buffer

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "fbe_final_models.h"

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
namespace FBE {
@ -536,8 +538,8 @@ inline size_t FinalModelMap<TKey, TValue>::get(std::map<TKey, TValue>& values) c
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
TKey key = TKey();
TValue value = TValue();
size_t offset_key = fbe_model_key.get(key);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
@ -568,8 +570,8 @@ inline size_t FinalModelMap<TKey, TValue>::get(std::unordered_map<TKey, TValue>&
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
TKey key = TKey();
TValue value = TValue();
size_t offset_key = fbe_model_key.get(key);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#include "fbe_models.h"

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
#pragma once

View file

@ -1,7 +1,9 @@
//------------------------------------------------------------------------------
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
// FBE version: 1.14.1.0
//------------------------------------------------------------------------------
namespace FBE {
@ -618,8 +620,8 @@ inline void FieldModelMap<TKey, TValue>::get(std::map<TKey, TValue>& values) con
auto fbe_model = (*this)[0];
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
TKey key = TKey();
TValue value = TValue();
fbe_model.first.get(key);
fbe_model.second.get(value);
values.emplace(key, value);
@ -640,8 +642,8 @@ inline void FieldModelMap<TKey, TValue>::get(std::unordered_map<TKey, TValue>& v
auto fbe_model = (*this)[0];
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
TKey key = TKey();
TValue value = TValue();
fbe_model.first.get(key);
fbe_model.second.get(value);
values.emplace(key, value);

View file

@ -32,7 +32,7 @@ private:
#endif
// must grab as shared if the operation is gonna modify "users"'s size or can be caught in a intermediary state such as SendFunds()
//must grab as unique if the operation is gonna user iterators
// must grab as unique if the operation is gonna use user iterators
static std::shared_mutex iter_lock;
public:
@ -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;

View file

@ -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,17 +35,21 @@ public:
static void AdminAddUser(req_args);
static void DelSelf(req_args);
static void AdminDelUser(req_args);
#endif
METHOD_LIST_BEGIN
#if API_VERSION >= 1
//Usage
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>");
@ -67,7 +73,6 @@ public:
METHOD_ADD(api::AdminAddUser, "/v1/admin/user/register", Post, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string) ["amount"](uint32) ["pass"](string)
METHOD_ADD(api::DelSelf, "/v1/user/delete", Delete, Options, "UserFilter<true, false>", "JsonFilter<false>");
METHOD_ADD(api::AdminDelUser, "/v1/admin/user/delete", Delete, Options, "JsonFilter<true>", "UserFilter<false, true>"); //expects ["name"](string)
#endif
METHOD_LIST_END
};

View file

@ -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;
};

View file

@ -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
*/

View file

@ -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; });

View file

@ -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

View file

@ -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;
}

View file

@ -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) {}

View file

@ -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);
}