Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up code around fiat converter #480

Merged
merged 1 commit into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/api/common/include/fiatconverter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <mutex>
#include <unordered_map>

#include "cachedresult.hpp"
#include "cct_string.hpp"
#include "curlhandle.hpp"
#include "currencycode.hpp"
Expand Down
16 changes: 6 additions & 10 deletions src/api/common/src/fiatconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ string LoadCurrencyConverterAPIKey(std::string_view dataDir) {
static constexpr std::string_view kThirdPartySecretFileName = "thirdparty_secret.json";
File thirdPartySecret(dataDir, File::Type::kSecret, kThirdPartySecretFileName, File::IfError::kNoThrow);
json data = thirdPartySecret.readAllJson();
if (data.empty() || data["freecurrencyconverter"].get<std::string_view>() == kDefaultCommunityKey) {
auto freeConverterIt = data.find("freecurrencyconverter");
if (freeConverterIt == data.end() || freeConverterIt->get<std::string_view>() == kDefaultCommunityKey) {
log::warn("Unable to find custom Free Currency Converter key in {}", kThirdPartySecretFileName);
log::warn("If you want to use extensively coincenter, please create your own key by going to");
log::warn("https://free.currencyconverterapi.com/free-api-key and place it in");
Expand All @@ -36,7 +37,7 @@ string LoadCurrencyConverterAPIKey(std::string_view dataDir) {
log::warn("Using default key provided as a demo to the community");
return string(kDefaultCommunityKey);
}
return data["freecurrencyconverter"];
return std::move(freeConverterIt->get_ref<string&>());
}

constexpr std::string_view kRatesCacheFile = "ratescache.json";
Expand All @@ -45,7 +46,7 @@ File GetRatesCacheFile(std::string_view dataDir) {
return {dataDir, File::Type::kCache, kRatesCacheFile, File::IfError::kNoThrow};
}

constexpr std::string_view kFiatConverterBaseUrl = "https://free.currconv.com/api";
constexpr std::string_view kFiatConverterBaseUrl = "https://free.currconv.com";
} // namespace

FiatConverter::FiatConverter(const CoincenterInfo& coincenterInfo, Duration ratesUpdateFrequency)
Expand Down Expand Up @@ -79,17 +80,12 @@ void FiatConverter::updateCacheFile() const {
std::optional<double> FiatConverter::queryCurrencyRate(Market mk) {
string qStr(mk.assetsPairStrUpper('_'));
CurlOptions opts(HttpRequestType::kGet, {{"q", qStr}, {"apiKey", _apiKey}});

string method = "/v7/convert?";
method.append(opts.getPostData().str());
opts.getPostData().clear();

std::string_view dataStr = _curlHandle.query(method, opts);
std::string_view dataStr = _curlHandle.query("/api/v7/convert", opts);
static constexpr bool kAllowExceptions = false;
json data = json::parse(dataStr, nullptr, kAllowExceptions);
//{"query":{"count":1},"results":{"EUR_KRW":{"id":"EUR_KRW","val":1329.475323,"to":"KRW","fr":"EUR"}}}
if (data == json::value_t::discarded || !data.contains("results") || !data["results"].contains(qStr)) {
log::error("No JSON data received from fiat currency converter service");
log::error("No JSON data received from fiat currency converter service for pair '{}'", mk);
auto it = _pricesMap.find(mk);
if (it != _pricesMap.end()) {
// Update cache time anyway to avoid querying too much the service
Expand Down
66 changes: 32 additions & 34 deletions src/api/common/test/fiatconverter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "cct_json.hpp"
#include "coincenterinfo.hpp"
#include "curlhandle.hpp"
#include "curloptions.hpp"
#include "permanentcurloptions.hpp"
#include "runmodes.hpp"
#include "timedef.hpp"
Expand All @@ -17,7 +18,7 @@ namespace cct {

namespace {
void AreDoubleEqual(double lhs, double rhs) {
static constexpr double kEpsilon = 0.000001;
static constexpr double kEpsilon = 0.00000001;
if (lhs < rhs) {
EXPECT_LT(rhs - lhs, kEpsilon);
} else {
Expand All @@ -39,43 +40,40 @@ CurlHandle::CurlHandle([[maybe_unused]] const BestURLPicker &bestURLPicker,
: _handle(nullptr), _bestUrlPicker(kSomeFakeURL) {}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
std::string_view CurlHandle::query(std::string_view endpoint, [[maybe_unused]] const CurlOptions &opts) {
std::string_view CurlHandle::query([[maybe_unused]] std::string_view endpoint, const CurlOptions &opts) {
json jsonData;
if (endpoint.find("currencies") != std::string_view::npos) {
// Currencies
jsonData["results"] = {"EUR", "USD", "GBP", "KRW"};
} else {
// Rates
std::string_view marketStr(endpoint.begin() + endpoint.find("q=") + 2, endpoint.begin() + endpoint.find("q=") + 9);
std::string_view fromCurrency = marketStr.substr(0, 3);
std::string_view targetCurrency = marketStr.substr(4);
double rate = 0;
if (fromCurrency == "EUR") {
if (targetCurrency == "KRW") {
rate = kKRW;
} else if (targetCurrency == "USD") {
rate = kUSD;
} else if (targetCurrency == "GBP") {
rate = kGBP;
}
} else if (fromCurrency == "KRW") {
if (targetCurrency == "EUR") {
rate = 1 / kKRW;
} else if (targetCurrency == "USD") {
rate = kUSD / kKRW;
} else if (targetCurrency == "GBP") {
rate = kGBP / kKRW;
}
} else if (fromCurrency == "GBP") {
if (targetCurrency == "USD") {
rate = kUSD / kGBP;
}
}

if (rate != 0) {
jsonData["results"][marketStr]["val"] = rate;
// Rates
std::string_view marketStr = opts.getPostData().get("q");
std::string_view fromCurrency = marketStr.substr(0, 3);
std::string_view targetCurrency = marketStr.substr(4);
double rate = 0;
if (fromCurrency == "EUR") {
if (targetCurrency == "KRW") {
rate = kKRW;
} else if (targetCurrency == "USD") {
rate = kUSD;
} else if (targetCurrency == "GBP") {
rate = kGBP;
}
} else if (fromCurrency == "KRW") {
if (targetCurrency == "EUR") {
rate = 1 / kKRW;
} else if (targetCurrency == "USD") {
rate = kUSD / kKRW;
} else if (targetCurrency == "GBP") {
rate = kGBP / kKRW;
}
} else if (fromCurrency == "GBP") {
if (targetCurrency == "USD") {
rate = kUSD / kGBP;
}
}

if (rate != 0) {
jsonData["results"][marketStr]["val"] = rate;
}

_queryData = jsonData.dump();
return _queryData;
}
Expand Down
20 changes: 10 additions & 10 deletions src/engine/include/staticcommandlineoptioncheck.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <algorithm>
#include <array>
#include <cstddef>
#include <numeric>
#include <string_view>

#include "commandlineoption.hpp"

Expand All @@ -12,7 +12,7 @@ namespace cct {
/// Compile time checker of arguments. Currently, the following checks are made:
/// - Uniqueness of short hand flags
/// - Uniqueness of long names
template <class T, size_t... N>
template <class T, std::size_t... N>
consteval bool StaticCommandLineOptionsDuplicatesCheck(std::array<T, N>... ar) {
auto all = ComputeAllCommandLineOptions(ar...);

Expand Down Expand Up @@ -42,7 +42,7 @@ consteval bool StaticCommandLineOptionsDuplicatesCheck(std::array<T, N>... ar) {
/// Compile time checker of descriptions. Following checks are made:
/// - Should not start nor end with a '\n'
/// - Should not start no end with a space
template <class T, size_t... N>
template <class T, std::size_t... N>
consteval bool StaticCommandLineOptionsDescriptionCheck(std::array<T, N>... ar) {
const auto all = ComputeAllCommandLineOptions(ar...);
const auto isSpaceOrNewLine = [](char ch) { return ch == '\n' || ch == ' '; };
Expand All @@ -60,20 +60,20 @@ consteval bool StaticCommandLineOptionsDescriptionCheck(std::array<T, N>... ar)
return true;
}

template <class T, size_t... N>
template <class T, std::size_t... N>
consteval auto ComputeAllCommandLineOptions(std::array<T, N>... ar) {
constexpr size_t kNbArrays = sizeof...(ar);
constexpr std::size_t kNbArrays = sizeof...(ar);

const T* arr[kNbArrays] = {&ar[0]...};
constexpr size_t lengths[kNbArrays] = {ar.size()...};
constexpr std::size_t lengths[kNbArrays] = {ar.size()...};

constexpr size_t kSumLen = std::accumulate(lengths, lengths + kNbArrays, 0);
constexpr std::size_t kSumLen = std::accumulate(lengths, lengths + kNbArrays, 0);

std::array<CommandLineOption, kSumLen> all;

size_t allIdx = 0;
for (size_t dataIdx = 0; dataIdx < kNbArrays; ++dataIdx) {
for (size_t lenIdx = 0; lenIdx < lengths[dataIdx]; ++lenIdx) {
std::size_t allIdx = 0;
for (std::size_t dataIdx = 0; dataIdx < kNbArrays; ++dataIdx) {
for (std::size_t lenIdx = 0; lenIdx < lengths[dataIdx]; ++lenIdx) {
all[allIdx] = std::get<0>(arr[dataIdx][lenIdx]);
++allIdx;
}
Expand Down
2 changes: 1 addition & 1 deletion src/objects/include/market.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct fmt::formatter<cct::Market> {
namespace std {
template <>
struct hash<cct::Market> {
size_t operator()(const cct::Market& mk) const {
auto operator()(const cct::Market& mk) const {
return cct::HashCombine(hash<cct::CurrencyCode>()(mk.base()), hash<cct::CurrencyCode>()(mk.quote()));
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/objects/include/monetaryamount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class MonetaryAmount {
}

[[nodiscard]] uint64_t code() const noexcept {
return HashCombine(static_cast<size_t>(_amount), static_cast<size_t>(_curWithDecimals.code()));
return HashCombine(static_cast<std::size_t>(_amount), static_cast<std::size_t>(_curWithDecimals.code()));
}

friend std::ostream &operator<<(std::ostream &os, const MonetaryAmount &ma);
Expand Down
1 change: 0 additions & 1 deletion src/tech/include/cct_hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <cstdint>
#include <functional>
#include <tuple>
#include <utility>

namespace cct {
constexpr uint64_t HashValue64(uint64_t h1) {
Expand Down
20 changes: 10 additions & 10 deletions src/tech/include/timedef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ using TimeInMs = std::chrono::milliseconds;
using TimeInUs = std::chrono::microseconds;

template <class T>
T GetTimeDiff(TimePoint t1, TimePoint t2) {
return std::chrono::duration_cast<T>(t2 - t1);
constexpr T GetTimeDiff(TimePoint tp1, TimePoint tp2) {
return std::chrono::duration_cast<T>(tp2 - tp1);
}

template <class T>
T GetTimeFrom(TimePoint t) {
return GetTimeDiff<T>(t, Clock::now());
constexpr T GetTimeFrom(TimePoint tp) {
return GetTimeDiff<T>(tp, Clock::now());
}

constexpr int64_t TimestampToS(TimePoint t) {
return std::chrono::duration_cast<TimeInS>(t.time_since_epoch()).count();
constexpr int64_t TimestampToS(TimePoint tp) {
return std::chrono::duration_cast<TimeInS>(tp.time_since_epoch()).count();
}
constexpr int64_t TimestampToMs(TimePoint t) {
return std::chrono::duration_cast<TimeInMs>(t.time_since_epoch()).count();
constexpr int64_t TimestampToMs(TimePoint tp) {
return std::chrono::duration_cast<TimeInMs>(tp.time_since_epoch()).count();
}
constexpr int64_t TimestampToUs(TimePoint t) {
return std::chrono::duration_cast<TimeInUs>(t.time_since_epoch()).count();
constexpr int64_t TimestampToUs(TimePoint tp) {
return std::chrono::duration_cast<TimeInUs>(tp.time_since_epoch()).count();
}
} // namespace cct
Loading