diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/addrman.h | 2 | ||||
-rw-r--r-- | src/base58.cpp | 8 | ||||
-rw-r--r-- | src/base58.h | 1 | ||||
-rw-r--r-- | src/bitcoin-tx.cpp | 6 | ||||
-rw-r--r-- | src/chainparams.cpp | 19 | ||||
-rw-r--r-- | src/chainparams.h | 3 | ||||
-rw-r--r-- | src/coins.cpp | 38 | ||||
-rw-r--r-- | src/coins.h | 8 | ||||
-rw-r--r-- | src/main.cpp | 34 | ||||
-rw-r--r-- | src/miner.cpp | 7 | ||||
-rw-r--r-- | src/net.cpp | 2 | ||||
-rw-r--r-- | src/netbase.cpp | 2 | ||||
-rw-r--r-- | src/qt/bitcoinunits.cpp | 5 | ||||
-rw-r--r-- | src/qt/coincontroldialog.cpp | 4 | ||||
-rw-r--r-- | src/qt/paymentserver.cpp | 8 | ||||
-rw-r--r-- | src/qt/walletmodel.cpp | 2 | ||||
-rw-r--r-- | src/rpcmisc.cpp | 4 | ||||
-rw-r--r-- | src/rpcrawtransaction.cpp | 12 | ||||
-rw-r--r-- | src/test/multisig_tests.cpp | 13 | ||||
-rw-r--r-- | src/test/script_P2SH_tests.cpp | 9 | ||||
-rw-r--r-- | src/txmempool.cpp | 6 | ||||
-rw-r--r-- | src/wallet.cpp | 37 | ||||
-rw-r--r-- | src/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet_ismine.cpp (renamed from src/scriptutils.cpp) | 38 | ||||
-rw-r--r-- | src/wallet_ismine.h (renamed from src/scriptutils.h) | 5 |
26 files changed, 152 insertions, 127 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9b7e99861d..b2071f49e2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -103,7 +103,7 @@ BITCOIN_CORE_H = \ script/script.h \ script/sign.h \ script/standard.h \ - scriptutils.h \ + wallet_ismine.h \ serialize.h \ sync.h \ threadsafety.h \ @@ -173,6 +173,7 @@ libbitcoin_wallet_a_SOURCES = \ crypter.cpp \ rpcdump.cpp \ rpcwallet.cpp \ + wallet_ismine.cpp \ wallet.cpp \ walletdb.cpp \ $(BITCOIN_CORE_H) @@ -216,7 +217,6 @@ libbitcoin_common_a_SOURCES = \ script/script.cpp \ script/sign.cpp \ script/standard.cpp \ - scriptutils.cpp \ $(BITCOIN_CORE_H) # util: shared between all executables. diff --git a/src/addrman.h b/src/addrman.h index 90507cb458..5fd698f18a 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -424,7 +424,7 @@ public: Check(); } if (fRet) - LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString(), nTried, nNew); + LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew); return fRet; } diff --git a/src/base58.cpp b/src/base58.cpp index c9e91beef1..76f0404a18 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -215,9 +215,13 @@ bool CBitcoinAddress::Set(const CTxDestination &dest) { } bool CBitcoinAddress::IsValid() const { + return IsValid(Params()); +} + +bool CBitcoinAddress::IsValid(const CChainParams ¶ms) const { bool fCorrectSize = vchData.size() == 20; - bool fKnownVersion = vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) || - vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); + bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) || + vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); return fCorrectSize && fKnownVersion; } diff --git a/src/base58.h b/src/base58.h index 216aca3648..15bf710f5e 100644 --- a/src/base58.h +++ b/src/base58.h @@ -104,6 +104,7 @@ public: bool Set(const CScriptID &id); bool Set(const CTxDestination &dest); bool IsValid() const; + bool IsValid(const CChainParams ¶ms) const; CBitcoinAddress() {} CBitcoinAddress(const CTxDestination &dest) { Set(dest); } diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index c455351411..91525b51c9 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -420,12 +420,12 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; - CCoins coins; - if (!view.GetCoins(txin.prevout.hash, coins) || !coins.IsAvailable(txin.prevout.n)) { + const CCoins* coins = view.AccessCoins(txin.prevout.hash); + if (!coins || !coins->IsAvailable(txin.prevout.n)) { fComplete = false; continue; } - const CScript& prevPubKey = coins.vout[txin.prevout.n].scriptPubKey; + const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; txin.scriptSig.clear(); // Only sign SIGHASH_SINGLE if there's a corresponding output: diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 460fabc6e6..179db5a818 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -221,24 +221,25 @@ const CChainParams &Params() { return *pCurrentParams; } -void SelectParams(CBaseChainParams::Network network) { - SelectBaseParams(network); +CChainParams &Params(CBaseChainParams::Network network) { switch (network) { case CBaseChainParams::MAIN: - pCurrentParams = &mainParams; - break; + return mainParams; case CBaseChainParams::TESTNET: - pCurrentParams = &testNetParams; - break; + return testNetParams; case CBaseChainParams::REGTEST: - pCurrentParams = ®TestParams; - break; + return regTestParams; default: assert(false && "Unimplemented network"); - return; + return mainParams; } } +void SelectParams(CBaseChainParams::Network network) { + SelectBaseParams(network); + pCurrentParams = &Params(network); +} + bool SelectParamsFromCommandLine() { if (!SelectBaseParamsFromCommandLine()) return false; diff --git a/src/chainparams.h b/src/chainparams.h index 95b972bd7f..e5dfc87c6d 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -111,6 +111,9 @@ protected: */ const CChainParams &Params(); +/** Return parameters for the given network. */ +CChainParams &Params(CBaseChainParams::Network network); + /** Sets the params returned by Params() to those for the given network. */ void SelectParams(CBaseChainParams::Network network); diff --git a/src/coins.cpp b/src/coins.cpp index 7bfb84ef3e..34485db2bd 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -110,9 +110,13 @@ CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { return it->second; } -const CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) const { - /* Avoid redundant implementation with the const-cast. */ - return const_cast<CCoinsViewCache*>(this)->GetCoins(txid); +const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { + CCoinsMap::const_iterator it = FetchCoins(txid); + if (it == cacheCoins.end()) { + return NULL; + } else { + return &it->second; + } } bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) { @@ -162,9 +166,9 @@ unsigned int CCoinsViewCache::GetCacheSize() const { const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const { - const CCoins &coins = GetCoins(input.prevout.hash); - assert(coins.IsAvailable(input.prevout.n)); - return coins.vout[input.prevout.n]; + const CCoins* coins = AccessCoins(input.prevout.hash); + assert(coins && coins->IsAvailable(input.prevout.n)); + return coins->vout[input.prevout.n]; } int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const @@ -182,19 +186,12 @@ int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const { if (!tx.IsCoinBase()) { - // first check whether information about the prevout hash is available for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; - if (!HaveCoins(prevout.hash)) - return false; - } - - // then check whether the actual outputs are available - for (unsigned int i = 0; i < tx.vin.size(); i++) { - const COutPoint &prevout = tx.vin[i].prevout; - const CCoins &coins = GetCoins(prevout.hash); - if (!coins.IsAvailable(prevout.n)) + const CCoins* coins = AccessCoins(prevout.hash); + if (!coins || !coins->IsAvailable(prevout.n)) { return false; + } } } return true; @@ -207,10 +204,11 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const double dResult = 0.0; BOOST_FOREACH(const CTxIn& txin, tx.vin) { - const CCoins &coins = GetCoins(txin.prevout.hash); - if (!coins.IsAvailable(txin.prevout.n)) continue; - if (coins.nHeight < nHeight) { - dResult += coins.vout[txin.prevout.n].nValue * (nHeight-coins.nHeight); + const CCoins* coins = AccessCoins(txin.prevout.hash); + assert(coins); + if (!coins->IsAvailable(txin.prevout.n)) continue; + if (coins->nHeight < nHeight) { + dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); } } return tx.ComputePriority(dResult); diff --git a/src/coins.h b/src/coins.h index d338e3172e..c25393f1e0 100644 --- a/src/coins.h +++ b/src/coins.h @@ -344,11 +344,13 @@ public: bool SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); + // Return a pointer to CCoins in the cache, or NULL if not found. This is + // more efficient than GetCoins. Modifications to other cache entries are + // allowed while accessing the returned pointer. + const CCoins* AccessCoins(const uint256 &txid) const; + // Return a modifiable reference to a CCoins. Check HaveCoins first. - // Many methods explicitly require a CCoinsViewCache because of this method, to reduce - // copying. CCoins &GetCoins(const uint256 &txid); - const CCoins &GetCoins(const uint256 &txid) const; // Push the modifications applied to this cache to its base. // Failure to call this method before destruction will cause the changes to be forgotten. diff --git a/src/main.cpp b/src/main.cpp index 21a352f7ba..f063a48fe5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1018,9 +1018,9 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock int nHeight = -1; { CCoinsViewCache &view = *pcoinsTip; - CCoins coins; - if (view.GetCoins(hash, coins)) - nHeight = coins.nHeight; + const CCoins* coins = view.AccessCoins(hash); + if (coins) + nHeight = coins->nHeight; } if (nHeight > 0) pindexSlow = chainActive[nHeight]; @@ -1372,19 +1372,20 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; - const CCoins &coins = inputs.GetCoins(prevout.hash); + const CCoins *coins = inputs.AccessCoins(prevout.hash); + assert(coins); // If prev is coinbase, check that it's matured - if (coins.IsCoinBase()) { - if (nSpendHeight - coins.nHeight < COINBASE_MATURITY) + if (coins->IsCoinBase()) { + if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) return state.Invalid( - error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins.nHeight), + error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); } // Check for negative or overflow input values - nValueIn += coins.vout[prevout.n].nValue; - if (!MoneyRange(coins.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + nValueIn += coins->vout[prevout.n].nValue; + if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn)) return state.DoS(100, error("CheckInputs() : txin values out of range"), REJECT_INVALID, "bad-txns-inputvalues-outofrange"); @@ -1414,10 +1415,11 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; - const CCoins &coins = inputs.GetCoins(prevout.hash); + const CCoins* coins = inputs.AccessCoins(prevout.hash); + assert(coins); // Verify signature - CScriptCheck check(coins, tx, i, flags, 0); + CScriptCheck check(*coins, tx, i, flags, 0); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1429,7 +1431,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(coins, tx, i, + CScriptCheck check(*coins, tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, 0); if (check()) return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); @@ -1615,8 +1617,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); if (fEnforceBIP30) { BOOST_FOREACH(const CTransaction& tx, block.vtx) { - const uint256& hash = tx.GetHash(); - if (view.HaveCoins(hash) && !view.GetCoins(hash).IsPruned()) + const CCoins* coins = view.AccessCoins(tx.GetHash()); + if (coins && !coins->IsPruned()) return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"), REJECT_INVALID, "bad-txns-BIP30"); } @@ -4400,7 +4402,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (!pto->fDisconnect && state.nBlocksInFlight && state.nLastBlockReceive < state.nLastBlockProcess - BLOCK_DOWNLOAD_TIMEOUT*1000000 && state.vBlocksInFlight.front().nTime < state.nLastBlockProcess - 2*BLOCK_DOWNLOAD_TIMEOUT*1000000) { - LogPrintf("Peer %s is stalling block download, disconnecting\n", state.name.c_str()); + LogPrintf("Peer %s is stalling block download, disconnecting\n", state.name); pto->fDisconnect = true; } @@ -4510,7 +4512,7 @@ bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock } std::string CBlockFileInfo::ToString() const { - return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst).c_str(), DateTimeStrFormat("%Y-%m-%d", nTimeLast).c_str()); + return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } diff --git a/src/miner.cpp b/src/miner.cpp index 96dc80a26d..d05ddbeb1f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -167,12 +167,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue; continue; } - const CCoins &coins = view.GetCoins(txin.prevout.hash); + const CCoins* coins = view.AccessCoins(txin.prevout.hash); + assert(coins); - int64_t nValueIn = coins.vout[txin.prevout.n].nValue; + int64_t nValueIn = coins->vout[txin.prevout.n].nValue; nTotalIn += nValueIn; - int nConf = pindexPrev->nHeight - coins.nHeight + 1; + int nConf = pindexPrev->nHeight - coins->nHeight + 1; dPriority += (double)nValueIn * nConf; } diff --git a/src/net.cpp b/src/net.cpp index 6b7e62d7cb..b18944a264 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2116,7 +2116,7 @@ void CNode::AskFor(const CInv& inv) nRequestTime = it->second; else nRequestTime = 0; - LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str(), id); + LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id); // Make sure not to reuse time indexes to keep things in the same order int64_t nNow = GetTimeMicros() - 1000000; diff --git a/src/netbase.cpp b/src/netbase.cpp index d5821d4465..954c11f77d 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -259,7 +259,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket) strSocks5 += strDest; strSocks5 += static_cast<char>((port >> 8) & 0xFF); strSocks5 += static_cast<char>((port >> 0) & 0xFF); - ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL); + ret = send(hSocket, strSocks5.data(), strSocks5.size(), MSG_NOSIGNAL); if (ret != (ssize_t)strSocks5.size()) { CloseSocket(hSocket); diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 6f506d3f25..3215363fa0 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -115,11 +115,6 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle sepa for (int i = 3; i < q_size; i += 3) quotient_str.insert(q_size - i, thin_sp); - int r_size = remainder_str.size(); - if (separators == separatorAlways || (separators == separatorStandard && r_size > 4)) - for (int i = 3, adj = 0; i < r_size ; i += 3, adj++) - remainder_str.insert(i + adj, thin_sp); - if (n < 0) quotient_str.insert(0, '-'); else if (fPlus && n > 0) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 7b30f8de09..d10463fd8f 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -705,7 +705,7 @@ void CoinControlDialog::updateView() QString sAddress = ""; if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) { - sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); + sAddress = QString::fromStdString(CBitcoinAddress(outputAddress).ToString()); // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs if (!treeMode || (!(sAddress == sWalletAddress))) @@ -752,7 +752,7 @@ void CoinControlDialog::updateView() // transaction hash uint256 txhash = out.tx->GetHash(); - itemOutput->setText(COLUMN_TXHASH, txhash.GetHex().c_str()); + itemOutput->setText(COLUMN_TXHASH, QString::fromStdString(txhash.GetHex())); // vout index itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i)); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index f6a4b599de..219a685faf 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -10,6 +10,7 @@ #include "optionsmodel.h" #include "base58.h" +#include "chainparams.h" #include "ui_interface.h" #include "util.h" #include "wallet.h" @@ -200,8 +201,11 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { CBitcoinAddress address(r.address.toStdString()); - SelectParams(CBaseChainParams::MAIN); - if (!address.IsValid()) + if (address.IsValid(Params(CBaseChainParams::MAIN))) + { + SelectParams(CBaseChainParams::MAIN); + } + else if (address.IsValid(Params(CBaseChainParams::TESTNET))) { SelectParams(CBaseChainParams::TESTNET); } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 530c46cdb4..8d2c2e96d8 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -622,7 +622,7 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) CTxDestination address; if(!out.fSpendable || !ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) continue; - mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + mapCoins[QString::fromStdString(CBitcoinAddress(address).ToString())].push_back(out); } } diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index bd992397b8..917c840536 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -74,8 +74,8 @@ Value getinfo(const Array& params, bool fHelp) GetProxy(NET_IPV4, proxy); Object obj; - obj.push_back(Pair("version", (int)CLIENT_VERSION)); - obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); + obj.push_back(Pair("version", CLIENT_VERSION)); + obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); #ifdef ENABLE_WALLET if (pwalletMain) { obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b5551524be..c5c99870fc 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -568,7 +568,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) { const uint256& prevHash = txin.prevout.hash; CCoins coins; - view.GetCoins(prevHash, coins); // this is certainly allowed to fail + view.AccessCoins(prevHash); // this is certainly allowed to fail } view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long @@ -672,12 +672,12 @@ Value signrawtransaction(const Array& params, bool fHelp) // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; - CCoins coins; - if (!view.GetCoins(txin.prevout.hash, coins) || !coins.IsAvailable(txin.prevout.n)) { + const CCoins* coins = view.AccessCoins(txin.prevout.hash); + if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { fComplete = false; continue; } - const CScript& prevPubKey = coins.vout[txin.prevout.n].scriptPubKey; + const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; txin.scriptSig.clear(); // Only sign SIGHASH_SINGLE if there's a corresponding output: @@ -735,9 +735,9 @@ Value sendrawtransaction(const Array& params, bool fHelp) fOverrideFees = params[1].get_bool(); CCoinsViewCache &view = *pcoinsTip; - CCoins existingCoins; + const CCoins* existingCoins = view.AccessCoins(hashTx); bool fHaveMempool = mempool.exists(hashTx); - bool fHaveChain = view.GetCoins(hashTx, existingCoins) && existingCoins.nHeight < 1000000000; + bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000; if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 6c5afa130c..91dfa39505 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -8,9 +8,12 @@ #include "script/script.h" #include "script/interpreter.h" #include "script/sign.h" -#include "scriptutils.h" #include "uint256.h" +#ifdef ENABLE_WALLET +#include "wallet_ismine.h" +#endif + #include <boost/assign/std/vector.hpp> #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> @@ -195,8 +198,10 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); +#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); +#endif } { vector<valtype> solutions; @@ -208,8 +213,10 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); +#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); +#endif } { vector<valtype> solutions; @@ -220,9 +227,11 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK_EQUAL(solutions.size(), 4U); CTxDestination addr; BOOST_CHECK(!ExtractDestination(s, addr)); +#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); +#endif } { vector<valtype> solutions; @@ -237,9 +246,11 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(addrs[0] == keyaddr[0]); BOOST_CHECK(addrs[1] == keyaddr[1]); BOOST_CHECK(nRequired == 1); +#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); +#endif } { vector<valtype> solutions; diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index b7e7487bb2..f99002017f 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -7,7 +7,10 @@ #include "main.h" #include "script/script.h" #include "script/sign.h" -#include "scriptutils.h" + +#ifdef ENABLE_WALLET +#include "wallet_ismine.h" +#endif #include <vector> @@ -95,7 +98,9 @@ BOOST_AUTO_TEST_CASE(sign) txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1; +#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); +#endif } for (int i = 0; i < 8; i++) { @@ -189,7 +194,9 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].scriptPubKey = inner[i]; +#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); +#endif } for (int i = 0; i < 4; i++) { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 238d5bab16..6bbadc8345 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -509,8 +509,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const const CTransaction& tx2 = it2->second.GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); } else { - const CCoins &coins = pcoins->GetCoins(txin.prevout.hash); - assert(coins.IsAvailable(txin.prevout.n)); + const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); + assert(coins && coins->IsAvailable(txin.prevout.n)); } // Check whether its inputs are marked in mapNextTx. std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout); @@ -606,7 +606,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, deltas.first += dPriorityDelta; deltas.second += nFeeDelta; } - LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash.c_str(), dPriorityDelta, nFeeDelta); + LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, nFeeDelta); } void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta) diff --git a/src/wallet.cpp b/src/wallet.cpp index b69ed223b4..52660be9a0 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -44,7 +44,7 @@ struct CompareValueOnly std::string COutput::ToString() const { - return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); + return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue)); } const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const @@ -2086,6 +2086,39 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) } } + +class CAffectedKeysVisitor : public boost::static_visitor<void> { +private: + const CKeyStore &keystore; + std::vector<CKeyID> &vKeys; + +public: + CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {} + + void Process(const CScript &script) { + txnouttype type; + std::vector<CTxDestination> vDest; + int nRequired; + if (ExtractDestinations(script, type, vDest, nRequired)) { + BOOST_FOREACH(const CTxDestination &dest, vDest) + boost::apply_visitor(*this, dest); + } + } + + void operator()(const CKeyID &keyId) { + if (keystore.HaveKey(keyId)) + vKeys.push_back(keyId); + } + + void operator()(const CScriptID &scriptId) { + CScript script; + if (keystore.GetCScript(scriptId, script)) + Process(script); + } + + void operator()(const CNoDestination &none) {} +}; + void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { AssertLockHeld(cs_wallet); // mapKeyMetadata mapKeyBirth.clear(); @@ -2121,7 +2154,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { int nHeight = blit->second->nHeight; BOOST_FOREACH(const CTxOut &txout, wtx.vout) { // iterate over all their outputs - ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected); + CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); BOOST_FOREACH(const CKeyID &keyid, vAffected) { // ... and all their affected keys std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid); diff --git a/src/wallet.h b/src/wallet.h index 6788986f88..5c26186730 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -11,7 +11,7 @@ #include "key.h" #include "keystore.h" #include "main.h" -#include "scriptutils.h" +#include "wallet_ismine.h" #include "ui_interface.h" #include "walletdb.h" diff --git a/src/scriptutils.cpp b/src/wallet_ismine.cpp index a636eeedab..1c2c117fad 100644 --- a/src/scriptutils.cpp +++ b/src/wallet_ismine.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "scriptutils.h" +#include "wallet_ismine.h" #include "key.h" #include "keystore.h" @@ -89,39 +89,3 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) return ISMINE_WATCH_ONLY; return ISMINE_NO; } - -class CAffectedKeysVisitor : public boost::static_visitor<void> { -private: - const CKeyStore &keystore; - std::vector<CKeyID> &vKeys; - -public: - CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {} - - void Process(const CScript &script) { - txnouttype type; - std::vector<CTxDestination> vDest; - int nRequired; - if (ExtractDestinations(script, type, vDest, nRequired)) { - BOOST_FOREACH(const CTxDestination &dest, vDest) - boost::apply_visitor(*this, dest); - } - } - - void operator()(const CKeyID &keyId) { - if (keystore.HaveKey(keyId)) - vKeys.push_back(keyId); - } - - void operator()(const CScriptID &scriptId) { - CScript script; - if (keystore.GetCScript(scriptId, script)) - Process(script); - } - - void operator()(const CNoDestination &none) {} -}; - -void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys) { - CAffectedKeysVisitor(keystore, vKeys).Process(scriptPubKey); -} diff --git a/src/scriptutils.h b/src/wallet_ismine.h index 98080fc456..9915e9f7bb 100644 --- a/src/scriptutils.h +++ b/src/wallet_ismine.h @@ -3,8 +3,8 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPTUTILS -#define H_BITCOIN_SCRIPTUTILS +#ifndef H_BITCOIN_WALLET_ISMINE +#define H_BITCOIN_WALLET_ISMINE #include "key.h" #include "script/script.h" @@ -24,6 +24,5 @@ typedef uint8_t isminefilter; isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); -void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys); #endif // H_BITCOIN_SCRIPT |