Verus Coin - this coin was backdoored by it's lead dev and should not be trusted! https://git.hush.is/duke/backdoors/src/branch/master/vrsc.md
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

557 lines
17 KiB

#include "params.h"
#include "ui_interface.h"
std::map<std::string, ParamFile> mapParams;
JsonDownload downloadedJSON;
static const int K_READ_BUF_SIZE{ 1024 * 16 };
std::string CalcSha256(std::string filename)
{
// Initialize openssl
SHA256_CTX context;
if(!SHA256_Init(&context)) {
return "";
}
// Read file and update calculated SHA
char buf[K_READ_BUF_SIZE];
std::ifstream file(filename, std::ifstream::binary);
while (file.good()) {
file.read(buf, sizeof(buf));
if(!SHA256_Update(&context, buf, file.gcount())) {
return "";
}
}
// Get Final SHA
unsigned char result[SHA256_DIGEST_LENGTH];
if(!SHA256_Final(result, &context)) {
return "";
}
// Transform byte-array to string
std::stringstream shastr;
shastr << std::hex << std::setfill('0');
for (const auto &byte: result) {
shastr << std::setw(2) << (int)byte;
}
return shastr.str();
}
bool checkParams() {
bool allVerified = true;
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
std::string uiMessage = "Verifying " + it->second.name + "....";
uiInterface.InitMessage(_(uiMessage.c_str()));
std::string sha256Sum = CalcSha256(it->second.path.string());
LogPrintf("sha256Sum %s\n", sha256Sum);
LogPrintf("checkSum %s\n", it->second.hash);
if (sha256Sum == it->second.hash) {
it->second.verified = true;
} else {
allVerified = false;
}
}
return allVerified;
}
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct CurlProgress *myp = (struct CurlProgress *)p;
CURL *curl = myp->curl;
TIMETYPE curtime = 0;
char *url = NULL;
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
std::map<std::string, ParamFile>::iterator mi = mapParams.find(url);
if (mi != mapParams.end()) {
mi->second.dlnow = dlnow;
mi->second.dltotal = dltotal;
}
return 0;
}
void initalizeMapParamBootstrap() {
mapParams.clear();
ParamFile bootSigFile;
bootSigFile.name = "bootstrap-signature";
bootSigFile.URL = "https://bootstrap.verus.io/VRSC-bootstrap.tar.gz.verusid";
bootSigFile.verified = false;
bootSigFile.path = GetDataDir() / "VRSC-bootstrap.tar.gz.verusid";
bootSigFile.dlnow = 0;
bootSigFile.dltotal = 0;
mapParams[bootSigFile.URL] = bootSigFile;
ParamFile bootFile;
bootFile.name = "bootstrap";
bootFile.URL = "https://bootstrap.verus.io/VRSC-bootstrap.tar.gz";
bootFile.verified = false;
bootFile.path = GetDataDir() / "VRSC-bootstrap.tar.gz";
bootFile.dlnow = 0;
bootFile.dltotal = 0;
mapParams[bootFile.URL] = bootFile;
}
void initalizeMapParam() {
mapParams.clear();
ParamFile pkFile;
pkFile.name = "sprout-proving.key";
pkFile.URL = PK_URL;
pkFile.hash = PK_SHA256;
pkFile.verified = false;
pkFile.path = ZC_GetParamsDir() / "sprout-proving.key";
pkFile.dlnow = 0;
pkFile.dltotal = 0;
mapParams[pkFile.URL] = pkFile;
ParamFile vkFile;
vkFile.name = "sprout-verifying.key";
vkFile.URL = VK_URL;
vkFile.hash = VK_SHA256;
vkFile.verified = false;
vkFile.path = ZC_GetParamsDir() / "sprout-verifying.key";
vkFile.dlnow = 0;
vkFile.dltotal = 0;
mapParams[vkFile.URL] = vkFile;
ParamFile spendFile;
spendFile.name = "sapling-spend.params";
spendFile.URL = SAPLING_SPEND_URL;
spendFile.hash = SAPLING_SPEND_SHA256;
spendFile.verified = false;
spendFile.path = ZC_GetParamsDir() / "sapling-spend.params";
spendFile.dlnow = 0;
spendFile.dltotal = 0;
mapParams[spendFile.URL] = spendFile;
ParamFile outputFile;
outputFile.name = "sapling-output.params";
outputFile.URL = SAPLING_OUTPUT_URL;
outputFile.hash = SAPLING_OUTPUT_SHA256;
outputFile.verified = false;
outputFile.path = ZC_GetParamsDir() / "sapling-output.params";
outputFile.dlnow = 0;
outputFile.dltotal = 0;
mapParams[outputFile.URL] = outputFile;
ParamFile groth16File;
groth16File.name = "sprout-groth16.params";
groth16File.URL = SPROUT_GROTH16_URL;
groth16File.hash = SPROUT_GROTH16_SHA256;
groth16File.verified = false;
groth16File.path = ZC_GetParamsDir() / "sprout-groth16.params";
groth16File.dlnow = 0;
groth16File.dltotal = 0;
mapParams[groth16File.URL] = groth16File;
}
bool downloadFiles(std::string title)
{
if (!exists(ZC_GetParamsDir())) {
create_directory(ZC_GetParamsDir());
}
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (!it->second.verified) {
//open file for writing
it->second.file = fopen(it->second.path.string().c_str(), "wb");
if (!it->second.file) {
return false;
}
}
}
bool downloadComplete;
curl_global_init(CURL_GLOBAL_ALL);
for (int i = 0; i < 500; i++) {
downloadComplete = true;
CURLM *multi_handle;
multi_handle = curl_multi_init();
int still_running = 0; /* keep number of running handles */
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (!it->second.verified) {
/* init the curl session */
it->second.curl = curl_easy_init();
if(it->second.curl) {
it->second.prog.lastruntime = 0;
it->second.prog.curl = it->second.curl;
}
curl_easy_setopt(it->second.curl, CURLOPT_URL, it->second.URL.c_str());
curl_easy_setopt(it->second.curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(it->second.curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(it->second.curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(it->second.curl, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(it->second.curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
curl_easy_setopt(it->second.curl, CURLOPT_XFERINFODATA, &it->second.prog);
curl_easy_setopt(it->second.curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(it->second.curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(it->second.curl, CURLOPT_WRITEDATA, it->second.file);
curl_easy_setopt(it->second.curl, CURLOPT_RESUME_FROM_LARGE, it->second.dlretrytotal);
curl_multi_add_handle(multi_handle, it->second.curl);
}
}
curl_multi_perform(multi_handle, &still_running);
std::string uiMessage;
uiMessage = "Downloading " + title + "......0.00%";
uiInterface.InitMessage(_(uiMessage.c_str()));
int64_t nNow = GetTime();
while(still_running) {
if (ShutdownRequested()) {
downloadComplete = false;
break;
}
if (GetTime() >= nNow + 2) {
nNow = GetTime();
int64_t dltotal = 0;
int64_t dlnow = 0;
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (!it->second.verified) {
dltotal += it->second.dltotal + it->second.dlretrytotal;
dlnow += it->second.dlnow + it->second.dlretrytotal;
}
}
double pert = 0.00;
if (dltotal > 0) {
pert = (dlnow / (double)dltotal) * 100;
}
uiMessage = "Downloading " + title + "......" + std::to_string(pert).substr(0,10) + "%";
uiInterface.InitMessage(_(uiMessage.c_str()));
}
struct timeval timeout;
int rc; /* select() return code */
CURLMcode mc; /* curl_multi_fdset() return code */
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
long curl_timeo = 5;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}
/* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
downloadComplete = false;
break;
}
/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
to sleep 100ms, which is the minimum suggested value in the
curl_multi_fdset() doc. */
if(maxfd == -1) {
#ifdef _WIN32
Sleep(100);
rc = 0;
#else
/* Portable sleep for platforms other than Windows. */
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
rc = select(0, NULL, NULL, NULL, &wait);
#endif
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
switch(rc) {
case -1:
downloadComplete = false;
break;
case 0:
default:
/* timeout or readable/writable sockets */
curl_multi_perform(multi_handle, &still_running);
break;
}
}
if (downloadComplete)
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (!it->second.verified) {
it->second.dlretrytotal += it->second.dlnow;
curl_easy_cleanup(it->second.curl);
if (it->second.dlnow != it->second.dltotal) {
downloadComplete = false;
}
}
}
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
if (downloadComplete)
break;
if (ShutdownRequested()) {
downloadComplete = false;
break;
}
LogPrintf("Retrying Download - Retry #%d\n", i);
}
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (!it->second.verified) {
fclose(it->second.file);
}
}
return downloadComplete;
}
static size_t writer(char *in, size_t size, size_t nmemb, std::string *out)
{
out->append((char*)in, size * nmemb);
return size * nmemb;
}
void getHttpsJson(std::string url)
{
{
JsonDownload newDownload;
downloadedJSON = newDownload;
}
downloadedJSON.failed = false;
downloadedJSON.complete = false;
downloadedJSON.URL = url;
std::string response_string;
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl;
CURLcode res;
struct curl_slist *headers=NULL; // init to NULL is important
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charset: utf-8");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, downloadedJSON.URL.c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
char *ct;
/* ask for the content-type */
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
if((CURLE_OK == res) && ct) {
downloadedJSON.response = response_string;
downloadedJSON.failed = false;
downloadedJSON.complete = true;
}
} else {
downloadedJSON.response = "";
downloadedJSON.failed = false;
downloadedJSON.complete = false;
}
}
/* always cleanup */
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
curl_global_cleanup();
}
bool getBootstrap() {
initalizeMapParamBootstrap();
bool dlsuccess = downloadFiles("Bootstrap");
ParamFile bootstrap;
ParamFile signature;
if (dlsuccess)
{
for (std::map<std::string, ParamFile>::iterator it = mapParams.begin(); it != mapParams.end(); ++it) {
if (it->second.name == "bootstrap")
{
bootstrap = it->second;
}
else if (it->second.name == "bootstrap-signature")
{
signature = it->second;
}
}
}
// check signature of downloaded bootstrap archive, then extract
if (dlsuccess) {
if (!extract(bootstrap.path)) {
boost::filesystem::remove_all(GetDataDir() / "blocks");
boost::filesystem::remove_all(GetDataDir() / "chainstate");
dlsuccess = false;
}
}
if (boost::filesystem::exists(bootstrap.path.string())) {
boost::filesystem::remove(bootstrap.path.string());
}
return dlsuccess;
}
bool extract(boost::filesystem::path filename) {
bool extractComplete = true;
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
int flags = ARCHIVE_EXTRACT_TIME;
flags |= ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
archive_write_disk_set_standard_lookup(ext);
if (archive_read_support_format_tar(a) != ARCHIVE_OK)
extractComplete = false;
if (archive_read_support_filter_gzip(a) != ARCHIVE_OK)
extractComplete = false;
r = archive_read_open_filename(a, filename.string().c_str(), 10240);
if (r != ARCHIVE_OK) {
LogPrintf("archive_read_open_filename() %s %d\n",archive_error_string(a), r);
extractComplete = false;
}
if (extractComplete) {
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF) {
break;
}
if (r != ARCHIVE_OK) {
LogPrintf("archive_read_next_header() %s %d\n",archive_error_string(a), r);
extractComplete = false;
break;
}
const char* currentFile = archive_entry_pathname(entry);
std::string path = GetDataDir().string() + "/" + currentFile;
std::string uiMessage = "Extracting Bootstrap file ";
uiMessage.append(currentFile);
uiInterface.InitMessage(_(uiMessage.c_str()));
archive_entry_set_pathname(entry, path.c_str());
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
LogPrintf("archive_write_header() %s %d\n",archive_error_string(ext), r);
extractComplete = false;
break;
} else {
copy_data(a, ext);
r = archive_write_finish_entry(ext);
if (r != ARCHIVE_OK) {
LogPrintf("archive_write_finish_entry() %s %d\n",archive_error_string(ext), r);
extractComplete = false;
break;
}
}
}
}
archive_read_close(a);
archive_read_free(a);
archive_write_close(ext);
archive_write_free(ext);
return extractComplete;
}
static int copy_data(struct archive *ar, struct archive *aw) {
int r;
const void *buff;
size_t size;
int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
LogPrintf("archive_write_data_block() %s\n",archive_error_string(aw));
return (r);
}
}
}