diff --git a/src/consensus.cpp b/src/consensus.cpp index 87818c5c..b260938a 100644 --- a/src/consensus.cpp +++ b/src/consensus.cpp @@ -278,7 +278,7 @@ namespace consensus // When requesting the next seq_no, serving peer will give all the hpfs logs upto it's latest. // So hash mismatch won't happen in the next round. if (!ledger::ledger_sync_worker.is_last_primary_shard_syncing) - sc::hpfs_log_sync::set_sync_target(lcl_id.seq_no + 1); + sc::hpfs_log_sync::set_sync_target(lcl_id.seq_no + 1, hpfs::get_root_hash(majority_patch_hash, majority_state_hash)); } else { diff --git a/src/sc/hpfs_log_sync.cpp b/src/sc/hpfs_log_sync.cpp index 3aced203..c3695685 100644 --- a/src/sc/hpfs_log_sync.cpp +++ b/src/sc/hpfs_log_sync.cpp @@ -47,7 +47,7 @@ namespace sc::hpfs_log_sync } } - void set_sync_target(const uint64_t target) + void set_sync_target(const uint64_t target, const util::h32 &target_root_hash) { { std::scoped_lock lock(sync_ctx.target_log_seq_no_mutex); @@ -55,9 +55,11 @@ namespace sc::hpfs_log_sync return; sync_ctx.target_log_seq_no = target; + sync_ctx.target_root_hash = target_root_hash; + const int res = get_verified_min_record(); // Finding the minimum seq_no to request hpfs logs. - if (get_verified_min_record() == -1) + if (res == -1 || res == 1) return; } @@ -97,27 +99,6 @@ namespace sc::hpfs_log_sync { LOG_INFO << "Hpfs log sync: sync target archived: " << sync_ctx.target_log_seq_no; sync_ctx.clear_target(); - - // After archiving the target, update latest state and patch hash in the in memory map. - util::h32 state_hash, patch_hash; - const std::string session_name = "ro_hpfs_log_sync"; - - if (sc::contract_fs.start_ro_session(session_name, true) != -1) - { - if (sc::contract_fs.get_hash(state_hash, session_name, sc::STATE_DIR_PATH) != -1) - sc::contract_fs.set_parent_hash(sc::STATE_DIR_PATH, state_hash); - else - LOG_ERROR << "Hpfs log sync: error getting the updated state hash"; - - if (sc::contract_fs.get_hash(patch_hash, session_name, sc::PATCH_FILE_PATH) != -1) - sc::contract_fs.set_parent_hash(sc::STATE_DIR_PATH, state_hash); - else - LOG_ERROR << "Hpfs log sync: error getting the updated patch hash"; - - sc::contract_fs.stop_ro_session(session_name); - } - else - LOG_ERROR << "Hpfs log sync: error starting the hpfs ro session"; } } @@ -310,9 +291,53 @@ namespace sc::hpfs_log_sync return -1; } - // In sync. No need to sync. if (last_from_index == last_from_ledger) - return 1; + { + // If the last hashes of the ledger and the index are equal, check whether target root hash is equal to the updated root hash in the fs. + const std::string session_name = "ro_hpfs_log_sync"; + + util::h32 state_hash, patch_hash; + if (sc::contract_fs.start_ro_session(session_name, true) == -1) + { + LOG_ERROR << "Hpfs log sync: error starting the hpfs ro session"; + return -1; + } + + if (sc::contract_fs.get_hash(state_hash, session_name, sc::STATE_DIR_PATH) == -1) + { + LOG_ERROR << "Hpfs log sync: error getting the updated state hash"; + sc::contract_fs.stop_ro_session(session_name); + return -1; + } + + if (sc::contract_fs.get_hash(patch_hash, session_name, sc::PATCH_FILE_PATH) == -1) + { + LOG_ERROR << "Hpfs log sync: error getting the updated patch hash"; + sc::contract_fs.stop_ro_session(session_name); + return -1; + } + sc::contract_fs.stop_ro_session(session_name); + + // If target is equal to the root hash, return 1 so the node in sync, otherwise request hpfs logs from the last ledger seq number. + if (hpfs::get_root_hash(patch_hash, state_hash) == sync_ctx.target_root_hash) + { + // After archiving the target, update the in-memory hash tree. + sc::contract_fs.set_parent_hash(sc::STATE_DIR_PATH, state_hash); + sc::contract_fs.set_parent_hash(sc::STATE_DIR_PATH, state_hash); + return 1; + } + else + { + // Truncate from the last ledger seq_no. There might be some additional log records after the last index update. + if (sc::contract_fs.truncate_log_file(last_from_ledger.seq_no) == -1) + { + LOG_ERROR << "Error truncating hpfs log file and index file from : " << last_from_ledger.seq_no; + return -1; + } + sync_ctx.min_log_record = last_from_ledger; + return 0; + } + } if (last_from_index.seq_no == last_from_ledger.seq_no) { diff --git a/src/sc/hpfs_log_sync.hpp b/src/sc/hpfs_log_sync.hpp index 4940c0f3..20e97e0b 100644 --- a/src/sc/hpfs_log_sync.hpp +++ b/src/sc/hpfs_log_sync.hpp @@ -14,6 +14,7 @@ namespace sc::hpfs_log_sync { // The current target log record seq no that we are syncing towards. uint64_t target_log_seq_no; + util::h32 target_root_hash; std::mutex target_log_seq_no_mutex; p2p::sequence_hash min_log_record; uint64_t target_requested_on = 0; @@ -26,6 +27,7 @@ namespace sc::hpfs_log_sync void clear_target() { target_log_seq_no = 0; + target_root_hash = util::h32_empty, min_log_record = {}; target_requested_on = 0; request_submissions = 0; @@ -38,7 +40,7 @@ namespace sc::hpfs_log_sync void deinit(); - void set_sync_target(const uint64_t target); + void set_sync_target(const uint64_t target, const util::h32 &target_root_hash); void hpfs_log_syncer_loop(); diff --git a/test/bin/hpfs b/test/bin/hpfs index 51552434..64287be6 100755 Binary files a/test/bin/hpfs and b/test/bin/hpfs differ