diff options
-rw-r--r-- | src/bitcoinrpc.cpp | 6 | ||||
-rw-r--r-- | src/init.cpp | 6 | ||||
-rw-r--r-- | src/main.cpp | 7 | ||||
-rw-r--r-- | src/main.h | 6 | ||||
-rw-r--r-- | src/net.cpp | 115 | ||||
-rw-r--r-- | src/netbase.cpp | 36 | ||||
-rw-r--r-- | src/netbase.h | 13 | ||||
-rw-r--r-- | src/protocol.h | 2 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 5 | ||||
-rw-r--r-- | src/qt/forms/aboutdialog.ui | 2 | ||||
-rw-r--r-- | src/qt/forms/sendcoinsdialog.ui | 3 | ||||
-rw-r--r-- | src/qt/optionsmodel.cpp | 4 |
12 files changed, 146 insertions, 59 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index db595cbf96..5ac58de06d 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1871,7 +1871,10 @@ Value getmemorypool(const Array& params, bool fHelp) " \"previousblockhash\" : hash of current highest block\n" " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n" " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n" + " \"coinbaseflags\" : data that should be included in coinbase so support for new features can be judged\n" " \"time\" : timestamp appropriate for next block\n" + " \"mintime\" : minimum timestamp appropriate for next block\n" + " \"curtime\" : current timestamp\n" " \"bits\" : compressed target of next block\n" "If [data] is specified, tries to solve the block and returns true if it was successful."); @@ -1925,7 +1928,10 @@ Value getmemorypool(const Array& params, bool fHelp) result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); result.push_back(Pair("time", (int64_t)pblock->nTime)); + result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("curtime", (int64_t)GetAdjustedTime())); union { int32_t nBits; diff --git a/src/init.cpp b/src/init.cpp index e01516eb33..837d73f959 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -192,7 +192,7 @@ bool AppInit2(int argc, char* argv[]) " -dns \t " + _("Allow DNS lookups for addnode and connect") + "\n" + " -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" + " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" + - " -addnode=<ip> \t " + _("Add a node to connect to") + "\n" + + " -addnode=<ip> \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + " -connect=<ip> \t\t " + _("Connect only to the specified node") + "\n" + " -noirc \t " + _("Don't find peers using internet relay chat") + "\n" + " -nolisten \t " + _("Don't accept connections from outside") + "\n" + @@ -463,7 +463,7 @@ bool AppInit2(int argc, char* argv[]) if (mapArgs.count("-proxy")) { fUseProxy = true; - addrProxy = CAddress(mapArgs["-proxy"]); + addrProxy = CService(mapArgs["-proxy"], 9050); if (!addrProxy.IsValid()) { wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); @@ -512,7 +512,7 @@ bool AppInit2(int argc, char* argv[]) { BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"]) { - CAddress addr(strAddr, fAllowDNS); + CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS)); addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) AddAddress(addr); diff --git a/src/main.cpp b/src/main.cpp index 3c3f066042..891dbed980 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3130,12 +3130,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& hashPrevBlock = pblock->hashPrevBlock; } ++nExtraNonce; - pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce); - - // Put "/P2SH/" in the coinbase so everybody can tell when - // a majority of miners support it - const char* pszP2SH = "/P2SH/"; - pblock->vtx[0].vin[0].scriptSig += CScript() << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); + pblock->vtx[0].vin[0].scriptSig = (CScript() << pblock->nTime << CBigNum(nExtraNonce)) + COINBASE_FLAGS; assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); diff --git a/src/main.h b/src/main.h index 678c14cc39..be5f2f58a5 100644 --- a/src/main.h +++ b/src/main.h @@ -49,6 +49,12 @@ static const int fHaveUPnP = false; #endif +// Put "/P2SH/" in the coinbase so everybody can tell when +// a majority of miners support it +static const char* pszP2SH = "/P2SH/"; +static const CScript COINBASE_FLAGS = CScript() << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); + + diff --git a/src/net.cpp b/src/net.cpp index 2329206188..5aaa682131 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -29,6 +29,7 @@ static const int MAX_OUTBOUND_CONNECTIONS = 8; void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); void ThreadOpenConnections2(void* parg); +void ThreadOpenAddedConnections2(void* parg); #ifdef USE_UPNP void ThreadMapPort2(void* parg); #endif @@ -61,6 +62,9 @@ CCriticalSection cs_mapRelay; map<CInv, int64> mapAlreadyAskedFor; +set<CNetAddr> setservAddNodeAddresses; +CCriticalSection cs_setservAddNodeAddresses; + @@ -133,7 +137,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha // We now get our external IP from the IRC server first and only use this as a backup bool GetMyExternalIP(CNetAddr& ipRet) { - CAddress addrConnect; + CService addrConnect; const char* pszGet; const char* pszKeyword; @@ -149,7 +153,7 @@ bool GetMyExternalIP(CNetAddr& ipRet) // <?php echo $_SERVER["REMOTE_ADDR"]; ?> if (nHost == 1) { - addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org + addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org if (nLookup == 1) { @@ -168,7 +172,7 @@ bool GetMyExternalIP(CNetAddr& ipRet) } else if (nHost == 2) { - addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com + addrConnect = CService("74.208.43.192", 80); // www.showmyip.com if (nLookup == 1) { @@ -525,8 +529,8 @@ void CNode::PushVersion() { /// when NTP implemented, change to just nTime = GetAdjustedTime() int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); - CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); - CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); + CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr); + CAddress addrMe = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight); @@ -750,7 +754,9 @@ void ThreadSocketHandler2(void* parg) } else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS) { - closesocket(hSocket); + CRITICAL_BLOCK(cs_setservAddNodeAddresses) + if (!setservAddNodeAddresses.count(addr)) + closesocket(hSocket); } else if (CNode::IsBanned(addr)) { @@ -1198,7 +1204,7 @@ void ThreadOpenConnections2(void* parg) { BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) { - CAddress addr(strAddr, fAllowDNS); + CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS)); if (addr.IsValid()) OpenNetworkConnection(addr); for (int i = 0; i < 10 && i < nLoop; i++) @@ -1211,22 +1217,6 @@ void ThreadOpenConnections2(void* parg) } } - // Connect to manually added nodes first - if (mapArgs.count("-addnode")) - { - BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"]) - { - CAddress addr(strAddr, fAllowDNS); - if (addr.IsValid()) - { - OpenNetworkConnection(addr); - Sleep(500); - if (fShutdown) - return; - } - } - } - // Initiate network connections int64 nStart = GetTime(); loop @@ -1355,6 +1345,76 @@ void ThreadOpenConnections2(void* parg) } } +void ThreadOpenAddedConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg)); + try + { + vnThreadsRunning[7]++; + ThreadOpenAddedConnections2(parg); + vnThreadsRunning[7]--; + } + catch (std::exception& e) { + vnThreadsRunning[7]--; + PrintException(&e, "ThreadOpenAddedConnections()"); + } catch (...) { + vnThreadsRunning[7]--; + PrintException(NULL, "ThreadOpenAddedConnections()"); + } + printf("ThreadOpenAddedConnections exiting\n"); +} + +void ThreadOpenAddedConnections2(void* parg) +{ + printf("ThreadOpenAddedConnections started\n"); + + if (mapArgs.count("-addnode") == 0) + return; + + vector<vector<CService> > vservAddressesToAdd(0); + BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) + { + vector<CService> vservNode(0); + if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0)) + { + vservAddressesToAdd.push_back(vservNode); + CRITICAL_BLOCK(cs_setservAddNodeAddresses) + BOOST_FOREACH(CService& serv, vservNode) + setservAddNodeAddresses.insert(serv); + } + } + loop + { + vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd; + // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry + // (keeping in mind that addnode entries can have many IPs if fAllowDNS) + CRITICAL_BLOCK(cs_vNodes) + BOOST_FOREACH(CNode* pnode, vNodes) + for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++) + BOOST_FOREACH(CService& addrNode, *(it)) + if (pnode->addr == addrNode) + { + it = vservConnectAddresses.erase(it); + it--; + break; + } + BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses) + { + OpenNetworkConnection(CAddress(*(vserv.begin()))); + Sleep(500); + if (fShutdown) + return; + } + if (fShutdown) + return; + vnThreadsRunning[7]--; + Sleep(120000); // Retry every 2 minutes + vnThreadsRunning[7]++; + if (fShutdown) + return; + } +} + bool OpenNetworkConnection(const CAddress& addrConnect) { // @@ -1631,6 +1691,10 @@ void StartNode(void* parg) if (!CreateThread(ThreadSocketHandler, NULL)) printf("Error: CreateThread(ThreadSocketHandler) failed\n"); + // Initiate outbound connections from -addnode + if (!CreateThread(ThreadOpenAddedConnections, NULL)) + printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n"); + // Initiate outbound connections if (!CreateThread(ThreadOpenConnections, NULL)) printf("Error: CreateThread(ThreadOpenConnections) failed\n"); @@ -1650,9 +1714,7 @@ bool StopNode() nTransactionsUpdated++; int64 nStart = GetTime(); while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 -#ifdef USE_UPNP - || vnThreadsRunning[5] > 0 -#endif + || (fHaveUPnP && vnThreadsRunning[5] > 0) || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0 ) { if (GetTime() - nStart > 20) @@ -1666,6 +1728,7 @@ bool StopNode() if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n"); if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n"); if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n"); + if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n"); while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0) Sleep(20); Sleep(50); diff --git a/src/netbase.cpp b/src/netbase.cpp index ca27c2a8ce..54e3119153 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -98,7 +98,7 @@ bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMax return LookupHost(pszName, vIP, nMaxSolutions, false); } -bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup) +bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, int nMaxSolutions) { if (pszName[0] == 0) return false; @@ -132,10 +132,22 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo } std::vector<CNetAddr> vIP; - bool fRet = LookupIntern(pszHost, vIP, 1, fAllowLookup); + bool fRet = LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); + if (!fRet) + return false; + vAddr.resize(vIP.size()); + for (int i = 0; i < vIP.size(); i++) + vAddr[i] = CService(vIP[i], port); + return true; +} + +bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup) +{ + std::vector<CService> vService; + bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); if (!fRet) return false; - addr = CService(vIP[0], port); + addr = vService[0]; return true; } @@ -615,11 +627,12 @@ CService::CService(const char *pszIpPort, bool fAllowLookup) *this = ip; } -CService::CService(const char *pszIp, int portIn, bool fAllowLookup) +CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) { - std::vector<CNetAddr> ip; - if (LookupHost(pszIp, ip, 1, fAllowLookup)) - *this = CService(ip[0], portIn); + Init(); + CService ip; + if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + *this = ip; } CService::CService(const std::string &strIpPort, bool fAllowLookup) @@ -630,11 +643,12 @@ CService::CService(const std::string &strIpPort, bool fAllowLookup) *this = ip; } -CService::CService(const std::string &strIp, int portIn, bool fAllowLookup) +CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) { - std::vector<CNetAddr> ip; - if (LookupHost(strIp.c_str(), ip, 1, fAllowLookup)) - *this = CService(ip[0], portIn); + Init(); + CService ip; + if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + *this = ip; } unsigned short CService::GetPort() const diff --git a/src/netbase.h b/src/netbase.h index 6f06f8fe08..04ced18260 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -39,8 +39,8 @@ class CNetAddr public: CNetAddr(); CNetAddr(const struct in_addr& ipv4Addr); - CNetAddr(const char *pszIp, bool fAllowLookup = false); - CNetAddr(const std::string &strIp, bool fAllowLookup = false); + explicit CNetAddr(const char *pszIp, bool fAllowLookup = false); + explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false); void Init(); void SetIP(const CNetAddr& ip); bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) @@ -91,10 +91,10 @@ class CService : public CNetAddr CService(const CNetAddr& ip, unsigned short port); CService(const struct in_addr& ipv4Addr, unsigned short port); CService(const struct sockaddr_in& addr); - CService(const char *pszIp, int port, bool fAllowLookup = false); - CService(const char *pszIpPort, bool fAllowLookup = false); - CService(const std::string& strIp, int port, bool fAllowLookup = false); - CService(const std::string& strIpPort, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, bool fAllowLookup = false); void Init(); void SetPort(unsigned short portIn); unsigned short GetPort() const; @@ -128,6 +128,7 @@ class CService : public CNetAddr bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0, bool fAllowLookup = true); bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0); bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); +bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, int nMaxSolutions = 0); bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout); diff --git a/src/protocol.h b/src/protocol.h index 67e20d94e1..a0bf677aac 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -67,7 +67,7 @@ class CAddress : public CService { public: CAddress(); - CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK); void Init(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index d4ce8a79e1..d77279d42b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -417,7 +417,6 @@ void BitcoinGUI::setNumBlocks(int count) { if(!clientModel) return; - int initTotal = clientModel->getNumBlocksAtStartup(); int total = clientModel->getNumBlocksOfPeers(); QString tooltip; @@ -428,8 +427,8 @@ void BitcoinGUI::setNumBlocks(int count) progressBarLabel->setVisible(true); progressBarLabel->setText(tr("Synchronizing with network...")); progressBar->setVisible(true); - progressBar->setMaximum(total - initTotal); - progressBar->setValue(count - initTotal); + progressBar->setMaximum(total); + progressBar->setValue(count); } else { diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index cf7997326c..127b90965a 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -82,7 +82,7 @@ <item> <widget class="QLabel" name="label_2"> <property name="text"> - <string>Copyright © 2009-2011 Bitcoin Developers + <string>Copyright © 2009-2012 Bitcoin Developers This is experimental software. diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index e5e19e1015..04cf404ae3 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -80,6 +80,9 @@ <verstretch>0</verstretch> </sizepolicy> </property> + <property name="toolTip"> + <string>Remove all transaction fields</string> + </property> <property name="text"> <string>Clear all</string> </property> diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3237845c2c..edc1d61e9d 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -40,7 +40,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const case ProxyIP: return QVariant(QString::fromStdString(addrProxy.ToStringIP())); case ProxyPort: - return QVariant(QString::fromStdString(addrProxy.ToStringPort())); + return QVariant(addrProxy.GetPort()); case Fee: return QVariant(nTransactionFee); case DisplayUnit: @@ -87,7 +87,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case ProxyIP: { // Use CAddress to parse and check IP - CAddress addr(value.toString().toStdString() + ":1"); + CNetAddr addr(value.toString().toStdString()); if (addr.IsValid()) { addrProxy.SetIP(addr); |