blockchain_db

/** \file
 * Cryptonote Blockchain Database Interface
 *
 * The DB interface is a store for the canonical block chain.
 * It serves as a persistent storage for the blockchain.
 *
 * For the sake of efficiency, a concrete implementation may also
 * store some blockchain data outside of the blocks, such as spent
 * transfer key images, unspent transaction outputs, etc.
 *
 * Examples are as follows:
 *
 * Transactions are duplicated so that we don't have to fetch a whole block
 * in order to fetch a transaction from that block.
 *
 * Spent key images are duplicated outside of the blocks so it is quick
 * to verify an output hasn't already been spent
 *
 * Unspent transaction outputs are duplicated to quickly gather random
 * outputs to use for mixins
 *
 * Indices and Identifiers:
 * The word "index" is used ambiguously throughout this code. It is
 * particularly confusing when talking about the output or transaction
 * tables since their indexing can refer to themselves or each other.
 * I have attempted to clarify these usages here:
 *
 * Blocks, transactions, and outputs are all identified by a hash.
 * For storage efficiency, a 64-bit integer ID is used instead of the hash
 * inside the DB. Tables exist to map between hash and ID. A block ID is
 * also referred to as its "height". Transactions and outputs generally are
 * not referred to by ID outside of this module, but the tx ID is returned
 * by tx_exists() and used by get_tx_amount_output_indices(). Like their
 * corresponding hashes, IDs are globally unique.
 *
 * The remaining uses of the word "index" refer to local offsets, and are
 * not globally unique. An "amount output index" N refers to the Nth output
 * of a specific amount. An "output local index" N refers to the Nth output
 * of a specific tx.
 *
 * Exceptions:
 *   DB_ERROR -- generic
 *   DB_OPEN_FAILURE
 *   DB_CREATE_FAILURE
 *   DB_SYNC_FAILURE
 *   BLOCK_DNE
 *   BLOCK_PARENT_DNE
 *   BLOCK_EXISTS
 *   BLOCK_INVALID -- considering making this multiple errors
 *   TX_DNE
 *   TX_EXISTS
 *   OUTPUT_DNE
 *   OUTPUT_EXISTS
 *   KEY_IMAGE_EXISTS
 */

add_block

   * @brief add the block and metadata to the db
   *
   * The subclass implementing this will add the specified block and
   * block metadata to its backing store.  This does not include its
   * transactions, those are added in a separate step.
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

remove_block

   * @brief remove data about the top block
   *
   * The subclass implementing this will remove the block data from the top
   * block in the chain.  The data to be removed is that which was added in
   * BlockchainDB::add_block(const block& blk, const size_t& block_size, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const crypto::hash& blk_hash)
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

add_transaction_data

   * @brief store the transaction and its metadata
   *
   * The subclass implementing this will add the specified transaction data
   * to its backing store.  This includes only the transaction blob itself
   * and the other data passed here, not the separate outputs of the
   * transaction.
   *
   * It returns a tx ID, which is a mapping from the tx_hash. The tx ID
   * is used in #add_tx_amount_output_indices().
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

remove_transaction_data

   * @brief remove data about a transaction
   *
   * The subclass implementing this will remove the transaction data 
   * for the passed transaction.  The data to be removed was added in
   * add_transaction_data().  Additionally, current subclasses have behavior
   * which requires the transaction itself as a parameter here.  Future
   * implementations should note that this parameter is subject to be removed
   * at a later time.
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

add_output

   * @brief store an output
   *
   * The subclass implementing this will add the output data passed to its
   * backing store in a suitable manner.  In addition, the subclass is responsible
   * for keeping track of the global output count in some manner, so that
   * outputs may be indexed by the order in which they were created.  In the
   * future, this tracking (of the number, at least) should be moved to
   * this class, as it is necessary and the same among all BlockchainDB.
   *
   * It returns an amount output index, which is the index of the output
   * for its specified amount.
   *
   * This data should be stored in such a manner that the only thing needed to
   * reverse the process is the tx_out.
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

add_tx_amount_output_indices

   * @brief store amount output indices for a tx's outputs
   *
   * The subclass implementing this will add the amount output indices to its
   * backing store in a suitable manner. The tx_id will be the same one that
   * was returned from #add_output().
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

add_spent_key

   * @brief store a spent key
   *
   * The subclass implementing this will store the spent key image.
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

remove_spent_key

   * @brief remove a spent key
   *
   * The subclass implementing this will remove the key image.
   *
   * If any of this cannot be done, the subclass should throw the corresponding
   * subclass of DB_EXCEPTION

pop_block

   * @brief private version of pop_block, for undoing if an add_block fails
   *
   * This function simply calls pop_block(block& blk, std::vector<transaction>& txs)
   * with dummy parameters, as the returns-by-reference can be discarded.

remove_transaction

   * @brief helper function to remove transaction from the blockchain
   *
   * This function encapsulates aspects of removing a transaction.

add_transaction

   * @brief helper function for add_transactions, to add each individual transaction
   *
   * This function is called by add_transactions() for each transaction to be
   * added.

block_exists

* @brief checks if a block exists

get_block_blob

   * @brief fetches the block with the given hash
   *
   * The subclass should return the requested block.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block

   * @brief fetches the block with the given hash
   *
   * Returns the requested block.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block_height

   * @brief gets the height of the block with a given hash
   *
   * The subclass should return the requested height.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block_header

   * @brief fetch a block header
   *
   * The subclass should return the block header from the block with
   * the given hash.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block_blob_from_height

   * @brief fetch a block blob by height
   *
   * The subclass should return the block at the given height.
   *
   * If the block does not exist, that is to say if the blockchain is not
   * that high, then the subclass should throw BLOCK_DNE

get_block_from_height

   * @brief fetch a block by height
   *
   * If the block does not exist, that is to say if the blockchain is not
   * that high, then the subclass should throw BLOCK_DNE

get_block_timestamp

   * @brief fetch a block's timestamp
   *
   * The subclass should return the timestamp of the block with the
   * given height.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_top_block_timestamp

   * @brief fetch the top block's timestamp
   *
   * The subclass should return the timestamp of the most recent block.

get_block_size

   * @brief fetch a block's size
   *
   * The subclass should return the size of the block with the
   * given height.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block_cumulative_difficulty

   * @brief fetch a block's cumulative difficulty
   *
   * The subclass should return the cumulative difficulty of the block with the
   * given height.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

get_block_difficulty

   * @brief fetch a block's difficulty
   *
   * The subclass should return the difficulty of the block with the
   * given height.
   *
   * If the block does not exist, the subclass should throw BLOCK_DNE

……

Last updated

Was this helpful?