167 lines
4.3 KiB
C++
167 lines
4.3 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include "json.hpp"
|
|
#include <ttmath/ttmath.h>
|
|
|
|
using json = nlohmann::json;
|
|
|
|
#define NS_BEGIN(n) namespace n {
|
|
|
|
#define NS_END1() }
|
|
#define NS_END2() NS_END1() }
|
|
#define NS_END3() NS_END2() }
|
|
#define NS_END4() NS_END3() }
|
|
#define NS_END5() NS_END4() }
|
|
|
|
#define NS_END(c) NS_END##c()
|
|
|
|
NS_BEGIN(Sia)
|
|
NS_BEGIN(Api)
|
|
|
|
typedef std::wstring String;
|
|
#define DEFAULT_CONFIG_FILE_PATH L".\\Config\\SiaDriveConfig.json"
|
|
|
|
#define Property(type, name, get_access, set_access) \
|
|
private:\
|
|
type _##name;\
|
|
get_access:\
|
|
const type& Get##name() const { return _##name;}\
|
|
set_access:\
|
|
const type& Set##name(const type& value) { _##name = value; return _##name; }
|
|
|
|
#define JProperty(type, name, get_access, set_access, json_doc) \
|
|
get_access:\
|
|
type Get##name() const { return json_doc[#name].get<type>();}\
|
|
set_access:\
|
|
type Set##name(const type& value) { json_doc[#name] = value; return value; }
|
|
|
|
struct SiaHostConfig
|
|
{
|
|
String HostName;
|
|
std::uint16_t HostPort;
|
|
String RequiredVersion;
|
|
};
|
|
|
|
template<typename T>
|
|
inline bool ApiSuccess(const T& t) {
|
|
return t == T::Success;
|
|
}
|
|
|
|
typedef ttmath::UInt<256> Hastings;
|
|
typedef ttmath::Big<1, 30> SiaCurrency;
|
|
/*
|
|
BigNumber.config({ EXPONENTIAL_AT: 1e+9 })
|
|
BigNumber.config({ DECIMAL_PLACES: 30 })
|
|
|
|
const hastingsPerSiacoin = new BigNumber('10').toPower(24)
|
|
const siacoinsToHastings = (siacoins) => new BigNumber(siacoins).times(hastingsPerSiacoin)
|
|
const hastingsToSiacoins = (hastings) => new BigNumber(hastings).dividedBy(hastingsPerSiacoin)
|
|
*/
|
|
inline static SiaCurrency HastingsStringToSiaCurrency(const String& value)
|
|
{
|
|
ttmath::Parser<SiaCurrency> parser;
|
|
parser.Parse(value + L" / (10^24)");
|
|
return parser.stack[0].value;
|
|
}
|
|
|
|
inline static String SiaCurrencyToString(const SiaCurrency& value)
|
|
{
|
|
ttmath::Conv conv;
|
|
conv.base = 10;
|
|
conv.round = 8;
|
|
|
|
return value.ToWString(conv);
|
|
}
|
|
|
|
class IHost
|
|
{
|
|
public:
|
|
IHost() {}
|
|
virtual ~IHost() {}
|
|
|
|
public:
|
|
virtual Hastings GetStoragePrice() const = 0;
|
|
virtual Hastings GetDownloadPrice() const = 0;
|
|
virtual Hastings GetUploadPrice() const = 0;
|
|
};
|
|
|
|
template<typename T, typename R>
|
|
inline static R CalculateAveragePrice(const std::vector<T>& v, std::function<R(const T& t)> PriceGetter)
|
|
{
|
|
R result = v.size() ? std::accumulate(std::next(v.begin()), v.end(), PriceGetter(v[0]), [&](const R& a, const T& b) {
|
|
return a + PriceGetter(b);
|
|
}).Div(v.size()) : 0;
|
|
|
|
return result;
|
|
}
|
|
|
|
inline static Hastings CalculateAverageHostPrice(const std::vector<IHost>& hosts)
|
|
{
|
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetStoragePrice(); });
|
|
}
|
|
|
|
inline static Hastings CalculateAverageDownloadPrice(const std::vector<IHost>& hosts)
|
|
{
|
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetDownloadPrice(); });
|
|
}
|
|
|
|
inline static Hastings CalculateAverageUploadPrice(const std::vector<IHost>& hosts)
|
|
{
|
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetUploadPrice(); });
|
|
}
|
|
|
|
template<typename T>
|
|
static T& ReplaceStringInPlace(T& subject, const T& search, const T& replace)
|
|
{
|
|
size_t pos = 0;
|
|
while ((pos = subject.find(search, pos)) != std::string::npos)
|
|
{
|
|
subject.replace(pos, search.length(), replace);
|
|
pos += replace.length();
|
|
}
|
|
|
|
return subject;
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, const T& replace)
|
|
{
|
|
return ReplaceStringInPlace(subject, T(search), replace);
|
|
}
|
|
|
|
template<typename T>
|
|
inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, typename T::value_type* replace)
|
|
{
|
|
return ReplaceStringInPlace(subject, T(search), T(replace));
|
|
}
|
|
|
|
static BOOL RetryAction(std::function<BOOL()> func, std::uint16_t retryCount, const DWORD& retryDelay)
|
|
{
|
|
BOOL ret = FALSE;
|
|
while (retryCount-- && !((ret = func())))
|
|
{
|
|
::Sleep(retryDelay);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#define RetryableAction(exec, count, delayMs) RetryAction([&]()->BOOL{return exec;}, count, delayMs)
|
|
#define DEFAULT_RETRY_COUNT 10
|
|
#define DEFAULT_RETRY_DELAY_MS 1000
|
|
|
|
static BOOL RetryDeleteFileIfExists(const String& filePath)
|
|
{
|
|
BOOL ret = TRUE;
|
|
if (::PathFileExists(filePath.c_str()))
|
|
{
|
|
ret = RetryableAction(::DeleteFile(filePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
String AFX_EXT_API GenerateSha256(const String& str);
|
|
NS_END(2) |