Skip to content

Commit

Permalink
[Refactoring] - Use glaze for file read, remove readAllJson from Reader
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Nov 24, 2024
1 parent a1b60fb commit c124e10
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 164 deletions.
5 changes: 3 additions & 2 deletions src/api/common/include/commonapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "binance-common-api.hpp"
#include "cache-file-updator-interface.hpp"
#include "cachedresult.hpp"
#include "cct_const.hpp"
#include "curlhandle.hpp"
#include "currencycode.hpp"
#include "currencycodeset.hpp"
Expand Down Expand Up @@ -38,10 +39,10 @@ class CommonAPI : public CacheFileUpdatorInterface {
/// Information here: https://en.wikipedia.org/wiki/Fiat_money
bool queryIsCurrencyCodeFiat(CurrencyCode currencyCode);

std::optional<MonetaryAmount> tryQueryWithdrawalFee(std::string_view exchangeName, CurrencyCode currencyCode);
std::optional<MonetaryAmount> tryQueryWithdrawalFee(ExchangeNameEnum exchangeNameEnum, CurrencyCode currencyCode);

/// Query withdrawal fees from crawler sources. It's not guaranteed to work though.
MonetaryAmountByCurrencySet tryQueryWithdrawalFees(std::string_view exchangeName);
MonetaryAmountByCurrencySet tryQueryWithdrawalFees(ExchangeNameEnum exchangeNameEnum);

BinanceGlobalInfos &getBinanceGlobalInfos() { return _binanceGlobalInfos; }

Expand Down
13 changes: 8 additions & 5 deletions src/api/common/include/withdrawalfees-crawler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "cache-file-updator-interface.hpp"
#include "cachedresult.hpp"
#include "cachedresultvault.hpp"
#include "cct_const.hpp"
#include "coincenterinfo.hpp"
#include "curlhandle.hpp"
#include "currencycode.hpp"
Expand All @@ -26,7 +27,9 @@ class WithdrawalFeesCrawler : public CacheFileUpdatorInterface {
using WithdrawalMinMap = std::unordered_map<CurrencyCode, MonetaryAmount>;
using WithdrawalInfoMaps = std::pair<MonetaryAmountByCurrencySet, WithdrawalMinMap>;

const WithdrawalInfoMaps& get(std::string_view exchangeName) { return _withdrawalFeesCache.get(exchangeName); }
const WithdrawalInfoMaps& get(ExchangeNameEnum exchangeNameEnum) {
return _withdrawalFeesCache.get(exchangeNameEnum);
}

void updateCacheFile() const override;

Expand All @@ -35,18 +38,18 @@ class WithdrawalFeesCrawler : public CacheFileUpdatorInterface {
public:
explicit WithdrawalFeesFunc(const CoincenterInfo& coincenterInfo);

WithdrawalInfoMaps operator()(std::string_view exchangeName);
WithdrawalInfoMaps operator()(ExchangeNameEnum exchangeNameEnum);

private:
WithdrawalInfoMaps get1(std::string_view exchangeName);
WithdrawalInfoMaps get2(std::string_view exchangeName);
WithdrawalInfoMaps get1(ExchangeNameEnum exchangeNameEnum);
WithdrawalInfoMaps get2(ExchangeNameEnum exchangeNameEnum);

CurlHandle _curlHandle1;
CurlHandle _curlHandle2;
};

const CoincenterInfo& _coincenterInfo;
CachedResult<WithdrawalFeesFunc, std::string_view> _withdrawalFeesCache;
CachedResult<WithdrawalFeesFunc, ExchangeNameEnum> _withdrawalFeesCache;
};

} // namespace cct
38 changes: 17 additions & 21 deletions src/api/common/src/commonapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,33 @@ CurrencyCodeSet CommonAPI::queryFiats() {

bool CommonAPI::queryIsCurrencyCodeFiat(CurrencyCode currencyCode) { return queryFiats().contains(currencyCode); }

MonetaryAmountByCurrencySet CommonAPI::tryQueryWithdrawalFees(std::string_view exchangeName) {
MonetaryAmountByCurrencySet CommonAPI::tryQueryWithdrawalFees(ExchangeNameEnum exchangeNameEnum) {
MonetaryAmountByCurrencySet ret;
{
std::lock_guard<std::recursive_mutex> guard(_globalMutex);
ret = _withdrawalFeesCrawler.get(exchangeName).first;
ret = _withdrawalFeesCrawler.get(exchangeNameEnum).first;
}

if (ret.empty()) {
log::warn("Taking binance withdrawal fees for {} as crawler failed to retrieve data", exchangeName);
log::warn("Taking binance withdrawal fees for {} as crawler failed to retrieve data",
kSupportedExchanges[static_cast<int>(exchangeNameEnum)]);
ret = _binanceGlobalInfos.queryWithdrawalFees();
}
return ret;
}

std::optional<MonetaryAmount> CommonAPI::tryQueryWithdrawalFee(std::string_view exchangeName,
std::optional<MonetaryAmount> CommonAPI::tryQueryWithdrawalFee(ExchangeNameEnum exchangeNameEnum,
CurrencyCode currencyCode) {
{
std::lock_guard<std::recursive_mutex> guard(_globalMutex);
const auto& withdrawalFees = _withdrawalFeesCrawler.get(exchangeName).first;
const auto& withdrawalFees = _withdrawalFeesCrawler.get(exchangeNameEnum).first;
auto it = withdrawalFees.find(currencyCode);
if (it != withdrawalFees.end()) {
return *it;
}
}
log::warn("Taking binance withdrawal fee for {} and currency {} as crawler failed to retrieve data", exchangeName,
currencyCode);
log::warn("Taking binance withdrawal fee for {} and currency {} as crawler failed to retrieve data",
kSupportedExchanges[static_cast<int>(exchangeNameEnum)], currencyCode);
MonetaryAmount withdrawFee = _binanceGlobalInfos.queryWithdrawalFee(currencyCode);
if (withdrawFee.isDefault()) {
return {};
Expand Down Expand Up @@ -213,24 +214,19 @@ CurrencyCodeVector CommonAPI::FiatsFunc::retrieveFiatsSource2() {

void CommonAPI::updateCacheFile() const {
const auto fiatsCacheFile = GetFiatCacheFile(_coincenterInfo.dataDir());
auto fiatsData = fiatsCacheFile.readAllJson();
auto fiatsDataStr = fiatsCacheFile.readAll();
schema::FiatsCache fiatsData;
ReadExactJsonOrThrow(fiatsDataStr, fiatsData);
const auto fiatsPtrLastUpdatedTimePair = _fiatsCache.retrieve();
const auto timeEpochIt = fiatsData.find("timeepoch");
bool updateFiatsCache = true;
if (timeEpochIt != fiatsData.end()) {
const int64_t lastTimeFileUpdated = timeEpochIt->get<int64_t>();
if (TimePoint(seconds(lastTimeFileUpdated)) >= fiatsPtrLastUpdatedTimePair.second) {
updateFiatsCache = false;
}
}
if (updateFiatsCache) {
fiatsData.clear();
if (TimePoint(seconds(fiatsData.timeepoch)) < fiatsPtrLastUpdatedTimePair.second) {
// update fiats cache file
fiatsData.fiats.clear();
if (fiatsPtrLastUpdatedTimePair.first != nullptr) {
for (CurrencyCode fiatCode : *fiatsPtrLastUpdatedTimePair.first) {
fiatsData["fiats"].emplace_back(fiatCode.str());
fiatsData.fiats.emplace_back(fiatCode.str());
}
fiatsData["timeepoch"] = TimestampToSecondsSinceEpoch(fiatsPtrLastUpdatedTimePair.second);
fiatsCacheFile.writeJson(fiatsData);
fiatsData.timeepoch = TimestampToSecondsSinceEpoch(fiatsPtrLastUpdatedTimePair.second);
fiatsCacheFile.write(WriteMiniJsonOrThrow(fiatsData));
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/api/common/src/withdrawal-fees-schema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cstdint>
#include <unordered_map>

#include "cct_const.hpp"
#include "cct_string.hpp"
#include "cct_vector.hpp"
#include "currencycode.hpp"
Expand All @@ -20,7 +21,7 @@ struct WithdrawInfoFileItem {
std::unordered_map<CurrencyCode, WithdrawInfoFileItemAsset> assets;
};

using WithdrawInfoFile = std::unordered_map<string, WithdrawInfoFileItem>;
using WithdrawInfoFile = std::unordered_map<ExchangeNameEnum, WithdrawInfoFileItem>;

struct WithdrawFeesCrawlerExchangeFeesCoinSource1 {
string symbol;
Expand Down
38 changes: 18 additions & 20 deletions src/api/common/src/withdrawalfees-crawler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ WithdrawalFeesCrawler::WithdrawalFeesCrawler(const CoincenterInfo& coincenterInf
ReadExactJsonOrThrow(data, withdrawInfoFileContent);

const auto nowTime = Clock::now();
for (const auto& [exchangeName, exchangeData] : withdrawInfoFileContent) {
for (const auto& [exchangeNameEnum, exchangeData] : withdrawInfoFileContent) {
TimePoint lastUpdatedTime(seconds(exchangeData.timeepoch));
if (nowTime - lastUpdatedTime < minDurationBetweenQueries) {
// we can reuse file data
WithdrawalInfoMaps withdrawalInfoMaps;

std::string_view exchangeName = kSupportedExchanges[static_cast<int>(exchangeNameEnum)];

for (const auto& [cur, val] : exchangeData.assets) {
MonetaryAmount withdrawMin(val.min, cur);
MonetaryAmount withdrawFee(val.fee, cur);
Expand All @@ -66,15 +68,7 @@ WithdrawalFeesCrawler::WithdrawalFeesCrawler(const CoincenterInfo& coincenterInf
withdrawalInfoMaps.second.insert_or_assign(cur, withdrawMin);
}

// Warning: we store a std::string_view in the cache, and 'exchangeName' will be destroyed at the end
// of this function. So we need to retrieve the 'constant' std::string_view of this exchange (in static memory)
// to store in the cache.
auto constantExchangeNameSVIt = std::ranges::find(kSupportedExchanges, exchangeName);
if (constantExchangeNameSVIt == std::end(kSupportedExchanges)) {
throw exception("unknown exchange name {}", exchangeName);
}

_withdrawalFeesCache.set(std::move(withdrawalInfoMaps), lastUpdatedTime, *constantExchangeNameSVIt);
_withdrawalFeesCache.set(std::move(withdrawalInfoMaps), lastUpdatedTime, exchangeNameEnum);
}
}
}
Expand All @@ -92,14 +86,15 @@ WithdrawalFeesCrawler::WithdrawalFeesFunc::WithdrawalFeesFunc(const CoincenterIn
coincenterInfo.getRunMode()) {}

WithdrawalFeesCrawler::WithdrawalInfoMaps WithdrawalFeesCrawler::WithdrawalFeesFunc::operator()(
std::string_view exchangeName) {
ExchangeNameEnum exchangeNameEnum) {
static constexpr auto kNbSources = 2;

ThreadPool threadPool(kNbSources);

std::array results{
threadPool.enqueue([this](std::string_view exchangeName) { return get1(exchangeName); }, exchangeName),
threadPool.enqueue([this](std::string_view exchangeName) { return get2(exchangeName); }, exchangeName)};
std::array results{threadPool.enqueue([this](ExchangeNameEnum exchangeNameEnum) { return get1(exchangeNameEnum); },
exchangeNameEnum),
threadPool.enqueue([this](ExchangeNameEnum exchangeNameEnum) { return get2(exchangeNameEnum); },
exchangeNameEnum)};

auto [withdrawFees1, withdrawMinMap1] = results[0].get();

Expand All @@ -111,21 +106,22 @@ WithdrawalFeesCrawler::WithdrawalInfoMaps WithdrawalFeesCrawler::WithdrawalFeesF
}

if (withdrawFees1.empty() || withdrawMinMap1.empty()) {
log::error("Unable to parse {} withdrawal fees", exchangeName);
log::error("Unable to parse {} withdrawal fees", kSupportedExchanges[static_cast<int>(exchangeNameEnum)]);
}

return std::make_pair(std::move(withdrawFees1), std::move(withdrawMinMap1));
}

void WithdrawalFeesCrawler::updateCacheFile() const {
schema::WithdrawInfoFile withdrawInfoFile;
for (const std::string_view exchangeName : kSupportedExchanges) {
const auto [withdrawalInfoMapsPtr, latestUpdate] = _withdrawalFeesCache.retrieve(exchangeName);
for (int exchangeNamePos = 0; exchangeNamePos < kNbSupportedExchanges; ++exchangeNamePos) {
auto exchangeNameEnum = static_cast<ExchangeNameEnum>(exchangeNamePos);
const auto [withdrawalInfoMapsPtr, latestUpdate] = _withdrawalFeesCache.retrieve(exchangeNameEnum);
if (withdrawalInfoMapsPtr != nullptr) {
const WithdrawalInfoMaps& withdrawalInfoMaps = *withdrawalInfoMapsPtr;

schema::WithdrawInfoFileItem& withdrawInfoFileItem =
withdrawInfoFile.emplace(std::make_pair(exchangeName, schema::WithdrawInfoFileItem{})).first->second;
withdrawInfoFile.emplace(std::make_pair(exchangeNameEnum, schema::WithdrawInfoFileItem{})).first->second;
withdrawInfoFileItem.timeepoch = TimestampToSecondsSinceEpoch(latestUpdate);
for (const auto withdrawFee : withdrawalInfoMaps.first) {
CurrencyCode cur = withdrawFee.currencyCode();
Expand All @@ -146,7 +142,8 @@ void WithdrawalFeesCrawler::updateCacheFile() const {
}

WithdrawalFeesCrawler::WithdrawalInfoMaps WithdrawalFeesCrawler::WithdrawalFeesFunc::get1(
std::string_view exchangeName) {
ExchangeNameEnum exchangeNameEnum) {
std::string_view exchangeName = kSupportedExchanges[static_cast<int>(exchangeNameEnum)];
string path(exchangeName);
path.append(".json");
std::string_view dataStr = _curlHandle1.query(path, CurlOptions(HttpRequestType::kGet));
Expand Down Expand Up @@ -188,7 +185,8 @@ WithdrawalFeesCrawler::WithdrawalInfoMaps WithdrawalFeesCrawler::WithdrawalFeesF
}

WithdrawalFeesCrawler::WithdrawalInfoMaps WithdrawalFeesCrawler::WithdrawalFeesFunc::get2(
std::string_view exchangeName) {
ExchangeNameEnum exchangeNameEnum) {
std::string_view exchangeName = kSupportedExchanges[static_cast<int>(exchangeNameEnum)];
std::string_view withdrawalFeesCsv = _curlHandle2.query(exchangeName, CurlOptions(HttpRequestType::kGet));

static constexpr std::string_view kBeginTableTitle = "Deposit & Withdrawal fees</h2>";
Expand Down
5 changes: 3 additions & 2 deletions src/api/common/test/withdrawalfees-crawler_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class WithdrawalFeesCrawlerTest : public ::testing::Test {
};

TEST_F(WithdrawalFeesCrawlerTest, WithdrawalFeesCrawlerService) {
for (const std::string_view exchangeName : kSupportedExchanges) {
const auto [amountByCurrencySet, withdrawalMinMap] = withdrawalFeesCrawler.get(exchangeName);
for (int exchangeNamePos = 0; exchangeNamePos < kNbSupportedExchanges; ++exchangeNamePos) {
const auto [amountByCurrencySet, withdrawalMinMap] =
withdrawalFeesCrawler.get(static_cast<ExchangeNameEnum>(exchangeNamePos));

if (!withdrawalMinMap.empty()) {
return;
Expand Down
23 changes: 14 additions & 9 deletions src/api/exchanges/include/bithumbprivateapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,19 @@ class BithumbPrivate : public ExchangePrivate {
void cancelOrderProcess(OrderIdView orderId, const TradeContext& tradeContext);

struct CurrencyOrderInfo {
int8_t nbDecimals{};
TimePoint lastNbDecimalsUpdatedTime;
MonetaryAmount minOrderSize;
TimePoint lastMinOrderSizeUpdatedTime;
MonetaryAmount minOrderPrice;
TimePoint lastMinOrderPriceUpdatedTime;
MonetaryAmount maxOrderPrice;
TimePoint lastMaxOrderPriceUpdatedTime;
struct MonetaryAmountWithTs {
int64_t ts;
MonetaryAmount val;
};
struct DecimalsWithTs {
int64_t ts;
int8_t val;
};

DecimalsWithTs nbDecimals;
MonetaryAmountWithTs minOrderSize;
MonetaryAmountWithTs minOrderPrice;
MonetaryAmountWithTs maxOrderPrice;
};

using CurrencyOrderInfoMap = std::unordered_map<CurrencyCode, CurrencyOrderInfo>;
Expand All @@ -88,4 +93,4 @@ class BithumbPrivate : public ExchangePrivate {
CachedResult<DepositWalletFunc, CurrencyCode> _depositWalletsCache;
};
} // namespace api
} // namespace cct
} // namespace cct
4 changes: 3 additions & 1 deletion src/api/exchanges/include/bithumbpublicapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class BithumbPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get()); }

MonetaryAmountByCurrencySet queryWithdrawalFees() override { return _commonApi.tryQueryWithdrawalFees(name()); }
MonetaryAmountByCurrencySet queryWithdrawalFees() override {
return _commonApi.tryQueryWithdrawalFees(exchangeNameEnum());
}

std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

Expand Down
4 changes: 1 addition & 3 deletions src/api/exchanges/include/krakenpublicapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ class CommonAPI;

class KrakenPublic : public ExchangePublic {
public:
static constexpr std::string_view kExchangeName = "kraken";

KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI);

bool healthCheck() override;
Expand All @@ -38,7 +36,7 @@ class KrakenPublic : public ExchangePublic {
MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

MonetaryAmountByCurrencySet queryWithdrawalFees() override {
return _commonApi.tryQueryWithdrawalFees(kExchangeName);
return _commonApi.tryQueryWithdrawalFees(exchangeNameEnum());
}

std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;
Expand Down
Loading

0 comments on commit c124e10

Please sign in to comment.