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