diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 70 | ||||
-rw-r--r-- | src/irc.cpp | 17 | ||||
-rw-r--r-- | src/main.cpp | 21 | ||||
-rw-r--r-- | src/makefile.osx | 5 | ||||
-rw-r--r-- | src/net.cpp | 61 | ||||
-rw-r--r-- | src/qt/forms/sendcoinsentry.ui | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_da.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_de.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_en.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_es.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_es_CL.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_hu.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_it.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_nb.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_nl.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_pt_BR.ts | 4 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_ru.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_uk.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_zh_CN.ts | 2 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_zh_TW.ts | 2 | ||||
-rw-r--r-- | src/script.cpp | 4 | ||||
-rw-r--r-- | src/test/multisig_tests.cpp | 5 | ||||
-rw-r--r-- | src/test/script_op_eval_tests.cpp | 72 | ||||
-rw-r--r-- | src/util.cpp | 17 | ||||
-rw-r--r-- | src/util.h | 25 |
25 files changed, 210 insertions, 119 deletions
diff --git a/src/init.cpp b/src/init.cpp index 1e389b226b..8cbf21cc4b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -194,6 +194,7 @@ bool AppInit2(int argc, char* argv[]) " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" + " -addnode=<ip> \t " + _("Add a node to connect to") + "\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" + " -nodnsseed \t " + _("Don't bootstrap list of peers using DNS") + "\n" + " -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + @@ -247,8 +248,8 @@ bool AppInit2(int argc, char* argv[]) return false; } + fTestNet = GetBoolArg("-testnet"); fDebug = GetBoolArg("-debug"); - fAllowDNS = GetBoolArg("-dns"); #ifndef WIN32 fDaemon = GetBoolArg("-daemon"); @@ -267,10 +268,6 @@ bool AppInit2(int argc, char* argv[]) #endif fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); - - fTestNet = GetBoolArg("-testnet"); - bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); - fNoListen = GetBoolArg("-nolisten") || fTOR; fLogTimestamps = GetBoolArg("-logtimestamps"); #ifndef QT_GUI @@ -332,17 +329,6 @@ bool AppInit2(int argc, char* argv[]) return false; } - // Bind to the port early so we can tell if another instance is already running. - if (!fNoListen) - { - std::string strError; - if (!BindListenPort(strError)) - { - wxMessageBox(strError, "Bitcoin"); - return false; - } - } - std::ostringstream strErrors; // // Load data files @@ -428,6 +414,10 @@ bool AppInit2(int argc, char* argv[]) // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); + // Note: Bitcoin-QT stores several settings in the wallet, so we want + // to load the wallet BEFORE parsing command-line arguments, so + // the command-line/bitcoin.conf settings override GUI setting. + // // Parameters // @@ -480,6 +470,43 @@ bool AppInit2(int argc, char* argv[]) } } + bool fTor = (fUseProxy && addrProxy.port == htons(9050)); + if (fTor) + { + // Use SoftSetArg here so user can override any of these if they wish. + // Note: the GetBoolArg() calls for all of these must happen later. + SoftSetArg("-nolisten", true); + SoftSetArg("-noirc", true); + SoftSetArg("-nodnsseed", true); + SoftSetArg("-noupnp", true); + SoftSetArg("-upnp", false); + SoftSetArg("-dns", false); + } + + fAllowDNS = GetBoolArg("-dns"); + fNoListen = GetBoolArg("-nolisten"); + + if (fHaveUPnP) + { +#if USE_UPNP + if (GetBoolArg("-noupnp")) + fUseUPnP = false; +#else + if (GetBoolArg("-upnp")) + fUseUPnP = true; +#endif + } + + if (!fNoListen) + { + std::string strError; + if (!BindListenPort(strError)) + { + wxMessageBox(strError, "Bitcoin"); + return false; + } + } + if (mapArgs.count("-addnode")) { BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"]) @@ -502,17 +529,6 @@ bool AppInit2(int argc, char* argv[]) wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION); } - if (fHaveUPnP) - { -#if USE_UPNP - if (GetBoolArg("-noupnp")) - fUseUPnP = false; -#else - if (GetBoolArg("-upnp")) - fUseUPnP = true; -#endif - } - // // Start the node // diff --git a/src/irc.cpp b/src/irc.cpp index 5278488dcd..fe96a90a1c 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -264,19 +264,14 @@ void ThreadIRCSeed2(void* parg) int nErrorWait = 10; int nRetryWait = 10; bool fNameInUse = false; - bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); while (!fShutdown) { - //CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org - if (!fTOR) - { - //struct hostent* phostent = gethostbyname("chat.freenode.net"); - CAddress addrIRC("irc.lfnet.org", 6667, true); - if (addrIRC.IsValid()) - addrConnect = addrIRC; - } + + CAddress addrIRC("irc.lfnet.org", 6667, true); + if (addrIRC.IsValid()) + addrConnect = addrIRC; SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) @@ -406,10 +401,6 @@ void ThreadIRCSeed2(void* parg) closesocket(hSocket); hSocket = INVALID_SOCKET; - // IRC usually blocks TOR, so only try once - if (fTOR) - return; - if (GetTime() - nStart > 20 * 60) { nErrorWait /= 3; diff --git a/src/main.cpp b/src/main.cpp index bef76f7374..15f047bf7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,7 +35,6 @@ map<COutPoint, CInPoint> mapNextTx; map<uint256, CBlockIndex*> mapBlockIndex; uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); -const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; CBigNum bnBestChainWork = 0; @@ -285,6 +284,7 @@ bool CTransaction::AreInputsStandard(std::map<uint256, std::pair<CTxIndex, CTran COutPoint prevout = vin[i].prevout; assert(mapInputs.count(prevout.hash) > 0); CTransaction& txPrev = mapInputs[prevout.hash].second; + assert(prevout.n < txPrev.vout.size()); vector<vector<unsigned char> > vSolutions; txnouttype whichType; @@ -826,7 +826,7 @@ int GetNumBlocksOfPeers() bool IsInitialBlockDownload() { - if (pindexBest == NULL || nBestHeight < (Checkpoints::GetTotalBlocksEstimate()-nInitialBlockThreshold)) + if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate()) return true; static int64 nLastUpdate; static CBlockIndex* pindexLastBest; @@ -946,6 +946,17 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); } } + + // Make sure all prevout.n's are valid: + for (int i = 0; i < vin.size(); i++) + { + const COutPoint prevout = vin[i].prevout; + const CTxIndex& txindex = inputsRet[prevout.hash].first; + const CTransaction& txPrev = inputsRet[prevout.hash].second; + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + } + return true; } @@ -976,10 +987,10 @@ bool CTransaction::ConnectInputs(map<uint256, pair<CTxIndex, CTransaction> > inp if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight); - // Skip ECDSA signature verification when connecting blocks (fBlock=true) during initial download - // (before the last blockchain checkpoint). This is safe because block merkle hashes are + // Skip ECDSA signature verification when connecting blocks (fBlock=true) + // before the last blockchain checkpoint. This is safe because block merkle hashes are // still computed and checked, and any change will be caught at the next checkpoint. - if (!(fBlock && IsInitialBlockDownload())) + if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate()))) { bool fStrictOpEval = true; // This code should be removed when OP_EVAL has diff --git a/src/makefile.osx b/src/makefile.osx index cf5ec38d29..966829e222 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -96,11 +96,6 @@ else endif endif -ifdef USE_QRCODE - DEFS += -DUSE_QRCODE=$(USE_QRCODE) - LIBS += -lqrencode -endif - all: bitcoind # auto-generated dependencies: diff --git a/src/net.cpp b/src/net.cpp index 9b8dbe11e8..6dab7e8c11 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -496,21 +496,25 @@ bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB) void AddressCurrentlyConnected(const CAddress& addr) { + CAddress *paddrFound = NULL; + CRITICAL_BLOCK(cs_mapAddresses) { // Only if it's been published already map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); if (it != mapAddresses.end()) + paddrFound = &(*it).second; + } + + if (paddrFound) + { + int64 nUpdateInterval = 20 * 60; + if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval) { - CAddress& addrFound = (*it).second; - int64 nUpdateInterval = 20 * 60; - if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) - { - // Periodically update most recently seen time - addrFound.nTime = GetAdjustedTime(); - CAddrDB addrdb; - addrdb.WriteAddress(addrFound); - } + // Periodically update most recently seen time + paddrFound->nTime = GetAdjustedTime(); + CAddrDB addrdb; + addrdb.WriteAddress(*paddrFound); } } } @@ -1271,13 +1275,13 @@ void ThreadDNSAddressSeed2(void* parg) if (!fTestNet) { printf("Loading addresses from DNS seeds (could take a while)\n"); - CAddrDB addrDB; - addrDB.TxnBegin(); for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { vector<CAddress> vaddr; if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true)) { + CAddrDB addrDB; + addrDB.TxnBegin(); BOOST_FOREACH (CAddress& addr, vaddr) { if (addr.GetByte(3) != 127) @@ -1287,10 +1291,9 @@ void ThreadDNSAddressSeed2(void* parg) found++; } } + addrDB.TxnCommit(); // Save addresses (it's ok if this fails) } } - - addrDB.TxnCommit(); // Save addresses (it's ok if this fails) } printf("%d addresses found from DNS seeds\n", found); @@ -1462,28 +1465,32 @@ void ThreadOpenConnections2(void* parg) if (fShutdown) return; + bool fAddSeeds = false; + CRITICAL_BLOCK(cs_mapAddresses) { // Add seed nodes if IRC isn't working bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); - if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet) + if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet) + fAddSeeds = true; + } + + if (fAddSeeds) + { + for (int i = 0; i < ARRAYLEN(pnSeed); i++) { - for (int i = 0; i < ARRAYLEN(pnSeed); i++) - { - // It'll only connect to one or two seed nodes because once it connects, - // it'll get a pile of addresses with newer timestamps. - // Seed nodes are given a random 'last seen time' of between one and two - // weeks ago. - const int64 nOneWeek = 7*24*60*60; - CAddress addr; - addr.ip = pnSeed[i]; - addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; - AddAddress(addr); - } + // It'll only connect to one or two seed nodes because once it connects, + // it'll get a pile of addresses with newer timestamps. + // Seed nodes are given a random 'last seen time' of between one and two + // weeks ago. + const int64 nOneWeek = 7*24*60*60; + CAddress addr; + addr.ip = pnSeed[i]; + addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; + AddAddress(addr); } } - // // Choose an address to connect to based on most recently seen // diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 0297d17f15..22a3f8fdc6 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -100,7 +100,7 @@ <item> <widget class="QToolButton" name="addressBookButton"> <property name="toolTip"> - <string>Choose adress from address book</string> + <string>Choose address from address book</string> </property> <property name="text"> <string/> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index c6ef676ffc..a0399e9f6c 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Vælg adresse fra adressebog</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 3b57d31a2c..022e71c294 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -915,7 +915,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Adresse aus dem Adressbuch auswählen</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 0dfb50835d..ff36675100 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -918,7 +918,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation type="unfinished"></translation> </message> <message> diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index bf2c49396d..44af31d88d 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -918,7 +918,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Elije dirección de la guia</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index c355a1e4a6..f7bedb2acf 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -918,7 +918,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Elije dirección de la guia</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 8cee3334b8..32dc15af84 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Válassz egy címet a címjegyzékből</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 56beb98e84..f2fa08dfdc 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -917,7 +917,7 @@ p, li { white-space: pre-wrap; }⏎ </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Scegli l'indirizzo dalla rubrica</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 95f5e9c59f..404e8f0f90 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Velg adresse fra adresseboken</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 408e18d6ed..c472c924f7 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -917,7 +917,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Kies adres uit adresboek</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 13263de865..55a86a08ae 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -909,8 +909,8 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> - <translation>Choose adress from address book</translation> + <source>Choose address from address book</source> + <translation>Choose address from address book</translation> </message> <message> <location filename="../forms/sendcoinsentry.ui" line="113"/> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 60332ac570..cefa092949 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Выбрать адрес из адресной книги</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 8c087ac6c8..ae64940b93 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>Вибрати адресу з адресної книги</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 2c5b5ba244..33cefda545 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -916,7 +916,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>从地址薄选择地址</translation> </message> <message> diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index f03ff82bbe..e460978f11 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -915,7 +915,7 @@ p, li { white-space: pre-wrap; } </message> <message> <location filename="../forms/sendcoinsentry.ui" line="103"/> - <source>Choose adress from address book</source> + <source>Choose address from address book</source> <translation>從位址簿中選一個位址</translation> </message> <message> diff --git a/src/script.cpp b/src/script.cpp index 0a1b3bb309..34872808b3 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1033,7 +1033,7 @@ bool EvalScriptInner(vector<vector<unsigned char> >& stack, const CScript& scrip return false; if (!EvalScriptInner(stack, subscript, txTo, nIn, nHashType, - pbegincodehash, pendcodehash, nOpCount, nSigOpCount, fStrictOpEval, nRecurseDepth++)) + pbegincodehash, pendcodehash, nOpCount, nSigOpCount, fStrictOpEval, nRecurseDepth+1)) return false; } break; @@ -1436,7 +1436,7 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); - return HaveKeys(vSolutions, keystore); + return HaveKeys(keys, keystore) == keys.size(); } } return false; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 742083f3cf..0c2e41aedd 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) // one key that would satisfy an (a|b) or 2-of-3 keys needed // to spend an escrow transaction. // - CBasicKeyStore keystore, emptykeystore; + CBasicKeyStore keystore, emptykeystore, partialkeystore; CKey key[3]; CBitcoinAddress keyaddr[3]; for (int i = 0; i < 3; i++) @@ -183,6 +183,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) keystore.AddKey(key[i]); keyaddr[i].SetPubKey(key[i].GetPubKey()); } + partialkeystore.AddKey(key[0]); { vector<valtype> solutions; @@ -221,6 +222,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(!ExtractAddress(s, addr)); BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); } { vector<valtype> solutions; @@ -237,6 +239,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(nRequired = 1); BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); } { vector<valtype> solutions; diff --git a/src/test/script_op_eval_tests.cpp b/src/test/script_op_eval_tests.cpp index c44642c6e9..b1bd52c5f2 100644 --- a/src/test/script_op_eval_tests.cpp +++ b/src/test/script_op_eval_tests.cpp @@ -93,31 +93,65 @@ BOOST_AUTO_TEST_CASE(script_op_eval2) { // Test OP_EVAL edge cases - CScript recurse; - recurse << OP_DUP << OP_EVAL; + // Make sure infinite recursion fails to validate: + CScript infiniteRecurse; + infiniteRecurse << OP_DUP << OP_EVAL; - uint160 recurseHash = Hash160(recurse); + uint160 infiniteRecurseHash = Hash160(infiniteRecurse); - CScript fund; - fund << OP_DUP << OP_HASH160 << recurseHash << OP_EQUALVERIFY << OP_EVAL; + CScript fund1; + fund1 << OP_DUP << OP_HASH160 << infiniteRecurseHash << OP_EQUALVERIFY << OP_EVAL; - CTransaction txFrom; // Funding transaction: - txFrom.vout.resize(1); - txFrom.vout[0].scriptPubKey = fund; + CTransaction txFrom1; // Funding transaction: + txFrom1.vout.resize(1); + txFrom1.vout[0].scriptPubKey = fund1; - BOOST_CHECK(txFrom.IsStandard()); // Looks like a standard transaction until you try to spend it + BOOST_CHECK(txFrom1.IsStandard()); // Looks like a standard transaction until you try to spend it - CTransaction txTo; - txTo.vin.resize(1); - txTo.vout.resize(1); - txTo.vin[0].prevout.n = 0; - txTo.vin[0].prevout.hash = txFrom.GetHash(); - txTo.vin[0].scriptSig = CScript() << static_cast<std::vector<unsigned char> >(recurse); - txTo.vout[0].nValue = 1; + std::vector<unsigned char> infiniteRecurseSerialized(infiniteRecurse); - int nUnused = 0; - BOOST_CHECK(!VerifyScript(txTo.vin[0].scriptSig, txFrom.vout[0].scriptPubKey, txTo, 0, nUnused, 0, true)); - BOOST_CHECK(!VerifySignature(txFrom, txTo, 0, nUnused, true)); + CTransaction txTo1; + txTo1.vin.resize(1); + txTo1.vout.resize(1); + txTo1.vin[0].prevout.n = 0; + txTo1.vin[0].prevout.hash = txFrom1.GetHash(); + txTo1.vin[0].scriptSig = CScript() << infiniteRecurseSerialized << infiniteRecurseSerialized; + txTo1.vout[0].nValue = 1; + + int nUnused1 = 0; + BOOST_CHECK(!VerifyScript(txTo1.vin[0].scriptSig, txFrom1.vout[0].scriptPubKey, txTo1, 0, nUnused1, 0, true)); + BOOST_CHECK(!VerifySignature(txFrom1, txTo1, 0, nUnused1, true)); + + // Make sure 3-level-deep recursion fails to validate: + CScript recurse3; + recurse3 << OP_EVAL; + + uint160 recurse3Hash = Hash160(recurse3); + + CScript fund2; + fund2 << OP_DUP << OP_HASH160 << recurse3Hash << OP_EQUALVERIFY << OP_EVAL; + + CTransaction txFrom2; // Funding transaction: + txFrom2.vout.resize(1); + txFrom2.vout[0].scriptPubKey = fund2; + + BOOST_CHECK(txFrom2.IsStandard()); // Looks like a standard transaction until you try to spend it + + std::vector<unsigned char> recurse3Serialized(recurse3); + CScript op1Script = CScript() << OP_1; + std::vector<unsigned char> op1Serialized(op1Script); + + CTransaction txTo2; + txTo2.vin.resize(1); + txTo2.vout.resize(1); + txTo2.vin[0].prevout.n = 0; + txTo2.vin[0].prevout.hash = txFrom2.GetHash(); + txTo2.vin[0].scriptSig = CScript() << op1Serialized << recurse3Serialized << recurse3Serialized; + txTo2.vout[0].nValue = 1; + + int nUnused2 = 0; + BOOST_CHECK(!VerifyScript(txTo2.vin[0].scriptSig, txFrom2.vout[0].scriptPubKey, txTo2, 0, nUnused2, 0, true)); + BOOST_CHECK(!VerifySignature(txFrom2, txTo2, 0, nUnused2, true)); } BOOST_AUTO_TEST_CASE(script_op_eval3) diff --git a/src/util.cpp b/src/util.cpp index a45ce33a1c..3805e077a1 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -470,6 +470,23 @@ void ParseParameters(int argc, char* argv[]) } } +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + + string EncodeBase64(const unsigned char* pch, size_t len) { static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/util.h b/src/util.h index bb90869962..48fea023bf 100644 --- a/src/util.h +++ b/src/util.h @@ -439,7 +439,7 @@ inline int64 GetArg(const std::string& strArg, int64 nDefault) return nDefault; } -inline bool GetBoolArg(const std::string& strArg) +inline bool GetBoolArg(const std::string& strArg, bool fDefault=false) { if (mapArgs.count(strArg)) { @@ -447,9 +447,26 @@ inline bool GetBoolArg(const std::string& strArg) return true; return (atoi(mapArgs[strArg]) != 0); } - return false; -} - + return fDefault; +} + +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); + +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, bool fValue); |