Refactoring and added common utils
This commit is contained in:
@@ -3,3 +3,34 @@
|
|||||||
#include <ttmath/ttmath.h>
|
#include <ttmath/ttmath.h>
|
||||||
|
|
||||||
using namespace Sia::Api;
|
using namespace Sia::Api;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// avgHostMetric computes the average of the metric given by `metric` on the
|
||||||
|
// list of `hosts`.
|
||||||
|
const avgHostMetric = (hosts, metric) = >
|
||||||
|
hosts.reduce((sum, host) = > sum.add(host[metric]), new BigNumber(0))
|
||||||
|
.dividedBy(hosts.size)
|
||||||
|
|
||||||
|
// avgStorageCost returns the average storage cost from a list of hosts given a
|
||||||
|
// period (blocks) and redundancy.
|
||||||
|
const avgStorageCost = (hosts, period, redundancy) = >
|
||||||
|
avgHostMetric(hosts, 'storageprice')
|
||||||
|
.times(period)
|
||||||
|
.plus(avgHostMetric(hosts, 'uploadbandwidthprice'))
|
||||||
|
.times(redundancy)
|
||||||
|
.plus(avgHostMetric(hosts, 'downloadbandwidthprice'))
|
||||||
|
|
||||||
|
// Compute an estimated amount of storage from an amount of funds (Hastings)
|
||||||
|
// and a list of hosts.
|
||||||
|
export const estimatedStorage = (funds, hosts) = > {
|
||||||
|
const validHosts = List(hosts).take(28)
|
||||||
|
const avgStorage = avgStorageCost(validHosts, allowancePeriod, baseRedundancy)
|
||||||
|
|
||||||
|
let fee = SiaAPI.siacoinsToHastings(baseFee)
|
||||||
|
fee = fee.plus(avgHostMetric(validHosts, 'contractprice').times(ncontracts))
|
||||||
|
fee = fee.plus(funds.minus(fee).times(siafundRate))
|
||||||
|
|
||||||
|
return '~' + readableFilesize(Math.max(0, funds.minus(fee).dividedBy(avgStorage).toNumber().toPrecision(1)))
|
||||||
|
}
|
||||||
|
*/
|
@@ -20,7 +20,8 @@ using json = nlohmann::json;
|
|||||||
NS_BEGIN(Sia)
|
NS_BEGIN(Sia)
|
||||||
NS_BEGIN(Api)
|
NS_BEGIN(Api)
|
||||||
|
|
||||||
#define String std::wstring
|
typedef std::wstring String;
|
||||||
|
#define DEFAULT_CONFIG_FILE_PATH L".\\Config\\SiaDriveConfig.json"
|
||||||
|
|
||||||
#define Property(type, name, get_access, set_access) \
|
#define Property(type, name, get_access, set_access) \
|
||||||
private:\
|
private:\
|
||||||
@@ -43,10 +44,12 @@ struct SiaHostConfig
|
|||||||
String RequiredVersion;
|
String RequiredVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define API_SUCCESS(t, x) (x == t::Success)
|
template<typename T>
|
||||||
|
inline bool ApiSuccess(const T& t) {
|
||||||
#define DEFAULT_CONFIG_FILE_PATH L".\\Config\\SiaDriveConfig.json"
|
return t == T::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef ttmath::UInt<256> Hastings;
|
||||||
typedef ttmath::Big<1, 30> SiaCurrency;
|
typedef ttmath::Big<1, 30> SiaCurrency;
|
||||||
/*
|
/*
|
||||||
BigNumber.config({ EXPONENTIAL_AT: 1e+9 })
|
BigNumber.config({ EXPONENTIAL_AT: 1e+9 })
|
||||||
@@ -72,4 +75,41 @@ static inline String SiaCurrencyToString(const SiaCurrency& value)
|
|||||||
return value.ToWString(conv);
|
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>
|
||||||
|
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 Hastings CalculateAverageHostPrice(const std::vector<IHost>& hosts)
|
||||||
|
{
|
||||||
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetStoragePrice(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Hastings CalculateAverageDownloadPrice(const std::vector<IHost>& hosts)
|
||||||
|
{
|
||||||
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetDownloadPrice(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Hastings CalculateAverageUploadPrice(const std::vector<IHost>& hosts)
|
||||||
|
{
|
||||||
|
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetUploadPrice(); });
|
||||||
|
}
|
||||||
|
|
||||||
NS_END(2)
|
NS_END(2)
|
@@ -24,7 +24,7 @@ void CSiaApi::_CSiaConsensus::StartRefreshThread()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
json result;
|
json result;
|
||||||
if (API_SUCCESS(SiaCurlError, _siaCurl.Get(L"/consensus", result)))
|
if (ApiSuccess(_siaCurl.Get(L"/consensus", result)))
|
||||||
{
|
{
|
||||||
SetHeight(result["height"].get<std::uint64_t>());
|
SetHeight(result["height"].get<std::uint64_t>());
|
||||||
SetSynced(result["synced"].get<bool>());
|
SetSynced(result["synced"].get<bool>());
|
||||||
|
@@ -62,7 +62,7 @@ SiaCurlError CSiaCurl::ProcessResponse(const int& res, const std::string& result
|
|||||||
if (res == CURLE_OK)
|
if (res == CURLE_OK)
|
||||||
{
|
{
|
||||||
ret = CheckHttpError(result);
|
ret = CheckHttpError(result);
|
||||||
if (API_SUCCESS(SiaCurlError, ret))
|
if (ApiSuccess(ret))
|
||||||
{
|
{
|
||||||
ret = (result.length() ? CheckApiError((response = json::parse(result.c_str()))) : SiaCurlError::Success);
|
ret = (result.length() ? CheckApiError((response = json::parse(result.c_str()))) : SiaCurlError::Success);
|
||||||
}
|
}
|
||||||
@@ -114,13 +114,13 @@ bool CSiaCurl::CheckVersion(SiaCurlError& error) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return API_SUCCESS(SiaCurlError, error);
|
return ApiSuccess(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
String CSiaCurl::GetServerVersion() const
|
String CSiaCurl::GetServerVersion() const
|
||||||
{
|
{
|
||||||
json response;
|
json response;
|
||||||
if (API_SUCCESS(SiaCurlError, _Get(L"/daemon/version", response)))
|
if (ApiSuccess(_Get(L"/daemon/version", response)))
|
||||||
{
|
{
|
||||||
return String(CA2W(response["version"].get<std::string>().c_str()));
|
return String(CA2W(response["version"].get<std::string>().c_str()));
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ SiaApiError CSiaApi::_CSiaRenter::FileExists(const String& siaPath, bool& exists
|
|||||||
{
|
{
|
||||||
CSiaFileTreePtr siaFileTree;
|
CSiaFileTreePtr siaFileTree;
|
||||||
SiaApiError ret = GetFileTree(siaFileTree);
|
SiaApiError ret = GetFileTree(siaFileTree);
|
||||||
if (API_SUCCESS(SiaApiError, ret))
|
if (ApiSuccess(ret))
|
||||||
{
|
{
|
||||||
exists = siaFileTree->FileExists(siaPath);
|
exists = siaFileTree->FileExists(siaPath);
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ SiaApiError CSiaApi::_CSiaRenter::GetFileTree(CSiaFileTreePtr& siaFileTree) cons
|
|||||||
SiaApiError ret = SiaApiError::RequestError;
|
SiaApiError ret = SiaApiError::RequestError;
|
||||||
siaFileTree.reset(new CSiaFileTree(_siaCurl));
|
siaFileTree.reset(new CSiaFileTree(_siaCurl));
|
||||||
json result;
|
json result;
|
||||||
if (API_SUCCESS(SiaCurlError, _siaCurl.Get(L"/renter/files", result)))
|
if (ApiSuccess(_siaCurl.Get(L"/renter/files", result)))
|
||||||
{
|
{
|
||||||
siaFileTree->BuildTree(result);
|
siaFileTree->BuildTree(result);
|
||||||
ret = SiaApiError::Success;
|
ret = SiaApiError::Success;
|
||||||
|
@@ -38,7 +38,7 @@ bool CSiaApi::_CSiaWallet::Refresh()
|
|||||||
{
|
{
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError error = _siaCurl.Get(L"/wallet", result);
|
SiaCurlError error = _siaCurl.Get(L"/wallet", result);
|
||||||
if (API_SUCCESS(SiaCurlError, error))
|
if (ApiSuccess(error))
|
||||||
{
|
{
|
||||||
SetCreated(result["encrypted"].get<bool>());
|
SetCreated(result["encrypted"].get<bool>());
|
||||||
SetLocked(!result["unlocked"].get<bool>());
|
SetLocked(!result["unlocked"].get<bool>());
|
||||||
@@ -60,7 +60,7 @@ SiaApiError CSiaApi::_CSiaWallet::Create(const SiaSeedLanguage& seedLanguage, St
|
|||||||
error = SiaApiError::RequestError;
|
error = SiaApiError::RequestError;
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Post(L"/wallet/init", { {L"dictionary", SeedLangToString(seedLanguage)} }, result);
|
SiaCurlError cerror = _siaCurl.Post(L"/wallet/init", { {L"dictionary", SeedLangToString(seedLanguage)} }, result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
error = SiaApiError::Success;
|
error = SiaApiError::Success;
|
||||||
seed = CA2W(result["primaryseed"].get<std::string>().c_str());
|
seed = CA2W(result["primaryseed"].get<std::string>().c_str());
|
||||||
@@ -82,13 +82,13 @@ SiaApiError CSiaApi::_CSiaWallet::Restore(const String& seed)
|
|||||||
SiaApiError CSiaApi::_CSiaWallet::Lock()
|
SiaApiError CSiaApi::_CSiaWallet::Lock()
|
||||||
{
|
{
|
||||||
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::WalletLocked : SiaApiError::Success) : SiaApiError::WalletNotCreated;
|
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::WalletLocked : SiaApiError::Success) : SiaApiError::WalletNotCreated;
|
||||||
if (API_SUCCESS(SiaApiError, error))
|
if (ApiSuccess(error))
|
||||||
{
|
{
|
||||||
error = SiaApiError::RequestError;
|
error = SiaApiError::RequestError;
|
||||||
|
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Post(L"/wallet/lock", {}, result);
|
SiaCurlError cerror = _siaCurl.Post(L"/wallet/lock", {}, result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
error = SiaApiError::Success;
|
error = SiaApiError::Success;
|
||||||
@@ -101,13 +101,13 @@ SiaApiError CSiaApi::_CSiaWallet::Lock()
|
|||||||
SiaApiError CSiaApi::_CSiaWallet::Unlock(const String& password)
|
SiaApiError CSiaApi::_CSiaWallet::Unlock(const String& password)
|
||||||
{
|
{
|
||||||
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::Success : SiaApiError::WalletUnlocked) : SiaApiError::WalletNotCreated;
|
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::Success : SiaApiError::WalletUnlocked) : SiaApiError::WalletNotCreated;
|
||||||
if (API_SUCCESS(SiaApiError, error))
|
if (ApiSuccess(error))
|
||||||
{
|
{
|
||||||
error = SiaApiError::RequestError;
|
error = SiaApiError::RequestError;
|
||||||
|
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Post(L"/wallet/unlock", { {L"encryptionpassword", password} }, result);
|
SiaCurlError cerror = _siaCurl.Post(L"/wallet/unlock", { {L"encryptionpassword", password} }, result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
error = SiaApiError::Success;
|
error = SiaApiError::Success;
|
||||||
@@ -135,7 +135,7 @@ SiaApiError CSiaApi::_CSiaWallet::GetConfirmedBalance(SiaCurrency& balance) cons
|
|||||||
|
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Get(L"/wallet", result);
|
SiaCurlError cerror = _siaCurl.Get(L"/wallet", result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
balance = HastingsStringToSiaCurrency(String(CA2W(result["confirmedsiacoinbalance"].get<std::string>().c_str())));
|
balance = HastingsStringToSiaCurrency(String(CA2W(result["confirmedsiacoinbalance"].get<std::string>().c_str())));
|
||||||
ret = SiaApiError::Success;
|
ret = SiaApiError::Success;
|
||||||
@@ -151,7 +151,7 @@ SiaApiError CSiaApi::_CSiaWallet::GetUnonfirmedBalance(SiaCurrency& balance) con
|
|||||||
|
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Get(L"/wallet", result);
|
SiaCurlError cerror = _siaCurl.Get(L"/wallet", result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
balance = HastingsStringToSiaCurrency(String(CA2W(result["unconfirmedincomingsiacoins"].get<std::string>().c_str())));
|
balance = HastingsStringToSiaCurrency(String(CA2W(result["unconfirmedincomingsiacoins"].get<std::string>().c_str())));
|
||||||
ret = SiaApiError::Success;
|
ret = SiaApiError::Success;
|
||||||
@@ -167,7 +167,7 @@ SiaApiError CSiaApi::_CSiaWallet::GetAddress(String& address) const
|
|||||||
|
|
||||||
json result;
|
json result;
|
||||||
SiaCurlError cerror = _siaCurl.Get(L"/wallet/address", result);
|
SiaCurlError cerror = _siaCurl.Get(L"/wallet/address", result);
|
||||||
if (API_SUCCESS(SiaCurlError, cerror))
|
if (ApiSuccess(cerror))
|
||||||
{
|
{
|
||||||
address = CA2W(result["address"].get<std::string>().c_str());
|
address = CA2W(result["address"].get<std::string>().c_str());
|
||||||
ret = SiaApiError::Success;
|
ret = SiaApiError::Success;
|
||||||
|
@@ -42,7 +42,7 @@ private:
|
|||||||
tempPath.resize(MAX_PATH + 1);
|
tempPath.resize(MAX_PATH + 1);
|
||||||
if (GetTempPath(MAX_PATH + 1, &tempPath[0]))
|
if (GetTempPath(MAX_PATH + 1, &tempPath[0]))
|
||||||
{
|
{
|
||||||
ret = API_SUCCESS(SiaApiError, _siaApi->GetRenter()->DownloadFile(siaPath, tempPath));
|
ret = ApiSuccess(_siaApi->GetRenter()->DownloadFile(siaPath, tempPath));
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ private:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool exists;
|
bool exists;
|
||||||
if (API_SUCCESS(SiaApiError, _siaApi->GetRenter()->FileExists(siaPath, exists)))
|
if (ApiSuccess(_siaApi->GetRenter()->FileExists(siaPath, exists)))
|
||||||
{
|
{
|
||||||
// Operations on existing files that are requested to be truncated, overwritten or re-created
|
// Operations on existing files that are requested to be truncated, overwritten or re-created
|
||||||
// will first be deleted and then replaced if, after the file operation is done, the resulting file
|
// will first be deleted and then replaced if, after the file operation is done, the resulting file
|
||||||
@@ -227,7 +227,7 @@ private:
|
|||||||
// If file isn't cached, delete from Sia only
|
// If file isn't cached, delete from Sia only
|
||||||
if (!PathFileExists(cacheFilePath.c_str()) || ::DeleteFile(cacheFilePath.c_str()))
|
if (!PathFileExists(cacheFilePath.c_str()) || ::DeleteFile(cacheFilePath.c_str()))
|
||||||
{
|
{
|
||||||
if (!API_SUCCESS(SiaApiError, _siaApi->GetRenter()->DeleteFile(siaPath)))
|
if (!ApiSuccess(_siaApi->GetRenter()->DeleteFile(siaPath)))
|
||||||
{
|
{
|
||||||
ret = STATUS_INVALID_SERVER_STATE;
|
ret = STATUS_INVALID_SERVER_STATE;
|
||||||
}
|
}
|
||||||
|
@@ -319,7 +319,7 @@ HRESULT CSiaDriveDlg::OnButtonUnlockWallet(IHTMLElement* /*pElement*/)
|
|||||||
SetBodyEnabled(false);
|
SetBodyEnabled(false);
|
||||||
String pwd = GetWalletUnlockPassword();
|
String pwd = GetWalletUnlockPassword();
|
||||||
std::thread th([this, pwd]() {
|
std::thread th([this, pwd]() {
|
||||||
if (API_SUCCESS(SiaApiError, _siaApi.GetWallet()->Unlock(pwd)))
|
if (ApiSuccess(_siaApi.GetWallet()->Unlock(pwd)))
|
||||||
{
|
{
|
||||||
QueueUiAction([this]() {
|
QueueUiAction([this]() {
|
||||||
SetWalletUnlockPassword(L"");
|
SetWalletUnlockPassword(L"");
|
||||||
@@ -501,10 +501,10 @@ bool CSiaDriveDlg::UpdateSiaInfo()
|
|||||||
if (_siaApi.GetWallet()->Refresh())
|
if (_siaApi.GetWallet()->Refresh())
|
||||||
{
|
{
|
||||||
SiaCurrency confirmed;
|
SiaCurrency confirmed;
|
||||||
if (API_SUCCESS(SiaApiError, _siaApi.GetWallet()->GetConfirmedBalance(confirmed)))
|
if (ApiSuccess(_siaApi.GetWallet()->GetConfirmedBalance(confirmed)))
|
||||||
{
|
{
|
||||||
SiaCurrency unconfirmed;
|
SiaCurrency unconfirmed;
|
||||||
if (API_SUCCESS(SiaApiError, _siaApi.GetWallet()->GetUnonfirmedBalance(unconfirmed)))
|
if (ApiSuccess(_siaApi.GetWallet()->GetUnonfirmedBalance(unconfirmed)))
|
||||||
{
|
{
|
||||||
SiaCurrency total = confirmed + unconfirmed;
|
SiaCurrency total = confirmed + unconfirmed;
|
||||||
|
|
||||||
@@ -708,7 +708,7 @@ HRESULT CSiaDriveDlg::OnButtonCreateWallet(IHTMLElement* pElement)
|
|||||||
KillTimer(IDT_UPDATE);
|
KillTimer(IDT_UPDATE);
|
||||||
|
|
||||||
String seed;
|
String seed;
|
||||||
if (API_SUCCESS(SiaApiError, _siaApi.GetWallet()->Create(SiaSeedLanguage::English, seed)))
|
if (ApiSuccess(_siaApi.GetWallet()->Create(SiaSeedLanguage::English, seed)))
|
||||||
{
|
{
|
||||||
DisplaySeedCreated(seed);
|
DisplaySeedCreated(seed);
|
||||||
}
|
}
|
||||||
|
@@ -23,15 +23,15 @@ namespace UnitTests
|
|||||||
Assert::IsTrue(wallet->GetLocked());
|
Assert::IsTrue(wallet->GetLocked());
|
||||||
|
|
||||||
String seed;
|
String seed;
|
||||||
Assert::IsTrue(API_SUCCESS(SiaApiError, wallet->Create(SiaSeedLanguage::English, seed)));
|
Assert::IsTrue(ApiSuccess(wallet->Create(SiaSeedLanguage::English, seed)));
|
||||||
Assert::IsTrue(wallet->GetCreated());
|
Assert::IsTrue(wallet->GetCreated());
|
||||||
Assert::IsTrue(wallet->GetLocked());
|
Assert::IsTrue(wallet->GetLocked());
|
||||||
|
|
||||||
Assert::IsTrue(API_SUCCESS(SiaApiError, wallet->Unlock(seed)));
|
Assert::IsTrue(ApiSuccess(wallet->Unlock(seed)));
|
||||||
Assert::IsTrue(wallet->GetCreated());
|
Assert::IsTrue(wallet->GetCreated());
|
||||||
Assert::IsFalse(wallet->GetLocked());
|
Assert::IsFalse(wallet->GetLocked());
|
||||||
|
|
||||||
Assert::IsTrue(API_SUCCESS(SiaApiError, wallet->Lock( )));
|
Assert::IsTrue(ApiSuccess(wallet->Lock( )));
|
||||||
Assert::IsTrue(wallet->GetCreated());
|
Assert::IsTrue(wallet->GetCreated());
|
||||||
Assert::IsTrue(wallet->GetLocked());
|
Assert::IsTrue(wallet->GetLocked());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user