Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show All 17 Lines | |||||
#include <key_io.h> | #include <key_io.h> | ||||
#include <keystore.h> | #include <keystore.h> | ||||
#include <policy/mempool.h> | #include <policy/mempool.h> | ||||
#include <policy/policy.h> | #include <policy/policy.h> | ||||
#include <policy/settings.h> | #include <policy/settings.h> | ||||
#include <primitives/block.h> | #include <primitives/block.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <script/descriptor.h> | |||||
#include <script/script.h> | #include <script/script.h> | ||||
#include <script/sighashtype.h> | #include <script/sighashtype.h> | ||||
#include <script/sign.h> | #include <script/sign.h> | ||||
#include <ui_interface.h> | #include <ui_interface.h> | ||||
#include <util/bip32.h> | #include <util/bip32.h> | ||||
#include <util/error.h> | #include <util/error.h> | ||||
#include <util/moneystr.h> | #include <util/moneystr.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | |||||
* @{ | * @{ | ||||
*/ | */ | ||||
std::string COutput::ToString() const { | std::string COutput::ToString() const { | ||||
return strprintf("COutput(%s, %d, %d) [%s]", tx->GetId().ToString(), i, | return strprintf("COutput(%s, %d, %d) [%s]", tx->GetId().ToString(), i, | ||||
nDepth, FormatMoney(tx->tx->vout[i].nValue)); | nDepth, FormatMoney(tx->tx->vout[i].nValue)); | ||||
} | } | ||||
class CAffectedKeysVisitor : public boost::static_visitor<void> { | std::vector<CKeyID> GetAffectedKeys(const CScript &spk, | ||||
private: | const SigningProvider &provider) { | ||||
const CKeyStore &keystore; | std::vector<CScript> dummy; | ||||
std::vector<CKeyID> &vKeys; | FlatSigningProvider out; | ||||
InferDescriptor(spk, provider) | |||||
public: | ->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out); | ||||
CAffectedKeysVisitor(const CKeyStore &keystoreIn, | std::vector<CKeyID> ret; | ||||
std::vector<CKeyID> &vKeysIn) | for (const auto &entry : out.pubkeys) { | ||||
: keystore(keystoreIn), vKeys(vKeysIn) {} | ret.push_back(entry.first); | ||||
void Process(const CScript &script) { | |||||
txnouttype type; | |||||
std::vector<CTxDestination> vDest; | |||||
int nRequired; | |||||
if (ExtractDestinations(script, type, vDest, nRequired)) { | |||||
for (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); | |||||
} | } | ||||
return ret; | |||||
} | } | ||||
void operator()(const CNoDestination &none) {} | |||||
}; | |||||
const CWalletTx *CWallet::GetWalletTx(const TxId &txid) const { | const CWalletTx *CWallet::GetWalletTx(const TxId &txid) const { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid); | std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid); | ||||
if (it == mapWallet.end()) { | if (it == mapWallet.end()) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
return &(it->second); | return &(it->second); | ||||
▲ Show 20 Lines • Show All 953 Lines • ▼ Show 20 Lines | if (fExisted || IsMine(tx) || IsFromMe(tx)) { | ||||
* that does not contain the mostly recently created transactions from | * that does not contain the mostly recently created transactions from | ||||
* newer versions of the wallet. | * newer versions of the wallet. | ||||
*/ | */ | ||||
// loop though all outputs | // loop though all outputs | ||||
for (const CTxOut &txout : tx.vout) { | for (const CTxOut &txout : tx.vout) { | ||||
// extract addresses and check if they match with an unused keypool | // extract addresses and check if they match with an unused keypool | ||||
// key | // key | ||||
std::vector<CKeyID> vAffected; | for (const auto &keyid : | ||||
CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); | GetAffectedKeys(txout.scriptPubKey, *this)) { | ||||
for (const CKeyID &keyid : vAffected) { | |||||
std::map<CKeyID, int64_t>::const_iterator mi = | std::map<CKeyID, int64_t>::const_iterator mi = | ||||
m_pool_key_to_index.find(keyid); | m_pool_key_to_index.find(keyid); | ||||
if (mi != m_pool_key_to_index.end()) { | if (mi != m_pool_key_to_index.end()) { | ||||
WalletLogPrintf("%s: Detected a used keypool key, mark all " | WalletLogPrintf("%s: Detected a used keypool key, mark all " | ||||
"keypool key up to this key as used\n", | "keypool key up to this key as used\n", | ||||
__func__); | __func__); | ||||
MarkReserveKeysAsUsed(mi->second); | MarkReserveKeysAsUsed(mi->second); | ||||
▲ Show 20 Lines • Show All 3,078 Lines • ▼ Show 20 Lines | void CWallet::GetKeyBirthTimes( | ||||
} | } | ||||
// If there are no such keys, we're done. | // If there are no such keys, we're done. | ||||
if (mapKeyFirstBlock.empty()) { | if (mapKeyFirstBlock.empty()) { | ||||
return; | return; | ||||
} | } | ||||
// Find first block that affects those keys, if there are any left. | // Find first block that affects those keys, if there are any left. | ||||
std::vector<CKeyID> vAffected; | |||||
for (const auto &entry : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
// iterate over all wallet transactions... | // iterate over all wallet transactions... | ||||
const CWalletTx &wtx = entry.second; | const CWalletTx &wtx = entry.second; | ||||
if (Optional<int> height = locked_chain.getBlockHeight(wtx.hashBlock)) { | if (Optional<int> height = locked_chain.getBlockHeight(wtx.hashBlock)) { | ||||
// ... which are already in a block | // ... which are already in a block | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
// Iterate over all their outputs... | // Iterate over all their outputs... | ||||
CAffectedKeysVisitor(*this, vAffected) | for (const auto &keyid : | ||||
.Process(txout.scriptPubKey); | GetAffectedKeys(txout.scriptPubKey, *this)) { | ||||
for (const CKeyID &keyid : vAffected) { | |||||
// ... and all their affected keys. | // ... and all their affected keys. | ||||
std::map<CKeyID, int>::iterator rit = | std::map<CKeyID, int>::iterator rit = | ||||
mapKeyFirstBlock.find(keyid); | mapKeyFirstBlock.find(keyid); | ||||
if (rit != mapKeyFirstBlock.end() && | if (rit != mapKeyFirstBlock.end() && | ||||
*height < rit->second) { | *height < rit->second) { | ||||
rit->second = *height; | rit->second = *height; | ||||
} | } | ||||
} | } | ||||
vAffected.clear(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
// Extract block timestamps for those keys. | // Extract block timestamps for those keys. | ||||
for (const auto &entry : mapKeyFirstBlock) { | for (const auto &entry : mapKeyFirstBlock) { | ||||
// block times can be 2h off | // block times can be 2h off | ||||
mapKeyBirth[entry.first] = | mapKeyBirth[entry.first] = | ||||
▲ Show 20 Lines • Show All 788 Lines • Show Last 20 Lines |