#ifndef _HP_LEDGER_ #define _HP_LEDGER_ #include "pchheader.hpp" #include "p2p/p2p.hpp" namespace ledger { constexpr const char *GENESIS_LEDGER = "0-genesis"; constexpr uint16_t HISTORY_REQ_LIST_CAP = 64; // Maximum history request count. constexpr uint16_t HISTORY_RES_LIST_CAP = 64; // Maximum history response count. struct sync_context { // The current target lcl that we are syncing towards. std::string target_lcl; uint64_t target_lcl_seq_no; std::mutex target_lcl_mutex; // Lists holding history requests and responses collected from incoming p2p messages. std::list> collected_history_requests; std::list collected_history_responses; std::mutex list_mutex; std::thread lcl_sync_thread; std::atomic is_syncing = false; std::atomic is_shutting_down = false; }; struct ledger_context { private: std::string lcl; uint64_t seq_no = 0; std::shared_mutex lcl_mutex; public: // Map of closed ledgers (lcl string) with sequence number as map key. // Contains closed ledgers from oldest to latest - MAX_LEDGER_SEQUENCE. // This is loaded when node started and updated throughout consensus. // Deletes ledgers that falls behind MAX_LEDGER_SEQUENCE range. std::map cache; std::mutex ledger_mutex; const std::string get_lcl() { std::shared_lock lock(lcl_mutex); return lcl; } uint64_t get_seq_no() { std::shared_lock lock(lcl_mutex); return seq_no; } void set_lcl(const uint64_t new_seq_no, std::string_view new_lcl) { std::unique_lock lock(lcl_mutex); lcl = new_lcl; seq_no = new_seq_no; } }; extern sync_context sync_ctx; extern ledger_context ctx; int init(); void deinit(); void lcl_syncer_loop(); void set_sync_target(const std::string &target_lcl); const std::pair get_ledger_cache_top(); int save_ledger(const p2p::proposal &proposal, const std::unordered_map raw_inputs); void remove_old_ledgers(const uint64_t led_seq_no); void clear_ledger(); int read_ledger(std::string_view file_path, std::vector &buffer); int write_ledger(const std::string &file_name, const uint8_t *ledger_raw, const size_t ledger_size); int write_full_history(const std::string &file_name, const uint8_t *full_history_raw, const size_t full_history_size); void remove_ledger(const std::string &file_name); void send_ledger_history_request(std::string_view current_lcl, std::string_view required_lcl); bool check_required_lcl_availability(const std::string &required_lcl); int retrieve_ledger_history(const p2p::history_request &hr, p2p::history_response &history_response); int handle_ledger_history_response(const p2p::history_response &hr, std::string &new_lcl); bool check_block_integrity(std::string_view hash, const std::vector &block_buffer); int sort_lcl_filenames_and_validate(std::list &list); int extract_lcl(const std::string &lcl, uint64_t &seq_no, std::string &hash); } // namespace ledger #endif