mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	- added new fift/func code for validator complaint creation - bugfixes in validator - updates in tonlib - new versions of rocksdb/abseil - hardfork support
		
			
				
	
	
		
			542 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			542 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
    This file is part of TON Blockchain Library.
 | 
						|
 | 
						|
    TON Blockchain Library is free software: you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU Lesser General Public License as published by
 | 
						|
    the Free Software Foundation, either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    TON Blockchain Library is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU Lesser General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU Lesser General Public License
 | 
						|
    along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
    Copyright 2017-2020 Telegram Systems LLP
 | 
						|
*/
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "interfaces/block-handle.h"
 | 
						|
#include "ton/ton-shard.h"
 | 
						|
#include "td/actor/actor.h"
 | 
						|
#include "interfaces/validator-manager.h"
 | 
						|
#include "ton/ton-io.hpp"
 | 
						|
 | 
						|
#include "td/utils/ThreadSafeCounter.h"
 | 
						|
 | 
						|
namespace ton {
 | 
						|
 | 
						|
namespace validator {
 | 
						|
 | 
						|
class ValidatorManager;
 | 
						|
 | 
						|
struct BlockHandleImpl : public BlockHandleInterface {
 | 
						|
 private:
 | 
						|
  enum Flags : td::uint32 {
 | 
						|
    dbf_masterchain = 0x1,
 | 
						|
    dbf_inited_prev_left = 0x2,
 | 
						|
    dbf_inited_prev_right = 0x4,
 | 
						|
    dbf_inited_next_left = 0x8,
 | 
						|
    dbf_inited_next_right = 0x10,
 | 
						|
    dbf_inited_split_after = 0x20,
 | 
						|
    dbf_split_after = 0x40,
 | 
						|
    dbf_inited_merge_before = 0x80,
 | 
						|
    dbf_merge_before = 0x100,
 | 
						|
    dbf_received = 0x200,
 | 
						|
    dbf_is_key_block = 0x400,
 | 
						|
    dbf_inited_proof = 0x800,
 | 
						|
    dbf_inited_proof_link = 0x1000,
 | 
						|
    dbf_inited_lt = 0x2000,
 | 
						|
    dbf_inited_ts = 0x4000,
 | 
						|
    dbf_inited_is_key_block = 0x8000,
 | 
						|
    dbf_inited_state = 0x20000,
 | 
						|
    dbf_inited_signatures = 0x40000,
 | 
						|
    dbf_inited_state_boc = 0x100000,
 | 
						|
    dbf_archived = 0x200000,
 | 
						|
    dbf_applied = 0x400000,
 | 
						|
    dbf_inited_masterchain_ref_block = 0x800000,
 | 
						|
    dbf_deleted = 0x2000000,
 | 
						|
    dbf_deleted_boc = 0x4000000,
 | 
						|
    dbf_moved_new = 0x8000000,
 | 
						|
    dbf_processed = 0x10000000,
 | 
						|
    dbf_moved_handle = 0x20000000,
 | 
						|
  };
 | 
						|
 | 
						|
  std::atomic<td::uint64> version_{0};
 | 
						|
  std::atomic<td::uint32> written_version_{0};
 | 
						|
  BlockIdExt id_;
 | 
						|
  std::atomic<td::uint32> flags_{0};
 | 
						|
  std::array<BlockIdExt, 2> prev_;
 | 
						|
  std::array<BlockIdExt, 2> next_;
 | 
						|
  LogicalTime lt_;
 | 
						|
  UnixTime ts_;
 | 
						|
  RootHash state_;
 | 
						|
  BlockSeqno masterchain_ref_seqno_;
 | 
						|
 | 
						|
  static constexpr td::uint64 lock_const() {
 | 
						|
    return static_cast<td::uint64>(1) << 32;
 | 
						|
  }
 | 
						|
  bool locked() const {
 | 
						|
    return version_.load(std::memory_order_consume) >> 32;
 | 
						|
  }
 | 
						|
  void lock() {
 | 
						|
    version_ += 1 + lock_const();
 | 
						|
  }
 | 
						|
  void unlock() {
 | 
						|
    version_ -= lock_const();
 | 
						|
  }
 | 
						|
 | 
						|
 public:
 | 
						|
  BlockIdExt id() const override {
 | 
						|
    return id_;
 | 
						|
  }
 | 
						|
  bool received() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_received;
 | 
						|
  }
 | 
						|
  bool moved_to_archive() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_moved_new;
 | 
						|
  }
 | 
						|
  bool handle_moved_to_archive() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_moved_handle;
 | 
						|
  }
 | 
						|
  bool deleted() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_deleted;
 | 
						|
  }
 | 
						|
  bool inited_next_left() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_next_left;
 | 
						|
  }
 | 
						|
  bool inited_next_right() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_next_right;
 | 
						|
  }
 | 
						|
  bool inited_next() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (!(f & Flags::dbf_inited_next_left)) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if (f & Flags::dbf_inited_next_right) {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    if ((f & Flags::dbf_inited_split_after) && !(f & Flags::dbf_split_after)) {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  bool inited_prev_left() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_prev_left;
 | 
						|
  }
 | 
						|
  bool inited_prev_right() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_prev_right;
 | 
						|
  }
 | 
						|
  bool inited_prev() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (!(f & Flags::dbf_inited_prev_left)) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if (f & Flags::dbf_inited_prev_right) {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    if ((f & Flags::dbf_inited_merge_before) && !(f & Flags::dbf_merge_before)) {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  bool inited_proof() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_proof;
 | 
						|
  }
 | 
						|
  bool inited_proof_link() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_proof_link;
 | 
						|
  }
 | 
						|
  bool inited_signatures() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_signatures;
 | 
						|
  }
 | 
						|
  bool inited_split_after() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_split_after;
 | 
						|
  }
 | 
						|
  bool inited_merge_before() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_merge_before;
 | 
						|
  }
 | 
						|
  bool inited_is_key_block() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    return f & Flags::dbf_inited_is_key_block;
 | 
						|
  }
 | 
						|
  bool split_after() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    CHECK(f & Flags::dbf_inited_split_after);
 | 
						|
    return f & Flags::dbf_split_after;
 | 
						|
  }
 | 
						|
  bool merge_before() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    CHECK(f & Flags::dbf_inited_merge_before);
 | 
						|
    return f & Flags::dbf_merge_before;
 | 
						|
  }
 | 
						|
  bool is_key_block() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    CHECK(f & Flags::dbf_inited_is_key_block);
 | 
						|
    return f & Flags::dbf_is_key_block;
 | 
						|
  }
 | 
						|
 | 
						|
  bool inited_state_root_hash() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_state;
 | 
						|
  }
 | 
						|
  bool inited_state_boc() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_state_boc;
 | 
						|
  }
 | 
						|
  bool deleted_state_boc() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_deleted_boc;
 | 
						|
  }
 | 
						|
  bool received_state() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_state_boc;
 | 
						|
  }
 | 
						|
  bool need_flush() const override {
 | 
						|
    return written_version_.load(std::memory_order_consume) < version();
 | 
						|
  }
 | 
						|
  bool is_zero() const override {
 | 
						|
    return id_.id.seqno == 0;
 | 
						|
  }
 | 
						|
  bool is_archived() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_archived;
 | 
						|
  }
 | 
						|
  bool is_applied() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_applied;
 | 
						|
  }
 | 
						|
  bool inited_masterchain_ref_block() const override {
 | 
						|
    return id_.is_masterchain() || (flags_.load(std::memory_order_consume) & Flags::dbf_inited_masterchain_ref_block);
 | 
						|
  }
 | 
						|
  BlockSeqno masterchain_ref_block() const override {
 | 
						|
    CHECK(inited_masterchain_ref_block());
 | 
						|
    return id_.is_masterchain() ? id_.seqno() : masterchain_ref_seqno_;
 | 
						|
  }
 | 
						|
  std::vector<BlockIdExt> prev() const override {
 | 
						|
    if (is_zero()) {
 | 
						|
      return {};
 | 
						|
    }
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    CHECK(f & Flags::dbf_inited_merge_before);
 | 
						|
    if (!(f & Flags::dbf_merge_before)) {
 | 
						|
      CHECK(f & Flags::dbf_inited_prev_left);
 | 
						|
      return {prev_[0]};
 | 
						|
    } else {
 | 
						|
      CHECK(f & Flags::dbf_inited_prev_left);
 | 
						|
      CHECK(f & Flags::dbf_inited_prev_right);
 | 
						|
      return {prev_[0], prev_[1]};
 | 
						|
    }
 | 
						|
  }
 | 
						|
  BlockIdExt one_prev(bool left) const override {
 | 
						|
    CHECK(!is_zero());
 | 
						|
    if (left) {
 | 
						|
      CHECK(flags_.load(std::memory_order_consume) & Flags::dbf_inited_prev_left);
 | 
						|
    } else {
 | 
						|
      CHECK(flags_.load(std::memory_order_consume) & Flags::dbf_inited_prev_right);
 | 
						|
    }
 | 
						|
    return prev_[left ? 0 : 1];
 | 
						|
  }
 | 
						|
  std::vector<BlockIdExt> next() const override {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    CHECK(f & Flags::dbf_inited_split_after);
 | 
						|
    if (!(f & Flags::dbf_split_after)) {
 | 
						|
      CHECK(f & Flags::dbf_inited_next_left);
 | 
						|
      return {next_[0]};
 | 
						|
    } else {
 | 
						|
      CHECK(f & Flags::dbf_inited_next_left);
 | 
						|
      CHECK(f & Flags::dbf_inited_next_right);
 | 
						|
      return {next_[0], next_[1]};
 | 
						|
    }
 | 
						|
  }
 | 
						|
  BlockIdExt one_next(bool left) const override {
 | 
						|
    if (left) {
 | 
						|
      CHECK(flags_.load(std::memory_order_consume) & Flags::dbf_inited_next_left);
 | 
						|
    } else {
 | 
						|
      CHECK(flags_.load(std::memory_order_consume) & Flags::dbf_inited_next_right);
 | 
						|
    }
 | 
						|
    return next_[left ? 0 : 1];
 | 
						|
  }
 | 
						|
  RootHash state() const override {
 | 
						|
    CHECK(flags_.load(std::memory_order_consume) & Flags::dbf_inited_state);
 | 
						|
    return state_;
 | 
						|
  }
 | 
						|
 | 
						|
  bool processed() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_processed;
 | 
						|
  }
 | 
						|
  void set_processed() override {
 | 
						|
    // does not increase version
 | 
						|
    flags_ |= Flags::dbf_processed;
 | 
						|
  }
 | 
						|
 | 
						|
  td::uint32 version() const override {
 | 
						|
    return static_cast<td::uint32>(version_.load(std::memory_order_consume));
 | 
						|
  }
 | 
						|
  void flush(td::actor::ActorId<ValidatorManagerInterface> manager, BlockHandle self,
 | 
						|
             td::Promise<td::Unit> promise) override;
 | 
						|
  void flushed_upto(td::uint32 version) override {
 | 
						|
    if (version > written_version_.load(std::memory_order_consume)) {
 | 
						|
      written_version_.store(version, std::memory_order_release);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  bool inited_logical_time() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_lt;
 | 
						|
  }
 | 
						|
  LogicalTime logical_time() const override {
 | 
						|
    CHECK(inited_logical_time());
 | 
						|
    return lt_;
 | 
						|
  }
 | 
						|
  void set_logical_time(LogicalTime lt) override {
 | 
						|
    if (inited_logical_time()) {
 | 
						|
      CHECK(lt_ == lt);
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      lt_ = lt;
 | 
						|
      flags_ |= Flags::dbf_inited_lt;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  bool inited_unix_time() const override {
 | 
						|
    return flags_.load(std::memory_order_consume) & Flags::dbf_inited_ts;
 | 
						|
  }
 | 
						|
  UnixTime unix_time() const override {
 | 
						|
    CHECK(inited_unix_time());
 | 
						|
    return ts_;
 | 
						|
  }
 | 
						|
  void set_unix_time(UnixTime ts) override {
 | 
						|
    if (inited_unix_time()) {
 | 
						|
      CHECK(ts_ == ts);
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      ts_ = ts;
 | 
						|
      flags_ |= Flags::dbf_inited_ts;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_proof() override {
 | 
						|
    if (!inited_proof()) {
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_inited_proof;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_proof_link() override {
 | 
						|
    if (!inited_proof_link()) {
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_inited_proof_link;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_signatures() override {
 | 
						|
    if (!inited_signatures()) {
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_inited_signatures;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_next_left(BlockIdExt next) {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_next_left) {
 | 
						|
      LOG_CHECK(next_[0] == next) << "id=" << id_ << " next=" << next_[0] << " to_be_next=" << next;
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      next_[0] = next;
 | 
						|
      flags_ |= Flags::dbf_inited_next_left;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_next_right(BlockIdExt next) {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_next_right) {
 | 
						|
      LOG_CHECK(next_[1] == next) << "id=" << id_ << " next=" << next_[1] << " to_be_next=" << next;
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      next_[1] = next;
 | 
						|
      flags_ |= Flags::dbf_inited_next_right;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_next(BlockIdExt next) override {
 | 
						|
    bool right = shard_child(id_.id.shard, false) == next.id.shard;
 | 
						|
    if (right) {
 | 
						|
      set_next_right(next);
 | 
						|
    } else {
 | 
						|
      set_next_left(next);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_prev_left(BlockIdExt prev) {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_prev_left) {
 | 
						|
      LOG_CHECK(prev_[0] == prev) << "id=" << id_ << " prev=" << prev_[0] << " to_be_prev=" << prev;
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      prev_[0] = prev;
 | 
						|
      flags_ |= Flags::dbf_inited_prev_left;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_prev_right(BlockIdExt prev) {
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_prev_right) {
 | 
						|
      LOG_CHECK(prev_[1] == prev) << "id=" << id_ << " prev=" << prev_[1] << " to_be_prev=" << prev;
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      prev_[1] = prev;
 | 
						|
      flags_ |= Flags::dbf_inited_prev_right;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_prev(BlockIdExt prev) override {
 | 
						|
    bool right = shard_child(id_.id.shard, false) == prev.id.shard;
 | 
						|
    if (right) {
 | 
						|
      set_prev_right(prev);
 | 
						|
    } else {
 | 
						|
      set_prev_left(prev);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_received() override {
 | 
						|
    if (flags_.load(std::memory_order_consume) & Flags::dbf_received) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    lock();
 | 
						|
    flags_ |= Flags::dbf_received;
 | 
						|
    unlock();
 | 
						|
  }
 | 
						|
  void set_moved_to_archive() override {
 | 
						|
    if (flags_.load(std::memory_order_consume) & Flags::dbf_moved_new) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    lock();
 | 
						|
    flags_ |= Flags::dbf_moved_new;
 | 
						|
    unlock();
 | 
						|
  }
 | 
						|
  void set_handle_moved_to_archive() override {
 | 
						|
    flags_ |= Flags::dbf_moved_handle;
 | 
						|
  }
 | 
						|
  void set_deleted() override {
 | 
						|
    if (flags_.load(std::memory_order_consume) & Flags::dbf_deleted) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    lock();
 | 
						|
    flags_ |= Flags::dbf_deleted;
 | 
						|
    unlock();
 | 
						|
  }
 | 
						|
  void set_split(bool value) override {
 | 
						|
    td::uint32 v = value ? static_cast<td::uint32>(Flags::dbf_split_after) : 0;
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_split_after) {
 | 
						|
      CHECK((f & Flags::dbf_split_after) == v);
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      flags_ |= v | Flags::dbf_inited_split_after;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_merge(bool value) override {
 | 
						|
    td::uint32 v = value ? static_cast<td::uint32>(Flags::dbf_merge_before) : 0;
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_merge_before) {
 | 
						|
      CHECK((f & Flags::dbf_merge_before) == v);
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      flags_ |= v | Flags::dbf_inited_merge_before;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_is_key_block(bool value) override {
 | 
						|
    td::uint32 v = value ? static_cast<td::uint32>(Flags::dbf_is_key_block) : 0;
 | 
						|
    auto f = flags_.load(std::memory_order_consume);
 | 
						|
    if (f & Flags::dbf_inited_is_key_block) {
 | 
						|
      CHECK((f & Flags::dbf_is_key_block) == v);
 | 
						|
    } else {
 | 
						|
      lock();
 | 
						|
      flags_ |= v | Flags::dbf_inited_is_key_block;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_state_root_hash(RootHash hash) override {
 | 
						|
    if (!(flags_.load(std::memory_order_consume) & Flags::dbf_inited_state)) {
 | 
						|
      lock();
 | 
						|
      state_ = hash;
 | 
						|
      flags_ |= Flags::dbf_inited_state;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_state_boc() override {
 | 
						|
    if (!inited_state_boc()) {
 | 
						|
      CHECK(inited_state_root_hash());
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_inited_state_boc;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_deleted_state_boc() override {
 | 
						|
    if (flags_.load(std::memory_order_consume) & Flags::dbf_deleted_boc) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    lock();
 | 
						|
    flags_ |= Flags::dbf_deleted_boc;
 | 
						|
    unlock();
 | 
						|
  }
 | 
						|
  void set_archived() override {
 | 
						|
    if (!is_archived()) {
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_archived;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_applied() override {
 | 
						|
    if (!is_applied()) {
 | 
						|
      lock();
 | 
						|
      flags_ |= Flags::dbf_applied;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void set_masterchain_ref_block(BlockSeqno seqno) override {
 | 
						|
    if (!inited_masterchain_ref_block()) {
 | 
						|
      lock();
 | 
						|
      masterchain_ref_seqno_ = seqno;
 | 
						|
      flags_ |= Flags::dbf_inited_masterchain_ref_block;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void unsafe_clear_applied() override {
 | 
						|
    if (is_applied()) {
 | 
						|
      lock();
 | 
						|
      flags_ &= ~Flags::dbf_applied;
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void unsafe_clear_next() override {
 | 
						|
    if (inited_next_left() || inited_next_right()) {
 | 
						|
      lock();
 | 
						|
      flags_ &= ~(Flags::dbf_inited_next_left | Flags::dbf_inited_next_right);
 | 
						|
      unlock();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  td::BufferSlice serialize() const override;
 | 
						|
  BlockHandleImpl(BlockIdExt id)
 | 
						|
      : id_(id), flags_(id_.is_masterchain() ? static_cast<td::uint32>(dbf_masterchain) : 0) {
 | 
						|
    get_thread_safe_counter().add(1);
 | 
						|
  }
 | 
						|
  BlockHandleImpl(td::Slice data);
 | 
						|
  ~BlockHandleImpl() {
 | 
						|
    LOG_CHECK(!need_flush()) << "flags=" << flags_;
 | 
						|
    get_thread_safe_counter().add(-1);
 | 
						|
  }
 | 
						|
 | 
						|
  static td::NamedThreadSafeCounter::CounterRef get_thread_safe_counter() {
 | 
						|
    static auto res = td::NamedThreadSafeCounter::get_default().get_counter("BlockHandleImpl");
 | 
						|
    return res;
 | 
						|
  }
 | 
						|
 | 
						|
  static BlockHandle create_empty(BlockIdExt id) {
 | 
						|
    return std::make_shared<BlockHandleImpl>(id);
 | 
						|
  }
 | 
						|
 | 
						|
  static BlockHandle create(td::Slice data) {
 | 
						|
    return std::make_shared<BlockHandleImpl>(std::move(data));
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace validator
 | 
						|
 | 
						|
}  // namespace ton
 |