Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: Rework utxoset/view to use outpoints. #2540

Merged
merged 1 commit into from
Jan 14, 2021

Commits on Jan 14, 2021

  1. multi: Rework utxoset/view to use outpoints.

    This modifies the utxoset in the database and related UtxoViewpoint to
    store and work with unspent transaction outputs on a per-output basis
    instead of at a transaction level.
    
    The primary motivation is to simplify the code, pave the way for a
    utxo cache, and generally focus on optimizing runtime performance.
    
    The tradeoff is that this approach does somewhat increase the size of
    the serialized utxoset since it means that the transaction hash is
    duplicated for each output as a part of the key and some additional
    details are duplicated in each output.  The details duplicated in each
    output include flags encoded into a single byte that specify whether the
    containing transaction is a coinbase, whether the containing transaction
    has an expiry, and the transaction type.  Additionally, the containing
    block height and index are stored in each output.
    
    However, in practice, the size difference isn't all that large, disk
    space is relatively cheap, certainly cheaper than memory, and it is much
    more important to provide more efficient runtime operation since that is
    the ultimate purpose of the daemon.
    
    While performing this conversion, it also simplifies the code to remove
    the transaction version information from the utxoset as well as the
    spend journal.  The logic for only serializing it under certain
    circumstances is complicated, and it was only used for the gettxout RPC,
    where it has already been removed.
    
    The utxo set and spend journal in the database are automatically
    migrated to the new format with this commit and it is possible to
    interrupt and resume the migration process.
    
    Finally, it also updates all references and tests that previously dealt
    with transaction hashes to use outpoints instead.
    
    An overview of the changes are as follows:
    
    - Remove transaction version from both spent and unspent output entries
      - Update utxo serialization format to exclude the version
      - Update spend journal serialization format to exclude the version
    - Convert UtxoEntry to represent a specific utxo instead of a
      transaction with all remaining utxos
      - Optimize for memory usage with an eye toward a utxo cache
        - Combine fields such as whether the containing transaction is a
          coinbase, whether the containing transaction has an expiry, and
          the transaction type into a single byte
        - Align entry fields to eliminate extra padding since ultimately
          there will be a lot of these in memory
        - Introduce a free list for serializing an outpoint to the database
          key format to significantly reduce pressure on the GC
      - Update entries to be keyed by a <hash><tree><output index> outpoint
        rather than just a tx hash
      - Update all related functions that previously dealt with transaction
        hashes to accept outpoints instead
      - Update all callers accordingly
      - Only add individually requested outputs from the mempool when
        constructing a mempool view
    - Modify the spend journal to always store the encoded flags with every
      spent txout
      - Combine fields such as whether the containing transaction is a
        coinbase, whether the containing transaction has an expiry, and the
        transaction type into a single byte
        - Use 4 bits instead of 3 for the transaction type to be consistent
          with utxos. The extra bit was already unused so this doesn't take
          any additional space
      - Remove the fully spent flag
    - Introduce ticketMinOuts in place of stakeExtra
      - Renamed stakeExtra as ticketMinOuts and updated all comments to make
        the purpose of the field clearer
      - Only store ticketMinOuts for ticket submission outputs
      - Add TicketMinimalOutputs function on UtxoEntry in place of
        ConvertUtxosToMinimalOutputs
    - Always decompress data loaded from the database now that a utxo entry
      only consists of a specific output
    - Introduce upgrade code to migrate the utxo set and spend journal to
      the new format
      - Update current database version to 9
      - Update current utxo set version to 3
      - Update current spend journal version to 3
      - Introduce the ability to run upgrades after the block index has been
        loaded
    - Update all tests to expect the correct encodings, remove tests that no
      longer apply, and add new ones for the new expected behavior
      - Convert old tests for the legacy utxo format deserialization code to
        test the new function that is used during upgrade
    - Introduce a few new functions on UtxoViewpoint
      - AddTxOut for adding an individual txout versus all of them
      - addTxOut to handle the common code between the new AddTxOut and
        existing AddTxOuts
      - RemoveEntry for removing an individual txout
    - Remove the ErrDiscordantTxTree error
      - Since utxos are now retrieved using an outpoint, which includes the
        tree, it is no longer possible to hit this error path
    rstaudt2 committed Jan 14, 2021
    Configuration menu
    Copy the full SHA
    397a9e9 View commit details
    Browse the repository at this point in the history