33 #include <boost/asio/io_service.hpp> 34 #if BOOST_VERSION >= 107400 35 #include <boost/serialization/library_version_type.hpp> 37 #include <boost/serialization/serialization.hpp> 38 #include <boost/serialization/version.hpp> 39 #include <boost/serialization/list.hpp> 40 #include <boost/multi_index_container.hpp> 41 #include <boost/multi_index/global_fun.hpp> 42 #include <boost/multi_index/hashed_index.hpp> 43 #include <boost/multi_index/member.hpp> 44 #include <boost/algorithm/hex.hpp> 47 #include <unordered_map> 48 #include <unordered_set> 67 namespace tools {
class Notify; }
187 bool get_blocks(
uint64_t start_offset,
size_t count, std::vector<std::pair<cryptonote::blobdata,block>>&
blocks, std::vector<cryptonote::blobdata>& txs)
const;
480 bool find_blockchain_supplement(
const uint64_t req_start_block,
const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >&
blocks,
uint64_t& total_height,
uint64_t& start_height,
bool pruned,
bool get_miner_tx_hash,
size_t max_count)
const;
705 template<
class t_
ids_container,
class t_blocks_container,
class t_missed_container>
706 bool get_blocks(
const t_ids_container& block_ids, t_blocks_container&
blocks, t_missed_container& missed_bs)
const;
721 template<
class t_
ids_container,
class t_tx_container,
class t_missed_container>
722 bool get_transactions_blobs(
const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs,
bool pruned =
false)
const;
723 template<
class t_
ids_container,
class t_tx_container,
class t_missed_container>
725 template<
class t_
ids_container,
class t_tx_container,
class t_missed_container>
726 bool get_transactions(
const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs)
const;
785 void set_block_notify(
const std::shared_ptr<tools::Notify> ¬ify) { m_block_notify = notify; }
792 void set_reorg_notify(
const std::shared_ptr<tools::Notify> ¬ify) { m_reorg_notify = notify; }
907 std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>>
get_output_histogram(
const std::vector<uint64_t> &amounts,
bool unlocked,
uint64_t recent_cutoff,
uint64_t min_count = 0)
const;
986 std::vector<output_data_t> &outputs)
const;
996 std::unordered_map<crypto::hash, crypto::hash> &map)
const;
1076 #ifndef IN_UNIT_TESTS 1081 typedef std::unordered_map<crypto::hash, size_t> blocks_by_id_index;
1083 typedef std::unordered_map<crypto::hash, transaction_chain_entry> transactions_container;
1085 typedef std::unordered_set<crypto::key_image> key_images_container;
1087 typedef std::vector<block_extended_info> blocks_container;
1089 typedef std::unordered_map<crypto::hash, block_extended_info> blocks_ext_by_hash;
1091 typedef std::unordered_map<crypto::hash, block> blocks_by_hash;
1093 typedef std::map<uint64_t, std::vector<std::pair<crypto::hash, size_t>>> outputs_container;
1103 transactions_container m_transactions;
1104 size_t m_current_block_cumul_weight_limit;
1105 size_t m_current_block_cumul_weight_median;
1108 std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, std::vector<output_data_t>>> m_scan_table;
1109 std::unordered_map<crypto::hash, crypto::hash> m_blocks_longhash_table;
1110 std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, bool>> m_check_txin_table;
1113 std::vector<crypto::hash> m_blocks_hash_check;
1114 std::vector<crypto::hash> m_blocks_txs_check;
1118 bool m_show_time_stats;
1119 bool m_db_default_sync;
1120 bool m_db_sync_on_blocks;
1122 uint64_t m_max_prepare_blocks_threads;
1127 std::vector<uint64_t> m_timestamps;
1128 std::vector<difficulty_type> m_difficulties;
1129 uint64_t m_timestamps_and_difficulties_height;
1130 uint64_t m_long_term_block_weights_window;
1131 uint64_t m_long_term_effective_median_block_weight;
1132 mutable crypto::hash m_long_term_block_weights_cache_tip_hash;
1140 std::vector<std::string> m_validators_public_keys;
1142 boost::asio::io_service m_async_service;
1143 boost::thread_group m_async_pool;
1144 std::unique_ptr<boost::asio::io_service::work> m_async_work_idle;
1147 blocks_ext_by_hash m_alternative_chains;
1150 blocks_ext_by_hash m_invalid_blocks;
1154 bool m_enforce_dns_checkpoints;
1163 bool m_fallback_to_pow;
1165 std::atomic<bool> m_cancel;
1178 bool m_batch_success;
1180 std::shared_ptr<tools::Notify> m_block_notify;
1181 std::shared_ptr<tools::Notify> m_reorg_notify;
1204 template<
class visitor_t>
1205 inline bool scan_outputkeys_for_indexes(
size_t tx_version,
const txin_to_key& tx_in_to_key, visitor_t &vis,
const crypto::hash &tx_prefix_hash,
uint64_t* pmax_related_block_height = NULL)
const;
1227 bool check_tx_input(
size_t tx_version,
const txin_to_key& txin,
const crypto::hash& tx_prefix_hash,
const std::vector<crypto::signature>& sig,
const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys,
uint64_t* pmax_related_block_height);
1263 bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::const_iterator>& alt_chain,
bool discard_disconnected_chain);
1270 block pop_block_from_blockchain();
1336 difficulty_type get_next_difficulty_for_alternative_chain(
const std::list<blocks_ext_by_hash::const_iterator>& alt_chain, block_extended_info& bei)
const;
1381 bool rollback_blockchain_switching(std::list<block>& original_chain,
uint64_t rollback_height);
1391 void get_last_n_blocks_weights(std::vector<uint64_t>& weights,
size_t count)
const;
1415 bool is_tx_spendtime_unlocked(
uint64_t unlock_time)
const;
1441 bool add_block_as_invalid(
const block_extended_info& bei,
const crypto::hash& h);
1459 bool check_block_timestamp(
const block& b,
uint64_t& median_ts)
const;
1460 bool check_block_timestamp(
const block& b)
const {
uint64_t median_ts;
return check_block_timestamp(b, median_ts); }
1473 bool check_block_timestamp(std::vector<uint64_t>& timestamps,
const block& b,
uint64_t& median_ts)
const;
1474 bool check_block_timestamp(std::vector<uint64_t>& timestamps,
const block& b)
const {
uint64_t median_ts;
return check_block_timestamp(timestamps, b, median_ts); }
1484 uint64_t get_adjusted_time()
const;
1497 bool complete_timestamps_vector(
uint64_t start_height, std::vector<uint64_t>& timestamps)
const;
1506 bool update_next_cumulative_weight_limit(
uint64_t *long_term_effective_median_block_weight = NULL);
1507 void return_tx_to_pool(std::vector<std::pair<transaction, blobdata>> &txs);
1517 bool check_for_double_spend(
const transaction& tx, key_images_container& keys_this_block)
const;
1529 const std::vector<rct::ctkey> &pubkeys,
const std::vector<crypto::signature> &sig,
uint64_t &result);
1549 bool expand_transaction_2(transaction &tx,
const crypto::hash &tx_prefix_hash,
const std::vector<std::vector<rct::ctkey>> &pubkeys);
1554 void invalidate_block_template_cache();
bool verify_block_signature(const block &b)
Verify block's digital signature.
difficulty_type cumulative_difficulty
the accumulated difficulty after that block
bool is_within_compiled_block_hash_area() const
bool get_blocks(uint64_t start_offset, size_t count, std::vector< std::pair< cryptonote::blobdata, block >> &blocks, std::vector< cryptonote::blobdata > &txs) const
get blocks and transactions from blocks based on start height and count
uint64_t get_current_cumulative_block_weight_limit() const
gets the block weight limit based on recent blocks
bool get_tx_outputs_gindexs(const crypto::hash &tx_id, std::vector< uint64_t > &indexs) const
gets the global indices for outputs from a given transaction
bool check_blockchain_pruning()
uint64_t height
the height of the block in the blockchain
bool get_split_transactions_blobs(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
void set_user_options(uint64_t maxthreads, bool sync_on_blocks, uint64_t sync_threshold, blockchain_db_sync_mode sync_mode, bool fast_sync, std::string validator_key)
Update the validators public key by fetching data from electroneum's endpoint.
void pop_blocks(uint64_t nblocks)
removes blocks from the top of the blockchain
handle syncing calls instead of the backing db, asynchronously
void get_output_key_mask_unlocked(const uint64_t &amount, const uint64_t &index, crypto::public_key &key, rct::key &mask, bool &unlocked) const
gets an output's key and unlocked state
uint8_t get_ideal_hard_fork_version(uint64_t height) const
returns the newest hardfork version voted to be enabled as of a certain height
uint8_t get_current_version() const
returns the current version
uint8_t get_next_version() const
returns the next version
bool get_txpool_tx_meta(const crypto::hash &txid, txpool_tx_meta_t &meta) const
void normalize_v7_difficulties()
Normalize the cumulative difficulty for V7 blocks, fixing the differing difficulty among nodes...
bool utxo_nonexistence_from_output(const txin_to_key_public &public_output) const
check if a single utxo in a transaction has already been spent using the hash and out index (v3 tx on...
bool prepare_handle_incoming_blocks(const std::vector< block_complete_entry > &blocks_entry, std::vector< block > &blocks)
performs some preprocessing on a group of incoming blocks to speed up verification ...
bool utxo_nonexistent(const transaction &tx) const
check if any utxo in a transaction has already been spent using the tx (v3 tx onwards) ...
bool find_blockchain_supplement(const std::list< crypto::hash > &qblock_ids, std::vector< crypto::hash > &hashes, uint64_t &start_height, uint64_t ¤t_height, bool clip_pruned) const
get recent block hashes for a foreign chain
bool get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request &req, COMMAND_RPC_GET_OUTPUTS_BIN::response &res) const
gets specific outputs to mix with
uint64_t m_keeper_block_height
user didn't specify, use db_async
bool for_all_transactions(std::function< bool(const crypto::hash &, const cryptonote::transaction &)>, bool pruned) const
perform a check on all transactions in the blockchain
bool store_blockchain()
stores the blockchain
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request &arg, NOTIFY_RESPONSE_GET_OBJECTS::request &rsp)
retrieves a set of blocks and their transactions, and possibly other transactions ...
void set_validators_list_instance(std::unique_ptr< electroneum::basic::Validators > &v)
handle syncing calls instead of the backing db, synchronously
std::function< const epee::span< const unsigned char >cryptonote::network_type network)> GetCheckpointsCallback
Callback routine that returns checkpoints data for specific network type.
bool for_all_txpool_txes(std::function< bool(const crypto::hash &, const txpool_tx_meta_t &, const cryptonote::blobdata *)>, bool include_blob=false, bool include_unrelayed_txes=true) const
void set_block_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a block notify object to call for every new block
void remove_txpool_tx(const crypto::hash &txid)
static const std::vector< HardFork::Params > & get_hard_fork_heights(network_type nettype)
gets the hardfork heights of given network
void set_enforce_dns_checkpoints(bool enforce)
configure whether or not to enforce DNS-based checkpoints
Non-owning sequence of data. Does not deep copy.
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
bool key_images_already_spent(const transaction &tx) const
check if any key image in a transaction has already been spent
void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta)
Now-defunct (TODO: remove) struct from in-memory blockchain.
static uint64_t get_dynamic_base_fee(uint64_t block_reward, size_t median_block_weight, uint8_t version)
get dynamic per kB or byte fee for a given block weight
struct hash_func hashes[]
bool add_new_block(const block &bl_, block_verification_context &bvc)
adds a block to the blockchain
void safesyncmode(const bool onoff)
Put DB in safe sync mode.
void set_checkpoints(checkpoints &&chk_pts)
assign a set of blockchain checkpoint hashes
uint64_t get_current_cumulative_block_weight_median() const
gets the block weight median based on recent blocks (same window as for the limit) ...
void set_reorg_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a reorg notify object to call for every reorg
bool get_short_chain_history(std::list< crypto::hash > &ids) const
gets the hashes for a subset of the blockchain
bool update_checkpoints(const std::string &file_path, bool check_dns)
loads new checkpoints from a file and optionally from DNS
std::list< std::pair< block_extended_info, std::vector< crypto::hash > > > get_alternative_chains() const
returns a set of known alternate chains
uint8_t get_current_hard_fork_version() const
gets the current hardfork version in use/voted for
Holds cryptonote related classes and helpers.
size_t get_total_transactions() const
gets the total number of transactions on the main chain
size_t block_cumulative_weight
the weight of the block
bool flush_txes_from_pool(const std::vector< crypto::hash > &txids)
remove transactions from the transaction pool (if present)
uint8_t get_next_hard_fork_version() const
returns the next hardfork version
mdb_size_t count(MDB_cursor *cur)
std::map< uint64_t, std::tuple< uint64_t, uint64_t, uint64_t > > get_output_histogram(const std::vector< uint64_t > &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count=0) const
return a histogram of outputs on the blockchain
bool for_all_key_images(std::function< bool(const crypto::key_image &)>) const
perform a check on all key images in the blockchain
bool for_all_outputs(std::function< bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)>) const
perform a check on all outputs in the blockchain
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
bool check_tx_inputs(transaction &tx, uint64_t &pmax_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block=false)
validates a transaction's inputs
uint64_t get_num_mature_outputs(uint64_t amount) const
get number of outputs of an amount past the minimum spendable age
uint64_t get_txpool_tx_count(bool include_unrelayed_txes=true) const
std::vector< uint64_t > m_global_output_indexes
uint8_t get(uint64_t height) const
returns the hard fork version for the given block height
void block_longhash_worker(uint64_t height, const epee::span< const block > &blocks, std::unordered_map< crypto::hash, crypto::hash > &map) const
computes the "short" and "long" hashes for a set of blocks
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector< uint64_t > &distribution, uint64_t &base) const
gets per block distribution of outputs of a given amount
crypto::public_key get_output_key(uint64_t amount, uint64_t global_index) const
get the public key for an output
void sign_block(block &b, std::string privateKey)
Digitally sign the block.
uint64_t already_generated_coins
the total coins minted after that block
HardFork::State get_hard_fork_state() const
gets the hardfork voting state object
static uint64_t get_fee_quantization_mask()
get fee quantization mask
void set_show_time_stats(bool stats)
set whether or not to show/print time statistics
bool prune_blockchain(uint32_t pruning_seed=0)
unsigned __int64 uint64_t
bool reset_and_set_genesis_block(const block &b)
clears the blockchain and starts a new one
difficulty_type get_difficulty_for_next_block()
returns the difficulty target the next block to be added must meet
void check_against_checkpoints(const checkpoints &points, bool enforce)
check the blockchain against a set of checkpoints
virtual uint64_t height() const =0
fetch the current blockchain height
Leave syncing up to the backing db (safest, but slowest because of disk I/O)
void on_new_tx_from_block(const cryptonote::transaction &tx)
called when we see a tx originating from a block
version
Supported socks variants.
bool update_blockchain_pruning()
const BlockchainDB & get_db() const
get a reference to the BlockchainDB in use by Blockchain
bool get_transactions(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
bool check_fee(size_t tx_weight, uint64_t fee) const
validate a transaction's fee
uint8_t get_ideal_version() const
returns the latest "ideal" version
bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const
check if a key image is already spent on the blockchain
Transaction pool, handles transactions which are not part of a block.
~Blockchain()
Blockchain destructor.
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
void output_scan_worker(const uint64_t amount, const std::vector< uint64_t > &offsets, std::vector< output_data_t > &outputs) const
get a number of outputs of a specific amount
uint32_t get_mempool_tx_livetime() const
uint32_t get_blockchain_pruning_seed() const
uint64_t get_dynamic_base_fee_estimate(uint64_t grace_blocks) const
get dynamic per kB or byte fee estimate for the next few blocks
bool get_transactions_blobs(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs, bool pruned=false) const
gets transactions based on a list of transaction hashes
The BlockchainDB backing store interface declaration/contract.
BlockchainDB & get_db()
get a reference to the BlockchainDB in use by Blockchain
bool have_tx(const crypto::hash &id) const
search the blockchain for a transaction by hash
boost::multiprecision::uint128_t difficulty_type
bool have_block(const crypto::hash &id) const
checks if a block is known about with a given hash
bool get_alternative_blocks(std::vector< block > &blocks) const
compiles a list of all blocks stored as alternative chains
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
Blockchain(tx_memory_pool &tx_pool)
Blockchain constructor.
uint8_t get_hard_fork_version(uint64_t height) const
returns the actual hardfork version for a given block height
uint64_t get_next_long_term_block_weight(uint64_t block_weight) const
gets the long term block weight for a new block
uint64_t get_difficulty_target() const
get difficulty target based on chain and hardfork version
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
difficulty_type block_difficulty(uint64_t i) const
gets the difficulty of the block with a given height
network_type get_nettype() const
get blockchain nettype
bool init(BlockchainDB *db, const network_type nettype=MAINNET, bool offline=false, const cryptonote::test_options *test_options=NULL, difficulty_type fixed_difficulty=0, const GetCheckpointsCallback &get_checkpoints=nullptr, bool ignore_bsig=false, bool fallback_to_pow=false)
Initialize the Blockchain state.
bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
get information about hardfork voting for a version
size_t get_alternative_blocks_count() const
returns the number of alternative blocks stored
A container for blockchain checkpoints.
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
bool check_tx_outputs(const transaction &tx, tx_verification_context &tvc)
check that a transaction's outputs conform to current standards
container for passing a block and metadata about it on the blockchain
electroneum::basic::Validator get_validator_by_height(uint64_t height)
virtual uint32_t get_blockchain_pruning_seed() const =0
get the blockchain pruning seed
void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta)
bool get_txpool_tx_blob(const crypto::hash &txid, cryptonote::blobdata &bd) const
bool deinit()
Uninitializes the blockchain state.
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
bool create_block_template(block &b, const account_public_address &miner_address, difficulty_type &di, uint64_t &height, uint64_t &expected_reward, const blobdata &ex_nonce)
creates a new block to mine against
void set_validator_key(std::string key)
set validator key
std::vector< time_t > get_last_block_timestamps(unsigned int blocks) const
returns the timestamps of the last N blocks
bool for_blocks_range(const uint64_t &h1, const uint64_t &h2, std::function< bool(uint64_t, const crypto::hash &, const block &)>) const
perform a check on all blocks in the blockchain in the given range
bool cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync