diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/bitcoin-tx.cpp | 2 | ||||
| -rw-r--r-- | src/init.cpp | 3 | ||||
| -rw-r--r-- | src/main.cpp | 65 | ||||
| -rw-r--r-- | src/main.h | 16 | ||||
| -rw-r--r-- | src/miner.cpp | 2 | ||||
| -rw-r--r-- | src/qt/bitcoinstrings.cpp | 16 | ||||
| -rw-r--r-- | src/qt/locale/bitcoin_en.ts | 346 | ||||
| -rw-r--r-- | src/rpcrawtransaction.cpp | 7 | ||||
| -rw-r--r-- | src/script/interpreter.cpp | 89 | ||||
| -rw-r--r-- | src/script/interpreter.h | 35 | ||||
| -rw-r--r-- | src/script/sigcache.cpp | 88 | ||||
| -rw-r--r-- | src/script/sigcache.h | 26 | ||||
| -rw-r--r-- | src/script/sign.cpp | 8 | ||||
| -rw-r--r-- | src/script/standard.cpp | 15 | ||||
| -rw-r--r-- | src/test/multisig_tests.cpp | 18 | ||||
| -rw-r--r-- | src/test/script_P2SH_tests.cpp | 4 | ||||
| -rw-r--r-- | src/test/script_tests.cpp | 36 | ||||
| -rw-r--r-- | src/test/transaction_tests.cpp | 5 |
19 files changed, 419 insertions, 364 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index bd6f1ba0d..155adfef7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -103,6 +103,7 @@ BITCOIN_CORE_H = \ script/compressor.h \ script/interpreter.h \ script/script.h \ + script/sigcache.h \ script/sign.h \ script/standard.h \ serialize.h \ @@ -218,6 +219,7 @@ libbitcoin_common_a_SOURCES = \ script/compressor.cpp \ script/interpreter.cpp \ script/script.cpp \ + script/sigcache.cpp \ script/sign.cpp \ script/standard.cpp \ $(BITCOIN_CORE_H) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index a61b4fe29..a198eb586 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -435,7 +435,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) fComplete = false; } diff --git a/src/init.cpp b/src/init.cpp index 980c589b2..36ba13b94 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -237,7 +237,7 @@ std::string HelpMessage(HelpMessageMode mode) #if !defined(WIN32) strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n"; #endif - strUsage += " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n"; + strUsage += " -txindex " + _("Maintain a full transaction index, used by the getrawtransaction rpc call (default: 0)") + "\n"; strUsage += "\n" + _("Connection options:") + "\n"; strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n"; @@ -280,7 +280,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n"; strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n"; strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n"; - strUsage += " -respendnotify=<cmd> " + _("Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)") + "\n"; strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n"; strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n"; strUsage += " -txconfirmtarget=<n> " + _("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)") + "\n"; diff --git a/src/main.cpp b/src/main.cpp index 83848bf84..5d46c30a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,8 +26,8 @@ #include <boost/filesystem/fstream.hpp> #include <boost/thread.hpp> -using namespace std; using namespace boost; +using namespace std; #if defined(NDEBUG) # error "Bitcoin cannot be compiled without assertions." @@ -645,7 +645,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // IsStandard() will have already returned false // and this method isn't called. vector<vector<unsigned char> > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false)) + if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker())) return false; if (whichType == TX_SCRIPTHASH) @@ -943,7 +943,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) { return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString()); } @@ -1316,12 +1316,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() const { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags)) + if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore))) return error("CScriptCheck() : %s:%d VerifySignature failed", ptxTo->GetHash().ToString(), nIn); return true; } -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) { if (!tx.IsCoinBase()) { @@ -1390,7 +1390,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags); + CScriptCheck check(*coins, tx, i, flags, cacheStore); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1403,7 +1403,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); if (check()) return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); } @@ -1599,8 +1599,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C int64_t nBIP16SwitchTime = 1333238400; bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); - unsigned int flags = SCRIPT_VERIFY_NOCACHE | - (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); + unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; CBlockUndo blockundo; @@ -1644,7 +1643,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector<CScriptCheck> vChecks; - if (!CheckInputs(tx, state, view, fScriptChecks, flags, nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) return false; control.Add(vChecks); } @@ -1688,7 +1687,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock() : FindUndoPos failed"); if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash())) - return state.Abort(_("Failed to write undo data")); + return state.Abort("Failed to write undo data"); // update nUndoPos in block index pindex->nUndoPos = pos.nPos; @@ -1699,12 +1698,12 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C CDiskBlockIndex blockindex(pindex); if (!pblocktree->WriteBlockIndex(blockindex)) - return state.Abort(_("Failed to write block index")); + return state.Abort("Failed to write block index"); } if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) - return state.Abort(_("Failed to write transaction index")); + return state.Abort("Failed to write transaction index"); // add this block to the view's block chain bool ret; @@ -1739,7 +1738,7 @@ bool static WriteChainState(CValidationState &state) { FlushBlockFile(); pblocktree->Sync(); if (!pcoinsTip->Flush()) - return state.Abort(_("Failed to write to coin database")); + return state.Abort("Failed to write to coin database"); nLastWrite = GetTimeMicros(); } return true; @@ -1787,7 +1786,7 @@ bool static DisconnectTip(CValidationState &state) { // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete)) - return state.Abort(_("Failed to read block")); + return state.Abort("Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { @@ -1836,7 +1835,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * CBlock block; if (!pblock) { if (!ReadBlockFromDisk(block, pindexNew)) - return state.Abort(_("Failed to read block")); + return state.Abort("Failed to read block"); pblock = █ } // Apply the block atomically to the chain state. @@ -1990,7 +1989,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo CheckForkWarningConditions(); if (!pblocktree->Flush()) - return state.Abort(_("Failed to sync block index")); + return state.Abort("Failed to sync block index"); return true; } @@ -2027,10 +2026,10 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { // Relay inventory, but don't relay old inventory during initial block download. int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) - pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } uiInterface.NotifyBlockTip(hashNewTip); @@ -2097,7 +2096,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl setBlockIndexValid.insert(pindexNew); if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew))) - return state.Abort(_("Failed to write block index")); + return state.Abort("Failed to write block index"); return true; } @@ -2149,7 +2148,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd } if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - return state.Abort(_("Failed to write file info")); + return state.Abort("Failed to write file info"); if (fUpdatedLast) pblocktree->WriteLastBlockFile(nLastBlockFile); @@ -2167,15 +2166,15 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne pos.nPos = infoLastBlockFile.nUndoSize; nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - return state.Abort(_("Failed to write block info")); + return state.Abort("Failed to write block info"); } else { CBlockFileInfo info; if (!pblocktree->ReadBlockFileInfo(nFile, info)) - return state.Abort(_("Failed to read block info")); + return state.Abort("Failed to read block info"); pos.nPos = info.nUndoSize; nNewSize = (info.nUndoSize += nAddSize); if (!pblocktree->WriteBlockFileInfo(nFile, info)) - return state.Abort(_("Failed to write block info")); + return state.Abort("Failed to write block info"); } unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; @@ -2392,11 +2391,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return error("AcceptBlock() : FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos)) - return state.Abort(_("Failed to write block")); + return state.Abort("Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock() : ReceivedBlockTransactions failed"); } catch(std::runtime_error &e) { - return state.Abort(_("System error: ") + e.what()); + return state.Abort(std::string("System error: ") + e.what()); } return true; @@ -2719,10 +2718,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { -bool AbortNode(const std::string &strMessage) { +bool AbortNode(const std::string &strMessage, const std::string &userMessage) { strMiscWarning = strMessage; LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR); + uiInterface.ThreadSafeMessageBox( + userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + "", CClientUIInterface::MSG_ERROR); StartShutdown(); return false; } @@ -2733,7 +2734,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) - return AbortNode(_("Error: Disk space is low!")); + return AbortNode("Disk space is low!", _("Error: Disk space is low!")); return true; } @@ -3143,7 +3144,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) } } } catch(std::runtime_error &e) { - AbortNode(_("Error: system error: ") + e.what()); + AbortNode(std::string("System error: ") + e.what()); } if (nLoaded > 0) LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart); diff --git a/src/main.h b/src/main.h index 7e849505d..cad7eebfb 100644 --- a/src/main.h +++ b/src/main.h @@ -17,6 +17,7 @@ #include "net.h" #include "pow.h" #include "script/script.h" +#include "script/sigcache.h" #include "script/standard.h" #include "sync.h" #include "txmempool.h" @@ -177,7 +178,7 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); /** Abort with a message */ -bool AbortNode(const std::string &msg); +bool AbortNode(const std::string &msg, const std::string &userMessage=""); /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Increase a node's misbehavior score. */ @@ -258,9 +259,8 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma // Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) // This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it // instead of being performed inline. -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true, - unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS, - std::vector<CScriptCheck> *pvChecks = NULL); +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, + unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL); // Apply the effects of this transaction on the UTXO set represented by view void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight); @@ -302,12 +302,13 @@ private: const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; + bool cacheStore; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn) : + CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false) {} + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn) { } bool operator()() const; @@ -316,6 +317,7 @@ public: std::swap(ptxTo, check.ptxTo); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); + std::swap(cacheStore, check.cacheStore); } }; diff --git a/src/miner.cpp b/src/miner.cpp index 361a2bea4..280349e8c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -257,7 +257,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. CValidationState state; - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS)) + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) continue; CTxUndo txundo; diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 3b4b40aae..25c811183 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -195,21 +195,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"), QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error: system error: "), QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to sync block index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write file info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write to coin database"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write transaction index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write undo data"), QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: 0)"), QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: 0)"), @@ -231,6 +221,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'") QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: 50000)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), @@ -245,7 +236,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'" QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."), QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: 1)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4, IPv6 or Tor)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"), QT_TRANSLATE_NOOP("bitcoin-core", "Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: 1)"), @@ -282,7 +273,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)") QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "System error: "), QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."), diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index a527602b5..5c3abef2e 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -19,7 +19,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>Copy the currently selected address to the system clipboard</source> <translation>Copy the currently selected address to the system clipboard</translation> </message> @@ -29,7 +29,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+58"/> + <location line="+67"/> <source>C&lose</source> <translation type="unfinished"></translation> </message> @@ -39,12 +39,12 @@ <translation>&Copy Address</translation> </message> <message> - <location filename="../forms/addressbookpage.ui" line="-47"/> + <location filename="../forms/addressbookpage.ui" line="-53"/> <source>Delete the currently selected address from the list</source> <translation>Delete the currently selected address from the list</translation> </message> <message> - <location line="+27"/> + <location line="+30"/> <source>Export the data in the current tab to a file</source> <translation>Export the data in the current tab to a file</translation> </message> @@ -54,7 +54,7 @@ <translation>&Export</translation> </message> <message> - <location line="-27"/> + <location line="-30"/> <source>&Delete</source> <translation>&Delete</translation> </message> @@ -286,17 +286,17 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+300"/> + <location filename="../bitcoingui.cpp" line="+327"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> <message> - <location line="+339"/> + <location line="+348"/> <source>Synchronizing with network...</source> <translation>Synchronizing with network...</translation> </message> <message> - <location line="-411"/> + <location line="-420"/> <source>&Overview</source> <translation>&Overview</translation> </message> @@ -377,13 +377,13 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+168"/> + <location line="+175"/> <location line="+5"/> <source>Bitcoin Core client</source> <translation type="unfinished"></translation> </message> <message> - <location line="+156"/> + <location line="+158"/> <source>Importing blocks from disk...</source> <translation>Importing blocks from disk...</translation> </message> @@ -393,7 +393,7 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-409"/> + <location line="-418"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -428,12 +428,12 @@ <translation>&Verify message...</translation> </message> <message> - <location line="+437"/> + <location line="+446"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-655"/> + <location line="-664"/> <source>Wallet</source> <translation>Wallet</translation> </message> @@ -500,12 +500,12 @@ </message> <message> <location line="-289"/> - <location line="+386"/> + <location line="+393"/> <source>[testnet]</source> <translation>[testnet]</translation> </message> <message> - <location line="-411"/> + <location line="-418"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -546,7 +546,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+310"/> + <location line="+316"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -554,7 +554,7 @@ </translation> </message> <message> - <location line="+22"/> + <location line="+25"/> <source>No block source available...</source> <translation>No block source available...</translation> </message> @@ -665,7 +665,7 @@ Address: %4 </translation> </message> <message> - <location line="+69"/> + <location line="+68"/> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Wallet is <b>encrypted</b> and currently <b>unlocked</b></translation> </message> @@ -678,7 +678,7 @@ Address: %4 <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+138"/> + <location filename="../clientmodel.cpp" line="+139"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -736,7 +736,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Tree mode</source> <translation type="unfinished"></translation> </message> @@ -1059,7 +1059,7 @@ Address: %4 <context> <name>HelpMessageDialog</name> <message> - <location filename="../utilitydialog.cpp" line="+29"/> + <location filename="../utilitydialog.cpp" line="+31"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -1201,7 +1201,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Select payment request file</source> <translation type="unfinished"></translation> </message> @@ -1430,12 +1430,12 @@ Address: %4 <translation>&OK</translation> </message> <message> - <location line="+7"/> + <location line="+13"/> <source>&Cancel</source> <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+68"/> + <location filename="../optionsdialog.cpp" line="+71"/> <source>default</source> <translation>default</translation> </message> @@ -1479,23 +1479,18 @@ Address: %4 <translation>Form</translation> </message> <message> - <location line="+52"/> - <location line="+394"/> + <location line="+53"/> + <location line="+372"/> <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> <translation>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</translation> </message> <message> - <location line="-401"/> - <source>Wallet</source> - <translation>Wallet</translation> - </message> - <message> - <location line="+33"/> + <location line="-133"/> <source>Watch-only:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+10"/> <source>Available:</source> <translation type="unfinished"></translation> </message> @@ -1505,62 +1500,72 @@ Address: %4 <translation>Your current spendable balance</translation> </message> <message> - <location line="+16"/> + <location line="+41"/> <source>Pending:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+16"/> + <location line="-236"/> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> <translation>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</translation> </message> <message> - <location line="+16"/> + <location line="+112"/> <source>Immature:</source> <translation>Immature:</translation> </message> <message> - <location line="+16"/> + <location line="-29"/> <source>Mined balance that has not yet matured</source> <translation>Mined balance that has not yet matured</translation> </message> <message> - <location line="+23"/> + <location line="-163"/> + <source>Balances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+147"/> <source>Total:</source> <translation>Total:</translation> </message> <message> - <location line="+16"/> + <location line="+61"/> <source>Your current total balance</source> <translation>Your current total balance</translation> </message> <message> - <location line="+38"/> + <location line="+92"/> <source>Your current balance in watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+23"/> + <source>Spendable:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+49"/> + <source>Recent transactions</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-317"/> <source>Unconfirmed transactions to watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+50"/> <source>Mined balance in watch-only addresses that has not yet matured</source> <translation type="unfinished"></translation> </message> <message> - <location line="+44"/> + <location line="+128"/> <source>Current total balance in watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+67"/> - <source><b>Recent transactions</b></source> - <translation><b>Recent transactions</b></translation> - </message> - <message> - <location filename="../overviewpage.cpp" line="+123"/> + <location filename="../overviewpage.cpp" line="+131"/> <location line="+1"/> <source>out of sync</source> <translation>out of sync</translation> @@ -1569,7 +1574,7 @@ Address: %4 <context> <name>PaymentServer</name> <message> - <location filename="../paymentserver.cpp" line="+405"/> + <location filename="../paymentserver.cpp" line="+410"/> <location line="+14"/> <location line="+7"/> <source>URI handling</source> @@ -1681,7 +1686,7 @@ Address: %4 <context> <name>PeerTableModel</name> <message> - <location filename="../peertablemodel.cpp" line="+112"/> + <location filename="../peertablemodel.cpp" line="+118"/> <source>User Agent</source> <translation type="unfinished"></translation> </message> @@ -1699,17 +1704,17 @@ Address: %4 <context> <name>QObject</name> <message> - <location filename="../bitcoinunits.cpp" line="+200"/> + <location filename="../bitcoinunits.cpp" line="+196"/> <source>Amount</source> <translation type="unfinished">Amount</translation> </message> <message> - <location filename="../guiutil.cpp" line="+97"/> + <location filename="../guiutil.cpp" line="+106"/> <source>Enter a Bitcoin address (e.g. %1)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+673"/> + <location line="+698"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1795,7 +1800,7 @@ Address: %4 <location line="+23"/> <location line="+36"/> <location line="+23"/> - <location line="+462"/> + <location line="+465"/> <location line="+23"/> <location line="+23"/> <location line="+23"/> @@ -1813,7 +1818,7 @@ Address: %4 <translation>N/A</translation> </message> <message> - <location line="-987"/> + <location line="-990"/> <source>Client version</source> <translation>Client version</translation> </message> @@ -1873,7 +1878,7 @@ Address: %4 <translation>Current number of blocks</translation> </message> <message> - <location line="+300"/> + <location line="+303"/> <source>Received</source> <translation type="unfinished"></translation> </message> @@ -1889,7 +1894,7 @@ Address: %4 </message> <message> <location line="+39"/> - <location filename="../rpcconsole.cpp" line="+234"/> + <location filename="../rpcconsole.cpp" line="+236"/> <location line="+327"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> @@ -1965,7 +1970,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-761"/> + <location line="-764"/> <source>Last block time</source> <translation>Last block time</translation> </message> @@ -1990,7 +1995,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Totals</source> <translation type="unfinished"></translation> </message> @@ -2005,7 +2010,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location filename="../forms/rpcconsole.ui" line="-354"/> + <location filename="../forms/rpcconsole.ui" line="-357"/> <source>Build date</source> <translation>Build date</translation> </message> @@ -2163,12 +2168,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+78"/> + <location line="+75"/> <source>Requested payments history</source> <translation type="unfinished"></translation> </message> <message> - <location line="-98"/> + <location line="-95"/> <source>&Request payment</source> <translation type="unfinished"></translation> </message> @@ -2183,7 +2188,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+17"/> <source>Remove the selected entries from the list</source> <translation type="unfinished"></translation> </message> @@ -2221,12 +2226,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>Copy &Address</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>&Save Image...</source> <translation type="unfinished"></translation> </message> @@ -2279,7 +2284,7 @@ Address: %4 <context> <name>RecentRequestsTableModel</name> <message> - <location filename="../recentrequeststablemodel.cpp" line="+24"/> + <location filename="../recentrequeststablemodel.cpp" line="+26"/> <source>Date</source> <translation type="unfinished">Date</translation> </message> @@ -2333,7 +2338,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>automatically selected</source> <translation type="unfinished"></translation> </message> @@ -2398,22 +2403,22 @@ Address: %4 <translation>Add &Recipient</translation> </message> <message> - <location line="-23"/> + <location line="-20"/> <source>Clear all fields of the form.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-271"/> + <location line="-274"/> <source>Dust:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+274"/> + <location line="+277"/> <source>Clear &All</source> <translation>Clear &All</translation> </message> <message> - <location line="+58"/> + <location line="+55"/> <source>Balance:</source> <translation>Balance:</translation> </message> @@ -2653,7 +2658,7 @@ Address: %4 <context> <name>ShutdownWindow</name> <message> - <location filename="../utilitydialog.cpp" line="+51"/> + <location filename="../utilitydialog.cpp" line="+47"/> <source>Bitcoin Core is shutting down...</source> <translation type="unfinished"></translation> </message> @@ -2671,7 +2676,7 @@ Address: %4 <translation>Signatures - Sign / Verify a Message</translation> </message> <message> - <location line="+10"/> + <location line="+13"/> <source>&Sign Message</source> <translation>&Sign Message</translation> </message> @@ -2848,7 +2853,7 @@ Address: %4 <context> <name>SplashScreen</name> <message> - <location filename="../splashscreen.cpp" line="+32"/> + <location filename="../splashscreen.cpp" line="+34"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -2874,7 +2879,7 @@ Address: %4 <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+33"/> + <location filename="../transactiondesc.cpp" line="+34"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -3098,7 +3103,7 @@ Address: %4 <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+237"/> + <location filename="../transactiontablemodel.cpp" line="+235"/> <source>Date</source> <translation>Date</translation> </message> @@ -3166,7 +3171,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+51"/> + <location line="+48"/> <source>Received with</source> <translation>Received with</translation> </message> @@ -3191,12 +3196,17 @@ Address: %4 <translation>Mined</translation> </message> <message> - <location line="+41"/> + <location line="+28"/> + <source>watch-only</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+15"/> <source>(n/a)</source> <translation>(n/a)</translation> </message> <message> - <location line="+193"/> + <location line="+210"/> <source>Transaction status. Hover over this field to show number of confirmations.</source> <translation>Transaction status. Hover over this field to show number of confirmations.</translation> </message> @@ -3212,6 +3222,11 @@ Address: %4 </message> <message> <location line="+2"/> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Destination address of transaction.</source> <translation>Destination address of transaction.</translation> </message> @@ -3224,7 +3239,7 @@ Address: %4 <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+60"/> + <location filename="../transactionview.cpp" line="+67"/> <location line="+16"/> <source>All</source> <translation>All</translation> @@ -3325,12 +3340,17 @@ Address: %4 <translation>Show transaction details</translation> </message> <message> - <location line="+163"/> + <location line="+179"/> <source>Export Transaction History</source> <translation type="unfinished"></translation> </message> <message> - <location line="+19"/> + <location line="+12"/> + <source>Watch-only</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Exporting Failed</source> <translation type="unfinished"></translation> </message> @@ -3350,7 +3370,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-22"/> + <location line="-24"/> <source>Comma separated file (*.csv)</source> <translation>Comma separated file (*.csv)</translation> </message> @@ -3360,7 +3380,7 @@ Address: %4 <translation>Confirmed</translation> </message> <message> - <location line="+1"/> + <location line="+3"/> <source>Date</source> <translation>Date</translation> </message> @@ -3398,7 +3418,7 @@ Address: %4 <context> <name>UnitDisplayStatusBarControl</name> <message> - <location filename="../bitcoingui.cpp" line="+101"/> + <location filename="../bitcoingui.cpp" line="+103"/> <source>Unit to show amounts in. Click to select another unit.</source> <translation type="unfinished"></translation> </message> @@ -3465,7 +3485,7 @@ Address: %4 <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+249"/> + <location filename="../bitcoinstrings.cpp" line="+240"/> <source>Options:</source> <translation>Options:</translation> </message> @@ -3495,22 +3515,22 @@ Address: %4 <translation>Maintain at most <n> connections to peers (default: 125)</translation> </message> <message> - <location line="-62"/> + <location line="-53"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+103"/> + <location line="+94"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="+7"/> + <location line="+6"/> <source>Threshold for disconnecting misbehaving peers (default: 100)</source> <translation>Threshold for disconnecting misbehaving peers (default: 100)</translation> </message> <message> - <location line="-181"/> + <location line="-171"/> <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> <translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation> </message> @@ -3525,17 +3545,17 @@ Address: %4 <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="+99"/> + <location line="+90"/> <source>Run in the background as a daemon and accept commands</source> <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+36"/> + <location line="+35"/> <source>Use the test network</source> <translation>Use the test network</translation> </message> <message> - <location line="-134"/> + <location line="-124"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation> </message> @@ -3756,6 +3776,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+2"/> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -3766,65 +3791,10 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> - <source>Error: system error: </source> - <translation>Error: system error: </translation> - </message> - <message> - <location line="+1"/> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Failed to listen on any port. Use -listen=0 if you want this.</translation> </message> <message> - <location line="+1"/> - <source>Failed to read block info</source> - <translation>Failed to read block info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to read block</source> - <translation>Failed to read block</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to sync block index</source> - <translation>Failed to sync block index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block index</source> - <translation>Failed to write block index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block info</source> - <translation>Failed to write block info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block</source> - <translation>Failed to write block</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write file info</source> - <translation>Failed to write file info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write to coin database</source> - <translation>Failed to write to coin database</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write transaction index</source> - <translation>Failed to write transaction index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write undo data</source> - <translation>Failed to write undo data</translation> - </message> - <message> <location line="+2"/> <source>Force safe mode (default: 0)</source> <translation type="unfinished"></translation> @@ -3860,12 +3830,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+22"/> <source>Not enough file descriptors available.</source> <translation>Not enough file descriptors available.</translation> </message> <message> - <location line="+5"/> + <location line="+2"/> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Prepend debug output with timestamp (default: 1)</source> <translation type="unfinished"></translation> </message> @@ -3905,7 +3880,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>This is intended for regression testing tools and app development.</source> <translation type="unfinished"></translation> </message> @@ -3940,7 +3915,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Imports blocks from external blk000??.dat file</translation> </message> <message> - <location line="-195"/> + <location line="-185"/> <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> <translation type="unfinished"></translation> </message> @@ -4080,12 +4055,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+5"/> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+3"/> <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4131,6 +4106,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Limit size of signature cache to <n> entries (default: 50000)</source> <translation type="unfinished"></translation> </message> @@ -4170,12 +4150,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Only accept block chain matching built-in checkpoints (default: 1)</translation> </message> <message> - <location line="+1"/> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</translation> - </message> - <message> - <location line="+4"/> + <location line="+5"/> <source>Print block on startup, if found in block index</source> <translation type="unfinished"></translation> </message> @@ -4255,12 +4230,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Specify connection timeout in milliseconds (default: 5000)</translation> </message> <message> - <location line="+7"/> - <source>System error: </source> - <translation>System error: </translation> - </message> - <message> - <location line="+2"/> + <location line="+8"/> <source>This is experimental software.</source> <translation type="unfinished"></translation> </message> @@ -4340,22 +4310,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>wallet.dat corrupt, salvage failed</translation> </message> <message> - <location line="-64"/> + <location line="-63"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-164"/> + <location line="-155"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation> </message> <message> - <location line="+210"/> + <location line="+200"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> <message> - <location line="-27"/> + <location line="-26"/> <source>Set key pool size to <n> (default: 100)</source> <translation>Set key pool size to <n> (default: 100)</translation> </message> @@ -4365,12 +4335,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Rescan the block chain for missing wallet transactions</translation> </message> <message> - <location line="+36"/> + <location line="+35"/> <source>Use OpenSSL (https) for JSON-RPC connections</source> <translation>Use OpenSSL (https) for JSON-RPC connections</translation> </message> <message> - <location line="-31"/> + <location line="-30"/> <source>Server certificate file (default: server.cert)</source> <translation>Server certificate file (default: server.cert)</translation> </message> @@ -4380,22 +4350,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Server private key (default: server.pem)</translation> </message> <message> - <location line="+19"/> + <location line="+18"/> <source>This help message</source> <translation>This help message</translation> </message> <message> - <location line="-118"/> + <location line="-108"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+68"/> + <location line="+59"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> <message> - <location line="-42"/> + <location line="-33"/> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> @@ -4405,7 +4375,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Error loading wallet.dat</translation> </message> <message> - <location line="+33"/> + <location line="+23"/> <source>Invalid -proxy address: '%s'</source> <translation>Invalid -proxy address: '%s'</translation> </message> @@ -4415,7 +4385,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-122"/> + <location line="-112"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4425,7 +4395,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot resolve -externalip address: '%s'</translation> </message> <message> - <location line="+56"/> + <location line="+46"/> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Invalid amount for -paytxfee=<amount>: '%s'</translation> </message> @@ -4440,22 +4410,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Insufficient funds</translation> </message> <message> - <location line="+13"/> + <location line="+14"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-70"/> + <location line="-61"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation>Add a node to connect to and attempt to keep the connection open</translation> </message> <message> - <location line="+71"/> + <location line="+62"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-66"/> + <location line="-57"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -4465,22 +4435,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot write default address</translation> </message> <message> - <location line="+86"/> + <location line="+77"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-73"/> + <location line="-64"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+101"/> + <location line="+91"/> <source>To use the %s option</source> <translation>To use the %s option</translation> </message> <message> - <location line="-93"/> + <location line="-83"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index bd87d7770..23e647b17 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -110,6 +110,9 @@ Value getrawtransaction(const Array& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getrawtransaction \"txid\" ( verbose )\n" + "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n" + "or there is an unspent output in the utxo for this transaction. To make it always work,\n" + "you need to maintain a transaction index, using the -txindex command line option.\n" "\nReturn the raw transaction data.\n" "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n" "If verbose is non-zero, returns an Object with information about 'txid'.\n" @@ -202,7 +205,7 @@ Value listunspent(const Array& params, bool fHelp) "Results are an array of Objects, each of which has:\n" "{txid, vout, scriptPubKey, amount, confirmations}\n" "\nArguments:\n" - "1. minconf (numeric, optional, default=1) The minimum confirmationsi to filter\n" + "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" " [\n" @@ -687,7 +690,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) fComplete = false; } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index a71f55dd2..56140f19d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -9,14 +9,10 @@ #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha2.h" -#include "random.h" #include "script/script.h" #include "uint256.h" #include "util.h" -#include <boost/thread.hpp> -#include <boost/tuple/tuple_comparison.hpp> - using namespace std; typedef vector<unsigned char> valtype; @@ -132,7 +128,7 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { return true; } -bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags) +bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker) { CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); @@ -675,7 +671,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); + checker.CheckSig(vchSig, vchPubKey, scriptCode); popstack(stack); popstack(stack); @@ -736,7 +732,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Check signature bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); + checker.CheckSig(vchSig, vchPubKey, scriptCode); if (fOk) { isig++; @@ -897,7 +893,7 @@ public: } // anon namespace -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { if (nIn >= txTo.vin.size()) { LogPrintf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); @@ -921,70 +917,19 @@ uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsig return ss.GetHash(); } -// Valid signature cache, to avoid doing expensive ECDSA signature checking -// twice for every transaction (once when accepted into memory pool, and -// again when accepted into the block chain) -class CSignatureCache +bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const { -private: - // sigdata_type is (signature hash, signature, public key): - typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type; - std::set< sigdata_type> setValid; - boost::shared_mutex cs_sigcache; - -public: - bool - Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) - { - boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); - - sigdata_type k(hash, vchSig, pubKey); - std::set<sigdata_type>::iterator mi = setValid.find(k); - if (mi != setValid.end()) - return true; - return false; - } - - void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) - { - // DoS prevention: limit cache size to less than 10MB - // (~200 bytes per cache entry times 50,000 entries) - // Since there are a maximum of 20,000 signature operations per block - // 50,000 is a reasonable default. - int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); - if (nMaxCacheSize <= 0) return; - - boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); - - while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) - { - // Evict a random entry. Random because that helps - // foil would-be DoS attackers who might try to pre-generate - // and re-use a set of valid signatures just-slightly-greater - // than our cache size. - uint256 randomHash = GetRandHash(); - std::vector<unsigned char> unused; - std::set<sigdata_type>::iterator it = - setValid.lower_bound(sigdata_type(randomHash, unused, unused)); - if (it == setValid.end()) - it = setValid.begin(); - setValid.erase(*it); - } - - sigdata_type k(hash, vchSig, pubKey); - setValid.insert(k); - } -}; + return pubkey.Verify(sighash, vchSig); +} -bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int flags) +bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const { - static CSignatureCache signatureCache; - CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) return false; // Hash type is one byte tacked on to the end of the signature + vector<unsigned char> vchSig(vchSigIn); if (vchSig.empty()) return false; int nHashType = vchSig.back(); @@ -992,26 +937,20 @@ bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubK uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); - if (signatureCache.Get(sighash, vchSig, pubkey)) - return true; - - if (!pubkey.Verify(sighash, vchSig)) + if (!VerifySignature(vchSig, pubkey, sighash)) return false; - if (!(flags & SCRIPT_VERIFY_NOCACHE)) - signatureCache.Set(sighash, vchSig, pubkey); - return true; } -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags) +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker) { vector<vector<unsigned char> > stack, stackCopy; - if (!EvalScript(stack, scriptSig, txTo, nIn, flags)) + if (!EvalScript(stack, scriptSig, flags, checker)) return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags)) + if (!EvalScript(stack, scriptPubKey, flags, checker)) return false; if (stack.empty()) return false; @@ -1034,7 +973,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stackCopy); - if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags)) + if (!EvalScript(stackCopy, pubKey2, flags, checker)) return false; if (stackCopy.empty()) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index adca2142a..0ff73964b 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -10,6 +10,7 @@ #include <stdint.h> #include <string> +class CPubKey; class CScript; class CTransaction; class uint256; @@ -30,16 +31,40 @@ enum SCRIPT_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values (<n/2) in signatures (depends on STRICTENC) - SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it) - SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length + SCRIPT_VERIFY_NULLDUMMY = (1U << 3), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length }; bool IsCanonicalPubKey(const std::vector<unsigned char> &vchPubKey, unsigned int flags); bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int flags); uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); -bool CheckSig(std::vector<unsigned char> vchSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int flags); -bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags); + +class BaseSignatureChecker +{ +public: + virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const + { + return false; + } + + virtual ~BaseSignatureChecker() {} +}; + +class SignatureChecker : public BaseSignatureChecker +{ +private: + const CTransaction& txTo; + unsigned int nIn; + +protected: + virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; + +public: + SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} + bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const; +}; + +bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker); #endif // H_BITCOIN_SCRIPT_INTERPRETER diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp new file mode 100644 index 000000000..ab366898d --- /dev/null +++ b/src/script/sigcache.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "sigcache.h" + +#include "key.h" +#include "random.h" +#include "uint256.h" +#include "util.h" + +#include <boost/thread.hpp> +#include <boost/tuple/tuple_comparison.hpp> + +namespace { + +// Valid signature cache, to avoid doing expensive ECDSA signature checking +// twice for every transaction (once when accepted into memory pool, and +// again when accepted into the block chain) +class CSignatureCache +{ +private: + // sigdata_type is (signature hash, signature, public key): + typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type; + std::set< sigdata_type> setValid; + boost::shared_mutex cs_sigcache; + +public: + bool + Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + { + boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); + + sigdata_type k(hash, vchSig, pubKey); + std::set<sigdata_type>::iterator mi = setValid.find(k); + if (mi != setValid.end()) + return true; + return false; + } + + void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + { + // DoS prevention: limit cache size to less than 10MB + // (~200 bytes per cache entry times 50,000 entries) + // Since there are a maximum of 20,000 signature operations per block + // 50,000 is a reasonable default. + int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); + if (nMaxCacheSize <= 0) return; + + boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); + + while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) + { + // Evict a random entry. Random because that helps + // foil would-be DoS attackers who might try to pre-generate + // and re-use a set of valid signatures just-slightly-greater + // than our cache size. + uint256 randomHash = GetRandHash(); + std::vector<unsigned char> unused; + std::set<sigdata_type>::iterator it = + setValid.lower_bound(sigdata_type(randomHash, unused, unused)); + if (it == setValid.end()) + it = setValid.begin(); + setValid.erase(*it); + } + + sigdata_type k(hash, vchSig, pubKey); + setValid.insert(k); + } +}; + +} + +bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const +{ + static CSignatureCache signatureCache; + + if (signatureCache.Get(sighash, vchSig, pubkey)) + return true; + + if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash)) + return false; + + if (store) + signatureCache.Set(sighash, vchSig, pubkey); + return true; +} diff --git a/src/script/sigcache.h b/src/script/sigcache.h new file mode 100644 index 000000000..46b8f4d33 --- /dev/null +++ b/src/script/sigcache.h @@ -0,0 +1,26 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef H_BITCOIN_SCRIPT_SIGCACHE +#define H_BITCOIN_SCRIPT_SIGCACHE + +#include "script/interpreter.h" + +#include <vector> + +class CPubKey; + +class CachingSignatureChecker : public SignatureChecker +{ +private: + bool store; + +public: + CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {} + + bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; +}; + +#endif // H_BITCOIN_SCRIPT_SIGCACHE diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 8abd8d221..da77e7d1f 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS); + return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn)); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -174,7 +174,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0)) + if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) { sigs[pubkey] = sig; break; @@ -252,9 +252,9 @@ CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsign Solver(scriptPubKey, txType, vSolutions); vector<valtype> stack1; - EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); + EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); vector<valtype> stack2; - EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); + EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); } diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 407baf621..53ae254d5 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -203,7 +203,11 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) if (whichType == TX_PUBKEY) { - addressRet = CPubKey(vSolutions[0]).GetID(); + CPubKey pubKey(vSolutions[0]); + if (!pubKey.IsValid()) + return false; + + addressRet = pubKey.GetID(); return true; } else if (whichType == TX_PUBKEYHASH) @@ -237,9 +241,16 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto nRequiredRet = vSolutions.front()[0]; for (unsigned int i = 1; i < vSolutions.size()-1; i++) { - CTxDestination address = CPubKey(vSolutions[i]).GetID(); + CPubKey pubKey(vSolutions[i]); + if (!pubKey.IsValid()) + continue; + + CTxDestination address = pubKey.GetID(); addressRet.push_back(address); } + + if (addressRet.empty()) + return false; } else { diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index cb3774006..5a2ec1cb3 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -82,19 +82,19 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.clear(); keys += key[0],key[1]; // magic operator+= from boost.assign s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, flags)); + BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0))); for (int i = 0; i < 4; i++) { keys.clear(); keys += key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0)), strprintf("a&b 1: %d", i)); keys.clear(); keys += key[1],key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0)), strprintf("a&b 2: %d", i)); } // Test a OR b: @@ -104,16 +104,16 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i]; s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)), strprintf("a|b: %d", i)); else - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)), strprintf("a|b: %d", i)); } s.clear(); s << OP_0 << OP_0; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0))); s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0))); for (int i = 0; i < 4; i++) @@ -123,9 +123,9 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i],key[j]; s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0)), strprintf("escrow 1: %d %d", i, j)); else - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0)), strprintf("escrow 2: %d %d", i, j)); } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index e6cf00c2d..6c32a263a 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); + return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0)); } @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(sign) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC)(); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 48a5635d8..6ed3e03f5 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -89,7 +89,7 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) { - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0, flags) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0)) == expect, message); } namespace @@ -464,18 +464,18 @@ BOOST_AUTO_TEST_CASE(script_PushData) static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; vector<vector<unsigned char> > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker())); vector<vector<unsigned char> > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker())); BOOST_CHECK(pushdata1Stack == directStack); vector<vector<unsigned char> > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker())); BOOST_CHECK(pushdata2Stack == directStack); vector<vector<unsigned char> > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker())); BOOST_CHECK(pushdata4Stack == directStack); } @@ -525,15 +525,15 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0))); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0))); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0))); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0))); } BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) @@ -553,46 +553,46 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector<CKey> keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0))); } BOOST_AUTO_TEST_CASE(script_combineSigs) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 83116b51e..823afa168 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -27,7 +27,6 @@ using namespace boost::algorithm; // In script_tests.cpp extern Array read_json(const std::string& jsondata); -// Note how NOCACHE is not included as it is a runtime-only flag. static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) @@ -139,7 +138,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags), + verify_flags, SignatureChecker(tx, i)), strTest); } } @@ -212,7 +211,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags); + verify_flags, SignatureChecker(tx, i)); } BOOST_CHECK_MESSAGE(!fValid, strTest); |