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

Fixes for Network issues #38

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ qrc_*.cpp
#mac specific
.DS_Store
build
# vscode IDE
.vscode

!src/leveldb/Makefile
*.autosave
8 changes: 5 additions & 3 deletions pinkcoin-qt.pro
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
TEMPLATE = app
TARGET = Pinkcoin-Qt
VERSION = 2.3.1.0

INCLUDEPATH += src src/json src/qt src/qt/plugins/mrichtexteditor
DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE
CONFIG += no_include_pwd
CONFIG += thread
CONFIG += c++11
CONFIG += c++17

greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets network svg
Expand Down Expand Up @@ -52,7 +51,7 @@ macx {

isEmpty(BOOST_LIB_SUFFIX) {
macx:BOOST_LIB_SUFFIX = -mt
windows:BOOST_LIB_SUFFIX = -mgw49-mt-s-1_57
windows:BOOST_LIB_SUFFIX = -mt-s
}

isEmpty(BOOST_THREAD_LIB_SUFFIX) {
Expand Down Expand Up @@ -140,6 +139,9 @@ contains(RELEASE, 1) {
# This can be enabled for Windows, when we switch to MinGW >= 4.4.x.
}

# Temporarily fix issue with too big main.o file
Debug:win32:QMAKE_CXXFLAGS *= -Wa,-mbig-obj -O2

# for extra security on Windows: enable ASLR and DEP via GCC linker flags
win32:QMAKE_LFLAGS *= -Wl,--dynamicbase -Wl,--nxcompat
win32:QMAKE_LFLAGS += -static-libgcc -static-libstdc++ -static
Expand Down
10 changes: 5 additions & 5 deletions src/makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ LIBPATHS= \
-L"C:\openssl-1.0.1c-mgw"

LIBS= \
-l boost_system-mgw44-mt-1_53 \
-l boost_filesystem-mgw44-mt-1_53 \
-l boost_program_options-mgw44-mt-1_53 \
-l boost_thread-mgw44-mt-1_53 \
-l boost_chrono-mgw44-mt-1_53 \
-l boost_system-mt-s \
-l boost_filesystem-mt-s \
-l boost_program_options-mt-s \
-l boost_thread-mt-s \
-l boost_chrono-mt-s \
-l db_cxx \
-l ssl \
-l crypto
Expand Down
89 changes: 66 additions & 23 deletions src/ntp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@
using namespace std;
static uint64_t nNTPUnix = 2208988800ull;

bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
bool GetNTPTime(const char *addrConnect, uint64_t &timeRet)
{

uint64_t startMicros = 0;
uint64_t endMicros = 0;
uint64_t diffMicros = 0;
Expand All @@ -60,7 +59,7 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
// should we ever need UDP support for any other reason, but for now this is fine.

// Standard UDP socket.
int socketNTP = -1;
SOCKET socketNTP = INVALID_SOCKET;

// Use getaddrinfo() with support code from netbase.cpp.
// getaddrinfo() is required to be thread safe (RFC3493).
Expand All @@ -74,14 +73,18 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
struct addrinfo *aiRes = NULL;
int nErr = getaddrinfo(addrConnect, "123", &aiHint, &aiRes);
if (nErr)
{
return false;
}

// Connect to NTP
for (; aiRes != NULL; aiRes = aiRes->ai_next)
{
socketNTP = socket(aiRes->ai_family , aiRes->ai_socktype, aiRes->ai_protocol);
if (socketNTP < 0)
if (socketNTP == INVALID_SOCKET)
{
continue;
}

// Set our timeout to 2 seconds.
#ifdef WIN32
Expand All @@ -94,9 +97,9 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
setsockopt(socketNTP, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
#endif

if (connect(socketNTP, (struct sockaddr*) aiRes->ai_addr, aiRes->ai_addrlen) < 0)
if (connect(socketNTP, (struct sockaddr*) aiRes->ai_addr, aiRes->ai_addrlen) == SOCKET_ERROR)
{
close(socketNTP);
closesocket(socketNTP);
continue;
}

Expand All @@ -105,8 +108,10 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)

if (aiRes == NULL)
{
if (socketNTP >= 0)
close(socketNTP);
if (socketNTP != INVALID_SOCKET)
{
closesocket(socketNTP);
}

return false;
}
Expand All @@ -125,23 +130,30 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
bTimeReq[0] = 0x1b;

// Time we send our request
startMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::system_clock::now().time_since_epoch()).count();
startMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::system_clock::now().time_since_epoch()
).count();
int n = send(socketNTP, (char*)&bTimeReq, 48, 0);

if (n < 0) {
close(socketNTP);
if (n == SOCKET_ERROR)
{
closesocket(socketNTP);
return false;
}

n = recv(socketNTP, (char*)&bTimeReq, 48, 0);
// Time we got it
endMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::system_clock::now().time_since_epoch()).count();
endMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::system_clock::now().time_since_epoch()
).count();

freeaddrinfo(aiRes);
close(socketNTP);
closesocket(socketNTP);

if (n < 0)
if (n == SOCKET_ERROR)
{
return false;
}

uint32_t tSeconds = 0;
uint32_t tMicros = 0;
Expand All @@ -160,11 +172,15 @@ bool GetNTPTime(const char *addrConnect, uint64_t& timeRet)
int64_t nEpoch = tSeconds - nNTPUnix;

if (nEpoch < 0)
{
nEpoch += std::numeric_limits<uint32_t>::max(); // NTP Rolled over int32 limit. Happens in Y2036.
}

// There is no reason this should *still* be < 0;
if (nEpoch < 0)
{
return false;
}

// Get our NTP time down to the microsecond.
// We have to convert NTP fractional time to Micros.
Expand All @@ -190,21 +206,30 @@ void *threadGetNTPTime(int nServer, const string strPool, uint64_t startMicros)
{
std::string strAddress = strPool;
if (nServer > 3)
{
return nullptr;
}

// User set :// or tried to use a port (org:###)
// or is trying to use something other than ntp.org.
// Drop whatever they set and just use the default.
if (strAddress == "" || strAddress.find(":") != std::string::npos || strAddress.find("pool.ntp.org") == std::string::npos)
if (
strAddress == "" || strAddress.find(":") != std::string::npos ||
strAddress.find("pool.ntp.org") == std::string::npos
)
{
strAddress = "pool.ntp.org";
}

// Prepend pool server number.
strAddress = to_string(nServer) + "." + strAddress;

uint64_t myTime = 0;
if (GetNTPTime(strAddress.c_str(), myTime))
{
uint64_t nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::system_clock::now().time_since_epoch()).count();
uint64_t nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::system_clock::now().time_since_epoch()
).count();

// Subtract how long it took our thread to get the time.
myTime -= (nowMicros - startMicros);
Expand Down Expand Up @@ -238,14 +263,20 @@ bool SetNTPOffset(const string &strPool)
// If we don't have 4 good times after 4 iterations and waiting
// 2 seconds for a response on our last try then we give up.
if (nWait == 5)
{
return false;
}

for (int i = 0; i < 4; i++)
{
ntpTime[i] = 0;
}

// Let our threads know when we're starting from so they can give
// us times that are consistent with what we need.
nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::system_clock::now().time_since_epoch()).count();
nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::system_clock::now().time_since_epoch()
).count();

// Any regional ntp pool can be used. But we prepend the number for NTP's randomized selection.
// By default we use pool.ntp.org - which generally selects pools that are appropriate for your ip.
Expand All @@ -262,14 +293,20 @@ bool SetNTPOffset(const string &strPool)

// Get this now so we know exactly when we woke up again.
// Helps us get an accurate offset.
nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(boost::chrono::system_clock::now().time_since_epoch()).count();
nowMicros = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::system_clock::now().time_since_epoch()
).count();

for (int i = 0; i < 4; i++)
{
// Make sure we actually got the time. NTP servers that respond but aren't able
// to give us an accurate time as requested instead send us the uint32 max.
// We tolerate 10 seconds here to accomodate our internal adjustments.
if (ntpTime[i] > 0 && abs((int64_t)(ntpTime[i] / 1000000) + (int64_t)nNTPUnix - (int64_t)std::numeric_limits<uint32_t>::max()) > 10)
auto timeCheck = abs(
(int64_t)(ntpTime[i] / 1000000) + (int64_t)nNTPUnix -
(int64_t)std::numeric_limits<uint32_t>::max()
);
if (ntpTime[i] > 0 && timeCheck > 10)
{
// Account for our wait time.
ntpTime[i] += (500000 * nWait);
Expand All @@ -279,16 +316,22 @@ bool SetNTPOffset(const string &strPool)

// Add it up.
for (vector<uint64_t>::iterator it = ntpMicros.begin(); it != ntpMicros.end(); it++)
avMicros += *it;
{
avMicros += *it;
}

// Average of what we got.
if (ntpMicros.size() > 0)
{
avMicros /= ntpMicros.size();
}

// Set our offset based on the difference and maintain an average.
nTimeOffset += (avMicros - nowMicros);
if (nWait > 1)
{
nTimeOffset /= 2;
}

// Add these to our successful NTP Request count.
tCount += ntpMicros.size();
Expand Down Expand Up @@ -367,7 +410,9 @@ void *threadNTPUpdate(const string &strNTPool)
if (!SetNTPOffset(strNTPool))
{
nFailCount++;
} else {
}
else
{
fNTPSuccess = true;
nFailCount = 0;
}
Expand All @@ -377,11 +422,9 @@ void *threadNTPUpdate(const string &strNTPool)

// Start our next loop with a fresh tTrack;
tTrack = GetAdjustedTime();

}

}

return nullptr;
}

37 changes: 19 additions & 18 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ static std::string Translate(const char* psz)
static void handleRunawayException(std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Pinkcoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
QMessageBox::critical(
nullptr,
"Runaway exception",
BitcoinGUI::tr(
"A fatal error occurred. Pinkcoin can no longer continue safely and will quit."
) + QString("\n\n") + QString::fromStdString(strMiscWarning));
exit(1);
}

Expand All @@ -126,12 +131,6 @@ int main(int argc, char *argv[])
// Do this early as we don't want to bother initializing if we are just calling IPC
ipcScanRelay(argc, argv);

#if QT_VERSION < 0x050000
// Internal string conversion is all UTF-8
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
#endif

Q_INIT_RESOURCE(bitcoin);
QApplication app(argc, argv);

Expand All @@ -146,16 +145,18 @@ int main(int argc, char *argv[])
{
// This message can not be translated, as translation is not initialized yet
// (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory)
QMessageBox::critical(0, "Pinkcoin",
QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
QMessageBox::critical(
nullptr, "Pinkcoin",
QString("Error: Specified data directory \"%1\" does not exist.").arg(
QString::fromStdString(mapArgs["-datadir"])
)
);
return 1;
}
ReadConfigFile(mapArgs, mapMultiArgs);

#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

// Set common app style for all platforms.
app.setStyle(QStyleFactory::create("Fusion"));
Expand Down Expand Up @@ -235,7 +236,7 @@ int main(int argc, char *argv[])
int splashWidth = (int)(0.55*screenGeometry.width());
QPixmap splashPixmap = QPixmap(":/images/splash").scaledToWidth(splashWidth, Qt::SmoothTransformation);

QSplashScreen splash(splashPixmap, 0);
QSplashScreen splash(splashPixmap, nullptr);
splash.setFont(fontData.font("Rubik", "Medium", 20));

if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
Expand Down Expand Up @@ -293,13 +294,13 @@ int main(int argc, char *argv[])
app.exec();

window.hide();
window.setClientModel(0);
window.setWalletModel(0, 0);
window.setMessageModel(0);
guiref = 0;
window.setClientModel(nullptr);
window.setWalletModel(nullptr, nullptr);
window.setMessageModel(nullptr);
guiref = nullptr;
}
// Shutdown the core and its threads, but don't exit Bitcoin-Qt here
Shutdown(NULL);
Shutdown(nullptr);
threadGroup.interrupt_all();
threadGroup.join_all();
}
Expand All @@ -310,7 +311,7 @@ int main(int argc, char *argv[])
} catch (std::exception& e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
handleRunawayException(nullptr);
}
return 0;
}
Expand Down