mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Exporting and importing candidates using validator-engine-console; lite mode for validator group
This commit is contained in:
		
							parent
							
								
									625516c568
								
							
						
					
					
						commit
						415ace3da9
					
				
					 16 changed files with 410 additions and 5 deletions
				
			
		| 
						 | 
					@ -633,6 +633,8 @@ engine.validator.overlaysStats overlays:(vector engine.validator.overlayStats) =
 | 
				
			||||||
engine.validator.validatorSessionInfo current_block:tonNode.blockId self:int256 current_round:int next_producers:(vector int256) = engine.validator.ValidatorSessionInfo;
 | 
					engine.validator.validatorSessionInfo current_block:tonNode.blockId self:int256 current_round:int next_producers:(vector int256) = engine.validator.ValidatorSessionInfo;
 | 
				
			||||||
engine.validator.validatorSessionsInfo sessions:(vector engine.validator.validatorSessionInfo) = engine.validator.ValidatorSessionsInfo;
 | 
					engine.validator.validatorSessionsInfo sessions:(vector engine.validator.validatorSessionInfo) = engine.validator.ValidatorSessionsInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					engine.validator.requiredBlockCandidates block_ids:(vector tonNode.blockId) = engine.validator.RequiredBlockCandidates;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---functions---
 | 
					---functions---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
engine.validator.getTime = engine.validator.Time;
 | 
					engine.validator.getTime = engine.validator.Time;
 | 
				
			||||||
| 
						 | 
					@ -684,6 +686,10 @@ engine.validator.importShardOverlayCertificate workchain:int shard:long signed_k
 | 
				
			||||||
 | 
					
 | 
				
			||||||
engine.validator.getValidatorSessionsInfo = engine.validator.ValidatorSessionsInfo;
 | 
					engine.validator.getValidatorSessionsInfo = engine.validator.ValidatorSessionsInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					engine.validator.generateBlockCandidate block_id:tonNode.BlockId = db.Candidate;
 | 
				
			||||||
 | 
					engine.validator.getRequiredBlockCandidates = engine.validator.RequiredBlockCandidates;
 | 
				
			||||||
 | 
					engine.validator.importBlockCandidate block:db.candidate = engine.validator.Success;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---types---
 | 
					---types---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
storage.pong = storage.Pong;
 | 
					storage.pong = storage.Pong;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -1028,3 +1028,66 @@ td::Status GetValidatorSessionsInfoQuery::receive(td::BufferSlice data) {
 | 
				
			||||||
  td::TerminalIO::out() << "---------\n" << s << "--------\n";
 | 
					  td::TerminalIO::out() << "---------\n" << s << "--------\n";
 | 
				
			||||||
  return td::Status::OK();
 | 
					  return td::Status::OK();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GenerateBlockCandidateQuery::run() {
 | 
				
			||||||
 | 
					  TRY_RESULT_ASSIGN(wc_, tokenizer_.get_token<td::int32>());
 | 
				
			||||||
 | 
					  TRY_RESULT_ASSIGN(shard_, tokenizer_.get_token<td::int64>() );
 | 
				
			||||||
 | 
					  TRY_RESULT_ASSIGN(seqno_, tokenizer_.get_token<td::int32>());
 | 
				
			||||||
 | 
					  TRY_RESULT_ASSIGN(file_, tokenizer_.get_token<std::string>());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GenerateBlockCandidateQuery::send() {
 | 
				
			||||||
 | 
					  auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_generateBlockCandidate>(
 | 
				
			||||||
 | 
					      ton::create_tl_block_id_simple(ton::BlockId(wc_, shard_, seqno_)));
 | 
				
			||||||
 | 
					  td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GenerateBlockCandidateQuery::receive(td::BufferSlice data) {
 | 
				
			||||||
 | 
					  TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::db_candidate>(data.as_slice(), true),
 | 
				
			||||||
 | 
					                    "received incorrect answer: ");
 | 
				
			||||||
 | 
					  TRY_STATUS_PREFIX(td::write_file(file_, data.as_slice()), "failed to write block to file");
 | 
				
			||||||
 | 
					  td::TerminalIO::out() << "successfully written candidate to file\n";
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GetRequiredBlockCandidatesQuery::run() {
 | 
				
			||||||
 | 
					  TRY_STATUS(tokenizer_.check_endl());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GetRequiredBlockCandidatesQuery::send() {
 | 
				
			||||||
 | 
					  auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_getRequiredBlockCandidates>();
 | 
				
			||||||
 | 
					  td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status GetRequiredBlockCandidatesQuery::receive(td::BufferSlice data) {
 | 
				
			||||||
 | 
					  TRY_RESULT_PREFIX(
 | 
				
			||||||
 | 
					      f, ton::fetch_tl_object<ton::ton_api::engine_validator_requiredBlockCandidates>(data.as_slice(), true),
 | 
				
			||||||
 | 
					      "received incorrect answer: ");
 | 
				
			||||||
 | 
					  td::TerminalIO::out() << td::json_encode<std::string>(td::ToJson(*f), true);
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status ImportBlockCandidateQuery::run() {
 | 
				
			||||||
 | 
					  TRY_RESULT_ASSIGN(file_, tokenizer_.get_token<std::string>());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status ImportBlockCandidateQuery::send() {
 | 
				
			||||||
 | 
					  TRY_RESULT(data, td::read_file(file_));
 | 
				
			||||||
 | 
					  TRY_RESULT_PREFIX(candidate, ton::fetch_tl_object<ton::ton_api::db_candidate>(data.as_slice(), true),
 | 
				
			||||||
 | 
					                    "invalid file: ");
 | 
				
			||||||
 | 
					  auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_importBlockCandidate>(std::move(candidate));
 | 
				
			||||||
 | 
					  td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Status ImportBlockCandidateQuery::receive(td::BufferSlice data) {
 | 
				
			||||||
 | 
					  TRY_RESULT_PREFIX(f, ton::fetch_tl_object<ton::ton_api::engine_validator_success>(data.as_slice(), true),
 | 
				
			||||||
 | 
					                    "received incorrect answer: ");
 | 
				
			||||||
 | 
					  td::TerminalIO::out() << "successfully imported a block candidate\n";
 | 
				
			||||||
 | 
					  return td::Status::OK();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1092,6 +1092,74 @@ class GetValidatorSessionsInfoQuery : public Query {
 | 
				
			||||||
  std::string name() const override {
 | 
					  std::string name() const override {
 | 
				
			||||||
    return get_name();
 | 
					    return get_name();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GenerateBlockCandidateQuery : public Query {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  GenerateBlockCandidateQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
 | 
				
			||||||
 | 
					      : Query(console, std::move(tokenizer)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  td::Status run() override;
 | 
				
			||||||
 | 
					  td::Status send() override;
 | 
				
			||||||
 | 
					  td::Status receive(td::BufferSlice data) override;
 | 
				
			||||||
 | 
					  static std::string get_name() {
 | 
				
			||||||
 | 
					    return "genblock";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static std::string get_help() {
 | 
				
			||||||
 | 
					    return "genblock <wc> <shard> <seqno> <file>\t"
 | 
				
			||||||
 | 
					           "generate a block candidate for a given shard (seqno mush match the next seqno for the shard), "
 | 
				
			||||||
 | 
					           "candidate is saved to <file>";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  std::string name() const override {
 | 
				
			||||||
 | 
					    return get_name();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
 | 
					  td::int32 wc_;
 | 
				
			||||||
 | 
					  td::int64 shard_;
 | 
				
			||||||
 | 
					  td::int32 seqno_;
 | 
				
			||||||
 | 
					  std::string file_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GetRequiredBlockCandidatesQuery : public Query {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  GetRequiredBlockCandidatesQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
 | 
				
			||||||
 | 
					      : Query(console, std::move(tokenizer)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  td::Status run() override;
 | 
				
			||||||
 | 
					  td::Status send() override;
 | 
				
			||||||
 | 
					  td::Status receive(td::BufferSlice data) override;
 | 
				
			||||||
 | 
					  static std::string get_name() {
 | 
				
			||||||
 | 
					    return "getrequiredblockcandidates";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static std::string get_help() {
 | 
				
			||||||
 | 
					    return "getrequiredblockcandidates\t"
 | 
				
			||||||
 | 
					           "get a list of block candidates that the validator is currently waiting for";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  std::string name() const override {
 | 
				
			||||||
 | 
					    return get_name();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ImportBlockCandidateQuery : public Query {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  ImportBlockCandidateQuery(td::actor::ActorId<ValidatorEngineConsole> console, Tokenizer tokenizer)
 | 
				
			||||||
 | 
					      : Query(console, std::move(tokenizer)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  td::Status run() override;
 | 
				
			||||||
 | 
					  td::Status send() override;
 | 
				
			||||||
 | 
					  td::Status receive(td::BufferSlice data) override;
 | 
				
			||||||
 | 
					  static std::string get_name() {
 | 
				
			||||||
 | 
					    return "importblockcandidate";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static std::string get_help() {
 | 
				
			||||||
 | 
					    return "importblockcandidate <file>\t"
 | 
				
			||||||
 | 
					           "load a block candidate from a given file";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  std::string name() const override {
 | 
				
			||||||
 | 
					    return get_name();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  std::string file_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,6 +141,9 @@ void ValidatorEngineConsole::run() {
 | 
				
			||||||
  add_query_runner(std::make_unique<QueryRunnerImpl<ImportShardOverlayCertificateQuery>>());
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<ImportShardOverlayCertificateQuery>>());
 | 
				
			||||||
  add_query_runner(std::make_unique<QueryRunnerImpl<SignShardOverlayCertificateQuery>>());
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<SignShardOverlayCertificateQuery>>());
 | 
				
			||||||
  add_query_runner(std::make_unique<QueryRunnerImpl<GetValidatorSessionsInfoQuery>>());
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<GetValidatorSessionsInfoQuery>>());
 | 
				
			||||||
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<GenerateBlockCandidateQuery>>());
 | 
				
			||||||
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<GetRequiredBlockCandidatesQuery>>());
 | 
				
			||||||
 | 
					  add_query_runner(std::make_unique<QueryRunnerImpl<ImportBlockCandidateQuery>>());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
 | 
					bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3307,6 +3307,94 @@ void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_getValida
 | 
				
			||||||
                          std::move(P));
 | 
					                          std::move(P));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_generateBlockCandidate &query,
 | 
				
			||||||
 | 
					                                        td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
 | 
				
			||||||
 | 
					                                        td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
 | 
					  if (!(perm & ValidatorEnginePermissions::vep_default)) {
 | 
				
			||||||
 | 
					    promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "not authorized")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (validator_manager_.empty()) {
 | 
				
			||||||
 | 
					    promise.set_value(
 | 
				
			||||||
 | 
					        create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "validator manager not started")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ton::BlockId block_id = ton::create_block_id_simple(query.block_id_);
 | 
				
			||||||
 | 
					  td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::generate_block_candidate,
 | 
				
			||||||
 | 
					                          block_id, [promise = std::move(promise)](td::Result<ton::BlockCandidate> R) mutable {
 | 
				
			||||||
 | 
					                            if (R.is_ok()) {
 | 
				
			||||||
 | 
					                              auto block = R.move_as_ok();
 | 
				
			||||||
 | 
					                              auto result = ton::create_serialize_tl_object<ton::ton_api::db_candidate>(
 | 
				
			||||||
 | 
					                                  ton::PublicKey{ton::pubkeys::Ed25519{block.pubkey.as_bits256()}}.tl(),
 | 
				
			||||||
 | 
					                                  ton::create_tl_block_id(block.id), std::move(block.data),
 | 
				
			||||||
 | 
					                                  std::move(block.collated_data));
 | 
				
			||||||
 | 
					                              promise.set_result(std::move(result));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                              promise.set_value(create_control_query_error(R.move_as_error()));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_getRequiredBlockCandidates &query,
 | 
				
			||||||
 | 
					                                        td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
 | 
				
			||||||
 | 
					                                        td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
 | 
					  if (!(perm & ValidatorEnginePermissions::vep_default)) {
 | 
				
			||||||
 | 
					    promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "not authorized")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (validator_manager_.empty()) {
 | 
				
			||||||
 | 
					    promise.set_value(
 | 
				
			||||||
 | 
					        create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "validator manager not started")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  td::actor::send_closure(
 | 
				
			||||||
 | 
					      validator_manager_, &ton::validator::ValidatorManagerInterface::get_required_block_candidates,
 | 
				
			||||||
 | 
					      [promise = std::move(promise)](td::Result<std::vector<ton::BlockId>> R) mutable {
 | 
				
			||||||
 | 
					        if (R.is_ok()) {
 | 
				
			||||||
 | 
					          std::vector<ton::tl_object_ptr<ton::ton_api::tonNode_blockId>> block_ids;
 | 
				
			||||||
 | 
					          for (const ton::BlockId &block_id : R.move_as_ok()) {
 | 
				
			||||||
 | 
					            block_ids.push_back(ton::create_tl_block_id_simple(block_id));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          auto result = ton::create_serialize_tl_object<ton::ton_api::engine_validator_requiredBlockCandidates>(
 | 
				
			||||||
 | 
					              std::move(block_ids));
 | 
				
			||||||
 | 
					          promise.set_result(std::move(result));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          promise.set_value(create_control_query_error(R.move_as_error()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_importBlockCandidate &query,
 | 
				
			||||||
 | 
					                                        td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
 | 
				
			||||||
 | 
					                                        td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
 | 
					  if (!(perm & ValidatorEnginePermissions::vep_modify)) {
 | 
				
			||||||
 | 
					    promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "not authorized")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (validator_manager_.empty()) {
 | 
				
			||||||
 | 
					    promise.set_value(
 | 
				
			||||||
 | 
					        create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "validator manager not started")));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  auto collated_data_hash = td::sha256_bits256(query.block_->collated_data_);
 | 
				
			||||||
 | 
					  auto key = ton::PublicKey{query.block_->source_};
 | 
				
			||||||
 | 
					  auto e_key = ton::Ed25519_PublicKey{key.ed25519_value().raw()};
 | 
				
			||||||
 | 
					  ton::BlockCandidate candidate{e_key, ton::create_block_id(query.block_->id_), collated_data_hash,
 | 
				
			||||||
 | 
					                                std::move(query.block_->data_), std::move(query.block_->collated_data_)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::import_block_candidate,
 | 
				
			||||||
 | 
					                          std::move(candidate),
 | 
				
			||||||
 | 
					                          [promise = std::move(promise)](td::Result<td::Unit> R) mutable {
 | 
				
			||||||
 | 
					                            if (R.is_ok()) {
 | 
				
			||||||
 | 
					                              promise.set_result(ton::serialize_tl_object(
 | 
				
			||||||
 | 
					                                  ton::create_tl_object<ton::ton_api::engine_validator_success>(), true));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                              promise.set_value(create_control_query_error(R.move_as_error()));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorEngine::process_control_query(td::uint16 port, ton::adnl::AdnlNodeIdShort src,
 | 
					void ValidatorEngine::process_control_query(td::uint16 port, ton::adnl::AdnlNodeIdShort src,
 | 
				
			||||||
                                            ton::adnl::AdnlNodeIdShort dst, td::BufferSlice data,
 | 
					                                            ton::adnl::AdnlNodeIdShort dst, td::BufferSlice data,
 | 
				
			||||||
                                            td::Promise<td::BufferSlice> promise) {
 | 
					                                            td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -409,6 +409,12 @@ class ValidatorEngine : public td::actor::Actor {
 | 
				
			||||||
                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
					                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
  void run_control_query(ton::ton_api::engine_validator_getValidatorSessionsInfo &query, td::BufferSlice data,
 | 
					  void run_control_query(ton::ton_api::engine_validator_getValidatorSessionsInfo &query, td::BufferSlice data,
 | 
				
			||||||
                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
					                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
 | 
					  void run_control_query(ton::ton_api::engine_validator_generateBlockCandidate &query, td::BufferSlice data,
 | 
				
			||||||
 | 
					                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
 | 
					  void run_control_query(ton::ton_api::engine_validator_getRequiredBlockCandidates &query, td::BufferSlice data,
 | 
				
			||||||
 | 
					                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
 | 
					  void run_control_query(ton::ton_api::engine_validator_importBlockCandidate &query, td::BufferSlice data,
 | 
				
			||||||
 | 
					                         ton::PublicKeyHash src, td::uint32 perm, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
  template <class T>
 | 
					  template <class T>
 | 
				
			||||||
  void run_control_query(T &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
 | 
					  void run_control_query(T &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm,
 | 
				
			||||||
                         td::Promise<td::BufferSlice> promise) {
 | 
					                         td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -449,6 +449,7 @@ bool ValidateQuery::init_parse() {
 | 
				
			||||||
    return reject_query("after_merge value mismatch in block header");
 | 
					    return reject_query("after_merge value mismatch in block header");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  rand_seed_ = extra.rand_seed;
 | 
					  rand_seed_ = extra.rand_seed;
 | 
				
			||||||
 | 
					  created_by_ = extra.created_by;
 | 
				
			||||||
  if (created_by_ != extra.created_by) {
 | 
					  if (created_by_ != extra.created_by) {
 | 
				
			||||||
    return reject_query("block candidate "s + id_.to_str() + " has creator " + created_by_.to_hex() +
 | 
					    return reject_query("block candidate "s + id_.to_str() + " has creator " + created_by_.to_hex() +
 | 
				
			||||||
                        " but the block header contains different value " + extra.created_by.to_hex());
 | 
					                        " but the block header contains different value " + extra.created_by.to_hex());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,6 +169,8 @@ class ValidatorManager : public ValidatorManagerInterface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) = 0;
 | 
					  virtual void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void wait_block_candidate(BlockId block_id, td::Timestamp timeout, td::Promise<BlockCandidate> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static bool is_persistent_state(UnixTime ts, UnixTime prev_ts) {
 | 
					  static bool is_persistent_state(UnixTime ts, UnixTime prev_ts) {
 | 
				
			||||||
    return ts / (1 << 17) != prev_ts / (1 << 17);
 | 
					    return ts / (1 << 17) != prev_ts / (1 << 17);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -371,6 +371,18 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
 | 
					      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  void generate_block_candidate(BlockId block_id, td::Promise<BlockCandidate> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void get_required_block_candidates(td::Promise<std::vector<BlockId>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void import_block_candidate(BlockCandidate candidate, td::Promise<td::Unit> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void wait_block_candidate(BlockId block_id, td::Timestamp timeout, td::Promise<BlockCandidate> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  PublicKeyHash local_id_;
 | 
					  PublicKeyHash local_id_;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -430,6 +430,19 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
 | 
					      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  void generate_block_candidate(BlockId block_id, td::Promise<BlockCandidate> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void get_required_block_candidates(td::Promise<std::vector<BlockId>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void import_block_candidate(BlockCandidate candidate, td::Promise<td::Unit> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void wait_block_candidate(BlockId block_id, td::Timestamp timeout, td::Promise<BlockCandidate> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  td::Ref<ValidatorManagerOptions> opts_;
 | 
					  td::Ref<ValidatorManagerOptions> opts_;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2031,7 +2031,7 @@ td::actor::ActorOwn<ValidatorGroup> ValidatorManagerImpl::create_validator_group
 | 
				
			||||||
    auto G = td::actor::create_actor<ValidatorGroup>(
 | 
					    auto G = td::actor::create_actor<ValidatorGroup>(
 | 
				
			||||||
        "validatorgroup", shard, validator_id, session_id, validator_set, opts, keyring_, adnl_, rldp_, overlays_,
 | 
					        "validatorgroup", shard, validator_id, session_id, validator_set, opts, keyring_, adnl_, rldp_, overlays_,
 | 
				
			||||||
        db_root_, actor_id(this), init_session,
 | 
					        db_root_, actor_id(this), init_session,
 | 
				
			||||||
        opts_->check_unsafe_resync_allowed(validator_set->get_catchain_seqno()));
 | 
					        opts_->check_unsafe_resync_allowed(validator_set->get_catchain_seqno()), true);
 | 
				
			||||||
    return G;
 | 
					    return G;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2583,6 +2583,119 @@ void ValidatorManagerImpl::get_validator_sessions_info(
 | 
				
			||||||
  IntermediateData::step({std::move(groups), {}, std::move(promise)});
 | 
					  IntermediateData::step({std::move(groups), {}, std::move(promise)});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::generate_block_candidate(BlockId block_id, td::Promise<BlockCandidate> promise) {
 | 
				
			||||||
 | 
					  if (!block_id.is_valid_full()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error("invalid block id"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (last_masterchain_state_.is_null()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error("not started"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ShardIdFull shard_id = block_id.shard_full();
 | 
				
			||||||
 | 
					  std::vector<BlockIdExt> prev;
 | 
				
			||||||
 | 
					  auto shard = last_masterchain_state_->get_shard_from_config(shard_id);
 | 
				
			||||||
 | 
					  if (shard.not_null()) {
 | 
				
			||||||
 | 
					    if (shard->before_split()) {
 | 
				
			||||||
 | 
					      promise.set_error(td::Status::Error("shard is before_split"));
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (shard->before_merge()) {
 | 
				
			||||||
 | 
					      promise.set_error(td::Status::Error("shard is before_merge"));
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    prev.push_back(shard->top_block_id());
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    auto parent = shard_id.pfx_len() == 0 ? td::Ref<McShardHash>()
 | 
				
			||||||
 | 
					                                          : last_masterchain_state_->get_shard_from_config(shard_parent(shard_id));
 | 
				
			||||||
 | 
					    if (parent.not_null() && parent->before_split()) {
 | 
				
			||||||
 | 
					      prev.push_back(parent->top_block_id());
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      auto child_l = last_masterchain_state_->get_shard_from_config(shard_child(shard_id, true));
 | 
				
			||||||
 | 
					      auto child_r = last_masterchain_state_->get_shard_from_config(shard_child(shard_id, false));
 | 
				
			||||||
 | 
					      if (child_l.not_null() && child_r.not_null() && child_l->before_merge() && child_r->before_merge()) {
 | 
				
			||||||
 | 
					        prev.push_back(child_l->top_block_id());
 | 
				
			||||||
 | 
					        prev.push_back(child_r->top_block_id());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prev.empty()) {
 | 
				
			||||||
 | 
					      promise.set_error(td::Status::Error("no such shard"));
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BlockSeqno next_seqno = 0;
 | 
				
			||||||
 | 
					  for (const BlockIdExt& prev_id : prev) {
 | 
				
			||||||
 | 
					    next_seqno = std::max(next_seqno, prev_id.seqno() + 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (next_seqno != block_id.seqno) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error(PSTRING() << "seqno mismatch: asked for seqno " << block_id.seqno
 | 
				
			||||||
 | 
					                                                  << ", but actual next seqno is " << next_seqno));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Ed25519_PublicKey local_id{Bits256::zero()};
 | 
				
			||||||
 | 
					  td::Ref<ValidatorSet> validator_set = last_masterchain_state_->get_validator_set(shard_id);
 | 
				
			||||||
 | 
					  if (validator_set.is_null()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error("cannot get validator set"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  run_collate_query(shard_id, last_masterchain_state_->get_unix_time(), last_masterchain_block_id_, std::move(prev),
 | 
				
			||||||
 | 
					                    local_id, std::move(validator_set), actor_id(this), td::Timestamp::in(10.0), std::move(promise));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::get_required_block_candidates(td::Promise<std::vector<BlockId>> promise) {
 | 
				
			||||||
 | 
					  std::vector<BlockId> block_ids;
 | 
				
			||||||
 | 
					  for (const auto& p : pending_block_candidates_) {
 | 
				
			||||||
 | 
					    block_ids.push_back(p.first);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  promise.set_result(std::move(block_ids));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::import_block_candidate(BlockCandidate candidate, td::Promise<td::Unit> promise) {
 | 
				
			||||||
 | 
					  auto it = pending_block_candidates_.find(candidate.id.id);
 | 
				
			||||||
 | 
					  if (it != pending_block_candidates_.end()) {
 | 
				
			||||||
 | 
					    while (!it->second.empty()) {
 | 
				
			||||||
 | 
					      auto promise = std::move(it->second.back().first);
 | 
				
			||||||
 | 
					      it->second.pop_back();
 | 
				
			||||||
 | 
					      if (it->second.empty()) {
 | 
				
			||||||
 | 
					        promise.set_result(std::move(candidate));
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        promise.set_result(candidate.clone());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pending_block_candidates_.erase(it);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  promise.set_result(td::Unit());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::wait_block_candidate(BlockId block_id, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                                td::Promise<BlockCandidate> promise) {
 | 
				
			||||||
 | 
					  pending_block_candidates_[block_id].emplace_back(std::move(promise), timeout);
 | 
				
			||||||
 | 
					  delay_action([SelfId = actor_id(this), block_id, timeout]() {
 | 
				
			||||||
 | 
					    td::actor::send_closure(SelfId, &ValidatorManagerImpl::cleanup_old_pending_candidates, block_id, timeout);
 | 
				
			||||||
 | 
					  }, timeout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::cleanup_old_pending_candidates(BlockId block_id, td::Timestamp now) {
 | 
				
			||||||
 | 
					  auto it = pending_block_candidates_.find(block_id);
 | 
				
			||||||
 | 
					  if (it == pending_block_candidates_.end()) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  it->second.erase(std::remove_if(it->second.begin(), it->second.end(),
 | 
				
			||||||
 | 
					                                  [&](std::pair<td::Promise<BlockCandidate>, td::Timestamp> &p) {
 | 
				
			||||||
 | 
					                                    if (p.second.is_in_past(now)) {
 | 
				
			||||||
 | 
					                                      p.first.set_error(td::Status::Error(ErrorCode::timeout, "timeout"));
 | 
				
			||||||
 | 
					                                      return true;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                    return false;
 | 
				
			||||||
 | 
					                                  }),
 | 
				
			||||||
 | 
					                   it->second.end());
 | 
				
			||||||
 | 
					  if (it->second.empty()) {
 | 
				
			||||||
 | 
					    pending_block_candidates_.erase(it);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::actor::ActorOwn<ValidatorManagerInterface> ValidatorManagerFactory::create(
 | 
					td::actor::ActorOwn<ValidatorManagerInterface> ValidatorManagerFactory::create(
 | 
				
			||||||
    td::Ref<ValidatorManagerOptions> opts, std::string db_root, td::actor::ActorId<keyring::Keyring> keyring,
 | 
					    td::Ref<ValidatorManagerOptions> opts, std::string db_root, td::actor::ActorId<keyring::Keyring> keyring,
 | 
				
			||||||
    td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
 | 
					    td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -534,6 +534,11 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  void get_validator_sessions_info(
 | 
					  void get_validator_sessions_info(
 | 
				
			||||||
      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override;
 | 
					      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void generate_block_candidate(BlockId block_id, td::Promise<BlockCandidate> promise) override;
 | 
				
			||||||
 | 
					  void get_required_block_candidates(td::Promise<std::vector<BlockId>> promise) override;
 | 
				
			||||||
 | 
					  void import_block_candidate(BlockCandidate candidate, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
 | 
					  void wait_block_candidate(BlockId block_id, td::Timestamp timeout, td::Promise<BlockCandidate> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  td::Timestamp resend_shard_blocks_at_;
 | 
					  td::Timestamp resend_shard_blocks_at_;
 | 
				
			||||||
  td::Timestamp check_waiters_at_;
 | 
					  td::Timestamp check_waiters_at_;
 | 
				
			||||||
| 
						 | 
					@ -598,6 +603,9 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  std::map<BlockSeqno, WaitList<td::actor::Actor, td::Unit>> shard_client_waiters_;
 | 
					  std::map<BlockSeqno, WaitList<td::actor::Actor, td::Unit>> shard_client_waiters_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::map<BlockId, std::vector<std::pair<td::Promise<BlockCandidate>, td::Timestamp>>> pending_block_candidates_;
 | 
				
			||||||
 | 
					  void cleanup_old_pending_candidates(BlockId block_id, td::Timestamp now);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace validator
 | 
					}  // namespace validator
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,22 @@ void ValidatorGroup::generate_block_candidate(td::uint32 round_id, td::Promise<B
 | 
				
			||||||
    promise.set_error(td::Status::Error(ErrorCode::notready, "cannot collate block: group not started"));
 | 
					    promise.set_error(td::Status::Error(ErrorCode::notready, "cannot collate block: group not started"));
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (lite_mode_) {
 | 
				
			||||||
 | 
					    auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
 | 
					        [promise = std::move(promise),
 | 
				
			||||||
 | 
					         pubkey = Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}](td::Result<BlockCandidate> R) mutable {
 | 
				
			||||||
 | 
					          if (R.is_error()) {
 | 
				
			||||||
 | 
					            promise.set_error(R.move_as_error());
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            BlockCandidate candidate = R.move_as_ok();
 | 
				
			||||||
 | 
					            candidate.pubkey = pubkey;
 | 
				
			||||||
 | 
					            promise.set_result(std::move(candidate));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    td::actor::send_closure(manager_, &ValidatorManager::wait_block_candidate, create_next_block_id_simple(),
 | 
				
			||||||
 | 
					                            td::Timestamp::in(15.0), std::move(P));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  run_collate_query(shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_,
 | 
					  run_collate_query(shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_,
 | 
				
			||||||
                    Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}, validator_set_, manager_,
 | 
					                    Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}, validator_set_, manager_,
 | 
				
			||||||
                    td::Timestamp::in(10.0), std::move(promise));
 | 
					                    td::Timestamp::in(10.0), std::move(promise));
 | 
				
			||||||
| 
						 | 
					@ -79,7 +95,7 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat
 | 
				
			||||||
  VLOG(VALIDATOR_DEBUG) << "validating block candidate " << next_block_id;
 | 
					  VLOG(VALIDATOR_DEBUG) << "validating block candidate " << next_block_id;
 | 
				
			||||||
  block.id = next_block_id;
 | 
					  block.id = next_block_id;
 | 
				
			||||||
  run_validate_query(shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_, std::move(block), validator_set_,
 | 
					  run_validate_query(shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_, std::move(block), validator_set_,
 | 
				
			||||||
                     manager_, td::Timestamp::in(10.0), std::move(P));
 | 
					                     manager_, td::Timestamp::in(10.0), std::move(P), lite_mode_ ? ValidateMode::lite : 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash src, td::BufferSlice block_data,
 | 
					void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash src, td::BufferSlice block_data,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,7 @@ class ValidatorGroup : public td::actor::Actor {
 | 
				
			||||||
                 td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
 | 
					                 td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
 | 
				
			||||||
                 td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
 | 
					                 td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
 | 
				
			||||||
                 std::string db_root, td::actor::ActorId<ValidatorManager> validator_manager, bool create_session,
 | 
					                 std::string db_root, td::actor::ActorId<ValidatorManager> validator_manager, bool create_session,
 | 
				
			||||||
                 bool allow_unsafe_self_blocks_resync)
 | 
					                 bool allow_unsafe_self_blocks_resync, bool lite_mode = false)
 | 
				
			||||||
      : shard_(shard)
 | 
					      : shard_(shard)
 | 
				
			||||||
      , local_id_(std::move(local_id))
 | 
					      , local_id_(std::move(local_id))
 | 
				
			||||||
      , session_id_(session_id)
 | 
					      , session_id_(session_id)
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,8 @@ class ValidatorGroup : public td::actor::Actor {
 | 
				
			||||||
      , db_root_(std::move(db_root))
 | 
					      , db_root_(std::move(db_root))
 | 
				
			||||||
      , manager_(validator_manager)
 | 
					      , manager_(validator_manager)
 | 
				
			||||||
      , init_(create_session)
 | 
					      , init_(create_session)
 | 
				
			||||||
      , allow_unsafe_self_blocks_resync_(allow_unsafe_self_blocks_resync) {
 | 
					      , allow_unsafe_self_blocks_resync_(allow_unsafe_self_blocks_resync)
 | 
				
			||||||
 | 
					      , lite_mode_(lite_mode) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
| 
						 | 
					@ -118,6 +119,7 @@ class ValidatorGroup : public td::actor::Actor {
 | 
				
			||||||
  bool init_ = false;
 | 
					  bool init_ = false;
 | 
				
			||||||
  bool started_ = false;
 | 
					  bool started_ = false;
 | 
				
			||||||
  bool allow_unsafe_self_blocks_resync_;
 | 
					  bool allow_unsafe_self_blocks_resync_;
 | 
				
			||||||
 | 
					  bool lite_mode_ = false;
 | 
				
			||||||
  td::uint32 last_known_round_id_ = 0;
 | 
					  td::uint32 last_known_round_id_ = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,6 +216,10 @@ class ValidatorManagerInterface : public td::actor::Actor {
 | 
				
			||||||
  virtual void prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) = 0;
 | 
					  virtual void prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) = 0;
 | 
				
			||||||
  virtual void get_validator_sessions_info(
 | 
					  virtual void get_validator_sessions_info(
 | 
				
			||||||
      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) = 0;
 | 
					      td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void generate_block_candidate(BlockId block_id, td::Promise<BlockCandidate> promise) = 0;
 | 
				
			||||||
 | 
					  virtual void get_required_block_candidates(td::Promise<std::vector<BlockId>> promise) = 0;
 | 
				
			||||||
 | 
					  virtual void import_block_candidate(BlockCandidate candidate, td::Promise<td::Unit> promise) = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace validator
 | 
					}  // namespace validator
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue