diff options
Diffstat (limited to 'src/wallet.cpp')
| -rw-r--r-- | src/wallet.cpp | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp index f7efeaec4..e69f59aac 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -9,6 +9,8 @@ #include "checkpoints.h" #include "coincontrol.h" #include "net.h" +#include "script/script.h" +#include "script/sign.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" @@ -42,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 @@ -637,7 +639,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl { { AssertLockHeld(cs_wallet); - bool fExisted = mapWallet.count(tx.GetHash()); + bool fExisted = mapWallet.count(tx.GetHash()) != 0; if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) { @@ -1129,7 +1131,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 && (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) - vCoins.push_back(COutput(pcoin, i, nDepth, mine & ISMINE_SPENDABLE)); + vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO)); } } } @@ -1383,7 +1385,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, // coin control: send change to custom address if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange)) - scriptChange.SetDestination(coinControl->destChange); + scriptChange = GetScriptForDestination(coinControl->destChange); // no coin control: send change to newly generated address else @@ -1401,7 +1403,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, ret = reservekey.GetReservedKey(vchPubKey); assert(ret); // should never fail, as we just unlocked - scriptChange.SetDestination(vchPubKey.GetID()); + scriptChange = GetScriptForDestination(vchPubKey.GetID()); } CTxOut newTxOut(nChange, scriptChange); @@ -1554,8 +1556,7 @@ string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWallet } // Parse Bitcoin address - CScript scriptPubKey; - scriptPubKey.SetDestination(address); + CScript scriptPubKey = GetScriptForDestination(address); // Create and send the transaction CReserveKey reservekey(this); @@ -1655,7 +1656,7 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam if (!strPurpose.empty()) /* update purpose only if requested */ mapAddressBook[address].purpose = strPurpose; } - NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), + NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO, strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) ); if (!fFileBacked) return false; @@ -1681,7 +1682,7 @@ bool CWallet::DelAddressBook(const CTxDestination& address) mapAddressBook.erase(address); } - NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED); + NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED); if (!fFileBacked) return false; @@ -2084,6 +2085,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(); @@ -2113,13 +2147,13 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { // iterate over all wallet transactions... const CWalletTx &wtx = (*it).second; - std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); + BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { // ... which are already in a block 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); @@ -2219,7 +2253,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) vMerkleBranch = block.GetMerkleBranch(nIndex); // Is the tx in a block that's in the main chain - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; const CBlockIndex* pindex = (*mi).second; @@ -2236,7 +2270,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const AssertLockHeld(cs_main); // Find the block it claims to be in - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; CBlockIndex* pindex = (*mi).second; |