| 1087 | } |
| 1088 | |
| 1089 | bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const SyncTxState& state, bool fUpdate, bool rescanning_old_block) |
| 1090 | { |
| 1091 | const CTransaction& tx = *ptx; |
| 1092 | { |
| 1093 | AssertLockHeld(cs_wallet); |
| 1094 | |
| 1095 | if (auto* conf = std::get_if<TxStateConfirmed>(&state)) { |
| 1096 | for (const CTxIn& txin : tx.vin) { |
| 1097 | std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout); |
| 1098 | while (range.first != range.second) { |
| 1099 | if (range.first->second != tx.GetHash()) { |
| 1100 | WalletLogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), conf->confirmed_block_hash.ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n); |
| 1101 | MarkConflicted(conf->confirmed_block_hash, conf->confirmed_block_height, range.first->second); |
| 1102 | } |
| 1103 | range.first++; |
| 1104 | } |
| 1105 | } |
| 1106 | } |
| 1107 | |
| 1108 | bool fExisted = mapWallet.count(tx.GetHash()) != 0; |
| 1109 | if (fExisted && !fUpdate) return false; |
| 1110 | if (fExisted || IsMine(tx) || IsFromMe(tx)) |
| 1111 | { |
| 1112 | /* Check if any keys in the wallet keypool that were supposed to be unused |
| 1113 | * have appeared in a new transaction. If so, remove those keys from the keypool. |
| 1114 | * This can happen when restoring an old wallet backup that does not contain |
| 1115 | * the mostly recently created transactions from newer versions of the wallet. |
| 1116 | */ |
| 1117 | |
| 1118 | // loop though all outputs |
| 1119 | for (const CTxOut& txout: tx.vout) { |
| 1120 | for (const auto& spk_man : GetScriptPubKeyMans(txout.scriptPubKey)) { |
| 1121 | for (auto &dest : spk_man->MarkUnusedAddresses(txout.scriptPubKey)) { |
| 1122 | // If internal flag is not defined try to infer it from the ScriptPubKeyMan |
| 1123 | if (!dest.internal.has_value()) { |
| 1124 | dest.internal = IsInternalScriptPubKeyMan(spk_man); |
| 1125 | } |
| 1126 | |
| 1127 | // skip if can't determine whether it's a receiving address or not |
| 1128 | if (!dest.internal.has_value()) continue; |
| 1129 | |
| 1130 | // If this is a receiving address and it's not in the address book yet |
| 1131 | // (e.g. it wasn't generated on this node or we're restoring from backup) |
| 1132 | // add it to the address book for proper transaction accounting |
| 1133 | if (!*dest.internal && !FindAddressBookEntry(dest.dest, /* allow_change= */ false)) { |
| 1134 | SetAddressBook(dest.dest, "", "receive"); |
| 1135 | } |
| 1136 | } |
| 1137 | } |
| 1138 | } |
| 1139 | |
| 1140 | // Block disconnection override an abandoned tx as unconfirmed |
| 1141 | // which means user may have to call abandontransaction again |
| 1142 | TxState tx_state = std::visit([](auto&& s) -> TxState { return s; }, state); |
| 1143 | return AddToWallet(MakeTransactionRef(tx), tx_state, /*update_wtx=*/nullptr, /*fFlushOnClose=*/false, rescanning_old_block); |
| 1144 | } |
| 1145 | } |
| 1146 | return false; |
nothing calls this directly
no test coverage detected