mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Move some constants to global config (#484)
This commit is contained in:
		
							parent
							
								
									580884033b
								
							
						
					
					
						commit
						1d42c38122
					
				
					 24 changed files with 218 additions and 88 deletions
				
			
		| 
						 | 
					@ -611,15 +611,29 @@ wfmt_ext#0 min_addr_len:(## 12) max_addr_len:(## 12) addr_len_step:(## 12)
 | 
				
			||||||
  workchain_type_id:(## 32) { workchain_type_id >= 1 }
 | 
					  workchain_type_id:(## 32) { workchain_type_id >= 1 }
 | 
				
			||||||
  = WorkchainFormat 0;
 | 
					  = WorkchainFormat 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
workchain#a6 enabled_since:uint32 actual_min_split:(## 8) 
 | 
					wc_split_merge_timings#0
 | 
				
			||||||
  min_split:(## 8) max_split:(## 8) { actual_min_split <= min_split }
 | 
					  split_merge_delay:uint32 split_merge_interval:uint32
 | 
				
			||||||
 | 
					  min_split_merge_interval:uint32 max_split_merge_delay:uint32
 | 
				
			||||||
 | 
					  = WcSplitMergeTimings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//workchain#a5 enabled_since:uint32 min_split:(## 8) max_split:(## 8)
 | 
					//workchain#a5 enabled_since:uint32 min_split:(## 8) max_split:(## 8)
 | 
				
			||||||
//  { min_split <= max_split } { max_split <= 60 }
 | 
					//  { min_split <= max_split } { max_split <= 60 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					workchain#a6 enabled_since:uint32 actual_min_split:(## 8) 
 | 
				
			||||||
 | 
					  min_split:(## 8) max_split:(## 8) { actual_min_split <= min_split }
 | 
				
			||||||
  basic:(## 1) active:Bool accept_msgs:Bool flags:(## 13) { flags = 0 }
 | 
					  basic:(## 1) active:Bool accept_msgs:Bool flags:(## 13) { flags = 0 }
 | 
				
			||||||
  zerostate_root_hash:bits256 zerostate_file_hash:bits256
 | 
					  zerostate_root_hash:bits256 zerostate_file_hash:bits256
 | 
				
			||||||
  version:uint32 format:(WorkchainFormat basic)
 | 
					  version:uint32 format:(WorkchainFormat basic)
 | 
				
			||||||
  = WorkchainDescr;
 | 
					  = WorkchainDescr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					workchain_v2#a7 enabled_since:uint32 actual_min_split:(## 8)
 | 
				
			||||||
 | 
					  min_split:(## 8) max_split:(## 8) { actual_min_split <= min_split }
 | 
				
			||||||
 | 
					  basic:(## 1) active:Bool accept_msgs:Bool flags:(## 13) { flags = 0 }
 | 
				
			||||||
 | 
					  zerostate_root_hash:bits256 zerostate_file_hash:bits256
 | 
				
			||||||
 | 
					  version:uint32 format:(WorkchainFormat basic)
 | 
				
			||||||
 | 
					  split_merge_timings:WcSplitMergeTimings
 | 
				
			||||||
 | 
					  = WorkchainDescr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_ workchains:(HashmapE 32 WorkchainDescr) = ConfigParam 12;
 | 
					_ workchains:(HashmapE 32 WorkchainDescr) = ConfigParam 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
complaint_prices#1a deposit:Grams bit_price:Grams cell_price:Grams = ComplaintPricing; 
 | 
					complaint_prices#1a deposit:Grams bit_price:Grams cell_price:Grams = ComplaintPricing; 
 | 
				
			||||||
| 
						 | 
					@ -734,6 +748,10 @@ misbehaviour_punishment_config_v1#01
 | 
				
			||||||
   = MisbehaviourPunishmentConfig;
 | 
					   = MisbehaviourPunishmentConfig;
 | 
				
			||||||
_ MisbehaviourPunishmentConfig = ConfigParam 40;
 | 
					_ MisbehaviourPunishmentConfig = ConfigParam 40;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_limits_config#01 max_msg_bits:uint32 max_msg_cells:uint32 max_library_cells:uint32 max_vm_data_depth:uint16
 | 
				
			||||||
 | 
					  max_ext_msg_size:uint32 max_ext_msg_depth:uint16 = SizeLimitsConfig;
 | 
				
			||||||
 | 
					_ SizeLimitsConfig = ConfigParam 43;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oracle_bridge_params#_ bridge_address:bits256 oracle_mutlisig_address:bits256 oracles:(HashmapE 256 uint256) external_chain_address:bits256 = OracleBridgeParams;
 | 
					oracle_bridge_params#_ bridge_address:bits256 oracle_mutlisig_address:bits256 oracles:(HashmapE 256 uint256) external_chain_address:bits256 = OracleBridgeParams;
 | 
				
			||||||
_ OracleBridgeParams = ConfigParam 71; // Ethereum bridge
 | 
					_ OracleBridgeParams = ConfigParam 71; // Ethereum bridge
 | 
				
			||||||
_ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge
 | 
					_ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1913,6 +1913,25 @@ std::vector<ton::ValidatorDescr> Config::compute_total_validator_set(int next) c
 | 
				
			||||||
  return res.move_as_ok()->export_validator_set();
 | 
					  return res.move_as_ok()->export_validator_set();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<SizeLimitsConfig> Config::get_size_limits_config() const {
 | 
				
			||||||
 | 
					  SizeLimitsConfig limits;
 | 
				
			||||||
 | 
					  td::Ref<vm::Cell> param = get_config_param(43);
 | 
				
			||||||
 | 
					  if (param.is_null()) {
 | 
				
			||||||
 | 
					    return limits;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  gen::SizeLimitsConfig::Record rec;
 | 
				
			||||||
 | 
					  if (!tlb::unpack_cell(param, rec)) {
 | 
				
			||||||
 | 
					    return td::Status::Error("configuration parameter 43 is invalid");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  limits.max_msg_bits = rec.max_msg_bits;
 | 
				
			||||||
 | 
					  limits.max_msg_cells = rec.max_msg_cells;
 | 
				
			||||||
 | 
					  limits.max_library_cells = rec.max_library_cells;
 | 
				
			||||||
 | 
					  limits.max_vm_data_depth = static_cast<td::uint16>(rec.max_vm_data_depth);
 | 
				
			||||||
 | 
					  limits.ext_msg_limits.max_size = rec.max_ext_msg_size;
 | 
				
			||||||
 | 
					  limits.ext_msg_limits.max_depth = static_cast<td::uint16>(rec.max_ext_msg_depth);
 | 
				
			||||||
 | 
					  return limits;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Result<std::pair<ton::UnixTime, ton::UnixTime>> Config::unpack_validator_set_start_stop(Ref<vm::Cell> vset_root) {
 | 
					td::Result<std::pair<ton::UnixTime, ton::UnixTime>> Config::unpack_validator_set_start_stop(Ref<vm::Cell> vset_root) {
 | 
				
			||||||
  if (vset_root.is_null()) {
 | 
					  if (vset_root.is_null()) {
 | 
				
			||||||
    return td::Status::Error("validator set absent");
 | 
					    return td::Status::Error("validator set absent");
 | 
				
			||||||
| 
						 | 
					@ -1942,31 +1961,58 @@ bool WorkchainInfo::unpack(ton::WorkchainId wc, vm::CellSlice& cs) {
 | 
				
			||||||
  if (wc == ton::workchainInvalid) {
 | 
					  if (wc == ton::workchainInvalid) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  block::gen::WorkchainDescr::Record info;
 | 
					  auto unpack_v1 = [this](auto& info) {
 | 
				
			||||||
  if (!tlb::unpack(cs, info)) {
 | 
					    enabled_since = info.enabled_since;
 | 
				
			||||||
    return false;
 | 
					    actual_min_split = info.actual_min_split;
 | 
				
			||||||
  }
 | 
					    min_split = info.min_split;
 | 
				
			||||||
  enabled_since = info.enabled_since;
 | 
					    max_split = info.max_split;
 | 
				
			||||||
  actual_min_split = info.actual_min_split;
 | 
					    basic = info.basic;
 | 
				
			||||||
  min_split = info.min_split;
 | 
					    active = info.active;
 | 
				
			||||||
  max_split = info.max_split;
 | 
					    accept_msgs = info.accept_msgs;
 | 
				
			||||||
  basic = info.basic;
 | 
					    flags = info.flags;
 | 
				
			||||||
  active = info.active;
 | 
					    zerostate_root_hash = info.zerostate_root_hash;
 | 
				
			||||||
  accept_msgs = info.accept_msgs;
 | 
					    zerostate_file_hash = info.zerostate_file_hash;
 | 
				
			||||||
  flags = info.flags;
 | 
					    version = info.version;
 | 
				
			||||||
  zerostate_root_hash = info.zerostate_root_hash;
 | 
					    if (basic) {
 | 
				
			||||||
  zerostate_file_hash = info.zerostate_file_hash;
 | 
					      min_addr_len = max_addr_len = addr_len_step = 256;
 | 
				
			||||||
  version = info.version;
 | 
					    } else {
 | 
				
			||||||
  if (basic) {
 | 
					      block::gen::WorkchainFormat::Record_wfmt_ext ext;
 | 
				
			||||||
    min_addr_len = max_addr_len = addr_len_step = 256;
 | 
					      if (!tlb::csr_type_unpack(info.format, block::gen::WorkchainFormat{basic}, ext)) {
 | 
				
			||||||
  } else {
 | 
					        return false;
 | 
				
			||||||
    block::gen::WorkchainFormat::Record_wfmt_ext ext;
 | 
					      }
 | 
				
			||||||
    if (!tlb::type_unpack(cs, block::gen::WorkchainFormat{basic}, ext)) {
 | 
					      min_addr_len = ext.min_addr_len;
 | 
				
			||||||
 | 
					      max_addr_len = ext.max_addr_len;
 | 
				
			||||||
 | 
					      addr_len_step = ext.addr_len_step;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  auto unpack_v2 = [&, this](auto& info) {
 | 
				
			||||||
 | 
					    if (!unpack_v1(info)) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    min_addr_len = ext.min_addr_len;
 | 
					    block::gen::WcSplitMergeTimings::Record rec;
 | 
				
			||||||
    max_addr_len = ext.max_addr_len;
 | 
					    if (!tlb::csr_unpack(info.split_merge_timings, rec)) {
 | 
				
			||||||
    addr_len_step = ext.addr_len_step;
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    split_merge_delay = rec.split_merge_delay;
 | 
				
			||||||
 | 
					    split_merge_interval = rec.split_merge_interval;
 | 
				
			||||||
 | 
					    min_split_merge_interval = rec.min_split_merge_interval;
 | 
				
			||||||
 | 
					    max_split_merge_delay = rec.max_split_merge_delay;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  block::gen::WorkchainDescr::Record_workchain info_v1;
 | 
				
			||||||
 | 
					  block::gen::WorkchainDescr::Record_workchain_v2 info_v2;
 | 
				
			||||||
 | 
					  vm::CellSlice cs0 = cs;
 | 
				
			||||||
 | 
					  if (tlb::unpack(cs, info_v1)) {
 | 
				
			||||||
 | 
					    if (!unpack_v1(info_v1)) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else if (tlb::unpack(cs = cs0, info_v2)) {
 | 
				
			||||||
 | 
					    if (!unpack_v2(info_v2)) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  workchain = wc;
 | 
					  workchain = wc;
 | 
				
			||||||
  LOG(DEBUG) << "unpacked info for workchain " << wc << ": basic=" << basic << ", active=" << active
 | 
					  LOG(DEBUG) << "unpacked info for workchain " << wc << ": basic=" << basic << ", active=" << active
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -376,6 +376,19 @@ struct MsgPrices {
 | 
				
			||||||
  td::RefInt256 get_next_part(td::RefInt256 total) const;
 | 
					  td::RefInt256 get_next_part(td::RefInt256 total) const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SizeLimitsConfig {
 | 
				
			||||||
 | 
					  // Default values are used when not present in global config
 | 
				
			||||||
 | 
					  struct ExtMsgLimits {
 | 
				
			||||||
 | 
					    td::uint32 max_size = 65535;
 | 
				
			||||||
 | 
					    td::uint16 max_depth = 512;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  td::uint32 max_msg_bits = 1 << 21;
 | 
				
			||||||
 | 
					  td::uint32 max_msg_cells = 1 << 13;
 | 
				
			||||||
 | 
					  td::uint32 max_library_cells = 1000;
 | 
				
			||||||
 | 
					  td::uint16 max_vm_data_depth = 512;
 | 
				
			||||||
 | 
					  ExtMsgLimits ext_msg_limits;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct CatchainValidatorsConfig {
 | 
					struct CatchainValidatorsConfig {
 | 
				
			||||||
  td::uint32 mc_cc_lifetime, shard_cc_lifetime, shard_val_lifetime, shard_val_num;
 | 
					  td::uint32 mc_cc_lifetime, shard_cc_lifetime, shard_val_lifetime, shard_val_num;
 | 
				
			||||||
  bool shuffle_mc_val;
 | 
					  bool shuffle_mc_val;
 | 
				
			||||||
| 
						 | 
					@ -402,6 +415,13 @@ struct WorkchainInfo : public td::CntObject {
 | 
				
			||||||
  ton::RootHash zerostate_root_hash;
 | 
					  ton::RootHash zerostate_root_hash;
 | 
				
			||||||
  ton::FileHash zerostate_file_hash;
 | 
					  ton::FileHash zerostate_file_hash;
 | 
				
			||||||
  int min_addr_len, max_addr_len, addr_len_step;
 | 
					  int min_addr_len, max_addr_len, addr_len_step;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Default values are used when split_merge_timings is not set in config
 | 
				
			||||||
 | 
					  unsigned split_merge_delay = 100;       // prepare (delay) split/merge for 100 seconds
 | 
				
			||||||
 | 
					  unsigned split_merge_interval = 100;    // split/merge is enabled during 60 second interval
 | 
				
			||||||
 | 
					  unsigned min_split_merge_interval = 30; // split/merge interval must be at least 30 seconds
 | 
				
			||||||
 | 
					  unsigned max_split_merge_delay = 1000;  // end of split/merge interval must be at most 1000 seconds in the future
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool is_valid() const {
 | 
					  bool is_valid() const {
 | 
				
			||||||
    return workchain != ton::workchainInvalid;
 | 
					    return workchain != ton::workchainInvalid;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -593,6 +613,7 @@ class Config {
 | 
				
			||||||
  std::vector<ton::ValidatorDescr> compute_validator_set(ton::ShardIdFull shard, ton::UnixTime time,
 | 
					  std::vector<ton::ValidatorDescr> compute_validator_set(ton::ShardIdFull shard, ton::UnixTime time,
 | 
				
			||||||
                                                         ton::CatchainSeqno cc_seqno) const;
 | 
					                                                         ton::CatchainSeqno cc_seqno) const;
 | 
				
			||||||
  std::vector<ton::ValidatorDescr> compute_total_validator_set(int next) const;
 | 
					  std::vector<ton::ValidatorDescr> compute_total_validator_set(int next) const;
 | 
				
			||||||
 | 
					  td::Result<SizeLimitsConfig> get_size_limits_config() const;
 | 
				
			||||||
  static std::vector<ton::ValidatorDescr> do_compute_validator_set(const block::CatchainValidatorsConfig& ccv_conf,
 | 
					  static std::vector<ton::ValidatorDescr> do_compute_validator_set(const block::CatchainValidatorsConfig& ccv_conf,
 | 
				
			||||||
                                                                   ton::ShardIdFull shard,
 | 
					                                                                   ton::ShardIdFull shard,
 | 
				
			||||||
                                                                   const block::ValidatorSet& vset, ton::UnixTime time,
 | 
					                                                                   const block::ValidatorSet& vset, ton::UnixTime time,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,7 +593,7 @@ bool Transaction::unpack_input_msg(bool ihr_delivered, const ActionPhaseConfig*
 | 
				
			||||||
      sstat.bits -= cs.size();         // bits in the root cells are free
 | 
					      sstat.bits -= cs.size();         // bits in the root cells are free
 | 
				
			||||||
      sstat.cells--;                   // the root cell itself is not counted as a cell
 | 
					      sstat.cells--;                   // the root cell itself is not counted as a cell
 | 
				
			||||||
      LOG(DEBUG) << "storage paid for a message: " << sstat.cells << " cells, " << sstat.bits << " bits";
 | 
					      LOG(DEBUG) << "storage paid for a message: " << sstat.cells << " cells, " << sstat.bits << " bits";
 | 
				
			||||||
      if (sstat.bits > max_msg_bits || sstat.cells > max_msg_cells) {
 | 
					      if (sstat.bits > cfg->size_limits.max_msg_bits || sstat.cells > cfg->size_limits.max_msg_cells) {
 | 
				
			||||||
        LOG(DEBUG) << "inbound external message too large, invalid";
 | 
					        LOG(DEBUG) << "inbound external message too large, invalid";
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -1043,6 +1043,7 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
 | 
				
			||||||
    vm_log.log_options = td::LogOptions(VERBOSITY_NAME(DEBUG), true, false);
 | 
					    vm_log.log_options = td::LogOptions(VERBOSITY_NAME(DEBUG), true, false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vm::VmState vm{new_code, std::move(stack), gas, 1, new_data, vm_log, compute_vm_libraries(cfg)};
 | 
					  vm::VmState vm{new_code, std::move(stack), gas, 1, new_data, vm_log, compute_vm_libraries(cfg)};
 | 
				
			||||||
 | 
					  vm.set_max_data_depth(cfg.max_vm_data_depth);
 | 
				
			||||||
  vm.set_c7(prepare_vm_c7(cfg));  // tuple with SmartContractInfo
 | 
					  vm.set_c7(prepare_vm_c7(cfg));  // tuple with SmartContractInfo
 | 
				
			||||||
  // vm.incr_stack_trace(1);    // enable stack dump after each step
 | 
					  // vm.incr_stack_trace(1);    // enable stack dump after each step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1272,6 +1273,11 @@ int Transaction::try_action_change_library(vm::CellSlice& cs, ActionPhase& ap, c
 | 
				
			||||||
        // library code not found
 | 
					        // library code not found
 | 
				
			||||||
        return 41;
 | 
					        return 41;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      vm::CellStorageStat sstat;
 | 
				
			||||||
 | 
					      sstat.compute_used_storage(lib_ref);
 | 
				
			||||||
 | 
					      if (sstat.cells > cfg.size_limits.max_library_cells) {
 | 
				
			||||||
 | 
					        return 43;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      vm::CellBuilder cb;
 | 
					      vm::CellBuilder cb;
 | 
				
			||||||
      CHECK(cb.store_bool_bool(rec.mode >> 1) && cb.store_ref_bool(std::move(lib_ref)));
 | 
					      CHECK(cb.store_bool_bool(rec.mode >> 1) && cb.store_ref_bool(std::move(lib_ref)));
 | 
				
			||||||
      CHECK(dict.set_builder(hash, cb));
 | 
					      CHECK(dict.set_builder(hash, cb));
 | 
				
			||||||
| 
						 | 
					@ -1546,7 +1552,7 @@ int Transaction::try_action_send_msg(const vm::CellSlice& cs0, ActionPhase& ap,
 | 
				
			||||||
    sstat.add_used_storage(info.value->prefetch_ref());
 | 
					    sstat.add_used_storage(info.value->prefetch_ref());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOG(DEBUG) << "storage paid for a message: " << sstat.cells << " cells, " << sstat.bits << " bits";
 | 
					  LOG(DEBUG) << "storage paid for a message: " << sstat.cells << " cells, " << sstat.bits << " bits";
 | 
				
			||||||
  if (sstat.bits > max_msg_bits || sstat.cells > max_msg_cells) {
 | 
					  if (sstat.bits > cfg.size_limits.max_msg_bits || sstat.cells > cfg.size_limits.max_msg_cells) {
 | 
				
			||||||
    LOG(DEBUG) << "message too large, invalid";
 | 
					    LOG(DEBUG) << "message too large, invalid";
 | 
				
			||||||
    return skip_invalid ? 0 : 40;
 | 
					    return skip_invalid ? 0 : 40;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,7 @@ struct ComputePhaseConfig {
 | 
				
			||||||
  Ref<vm::Cell> global_config;
 | 
					  Ref<vm::Cell> global_config;
 | 
				
			||||||
  td::BitArray<256> block_rand_seed;
 | 
					  td::BitArray<256> block_rand_seed;
 | 
				
			||||||
  bool with_vm_log{false};
 | 
					  bool with_vm_log{false};
 | 
				
			||||||
 | 
					  td::uint16 max_vm_data_depth = 512;
 | 
				
			||||||
  ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0)
 | 
					  ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0)
 | 
				
			||||||
      : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) {
 | 
					      : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) {
 | 
				
			||||||
    compute_threshold();
 | 
					    compute_threshold();
 | 
				
			||||||
| 
						 | 
					@ -143,6 +144,7 @@ struct ActionPhaseConfig {
 | 
				
			||||||
  int bounce_msg_body{0};  // usually 0 or 256 bits
 | 
					  int bounce_msg_body{0};  // usually 0 or 256 bits
 | 
				
			||||||
  MsgPrices fwd_std;
 | 
					  MsgPrices fwd_std;
 | 
				
			||||||
  MsgPrices fwd_mc;  // from/to masterchain
 | 
					  MsgPrices fwd_mc;  // from/to masterchain
 | 
				
			||||||
 | 
					  SizeLimitsConfig size_limits;
 | 
				
			||||||
  const WorkchainSet* workchains{nullptr};
 | 
					  const WorkchainSet* workchains{nullptr};
 | 
				
			||||||
  const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
 | 
					  const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
 | 
				
			||||||
    return is_masterchain ? fwd_mc : fwd_std;
 | 
					    return is_masterchain ? fwd_mc : fwd_std;
 | 
				
			||||||
| 
						 | 
					@ -283,7 +285,6 @@ struct Account {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Transaction {
 | 
					struct Transaction {
 | 
				
			||||||
  static constexpr unsigned max_msg_bits = (1 << 21), max_msg_cells = (1 << 13);
 | 
					 | 
				
			||||||
  enum {
 | 
					  enum {
 | 
				
			||||||
    tr_none,
 | 
					    tr_none,
 | 
				
			||||||
    tr_ord,
 | 
					    tr_ord,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,6 +97,7 @@ class VmState final : public VmStateInterface {
 | 
				
			||||||
  int stack_trace{0}, debug_off{0};
 | 
					  int stack_trace{0}, debug_off{0};
 | 
				
			||||||
  bool chksig_always_succeed{false};
 | 
					  bool chksig_always_succeed{false};
 | 
				
			||||||
  td::ConstBitPtr missing_library{0};
 | 
					  td::ConstBitPtr missing_library{0};
 | 
				
			||||||
 | 
					  td::uint16 max_data_depth = 512; // Default value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  enum {
 | 
					  enum {
 | 
				
			||||||
| 
						 | 
					@ -108,8 +109,7 @@ class VmState final : public VmStateInterface {
 | 
				
			||||||
    implicit_jmpref_gas_price = 10,
 | 
					    implicit_jmpref_gas_price = 10,
 | 
				
			||||||
    implicit_ret_gas_price = 5,
 | 
					    implicit_ret_gas_price = 5,
 | 
				
			||||||
    free_stack_depth = 32,
 | 
					    free_stack_depth = 32,
 | 
				
			||||||
    stack_entry_gas_price = 1,
 | 
					    stack_entry_gas_price = 1
 | 
				
			||||||
    max_data_depth = 512
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  VmState();
 | 
					  VmState();
 | 
				
			||||||
  VmState(Ref<CellSlice> _code);
 | 
					  VmState(Ref<CellSlice> _code);
 | 
				
			||||||
| 
						 | 
					@ -325,6 +325,9 @@ class VmState final : public VmStateInterface {
 | 
				
			||||||
  td::ConstBitPtr get_missing_library() const {
 | 
					  td::ConstBitPtr get_missing_library() const {
 | 
				
			||||||
    return missing_library;
 | 
					    return missing_library;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  void set_max_data_depth(td::uint16 depth) {
 | 
				
			||||||
 | 
					    max_data_depth = depth;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  void init_cregs(bool same_c3 = false, bool push_0 = true);
 | 
					  void init_cregs(bool same_c3 = false, bool push_0 = true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,12 +51,6 @@ using ValidatorSessionId = td::Bits256;
 | 
				
			||||||
constexpr WorkchainId masterchainId = -1, basechainId = 0, workchainInvalid = 0x80000000;
 | 
					constexpr WorkchainId masterchainId = -1, basechainId = 0, workchainInvalid = 0x80000000;
 | 
				
			||||||
constexpr ShardId shardIdAll = (1ULL << 63);
 | 
					constexpr ShardId shardIdAll = (1ULL << 63);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr unsigned split_merge_delay = 100;        // prepare (delay) split/merge for 100 seconds
 | 
					 | 
				
			||||||
constexpr unsigned split_merge_interval = 100;     // split/merge is enabled during 60 second interval
 | 
					 | 
				
			||||||
constexpr unsigned min_split_merge_interval = 30;  // split/merge interval must be at least 30 seconds
 | 
					 | 
				
			||||||
constexpr unsigned max_split_merge_delay =
 | 
					 | 
				
			||||||
    1000;  // end of split/merge interval must be at most 1000 seconds in the future
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum GlobalCapabilities {
 | 
					enum GlobalCapabilities {
 | 
				
			||||||
  capIhrEnabled = 1,
 | 
					  capIhrEnabled = 1,
 | 
				
			||||||
  capCreateStatsEnabled = 2,
 | 
					  capCreateStatsEnabled = 2,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,13 +40,15 @@ td::Result<BlockHandle> create_block_handle(td::BufferSlice data);
 | 
				
			||||||
td::Result<BlockHandle> create_block_handle(td::Slice data);
 | 
					td::Result<BlockHandle> create_block_handle(td::Slice data);
 | 
				
			||||||
td::Result<ConstBlockHandle> create_temp_block_handle(td::BufferSlice data);
 | 
					td::Result<ConstBlockHandle> create_temp_block_handle(td::BufferSlice data);
 | 
				
			||||||
BlockHandle create_empty_block_handle(BlockIdExt id);
 | 
					BlockHandle create_empty_block_handle(BlockIdExt id);
 | 
				
			||||||
td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data);
 | 
					td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data,
 | 
				
			||||||
 | 
					                                                   block::SizeLimitsConfig::ExtMsgLimits limits);
 | 
				
			||||||
td::Result<td::Ref<IhrMessage>> create_ihr_message(td::BufferSlice data);
 | 
					td::Result<td::Ref<IhrMessage>> create_ihr_message(td::BufferSlice data);
 | 
				
			||||||
td::Result<std::vector<td::Ref<ShardTopBlockDescription>>> create_new_shard_block_descriptions(td::BufferSlice data);
 | 
					td::Result<std::vector<td::Ref<ShardTopBlockDescription>>> create_new_shard_block_descriptions(td::BufferSlice data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_set);
 | 
					td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_set);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run_check_external_message(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
 | 
					void run_check_external_message(td::BufferSlice data, block::SizeLimitsConfig::ExtMsgLimits limits,
 | 
				
			||||||
 | 
					                                td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Ref<ExtMessage>> promise);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
 | 
					void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
 | 
				
			||||||
                            td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
 | 
					                            td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,7 +109,14 @@ void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broad
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto q = B.move_as_ok();
 | 
					  auto q = B.move_as_ok();
 | 
				
			||||||
  td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_external_message,
 | 
					  td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_external_message,
 | 
				
			||||||
                          std::move(q->message_->data_), std::move(promise));
 | 
					                          std::move(q->message_->data_),
 | 
				
			||||||
 | 
					                          [promise = std::move(promise)](td::Result<td::Ref<ExtMessage>> R) mutable {
 | 
				
			||||||
 | 
					                            if (R.is_error()) {
 | 
				
			||||||
 | 
					                              promise.set_error(R.move_as_error());
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                              promise.set_result(td::Unit());
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) {
 | 
					void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1598,6 +1598,7 @@ td::Result<std::unique_ptr<block::ConfigInfo>>
 | 
				
			||||||
    prng::rand_gen().strong_rand_bytes(rand_seed->data(), 32);
 | 
					    prng::rand_gen().strong_rand_bytes(rand_seed->data(), 32);
 | 
				
			||||||
    LOG(DEBUG) << "block random seed set to " << rand_seed->to_hex();
 | 
					    LOG(DEBUG) << "block random seed set to " << rand_seed->to_hex();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  TRY_RESULT(size_limits, config->get_size_limits_config());
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // compute compute_phase_cfg / storage_phase_cfg
 | 
					    // compute compute_phase_cfg / storage_phase_cfg
 | 
				
			||||||
    auto cell = config->get_config_param(wc == ton::masterchainId ? 20 : 21);
 | 
					    auto cell = config->get_config_param(wc == ton::masterchainId ? 20 : 21);
 | 
				
			||||||
| 
						 | 
					@ -1610,6 +1611,7 @@ td::Result<std::unique_ptr<block::ConfigInfo>>
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    compute_phase_cfg->block_rand_seed = *rand_seed;
 | 
					    compute_phase_cfg->block_rand_seed = *rand_seed;
 | 
				
			||||||
    compute_phase_cfg->libraries = std::make_unique<vm::Dictionary>(config->get_libraries_root(), 256);
 | 
					    compute_phase_cfg->libraries = std::make_unique<vm::Dictionary>(config->get_libraries_root(), 256);
 | 
				
			||||||
 | 
					    compute_phase_cfg->max_vm_data_depth = size_limits.max_vm_data_depth;
 | 
				
			||||||
    compute_phase_cfg->global_config = config->get_root_cell();
 | 
					    compute_phase_cfg->global_config = config->get_root_cell();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
| 
						 | 
					@ -1631,6 +1633,7 @@ td::Result<std::unique_ptr<block::ConfigInfo>>
 | 
				
			||||||
                         (unsigned)rec.first_frac, (unsigned)rec.next_frac};
 | 
					                         (unsigned)rec.first_frac, (unsigned)rec.next_frac};
 | 
				
			||||||
    action_phase_cfg->workchains = &config->get_workchain_list();
 | 
					    action_phase_cfg->workchains = &config->get_workchain_list();
 | 
				
			||||||
    action_phase_cfg->bounce_msg_body = (config->has_capability(ton::capBounceMsgBody) ? 256 : 0);
 | 
					    action_phase_cfg->bounce_msg_body = (config->has_capability(ton::capBounceMsgBody) ? 256 : 0);
 | 
				
			||||||
 | 
					    action_phase_cfg->size_limits = size_limits;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // fetch block_grams_created
 | 
					    // fetch block_grams_created
 | 
				
			||||||
| 
						 | 
					@ -3095,7 +3098,7 @@ static int update_one_shard(block::McShardHash& info, const block::McShardHash*
 | 
				
			||||||
    if (info.is_fsm_none() && (info.want_split_ || depth < wc_info->min_split) && depth < wc_info->max_split &&
 | 
					    if (info.is_fsm_none() && (info.want_split_ || depth < wc_info->min_split) && depth < wc_info->max_split &&
 | 
				
			||||||
        depth < 60) {
 | 
					        depth < 60) {
 | 
				
			||||||
      // prepare split
 | 
					      // prepare split
 | 
				
			||||||
      info.set_fsm_split(now + ton::split_merge_delay, ton::split_merge_interval);
 | 
					      info.set_fsm_split(now + wc_info->split_merge_delay, wc_info->split_merge_interval);
 | 
				
			||||||
      changed = true;
 | 
					      changed = true;
 | 
				
			||||||
      LOG(INFO) << "preparing to split shard " << info.shard().to_str() << " during " << info.fsm_utime() << " .. "
 | 
					      LOG(INFO) << "preparing to split shard " << info.shard().to_str() << " during " << info.fsm_utime() << " .. "
 | 
				
			||||||
                << info.fsm_utime_end();
 | 
					                << info.fsm_utime_end();
 | 
				
			||||||
| 
						 | 
					@ -3103,7 +3106,7 @@ static int update_one_shard(block::McShardHash& info, const block::McShardHash*
 | 
				
			||||||
               sibling && !sibling->before_split_ && sibling->is_fsm_none() &&
 | 
					               sibling && !sibling->before_split_ && sibling->is_fsm_none() &&
 | 
				
			||||||
               (sibling->want_merge_ || depth > wc_info->max_split)) {
 | 
					               (sibling->want_merge_ || depth > wc_info->max_split)) {
 | 
				
			||||||
      // prepare merge
 | 
					      // prepare merge
 | 
				
			||||||
      info.set_fsm_merge(now + ton::split_merge_delay, ton::split_merge_interval);
 | 
					      info.set_fsm_merge(now + wc_info->split_merge_delay, wc_info->split_merge_interval);
 | 
				
			||||||
      changed = true;
 | 
					      changed = true;
 | 
				
			||||||
      LOG(INFO) << "preparing to merge shard " << info.shard().to_str() << " with " << sibling->shard().to_str()
 | 
					      LOG(INFO) << "preparing to merge shard " << info.shard().to_str() << " with " << sibling->shard().to_str()
 | 
				
			||||||
                << " during " << info.fsm_utime() << " .. " << info.fsm_utime_end();
 | 
					                << " during " << info.fsm_utime() << " .. " << info.fsm_utime_end();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,8 +38,9 @@ ExtMessageQ::ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountId
 | 
				
			||||||
  hash_ = block::compute_file_hash(data_);
 | 
					  hash_ = block::compute_file_hash(data_);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Result<Ref<ExtMessageQ>> ExtMessageQ::create_ext_message(td::BufferSlice data) {
 | 
					td::Result<Ref<ExtMessageQ>> ExtMessageQ::create_ext_message(td::BufferSlice data,
 | 
				
			||||||
  if (data.size() > max_ext_msg_size) {
 | 
					                                                             block::SizeLimitsConfig::ExtMsgLimits limits) {
 | 
				
			||||||
 | 
					  if (data.size() > limits.max_size) {
 | 
				
			||||||
    return td::Status::Error("external message too large, rejecting");
 | 
					    return td::Status::Error("external message too large, rejecting");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vm::BagOfCells boc;
 | 
					  vm::BagOfCells boc;
 | 
				
			||||||
| 
						 | 
					@ -54,7 +55,7 @@ td::Result<Ref<ExtMessageQ>> ExtMessageQ::create_ext_message(td::BufferSlice dat
 | 
				
			||||||
  if (ext_msg->get_level() != 0) {
 | 
					  if (ext_msg->get_level() != 0) {
 | 
				
			||||||
    return td::Status::Error("external message must have zero level");
 | 
					    return td::Status::Error("external message must have zero level");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (ext_msg->get_depth() >= max_ext_msg_depth) {
 | 
					  if (ext_msg->get_depth() >= limits.max_depth) {
 | 
				
			||||||
    return td::Status::Error("external message is too deep");
 | 
					    return td::Status::Error("external message is too deep");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vm::CellSlice cs{vm::NoVmOrd{}, ext_msg};
 | 
					  vm::CellSlice cs{vm::NoVmOrd{}, ext_msg};
 | 
				
			||||||
| 
						 | 
					@ -85,21 +86,25 @@ td::Result<Ref<ExtMessageQ>> ExtMessageQ::create_ext_message(td::BufferSlice dat
 | 
				
			||||||
  return Ref<ExtMessageQ>{true, std::move(data), std::move(ext_msg), dest_prefix, wc, addr};
 | 
					  return Ref<ExtMessageQ>{true, std::move(data), std::move(ext_msg), dest_prefix, wc, addr};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ExtMessageQ::run_message(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
 | 
					void ExtMessageQ::run_message(td::BufferSlice data, block::SizeLimitsConfig::ExtMsgLimits limits,
 | 
				
			||||||
                              td::Promise<td::Unit> promise) {
 | 
					                              td::actor::ActorId<ton::validator::ValidatorManager> manager,
 | 
				
			||||||
  auto R = create_ext_message(std::move(data));
 | 
					                              td::Promise<td::Ref<ExtMessage>> promise) {
 | 
				
			||||||
 | 
					  auto R = create_ext_message(std::move(data), limits);
 | 
				
			||||||
  if (R.is_error()) {
 | 
					  if (R.is_error()) {
 | 
				
			||||||
    return promise.set_error(R.move_as_error_prefix("failed to parse external message "));
 | 
					    return promise.set_error(R.move_as_error_prefix("failed to parse external message "));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  auto M = R.move_as_ok();
 | 
					  auto M = R.move_as_ok();
 | 
				
			||||||
  auto root = M->root_cell();
 | 
					  auto root = M->root_cell();
 | 
				
			||||||
  block::gen::CommonMsgInfo::Record_ext_in_msg_info info;
 | 
					  block::gen::CommonMsgInfo::Record_ext_in_msg_info info;
 | 
				
			||||||
  tlb::unpack_cell_inexact(root, info); // checked in create message
 | 
					  tlb::unpack_cell_inexact(root, info);  // checked in create message
 | 
				
			||||||
  ton::StdSmcAddress addr = M->addr();
 | 
					  ton::StdSmcAddress addr = M->addr();
 | 
				
			||||||
  ton::WorkchainId wc = M->wc();
 | 
					  ton::WorkchainId wc = M->wc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  run_fetch_account_state(wc, addr, manager,
 | 
					  run_fetch_account_state(
 | 
				
			||||||
      [promise = std::move(promise), msg_root = root, wc = wc](td::Result<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> res) mutable {
 | 
					      wc, addr, manager,
 | 
				
			||||||
 | 
					      [promise = std::move(promise), msg_root = root, wc,
 | 
				
			||||||
 | 
					       M](td::Result<std::tuple<td::Ref<vm::CellSlice>, UnixTime, LogicalTime, std::unique_ptr<block::ConfigInfo>>>
 | 
				
			||||||
 | 
					              res) mutable {
 | 
				
			||||||
        if (res.is_error()) {
 | 
					        if (res.is_error()) {
 | 
				
			||||||
          promise.set_error(td::Status::Error(PSLICE() << "Failed to get account state"));
 | 
					          promise.set_error(td::Status::Error(PSLICE() << "Failed to get account state"));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
| 
						 | 
					@ -109,20 +114,19 @@ void ExtMessageQ::run_message(td::BufferSlice data, td::actor::ActorId<ton::vali
 | 
				
			||||||
          auto utime = std::get<1>(tuple);
 | 
					          auto utime = std::get<1>(tuple);
 | 
				
			||||||
          auto lt = std::get<2>(tuple);
 | 
					          auto lt = std::get<2>(tuple);
 | 
				
			||||||
          auto config = std::move(std::get<3>(tuple));
 | 
					          auto config = std::move(std::get<3>(tuple));
 | 
				
			||||||
          if(!acc.unpack(shard_acc, {}, utime, false)) {
 | 
					          if (!acc.unpack(shard_acc, {}, utime, false)) {
 | 
				
			||||||
            promise.set_error(td::Status::Error(PSLICE() << "Failed to unpack account state"));
 | 
					            promise.set_error(td::Status::Error(PSLICE() << "Failed to unpack account state"));
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            auto status = run_message_on_account(wc, &acc, utime, lt + 1, msg_root, std::move(config));
 | 
					            auto status = run_message_on_account(wc, &acc, utime, lt + 1, msg_root, std::move(config));
 | 
				
			||||||
            if (status.is_ok()) {
 | 
					            if (status.is_ok()) {
 | 
				
			||||||
              promise.set_value(td::Unit());
 | 
					              promise.set_value(std::move(M));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              promise.set_error(td::Status::Error(
 | 
					              promise.set_error(td::Status::Error(PSLICE() << "External message was not accepted\n"
 | 
				
			||||||
                  PSLICE() << "External message was not accepted\n" << status.message()));
 | 
					                                                           << status.message()));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      });
 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Status ExtMessageQ::run_message_on_account(ton::WorkchainId wc,
 | 
					td::Status ExtMessageQ::run_message_on_account(ton::WorkchainId wc,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,8 +37,6 @@ class ExtMessageQ : public ExtMessage {
 | 
				
			||||||
  ton::StdSmcAddress addr_;
 | 
					  ton::StdSmcAddress addr_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  static constexpr unsigned max_ext_msg_size = 65535;
 | 
					 | 
				
			||||||
  static constexpr unsigned max_ext_msg_depth = 512;
 | 
					 | 
				
			||||||
  AccountIdPrefixFull shard() const override {
 | 
					  AccountIdPrefixFull shard() const override {
 | 
				
			||||||
    return addr_prefix_;
 | 
					    return addr_prefix_;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -59,10 +57,13 @@ class ExtMessageQ : public ExtMessage {
 | 
				
			||||||
    return addr_;
 | 
					    return addr_;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull shard, ton::WorkchainId wc, ton::StdSmcAddress addr);
 | 
					  ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull shard, ton::WorkchainId wc,
 | 
				
			||||||
  static td::Result<td::Ref<ExtMessageQ>> create_ext_message(td::BufferSlice data);
 | 
					              ton::StdSmcAddress addr);
 | 
				
			||||||
  static void run_message(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
 | 
					  static td::Result<td::Ref<ExtMessageQ>> create_ext_message(td::BufferSlice data,
 | 
				
			||||||
                        td::Promise<td::Unit> promise);
 | 
					                                                             block::SizeLimitsConfig::ExtMsgLimits limits);
 | 
				
			||||||
 | 
					  static void run_message(td::BufferSlice data, block::SizeLimitsConfig::ExtMsgLimits limits,
 | 
				
			||||||
 | 
					                          td::actor::ActorId<ton::validator::ValidatorManager> manager,
 | 
				
			||||||
 | 
					                          td::Promise<td::Ref<ExtMessage>> promise);
 | 
				
			||||||
  static td::Status run_message_on_account(ton::WorkchainId wc,
 | 
					  static td::Status run_message_on_account(ton::WorkchainId wc,
 | 
				
			||||||
                                           block::Account* acc,
 | 
					                                           block::Account* acc,
 | 
				
			||||||
                                           UnixTime utime, LogicalTime lt,
 | 
					                                           UnixTime utime, LogicalTime lt,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,13 +111,16 @@ td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_
 | 
				
			||||||
  return td::Ref<BlockSignatureSetQ>{true, std::move(sig_set)};
 | 
					  return td::Ref<BlockSignatureSetQ>{true, std::move(sig_set)};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data) {
 | 
					td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data,
 | 
				
			||||||
  TRY_RESULT(res, ExtMessageQ::create_ext_message(std::move(data)));
 | 
					                                                   block::SizeLimitsConfig::ExtMsgLimits limits) {
 | 
				
			||||||
 | 
					  TRY_RESULT(res, ExtMessageQ::create_ext_message(std::move(data), limits));
 | 
				
			||||||
  return std::move(res);
 | 
					  return std::move(res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run_check_external_message(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise) {
 | 
					void run_check_external_message(td::BufferSlice data, block::SizeLimitsConfig::ExtMsgLimits limits,
 | 
				
			||||||
  ExtMessageQ::run_message(std::move(data), std::move(manager), std::move(promise));
 | 
					                                td::actor::ActorId<ValidatorManager> manager,
 | 
				
			||||||
 | 
					                                td::Promise<td::Ref<ExtMessage>> promise) {
 | 
				
			||||||
 | 
					  ExtMessageQ::run_message(std::move(data), limits, std::move(manager), std::move(promise));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::Result<td::Ref<IhrMessage>> create_ihr_message(td::BufferSlice data) {
 | 
					td::Result<td::Ref<IhrMessage>> create_ihr_message(td::BufferSlice data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,20 +482,13 @@ void LiteQuery::perform_sendMessage(td::BufferSlice data) {
 | 
				
			||||||
  auto copy = data.clone();
 | 
					  auto copy = data.clone();
 | 
				
			||||||
  td::actor::send_closure_later(
 | 
					  td::actor::send_closure_later(
 | 
				
			||||||
      manager_, &ValidatorManager::check_external_message, std::move(copy),
 | 
					      manager_, &ValidatorManager::check_external_message, std::move(copy),
 | 
				
			||||||
      [Self = actor_id(this), data = std::move(data), manager = manager_](td::Result<td::Unit> res) mutable {
 | 
					      [Self = actor_id(this), data = std::move(data), manager = manager_](td::Result<td::Ref<ExtMessage>> res) mutable {
 | 
				
			||||||
        if(res.is_error()) {
 | 
					        if(res.is_error()) {
 | 
				
			||||||
           td::actor::send_closure(Self, &LiteQuery::abort_query,
 | 
					           td::actor::send_closure(Self, &LiteQuery::abort_query,
 | 
				
			||||||
                                   res.move_as_error_prefix("cannot apply external message to current state : "s));
 | 
					                                   res.move_as_error_prefix("cannot apply external message to current state : "s));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          auto crm = ton::validator::create_ext_message(std::move(data));
 | 
					 | 
				
			||||||
          if (crm.is_error()) {
 | 
					 | 
				
			||||||
             //UNREACHABLE, checks in check_external_message,
 | 
					 | 
				
			||||||
             td::actor::send_closure(Self, &LiteQuery::abort_query,
 | 
					 | 
				
			||||||
                                     crm.move_as_error());
 | 
					 | 
				
			||||||
             return;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          LOG(INFO) << "sending an external message to validator manager";
 | 
					          LOG(INFO) << "sending an external message to validator manager";
 | 
				
			||||||
          td::actor::send_closure_later(manager, &ValidatorManager::send_external_message, crm.move_as_ok());
 | 
					          td::actor::send_closure_later(manager, &ValidatorManager::send_external_message, res.move_as_ok());
 | 
				
			||||||
          auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_sendMsgStatus>(1);
 | 
					          auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_sendMsgStatus>(1);
 | 
				
			||||||
          td::actor::send_closure(Self, &LiteQuery::finish_query, std::move(b));
 | 
					          td::actor::send_closure(Self, &LiteQuery::finish_query, std::move(b));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,6 +126,10 @@ class MasterchainStateQ : public MasterchainState, public ShardStateQ {
 | 
				
			||||||
  ValidatorSessionConfig get_consensus_config() const override {
 | 
					  ValidatorSessionConfig get_consensus_config() const override {
 | 
				
			||||||
    return config_->get_consensus_config();
 | 
					    return config_->get_consensus_config();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  block::SizeLimitsConfig::ExtMsgLimits get_ext_msg_limits() const override {
 | 
				
			||||||
 | 
					    auto R = config_->get_size_limits_config();
 | 
				
			||||||
 | 
					    return R.is_error() ? block::SizeLimitsConfig::ExtMsgLimits() : R.ok_ref().ext_msg_limits;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  BlockIdExt last_key_block_id() const override;
 | 
					  BlockIdExt last_key_block_id() const override;
 | 
				
			||||||
  BlockIdExt next_key_block_id(BlockSeqno seqno) const override;
 | 
					  BlockIdExt next_key_block_id(BlockSeqno seqno) const override;
 | 
				
			||||||
  BlockIdExt prev_key_block_id(BlockSeqno seqno) const override;
 | 
					  BlockIdExt prev_key_block_id(BlockSeqno seqno) const override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -764,6 +764,14 @@ bool ValidateQuery::fetch_config_params() {
 | 
				
			||||||
    // recover (not generate) rand seed from block header
 | 
					    // recover (not generate) rand seed from block header
 | 
				
			||||||
    CHECK(!rand_seed_.is_zero());
 | 
					    CHECK(!rand_seed_.is_zero());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  block::SizeLimitsConfig size_limits;
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    auto res = config_->get_size_limits_config();
 | 
				
			||||||
 | 
					    if (res.is_error()) {
 | 
				
			||||||
 | 
					      return fatal_error(res.move_as_error());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    size_limits = res.move_as_ok();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // compute compute_phase_cfg / storage_phase_cfg
 | 
					    // compute compute_phase_cfg / storage_phase_cfg
 | 
				
			||||||
    auto cell = config_->get_config_param(is_masterchain() ? 20 : 21);
 | 
					    auto cell = config_->get_config_param(is_masterchain() ? 20 : 21);
 | 
				
			||||||
| 
						 | 
					@ -776,6 +784,7 @@ bool ValidateQuery::fetch_config_params() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    compute_phase_cfg_.block_rand_seed = rand_seed_;
 | 
					    compute_phase_cfg_.block_rand_seed = rand_seed_;
 | 
				
			||||||
    compute_phase_cfg_.libraries = std::make_unique<vm::Dictionary>(config_->get_libraries_root(), 256);
 | 
					    compute_phase_cfg_.libraries = std::make_unique<vm::Dictionary>(config_->get_libraries_root(), 256);
 | 
				
			||||||
 | 
					    compute_phase_cfg_.max_vm_data_depth = size_limits.max_vm_data_depth;
 | 
				
			||||||
    compute_phase_cfg_.global_config = config_->get_root_cell();
 | 
					    compute_phase_cfg_.global_config = config_->get_root_cell();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
| 
						 | 
					@ -797,6 +806,7 @@ bool ValidateQuery::fetch_config_params() {
 | 
				
			||||||
                         (unsigned)rec.first_frac, (unsigned)rec.next_frac};
 | 
					                         (unsigned)rec.first_frac, (unsigned)rec.next_frac};
 | 
				
			||||||
    action_phase_cfg_.workchains = &config_->get_workchain_list();
 | 
					    action_phase_cfg_.workchains = &config_->get_workchain_list();
 | 
				
			||||||
    action_phase_cfg_.bounce_msg_body = (config_->has_capability(ton::capBounceMsgBody) ? 256 : 0);
 | 
					    action_phase_cfg_.bounce_msg_body = (config_->has_capability(ton::capBounceMsgBody) ? 256 : 0);
 | 
				
			||||||
 | 
					    action_phase_cfg_.size_limits = size_limits;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // fetch block_grams_created
 | 
					    // fetch block_grams_created
 | 
				
			||||||
| 
						 | 
					@ -1610,8 +1620,8 @@ bool ValidateQuery::check_one_shard(const block::McShardHash& info, const block:
 | 
				
			||||||
                    (sibling->want_merge_ || depth > wc_info->max_split);
 | 
					                    (sibling->want_merge_ || depth > wc_info->max_split);
 | 
				
			||||||
  if (!fsm_inherited && !info.is_fsm_none()) {
 | 
					  if (!fsm_inherited && !info.is_fsm_none()) {
 | 
				
			||||||
    if (info.fsm_utime() < now_ || info.fsm_utime_end() <= info.fsm_utime() ||
 | 
					    if (info.fsm_utime() < now_ || info.fsm_utime_end() <= info.fsm_utime() ||
 | 
				
			||||||
        info.fsm_utime_end() < info.fsm_utime() + ton::min_split_merge_interval ||
 | 
					        info.fsm_utime_end() < info.fsm_utime() + wc_info->min_split_merge_interval ||
 | 
				
			||||||
        info.fsm_utime_end() > now_ + ton::max_split_merge_delay) {
 | 
					        info.fsm_utime_end() > now_ + wc_info->max_split_merge_delay) {
 | 
				
			||||||
      return reject_query(PSTRING() << "incorrect future split/merge interval " << info.fsm_utime() << " .. "
 | 
					      return reject_query(PSTRING() << "incorrect future split/merge interval " << info.fsm_utime() << " .. "
 | 
				
			||||||
                                    << info.fsm_utime_end() << " set for shard " << shard.to_str()
 | 
					                                    << info.fsm_utime_end() << " set for shard " << shard.to_str()
 | 
				
			||||||
                                    << " in new shard configuration (it is " << now_ << " now)");
 | 
					                                    << " in new shard configuration (it is " << now_ << " now)");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,7 @@ class MasterchainState : virtual public ShardState {
 | 
				
			||||||
  virtual td::Status prepare() {
 | 
					  virtual td::Status prepare() {
 | 
				
			||||||
    return td::Status::OK();
 | 
					    return td::Status::OK();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  virtual block::SizeLimitsConfig::ExtMsgLimits get_ext_msg_limits() const = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace validator
 | 
					}  // namespace validator
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -260,7 +260,10 @@ void ValidatorManagerImpl::get_key_block_proof_link(BlockIdExt block_id, td::Pro
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
 | 
					void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
 | 
				
			||||||
  auto R = create_ext_message(std::move(data));
 | 
					  if (last_masterchain_state_.is_null()) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto R = create_ext_message(std::move(data), last_masterchain_state_->get_ext_msg_limits());
 | 
				
			||||||
  if (R.is_ok()) {
 | 
					  if (R.is_ok()) {
 | 
				
			||||||
    ext_messages_.emplace_back(R.move_as_ok());
 | 
					    ext_messages_.emplace_back(R.move_as_ok());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,7 +124,7 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  //void get_block_description(BlockIdExt block_id, td::Promise<BlockDescription> promise) override;
 | 
					  //void get_block_description(BlockIdExt block_id, td::Promise<BlockDescription> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void new_external_message(td::BufferSlice data) override;
 | 
					  void new_external_message(td::BufferSlice data) override;
 | 
				
			||||||
  void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
 | 
					  void check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  void new_ihr_message(td::BufferSlice data) override;
 | 
					  void new_ihr_message(td::BufferSlice data) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,7 +151,7 @@ void ValidatorManagerImpl::get_key_block_proof_link(BlockIdExt block_id, td::Pro
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
 | 
					void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
 | 
				
			||||||
  auto R = create_ext_message(std::move(data));
 | 
					  auto R = create_ext_message(std::move(data), block::SizeLimitsConfig::ExtMsgLimits());
 | 
				
			||||||
  if (R.is_ok()) {
 | 
					  if (R.is_ok()) {
 | 
				
			||||||
    ext_messages_.emplace_back(R.move_as_ok());
 | 
					    ext_messages_.emplace_back(R.move_as_ok());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  void get_key_block_proof_link(BlockIdExt block_id, td::Promise<td::BufferSlice> promise) override;
 | 
					  void get_key_block_proof_link(BlockIdExt block_id, td::Promise<td::BufferSlice> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void new_external_message(td::BufferSlice data) override;
 | 
					  void new_external_message(td::BufferSlice data) override;
 | 
				
			||||||
  void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
 | 
					  void check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  void new_ihr_message(td::BufferSlice data) override;
 | 
					  void new_ihr_message(td::BufferSlice data) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -372,12 +372,16 @@ void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
 | 
				
			||||||
  if (!is_validator()) {
 | 
					  if (!is_validator()) {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if( ext_messages_.size() > max_mempool_num() ) {
 | 
					  if (last_masterchain_state_.is_null()) {
 | 
				
			||||||
 | 
					    VLOG(VALIDATOR_NOTICE) << "dropping ext message: validator is not ready";
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  auto R = create_ext_message(std::move(data));
 | 
					  if (ext_messages_.size() > max_mempool_num()) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto R = create_ext_message(std::move(data), last_masterchain_state_->get_ext_msg_limits());
 | 
				
			||||||
  if (R.is_error()) {
 | 
					  if (R.is_error()) {
 | 
				
			||||||
    VLOG(VALIDATOR_NOTICE) << "dropping bad ihr message: " << R.move_as_error();
 | 
					    VLOG(VALIDATOR_NOTICE) << "dropping bad ext message: " << R.move_as_error();
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  add_external_message(R.move_as_ok());
 | 
					  add_external_message(R.move_as_ok());
 | 
				
			||||||
| 
						 | 
					@ -396,8 +400,13 @@ void ValidatorManagerImpl::add_external_message(td::Ref<ExtMessage> msg) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) {
 | 
					void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) {
 | 
				
			||||||
  run_check_external_message(std::move(data), actor_id(this), std::move(promise));
 | 
					  if (last_masterchain_state_.is_null()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error(ErrorCode::notready, "not ready"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  run_check_external_message(std::move(data), last_masterchain_state_->get_ext_msg_limits(), actor_id(this),
 | 
				
			||||||
 | 
					                             std::move(promise));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
 | 
					void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,7 +334,7 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void new_external_message(td::BufferSlice data) override;
 | 
					  void new_external_message(td::BufferSlice data) override;
 | 
				
			||||||
  void add_external_message(td::Ref<ExtMessage> message);
 | 
					  void add_external_message(td::Ref<ExtMessage> message);
 | 
				
			||||||
  void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override;
 | 
					  void check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void new_ihr_message(td::BufferSlice data) override;
 | 
					  void new_ihr_message(td::BufferSlice data) override;
 | 
				
			||||||
  void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override;
 | 
					  void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@
 | 
				
			||||||
#include "interfaces/proof.h"
 | 
					#include "interfaces/proof.h"
 | 
				
			||||||
#include "interfaces/shard.h"
 | 
					#include "interfaces/shard.h"
 | 
				
			||||||
#include "catchain/catchain-types.h"
 | 
					#include "catchain/catchain-types.h"
 | 
				
			||||||
 | 
					#include "interfaces/external-message.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ton {
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +187,7 @@ class ValidatorManagerInterface : public td::actor::Actor {
 | 
				
			||||||
  virtual void write_handle(BlockHandle handle, td::Promise<td::Unit> promise) = 0;
 | 
					  virtual void write_handle(BlockHandle handle, td::Promise<td::Unit> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void new_external_message(td::BufferSlice data) = 0;
 | 
					  virtual void new_external_message(td::BufferSlice data) = 0;
 | 
				
			||||||
  virtual void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) = 0;
 | 
					  virtual void check_external_message(td::BufferSlice data, td::Promise<td::Ref<ExtMessage>> promise) = 0;
 | 
				
			||||||
  virtual void new_ihr_message(td::BufferSlice data) = 0;
 | 
					  virtual void new_ihr_message(td::BufferSlice data) = 0;
 | 
				
			||||||
  virtual void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) = 0;
 | 
					  virtual void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue