| 945 | } |
| 946 | |
| 947 | CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx, bool fFlushOnClose, bool rescanning_old_block) |
| 948 | { |
| 949 | LOCK(cs_wallet); |
| 950 | |
| 951 | WalletBatch batch(GetDatabase(), fFlushOnClose); |
| 952 | |
| 953 | uint256 hash = tx->GetHash(); |
| 954 | |
| 955 | if (IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) { |
| 956 | // Mark used destinations |
| 957 | std::set<CTxDestination> tx_destinations; |
| 958 | |
| 959 | for (const CTxIn& txin : tx->vin) { |
| 960 | const COutPoint& op = txin.prevout; |
| 961 | SetSpentKeyState(batch, op.hash, op.n, true, tx_destinations); |
| 962 | } |
| 963 | |
| 964 | MarkDestinationsDirty(tx_destinations); |
| 965 | } |
| 966 | |
| 967 | // Inserts only if not already there, returns tx inserted or tx found |
| 968 | auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(tx, state)); |
| 969 | CWalletTx& wtx = (*ret.first).second; |
| 970 | bool fInsertedNew = ret.second; |
| 971 | bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew); |
| 972 | if (fInsertedNew) { |
| 973 | wtx.nTimeReceived = GetTime(); |
| 974 | wtx.nOrderPos = IncOrderPosNext(&batch); |
| 975 | wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx)); |
| 976 | wtx.nTimeSmart = ComputeTimeSmart(wtx, rescanning_old_block); |
| 977 | AddToSpends(hash, &batch); |
| 978 | } |
| 979 | |
| 980 | if (!fInsertedNew) |
| 981 | { |
| 982 | if (state.index() != wtx.m_state.index()) { |
| 983 | wtx.m_state = state; |
| 984 | fUpdated = true; |
| 985 | } else { |
| 986 | assert(TxStateSerializedIndex(wtx.m_state) == TxStateSerializedIndex(state)); |
| 987 | assert(TxStateSerializedBlockHash(wtx.m_state) == TxStateSerializedBlockHash(state)); |
| 988 | } |
| 989 | // If we have a witness-stripped version of this transaction, and we |
| 990 | // see a new version with a witness, then we must be upgrading a pre-segwit |
| 991 | // wallet. Store the new version of the transaction with the witness, |
| 992 | // as the stripped-version must be invalid. |
| 993 | // TODO: Store all versions of the transaction, instead of just one. |
| 994 | if (tx->HasWitness() && !wtx.tx->HasWitness()) { |
| 995 | wtx.SetTx(tx); |
| 996 | fUpdated = true; |
| 997 | } |
| 998 | } |
| 999 | |
| 1000 | //// debug print |
| 1001 | WalletLogPrintf("AddToWallet %s %s%s\n", hash.ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); |
| 1002 | |
| 1003 | // Write to disk |
| 1004 | if (fInsertedNew || fUpdated) |