* 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 */
| 1589 | * @return A DisconnectResult as an int |
| 1590 | */ |
| 1591 | int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out) |
| 1592 | { |
| 1593 | bool fClean = true; |
| 1594 | |
| 1595 | if (view.HaveCoin(out)) fClean = false; // overwriting transaction output |
| 1596 | |
| 1597 | if (undo.nHeight == 0) { |
| 1598 | // Missing undo metadata (height and coinbase). Older versions included this |
| 1599 | // information only in undo records for the last spend of a transactions' |
| 1600 | // outputs. This implies that it must be present for some other output of the same tx. |
| 1601 | const Coin& alternate = AccessByTxid(view, out.hash); |
| 1602 | if (!alternate.IsSpent()) { |
| 1603 | undo.nHeight = alternate.nHeight; |
| 1604 | undo.fCoinBase = alternate.fCoinBase; |
| 1605 | } else { |
| 1606 | return DISCONNECT_FAILED; // adding output for transaction without known metadata |
| 1607 | } |
| 1608 | } |
| 1609 | // The potential_overwrite parameter to AddCoin is only allowed to be false if we know for |
| 1610 | // sure that the coin did not already exist in the cache. As we have queried for that above |
| 1611 | // using HaveCoin, we don't need to guess. When fClean is false, a coin already existed and |
| 1612 | // it is an overwrite. |
| 1613 | view.AddCoin(out, std::move(undo), !fClean); |
| 1614 | |
| 1615 | return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; |
| 1616 | } |
| 1617 | |
| 1618 | /** Undo the effects of this block (with given index) on the UTXO set represented by coins. |
| 1619 | * When FAILED is returned, view is left in an indeterminate state. */ |