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?