1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include <wallet/wallet.h>
7
8 #include <checkpoints.h>
9 #include <chain.h>
10 #include <wallet/coincontrol.h>
11 #include <consensus/consensus.h>
12 #include <consensus/validation.h>
13 #include <fs.h>
14 #include <interfaces/chain.h>
15 #include <key.h>
16 #include <key_io.h>
17 #include <keystore.h>
18 #include <validation.h>
19 #include <net.h>
20 #include <policy/fees.h>
21 #include <policy/policy.h>
22 #include <policy/rbf.h>
23 #include <primitives/block.h>
24 #include <primitives/transaction.h>
25 #include <script/descriptor.h>
26 #include <script/script.h>
27 #include <shutdown.h>
28 #include <timedata.h>
29 #include <txmempool.h>
30 #include <util/bip32.h>
31 #include <util/moneystr.h>
32 #include <wallet/fees.h>
33
34 #include <algorithm>
35 #include <assert.h>
36 #include <future>
37
38 #include <boost/algorithm/string/replace.hpp>
39
40 static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10;
41
42 static CCriticalSection cs_wallets;
43 static std::vector<std::shared_ptr<CWallet>> vpwallets GUARDED_BY(cs_wallets);
44
AddWallet(const std::shared_ptr<CWallet> & wallet)45 bool AddWallet(const std::shared_ptr<CWallet>& wallet)
46 {
47 LOCK(cs_wallets);
48 assert(wallet);
49 std::vector<std::shared_ptr<CWallet>>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
50 if (i != vpwallets.end()) return false;
51 vpwallets.push_back(wallet);
52 return true;
53 }
54
RemoveWallet(const std::shared_ptr<CWallet> & wallet)55 bool RemoveWallet(const std::shared_ptr<CWallet>& wallet)
56 {
57 LOCK(cs_wallets);
58 assert(wallet);
59 std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
60 if (i == vpwallets.end()) return false;
61 vpwallets.erase(i);
62 return true;
63 }
64
HasWallets()65 bool HasWallets()
66 {
67 LOCK(cs_wallets);
68 return !vpwallets.empty();
69 }
70
GetWallets()71 std::vector<std::shared_ptr<CWallet>> GetWallets()
72 {
73 LOCK(cs_wallets);
74 return vpwallets;
75 }
76
GetWallet(const std::string & name)77 std::shared_ptr<CWallet> GetWallet(const std::string& name)
78 {
79 LOCK(cs_wallets);
80 for (const std::shared_ptr<CWallet>& wallet : vpwallets) {
81 if (wallet->GetName() == name) return wallet;
82 }
83 return nullptr;
84 }
85
86 static Mutex g_wallet_release_mutex;
87 static std::condition_variable g_wallet_release_cv;
88 static std::set<CWallet*> g_unloading_wallet_set;
89
90 // Custom deleter for shared_ptr<CWallet>.
ReleaseWallet(CWallet * wallet)91 static void ReleaseWallet(CWallet* wallet)
92 {
93 // Unregister and delete the wallet right after BlockUntilSyncedToCurrentChain
94 // so that it's in sync with the current chainstate.
95 wallet->WalletLogPrintf("Releasing wallet\n");
96 wallet->BlockUntilSyncedToCurrentChain();
97 wallet->Flush();
98 UnregisterValidationInterface(wallet);
99 delete wallet;
100 // Wallet is now released, notify UnloadWallet, if any.
101 {
102 LOCK(g_wallet_release_mutex);
103 if (g_unloading_wallet_set.erase(wallet) == 0) {
104 // UnloadWallet was not called for this wallet, all done.
105 return;
106 }
107 }
108 g_wallet_release_cv.notify_all();
109 }
110
UnloadWallet(std::shared_ptr<CWallet> && wallet)111 void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
112 {
113 // Mark wallet for unloading.
114 CWallet* pwallet = wallet.get();
115 {
116 LOCK(g_wallet_release_mutex);
117 auto it = g_unloading_wallet_set.insert(pwallet);
118 assert(it.second);
119 }
120 // The wallet can be in use so it's not possible to explicitly unload here.
121 // Notify the unload intent so that all remaining shared pointers are
122 // released.
123 pwallet->NotifyUnload();
124 // Time to ditch our shared_ptr and wait for ReleaseWallet call.
125 wallet.reset();
126 {
127 WAIT_LOCK(g_wallet_release_mutex, lock);
128 while (g_unloading_wallet_set.count(pwallet) == 1) {
129 g_wallet_release_cv.wait(lock);
130 }
131 }
132 }
133
LoadWallet(interfaces::Chain & chain,const WalletLocation & location,std::string & error,std::string & warning)134 std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::string& warning)
135 {
136 if (!CWallet::Verify(chain, location, false, error, warning)) {
137 error = "Wallet file verification failed: " + error;
138 return nullptr;
139 }
140
141 std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location);
142 if (!wallet) {
143 error = "Wallet loading failed.";
144 return nullptr;
145 }
146 AddWallet(wallet);
147 wallet->postInitProcess();
148 return wallet;
149 }
150
LoadWallet(interfaces::Chain & chain,const std::string & name,std::string & error,std::string & warning)151 std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
152 {
153 return LoadWallet(chain, WalletLocation(name), error, warning);
154 }
155
156 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
157
158 const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
159
160 /** @defgroup mapWallet
161 *
162 * @{
163 */
164
ToString() const165 std::string COutput::ToString() const
166 {
167 return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue));
168 }
169
GetAffectedKeys(const CScript & spk,const SigningProvider & provider)170 std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
171 {
172 std::vector<CScript> dummy;
173 FlatSigningProvider out;
174 InferDescriptor(spk, provider)->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out);
175 std::vector<CKeyID> ret;
176 for (const auto& entry : out.pubkeys) {
177 ret.push_back(entry.first);
178 }
179 return ret;
180 }
181
GetWalletTx(const uint256 & hash) const182 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
183 {
184 LOCK(cs_wallet);
185 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
186 if (it == mapWallet.end())
187 return nullptr;
188 return &(it->second);
189 }
190
GenerateNewKey(WalletBatch & batch,bool internal)191 CPubKey CWallet::GenerateNewKey(WalletBatch &batch, bool internal)
192 {
193 assert(!IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
194 assert(!IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET));
195 AssertLockHeld(cs_wallet); // mapKeyMetadata
196 bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
197
198 CKey secret;
199
200 // Create new metadata
201 int64_t nCreationTime = GetTime();
202 CKeyMetadata metadata(nCreationTime);
203
204 // use HD key derivation if HD was enabled during wallet creation and a seed is present
205 if (IsHDEnabled()) {
206 DeriveNewChildKey(batch, metadata, secret, (CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
207 } else {
208 secret.MakeNewKey(fCompressed);
209 }
210
211 // Compressed public keys were introduced in version 0.6.0
212 if (fCompressed) {
213 SetMinVersion(FEATURE_COMPRPUBKEY);
214 }
215
216 CPubKey pubkey = secret.GetPubKey();
217 assert(secret.VerifyPubKey(pubkey));
218
219 mapKeyMetadata[pubkey.GetID()] = metadata;
220 UpdateTimeFirstKey(nCreationTime);
221
222 if (!AddKeyPubKeyWithDB(batch, secret, pubkey)) {
223 throw std::runtime_error(std::string(__func__) + ": AddKey failed");
224 }
225 return pubkey;
226 }
227
DeriveNewChildKey(WalletBatch & batch,CKeyMetadata & metadata,CKey & secret,bool internal)228 void CWallet::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, bool internal)
229 {
230 // for now we use a fixed keypath scheme of m/0'/0'/k
231 CKey seed; //seed (256bit)
232 CExtKey masterKey; //hd master key
233 CExtKey accountKey; //key at m/0'
234 CExtKey chainChildKey; //key at m/0'/0' (external) or m/0'/1' (internal)
235 CExtKey childKey; //key at m/0'/0'/<n>'
236
237 // try to get the seed
238 if (!GetKey(hdChain.seed_id, seed))
239 throw std::runtime_error(std::string(__func__) + ": seed not found");
240
241 masterKey.SetSeed(seed.begin(), seed.size());
242
243 // derive m/0'
244 // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
245 masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
246
247 // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
248 assert(internal ? CanSupportFeature(FEATURE_HD_SPLIT) : true);
249 accountKey.Derive(chainChildKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0));
250
251 // derive child key at next index, skip keys already known to the wallet
252 do {
253 // always derive hardened keys
254 // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
255 // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
256 if (internal) {
257 chainChildKey.Derive(childKey, hdChain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
258 metadata.hdKeypath = "m/0'/1'/" + std::to_string(hdChain.nInternalChainCounter) + "'";
259 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
260 metadata.key_origin.path.push_back(1 | BIP32_HARDENED_KEY_LIMIT);
261 metadata.key_origin.path.push_back(hdChain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
262 hdChain.nInternalChainCounter++;
263 }
264 else {
265 chainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
266 metadata.hdKeypath = "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
267 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
268 metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
269 metadata.key_origin.path.push_back(hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
270 hdChain.nExternalChainCounter++;
271 }
272 } while (HaveKey(childKey.key.GetPubKey().GetID()));
273 secret = childKey.key;
274 metadata.hd_seed_id = hdChain.seed_id;
275 CKeyID master_id = masterKey.key.GetPubKey().GetID();
276 std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
277 metadata.has_key_origin = true;
278 // update the chain model in the database
279 if (!batch.WriteHDChain(hdChain))
280 throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
281 }
282
AddKeyPubKeyWithDB(WalletBatch & batch,const CKey & secret,const CPubKey & pubkey)283 bool CWallet::AddKeyPubKeyWithDB(WalletBatch &batch, const CKey& secret, const CPubKey &pubkey)
284 {
285 AssertLockHeld(cs_wallet); // mapKeyMetadata
286
287 // Make sure we aren't adding private keys to private key disabled wallets
288 assert(!IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
289
290 // CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
291 // which is overridden below. To avoid flushes, the database handle is
292 // tunneled through to it.
293 bool needsDB = !encrypted_batch;
294 if (needsDB) {
295 encrypted_batch = &batch;
296 }
297 if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
298 if (needsDB) encrypted_batch = nullptr;
299 return false;
300 }
301 if (needsDB) encrypted_batch = nullptr;
302
303 // check if we need to remove from watch-only
304 CScript script;
305 script = GetScriptForDestination(pubkey.GetID());
306 if (HaveWatchOnly(script)) {
307 RemoveWatchOnly(script);
308 }
309 script = GetScriptForRawPubKey(pubkey);
310 if (HaveWatchOnly(script)) {
311 RemoveWatchOnly(script);
312 }
313
314 if (!IsCrypted()) {
315 return batch.WriteKey(pubkey,
316 secret.GetPrivKey(),
317 mapKeyMetadata[pubkey.GetID()]);
318 }
319 UnsetWalletFlag(WALLET_FLAG_BLANK_WALLET);
320 return true;
321 }
322
AddKeyPubKey(const CKey & secret,const CPubKey & pubkey)323 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
324 {
325 WalletBatch batch(*database);
326 return CWallet::AddKeyPubKeyWithDB(batch, secret, pubkey);
327 }
328
AddCryptedKey(const CPubKey & vchPubKey,const std::vector<unsigned char> & vchCryptedSecret)329 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
330 const std::vector<unsigned char> &vchCryptedSecret)
331 {
332 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
333 return false;
334 {
335 LOCK(cs_wallet);
336 if (encrypted_batch)
337 return encrypted_batch->WriteCryptedKey(vchPubKey,
338 vchCryptedSecret,
339 mapKeyMetadata[vchPubKey.GetID()]);
340 else
341 return WalletBatch(*database).WriteCryptedKey(vchPubKey,
342 vchCryptedSecret,
343 mapKeyMetadata[vchPubKey.GetID()]);
344 }
345 }
346
LoadKeyMetadata(const CKeyID & keyID,const CKeyMetadata & meta)347 void CWallet::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &meta)
348 {
349 AssertLockHeld(cs_wallet); // mapKeyMetadata
350 UpdateTimeFirstKey(meta.nCreateTime);
351 mapKeyMetadata[keyID] = meta;
352 }
353
LoadScriptMetadata(const CScriptID & script_id,const CKeyMetadata & meta)354 void CWallet::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &meta)
355 {
356 AssertLockHeld(cs_wallet); // m_script_metadata
357 UpdateTimeFirstKey(meta.nCreateTime);
358 m_script_metadata[script_id] = meta;
359 }
360
361 // Writes a keymetadata for a public key. overwrite specifies whether to overwrite an existing metadata for that key if there exists one.
WriteKeyMetadata(const CKeyMetadata & meta,const CPubKey & pubkey,const bool overwrite)362 bool CWallet::WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite)
363 {
364 return WalletBatch(*database).WriteKeyMetadata(meta, pubkey, overwrite);
365 }
366
UpgradeKeyMetadata()367 void CWallet::UpgradeKeyMetadata()
368 {
369 AssertLockHeld(cs_wallet); // mapKeyMetadata
370 if (IsLocked() || IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
371 return;
372 }
373
374 std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(*database);
375 size_t cnt = 0;
376 for (auto& meta_pair : mapKeyMetadata) {
377 CKeyMetadata& meta = meta_pair.second;
378 if (!meta.hd_seed_id.IsNull() && !meta.has_key_origin && meta.hdKeypath != "s") { // If the hdKeypath is "s", that's the seed and it doesn't have a key origin
379 CKey key;
380 GetKey(meta.hd_seed_id, key);
381 CExtKey masterKey;
382 masterKey.SetSeed(key.begin(), key.size());
383 // Add to map
384 CKeyID master_id = masterKey.key.GetPubKey().GetID();
385 std::copy(master_id.begin(), master_id.begin() + 4, meta.key_origin.fingerprint);
386 if (!ParseHDKeypath(meta.hdKeypath, meta.key_origin.path)) {
387 throw std::runtime_error("Invalid stored hdKeypath");
388 }
389 meta.has_key_origin = true;
390 if (meta.nVersion < CKeyMetadata::VERSION_WITH_KEY_ORIGIN) {
391 meta.nVersion = CKeyMetadata::VERSION_WITH_KEY_ORIGIN;
392 }
393
394 // Write meta to wallet
395 CPubKey pubkey;
396 if (GetPubKey(meta_pair.first, pubkey)) {
397 batch->WriteKeyMetadata(meta, pubkey, true);
398 if (++cnt % 1000 == 0) {
399 // avoid creating overlarge in-memory batches in case the wallet contains large amounts of keys
400 batch.reset(new WalletBatch(*database));
401 }
402 }
403 }
404 }
405 batch.reset(); //write before setting the flag
406 SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
407 }
408
LoadCryptedKey(const CPubKey & vchPubKey,const std::vector<unsigned char> & vchCryptedSecret)409 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
410 {
411 return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
412 }
413
414 /**
415 * Update wallet first key creation time. This should be called whenever keys
416 * are added to the wallet, with the oldest key creation time.
417 */
UpdateTimeFirstKey(int64_t nCreateTime)418 void CWallet::UpdateTimeFirstKey(int64_t nCreateTime)
419 {
420 AssertLockHeld(cs_wallet);
421 if (nCreateTime <= 1) {
422 // Cannot determine birthday information, so set the wallet birthday to
423 // the beginning of time.
424 nTimeFirstKey = 1;
425 } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
426 nTimeFirstKey = nCreateTime;
427 }
428 }
429
AddCScript(const CScript & redeemScript)430 bool CWallet::AddCScript(const CScript& redeemScript)
431 {
432 if (!CCryptoKeyStore::AddCScript(redeemScript))
433 return false;
434 if (WalletBatch(*database).WriteCScript(Hash160(redeemScript), redeemScript)) {
435 UnsetWalletFlag(WALLET_FLAG_BLANK_WALLET);
436 return true;
437 }
438 return false;
439 }
440
LoadCScript(const CScript & redeemScript)441 bool CWallet::LoadCScript(const CScript& redeemScript)
442 {
443 /* A sanity check was added in pull #3843 to avoid adding redeemScripts
444 * that never can be redeemed. However, old wallets may still contain
445 * these. Do not add them to the wallet and warn. */
446 if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
447 {
448 std::string strAddr = EncodeDestination(CScriptID(redeemScript));
449 WalletLogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
450 return true;
451 }
452
453 return CCryptoKeyStore::AddCScript(redeemScript);
454 }
455
AddWatchOnly(const CScript & dest)456 bool CWallet::AddWatchOnly(const CScript& dest)
457 {
458 if (!CCryptoKeyStore::AddWatchOnly(dest))
459 return false;
460 const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
461 UpdateTimeFirstKey(meta.nCreateTime);
462 NotifyWatchonlyChanged(true);
463 if (WalletBatch(*database).WriteWatchOnly(dest, meta)) {
464 UnsetWalletFlag(WALLET_FLAG_BLANK_WALLET);
465 return true;
466 }
467 return false;
468 }
469
AddWatchOnly(const CScript & dest,int64_t nCreateTime)470 bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
471 {
472 m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
473 return AddWatchOnly(dest);
474 }
475
RemoveWatchOnly(const CScript & dest)476 bool CWallet::RemoveWatchOnly(const CScript &dest)
477 {
478 AssertLockHeld(cs_wallet);
479 if (!CCryptoKeyStore::RemoveWatchOnly(dest))
480 return false;
481 if (!HaveWatchOnly())
482 NotifyWatchonlyChanged(false);
483 if (!WalletBatch(*database).EraseWatchOnly(dest))
484 return false;
485
486 return true;
487 }
488
LoadWatchOnly(const CScript & dest)489 bool CWallet::LoadWatchOnly(const CScript &dest)
490 {
491 return CCryptoKeyStore::AddWatchOnly(dest);
492 }
493
Unlock(const SecureString & strWalletPassphrase,bool accept_no_keys)494 bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
495 {
496 CCrypter crypter;
497 CKeyingMaterial _vMasterKey;
498
499 {
500 LOCK(cs_wallet);
501 for (const MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
502 {
503 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
504 return false;
505 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
506 continue; // try another master key
507 if (CCryptoKeyStore::Unlock(_vMasterKey, accept_no_keys)) {
508 // Now that we've unlocked, upgrade the key metadata
509 UpgradeKeyMetadata();
510 return true;
511 }
512 }
513 }
514 return false;
515 }
516
ChangeWalletPassphrase(const SecureString & strOldWalletPassphrase,const SecureString & strNewWalletPassphrase)517 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
518 {
519 bool fWasLocked = IsLocked();
520
521 {
522 LOCK(cs_wallet);
523 Lock();
524
525 CCrypter crypter;
526 CKeyingMaterial _vMasterKey;
527 for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
528 {
529 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
530 return false;
531 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
532 return false;
533 if (CCryptoKeyStore::Unlock(_vMasterKey))
534 {
535 int64_t nStartTime = GetTimeMillis();
536 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
537 pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))));
538
539 nStartTime = GetTimeMillis();
540 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
541 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
542
543 if (pMasterKey.second.nDeriveIterations < 25000)
544 pMasterKey.second.nDeriveIterations = 25000;
545
546 WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
547
548 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
549 return false;
550 if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
551 return false;
552 WalletBatch(*database).WriteMasterKey(pMasterKey.first, pMasterKey.second);
553 if (fWasLocked)
554 Lock();
555 return true;
556 }
557 }
558 }
559
560 return false;
561 }
562
ChainStateFlushed(const CBlockLocator & loc)563 void CWallet::ChainStateFlushed(const CBlockLocator& loc)
564 {
565 WalletBatch batch(*database);
566 batch.WriteBestBlock(loc);
567 }
568
SetMinVersion(enum WalletFeature nVersion,WalletBatch * batch_in,bool fExplicit)569 void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in, bool fExplicit)
570 {
571 LOCK(cs_wallet); // nWalletVersion
572 if (nWalletVersion >= nVersion)
573 return;
574
575 // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
576 if (fExplicit && nVersion > nWalletMaxVersion)
577 nVersion = FEATURE_LATEST;
578
579 nWalletVersion = nVersion;
580
581 if (nVersion > nWalletMaxVersion)
582 nWalletMaxVersion = nVersion;
583
584 {
585 WalletBatch* batch = batch_in ? batch_in : new WalletBatch(*database);
586 if (nWalletVersion > 40000)
587 batch->WriteMinVersion(nWalletVersion);
588 if (!batch_in)
589 delete batch;
590 }
591 }
592
SetMaxVersion(int nVersion)593 bool CWallet::SetMaxVersion(int nVersion)
594 {
595 LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
596 // cannot downgrade below current version
597 if (nWalletVersion > nVersion)
598 return false;
599
600 nWalletMaxVersion = nVersion;
601
602 return true;
603 }
604
GetConflicts(const uint256 & txid) const605 std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
606 {
607 std::set<uint256> result;
608 AssertLockHeld(cs_wallet);
609
610 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
611 if (it == mapWallet.end())
612 return result;
613 const CWalletTx& wtx = it->second;
614
615 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
616
617 for (const CTxIn& txin : wtx.tx->vin)
618 {
619 if (mapTxSpends.count(txin.prevout) <= 1)
620 continue; // No conflict if zero or one spends
621 range = mapTxSpends.equal_range(txin.prevout);
622 for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
623 result.insert(_it->second);
624 }
625 return result;
626 }
627
HasWalletSpend(const uint256 & txid) const628 bool CWallet::HasWalletSpend(const uint256& txid) const
629 {
630 AssertLockHeld(cs_wallet);
631 auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
632 return (iter != mapTxSpends.end() && iter->first.hash == txid);
633 }
634
Flush(bool shutdown)635 void CWallet::Flush(bool shutdown)
636 {
637 database->Flush(shutdown);
638 }
639
SyncMetaData(std::pair<TxSpends::iterator,TxSpends::iterator> range)640 void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
641 {
642 // We want all the wallet transactions in range to have the same metadata as
643 // the oldest (smallest nOrderPos).
644 // So: find smallest nOrderPos:
645
646 int nMinOrderPos = std::numeric_limits<int>::max();
647 const CWalletTx* copyFrom = nullptr;
648 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
649 const CWalletTx* wtx = &mapWallet.at(it->second);
650 if (wtx->nOrderPos < nMinOrderPos) {
651 nMinOrderPos = wtx->nOrderPos;
652 copyFrom = wtx;
653 }
654 }
655
656 if (!copyFrom) {
657 return;
658 }
659
660 // Now copy data from copyFrom to rest:
661 for (TxSpends::iterator it = range.first; it != range.second; ++it)
662 {
663 const uint256& hash = it->second;
664 CWalletTx* copyTo = &mapWallet.at(hash);
665 if (copyFrom == copyTo) continue;
666 assert(copyFrom && "Oldest wallet transaction in range assumed to have been found.");
667 if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
668 copyTo->mapValue = copyFrom->mapValue;
669 copyTo->vOrderForm = copyFrom->vOrderForm;
670 // fTimeReceivedIsTxTime not copied on purpose
671 // nTimeReceived not copied on purpose
672 copyTo->nTimeSmart = copyFrom->nTimeSmart;
673 copyTo->fFromMe = copyFrom->fFromMe;
674 // nOrderPos not copied on purpose
675 // cached members not copied on purpose
676 }
677 }
678
679 /**
680 * Outpoint is spent if any non-conflicted transaction
681 * spends it:
682 */
IsSpent(interfaces::Chain::Lock & locked_chain,const uint256 & hash,unsigned int n) const683 bool CWallet::IsSpent(interfaces::Chain::Lock& locked_chain, const uint256& hash, unsigned int n) const
684 {
685 const COutPoint outpoint(hash, n);
686 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
687 range = mapTxSpends.equal_range(outpoint);
688
689 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
690 {
691 const uint256& wtxid = it->second;
692 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
693 if (mit != mapWallet.end()) {
694 int depth = mit->second.GetDepthInMainChain(locked_chain);
695 if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
696 return true; // Spent
697 }
698 }
699 return false;
700 }
701
AddToSpends(const COutPoint & outpoint,const uint256 & wtxid)702 void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
703 {
704 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
705
706 setLockedCoins.erase(outpoint);
707
708 std::pair<TxSpends::iterator, TxSpends::iterator> range;
709 range = mapTxSpends.equal_range(outpoint);
710 SyncMetaData(range);
711 }
712
713
AddToSpends(const uint256 & wtxid)714 void CWallet::AddToSpends(const uint256& wtxid)
715 {
716 auto it = mapWallet.find(wtxid);
717 assert(it != mapWallet.end());
718 CWalletTx& thisTx = it->second;
719 if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
720 return;
721
722 for (const CTxIn& txin : thisTx.tx->vin)
723 AddToSpends(txin.prevout, wtxid);
724 }
725
EncryptWallet(const SecureString & strWalletPassphrase)726 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
727 {
728 if (IsCrypted())
729 return false;
730
731 CKeyingMaterial _vMasterKey;
732
733 _vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
734 GetStrongRandBytes(&_vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
735
736 CMasterKey kMasterKey;
737
738 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
739 GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
740
741 CCrypter crypter;
742 int64_t nStartTime = GetTimeMillis();
743 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
744 kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(GetTimeMillis() - nStartTime)));
745
746 nStartTime = GetTimeMillis();
747 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
748 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
749
750 if (kMasterKey.nDeriveIterations < 25000)
751 kMasterKey.nDeriveIterations = 25000;
752
753 WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
754
755 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
756 return false;
757 if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey))
758 return false;
759
760 {
761 LOCK(cs_wallet);
762 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
763 assert(!encrypted_batch);
764 encrypted_batch = new WalletBatch(*database);
765 if (!encrypted_batch->TxnBegin()) {
766 delete encrypted_batch;
767 encrypted_batch = nullptr;
768 return false;
769 }
770 encrypted_batch->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
771
772 if (!EncryptKeys(_vMasterKey))
773 {
774 encrypted_batch->TxnAbort();
775 delete encrypted_batch;
776 encrypted_batch = nullptr;
777 // We now probably have half of our keys encrypted in memory, and half not...
778 // die and let the user reload the unencrypted wallet.
779 assert(false);
780 }
781
782 // Encryption was introduced in version 0.4.0
783 SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch, true);
784
785 if (!encrypted_batch->TxnCommit()) {
786 delete encrypted_batch;
787 encrypted_batch = nullptr;
788 // We now have keys encrypted in memory, but not on disk...
789 // die to avoid confusion and let the user reload the unencrypted wallet.
790 assert(false);
791 }
792
793 delete encrypted_batch;
794 encrypted_batch = nullptr;
795
796 Lock();
797 Unlock(strWalletPassphrase);
798
799 // if we are using HD, replace the HD seed with a new one
800 if (IsHDEnabled()) {
801 SetHDSeed(GenerateNewSeed());
802 }
803
804 NewKeyPool();
805 Lock();
806
807 // Need to completely rewrite the wallet file; if we don't, bdb might keep
808 // bits of the unencrypted private key in slack space in the database file.
809 database->Rewrite();
810
811 // BDB seems to have a bad habit of writing old data into
812 // slack space in .dat files; that is bad if the old data is
813 // unencrypted private keys. So:
814 database->ReloadDbEnv();
815
816 }
817 NotifyStatusChanged(this);
818
819 return true;
820 }
821
ReorderTransactions()822 DBErrors CWallet::ReorderTransactions()
823 {
824 LOCK(cs_wallet);
825 WalletBatch batch(*database);
826
827 // Old wallets didn't have any defined order for transactions
828 // Probably a bad idea to change the output of this
829
830 // First: get all CWalletTx into a sorted-by-time multimap.
831 typedef std::multimap<int64_t, CWalletTx*> TxItems;
832 TxItems txByTime;
833
834 for (auto& entry : mapWallet)
835 {
836 CWalletTx* wtx = &entry.second;
837 txByTime.insert(std::make_pair(wtx->nTimeReceived, wtx));
838 }
839
840 nOrderPosNext = 0;
841 std::vector<int64_t> nOrderPosOffsets;
842 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
843 {
844 CWalletTx *const pwtx = (*it).second;
845 int64_t& nOrderPos = pwtx->nOrderPos;
846
847 if (nOrderPos == -1)
848 {
849 nOrderPos = nOrderPosNext++;
850 nOrderPosOffsets.push_back(nOrderPos);
851
852 if (!batch.WriteTx(*pwtx))
853 return DBErrors::LOAD_FAIL;
854 }
855 else
856 {
857 int64_t nOrderPosOff = 0;
858 for (const int64_t& nOffsetStart : nOrderPosOffsets)
859 {
860 if (nOrderPos >= nOffsetStart)
861 ++nOrderPosOff;
862 }
863 nOrderPos += nOrderPosOff;
864 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
865
866 if (!nOrderPosOff)
867 continue;
868
869 // Since we're changing the order, write it back
870 if (!batch.WriteTx(*pwtx))
871 return DBErrors::LOAD_FAIL;
872 }
873 }
874 batch.WriteOrderPosNext(nOrderPosNext);
875
876 return DBErrors::LOAD_OK;
877 }
878
IncOrderPosNext(WalletBatch * batch)879 int64_t CWallet::IncOrderPosNext(WalletBatch *batch)
880 {
881 AssertLockHeld(cs_wallet); // nOrderPosNext
882 int64_t nRet = nOrderPosNext++;
883 if (batch) {
884 batch->WriteOrderPosNext(nOrderPosNext);
885 } else {
886 WalletBatch(*database).WriteOrderPosNext(nOrderPosNext);
887 }
888 return nRet;
889 }
890
MarkDirty()891 void CWallet::MarkDirty()
892 {
893 {
894 LOCK(cs_wallet);
895 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
896 item.second.MarkDirty();
897 }
898 }
899
MarkReplaced(const uint256 & originalHash,const uint256 & newHash)900 bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
901 {
902 LOCK(cs_wallet);
903
904 auto mi = mapWallet.find(originalHash);
905
906 // There is a bug if MarkReplaced is not called on an existing wallet transaction.
907 assert(mi != mapWallet.end());
908
909 CWalletTx& wtx = (*mi).second;
910
911 // Ensure for now that we're not overwriting data
912 assert(wtx.mapValue.count("replaced_by_txid") == 0);
913
914 wtx.mapValue["replaced_by_txid"] = newHash.ToString();
915
916 WalletBatch batch(*database, "r+");
917
918 bool success = true;
919 if (!batch.WriteTx(wtx)) {
920 WalletLogPrintf("%s: Updating batch tx %s failed\n", __func__, wtx.GetHash().ToString());
921 success = false;
922 }
923
924 NotifyTransactionChanged(this, originalHash, CT_UPDATED);
925
926 return success;
927 }
928
AddToWallet(const CWalletTx & wtxIn,bool fFlushOnClose)929 bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
930 {
931 LOCK(cs_wallet);
932
933 WalletBatch batch(*database, "r+", fFlushOnClose);
934
935 uint256 hash = wtxIn.GetHash();
936
937 // Inserts only if not already there, returns tx inserted or tx found
938 std::pair<std::map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(std::make_pair(hash, wtxIn));
939 CWalletTx& wtx = (*ret.first).second;
940 wtx.BindWallet(this);
941 bool fInsertedNew = ret.second;
942 if (fInsertedNew) {
943 wtx.nTimeReceived = GetAdjustedTime();
944 wtx.nOrderPos = IncOrderPosNext(&batch);
945 wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
946 wtx.nTimeSmart = ComputeTimeSmart(wtx);
947 AddToSpends(hash);
948 }
949
950 bool fUpdated = false;
951 if (!fInsertedNew)
952 {
953 // Merge
954 if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock)
955 {
956 wtx.hashBlock = wtxIn.hashBlock;
957 fUpdated = true;
958 }
959 // If no longer abandoned, update
960 if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned())
961 {
962 wtx.hashBlock = wtxIn.hashBlock;
963 fUpdated = true;
964 }
965 if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
966 {
967 wtx.nIndex = wtxIn.nIndex;
968 fUpdated = true;
969 }
970 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
971 {
972 wtx.fFromMe = wtxIn.fFromMe;
973 fUpdated = true;
974 }
975 // If we have a witness-stripped version of this transaction, and we
976 // see a new version with a witness, then we must be upgrading a pre-segwit
977 // wallet. Store the new version of the transaction with the witness,
978 // as the stripped-version must be invalid.
979 // TODO: Store all versions of the transaction, instead of just one.
980 if (wtxIn.tx->HasWitness() && !wtx.tx->HasWitness()) {
981 wtx.SetTx(wtxIn.tx);
982 fUpdated = true;
983 }
984 }
985
986 //// debug print
987 WalletLogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
988
989 // Write to disk
990 if (fInsertedNew || fUpdated)
991 if (!batch.WriteTx(wtx))
992 return false;
993
994 // Break debit/credit balance caches:
995 wtx.MarkDirty();
996
997 // Notify UI of new or updated transaction
998 NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
999
1000 // notify an external script when a wallet transaction comes in or is updated
1001 std::string strCmd = gArgs.GetArg("-walletnotify", "");
1002
1003 if (!strCmd.empty())
1004 {
1005 boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
1006 std::thread t(runCommand, strCmd);
1007 t.detach(); // thread runs free
1008 }
1009
1010 return true;
1011 }
1012
LoadToWallet(const CWalletTx & wtxIn)1013 void CWallet::LoadToWallet(const CWalletTx& wtxIn)
1014 {
1015 uint256 hash = wtxIn.GetHash();
1016 const auto& ins = mapWallet.emplace(hash, wtxIn);
1017 CWalletTx& wtx = ins.first->second;
1018 wtx.BindWallet(this);
1019 if (/* insertion took place */ ins.second) {
1020 wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
1021 }
1022 AddToSpends(hash);
1023 for (const CTxIn& txin : wtx.tx->vin) {
1024 auto it = mapWallet.find(txin.prevout.hash);
1025 if (it != mapWallet.end()) {
1026 CWalletTx& prevtx = it->second;
1027 if (prevtx.nIndex == -1 && !prevtx.hashUnset()) {
1028 MarkConflicted(prevtx.hashBlock, wtx.GetHash());
1029 }
1030 }
1031 }
1032 }
1033
AddToWalletIfInvolvingMe(const CTransactionRef & ptx,const uint256 & block_hash,int posInBlock,bool fUpdate)1034 bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const uint256& block_hash, int posInBlock, bool fUpdate)
1035 {
1036 const CTransaction& tx = *ptx;
1037 {
1038 AssertLockHeld(cs_wallet);
1039
1040 if (!block_hash.IsNull()) {
1041 for (const CTxIn& txin : tx.vin) {
1042 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
1043 while (range.first != range.second) {
1044 if (range.first->second != tx.GetHash()) {
1045 WalletLogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), block_hash.ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
1046 MarkConflicted(block_hash, range.first->second);
1047 }
1048 range.first++;
1049 }
1050 }
1051 }
1052
1053 bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1054 if (fExisted && !fUpdate) return false;
1055 if (fExisted || IsMine(tx) || IsFromMe(tx))
1056 {
1057 /* Check if any keys in the wallet keypool that were supposed to be unused
1058 * have appeared in a new transaction. If so, remove those keys from the keypool.
1059 * This can happen when restoring an old wallet backup that does not contain
1060 * the mostly recently created transactions from newer versions of the wallet.
1061 */
1062
1063 // loop though all outputs
1064 for (const CTxOut& txout: tx.vout) {
1065 // extract addresses and check if they match with an unused keypool key
1066 for (const auto& keyid : GetAffectedKeys(txout.scriptPubKey, *this)) {
1067 std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
1068 if (mi != m_pool_key_to_index.end()) {
1069 WalletLogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
1070 MarkReserveKeysAsUsed(mi->second);
1071
1072 if (!TopUpKeyPool()) {
1073 WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
1074 }
1075 }
1076 }
1077 }
1078
1079 CWalletTx wtx(this, ptx);
1080
1081 // Get merkle branch if transaction was found in a block
1082 if (!block_hash.IsNull())
1083 wtx.SetMerkleBranch(block_hash, posInBlock);
1084
1085 return AddToWallet(wtx, false);
1086 }
1087 }
1088 return false;
1089 }
1090
TransactionCanBeAbandoned(const uint256 & hashTx) const1091 bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const
1092 {
1093 auto locked_chain = chain().lock();
1094 LOCK(cs_wallet);
1095 const CWalletTx* wtx = GetWalletTx(hashTx);
1096 return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain(*locked_chain) == 0 && !wtx->InMempool();
1097 }
1098
MarkInputsDirty(const CTransactionRef & tx)1099 void CWallet::MarkInputsDirty(const CTransactionRef& tx)
1100 {
1101 for (const CTxIn& txin : tx->vin) {
1102 auto it = mapWallet.find(txin.prevout.hash);
1103 if (it != mapWallet.end()) {
1104 it->second.MarkDirty();
1105 }
1106 }
1107 }
1108
AbandonTransaction(interfaces::Chain::Lock & locked_chain,const uint256 & hashTx)1109 bool CWallet::AbandonTransaction(interfaces::Chain::Lock& locked_chain, const uint256& hashTx)
1110 {
1111 auto locked_chain_recursive = chain().lock(); // Temporary. Removed in upcoming lock cleanup
1112 LOCK(cs_wallet);
1113
1114 WalletBatch batch(*database, "r+");
1115
1116 std::set<uint256> todo;
1117 std::set<uint256> done;
1118
1119 // Can't mark abandoned if confirmed or in mempool
1120 auto it = mapWallet.find(hashTx);
1121 assert(it != mapWallet.end());
1122 CWalletTx& origtx = it->second;
1123 if (origtx.GetDepthInMainChain(locked_chain) != 0 || origtx.InMempool()) {
1124 return false;
1125 }
1126
1127 todo.insert(hashTx);
1128
1129 while (!todo.empty()) {
1130 uint256 now = *todo.begin();
1131 todo.erase(now);
1132 done.insert(now);
1133 auto it = mapWallet.find(now);
1134 assert(it != mapWallet.end());
1135 CWalletTx& wtx = it->second;
1136 int currentconfirm = wtx.GetDepthInMainChain(locked_chain);
1137 // If the orig tx was not in block, none of its spends can be
1138 assert(currentconfirm <= 0);
1139 // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon}
1140 if (currentconfirm == 0 && !wtx.isAbandoned()) {
1141 // If the orig tx was not in block/mempool, none of its spends can be in mempool
1142 assert(!wtx.InMempool());
1143 wtx.nIndex = -1;
1144 wtx.setAbandoned();
1145 wtx.MarkDirty();
1146 batch.WriteTx(wtx);
1147 NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
1148 // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
1149 TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1150 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1151 if (!done.count(iter->second)) {
1152 todo.insert(iter->second);
1153 }
1154 iter++;
1155 }
1156 // If a transaction changes 'conflicted' state, that changes the balance
1157 // available of the outputs it spends. So force those to be recomputed
1158 MarkInputsDirty(wtx.tx);
1159 }
1160 }
1161
1162 return true;
1163 }
1164
MarkConflicted(const uint256 & hashBlock,const uint256 & hashTx)1165 void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
1166 {
1167 auto locked_chain = chain().lock();
1168 LOCK(cs_wallet);
1169
1170 int conflictconfirms = -locked_chain->getBlockDepth(hashBlock);
1171 // If number of conflict confirms cannot be determined, this means
1172 // that the block is still unknown or not yet part of the main chain,
1173 // for example when loading the wallet during a reindex. Do nothing in that
1174 // case.
1175 if (conflictconfirms >= 0)
1176 return;
1177
1178 // Do not flush the wallet here for performance reasons
1179 WalletBatch batch(*database, "r+", false);
1180
1181 std::set<uint256> todo;
1182 std::set<uint256> done;
1183
1184 todo.insert(hashTx);
1185
1186 while (!todo.empty()) {
1187 uint256 now = *todo.begin();
1188 todo.erase(now);
1189 done.insert(now);
1190 auto it = mapWallet.find(now);
1191 assert(it != mapWallet.end());
1192 CWalletTx& wtx = it->second;
1193 int currentconfirm = wtx.GetDepthInMainChain(*locked_chain);
1194 if (conflictconfirms < currentconfirm) {
1195 // Block is 'more conflicted' than current confirm; update.
1196 // Mark transaction as conflicted with this block.
1197 wtx.nIndex = -1;
1198 wtx.hashBlock = hashBlock;
1199 wtx.MarkDirty();
1200 batch.WriteTx(wtx);
1201 // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
1202 TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1203 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1204 if (!done.count(iter->second)) {
1205 todo.insert(iter->second);
1206 }
1207 iter++;
1208 }
1209 // If a transaction changes 'conflicted' state, that changes the balance
1210 // available of the outputs it spends. So force those to be recomputed
1211 MarkInputsDirty(wtx.tx);
1212 }
1213 }
1214 }
1215
SyncTransaction(const CTransactionRef & ptx,const uint256 & block_hash,int posInBlock,bool update_tx)1216 void CWallet::SyncTransaction(const CTransactionRef& ptx, const uint256& block_hash, int posInBlock, bool update_tx) {
1217 if (!AddToWalletIfInvolvingMe(ptx, block_hash, posInBlock, update_tx))
1218 return; // Not one of ours
1219
1220 // If a transaction changes 'conflicted' state, that changes the balance
1221 // available of the outputs it spends. So force those to be
1222 // recomputed, also:
1223 MarkInputsDirty(ptx);
1224 }
1225
TransactionAddedToMempool(const CTransactionRef & ptx)1226 void CWallet::TransactionAddedToMempool(const CTransactionRef& ptx) {
1227 auto locked_chain = chain().lock();
1228 LOCK(cs_wallet);
1229 SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
1230
1231 auto it = mapWallet.find(ptx->GetHash());
1232 if (it != mapWallet.end()) {
1233 it->second.fInMempool = true;
1234 }
1235 }
1236
TransactionRemovedFromMempool(const CTransactionRef & ptx)1237 void CWallet::TransactionRemovedFromMempool(const CTransactionRef &ptx) {
1238 LOCK(cs_wallet);
1239 auto it = mapWallet.find(ptx->GetHash());
1240 if (it != mapWallet.end()) {
1241 it->second.fInMempool = false;
1242 }
1243 }
1244
BlockConnected(const std::shared_ptr<const CBlock> & pblock,const CBlockIndex * pindex,const std::vector<CTransactionRef> & vtxConflicted)1245 void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) {
1246 auto locked_chain = chain().lock();
1247 LOCK(cs_wallet);
1248 // TODO: Temporarily ensure that mempool removals are notified before
1249 // connected transactions. This shouldn't matter, but the abandoned
1250 // state of transactions in our wallet is currently cleared when we
1251 // receive another notification and there is a race condition where
1252 // notification of a connected conflict might cause an outside process
1253 // to abandon a transaction and then have it inadvertently cleared by
1254 // the notification that the conflicted transaction was evicted.
1255
1256 for (const CTransactionRef& ptx : vtxConflicted) {
1257 SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
1258 TransactionRemovedFromMempool(ptx);
1259 }
1260 for (size_t i = 0; i < pblock->vtx.size(); i++) {
1261 SyncTransaction(pblock->vtx[i], pindex->GetBlockHash(), i);
1262 TransactionRemovedFromMempool(pblock->vtx[i]);
1263 }
1264
1265 m_last_block_processed = pindex->GetBlockHash();
1266 }
1267
BlockDisconnected(const std::shared_ptr<const CBlock> & pblock)1268 void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
1269 auto locked_chain = chain().lock();
1270 LOCK(cs_wallet);
1271
1272 for (const CTransactionRef& ptx : pblock->vtx) {
1273 SyncTransaction(ptx, {} /* block hash */, 0 /* position in block */);
1274 }
1275 }
1276
1277
1278
BlockUntilSyncedToCurrentChain()1279 void CWallet::BlockUntilSyncedToCurrentChain() {
1280 AssertLockNotHeld(cs_main);
1281 AssertLockNotHeld(cs_wallet);
1282
1283 {
1284 // Skip the queue-draining stuff if we know we're caught up with
1285 // chainActive.Tip()...
1286 // We could also take cs_wallet here, and call m_last_block_processed
1287 // protected by cs_wallet instead of cs_main, but as long as we need
1288 // cs_main here anyway, it's easier to just call it cs_main-protected.
1289 auto locked_chain = chain().lock();
1290
1291 if (!m_last_block_processed.IsNull() && locked_chain->isPotentialTip(m_last_block_processed)) {
1292 return;
1293 }
1294 }
1295
1296 // ...otherwise put a callback in the validation interface queue and wait
1297 // for the queue to drain enough to execute it (indicating we are caught up
1298 // at least with the time we entered this function).
1299 SyncWithValidationInterfaceQueue();
1300 }
1301
1302
IsMine(const CTxIn & txin) const1303 isminetype CWallet::IsMine(const CTxIn &txin) const
1304 {
1305 {
1306 LOCK(cs_wallet);
1307 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1308 if (mi != mapWallet.end())
1309 {
1310 const CWalletTx& prev = (*mi).second;
1311 if (txin.prevout.n < prev.tx->vout.size())
1312 return IsMine(prev.tx->vout[txin.prevout.n]);
1313 }
1314 }
1315 return ISMINE_NO;
1316 }
1317
1318 // Note that this function doesn't distinguish between a 0-valued input,
1319 // and a not-"is mine" (according to the filter) input.
GetDebit(const CTxIn & txin,const isminefilter & filter) const1320 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
1321 {
1322 {
1323 LOCK(cs_wallet);
1324 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1325 if (mi != mapWallet.end())
1326 {
1327 const CWalletTx& prev = (*mi).second;
1328 if (txin.prevout.n < prev.tx->vout.size())
1329 if (IsMine(prev.tx->vout[txin.prevout.n]) & filter)
1330 return prev.tx->vout[txin.prevout.n].nValue;
1331 }
1332 }
1333 return 0;
1334 }
1335
IsMine(const CTxOut & txout) const1336 isminetype CWallet::IsMine(const CTxOut& txout) const
1337 {
1338 return ::IsMine(*this, txout.scriptPubKey);
1339 }
1340
GetCredit(const CTxOut & txout,const isminefilter & filter) const1341 CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
1342 {
1343 if (!MoneyRange(txout.nValue))
1344 throw std::runtime_error(std::string(__func__) + ": value out of range");
1345 return ((IsMine(txout) & filter) ? txout.nValue : 0);
1346 }
1347
IsChange(const CTxOut & txout) const1348 bool CWallet::IsChange(const CTxOut& txout) const
1349 {
1350 return IsChange(txout.scriptPubKey);
1351 }
1352
IsChange(const CScript & script) const1353 bool CWallet::IsChange(const CScript& script) const
1354 {
1355 // TODO: fix handling of 'change' outputs. The assumption is that any
1356 // payment to a script that is ours, but is not in the address book
1357 // is change. That assumption is likely to break when we implement multisignature
1358 // wallets that return change back into a multi-signature-protected address;
1359 // a better way of identifying which outputs are 'the send' and which are
1360 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
1361 // which output, if any, was change).
1362 if (::IsMine(*this, script))
1363 {
1364 CTxDestination address;
1365 if (!ExtractDestination(script, address))
1366 return true;
1367
1368 LOCK(cs_wallet);
1369 if (!mapAddressBook.count(address))
1370 return true;
1371 }
1372 return false;
1373 }
1374
GetChange(const CTxOut & txout) const1375 CAmount CWallet::GetChange(const CTxOut& txout) const
1376 {
1377 if (!MoneyRange(txout.nValue))
1378 throw std::runtime_error(std::string(__func__) + ": value out of range");
1379 return (IsChange(txout) ? txout.nValue : 0);
1380 }
1381
IsMine(const CTransaction & tx) const1382 bool CWallet::IsMine(const CTransaction& tx) const
1383 {
1384 for (const CTxOut& txout : tx.vout)
1385 if (IsMine(txout))
1386 return true;
1387 return false;
1388 }
1389
IsFromMe(const CTransaction & tx) const1390 bool CWallet::IsFromMe(const CTransaction& tx) const
1391 {
1392 return (GetDebit(tx, ISMINE_ALL) > 0);
1393 }
1394
GetDebit(const CTransaction & tx,const isminefilter & filter) const1395 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1396 {
1397 CAmount nDebit = 0;
1398 for (const CTxIn& txin : tx.vin)
1399 {
1400 nDebit += GetDebit(txin, filter);
1401 if (!MoneyRange(nDebit))
1402 throw std::runtime_error(std::string(__func__) + ": value out of range");
1403 }
1404 return nDebit;
1405 }
1406
IsAllFromMe(const CTransaction & tx,const isminefilter & filter) const1407 bool CWallet::IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const
1408 {
1409 LOCK(cs_wallet);
1410
1411 for (const CTxIn& txin : tx.vin)
1412 {
1413 auto mi = mapWallet.find(txin.prevout.hash);
1414 if (mi == mapWallet.end())
1415 return false; // any unknown inputs can't be from us
1416
1417 const CWalletTx& prev = (*mi).second;
1418
1419 if (txin.prevout.n >= prev.tx->vout.size())
1420 return false; // invalid input!
1421
1422 if (!(IsMine(prev.tx->vout[txin.prevout.n]) & filter))
1423 return false;
1424 }
1425 return true;
1426 }
1427
GetCredit(const CTransaction & tx,const isminefilter & filter) const1428 CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
1429 {
1430 CAmount nCredit = 0;
1431 for (const CTxOut& txout : tx.vout)
1432 {
1433 nCredit += GetCredit(txout, filter);
1434 if (!MoneyRange(nCredit))
1435 throw std::runtime_error(std::string(__func__) + ": value out of range");
1436 }
1437 return nCredit;
1438 }
1439
GetChange(const CTransaction & tx) const1440 CAmount CWallet::GetChange(const CTransaction& tx) const
1441 {
1442 CAmount nChange = 0;
1443 for (const CTxOut& txout : tx.vout)
1444 {
1445 nChange += GetChange(txout);
1446 if (!MoneyRange(nChange))
1447 throw std::runtime_error(std::string(__func__) + ": value out of range");
1448 }
1449 return nChange;
1450 }
1451
GenerateNewSeed()1452 CPubKey CWallet::GenerateNewSeed()
1453 {
1454 assert(!IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
1455 CKey key;
1456 key.MakeNewKey(true);
1457 return DeriveNewSeed(key);
1458 }
1459
DeriveNewSeed(const CKey & key)1460 CPubKey CWallet::DeriveNewSeed(const CKey& key)
1461 {
1462 int64_t nCreationTime = GetTime();
1463 CKeyMetadata metadata(nCreationTime);
1464
1465 // calculate the seed
1466 CPubKey seed = key.GetPubKey();
1467 assert(key.VerifyPubKey(seed));
1468
1469 // set the hd keypath to "s" -> Seed, refers the seed to itself
1470 metadata.hdKeypath = "s";
1471 metadata.has_key_origin = false;
1472 metadata.hd_seed_id = seed.GetID();
1473
1474 {
1475 LOCK(cs_wallet);
1476
1477 // mem store the metadata
1478 mapKeyMetadata[seed.GetID()] = metadata;
1479
1480 // write the key&metadata to the database
1481 if (!AddKeyPubKey(key, seed))
1482 throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
1483 }
1484
1485 return seed;
1486 }
1487
SetHDSeed(const CPubKey & seed)1488 void CWallet::SetHDSeed(const CPubKey& seed)
1489 {
1490 LOCK(cs_wallet);
1491 // store the keyid (hash160) together with
1492 // the child index counter in the database
1493 // as a hdchain object
1494 CHDChain newHdChain;
1495 newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
1496 newHdChain.seed_id = seed.GetID();
1497 SetHDChain(newHdChain, false);
1498 NotifyCanGetAddressesChanged();
1499 UnsetWalletFlag(WALLET_FLAG_BLANK_WALLET);
1500 }
1501
SetHDChain(const CHDChain & chain,bool memonly)1502 void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
1503 {
1504 LOCK(cs_wallet);
1505 if (!memonly && !WalletBatch(*database).WriteHDChain(chain))
1506 throw std::runtime_error(std::string(__func__) + ": writing chain failed");
1507
1508 hdChain = chain;
1509 }
1510
IsHDEnabled() const1511 bool CWallet::IsHDEnabled() const
1512 {
1513 return !hdChain.seed_id.IsNull();
1514 }
1515
CanGenerateKeys()1516 bool CWallet::CanGenerateKeys()
1517 {
1518 // A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD)
1519 LOCK(cs_wallet);
1520 return IsHDEnabled() || !CanSupportFeature(FEATURE_HD);
1521 }
1522
CanGetAddresses(bool internal)1523 bool CWallet::CanGetAddresses(bool internal)
1524 {
1525 LOCK(cs_wallet);
1526 // Check if the keypool has keys
1527 bool keypool_has_keys;
1528 if (internal && CanSupportFeature(FEATURE_HD_SPLIT)) {
1529 keypool_has_keys = setInternalKeyPool.size() > 0;
1530 } else {
1531 keypool_has_keys = KeypoolCountExternalKeys() > 0;
1532 }
1533 // If the keypool doesn't have keys, check if we can generate them
1534 if (!keypool_has_keys) {
1535 return CanGenerateKeys();
1536 }
1537 return keypool_has_keys;
1538 }
1539
SetWalletFlag(uint64_t flags)1540 void CWallet::SetWalletFlag(uint64_t flags)
1541 {
1542 LOCK(cs_wallet);
1543 m_wallet_flags |= flags;
1544 if (!WalletBatch(*database).WriteWalletFlags(m_wallet_flags))
1545 throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1546 }
1547
UnsetWalletFlag(uint64_t flag)1548 void CWallet::UnsetWalletFlag(uint64_t flag)
1549 {
1550 LOCK(cs_wallet);
1551 m_wallet_flags &= ~flag;
1552 if (!WalletBatch(*database).WriteWalletFlags(m_wallet_flags))
1553 throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1554 }
1555
IsWalletFlagSet(uint64_t flag)1556 bool CWallet::IsWalletFlagSet(uint64_t flag)
1557 {
1558 return (m_wallet_flags & flag);
1559 }
1560
SetWalletFlags(uint64_t overwriteFlags,bool memonly)1561 bool CWallet::SetWalletFlags(uint64_t overwriteFlags, bool memonly)
1562 {
1563 LOCK(cs_wallet);
1564 m_wallet_flags = overwriteFlags;
1565 if (((overwriteFlags & g_known_wallet_flags) >> 32) ^ (overwriteFlags >> 32)) {
1566 // contains unknown non-tolerable wallet flags
1567 return false;
1568 }
1569 if (!memonly && !WalletBatch(*database).WriteWalletFlags(m_wallet_flags)) {
1570 throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1571 }
1572
1573 return true;
1574 }
1575
GetTxTime() const1576 int64_t CWalletTx::GetTxTime() const
1577 {
1578 int64_t n = nTimeSmart;
1579 return n ? n : nTimeReceived;
1580 }
1581
1582 // Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
1583 // or a max-sized low-S signature (e.g. 72 bytes) if use_max_sig is true
DummySignInput(CTxIn & tx_in,const CTxOut & txout,bool use_max_sig) const1584 bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig) const
1585 {
1586 // Fill in dummy signatures for fee calculation.
1587 const CScript& scriptPubKey = txout.scriptPubKey;
1588 SignatureData sigdata;
1589
1590 if (!ProduceSignature(*this, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) {
1591 return false;
1592 }
1593 UpdateInput(tx_in, sigdata);
1594 return true;
1595 }
1596
1597 // Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 bytes)
DummySignTx(CMutableTransaction & txNew,const std::vector<CTxOut> & txouts,bool use_max_sig) const1598 bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig) const
1599 {
1600 // Fill in dummy signatures for fee calculation.
1601 int nIn = 0;
1602 for (const auto& txout : txouts)
1603 {
1604 if (!DummySignInput(txNew.vin[nIn], txout, use_max_sig)) {
1605 return false;
1606 }
1607
1608 nIn++;
1609 }
1610 return true;
1611 }
1612
CalculateMaximumSignedTxSize(const CTransaction & tx,const CWallet * wallet,bool use_max_sig)1613 int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
1614 {
1615 std::vector<CTxOut> txouts;
1616 // Look up the inputs. We should have already checked that this transaction
1617 // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our
1618 // wallet, with a valid index into the vout array, and the ability to sign.
1619 for (const CTxIn& input : tx.vin) {
1620 const auto mi = wallet->mapWallet.find(input.prevout.hash);
1621 if (mi == wallet->mapWallet.end()) {
1622 return -1;
1623 }
1624 assert(input.prevout.n < mi->second.tx->vout.size());
1625 txouts.emplace_back(mi->second.tx->vout[input.prevout.n]);
1626 }
1627 return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig);
1628 }
1629
1630 // txouts needs to be in the order of tx.vin
CalculateMaximumSignedTxSize(const CTransaction & tx,const CWallet * wallet,const std::vector<CTxOut> & txouts,bool use_max_sig)1631 int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig)
1632 {
1633 CMutableTransaction txNew(tx);
1634 if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) {
1635 // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
1636 // implies that we can sign for every input.
1637 return -1;
1638 }
1639 return GetVirtualTransactionSize(CTransaction(txNew));
1640 }
1641
CalculateMaximumSignedInputSize(const CTxOut & txout,const CWallet * wallet,bool use_max_sig)1642 int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, bool use_max_sig)
1643 {
1644 CMutableTransaction txn;
1645 txn.vin.push_back(CTxIn(COutPoint()));
1646 if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
1647 return -1;
1648 }
1649 return GetVirtualTransactionInputSize(txn.vin[0]);
1650 }
1651
GetAmounts(std::list<COutputEntry> & listReceived,std::list<COutputEntry> & listSent,CAmount & nFee,const isminefilter & filter) const1652 void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
1653 std::list<COutputEntry>& listSent, CAmount& nFee, const isminefilter& filter) const
1654 {
1655 nFee = 0;
1656 listReceived.clear();
1657 listSent.clear();
1658
1659 // Compute fee:
1660 CAmount nDebit = GetDebit(filter);
1661 if (nDebit > 0) // debit>0 means we signed/sent this transaction
1662 {
1663 CAmount nValueOut = tx->GetValueOut();
1664 nFee = nDebit - nValueOut;
1665 }
1666
1667 // Sent/received.
1668 for (unsigned int i = 0; i < tx->vout.size(); ++i)
1669 {
1670 const CTxOut& txout = tx->vout[i];
1671 isminetype fIsMine = pwallet->IsMine(txout);
1672 // Only need to handle txouts if AT LEAST one of these is true:
1673 // 1) they debit from us (sent)
1674 // 2) the output is to us (received)
1675 if (nDebit > 0)
1676 {
1677 // Don't report 'change' txouts
1678 if (pwallet->IsChange(txout))
1679 continue;
1680 }
1681 else if (!(fIsMine & filter))
1682 continue;
1683
1684 // In either case, we need to get the destination address
1685 CTxDestination address;
1686
1687 if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable())
1688 {
1689 pwallet->WalletLogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
1690 this->GetHash().ToString());
1691 address = CNoDestination();
1692 }
1693
1694 COutputEntry output = {address, txout.nValue, (int)i};
1695
1696 // If we are debited by the transaction, add the output as a "sent" entry
1697 if (nDebit > 0)
1698 listSent.push_back(output);
1699
1700 // If we are receiving the output, add it as a "received" entry
1701 if (fIsMine & filter)
1702 listReceived.push_back(output);
1703 }
1704
1705 }
1706
1707 /**
1708 * Scan active chain for relevant transactions after importing keys. This should
1709 * be called whenever new keys are added to the wallet, with the oldest key
1710 * creation time.
1711 *
1712 * @return Earliest timestamp that could be successfully scanned from. Timestamp
1713 * returned will be higher than startTime if relevant blocks could not be read.
1714 */
RescanFromTime(int64_t startTime,const WalletRescanReserver & reserver,bool update)1715 int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update)
1716 {
1717 // Find starting block. May be null if nCreateTime is greater than the
1718 // highest blockchain timestamp, in which case there is nothing that needs
1719 // to be scanned.
1720 uint256 start_block;
1721 {
1722 auto locked_chain = chain().lock();
1723 const Optional<int> start_height = locked_chain->findFirstBlockWithTime(startTime - TIMESTAMP_WINDOW, &start_block);
1724 const Optional<int> tip_height = locked_chain->getHeight();
1725 WalletLogPrintf("%s: Rescanning last %i blocks\n", __func__, tip_height && start_height ? *tip_height - *start_height + 1 : 0);
1726 }
1727
1728 if (!start_block.IsNull()) {
1729 // TODO: this should take into account failure by ScanResult::USER_ABORT
1730 ScanResult result = ScanForWalletTransactions(start_block, {} /* stop_block */, reserver, update);
1731 if (result.status == ScanResult::FAILURE) {
1732 int64_t time_max;
1733 if (!chain().findBlock(result.last_failed_block, nullptr /* block */, nullptr /* time */, &time_max)) {
1734 throw std::logic_error("ScanForWalletTransactions returned invalid block hash");
1735 }
1736 return time_max + TIMESTAMP_WINDOW + 1;
1737 }
1738 }
1739 return startTime;
1740 }
1741
1742 /**
1743 * Scan the block chain (starting in start_block) for transactions
1744 * from or to us. If fUpdate is true, found transactions that already
1745 * exist in the wallet will be updated.
1746 *
1747 * @param[in] start_block Scan starting block. If block is not on the active
1748 * chain, the scan will return SUCCESS immediately.
1749 * @param[in] stop_block Scan ending block. If block is not on the active
1750 * chain, the scan will continue until it reaches the
1751 * chain tip.
1752 *
1753 * @return ScanResult returning scan information and indicating success or
1754 * failure. Return status will be set to SUCCESS if scan was
1755 * successful. FAILURE if a complete rescan was not possible (due to
1756 * pruning or corruption). USER_ABORT if the rescan was aborted before
1757 * it could complete.
1758 *
1759 * @pre Caller needs to make sure start_block (and the optional stop_block) are on
1760 * the main chain after to the addition of any new keys you want to detect
1761 * transactions for.
1762 */
ScanForWalletTransactions(const uint256 & start_block,const uint256 & stop_block,const WalletRescanReserver & reserver,bool fUpdate)1763 CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_block, const uint256& stop_block, const WalletRescanReserver& reserver, bool fUpdate)
1764 {
1765 int64_t nNow = GetTime();
1766
1767 assert(reserver.isReserved());
1768
1769 uint256 block_hash = start_block;
1770 ScanResult result;
1771
1772 WalletLogPrintf("Rescan started from block %s...\n", start_block.ToString());
1773
1774 {
1775 fAbortRescan = false;
1776 ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1777 uint256 tip_hash;
1778 // The way the 'block_height' is initialized is just a workaround for the gcc bug #47679 since version 4.6.0.
1779 Optional<int> block_height = MakeOptional(false, int());
1780 double progress_begin;
1781 double progress_end;
1782 {
1783 auto locked_chain = chain().lock();
1784 if (Optional<int> tip_height = locked_chain->getHeight()) {
1785 tip_hash = locked_chain->getBlockHash(*tip_height);
1786 }
1787 block_height = locked_chain->getBlockHeight(block_hash);
1788 progress_begin = chain().guessVerificationProgress(block_hash);
1789 progress_end = chain().guessVerificationProgress(stop_block.IsNull() ? tip_hash : stop_block);
1790 }
1791 double progress_current = progress_begin;
1792 while (block_height && !fAbortRescan && !ShutdownRequested()) {
1793 if (*block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1794 ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), std::max(1, std::min(99, (int)((progress_current - progress_begin) / (progress_end - progress_begin) * 100))));
1795 }
1796 if (GetTime() >= nNow + 60) {
1797 nNow = GetTime();
1798 WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", *block_height, progress_current);
1799 }
1800
1801 CBlock block;
1802 if (chain().findBlock(block_hash, &block) && !block.IsNull()) {
1803 auto locked_chain = chain().lock();
1804 LOCK(cs_wallet);
1805 if (!locked_chain->getBlockHeight(block_hash)) {
1806 // Abort scan if current block is no longer active, to prevent
1807 // marking transactions as coming from the wrong block.
1808 // TODO: This should return success instead of failure, see
1809 // https://github.com/bitcoin/bitcoin/pull/14711#issuecomment-458342518
1810 result.last_failed_block = block_hash;
1811 result.status = ScanResult::FAILURE;
1812 break;
1813 }
1814 for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
1815 SyncTransaction(block.vtx[posInBlock], block_hash, posInBlock, fUpdate);
1816 }
1817 // scan succeeded, record block as most recent successfully scanned
1818 result.last_scanned_block = block_hash;
1819 result.last_scanned_height = *block_height;
1820 } else {
1821 // could not scan block, keep scanning but record this block as the most recent failure
1822 result.last_failed_block = block_hash;
1823 result.status = ScanResult::FAILURE;
1824 }
1825 if (block_hash == stop_block) {
1826 break;
1827 }
1828 {
1829 auto locked_chain = chain().lock();
1830 Optional<int> tip_height = locked_chain->getHeight();
1831 if (!tip_height || *tip_height <= block_height || !locked_chain->getBlockHeight(block_hash)) {
1832 // break successfully when rescan has reached the tip, or
1833 // previous block is no longer on the chain due to a reorg
1834 break;
1835 }
1836
1837 // increment block and verification progress
1838 block_hash = locked_chain->getBlockHash(++*block_height);
1839 progress_current = chain().guessVerificationProgress(block_hash);
1840
1841 // handle updated tip hash
1842 const uint256 prev_tip_hash = tip_hash;
1843 tip_hash = locked_chain->getBlockHash(*tip_height);
1844 if (stop_block.IsNull() && prev_tip_hash != tip_hash) {
1845 // in case the tip has changed, update progress max
1846 progress_end = chain().guessVerificationProgress(tip_hash);
1847 }
1848 }
1849 }
1850 ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), 100); // hide progress dialog in GUI
1851 if (block_height && fAbortRescan) {
1852 WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", *block_height, progress_current);
1853 result.status = ScanResult::USER_ABORT;
1854 } else if (block_height && ShutdownRequested()) {
1855 WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", *block_height, progress_current);
1856 result.status = ScanResult::USER_ABORT;
1857 }
1858 }
1859 return result;
1860 }
1861
ReacceptWalletTransactions(interfaces::Chain::Lock & locked_chain)1862 void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
1863 {
1864 // If transactions aren't being broadcasted, don't let them into local mempool either
1865 if (!fBroadcastTransactions)
1866 return;
1867 std::map<int64_t, CWalletTx*> mapSorted;
1868
1869 // Sort pending wallet transactions based on their initial wallet insertion order
1870 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
1871 {
1872 const uint256& wtxid = item.first;
1873 CWalletTx& wtx = item.second;
1874 assert(wtx.GetHash() == wtxid);
1875
1876 int nDepth = wtx.GetDepthInMainChain(locked_chain);
1877
1878 if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
1879 mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
1880 }
1881 }
1882
1883 // Try to add wallet transactions to memory pool
1884 for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
1885 CWalletTx& wtx = *(item.second);
1886 CValidationState state;
1887 wtx.AcceptToMemoryPool(locked_chain, maxTxFee, state);
1888 }
1889 }
1890
RelayWalletTransaction(interfaces::Chain::Lock & locked_chain,CConnman * connman)1891 bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain, CConnman* connman)
1892 {
1893 assert(pwallet->GetBroadcastTransactions());
1894 if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain(locked_chain) == 0)
1895 {
1896 CValidationState state;
1897 /* GetDepthInMainChain already catches known conflicts. */
1898 if (InMempool() || AcceptToMemoryPool(locked_chain, maxTxFee, state)) {
1899 pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
1900 if (connman) {
1901 CInv inv(MSG_TX, GetHash());
1902 connman->ForEachNode([&inv](CNode* pnode)
1903 {
1904 pnode->PushInventory(inv);
1905 });
1906 return true;
1907 }
1908 }
1909 }
1910 return false;
1911 }
1912
GetConflicts() const1913 std::set<uint256> CWalletTx::GetConflicts() const
1914 {
1915 std::set<uint256> result;
1916 if (pwallet != nullptr)
1917 {
1918 uint256 myHash = GetHash();
1919 result = pwallet->GetConflicts(myHash);
1920 result.erase(myHash);
1921 }
1922 return result;
1923 }
1924
GetDebit(const isminefilter & filter) const1925 CAmount CWalletTx::GetDebit(const isminefilter& filter) const
1926 {
1927 if (tx->vin.empty())
1928 return 0;
1929
1930 CAmount debit = 0;
1931 if(filter & ISMINE_SPENDABLE)
1932 {
1933 if (fDebitCached)
1934 debit += nDebitCached;
1935 else
1936 {
1937 nDebitCached = pwallet->GetDebit(*tx, ISMINE_SPENDABLE);
1938 fDebitCached = true;
1939 debit += nDebitCached;
1940 }
1941 }
1942 if(filter & ISMINE_WATCH_ONLY)
1943 {
1944 if(fWatchDebitCached)
1945 debit += nWatchDebitCached;
1946 else
1947 {
1948 nWatchDebitCached = pwallet->GetDebit(*tx, ISMINE_WATCH_ONLY);
1949 fWatchDebitCached = true;
1950 debit += nWatchDebitCached;
1951 }
1952 }
1953 return debit;
1954 }
1955
GetCredit(interfaces::Chain::Lock & locked_chain,const isminefilter & filter) const1956 CAmount CWalletTx::GetCredit(interfaces::Chain::Lock& locked_chain, const isminefilter& filter) const
1957 {
1958 // Must wait until coinbase is safely deep enough in the chain before valuing it
1959 if (IsImmatureCoinBase(locked_chain))
1960 return 0;
1961
1962 CAmount credit = 0;
1963 if (filter & ISMINE_SPENDABLE)
1964 {
1965 // GetBalance can assume transactions in mapWallet won't change
1966 if (fCreditCached)
1967 credit += nCreditCached;
1968 else
1969 {
1970 nCreditCached = pwallet->GetCredit(*tx, ISMINE_SPENDABLE);
1971 fCreditCached = true;
1972 credit += nCreditCached;
1973 }
1974 }
1975 if (filter & ISMINE_WATCH_ONLY)
1976 {
1977 if (fWatchCreditCached)
1978 credit += nWatchCreditCached;
1979 else
1980 {
1981 nWatchCreditCached = pwallet->GetCredit(*tx, ISMINE_WATCH_ONLY);
1982 fWatchCreditCached = true;
1983 credit += nWatchCreditCached;
1984 }
1985 }
1986 return credit;
1987 }
1988
GetImmatureCredit(interfaces::Chain::Lock & locked_chain,bool fUseCache) const1989 CAmount CWalletTx::GetImmatureCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache) const
1990 {
1991 if (IsImmatureCoinBase(locked_chain) && IsInMainChain(locked_chain)) {
1992 if (fUseCache && fImmatureCreditCached)
1993 return nImmatureCreditCached;
1994 nImmatureCreditCached = pwallet->GetCredit(*tx, ISMINE_SPENDABLE);
1995 fImmatureCreditCached = true;
1996 return nImmatureCreditCached;
1997 }
1998
1999 return 0;
2000 }
2001
GetAvailableCredit(interfaces::Chain::Lock & locked_chain,bool fUseCache,const isminefilter & filter) const2002 CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache, const isminefilter& filter) const
2003 {
2004 if (pwallet == nullptr)
2005 return 0;
2006
2007 // Must wait until coinbase is safely deep enough in the chain before valuing it
2008 if (IsImmatureCoinBase(locked_chain))
2009 return 0;
2010
2011 CAmount* cache = nullptr;
2012 bool* cache_used = nullptr;
2013
2014 if (filter == ISMINE_SPENDABLE) {
2015 cache = &nAvailableCreditCached;
2016 cache_used = &fAvailableCreditCached;
2017 } else if (filter == ISMINE_WATCH_ONLY) {
2018 cache = &nAvailableWatchCreditCached;
2019 cache_used = &fAvailableWatchCreditCached;
2020 }
2021
2022 if (fUseCache && cache_used && *cache_used) {
2023 return *cache;
2024 }
2025
2026 CAmount nCredit = 0;
2027 uint256 hashTx = GetHash();
2028 for (unsigned int i = 0; i < tx->vout.size(); i++)
2029 {
2030 if (!pwallet->IsSpent(locked_chain, hashTx, i))
2031 {
2032 const CTxOut &txout = tx->vout[i];
2033 nCredit += pwallet->GetCredit(txout, filter);
2034 if (!MoneyRange(nCredit))
2035 throw std::runtime_error(std::string(__func__) + " : value out of range");
2036 }
2037 }
2038
2039 if (cache) {
2040 *cache = nCredit;
2041 assert(cache_used);
2042 *cache_used = true;
2043 }
2044 return nCredit;
2045 }
2046
GetImmatureWatchOnlyCredit(interfaces::Chain::Lock & locked_chain,const bool fUseCache) const2047 CAmount CWalletTx::GetImmatureWatchOnlyCredit(interfaces::Chain::Lock& locked_chain, const bool fUseCache) const
2048 {
2049 if (IsImmatureCoinBase(locked_chain) && IsInMainChain(locked_chain)) {
2050 if (fUseCache && fImmatureWatchCreditCached)
2051 return nImmatureWatchCreditCached;
2052 nImmatureWatchCreditCached = pwallet->GetCredit(*tx, ISMINE_WATCH_ONLY);
2053 fImmatureWatchCreditCached = true;
2054 return nImmatureWatchCreditCached;
2055 }
2056
2057 return 0;
2058 }
2059
GetChange() const2060 CAmount CWalletTx::GetChange() const
2061 {
2062 if (fChangeCached)
2063 return nChangeCached;
2064 nChangeCached = pwallet->GetChange(*tx);
2065 fChangeCached = true;
2066 return nChangeCached;
2067 }
2068
InMempool() const2069 bool CWalletTx::InMempool() const
2070 {
2071 return fInMempool;
2072 }
2073
IsTrusted(interfaces::Chain::Lock & locked_chain) const2074 bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain) const
2075 {
2076 LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
2077
2078 // Quick answer in most cases
2079 if (!CheckFinalTx(*tx))
2080 return false;
2081 int nDepth = GetDepthInMainChain(locked_chain);
2082 if (nDepth >= 1)
2083 return true;
2084 if (nDepth < 0)
2085 return false;
2086 if (!pwallet->m_spend_zero_conf_change || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
2087 return false;
2088
2089 // Don't trust unconfirmed transactions from us unless they are in the mempool.
2090 if (!InMempool())
2091 return false;
2092
2093 // Trusted if all inputs are from us and are in the mempool:
2094 for (const CTxIn& txin : tx->vin)
2095 {
2096 // Transactions not sent by us: not trusted
2097 const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
2098 if (parent == nullptr)
2099 return false;
2100 const CTxOut& parentOut = parent->tx->vout[txin.prevout.n];
2101 if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
2102 return false;
2103 }
2104 return true;
2105 }
2106
IsEquivalentTo(const CWalletTx & _tx) const2107 bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
2108 {
2109 CMutableTransaction tx1 {*this->tx};
2110 CMutableTransaction tx2 {*_tx.tx};
2111 for (auto& txin : tx1.vin) txin.scriptSig = CScript();
2112 for (auto& txin : tx2.vin) txin.scriptSig = CScript();
2113 return CTransaction(tx1) == CTransaction(tx2);
2114 }
2115
ResendWalletTransactionsBefore(interfaces::Chain::Lock & locked_chain,int64_t nTime,CConnman * connman)2116 std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime, CConnman* connman)
2117 {
2118 std::vector<uint256> result;
2119
2120 LOCK(cs_wallet);
2121
2122 // Sort them in chronological order
2123 std::multimap<unsigned int, CWalletTx*> mapSorted;
2124 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
2125 {
2126 CWalletTx& wtx = item.second;
2127 // Don't rebroadcast if newer than nTime:
2128 if (wtx.nTimeReceived > nTime)
2129 continue;
2130 mapSorted.insert(std::make_pair(wtx.nTimeReceived, &wtx));
2131 }
2132 for (const std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
2133 {
2134 CWalletTx& wtx = *item.second;
2135 if (wtx.RelayWalletTransaction(locked_chain, connman))
2136 result.push_back(wtx.GetHash());
2137 }
2138 return result;
2139 }
2140
ResendWalletTransactions(int64_t nBestBlockTime,CConnman * connman)2141 void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman)
2142 {
2143 // Do this infrequently and randomly to avoid giving away
2144 // that these are our transactions.
2145 if (GetTime() < nNextResend || !fBroadcastTransactions)
2146 return;
2147 bool fFirst = (nNextResend == 0);
2148 nNextResend = GetTime() + GetRand(30 * 60);
2149 if (fFirst)
2150 return;
2151
2152 // Only do it if there's been a new block since last time
2153 if (nBestBlockTime < nLastResend)
2154 return;
2155 nLastResend = GetTime();
2156
2157 // Rebroadcast unconfirmed txes older than 5 minutes before the last
2158 // block was found:
2159 auto locked_chain = chain().assumeLocked(); // Temporary. Removed in upcoming lock cleanup
2160 std::vector<uint256> relayed = ResendWalletTransactionsBefore(*locked_chain, nBestBlockTime-5*60, connman);
2161 if (!relayed.empty())
2162 WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
2163 }
2164
2165 /** @} */ // end of mapWallet
2166
2167
2168
2169
2170 /** @defgroup Actions
2171 *
2172 * @{
2173 */
2174
2175
GetBalance(const isminefilter & filter,const int min_depth) const2176 CAmount CWallet::GetBalance(const isminefilter& filter, const int min_depth) const
2177 {
2178 CAmount nTotal = 0;
2179 {
2180 auto locked_chain = chain().lock();
2181 LOCK(cs_wallet);
2182 for (const auto& entry : mapWallet)
2183 {
2184 const CWalletTx* pcoin = &entry.second;
2185 if (pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) >= min_depth) {
2186 nTotal += pcoin->GetAvailableCredit(*locked_chain, true, filter);
2187 }
2188 }
2189 }
2190
2191 return nTotal;
2192 }
2193
GetUnconfirmedBalance() const2194 CAmount CWallet::GetUnconfirmedBalance() const
2195 {
2196 CAmount nTotal = 0;
2197 {
2198 auto locked_chain = chain().lock();
2199 LOCK(cs_wallet);
2200 for (const auto& entry : mapWallet)
2201 {
2202 const CWalletTx* pcoin = &entry.second;
2203 if (!pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) == 0 && pcoin->InMempool())
2204 nTotal += pcoin->GetAvailableCredit(*locked_chain);
2205 }
2206 }
2207 return nTotal;
2208 }
2209
GetImmatureBalance() const2210 CAmount CWallet::GetImmatureBalance() const
2211 {
2212 CAmount nTotal = 0;
2213 {
2214 auto locked_chain = chain().lock();
2215 LOCK(cs_wallet);
2216 for (const auto& entry : mapWallet)
2217 {
2218 const CWalletTx* pcoin = &entry.second;
2219 nTotal += pcoin->GetImmatureCredit(*locked_chain);
2220 }
2221 }
2222 return nTotal;
2223 }
2224
GetUnconfirmedWatchOnlyBalance() const2225 CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
2226 {
2227 CAmount nTotal = 0;
2228 {
2229 auto locked_chain = chain().lock();
2230 LOCK(cs_wallet);
2231 for (const auto& entry : mapWallet)
2232 {
2233 const CWalletTx* pcoin = &entry.second;
2234 if (!pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) == 0 && pcoin->InMempool())
2235 nTotal += pcoin->GetAvailableCredit(*locked_chain, true, ISMINE_WATCH_ONLY);
2236 }
2237 }
2238 return nTotal;
2239 }
2240
GetImmatureWatchOnlyBalance() const2241 CAmount CWallet::GetImmatureWatchOnlyBalance() const
2242 {
2243 CAmount nTotal = 0;
2244 {
2245 auto locked_chain = chain().lock();
2246 LOCK(cs_wallet);
2247 for (const auto& entry : mapWallet)
2248 {
2249 const CWalletTx* pcoin = &entry.second;
2250 nTotal += pcoin->GetImmatureWatchOnlyCredit(*locked_chain);
2251 }
2252 }
2253 return nTotal;
2254 }
2255
2256 // Calculate total balance in a different way from GetBalance. The biggest
2257 // difference is that GetBalance sums up all unspent TxOuts paying to the
2258 // wallet, while this sums up both spent and unspent TxOuts paying to the
2259 // wallet, and then subtracts the values of TxIns spending from the wallet. This
2260 // also has fewer restrictions on which unconfirmed transactions are considered
2261 // trusted.
GetLegacyBalance(const isminefilter & filter,int minDepth) const2262 CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth) const
2263 {
2264 LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
2265 auto locked_chain = chain().lock();
2266 LOCK(cs_wallet);
2267
2268 CAmount balance = 0;
2269 for (const auto& entry : mapWallet) {
2270 const CWalletTx& wtx = entry.second;
2271 const int depth = wtx.GetDepthInMainChain(*locked_chain);
2272 if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase(*locked_chain)) {
2273 continue;
2274 }
2275
2276 // Loop through tx outputs and add incoming payments. For outgoing txs,
2277 // treat change outputs specially, as part of the amount debited.
2278 CAmount debit = wtx.GetDebit(filter);
2279 const bool outgoing = debit > 0;
2280 for (const CTxOut& out : wtx.tx->vout) {
2281 if (outgoing && IsChange(out)) {
2282 debit -= out.nValue;
2283 } else if (IsMine(out) & filter && depth >= minDepth) {
2284 balance += out.nValue;
2285 }
2286 }
2287
2288 // For outgoing txs, subtract amount debited.
2289 if (outgoing) {
2290 balance -= debit;
2291 }
2292 }
2293
2294 return balance;
2295 }
2296
GetAvailableBalance(const CCoinControl * coinControl) const2297 CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const
2298 {
2299 auto locked_chain = chain().lock();
2300 LOCK(cs_wallet);
2301
2302 CAmount balance = 0;
2303 std::vector<COutput> vCoins;
2304 AvailableCoins(*locked_chain, vCoins, true, coinControl);
2305 for (const COutput& out : vCoins) {
2306 if (out.fSpendable) {
2307 balance += out.tx->tx->vout[out.i].nValue;
2308 }
2309 }
2310 return balance;
2311 }
2312
AvailableCoins(interfaces::Chain::Lock & locked_chain,std::vector<COutput> & vCoins,bool fOnlySafe,const CCoinControl * coinControl,const CAmount & nMinimumAmount,const CAmount & nMaximumAmount,const CAmount & nMinimumSumAmount,const uint64_t nMaximumCount,const int nMinDepth,const int nMaxDepth) const2313 void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<COutput> &vCoins, bool fOnlySafe, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount, const int nMinDepth, const int nMaxDepth) const
2314 {
2315 AssertLockHeld(cs_main);
2316 AssertLockHeld(cs_wallet);
2317
2318 vCoins.clear();
2319 CAmount nTotal = 0;
2320
2321 for (const auto& entry : mapWallet)
2322 {
2323 const uint256& wtxid = entry.first;
2324 const CWalletTx* pcoin = &entry.second;
2325
2326 if (!CheckFinalTx(*pcoin->tx))
2327 continue;
2328
2329 if (pcoin->IsImmatureCoinBase(locked_chain))
2330 continue;
2331
2332 int nDepth = pcoin->GetDepthInMainChain(locked_chain);
2333 if (nDepth < 0)
2334 continue;
2335
2336 // We should not consider coins which aren't at least in our mempool
2337 // It's possible for these to be conflicted via ancestors which we may never be able to detect
2338 if (nDepth == 0 && !pcoin->InMempool())
2339 continue;
2340
2341 bool safeTx = pcoin->IsTrusted(locked_chain);
2342
2343 // We should not consider coins from transactions that are replacing
2344 // other transactions.
2345 //
2346 // Example: There is a transaction A which is replaced by bumpfee
2347 // transaction B. In this case, we want to prevent creation of
2348 // a transaction B' which spends an output of B.
2349 //
2350 // Reason: If transaction A were initially confirmed, transactions B
2351 // and B' would no longer be valid, so the user would have to create
2352 // a new transaction C to replace B'. However, in the case of a
2353 // one-block reorg, transactions B' and C might BOTH be accepted,
2354 // when the user only wanted one of them. Specifically, there could
2355 // be a 1-block reorg away from the chain where transactions A and C
2356 // were accepted to another chain where B, B', and C were all
2357 // accepted.
2358 if (nDepth == 0 && pcoin->mapValue.count("replaces_txid")) {
2359 safeTx = false;
2360 }
2361
2362 // Similarly, we should not consider coins from transactions that
2363 // have been replaced. In the example above, we would want to prevent
2364 // creation of a transaction A' spending an output of A, because if
2365 // transaction B were initially confirmed, conflicting with A and
2366 // A', we wouldn't want to the user to create a transaction D
2367 // intending to replace A', but potentially resulting in a scenario
2368 // where A, A', and D could all be accepted (instead of just B and
2369 // D, or just A and A' like the user would want).
2370 if (nDepth == 0 && pcoin->mapValue.count("replaced_by_txid")) {
2371 safeTx = false;
2372 }
2373
2374 if (fOnlySafe && !safeTx) {
2375 continue;
2376 }
2377
2378 if (nDepth < nMinDepth || nDepth > nMaxDepth)
2379 continue;
2380
2381 for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
2382 if (pcoin->tx->vout[i].nValue < nMinimumAmount || pcoin->tx->vout[i].nValue > nMaximumAmount)
2383 continue;
2384
2385 if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i)))
2386 continue;
2387
2388 if (IsLockedCoin(entry.first, i))
2389 continue;
2390
2391 if (IsSpent(locked_chain, wtxid, i))
2392 continue;
2393
2394 isminetype mine = IsMine(pcoin->tx->vout[i]);
2395
2396 if (mine == ISMINE_NO) {
2397 continue;
2398 }
2399
2400 bool solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
2401 bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
2402
2403 vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
2404
2405 // Checks the sum amount of all UTXO's.
2406 if (nMinimumSumAmount != MAX_MONEY) {
2407 nTotal += pcoin->tx->vout[i].nValue;
2408
2409 if (nTotal >= nMinimumSumAmount) {
2410 return;
2411 }
2412 }
2413
2414 // Checks the maximum number of UTXO's.
2415 if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
2416 return;
2417 }
2418 }
2419 }
2420 }
2421
ListCoins(interfaces::Chain::Lock & locked_chain) const2422 std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins(interfaces::Chain::Lock& locked_chain) const
2423 {
2424 AssertLockHeld(cs_main);
2425 AssertLockHeld(cs_wallet);
2426
2427 std::map<CTxDestination, std::vector<COutput>> result;
2428 std::vector<COutput> availableCoins;
2429
2430 AvailableCoins(locked_chain, availableCoins);
2431
2432 for (const COutput& coin : availableCoins) {
2433 CTxDestination address;
2434 if (coin.fSpendable &&
2435 ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2436 result[address].emplace_back(std::move(coin));
2437 }
2438 }
2439
2440 std::vector<COutPoint> lockedCoins;
2441 ListLockedCoins(lockedCoins);
2442 for (const COutPoint& output : lockedCoins) {
2443 auto it = mapWallet.find(output.hash);
2444 if (it != mapWallet.end()) {
2445 int depth = it->second.GetDepthInMainChain(locked_chain);
2446 if (depth >= 0 && output.n < it->second.tx->vout.size() &&
2447 IsMine(it->second.tx->vout[output.n]) == ISMINE_SPENDABLE) {
2448 CTxDestination address;
2449 if (ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2450 result[address].emplace_back(
2451 &it->second, output.n, depth, true /* spendable */, true /* solvable */, false /* safe */);
2452 }
2453 }
2454 }
2455 }
2456
2457 return result;
2458 }
2459
FindNonChangeParentOutput(const CTransaction & tx,int output) const2460 const CTxOut& CWallet::FindNonChangeParentOutput(const CTransaction& tx, int output) const
2461 {
2462 const CTransaction* ptx = &tx;
2463 int n = output;
2464 while (IsChange(ptx->vout[n]) && ptx->vin.size() > 0) {
2465 const COutPoint& prevout = ptx->vin[0].prevout;
2466 auto it = mapWallet.find(prevout.hash);
2467 if (it == mapWallet.end() || it->second.tx->vout.size() <= prevout.n ||
2468 !IsMine(it->second.tx->vout[prevout.n])) {
2469 break;
2470 }
2471 ptx = it->second.tx.get();
2472 n = prevout.n;
2473 }
2474 return ptx->vout[n];
2475 }
2476
SelectCoinsMinConf(const CAmount & nTargetValue,const CoinEligibilityFilter & eligibility_filter,std::vector<OutputGroup> groups,std::set<CInputCoin> & setCoinsRet,CAmount & nValueRet,const CoinSelectionParams & coin_selection_params,bool & bnb_used) const2477 bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, std::vector<OutputGroup> groups,
2478 std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CoinSelectionParams& coin_selection_params, bool& bnb_used) const
2479 {
2480 setCoinsRet.clear();
2481 nValueRet = 0;
2482
2483 std::vector<OutputGroup> utxo_pool;
2484 if (coin_selection_params.use_bnb) {
2485 // Get long term estimate
2486 FeeCalculation feeCalc;
2487 CCoinControl temp;
2488 temp.m_confirm_target = 1008;
2489 CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, ::mempool, ::feeEstimator, &feeCalc);
2490
2491 // Calculate cost of change
2492 CAmount cost_of_change = GetDiscardRate(*this, ::feeEstimator).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
2493
2494 // Filter by the min conf specs and add to utxo_pool and calculate effective value
2495 for (OutputGroup& group : groups) {
2496 if (!group.EligibleForSpending(eligibility_filter)) continue;
2497
2498 group.fee = 0;
2499 group.long_term_fee = 0;
2500 group.effective_value = 0;
2501 for (auto it = group.m_outputs.begin(); it != group.m_outputs.end(); ) {
2502 const CInputCoin& coin = *it;
2503 CAmount effective_value = coin.txout.nValue - (coin.m_input_bytes < 0 ? 0 : coin_selection_params.effective_fee.GetFee(coin.m_input_bytes));
2504 // Only include outputs that are positive effective value (i.e. not dust)
2505 if (effective_value > 0) {
2506 group.fee += coin.m_input_bytes < 0 ? 0 : coin_selection_params.effective_fee.GetFee(coin.m_input_bytes);
2507 group.long_term_fee += coin.m_input_bytes < 0 ? 0 : long_term_feerate.GetFee(coin.m_input_bytes);
2508 group.effective_value += effective_value;
2509 ++it;
2510 } else {
2511 it = group.Discard(coin);
2512 }
2513 }
2514 if (group.effective_value > 0) utxo_pool.push_back(group);
2515 }
2516 // Calculate the fees for things that aren't inputs
2517 CAmount not_input_fees = coin_selection_params.effective_fee.GetFee(coin_selection_params.tx_noinputs_size);
2518 bnb_used = true;
2519 return SelectCoinsBnB(utxo_pool, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
2520 } else {
2521 // Filter by the min conf specs and add to utxo_pool
2522 for (const OutputGroup& group : groups) {
2523 if (!group.EligibleForSpending(eligibility_filter)) continue;
2524 utxo_pool.push_back(group);
2525 }
2526 bnb_used = false;
2527 return KnapsackSolver(nTargetValue, utxo_pool, setCoinsRet, nValueRet);
2528 }
2529 }
2530
SelectCoins(const std::vector<COutput> & vAvailableCoins,const CAmount & nTargetValue,std::set<CInputCoin> & setCoinsRet,CAmount & nValueRet,const CCoinControl & coin_control,CoinSelectionParams & coin_selection_params,bool & bnb_used) const2531 bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl& coin_control, CoinSelectionParams& coin_selection_params, bool& bnb_used) const
2532 {
2533 std::vector<COutput> vCoins(vAvailableCoins);
2534
2535 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
2536 if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
2537 {
2538 // We didn't use BnB here, so set it to false.
2539 bnb_used = false;
2540
2541 for (const COutput& out : vCoins)
2542 {
2543 if (!out.fSpendable)
2544 continue;
2545 nValueRet += out.tx->tx->vout[out.i].nValue;
2546 setCoinsRet.insert(out.GetInputCoin());
2547 }
2548 return (nValueRet >= nTargetValue);
2549 }
2550
2551 // calculate value from preset inputs and store them
2552 std::set<CInputCoin> setPresetCoins;
2553 CAmount nValueFromPresetInputs = 0;
2554
2555 std::vector<COutPoint> vPresetInputs;
2556 coin_control.ListSelected(vPresetInputs);
2557 for (const COutPoint& outpoint : vPresetInputs)
2558 {
2559 // For now, don't use BnB if preset inputs are selected. TODO: Enable this later
2560 bnb_used = false;
2561 coin_selection_params.use_bnb = false;
2562
2563 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2564 if (it != mapWallet.end())
2565 {
2566 const CWalletTx* pcoin = &it->second;
2567 // Clearly invalid input, fail
2568 if (pcoin->tx->vout.size() <= outpoint.n)
2569 return false;
2570 // Just to calculate the marginal byte size
2571 nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
2572 setPresetCoins.insert(CInputCoin(pcoin->tx, outpoint.n));
2573 } else
2574 return false; // TODO: Allow non-wallet inputs
2575 }
2576
2577 // remove preset inputs from vCoins
2578 for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
2579 {
2580 if (setPresetCoins.count(it->GetInputCoin()))
2581 it = vCoins.erase(it);
2582 else
2583 ++it;
2584 }
2585
2586 // form groups from remaining coins; note that preset coins will not
2587 // automatically have their associated (same address) coins included
2588 if (coin_control.m_avoid_partial_spends && vCoins.size() > OUTPUT_GROUP_MAX_ENTRIES) {
2589 // Cases where we have 11+ outputs all pointing to the same destination may result in
2590 // privacy leaks as they will potentially be deterministically sorted. We solve that by
2591 // explicitly shuffling the outputs before processing
2592 Shuffle(vCoins.begin(), vCoins.end(), FastRandomContext());
2593 }
2594 std::vector<OutputGroup> groups = GroupOutputs(vCoins, !coin_control.m_avoid_partial_spends);
2595
2596 size_t max_ancestors = (size_t)std::max<int64_t>(1, gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT));
2597 size_t max_descendants = (size_t)std::max<int64_t>(1, gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
2598 bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
2599
2600 bool res = nTargetValue <= nValueFromPresetInputs ||
2601 SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(1, 6, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2602 SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(1, 1, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2603 (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, 2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2604 (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::min((size_t)4, max_ancestors/3), std::min((size_t)4, max_descendants/3)), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2605 (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2606 (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2607 (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2608
2609 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2610 util::insert(setCoinsRet, setPresetCoins);
2611
2612 // add preset inputs to the total value selected
2613 nValueRet += nValueFromPresetInputs;
2614
2615 return res;
2616 }
2617
SignTransaction(CMutableTransaction & tx)2618 bool CWallet::SignTransaction(CMutableTransaction &tx)
2619 {
2620 AssertLockHeld(cs_wallet); // mapWallet
2621
2622 // sign the new tx
2623 int nIn = 0;
2624 for (auto& input : tx.vin) {
2625 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
2626 if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2627 return false;
2628 }
2629 const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
2630 const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
2631 SignatureData sigdata;
2632 if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&tx, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
2633 return false;
2634 }
2635 UpdateInput(input, sigdata);
2636 nIn++;
2637 }
2638 return true;
2639 }
2640
FundTransaction(CMutableTransaction & tx,CAmount & nFeeRet,int & nChangePosInOut,std::string & strFailReason,bool lockUnspents,const std::set<int> & setSubtractFeeFromOutputs,CCoinControl coinControl)2641 bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
2642 {
2643 std::vector<CRecipient> vecSend;
2644
2645 // Turn the txout set into a CRecipient vector.
2646 for (size_t idx = 0; idx < tx.vout.size(); idx++) {
2647 const CTxOut& txOut = tx.vout[idx];
2648 CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1};
2649 vecSend.push_back(recipient);
2650 }
2651
2652 coinControl.fAllowOtherInputs = true;
2653
2654 for (const CTxIn& txin : tx.vin) {
2655 coinControl.Select(txin.prevout);
2656 }
2657
2658 // Acquire the locks to prevent races to the new locked unspents between the
2659 // CreateTransaction call and LockCoin calls (when lockUnspents is true).
2660 auto locked_chain = chain().lock();
2661 LOCK(cs_wallet);
2662
2663 CReserveKey reservekey(this);
2664 CTransactionRef tx_new;
2665 if (!CreateTransaction(*locked_chain, vecSend, tx_new, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
2666 return false;
2667 }
2668
2669 if (nChangePosInOut != -1) {
2670 tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
2671 // We don't have the normal Create/Commit cycle, and don't want to risk
2672 // reusing change, so just remove the key from the keypool here.
2673 reservekey.KeepKey();
2674 }
2675
2676 // Copy output sizes from new transaction; they may have had the fee
2677 // subtracted from them.
2678 for (unsigned int idx = 0; idx < tx.vout.size(); idx++) {
2679 tx.vout[idx].nValue = tx_new->vout[idx].nValue;
2680 }
2681
2682 // Add new txins while keeping original txin scriptSig/order.
2683 for (const CTxIn& txin : tx_new->vin) {
2684 if (!coinControl.IsSelected(txin.prevout)) {
2685 tx.vin.push_back(txin);
2686
2687 if (lockUnspents) {
2688 LockCoin(txin.prevout);
2689 }
2690 }
2691 }
2692
2693 return true;
2694 }
2695
IsCurrentForAntiFeeSniping(interfaces::Chain::Lock & locked_chain)2696 static bool IsCurrentForAntiFeeSniping(interfaces::Chain::Lock& locked_chain)
2697 {
2698 if (IsInitialBlockDownload()) {
2699 return false;
2700 }
2701 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
2702 if (chainActive.Tip()->GetBlockTime() < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
2703 return false;
2704 }
2705 return true;
2706 }
2707
2708 /**
2709 * Return a height-based locktime for new transactions (uses the height of the
2710 * current chain tip unless we are not synced with the current chain
2711 */
GetLocktimeForNewTransaction(interfaces::Chain::Lock & locked_chain)2712 static uint32_t GetLocktimeForNewTransaction(interfaces::Chain::Lock& locked_chain)
2713 {
2714 uint32_t const height = locked_chain.getHeight().get_value_or(-1);
2715 uint32_t locktime;
2716 // Discourage fee sniping.
2717 //
2718 // For a large miner the value of the transactions in the best block and
2719 // the mempool can exceed the cost of deliberately attempting to mine two
2720 // blocks to orphan the current best block. By setting nLockTime such that
2721 // only the next block can include the transaction, we discourage this
2722 // practice as the height restricted and limited blocksize gives miners
2723 // considering fee sniping fewer options for pulling off this attack.
2724 //
2725 // A simple way to think about this is from the wallet's point of view we
2726 // always want the blockchain to move forward. By setting nLockTime this
2727 // way we're basically making the statement that we only want this
2728 // transaction to appear in the next block; we don't want to potentially
2729 // encourage reorgs by allowing transactions to appear at lower heights
2730 // than the next block in forks of the best chain.
2731 //
2732 // Of course, the subsidy is high enough, and transaction volume low
2733 // enough, that fee sniping isn't a problem yet, but by implementing a fix
2734 // now we ensure code won't be written that makes assumptions about
2735 // nLockTime that preclude a fix later.
2736 if (IsCurrentForAntiFeeSniping(locked_chain)) {
2737 locktime = height;
2738
2739 // Secondly occasionally randomly pick a nLockTime even further back, so
2740 // that transactions that are delayed after signing for whatever reason,
2741 // e.g. high-latency mix networks and some CoinJoin implementations, have
2742 // better privacy.
2743 if (GetRandInt(10) == 0)
2744 locktime = std::max(0, (int)locktime - GetRandInt(100));
2745 } else {
2746 // If our chain is lagging behind, we can't discourage fee sniping nor help
2747 // the privacy of high-latency transactions. To avoid leaking a potentially
2748 // unique "nLockTime fingerprint", set nLockTime to a constant.
2749 locktime = 0;
2750 }
2751 assert(locktime <= height);
2752 assert(locktime < LOCKTIME_THRESHOLD);
2753 return locktime;
2754 }
2755
TransactionChangeType(OutputType change_type,const std::vector<CRecipient> & vecSend)2756 OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend)
2757 {
2758 // If -changetype is specified, always use that change type.
2759 if (change_type != OutputType::CHANGE_AUTO) {
2760 return change_type;
2761 }
2762
2763 // if m_default_address_type is legacy, use legacy address as change (even
2764 // if some of the outputs are P2WPKH or P2WSH).
2765 if (m_default_address_type == OutputType::LEGACY) {
2766 return OutputType::LEGACY;
2767 }
2768
2769 // if any destination is P2WPKH or P2WSH, use P2WPKH for the change
2770 // output.
2771 for (const auto& recipient : vecSend) {
2772 // Check if any destination contains a witness program:
2773 int witnessversion = 0;
2774 std::vector<unsigned char> witnessprogram;
2775 if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
2776 return OutputType::BECH32;
2777 }
2778 }
2779
2780 // else use m_default_address_type for change
2781 return m_default_address_type;
2782 }
2783
CreateTransaction(interfaces::Chain::Lock & locked_chain,const std::vector<CRecipient> & vecSend,CTransactionRef & tx,CReserveKey & reservekey,CAmount & nFeeRet,int & nChangePosInOut,std::string & strFailReason,const CCoinControl & coin_control,bool sign)2784 bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet,
2785 int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
2786 {
2787 CAmount nValue = 0;
2788 int nChangePosRequest = nChangePosInOut;
2789 unsigned int nSubtractFeeFromAmount = 0;
2790 for (const auto& recipient : vecSend)
2791 {
2792 if (nValue < 0 || recipient.nAmount < 0)
2793 {
2794 strFailReason = _("Transaction amounts must not be negative");
2795 return false;
2796 }
2797 nValue += recipient.nAmount;
2798
2799 if (recipient.fSubtractFeeFromAmount)
2800 nSubtractFeeFromAmount++;
2801 }
2802 if (vecSend.empty())
2803 {
2804 strFailReason = _("Transaction must have at least one recipient");
2805 return false;
2806 }
2807
2808 CMutableTransaction txNew;
2809
2810 txNew.nLockTime = GetLocktimeForNewTransaction(locked_chain);
2811
2812 FeeCalculation feeCalc;
2813 CAmount nFeeNeeded;
2814 int nBytes;
2815 {
2816 std::set<CInputCoin> setCoins;
2817 auto locked_chain = chain().lock();
2818 LOCK(cs_wallet);
2819 {
2820 std::vector<COutput> vAvailableCoins;
2821 AvailableCoins(*locked_chain, vAvailableCoins, true, &coin_control);
2822 CoinSelectionParams coin_selection_params; // Parameters for coin selection, init with dummy
2823
2824 // Create change script that will be used if we need change
2825 // TODO: pass in scriptChange instead of reservekey so
2826 // change transaction isn't always pay-to-bitcoin-address
2827 CScript scriptChange;
2828
2829 // coin control: send change to custom address
2830 if (!boost::get<CNoDestination>(&coin_control.destChange)) {
2831 scriptChange = GetScriptForDestination(coin_control.destChange);
2832 } else { // no coin control: send change to newly generated address
2833 // Note: We use a new key here to keep it from being obvious which side is the change.
2834 // The drawback is that by not reusing a previous key, the change may be lost if a
2835 // backup is restored, if the backup doesn't have the new private key for the change.
2836 // If we reused the old key, it would be possible to add code to look for and
2837 // rediscover unknown transactions that were written with keys of ours to recover
2838 // post-backup change.
2839
2840 // Reserve a new key pair from key pool
2841 if (!CanGetAddresses(true)) {
2842 strFailReason = _("Can't generate a change-address key. No keys in the internal keypool and can't generate any keys.");
2843 return false;
2844 }
2845 CPubKey vchPubKey;
2846 bool ret;
2847 ret = reservekey.GetReservedKey(vchPubKey, true);
2848 if (!ret)
2849 {
2850 strFailReason = _("Keypool ran out, please call keypoolrefill first");
2851 return false;
2852 }
2853
2854 const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
2855
2856 LearnRelatedScripts(vchPubKey, change_type);
2857 scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
2858 }
2859 CTxOut change_prototype_txout(0, scriptChange);
2860 coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
2861
2862 CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator);
2863
2864 // Get the fee rate to use effective values in coin selection
2865 CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, ::mempool, ::feeEstimator, &feeCalc);
2866
2867 nFeeRet = 0;
2868 bool pick_new_inputs = true;
2869 CAmount nValueIn = 0;
2870
2871 // BnB selector is the only selector used when this is true.
2872 // That should only happen on the first pass through the loop.
2873 coin_selection_params.use_bnb = nSubtractFeeFromAmount == 0; // If we are doing subtract fee from recipient, then don't use BnB
2874 // Start with no fee and loop until there is enough fee
2875 while (true)
2876 {
2877 nChangePosInOut = nChangePosRequest;
2878 txNew.vin.clear();
2879 txNew.vout.clear();
2880 bool fFirst = true;
2881
2882 CAmount nValueToSelect = nValue;
2883 if (nSubtractFeeFromAmount == 0)
2884 nValueToSelect += nFeeRet;
2885
2886 // vouts to the payees
2887 coin_selection_params.tx_noinputs_size = 11; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 output count, 1 witness overhead (dummy, flag, stack size)
2888 for (const auto& recipient : vecSend)
2889 {
2890 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2891
2892 if (recipient.fSubtractFeeFromAmount)
2893 {
2894 assert(nSubtractFeeFromAmount != 0);
2895 txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
2896
2897 if (fFirst) // first receiver pays the remainder not divisible by output count
2898 {
2899 fFirst = false;
2900 txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
2901 }
2902 }
2903 // Include the fee cost for outputs. Note this is only used for BnB right now
2904 coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION);
2905
2906 if (IsDust(txout, ::dustRelayFee))
2907 {
2908 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2909 {
2910 if (txout.nValue < 0)
2911 strFailReason = _("The transaction amount is too small to pay the fee");
2912 else
2913 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
2914 }
2915 else
2916 strFailReason = _("Transaction amount too small");
2917 return false;
2918 }
2919 txNew.vout.push_back(txout);
2920 }
2921
2922 // Choose coins to use
2923 bool bnb_used;
2924 if (pick_new_inputs) {
2925 nValueIn = 0;
2926 setCoins.clear();
2927 int change_spend_size = CalculateMaximumSignedInputSize(change_prototype_txout, this);
2928 // If the wallet doesn't know how to sign change output, assume p2sh-p2wpkh
2929 // as lower-bound to allow BnB to do it's thing
2930 if (change_spend_size == -1) {
2931 coin_selection_params.change_spend_size = DUMMY_NESTED_P2WPKH_INPUT_SIZE;
2932 } else {
2933 coin_selection_params.change_spend_size = (size_t)change_spend_size;
2934 }
2935 coin_selection_params.effective_fee = nFeeRateNeeded;
2936 if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coin_control, coin_selection_params, bnb_used))
2937 {
2938 // If BnB was used, it was the first pass. No longer the first pass and continue loop with knapsack.
2939 if (bnb_used) {
2940 coin_selection_params.use_bnb = false;
2941 continue;
2942 }
2943 else {
2944 strFailReason = _("Insufficient funds");
2945 return false;
2946 }
2947 }
2948 } else {
2949 bnb_used = false;
2950 }
2951
2952 const CAmount nChange = nValueIn - nValueToSelect;
2953 if (nChange > 0)
2954 {
2955 // Fill a vout to ourself
2956 CTxOut newTxOut(nChange, scriptChange);
2957
2958 // Never create dust outputs; if we would, just
2959 // add the dust to the fee.
2960 // The nChange when BnB is used is always going to go to fees.
2961 if (IsDust(newTxOut, discard_rate) || bnb_used)
2962 {
2963 nChangePosInOut = -1;
2964 nFeeRet += nChange;
2965 }
2966 else
2967 {
2968 if (nChangePosInOut == -1)
2969 {
2970 // Insert change txn at random position:
2971 nChangePosInOut = GetRandInt(txNew.vout.size()+1);
2972 }
2973 else if ((unsigned int)nChangePosInOut > txNew.vout.size())
2974 {
2975 strFailReason = _("Change index out of range");
2976 return false;
2977 }
2978
2979 std::vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosInOut;
2980 txNew.vout.insert(position, newTxOut);
2981 }
2982 } else {
2983 nChangePosInOut = -1;
2984 }
2985
2986 // Dummy fill vin for maximum size estimation
2987 //
2988 for (const auto& coin : setCoins) {
2989 txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
2990 }
2991
2992 nBytes = CalculateMaximumSignedTxSize(CTransaction(txNew), this, coin_control.fAllowWatchOnly);
2993 if (nBytes < 0) {
2994 strFailReason = _("Signing transaction failed");
2995 return false;
2996 }
2997
2998 nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
2999 if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) {
3000 // eventually allow a fallback fee
3001 strFailReason = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
3002 return false;
3003 }
3004
3005 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
3006 // because we must be at the maximum allowed fee.
3007 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
3008 {
3009 strFailReason = _("Transaction too large for fee policy");
3010 return false;
3011 }
3012
3013 if (nFeeRet >= nFeeNeeded) {
3014 // Reduce fee to only the needed amount if possible. This
3015 // prevents potential overpayment in fees if the coins
3016 // selected to meet nFeeNeeded result in a transaction that
3017 // requires less fee than the prior iteration.
3018
3019 // If we have no change and a big enough excess fee, then
3020 // try to construct transaction again only without picking
3021 // new inputs. We now know we only need the smaller fee
3022 // (because of reduced tx size) and so we should add a
3023 // change output. Only try this once.
3024 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
3025 unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size
3026 CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
3027 CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
3028 if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
3029 pick_new_inputs = false;
3030 nFeeRet = fee_needed_with_change;
3031 continue;
3032 }
3033 }
3034
3035 // If we have change output already, just increase it
3036 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3037 CAmount extraFeePaid = nFeeRet - nFeeNeeded;
3038 std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3039 change_position->nValue += extraFeePaid;
3040 nFeeRet -= extraFeePaid;
3041 }
3042 break; // Done, enough fee included.
3043 }
3044 else if (!pick_new_inputs) {
3045 // This shouldn't happen, we should have had enough excess
3046 // fee to pay for the new output and still meet nFeeNeeded
3047 // Or we should have just subtracted fee from recipients and
3048 // nFeeNeeded should not have changed
3049 strFailReason = _("Transaction fee and change calculation failed");
3050 return false;
3051 }
3052
3053 // Try to reduce change to include necessary fee
3054 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3055 CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3056 std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3057 // Only reduce change if remaining amount is still a large enough output.
3058 if (change_position->nValue >= MIN_FINAL_CHANGE + additionalFeeNeeded) {
3059 change_position->nValue -= additionalFeeNeeded;
3060 nFeeRet += additionalFeeNeeded;
3061 break; // Done, able to increase fee from change
3062 }
3063 }
3064
3065 // If subtracting fee from recipients, we now know what fee we
3066 // need to subtract, we have no reason to reselect inputs
3067 if (nSubtractFeeFromAmount > 0) {
3068 pick_new_inputs = false;
3069 }
3070
3071 // Include more fee and try again.
3072 nFeeRet = nFeeNeeded;
3073 coin_selection_params.use_bnb = false;
3074 continue;
3075 }
3076 }
3077
3078 if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change
3079
3080 // Shuffle selected coins and fill in final vin
3081 txNew.vin.clear();
3082 std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
3083 Shuffle(selected_coins.begin(), selected_coins.end(), FastRandomContext());
3084
3085 // Note how the sequence number is set to non-maxint so that
3086 // the nLockTime set above actually works.
3087 //
3088 // BIP125 defines opt-in RBF as any nSequence < maxint-1, so
3089 // we use the highest possible value in that range (maxint-2)
3090 // to avoid conflicting with other possible uses of nSequence,
3091 // and in the spirit of "smallest possible change from prior
3092 // behavior."
3093 const uint32_t nSequence = coin_control.m_signal_bip125_rbf.get_value_or(m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
3094 for (const auto& coin : selected_coins) {
3095 txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence));
3096 }
3097
3098 if (sign)
3099 {
3100 int nIn = 0;
3101 for (const auto& coin : selected_coins)
3102 {
3103 const CScript& scriptPubKey = coin.txout.scriptPubKey;
3104 SignatureData sigdata;
3105
3106 if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&txNew, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
3107 {
3108 strFailReason = _("Signing transaction failed");
3109 return false;
3110 } else {
3111 UpdateInput(txNew.vin.at(nIn), sigdata);
3112 }
3113
3114 nIn++;
3115 }
3116 }
3117
3118 // Return the constructed transaction data.
3119 tx = MakeTransactionRef(std::move(txNew));
3120
3121 // Limit size
3122 if (GetTransactionWeight(*tx) > MAX_STANDARD_TX_WEIGHT)
3123 {
3124 strFailReason = _("Transaction too large");
3125 return false;
3126 }
3127 }
3128
3129 if (nFeeRet > maxTxFee) {
3130 strFailReason = _("Fee exceeds maximum configured by -maxtxfee");
3131 return false;
3132 }
3133
3134 if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
3135 // Lastly, ensure this tx will pass the mempool's chain limits
3136 LockPoints lp;
3137 CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
3138 CTxMemPool::setEntries setAncestors;
3139 size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
3140 size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
3141 size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
3142 size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
3143 std::string errString;
3144 LOCK(::mempool.cs);
3145 if (!::mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
3146 strFailReason = _("Transaction has too long of a mempool chain");
3147 return false;
3148 }
3149 }
3150
3151 WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Needed:%d Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
3152 nFeeRet, nBytes, nFeeNeeded, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
3153 feeCalc.est.pass.start, feeCalc.est.pass.end,
3154 100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool),
3155 feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
3156 feeCalc.est.fail.start, feeCalc.est.fail.end,
3157 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool),
3158 feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
3159 return true;
3160 }
3161
3162 /**
3163 * Call after CreateTransaction unless you want to abort
3164 */
CommitTransaction(CTransactionRef tx,mapValue_t mapValue,std::vector<std::pair<std::string,std::string>> orderForm,CReserveKey & reservekey,CConnman * connman,CValidationState & state)3165 bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
3166 {
3167 {
3168 auto locked_chain = chain().lock();
3169 LOCK(cs_wallet);
3170
3171 CWalletTx wtxNew(this, std::move(tx));
3172 wtxNew.mapValue = std::move(mapValue);
3173 wtxNew.vOrderForm = std::move(orderForm);
3174 wtxNew.fTimeReceivedIsTxTime = true;
3175 wtxNew.fFromMe = true;
3176
3177 WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
3178 {
3179 // Take key pair from key pool so it won't be used again
3180 reservekey.KeepKey();
3181
3182 // Add tx to wallet, because if it has change it's also ours,
3183 // otherwise just for transaction history.
3184 AddToWallet(wtxNew);
3185
3186 // Notify that old coins are spent
3187 for (const CTxIn& txin : wtxNew.tx->vin)
3188 {
3189 CWalletTx &coin = mapWallet.at(txin.prevout.hash);
3190 coin.BindWallet(this);
3191 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
3192 }
3193 }
3194
3195 // Get the inserted-CWalletTx from mapWallet so that the
3196 // fInMempool flag is cached properly
3197 CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
3198
3199 if (fBroadcastTransactions)
3200 {
3201 // Broadcast
3202 if (!wtx.AcceptToMemoryPool(*locked_chain, maxTxFee, state)) {
3203 WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", FormatStateMessage(state));
3204 // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
3205 } else {
3206 wtx.RelayWalletTransaction(*locked_chain, connman);
3207 }
3208 }
3209 }
3210 return true;
3211 }
3212
LoadWallet(bool & fFirstRunRet)3213 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
3214 {
3215 auto locked_chain = chain().lock();
3216 LOCK(cs_wallet);
3217
3218 fFirstRunRet = false;
3219 DBErrors nLoadWalletRet = WalletBatch(*database,"cr+").LoadWallet(this);
3220 if (nLoadWalletRet == DBErrors::NEED_REWRITE)
3221 {
3222 if (database->Rewrite("\x04pool"))
3223 {
3224 setInternalKeyPool.clear();
3225 setExternalKeyPool.clear();
3226 m_pool_key_to_index.clear();
3227 // Note: can't top-up keypool here, because wallet is locked.
3228 // User will be prompted to unlock wallet the next operation
3229 // that requires a new key.
3230 }
3231 }
3232
3233 {
3234 LOCK(cs_KeyStore);
3235 // This wallet is in its first run if all of these are empty
3236 fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty()
3237 && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
3238 }
3239
3240 if (nLoadWalletRet != DBErrors::LOAD_OK)
3241 return nLoadWalletRet;
3242
3243 return DBErrors::LOAD_OK;
3244 }
3245
ZapSelectTx(std::vector<uint256> & vHashIn,std::vector<uint256> & vHashOut)3246 DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
3247 {
3248 AssertLockHeld(cs_wallet); // mapWallet
3249 DBErrors nZapSelectTxRet = WalletBatch(*database,"cr+").ZapSelectTx(vHashIn, vHashOut);
3250 for (uint256 hash : vHashOut) {
3251 const auto& it = mapWallet.find(hash);
3252 wtxOrdered.erase(it->second.m_it_wtxOrdered);
3253 mapWallet.erase(it);
3254 }
3255
3256 if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
3257 {
3258 if (database->Rewrite("\x04pool"))
3259 {
3260 setInternalKeyPool.clear();
3261 setExternalKeyPool.clear();
3262 m_pool_key_to_index.clear();
3263 // Note: can't top-up keypool here, because wallet is locked.
3264 // User will be prompted to unlock wallet the next operation
3265 // that requires a new key.
3266 }
3267 }
3268
3269 if (nZapSelectTxRet != DBErrors::LOAD_OK)
3270 return nZapSelectTxRet;
3271
3272 MarkDirty();
3273
3274 return DBErrors::LOAD_OK;
3275
3276 }
3277
ZapWalletTx(std::vector<CWalletTx> & vWtx)3278 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
3279 {
3280 DBErrors nZapWalletTxRet = WalletBatch(*database,"cr+").ZapWalletTx(vWtx);
3281 if (nZapWalletTxRet == DBErrors::NEED_REWRITE)
3282 {
3283 if (database->Rewrite("\x04pool"))
3284 {
3285 LOCK(cs_wallet);
3286 setInternalKeyPool.clear();
3287 setExternalKeyPool.clear();
3288 m_pool_key_to_index.clear();
3289 // Note: can't top-up keypool here, because wallet is locked.
3290 // User will be prompted to unlock wallet the next operation
3291 // that requires a new key.
3292 }
3293 }
3294
3295 if (nZapWalletTxRet != DBErrors::LOAD_OK)
3296 return nZapWalletTxRet;
3297
3298 return DBErrors::LOAD_OK;
3299 }
3300
3301
SetAddressBook(const CTxDestination & address,const std::string & strName,const std::string & strPurpose)3302 bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3303 {
3304 bool fUpdated = false;
3305 {
3306 LOCK(cs_wallet);
3307 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
3308 fUpdated = mi != mapAddressBook.end();
3309 mapAddressBook[address].name = strName;
3310 if (!strPurpose.empty()) /* update purpose only if requested */
3311 mapAddressBook[address].purpose = strPurpose;
3312 }
3313 NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
3314 strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
3315 if (!strPurpose.empty() && !WalletBatch(*database).WritePurpose(EncodeDestination(address), strPurpose))
3316 return false;
3317 return WalletBatch(*database).WriteName(EncodeDestination(address), strName);
3318 }
3319
DelAddressBook(const CTxDestination & address)3320 bool CWallet::DelAddressBook(const CTxDestination& address)
3321 {
3322 {
3323 LOCK(cs_wallet);
3324
3325 // Delete destdata tuples associated with address
3326 std::string strAddress = EncodeDestination(address);
3327 for (const std::pair<const std::string, std::string> &item : mapAddressBook[address].destdata)
3328 {
3329 WalletBatch(*database).EraseDestData(strAddress, item.first);
3330 }
3331 mapAddressBook.erase(address);
3332 }
3333
3334 NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
3335
3336 WalletBatch(*database).ErasePurpose(EncodeDestination(address));
3337 return WalletBatch(*database).EraseName(EncodeDestination(address));
3338 }
3339
GetLabelName(const CScript & scriptPubKey) const3340 const std::string& CWallet::GetLabelName(const CScript& scriptPubKey) const
3341 {
3342 CTxDestination address;
3343 if (ExtractDestination(scriptPubKey, address) && !scriptPubKey.IsUnspendable()) {
3344 auto mi = mapAddressBook.find(address);
3345 if (mi != mapAddressBook.end()) {
3346 return mi->second.name;
3347 }
3348 }
3349 // A scriptPubKey that doesn't have an entry in the address book is
3350 // associated with the default label ("").
3351 const static std::string DEFAULT_LABEL_NAME;
3352 return DEFAULT_LABEL_NAME;
3353 }
3354
3355 /**
3356 * Mark old keypool keys as used,
3357 * and generate all new keys
3358 */
NewKeyPool()3359 bool CWallet::NewKeyPool()
3360 {
3361 if (IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3362 return false;
3363 }
3364 {
3365 LOCK(cs_wallet);
3366 WalletBatch batch(*database);
3367
3368 for (const int64_t nIndex : setInternalKeyPool) {
3369 batch.ErasePool(nIndex);
3370 }
3371 setInternalKeyPool.clear();
3372
3373 for (const int64_t nIndex : setExternalKeyPool) {
3374 batch.ErasePool(nIndex);
3375 }
3376 setExternalKeyPool.clear();
3377
3378 for (const int64_t nIndex : set_pre_split_keypool) {
3379 batch.ErasePool(nIndex);
3380 }
3381 set_pre_split_keypool.clear();
3382
3383 m_pool_key_to_index.clear();
3384
3385 if (!TopUpKeyPool()) {
3386 return false;
3387 }
3388 WalletLogPrintf("CWallet::NewKeyPool rewrote keypool\n");
3389 }
3390 return true;
3391 }
3392
KeypoolCountExternalKeys()3393 size_t CWallet::KeypoolCountExternalKeys()
3394 {
3395 AssertLockHeld(cs_wallet); // setExternalKeyPool
3396 return setExternalKeyPool.size() + set_pre_split_keypool.size();
3397 }
3398
LoadKeyPool(int64_t nIndex,const CKeyPool & keypool)3399 void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
3400 {
3401 AssertLockHeld(cs_wallet);
3402 if (keypool.m_pre_split) {
3403 set_pre_split_keypool.insert(nIndex);
3404 } else if (keypool.fInternal) {
3405 setInternalKeyPool.insert(nIndex);
3406 } else {
3407 setExternalKeyPool.insert(nIndex);
3408 }
3409 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
3410 m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
3411
3412 // If no metadata exists yet, create a default with the pool key's
3413 // creation time. Note that this may be overwritten by actually
3414 // stored metadata for that key later, which is fine.
3415 CKeyID keyid = keypool.vchPubKey.GetID();
3416 if (mapKeyMetadata.count(keyid) == 0)
3417 mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
3418 }
3419
TopUpKeyPool(unsigned int kpSize)3420 bool CWallet::TopUpKeyPool(unsigned int kpSize)
3421 {
3422 if (!CanGenerateKeys()) {
3423 return false;
3424 }
3425 {
3426 LOCK(cs_wallet);
3427
3428 if (IsLocked())
3429 return false;
3430
3431 // Top up key pool
3432 unsigned int nTargetSize;
3433 if (kpSize > 0)
3434 nTargetSize = kpSize;
3435 else
3436 nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
3437
3438 // count amount of available keys (internal, external)
3439 // make sure the keypool of external and internal keys fits the user selected target (-keypool)
3440 int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
3441 int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);
3442
3443 if (!IsHDEnabled() || !CanSupportFeature(FEATURE_HD_SPLIT))
3444 {
3445 // don't create extra internal keys
3446 missingInternal = 0;
3447 }
3448 bool internal = false;
3449 WalletBatch batch(*database);
3450 for (int64_t i = missingInternal + missingExternal; i--;)
3451 {
3452 if (i < missingInternal) {
3453 internal = true;
3454 }
3455
3456 CPubKey pubkey(GenerateNewKey(batch, internal));
3457 AddKeypoolPubkeyWithDB(pubkey, internal, batch);
3458 }
3459 if (missingInternal + missingExternal > 0) {
3460 WalletLogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
3461 }
3462 }
3463 NotifyCanGetAddressesChanged();
3464 return true;
3465 }
3466
AddKeypoolPubkey(const CPubKey & pubkey,const bool internal)3467 void CWallet::AddKeypoolPubkey(const CPubKey& pubkey, const bool internal)
3468 {
3469 WalletBatch batch(*database);
3470 AddKeypoolPubkeyWithDB(pubkey, internal, batch);
3471 NotifyCanGetAddressesChanged();
3472 }
3473
AddKeypoolPubkeyWithDB(const CPubKey & pubkey,const bool internal,WalletBatch & batch)3474 void CWallet::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
3475 {
3476 LOCK(cs_wallet);
3477 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
3478 int64_t index = ++m_max_keypool_index;
3479 if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
3480 throw std::runtime_error(std::string(__func__) + ": writing imported pubkey failed");
3481 }
3482 if (internal) {
3483 setInternalKeyPool.insert(index);
3484 } else {
3485 setExternalKeyPool.insert(index);
3486 }
3487 m_pool_key_to_index[pubkey.GetID()] = index;
3488 }
3489
ReserveKeyFromKeyPool(int64_t & nIndex,CKeyPool & keypool,bool fRequestedInternal)3490 bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
3491 {
3492 nIndex = -1;
3493 keypool.vchPubKey = CPubKey();
3494 {
3495 LOCK(cs_wallet);
3496
3497 if (!IsLocked())
3498 TopUpKeyPool();
3499
3500 bool fReturningInternal = fRequestedInternal;
3501 fReturningInternal &= (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT)) || IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
3502 bool use_split_keypool = set_pre_split_keypool.empty();
3503 std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
3504
3505 // Get the oldest key
3506 if (setKeyPool.empty()) {
3507 return false;
3508 }
3509
3510 WalletBatch batch(*database);
3511
3512 auto it = setKeyPool.begin();
3513 nIndex = *it;
3514 setKeyPool.erase(it);
3515 if (!batch.ReadPool(nIndex, keypool)) {
3516 throw std::runtime_error(std::string(__func__) + ": read failed");
3517 }
3518 CPubKey pk;
3519 if (!GetPubKey(keypool.vchPubKey.GetID(), pk)) {
3520 throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
3521 }
3522 // If the key was pre-split keypool, we don't care about what type it is
3523 if (use_split_keypool && keypool.fInternal != fReturningInternal) {
3524 throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified");
3525 }
3526 if (!keypool.vchPubKey.IsValid()) {
3527 throw std::runtime_error(std::string(__func__) + ": keypool entry invalid");
3528 }
3529
3530 m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
3531 WalletLogPrintf("keypool reserve %d\n", nIndex);
3532 }
3533 NotifyCanGetAddressesChanged();
3534 return true;
3535 }
3536
KeepKey(int64_t nIndex)3537 void CWallet::KeepKey(int64_t nIndex)
3538 {
3539 // Remove from key pool
3540 WalletBatch batch(*database);
3541 batch.ErasePool(nIndex);
3542 WalletLogPrintf("keypool keep %d\n", nIndex);
3543 }
3544
ReturnKey(int64_t nIndex,bool fInternal,const CPubKey & pubkey)3545 void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
3546 {
3547 // Return to key pool
3548 {
3549 LOCK(cs_wallet);
3550 if (fInternal) {
3551 setInternalKeyPool.insert(nIndex);
3552 } else if (!set_pre_split_keypool.empty()) {
3553 set_pre_split_keypool.insert(nIndex);
3554 } else {
3555 setExternalKeyPool.insert(nIndex);
3556 }
3557 m_pool_key_to_index[pubkey.GetID()] = nIndex;
3558 NotifyCanGetAddressesChanged();
3559 }
3560 WalletLogPrintf("keypool return %d\n", nIndex);
3561 }
3562
GetKeyFromPool(CPubKey & result,bool internal)3563 bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
3564 {
3565 if (!CanGetAddresses(internal)) {
3566 return false;
3567 }
3568
3569 CKeyPool keypool;
3570 {
3571 LOCK(cs_wallet);
3572 int64_t nIndex;
3573 if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3574 if (IsLocked()) return false;
3575 WalletBatch batch(*database);
3576 result = GenerateNewKey(batch, internal);
3577 return true;
3578 }
3579 KeepKey(nIndex);
3580 result = keypool.vchPubKey;
3581 }
3582 return true;
3583 }
3584
GetOldestKeyTimeInPool(const std::set<int64_t> & setKeyPool,WalletBatch & batch)3585 static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
3586 if (setKeyPool.empty()) {
3587 return GetTime();
3588 }
3589
3590 CKeyPool keypool;
3591 int64_t nIndex = *(setKeyPool.begin());
3592 if (!batch.ReadPool(nIndex, keypool)) {
3593 throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
3594 }
3595 assert(keypool.vchPubKey.IsValid());
3596 return keypool.nTime;
3597 }
3598
GetOldestKeyPoolTime()3599 int64_t CWallet::GetOldestKeyPoolTime()
3600 {
3601 LOCK(cs_wallet);
3602
3603 WalletBatch batch(*database);
3604
3605 // load oldest key from keypool, get time and return
3606 int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, batch);
3607 if (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT)) {
3608 oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, batch), oldestKey);
3609 if (!set_pre_split_keypool.empty()) {
3610 oldestKey = std::max(GetOldestKeyTimeInPool(set_pre_split_keypool, batch), oldestKey);
3611 }
3612 }
3613
3614 return oldestKey;
3615 }
3616
GetAddressBalances(interfaces::Chain::Lock & locked_chain)3617 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances(interfaces::Chain::Lock& locked_chain)
3618 {
3619 std::map<CTxDestination, CAmount> balances;
3620
3621 {
3622 LOCK(cs_wallet);
3623 for (const auto& walletEntry : mapWallet)
3624 {
3625 const CWalletTx *pcoin = &walletEntry.second;
3626
3627 if (!pcoin->IsTrusted(locked_chain))
3628 continue;
3629
3630 if (pcoin->IsImmatureCoinBase(locked_chain))
3631 continue;
3632
3633 int nDepth = pcoin->GetDepthInMainChain(locked_chain);
3634 if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
3635 continue;
3636
3637 for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
3638 {
3639 CTxDestination addr;
3640 if (!IsMine(pcoin->tx->vout[i]))
3641 continue;
3642 if(!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, addr))
3643 continue;
3644
3645 CAmount n = IsSpent(locked_chain, walletEntry.first, i) ? 0 : pcoin->tx->vout[i].nValue;
3646
3647 if (!balances.count(addr))
3648 balances[addr] = 0;
3649 balances[addr] += n;
3650 }
3651 }
3652 }
3653
3654 return balances;
3655 }
3656
GetAddressGroupings()3657 std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
3658 {
3659 AssertLockHeld(cs_wallet); // mapWallet
3660 std::set< std::set<CTxDestination> > groupings;
3661 std::set<CTxDestination> grouping;
3662
3663 for (const auto& walletEntry : mapWallet)
3664 {
3665 const CWalletTx *pcoin = &walletEntry.second;
3666
3667 if (pcoin->tx->vin.size() > 0)
3668 {
3669 bool any_mine = false;
3670 // group all input addresses with each other
3671 for (const CTxIn& txin : pcoin->tx->vin)
3672 {
3673 CTxDestination address;
3674 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
3675 continue;
3676 if(!ExtractDestination(mapWallet.at(txin.prevout.hash).tx->vout[txin.prevout.n].scriptPubKey, address))
3677 continue;
3678 grouping.insert(address);
3679 any_mine = true;
3680 }
3681
3682 // group change with input addresses
3683 if (any_mine)
3684 {
3685 for (const CTxOut& txout : pcoin->tx->vout)
3686 if (IsChange(txout))
3687 {
3688 CTxDestination txoutAddr;
3689 if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
3690 continue;
3691 grouping.insert(txoutAddr);
3692 }
3693 }
3694 if (grouping.size() > 0)
3695 {
3696 groupings.insert(grouping);
3697 grouping.clear();
3698 }
3699 }
3700
3701 // group lone addrs by themselves
3702 for (const auto& txout : pcoin->tx->vout)
3703 if (IsMine(txout))
3704 {
3705 CTxDestination address;
3706 if(!ExtractDestination(txout.scriptPubKey, address))
3707 continue;
3708 grouping.insert(address);
3709 groupings.insert(grouping);
3710 grouping.clear();
3711 }
3712 }
3713
3714 std::set< std::set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
3715 std::map< CTxDestination, std::set<CTxDestination>* > setmap; // map addresses to the unique group containing it
3716 for (std::set<CTxDestination> _grouping : groupings)
3717 {
3718 // make a set of all the groups hit by this new group
3719 std::set< std::set<CTxDestination>* > hits;
3720 std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;
3721 for (const CTxDestination& address : _grouping)
3722 if ((it = setmap.find(address)) != setmap.end())
3723 hits.insert((*it).second);
3724
3725 // merge all hit groups into a new single group and delete old groups
3726 std::set<CTxDestination>* merged = new std::set<CTxDestination>(_grouping);
3727 for (std::set<CTxDestination>* hit : hits)
3728 {
3729 merged->insert(hit->begin(), hit->end());
3730 uniqueGroupings.erase(hit);
3731 delete hit;
3732 }
3733 uniqueGroupings.insert(merged);
3734
3735 // update setmap
3736 for (const CTxDestination& element : *merged)
3737 setmap[element] = merged;
3738 }
3739
3740 std::set< std::set<CTxDestination> > ret;
3741 for (const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
3742 {
3743 ret.insert(*uniqueGrouping);
3744 delete uniqueGrouping;
3745 }
3746
3747 return ret;
3748 }
3749
GetLabelAddresses(const std::string & label) const3750 std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) const
3751 {
3752 LOCK(cs_wallet);
3753 std::set<CTxDestination> result;
3754 for (const std::pair<const CTxDestination, CAddressBookData>& item : mapAddressBook)
3755 {
3756 const CTxDestination& address = item.first;
3757 const std::string& strName = item.second.name;
3758 if (strName == label)
3759 result.insert(address);
3760 }
3761 return result;
3762 }
3763
GetReservedKey(CPubKey & pubkey,bool internal)3764 bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal)
3765 {
3766 if (!pwallet->CanGetAddresses(internal)) {
3767 return false;
3768 }
3769
3770 if (nIndex == -1)
3771 {
3772 CKeyPool keypool;
3773 if (!pwallet->ReserveKeyFromKeyPool(nIndex, keypool, internal)) {
3774 return false;
3775 }
3776 vchPubKey = keypool.vchPubKey;
3777 fInternal = keypool.fInternal;
3778 }
3779 assert(vchPubKey.IsValid());
3780 pubkey = vchPubKey;
3781 return true;
3782 }
3783
KeepKey()3784 void CReserveKey::KeepKey()
3785 {
3786 if (nIndex != -1)
3787 pwallet->KeepKey(nIndex);
3788 nIndex = -1;
3789 vchPubKey = CPubKey();
3790 }
3791
ReturnKey()3792 void CReserveKey::ReturnKey()
3793 {
3794 if (nIndex != -1) {
3795 pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
3796 }
3797 nIndex = -1;
3798 vchPubKey = CPubKey();
3799 }
3800
MarkReserveKeysAsUsed(int64_t keypool_id)3801 void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id)
3802 {
3803 AssertLockHeld(cs_wallet);
3804 bool internal = setInternalKeyPool.count(keypool_id);
3805 if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
3806 std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
3807 auto it = setKeyPool->begin();
3808
3809 WalletBatch batch(*database);
3810 while (it != std::end(*setKeyPool)) {
3811 const int64_t& index = *(it);
3812 if (index > keypool_id) break; // set*KeyPool is ordered
3813
3814 CKeyPool keypool;
3815 if (batch.ReadPool(index, keypool)) { //TODO: This should be unnecessary
3816 m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
3817 }
3818 LearnAllRelatedScripts(keypool.vchPubKey);
3819 batch.ErasePool(index);
3820 WalletLogPrintf("keypool index %d removed\n", index);
3821 it = setKeyPool->erase(it);
3822 }
3823 }
3824
GetScriptForMining(std::shared_ptr<CReserveScript> & script)3825 void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
3826 {
3827 std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);
3828 CPubKey pubkey;
3829 if (!rKey->GetReservedKey(pubkey))
3830 return;
3831
3832 script = rKey;
3833 script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
3834 }
3835
LockCoin(const COutPoint & output)3836 void CWallet::LockCoin(const COutPoint& output)
3837 {
3838 AssertLockHeld(cs_wallet); // setLockedCoins
3839 setLockedCoins.insert(output);
3840 }
3841
UnlockCoin(const COutPoint & output)3842 void CWallet::UnlockCoin(const COutPoint& output)
3843 {
3844 AssertLockHeld(cs_wallet); // setLockedCoins
3845 setLockedCoins.erase(output);
3846 }
3847
UnlockAllCoins()3848 void CWallet::UnlockAllCoins()
3849 {
3850 AssertLockHeld(cs_wallet); // setLockedCoins
3851 setLockedCoins.clear();
3852 }
3853
IsLockedCoin(uint256 hash,unsigned int n) const3854 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
3855 {
3856 AssertLockHeld(cs_wallet); // setLockedCoins
3857 COutPoint outpt(hash, n);
3858
3859 return (setLockedCoins.count(outpt) > 0);
3860 }
3861
ListLockedCoins(std::vector<COutPoint> & vOutpts) const3862 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
3863 {
3864 AssertLockHeld(cs_wallet); // setLockedCoins
3865 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
3866 it != setLockedCoins.end(); it++) {
3867 COutPoint outpt = (*it);
3868 vOutpts.push_back(outpt);
3869 }
3870 }
3871
3872 /** @} */ // end of Actions
3873
GetKeyBirthTimes(interfaces::Chain::Lock & locked_chain,std::map<CTxDestination,int64_t> & mapKeyBirth) const3874 void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<CTxDestination, int64_t> &mapKeyBirth) const {
3875 AssertLockHeld(cs_wallet); // mapKeyMetadata
3876 mapKeyBirth.clear();
3877
3878 // get birth times for keys with metadata
3879 for (const auto& entry : mapKeyMetadata) {
3880 if (entry.second.nCreateTime) {
3881 mapKeyBirth[entry.first] = entry.second.nCreateTime;
3882 }
3883 }
3884
3885 // map in which we'll infer heights of other keys
3886 const Optional<int> tip_height = locked_chain.getHeight();
3887 const int max_height = tip_height && *tip_height > 144 ? *tip_height - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
3888 std::map<CKeyID, int> mapKeyFirstBlock;
3889 for (const CKeyID &keyid : GetKeys()) {
3890 if (mapKeyBirth.count(keyid) == 0)
3891 mapKeyFirstBlock[keyid] = max_height;
3892 }
3893
3894 // if there are no such keys, we're done
3895 if (mapKeyFirstBlock.empty())
3896 return;
3897
3898 // find first block that affects those keys, if there are any left
3899 for (const auto& entry : mapWallet) {
3900 // iterate over all wallet transactions...
3901 const CWalletTx &wtx = entry.second;
3902 if (Optional<int> height = locked_chain.getBlockHeight(wtx.hashBlock)) {
3903 // ... which are already in a block
3904 for (const CTxOut &txout : wtx.tx->vout) {
3905 // iterate over all their outputs
3906 for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *this)) {
3907 // ... and all their affected keys
3908 std::map<CKeyID, int>::iterator rit = mapKeyFirstBlock.find(keyid);
3909 if (rit != mapKeyFirstBlock.end() && *height < rit->second)
3910 rit->second = *height;
3911 }
3912 }
3913 }
3914 }
3915
3916 // Extract block timestamps for those keys
3917 for (const auto& entry : mapKeyFirstBlock)
3918 mapKeyBirth[entry.first] = locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; // block times can be 2h off
3919 }
3920
3921 /**
3922 * Compute smart timestamp for a transaction being added to the wallet.
3923 *
3924 * Logic:
3925 * - If sending a transaction, assign its timestamp to the current time.
3926 * - If receiving a transaction outside a block, assign its timestamp to the
3927 * current time.
3928 * - If receiving a block with a future timestamp, assign all its (not already
3929 * known) transactions' timestamps to the current time.
3930 * - If receiving a block with a past timestamp, before the most recent known
3931 * transaction (that we care about), assign all its (not already known)
3932 * transactions' timestamps to the same timestamp as that most-recent-known
3933 * transaction.
3934 * - If receiving a block with a past timestamp, but after the most recent known
3935 * transaction, assign all its (not already known) transactions' timestamps to
3936 * the block time.
3937 *
3938 * For more information see CWalletTx::nTimeSmart,
3939 * https://bitcointalk.org/?topic=54527, or
3940 * https://github.com/bitcoin/bitcoin/pull/1393.
3941 */
ComputeTimeSmart(const CWalletTx & wtx) const3942 unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
3943 {
3944 unsigned int nTimeSmart = wtx.nTimeReceived;
3945 if (!wtx.hashUnset()) {
3946 int64_t blocktime;
3947 if (chain().findBlock(wtx.hashBlock, nullptr /* block */, &blocktime)) {
3948 int64_t latestNow = wtx.nTimeReceived;
3949 int64_t latestEntry = 0;
3950
3951 // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
3952 int64_t latestTolerated = latestNow + 300;
3953 const TxItems& txOrdered = wtxOrdered;
3954 for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
3955 CWalletTx* const pwtx = it->second;
3956 if (pwtx == &wtx) {
3957 continue;
3958 }
3959 int64_t nSmartTime;
3960 nSmartTime = pwtx->nTimeSmart;
3961 if (!nSmartTime) {
3962 nSmartTime = pwtx->nTimeReceived;
3963 }
3964 if (nSmartTime <= latestTolerated) {
3965 latestEntry = nSmartTime;
3966 if (nSmartTime > latestNow) {
3967 latestNow = nSmartTime;
3968 }
3969 break;
3970 }
3971 }
3972
3973 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
3974 } else {
3975 WalletLogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.hashBlock.ToString());
3976 }
3977 }
3978 return nTimeSmart;
3979 }
3980
AddDestData(const CTxDestination & dest,const std::string & key,const std::string & value)3981 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3982 {
3983 if (boost::get<CNoDestination>(&dest))
3984 return false;
3985
3986 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
3987 return WalletBatch(*database).WriteDestData(EncodeDestination(dest), key, value);
3988 }
3989
EraseDestData(const CTxDestination & dest,const std::string & key)3990 bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
3991 {
3992 if (!mapAddressBook[dest].destdata.erase(key))
3993 return false;
3994 return WalletBatch(*database).EraseDestData(EncodeDestination(dest), key);
3995 }
3996
LoadDestData(const CTxDestination & dest,const std::string & key,const std::string & value)3997 void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3998 {
3999 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
4000 }
4001
GetDestData(const CTxDestination & dest,const std::string & key,std::string * value) const4002 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
4003 {
4004 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
4005 if(i != mapAddressBook.end())
4006 {
4007 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
4008 if(j != i->second.destdata.end())
4009 {
4010 if(value)
4011 *value = j->second;
4012 return true;
4013 }
4014 }
4015 return false;
4016 }
4017
GetDestValues(const std::string & prefix) const4018 std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const
4019 {
4020 std::vector<std::string> values;
4021 for (const auto& address : mapAddressBook) {
4022 for (const auto& data : address.second.destdata) {
4023 if (!data.first.compare(0, prefix.size(), prefix)) {
4024 values.emplace_back(data.second);
4025 }
4026 }
4027 }
4028 return values;
4029 }
4030
MarkPreSplitKeys()4031 void CWallet::MarkPreSplitKeys()
4032 {
4033 WalletBatch batch(*database);
4034 for (auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
4035 int64_t index = *it;
4036 CKeyPool keypool;
4037 if (!batch.ReadPool(index, keypool)) {
4038 throw std::runtime_error(std::string(__func__) + ": read keypool entry failed");
4039 }
4040 keypool.m_pre_split = true;
4041 if (!batch.WritePool(index, keypool)) {
4042 throw std::runtime_error(std::string(__func__) + ": writing modified keypool entry failed");
4043 }
4044 set_pre_split_keypool.insert(index);
4045 it = setExternalKeyPool.erase(it);
4046 }
4047 }
4048
Verify(interfaces::Chain & chain,const WalletLocation & location,bool salvage_wallet,std::string & error_string,std::string & warning_string)4049 bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::string& warning_string)
4050 {
4051 // Do some checking on wallet path. It should be either a:
4052 //
4053 // 1. Path where a directory can be created.
4054 // 2. Path to an existing directory.
4055 // 3. Path to a symlink to a directory.
4056 // 4. For backwards compatibility, the name of a data file in -walletdir.
4057 LOCK(cs_wallets);
4058 const fs::path& wallet_path = location.GetPath();
4059 fs::file_type path_type = fs::symlink_status(wallet_path).type();
4060 if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
4061 (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
4062 (path_type == fs::regular_file && fs::path(location.GetName()).filename() == location.GetName()))) {
4063 error_string = strprintf(
4064 "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
4065 "database/log.?????????? files can be stored, a location where such a directory could be created, "
4066 "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
4067 location.GetName(), GetWalletDir());
4068 return false;
4069 }
4070
4071 // Make sure that the wallet path doesn't clash with an existing wallet path
4072 if (IsWalletLoaded(wallet_path)) {
4073 error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName());
4074 return false;
4075 }
4076
4077 // Keep same database environment instance across Verify/Recover calls below.
4078 std::unique_ptr<WalletDatabase> database = WalletDatabase::Create(wallet_path);
4079
4080 try {
4081 if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) {
4082 return false;
4083 }
4084 } catch (const fs::filesystem_error& e) {
4085 error_string = strprintf("Error loading wallet %s. %s", location.GetName(), fsbridge::get_filesystem_error_message(e));
4086 return false;
4087 }
4088
4089 if (salvage_wallet) {
4090 // Recover readable keypairs:
4091 CWallet dummyWallet(chain, WalletLocation(), WalletDatabase::CreateDummy());
4092 std::string backup_filename;
4093 if (!WalletBatch::Recover(wallet_path, (void *)&dummyWallet, WalletBatch::RecoverKeysOnlyFilter, backup_filename)) {
4094 return false;
4095 }
4096 }
4097
4098 return WalletBatch::VerifyDatabaseFile(wallet_path, warning_string, error_string);
4099 }
4100
CreateWalletFromFile(interfaces::Chain & chain,const WalletLocation & location,uint64_t wallet_creation_flags)4101 std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags)
4102 {
4103 const std::string& walletFile = location.GetName();
4104
4105 // needed to restore wallet transaction meta data after -zapwallettxes
4106 std::vector<CWalletTx> vWtx;
4107
4108 if (gArgs.GetBoolArg("-zapwallettxes", false)) {
4109 uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
4110
4111 std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(chain, location, WalletDatabase::Create(location.GetPath()));
4112 DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
4113 if (nZapWalletRet != DBErrors::LOAD_OK) {
4114 InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
4115 return nullptr;
4116 }
4117 }
4118
4119 uiInterface.InitMessage(_("Loading wallet..."));
4120
4121 int64_t nStart = GetTimeMillis();
4122 bool fFirstRun = true;
4123 // TODO: Can't use std::make_shared because we need a custom deleter but
4124 // should be possible to use std::allocate_shared.
4125 std::shared_ptr<CWallet> walletInstance(new CWallet(chain, location, WalletDatabase::Create(location.GetPath())), ReleaseWallet);
4126 DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
4127 if (nLoadWalletRet != DBErrors::LOAD_OK)
4128 {
4129 if (nLoadWalletRet == DBErrors::CORRUPT) {
4130 InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
4131 return nullptr;
4132 }
4133 else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
4134 {
4135 InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
4136 " or address book entries might be missing or incorrect."),
4137 walletFile));
4138 }
4139 else if (nLoadWalletRet == DBErrors::TOO_NEW) {
4140 InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, PACKAGE_NAME));
4141 return nullptr;
4142 }
4143 else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
4144 {
4145 InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME));
4146 return nullptr;
4147 }
4148 else {
4149 InitError(strprintf(_("Error loading %s"), walletFile));
4150 return nullptr;
4151 }
4152 }
4153
4154 int prev_version = walletInstance->nWalletVersion;
4155 if (gArgs.GetBoolArg("-upgradewallet", fFirstRun))
4156 {
4157 int nMaxVersion = gArgs.GetArg("-upgradewallet", 0);
4158 if (nMaxVersion == 0) // the -upgradewallet without argument case
4159 {
4160 walletInstance->WalletLogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
4161 nMaxVersion = FEATURE_LATEST;
4162 walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
4163 }
4164 else
4165 walletInstance->WalletLogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
4166 if (nMaxVersion < walletInstance->GetVersion())
4167 {
4168 InitError(_("Cannot downgrade wallet"));
4169 return nullptr;
4170 }
4171 walletInstance->SetMaxVersion(nMaxVersion);
4172 }
4173
4174 // Upgrade to HD if explicit upgrade
4175 if (gArgs.GetBoolArg("-upgradewallet", false)) {
4176 LOCK(walletInstance->cs_wallet);
4177
4178 // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
4179 int max_version = walletInstance->nWalletVersion;
4180 if (!walletInstance->CanSupportFeature(FEATURE_HD_SPLIT) && max_version >=FEATURE_HD_SPLIT && max_version < FEATURE_PRE_SPLIT_KEYPOOL) {
4181 InitError(_("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified."));
4182 return nullptr;
4183 }
4184
4185 bool hd_upgrade = false;
4186 bool split_upgrade = false;
4187 if (walletInstance->CanSupportFeature(FEATURE_HD) && !walletInstance->IsHDEnabled()) {
4188 walletInstance->WalletLogPrintf("Upgrading wallet to HD\n");
4189 walletInstance->SetMinVersion(FEATURE_HD);
4190
4191 // generate a new master key
4192 CPubKey masterPubKey = walletInstance->GenerateNewSeed();
4193 walletInstance->SetHDSeed(masterPubKey);
4194 hd_upgrade = true;
4195 }
4196 // Upgrade to HD chain split if necessary
4197 if (walletInstance->CanSupportFeature(FEATURE_HD_SPLIT)) {
4198 walletInstance->WalletLogPrintf("Upgrading wallet to use HD chain split\n");
4199 walletInstance->SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL);
4200 split_upgrade = FEATURE_HD_SPLIT > prev_version;
4201 }
4202 // Mark all keys currently in the keypool as pre-split
4203 if (split_upgrade) {
4204 walletInstance->MarkPreSplitKeys();
4205 }
4206 // Regenerate the keypool if upgraded to HD
4207 if (hd_upgrade) {
4208 if (!walletInstance->TopUpKeyPool()) {
4209 InitError(_("Unable to generate keys"));
4210 return nullptr;
4211 }
4212 }
4213 }
4214
4215 if (fFirstRun)
4216 {
4217 // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
4218 walletInstance->SetMinVersion(FEATURE_LATEST);
4219
4220 if ((wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
4221 //selective allow to set flags
4222 walletInstance->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
4223 } else if (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET) {
4224 walletInstance->SetWalletFlag(WALLET_FLAG_BLANK_WALLET);
4225 } else {
4226 // generate a new seed
4227 CPubKey seed = walletInstance->GenerateNewSeed();
4228 walletInstance->SetHDSeed(seed);
4229 } // Otherwise, do not generate a new seed
4230
4231 // Top up the keypool
4232 if (walletInstance->CanGenerateKeys() && !walletInstance->TopUpKeyPool()) {
4233 InitError(_("Unable to generate initial keys"));
4234 return nullptr;
4235 }
4236
4237 auto locked_chain = chain.assumeLocked(); // Temporary. Removed in upcoming lock cleanup
4238 walletInstance->ChainStateFlushed(locked_chain->getTipLocator());
4239 } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
4240 // Make it impossible to disable private keys after creation
4241 InitError(strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile));
4242 return NULL;
4243 } else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
4244 LOCK(walletInstance->cs_KeyStore);
4245 if (!walletInstance->mapKeys.empty() || !walletInstance->mapCryptedKeys.empty()) {
4246 InitWarning(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
4247 }
4248 }
4249
4250 if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
4251 InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
4252 return nullptr;
4253 }
4254
4255 if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
4256 InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
4257 return nullptr;
4258 }
4259
4260 if (gArgs.IsArgSet("-mintxfee")) {
4261 CAmount n = 0;
4262 if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
4263 InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
4264 return nullptr;
4265 }
4266 if (n > HIGH_TX_FEE_PER_KB) {
4267 InitWarning(AmountHighWarn("-mintxfee") + " " +
4268 _("This is the minimum transaction fee you pay on every transaction."));
4269 }
4270 walletInstance->m_min_fee = CFeeRate(n);
4271 }
4272
4273 walletInstance->m_allow_fallback_fee = Params().IsFallbackFeeEnabled();
4274 if (gArgs.IsArgSet("-fallbackfee")) {
4275 CAmount nFeePerK = 0;
4276 if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
4277 InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
4278 return nullptr;
4279 }
4280 if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4281 InitWarning(AmountHighWarn("-fallbackfee") + " " +
4282 _("This is the transaction fee you may pay when fee estimates are not available."));
4283 }
4284 walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
4285 walletInstance->m_allow_fallback_fee = nFeePerK != 0; //disable fallback fee in case value was set to 0, enable if non-null value
4286 }
4287 if (gArgs.IsArgSet("-discardfee")) {
4288 CAmount nFeePerK = 0;
4289 if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
4290 InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
4291 return nullptr;
4292 }
4293 if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4294 InitWarning(AmountHighWarn("-discardfee") + " " +
4295 _("This is the transaction fee you may discard if change is smaller than dust at this level"));
4296 }
4297 walletInstance->m_discard_rate = CFeeRate(nFeePerK);
4298 }
4299 if (gArgs.IsArgSet("-paytxfee")) {
4300 CAmount nFeePerK = 0;
4301 if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
4302 InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
4303 return nullptr;
4304 }
4305 if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4306 InitWarning(AmountHighWarn("-paytxfee") + " " +
4307 _("This is the transaction fee you will pay if you send a transaction."));
4308 }
4309 walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
4310 if (walletInstance->m_pay_tx_fee < ::minRelayTxFee) {
4311 InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
4312 gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
4313 return nullptr;
4314 }
4315 }
4316 walletInstance->m_confirm_target = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
4317 walletInstance->m_spend_zero_conf_change = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
4318 walletInstance->m_signal_rbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
4319
4320 walletInstance->WalletLogPrintf("Wallet completed loading in %15dms\n", GetTimeMillis() - nStart);
4321
4322 // Try to top up keypool. No-op if the wallet is locked.
4323 walletInstance->TopUpKeyPool();
4324
4325 auto locked_chain = chain.lock();
4326 LOCK(walletInstance->cs_wallet);
4327
4328 int rescan_height = 0;
4329 if (!gArgs.GetBoolArg("-rescan", false))
4330 {
4331 WalletBatch batch(*walletInstance->database);
4332 CBlockLocator locator;
4333 if (batch.ReadBestBlock(locator)) {
4334 if (const Optional<int> fork_height = locked_chain->findLocatorFork(locator)) {
4335 rescan_height = *fork_height;
4336 }
4337 }
4338 }
4339
4340 const Optional<int> tip_height = locked_chain->getHeight();
4341 if (tip_height) {
4342 walletInstance->m_last_block_processed = locked_chain->getBlockHash(*tip_height);
4343 } else {
4344 walletInstance->m_last_block_processed.SetNull();
4345 }
4346
4347 if (tip_height && *tip_height != rescan_height)
4348 {
4349 //We can't rescan beyond non-pruned blocks, stop and throw an error
4350 //this might happen if a user uses an old wallet within a pruned node
4351 // or if he ran -disablewallet for a longer time, then decided to re-enable
4352 if (fPruneMode)
4353 {
4354 int block_height = *tip_height;
4355 while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
4356 --block_height;
4357 }
4358
4359 if (rescan_height != block_height) {
4360 InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
4361 return nullptr;
4362 }
4363 }
4364
4365 uiInterface.InitMessage(_("Rescanning..."));
4366 walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
4367
4368 // No need to read and scan block if block was created before
4369 // our wallet birthday (as adjusted for block time variability)
4370 if (walletInstance->nTimeFirstKey) {
4371 if (Optional<int> first_block = locked_chain->findFirstBlockWithTimeAndHeight(walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW, rescan_height)) {
4372 rescan_height = *first_block;
4373 }
4374 }
4375
4376 nStart = GetTimeMillis();
4377 {
4378 WalletRescanReserver reserver(walletInstance.get());
4379 if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(locked_chain->getBlockHash(rescan_height), {} /* stop block */, reserver, true /* update */).status)) {
4380 InitError(_("Failed to rescan the wallet during initialization"));
4381 return nullptr;
4382 }
4383 }
4384 walletInstance->WalletLogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nStart);
4385 walletInstance->ChainStateFlushed(locked_chain->getTipLocator());
4386 walletInstance->database->IncrementUpdateCounter();
4387
4388 // Restore wallet transaction metadata after -zapwallettxes=1
4389 if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2")
4390 {
4391 WalletBatch batch(*walletInstance->database);
4392
4393 for (const CWalletTx& wtxOld : vWtx)
4394 {
4395 uint256 hash = wtxOld.GetHash();
4396 std::map<uint256, CWalletTx>::iterator mi = walletInstance->mapWallet.find(hash);
4397 if (mi != walletInstance->mapWallet.end())
4398 {
4399 const CWalletTx* copyFrom = &wtxOld;
4400 CWalletTx* copyTo = &mi->second;
4401 copyTo->mapValue = copyFrom->mapValue;
4402 copyTo->vOrderForm = copyFrom->vOrderForm;
4403 copyTo->nTimeReceived = copyFrom->nTimeReceived;
4404 copyTo->nTimeSmart = copyFrom->nTimeSmart;
4405 copyTo->fFromMe = copyFrom->fFromMe;
4406 copyTo->nOrderPos = copyFrom->nOrderPos;
4407 batch.WriteTx(*copyTo);
4408 }
4409 }
4410 }
4411 }
4412
4413 uiInterface.LoadWallet(walletInstance);
4414
4415 // Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main.
4416 RegisterValidationInterface(walletInstance.get());
4417
4418 walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
4419
4420 {
4421 walletInstance->WalletLogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
4422 walletInstance->WalletLogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
4423 walletInstance->WalletLogPrintf("mapAddressBook.size() = %u\n", walletInstance->mapAddressBook.size());
4424 }
4425
4426 return walletInstance;
4427 }
4428
postInitProcess()4429 void CWallet::postInitProcess()
4430 {
4431 auto locked_chain = chain().lock();
4432 LOCK(cs_wallet);
4433
4434 // Add wallet transactions that aren't already in a block to mempool
4435 // Do this here as mempool requires genesis block to be loaded
4436 ReacceptWalletTransactions(*locked_chain);
4437
4438 // Update wallet transactions with current mempool transactions.
4439 chain().requestMempoolTransactions([this](const CTransactionRef& tx) { TransactionAddedToMempool(tx); });
4440 }
4441
BackupWallet(const std::string & strDest)4442 bool CWallet::BackupWallet(const std::string& strDest)
4443 {
4444 return database->Backup(strDest);
4445 }
4446
CKeyPool()4447 CKeyPool::CKeyPool()
4448 {
4449 nTime = GetTime();
4450 fInternal = false;
4451 m_pre_split = false;
4452 }
4453
CKeyPool(const CPubKey & vchPubKeyIn,bool internalIn)4454 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
4455 {
4456 nTime = GetTime();
4457 vchPubKey = vchPubKeyIn;
4458 fInternal = internalIn;
4459 m_pre_split = false;
4460 }
4461
CWalletKey(int64_t nExpires)4462 CWalletKey::CWalletKey(int64_t nExpires)
4463 {
4464 nTimeCreated = (nExpires ? GetTime() : 0);
4465 nTimeExpires = nExpires;
4466 }
4467
SetMerkleBranch(const uint256 & block_hash,int posInBlock)4468 void CMerkleTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
4469 {
4470 // Update the tx's hashBlock
4471 hashBlock = block_hash;
4472
4473 // set the position of the transaction in the block
4474 nIndex = posInBlock;
4475 }
4476
GetDepthInMainChain(interfaces::Chain::Lock & locked_chain) const4477 int CMerkleTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
4478 {
4479 if (hashUnset())
4480 return 0;
4481
4482 AssertLockHeld(cs_main);
4483
4484 return locked_chain.getBlockDepth(hashBlock) * (nIndex == -1 ? -1 : 1);
4485 }
4486
GetBlocksToMaturity(interfaces::Chain::Lock & locked_chain) const4487 int CMerkleTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
4488 {
4489 if (!IsCoinBase())
4490 return 0;
4491 int chain_depth = GetDepthInMainChain(locked_chain);
4492 assert(chain_depth >= 0); // coinbase tx should not be conflicted
4493 return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
4494 }
4495
IsImmatureCoinBase(interfaces::Chain::Lock & locked_chain) const4496 bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
4497 {
4498 // note GetBlocksToMaturity is 0 for non-coinbase tx
4499 return GetBlocksToMaturity(locked_chain) > 0;
4500 }
4501
AcceptToMemoryPool(interfaces::Chain::Lock & locked_chain,const CAmount & nAbsurdFee,CValidationState & state)4502 bool CWalletTx::AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, const CAmount& nAbsurdFee, CValidationState& state)
4503 {
4504 LockAnnotation lock(::cs_main); // Temporary, for AcceptToMemoryPool below. Removed in upcoming commit.
4505
4506 // We must set fInMempool here - while it will be re-set to true by the
4507 // entered-mempool callback, if we did not there would be a race where a
4508 // user could call sendmoney in a loop and hit spurious out of funds errors
4509 // because we think that this newly generated transaction's change is
4510 // unavailable as we're not yet aware that it is in the mempool.
4511 bool ret = ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
4512 nullptr /* plTxnReplaced */, false /* bypass_limits */, nAbsurdFee);
4513 fInMempool |= ret;
4514 return ret;
4515 }
4516
LearnRelatedScripts(const CPubKey & key,OutputType type)4517 void CWallet::LearnRelatedScripts(const CPubKey& key, OutputType type)
4518 {
4519 if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
4520 CTxDestination witdest = WitnessV0KeyHash(key.GetID());
4521 CScript witprog = GetScriptForDestination(witdest);
4522 // Make sure the resulting program is solvable.
4523 assert(IsSolvable(*this, witprog));
4524 AddCScript(witprog);
4525 }
4526 }
4527
LearnAllRelatedScripts(const CPubKey & key)4528 void CWallet::LearnAllRelatedScripts(const CPubKey& key)
4529 {
4530 // OutputType::P2SH_SEGWIT always adds all necessary scripts for all types.
4531 LearnRelatedScripts(key, OutputType::P2SH_SEGWIT);
4532 }
4533
GroupOutputs(const std::vector<COutput> & outputs,bool single_coin) const4534 std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outputs, bool single_coin) const {
4535 std::vector<OutputGroup> groups;
4536 std::map<CTxDestination, OutputGroup> gmap;
4537 CTxDestination dst;
4538 for (const auto& output : outputs) {
4539 if (output.fSpendable) {
4540 CInputCoin input_coin = output.GetInputCoin();
4541
4542 size_t ancestors, descendants;
4543 mempool.GetTransactionAncestry(output.tx->GetHash(), ancestors, descendants);
4544 if (!single_coin && ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
4545 // Limit output groups to no more than 10 entries, to protect
4546 // against inadvertently creating a too-large transaction
4547 // when using -avoidpartialspends
4548 if (gmap[dst].m_outputs.size() >= OUTPUT_GROUP_MAX_ENTRIES) {
4549 groups.push_back(gmap[dst]);
4550 gmap.erase(dst);
4551 }
4552 gmap[dst].Insert(input_coin, output.nDepth, output.tx->IsFromMe(ISMINE_ALL), ancestors, descendants);
4553 } else {
4554 groups.emplace_back(input_coin, output.nDepth, output.tx->IsFromMe(ISMINE_ALL), ancestors, descendants);
4555 }
4556 }
4557 }
4558 if (!single_coin) {
4559 for (const auto& it : gmap) groups.push_back(it.second);
4560 }
4561 return groups;
4562 }
4563
GetKeyOrigin(const CKeyID & keyID,KeyOriginInfo & info) const4564 bool CWallet::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
4565 {
4566 CKeyMetadata meta;
4567 {
4568 LOCK(cs_wallet);
4569 auto it = mapKeyMetadata.find(keyID);
4570 if (it != mapKeyMetadata.end()) {
4571 meta = it->second;
4572 }
4573 }
4574 if (meta.has_key_origin) {
4575 std::copy(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4, info.fingerprint);
4576 info.path = meta.key_origin.path;
4577 } else { // Single pubkeys get the master fingerprint of themselves
4578 std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint);
4579 }
4580 return true;
4581 }
4582
AddKeyOrigin(const CPubKey & pubkey,const KeyOriginInfo & info)4583 bool CWallet::AddKeyOrigin(const CPubKey& pubkey, const KeyOriginInfo& info)
4584 {
4585 LOCK(cs_wallet);
4586 std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint);
4587 mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
4588 mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
4589 mapKeyMetadata[pubkey.GetID()].hdKeypath = WriteHDKeypath(info.path);
4590 return WriteKeyMetadata(mapKeyMetadata[pubkey.GetID()], pubkey, true);
4591 }
4592