* Restore the UTXO in a Coin at a given COutPoint * @param undo The Coin to be restored. * @param view The coins view to which to apply the changes. * @param out The out point that corresponds to the tx input. * @return A DisconnectResult as an int */
| 2153 | * @return A DisconnectResult as an int |
| 2154 | */ |
| 2155 | int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out) |
| 2156 | { |
| 2157 | bool fClean = true; |
| 2158 | |
| 2159 | if (view.HaveCoin(out)) fClean = false; // overwriting transaction output |
| 2160 | |
| 2161 | if (undo.nHeight == 0) { |
| 2162 | // Missing undo metadata (height and coinbase). Older versions included this |
| 2163 | // information only in undo records for the last spend of a transactions' |
| 2164 | // outputs. This implies that it must be present for some other output of the same tx. |
| 2165 | const Coin& alternate = AccessByTxid(view, out.hash); |
| 2166 | if (!alternate.IsSpent()) { |
| 2167 | undo.nHeight = alternate.nHeight; |
| 2168 | undo.fCoinBase = alternate.fCoinBase; |
| 2169 | } else { |
| 2170 | return DISCONNECT_FAILED; // adding output for transaction without known metadata |
| 2171 | } |
| 2172 | } |
| 2173 | // If the coin already exists as an unspent coin in the cache, then the |
| 2174 | // possible_overwrite parameter to AddCoin must be set to true. We have |
| 2175 | // already checked whether an unspent coin exists above using HaveCoin, so |
| 2176 | // we don't need to guess. When fClean is false, an unspent coin already |
| 2177 | // existed and it is an overwrite. |
| 2178 | view.AddCoin(out, std::move(undo), !fClean); |
| 2179 | |
| 2180 | return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; |
| 2181 | } |
| 2182 | |
| 2183 | /** Undo the effects of this block (with given index) on the UTXO set represented by coins. |
| 2184 | * When FAILED is returned, view is left in an indeterminate state. */ |