mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add collator options (#1052)
* Set collator options from validator console * Fix compilation error in manager-disk * Defer all messages if out msg queue is too big * Fix checking queue size in collator --------- Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
c54f095c1b
commit
57f95cc282
22 changed files with 294 additions and 27 deletions
|
@ -801,7 +801,7 @@ size_limits_config#01 max_msg_bits:uint32 max_msg_cells:uint32 max_library_cells
|
||||||
max_ext_msg_size:uint32 max_ext_msg_depth:uint16 = SizeLimitsConfig;
|
max_ext_msg_size:uint32 max_ext_msg_depth:uint16 = SizeLimitsConfig;
|
||||||
size_limits_config_v2#02 max_msg_bits:uint32 max_msg_cells:uint32 max_library_cells:uint32 max_vm_data_depth:uint16
|
size_limits_config_v2#02 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 max_acc_state_cells:uint32 max_acc_state_bits:uint32
|
max_ext_msg_size:uint32 max_ext_msg_depth:uint16 max_acc_state_cells:uint32 max_acc_state_bits:uint32
|
||||||
max_acc_public_libraries:uint32 = SizeLimitsConfig;
|
max_acc_public_libraries:uint32 defer_out_queue_size_limit:uint32 = SizeLimitsConfig;
|
||||||
_ SizeLimitsConfig = ConfigParam 43;
|
_ SizeLimitsConfig = ConfigParam 43;
|
||||||
|
|
||||||
// key is [ wc:int32 addr:uint256 ]
|
// key is [ wc:int32 addr:uint256 ]
|
||||||
|
|
|
@ -1956,6 +1956,7 @@ td::Result<SizeLimitsConfig> Config::do_get_size_limits_config(td::Ref<vm::CellS
|
||||||
limits.max_acc_state_bits = rec.max_acc_state_bits;
|
limits.max_acc_state_bits = rec.max_acc_state_bits;
|
||||||
limits.max_acc_state_cells = rec.max_acc_state_cells;
|
limits.max_acc_state_cells = rec.max_acc_state_cells;
|
||||||
limits.max_acc_public_libraries = rec.max_acc_public_libraries;
|
limits.max_acc_public_libraries = rec.max_acc_public_libraries;
|
||||||
|
limits.defer_out_queue_size_limit = rec.defer_out_queue_size_limit;
|
||||||
};
|
};
|
||||||
gen::SizeLimitsConfig::Record_size_limits_config rec_v1;
|
gen::SizeLimitsConfig::Record_size_limits_config rec_v1;
|
||||||
gen::SizeLimitsConfig::Record_size_limits_config_v2 rec_v2;
|
gen::SizeLimitsConfig::Record_size_limits_config_v2 rec_v2;
|
||||||
|
|
|
@ -395,6 +395,7 @@ struct SizeLimitsConfig {
|
||||||
td::uint32 max_acc_state_cells = 1 << 16;
|
td::uint32 max_acc_state_cells = 1 << 16;
|
||||||
td::uint32 max_acc_state_bits = (1 << 16) * 1023;
|
td::uint32 max_acc_state_bits = (1 << 16) * 1023;
|
||||||
td::uint32 max_acc_public_libraries = 256;
|
td::uint32 max_acc_public_libraries = 256;
|
||||||
|
td::uint32 defer_out_queue_size_limit = 256;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CatchainValidatorsConfig {
|
struct CatchainValidatorsConfig {
|
||||||
|
|
|
@ -606,6 +606,11 @@ engine.validator.customOverlayNode adnl_id:int256 msg_sender:Bool msg_sender_pri
|
||||||
engine.validator.customOverlay name:string nodes:(vector engine.validator.customOverlayNode) = engine.validator.CustomOverlay;
|
engine.validator.customOverlay name:string nodes:(vector engine.validator.customOverlayNode) = engine.validator.CustomOverlay;
|
||||||
engine.validator.customOverlaysConfig overlays:(vector engine.validator.customOverlay) = engine.validator.CustomOverlaysConfig;
|
engine.validator.customOverlaysConfig overlays:(vector engine.validator.customOverlay) = engine.validator.CustomOverlaysConfig;
|
||||||
|
|
||||||
|
engine.validator.collatorOptions
|
||||||
|
deferring_enabled:Bool defer_messages_after:int defer_out_queue_size_limit:long
|
||||||
|
dispatch_phase_2_max_total:int dispatch_phase_3_max_total:int
|
||||||
|
dispatch_phase_2_max_per_initiator:int dispatch_phase_3_max_per_initiator:int = engine.validator.CollatorOptions;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
---types---
|
---types---
|
||||||
|
|
||||||
|
@ -715,6 +720,8 @@ engine.validator.showCustomOverlays = engine.validator.CustomOverlaysConfig;
|
||||||
|
|
||||||
engine.validator.setStateSerializerEnabled enabled:Bool = engine.validator.Success;
|
engine.validator.setStateSerializerEnabled enabled:Bool = engine.validator.Success;
|
||||||
|
|
||||||
|
engine.validator.setCollatorOptionsJson json:string = engine.validator.Success;
|
||||||
|
|
||||||
---types---
|
---types---
|
||||||
|
|
||||||
storage.pong = storage.Pong;
|
storage.pong = storage.Pong;
|
||||||
|
|
Binary file not shown.
|
@ -1203,3 +1203,42 @@ td::Status SetStateSerializerEnabledQuery::receive(td::BufferSlice data) {
|
||||||
td::TerminalIO::out() << "success\n";
|
td::TerminalIO::out() << "success\n";
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td::Status SetCollatorOptionsJsonQuery::run() {
|
||||||
|
TRY_RESULT_ASSIGN(file_name_, tokenizer_.get_token<std::string>());
|
||||||
|
TRY_STATUS(tokenizer_.check_endl());
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status SetCollatorOptionsJsonQuery::send() {
|
||||||
|
TRY_RESULT(data, td::read_file(file_name_));
|
||||||
|
auto b =
|
||||||
|
ton::create_serialize_tl_object<ton::ton_api::engine_validator_setCollatorOptionsJson>(data.as_slice().str());
|
||||||
|
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status SetCollatorOptionsJsonQuery::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() << "success\n";
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status ResetCollatorOptionsQuery::run() {
|
||||||
|
TRY_STATUS(tokenizer_.check_endl());
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status ResetCollatorOptionsQuery::send() {
|
||||||
|
auto b = ton::create_serialize_tl_object<ton::ton_api::engine_validator_setCollatorOptionsJson>("{}");
|
||||||
|
td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise());
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
td::Status ResetCollatorOptionsQuery::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() << "success\n";
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
|
@ -1229,3 +1229,44 @@ class SetStateSerializerEnabledQuery : public Query {
|
||||||
private:
|
private:
|
||||||
bool enabled_;
|
bool enabled_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SetCollatorOptionsJsonQuery : public Query {
|
||||||
|
public:
|
||||||
|
SetCollatorOptionsJsonQuery(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 "setcollatoroptionsjson";
|
||||||
|
}
|
||||||
|
static std::string get_help() {
|
||||||
|
return "setcollatoroptionsjson <filename>\tset collator options from file <filename>";
|
||||||
|
}
|
||||||
|
std::string name() const override {
|
||||||
|
return get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string file_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResetCollatorOptionsQuery : public Query {
|
||||||
|
public:
|
||||||
|
ResetCollatorOptionsQuery(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 "resetcollatoroptions";
|
||||||
|
}
|
||||||
|
static std::string get_help() {
|
||||||
|
return "resetcollatoroptions\tset collator options to default values";
|
||||||
|
}
|
||||||
|
std::string name() const override {
|
||||||
|
return get_name();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -147,6 +147,8 @@ void ValidatorEngineConsole::run() {
|
||||||
add_query_runner(std::make_unique<QueryRunnerImpl<DelCustomOverlayQuery>>());
|
add_query_runner(std::make_unique<QueryRunnerImpl<DelCustomOverlayQuery>>());
|
||||||
add_query_runner(std::make_unique<QueryRunnerImpl<ShowCustomOverlaysQuery>>());
|
add_query_runner(std::make_unique<QueryRunnerImpl<ShowCustomOverlaysQuery>>());
|
||||||
add_query_runner(std::make_unique<QueryRunnerImpl<SetStateSerializerEnabledQuery>>());
|
add_query_runner(std::make_unique<QueryRunnerImpl<SetStateSerializerEnabledQuery>>());
|
||||||
|
add_query_runner(std::make_unique<QueryRunnerImpl<SetCollatorOptionsJsonQuery>>());
|
||||||
|
add_query_runner(std::make_unique<QueryRunnerImpl<ResetCollatorOptionsQuery>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
@ -1823,6 +1823,7 @@ void ValidatorEngine::started_overlays() {
|
||||||
void ValidatorEngine::start_validator() {
|
void ValidatorEngine::start_validator() {
|
||||||
validator_options_.write().set_allow_blockchain_init(config_.validators.size() > 0);
|
validator_options_.write().set_allow_blockchain_init(config_.validators.size() > 0);
|
||||||
validator_options_.write().set_state_serializer_enabled(config_.state_serializer_enabled);
|
validator_options_.write().set_state_serializer_enabled(config_.state_serializer_enabled);
|
||||||
|
load_collator_options();
|
||||||
|
|
||||||
validator_manager_ = ton::validator::ValidatorManagerFactory::create(
|
validator_manager_ = ton::validator::ValidatorManagerFactory::create(
|
||||||
validator_options_, db_root_, keyring_.get(), adnl_.get(), rldp_.get(), overlay_manager_.get());
|
validator_options_, db_root_, keyring_.get(), adnl_.get(), rldp_.get(), overlay_manager_.get());
|
||||||
|
@ -2414,6 +2415,69 @@ void ValidatorEngine::del_custom_overlay_from_config(std::string name, td::Promi
|
||||||
promise.set_error(td::Status::Error(PSTRING() << "no overlay \"" << name << "\" in config"));
|
promise.set_error(td::Status::Error(PSTRING() << "no overlay \"" << name << "\" in config"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static td::Result<td::Ref<ton::validator::CollatorOptions>> parse_collator_options(td::MutableSlice json_str) {
|
||||||
|
td::Ref<ton::validator::CollatorOptions> ref{true};
|
||||||
|
ton::validator::CollatorOptions& opts = ref.write();
|
||||||
|
|
||||||
|
// Set default values (from_json leaves missing fields as is)
|
||||||
|
ton::ton_api::engine_validator_collatorOptions f;
|
||||||
|
f.deferring_enabled_ = opts.deferring_enabled;
|
||||||
|
f.defer_out_queue_size_limit_ = opts.defer_out_queue_size_limit;
|
||||||
|
f.defer_messages_after_ = opts.defer_messages_after;
|
||||||
|
f.dispatch_phase_2_max_total_ = opts.dispatch_phase_2_max_total;
|
||||||
|
f.dispatch_phase_3_max_total_ = opts.dispatch_phase_3_max_total;
|
||||||
|
f.dispatch_phase_2_max_per_initiator_ = opts.dispatch_phase_2_max_per_initiator;
|
||||||
|
f.dispatch_phase_3_max_per_initiator_ =
|
||||||
|
opts.dispatch_phase_3_max_per_initiator ? opts.dispatch_phase_3_max_per_initiator.value() : -1;
|
||||||
|
|
||||||
|
TRY_RESULT_PREFIX(json, td::json_decode(json_str), "failed to parse json: ");
|
||||||
|
TRY_STATUS_PREFIX(ton::ton_api::from_json(f, json.get_object()), "json does not fit TL scheme: ");
|
||||||
|
|
||||||
|
if (f.defer_messages_after_ <= 0) {
|
||||||
|
return td::Status::Error("defer_messages_after should be positive");
|
||||||
|
}
|
||||||
|
if (f.defer_out_queue_size_limit_ < 0) {
|
||||||
|
return td::Status::Error("defer_out_queue_size_limit should be non-negative");
|
||||||
|
}
|
||||||
|
if (f.dispatch_phase_2_max_total_ < 0) {
|
||||||
|
return td::Status::Error("dispatch_phase_2_max_total should be non-negative");
|
||||||
|
}
|
||||||
|
if (f.dispatch_phase_3_max_total_ < 0) {
|
||||||
|
return td::Status::Error("dispatch_phase_3_max_total should be non-negative");
|
||||||
|
}
|
||||||
|
if (f.dispatch_phase_2_max_per_initiator_ < 0) {
|
||||||
|
return td::Status::Error("dispatch_phase_2_max_per_initiator should be non-negative");
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.deferring_enabled = f.deferring_enabled_;
|
||||||
|
opts.defer_messages_after = f.defer_messages_after_;
|
||||||
|
opts.defer_out_queue_size_limit = f.defer_out_queue_size_limit_;
|
||||||
|
opts.dispatch_phase_2_max_total = f.dispatch_phase_2_max_total_;
|
||||||
|
opts.dispatch_phase_3_max_total = f.dispatch_phase_3_max_total_;
|
||||||
|
opts.dispatch_phase_2_max_per_initiator = f.dispatch_phase_2_max_per_initiator_;
|
||||||
|
if (f.dispatch_phase_3_max_per_initiator_ >= 0) {
|
||||||
|
opts.dispatch_phase_3_max_per_initiator = f.dispatch_phase_3_max_per_initiator_;
|
||||||
|
} else {
|
||||||
|
opts.dispatch_phase_3_max_per_initiator = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValidatorEngine::load_collator_options() {
|
||||||
|
auto r_data = td::read_file(collator_options_file());
|
||||||
|
if (r_data.is_error()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
td::BufferSlice data = r_data.move_as_ok();
|
||||||
|
auto r_collator_options = parse_collator_options(data.as_slice());
|
||||||
|
if (r_collator_options.is_error()) {
|
||||||
|
LOG(ERROR) << "Failed to read collator options from file: " << r_collator_options.move_as_error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validator_options_.write().set_collator_options(r_collator_options.move_as_ok());
|
||||||
|
}
|
||||||
|
|
||||||
void ValidatorEngine::check_key(ton::PublicKeyHash id, td::Promise<td::Unit> promise) {
|
void ValidatorEngine::check_key(ton::PublicKeyHash id, td::Promise<td::Unit> promise) {
|
||||||
if (keys_.count(id) == 1) {
|
if (keys_.count(id) == 1) {
|
||||||
promise.set_value(td::Unit());
|
promise.set_value(td::Unit());
|
||||||
|
@ -3684,6 +3748,33 @@ void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_setStateS
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_setCollatorOptionsJson &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 (!started_) {
|
||||||
|
promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "not started")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto r_collator_options = parse_collator_options(query.json_);
|
||||||
|
if (r_collator_options.is_error()) {
|
||||||
|
promise.set_value(create_control_query_error(r_collator_options.move_as_error_prefix("failed to parse json: ")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto S = td::write_file(collator_options_file(), query.json_);
|
||||||
|
if (S.is_error()) {
|
||||||
|
promise.set_value(create_control_query_error(r_collator_options.move_as_error_prefix("failed to write file: ")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validator_options_.write().set_collator_options(r_collator_options.move_as_ok());
|
||||||
|
td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::update_options,
|
||||||
|
validator_options_);
|
||||||
|
promise.set_value(ton::create_serialize_tl_object<ton::ton_api::engine_validator_success>());
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
@ -384,12 +384,16 @@ class ValidatorEngine : public td::actor::Actor {
|
||||||
std::string custom_overlays_config_file() const {
|
std::string custom_overlays_config_file() const {
|
||||||
return db_root_ + "/custom-overlays.json";
|
return db_root_ + "/custom-overlays.json";
|
||||||
}
|
}
|
||||||
|
std::string collator_options_file() const {
|
||||||
|
return db_root_ + "/collator-options.json";
|
||||||
|
}
|
||||||
|
|
||||||
void load_custom_overlays_config();
|
void load_custom_overlays_config();
|
||||||
td::Status write_custom_overlays_config();
|
td::Status write_custom_overlays_config();
|
||||||
void add_custom_overlay_to_config(
|
void add_custom_overlay_to_config(
|
||||||
ton::tl_object_ptr<ton::ton_api::engine_validator_customOverlay> overlay, td::Promise<td::Unit> promise);
|
ton::tl_object_ptr<ton::ton_api::engine_validator_customOverlay> overlay, td::Promise<td::Unit> promise);
|
||||||
void del_custom_overlay_from_config(std::string name, td::Promise<td::Unit> promise);
|
void del_custom_overlay_from_config(std::string name, td::Promise<td::Unit> promise);
|
||||||
|
void load_collator_options();
|
||||||
|
|
||||||
void check_key(ton::PublicKeyHash id, td::Promise<td::Unit> promise);
|
void check_key(ton::PublicKeyHash id, td::Promise<td::Unit> promise);
|
||||||
|
|
||||||
|
@ -477,6 +481,8 @@ 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_setStateSerializerEnabled &query, td::BufferSlice data,
|
void run_control_query(ton::ton_api::engine_validator_setStateSerializerEnabled &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_setCollatorOptionsJson &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) {
|
||||||
|
|
|
@ -80,8 +80,8 @@ void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_maste
|
||||||
td::Promise<ValidateCandidateResult> promise, bool is_fake = false);
|
td::Promise<ValidateCandidateResult> promise, bool is_fake = false);
|
||||||
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
||||||
std::vector<BlockIdExt> prev, Ed25519_PublicKey local_id, td::Ref<ValidatorSet> validator_set,
|
std::vector<BlockIdExt> prev, Ed25519_PublicKey local_id, td::Ref<ValidatorSet> validator_set,
|
||||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
td::Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager,
|
||||||
td::Promise<BlockCandidate> promise);
|
td::Timestamp timeout, td::Promise<BlockCandidate> promise);
|
||||||
void run_collate_hardfork(ShardIdFull shard, const BlockIdExt& min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
void run_collate_hardfork(ShardIdFull shard, const BlockIdExt& min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||||
td::Promise<BlockCandidate> promise);
|
td::Promise<BlockCandidate> promise);
|
||||||
|
|
|
@ -71,6 +71,7 @@ class Collator final : public td::actor::Actor {
|
||||||
std::vector<Ref<ShardState>> prev_states;
|
std::vector<Ref<ShardState>> prev_states;
|
||||||
std::vector<Ref<BlockData>> prev_block_data;
|
std::vector<Ref<BlockData>> prev_block_data;
|
||||||
Ed25519_PublicKey created_by_;
|
Ed25519_PublicKey created_by_;
|
||||||
|
Ref<CollatorOptions> collator_opts_;
|
||||||
Ref<ValidatorSet> validator_set_;
|
Ref<ValidatorSet> validator_set_;
|
||||||
td::actor::ActorId<ValidatorManager> manager;
|
td::actor::ActorId<ValidatorManager> manager;
|
||||||
td::Timestamp timeout;
|
td::Timestamp timeout;
|
||||||
|
@ -90,7 +91,8 @@ class Collator final : public td::actor::Actor {
|
||||||
public:
|
public:
|
||||||
Collator(ShardIdFull shard, bool is_hardfork, td::uint32 min_ts, BlockIdExt min_masterchain_block_id,
|
Collator(ShardIdFull shard, bool is_hardfork, td::uint32 min_ts, BlockIdExt min_masterchain_block_id,
|
||||||
std::vector<BlockIdExt> prev, Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
|
std::vector<BlockIdExt> prev, Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
|
||||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout, td::Promise<BlockCandidate> promise);
|
Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||||
|
td::Promise<BlockCandidate> promise);
|
||||||
~Collator() override = default;
|
~Collator() override = default;
|
||||||
bool is_busy() const {
|
bool is_busy() const {
|
||||||
return busy_;
|
return busy_;
|
||||||
|
@ -195,6 +197,7 @@ class Collator final : public td::actor::Actor {
|
||||||
std::unique_ptr<vm::AugmentedDictionary> in_msg_dict, out_msg_dict, out_msg_queue_, sibling_out_msg_queue_;
|
std::unique_ptr<vm::AugmentedDictionary> in_msg_dict, out_msg_dict, out_msg_queue_, sibling_out_msg_queue_;
|
||||||
std::map<StdSmcAddress, size_t> unprocessed_deferred_messages_; // number of messages from dispatch queue in new_msgs
|
std::map<StdSmcAddress, size_t> unprocessed_deferred_messages_; // number of messages from dispatch queue in new_msgs
|
||||||
td::uint64 out_msg_queue_size_ = 0;
|
td::uint64 out_msg_queue_size_ = 0;
|
||||||
|
td::uint64 old_out_msg_queue_size_ = 0;
|
||||||
bool have_out_msg_queue_size_in_state_ = false;
|
bool have_out_msg_queue_size_in_state_ = false;
|
||||||
std::unique_ptr<vm::Dictionary> ihr_pending;
|
std::unique_ptr<vm::Dictionary> ihr_pending;
|
||||||
std::shared_ptr<block::MsgProcessedUptoCollection> processed_upto_, sibling_processed_upto_;
|
std::shared_ptr<block::MsgProcessedUptoCollection> processed_upto_, sibling_processed_upto_;
|
||||||
|
@ -211,6 +214,8 @@ class Collator final : public td::actor::Actor {
|
||||||
unsigned dispatch_queue_ops_{0};
|
unsigned dispatch_queue_ops_{0};
|
||||||
std::map<StdSmcAddress, LogicalTime> last_dispatch_queue_emitted_lt_;
|
std::map<StdSmcAddress, LogicalTime> last_dispatch_queue_emitted_lt_;
|
||||||
bool have_unprocessed_account_dispatch_queue_ = true;
|
bool have_unprocessed_account_dispatch_queue_ = true;
|
||||||
|
td::uint64 defer_out_queue_size_limit_;
|
||||||
|
td::uint64 hard_defer_out_queue_size_limit_;
|
||||||
|
|
||||||
bool msg_metadata_enabled_ = false;
|
bool msg_metadata_enabled_ = false;
|
||||||
bool deferring_messages_enabled_ = false;
|
bool deferring_messages_enabled_ = false;
|
||||||
|
|
|
@ -50,7 +50,6 @@ static const td::uint32 SPLIT_MAX_QUEUE_SIZE = 100000;
|
||||||
static const td::uint32 MERGE_MAX_QUEUE_SIZE = 2047;
|
static const td::uint32 MERGE_MAX_QUEUE_SIZE = 2047;
|
||||||
static const td::uint32 SKIP_EXTERNALS_QUEUE_SIZE = 8000;
|
static const td::uint32 SKIP_EXTERNALS_QUEUE_SIZE = 8000;
|
||||||
static const int HIGH_PRIORITY_EXTERNAL = 10; // don't skip high priority externals when queue is big
|
static const int HIGH_PRIORITY_EXTERNAL = 10; // don't skip high priority externals when queue is big
|
||||||
static const int DEFER_MESSAGES_AFTER = 10; // 10'th and later messages from address will be deferred
|
|
||||||
|
|
||||||
#define DBG(__n) dbg(__n)&&
|
#define DBG(__n) dbg(__n)&&
|
||||||
#define DSTART int __dcnt = 0;
|
#define DSTART int __dcnt = 0;
|
||||||
|
@ -72,20 +71,22 @@ static inline bool dbg(int c) {
|
||||||
* @param prev A vector of BlockIdExt representing the previous blocks.
|
* @param prev A vector of BlockIdExt representing the previous blocks.
|
||||||
* @param validator_set A reference to the ValidatorSet.
|
* @param validator_set A reference to the ValidatorSet.
|
||||||
* @param collator_id The public key of the block creator.
|
* @param collator_id The public key of the block creator.
|
||||||
|
* @param collator_opts A reference to CollatorOptions.
|
||||||
* @param manager The ActorId of the ValidatorManager.
|
* @param manager The ActorId of the ValidatorManager.
|
||||||
* @param timeout The timeout for the collator.
|
* @param timeout The timeout for the collator.
|
||||||
* @param promise The promise to return the result.
|
* @param promise The promise to return the result.
|
||||||
*/
|
*/
|
||||||
Collator::Collator(ShardIdFull shard, bool is_hardfork, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
Collator::Collator(ShardIdFull shard, bool is_hardfork, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||||
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
|
std::vector<BlockIdExt> prev, Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
|
||||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager,
|
||||||
td::Promise<BlockCandidate> promise)
|
td::Timestamp timeout, td::Promise<BlockCandidate> promise)
|
||||||
: shard_(shard)
|
: shard_(shard)
|
||||||
, is_hardfork_(is_hardfork)
|
, is_hardfork_(is_hardfork)
|
||||||
, min_ts(min_ts)
|
, min_ts(min_ts)
|
||||||
, min_mc_block_id{min_masterchain_block_id}
|
, min_mc_block_id{min_masterchain_block_id}
|
||||||
, prev_blocks(std::move(prev))
|
, prev_blocks(std::move(prev))
|
||||||
, created_by_(collator_id)
|
, created_by_(collator_id)
|
||||||
|
, collator_opts_(collator_opts)
|
||||||
, validator_set_(std::move(validator_set))
|
, validator_set_(std::move(validator_set))
|
||||||
, manager(manager)
|
, manager(manager)
|
||||||
, timeout(timeout)
|
, timeout(timeout)
|
||||||
|
@ -1786,6 +1787,7 @@ bool Collator::try_collate() {
|
||||||
last_proc_int_msg_.second.set_zero();
|
last_proc_int_msg_.second.set_zero();
|
||||||
first_unproc_int_msg_.first = ~0ULL;
|
first_unproc_int_msg_.first = ~0ULL;
|
||||||
first_unproc_int_msg_.second.set_ones();
|
first_unproc_int_msg_.second.set_ones();
|
||||||
|
old_out_msg_queue_size_ = out_msg_queue_size_;
|
||||||
if (is_masterchain()) {
|
if (is_masterchain()) {
|
||||||
LOG(DEBUG) << "getting the list of special smart contracts";
|
LOG(DEBUG) << "getting the list of special smart contracts";
|
||||||
auto res = config_->get_special_smartcontracts();
|
auto res = config_->get_special_smartcontracts();
|
||||||
|
@ -1970,6 +1972,10 @@ bool Collator::fetch_config_params() {
|
||||||
return fatal_error(res.move_as_error());
|
return fatal_error(res.move_as_error());
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
defer_out_queue_size_limit_ = std::max<td::uint64>(collator_opts_->defer_out_queue_size_limit,
|
||||||
|
compute_phase_cfg_.size_limits.defer_out_queue_size_limit);
|
||||||
|
// This one is checked in validate-query
|
||||||
|
hard_defer_out_queue_size_limit_ = compute_phase_cfg_.size_limits.defer_out_queue_size_limit;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3053,8 +3059,10 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
|
||||||
bool is_special_account = is_masterchain() && config_->is_special_smartcontract(src_addr);
|
bool is_special_account = is_masterchain() && config_->is_special_smartcontract(src_addr);
|
||||||
bool defer = false;
|
bool defer = false;
|
||||||
if (!from_dispatch_queue) {
|
if (!from_dispatch_queue) {
|
||||||
if (deferring_messages_enabled_ && !is_special && !is_special_account && msg.msg_idx != 0) {
|
if (deferring_messages_enabled_ && collator_opts_->deferring_enabled && !is_special && !is_special_account &&
|
||||||
if (++sender_generated_messages_count_[src_addr] >= DEFER_MESSAGES_AFTER) {
|
msg.msg_idx != 0) {
|
||||||
|
if (++sender_generated_messages_count_[src_addr] >= collator_opts_->defer_messages_after ||
|
||||||
|
out_msg_queue_size_ > defer_out_queue_size_limit_) {
|
||||||
defer = true;
|
defer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3626,18 +3634,24 @@ int Collator::process_external_message(Ref<vm::Cell> msg) {
|
||||||
* @returns True if the processing was successful, false otherwise.
|
* @returns True if the processing was successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool Collator::process_dispatch_queue() {
|
bool Collator::process_dispatch_queue() {
|
||||||
|
if (out_msg_queue_size_ > defer_out_queue_size_limit_ && old_out_msg_queue_size_ > hard_defer_out_queue_size_limit_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
have_unprocessed_account_dispatch_queue_ = true;
|
have_unprocessed_account_dispatch_queue_ = true;
|
||||||
size_t max_total_count[3] = {1 << 30, 150, 150};
|
size_t max_total_count[3] = {1 << 30, collator_opts_->dispatch_phase_2_max_total,
|
||||||
size_t max_per_initiator[3] = {1 << 30, 20, 0};
|
collator_opts_->dispatch_phase_3_max_total};
|
||||||
if (out_msg_queue_size_ <= 256) {
|
size_t max_per_initiator[3] = {1 << 30, collator_opts_->dispatch_phase_2_max_per_initiator, 0};
|
||||||
|
if (collator_opts_->dispatch_phase_3_max_per_initiator) {
|
||||||
|
max_per_initiator[2] = collator_opts_->dispatch_phase_3_max_per_initiator.value();
|
||||||
|
} else if (out_msg_queue_size_ <= 256) {
|
||||||
max_per_initiator[2] = 10;
|
max_per_initiator[2] = 10;
|
||||||
} else if (out_msg_queue_size_ <= 512) {
|
} else if (out_msg_queue_size_ <= 512) {
|
||||||
max_per_initiator[2] = 2;
|
max_per_initiator[2] = 2;
|
||||||
} else if (out_msg_queue_size_ <= 2048) {
|
} else if (out_msg_queue_size_ <= 1500) {
|
||||||
max_per_initiator[2] = 1;
|
max_per_initiator[2] = 1;
|
||||||
}
|
}
|
||||||
for (int iter = 0; iter < 3; ++iter) {
|
for (int iter = 0; iter < 3; ++iter) {
|
||||||
if (max_per_initiator[iter] == 0) {
|
if (max_per_initiator[iter] == 0 || max_total_count[iter] == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
vm::AugmentedDictionary cur_dispatch_queue{dispatch_queue_->get_root(), 256, block::tlb::aug_DispatchQueue};
|
vm::AugmentedDictionary cur_dispatch_queue{dispatch_queue_->get_root(), 256, block::tlb::aug_DispatchQueue};
|
||||||
|
@ -3676,7 +3690,8 @@ bool Collator::process_dispatch_queue() {
|
||||||
|
|
||||||
// Remove message from DispatchQueue
|
// Remove message from DispatchQueue
|
||||||
bool ok;
|
bool ok;
|
||||||
if (iter == 0 || (iter == 1 && sender_generated_messages_count_[src_addr] >= DEFER_MESSAGES_AFTER)) {
|
if (iter == 0 ||
|
||||||
|
(iter == 1 && sender_generated_messages_count_[src_addr] >= collator_opts_->defer_messages_after)) {
|
||||||
ok = cur_dispatch_queue.lookup_delete(src_addr).not_null();
|
ok = cur_dispatch_queue.lookup_delete(src_addr).not_null();
|
||||||
} else {
|
} else {
|
||||||
dict.lookup_delete(key);
|
dict.lookup_delete(key);
|
||||||
|
|
|
@ -213,8 +213,8 @@ void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_maste
|
||||||
|
|
||||||
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
||||||
std::vector<BlockIdExt> prev, Ed25519_PublicKey collator_id, td::Ref<ValidatorSet> validator_set,
|
std::vector<BlockIdExt> prev, Ed25519_PublicKey collator_id, td::Ref<ValidatorSet> validator_set,
|
||||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
td::Ref<CollatorOptions> collator_opts, td::actor::ActorId<ValidatorManager> manager,
|
||||||
td::Promise<BlockCandidate> promise) {
|
td::Timestamp timeout, td::Promise<BlockCandidate> promise) {
|
||||||
BlockSeqno seqno = 0;
|
BlockSeqno seqno = 0;
|
||||||
for (auto& p : prev) {
|
for (auto& p : prev) {
|
||||||
if (p.seqno() > seqno) {
|
if (p.seqno() > seqno) {
|
||||||
|
@ -223,7 +223,8 @@ void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& m
|
||||||
}
|
}
|
||||||
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, false,
|
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, false,
|
||||||
min_ts, min_masterchain_block_id, std::move(prev), std::move(validator_set),
|
min_ts, min_masterchain_block_id, std::move(prev), std::move(validator_set),
|
||||||
collator_id, std::move(manager), timeout, std::move(promise))
|
collator_id, std::move(collator_opts), std::move(manager), timeout,
|
||||||
|
std::move(promise))
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +239,8 @@ void run_collate_hardfork(ShardIdFull shard, const BlockIdExt& min_masterchain_b
|
||||||
}
|
}
|
||||||
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, true, 0,
|
td::actor::create_actor<Collator>(PSTRING() << "collate" << shard.to_str() << ":" << (seqno + 1), shard, true, 0,
|
||||||
min_masterchain_block_id, std::move(prev), td::Ref<ValidatorSet>{},
|
min_masterchain_block_id, std::move(prev), td::Ref<ValidatorSet>{},
|
||||||
Ed25519_PublicKey{Bits256::zero()}, std::move(manager), timeout, std::move(promise))
|
Ed25519_PublicKey{Bits256::zero()}, td::Ref<CollatorOptions>{true},
|
||||||
|
std::move(manager), timeout, std::move(promise))
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3405,7 +3405,7 @@ bool ValidateQuery::check_account_dispatch_queue_update(td::Bits256 addr, Ref<vm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (old_dict_size > 0 && max_removed_lt == 0) {
|
if (old_dict_size > 0 && max_removed_lt == 0) {
|
||||||
have_unprocessed_account_dispatch_queue_ = true;
|
++processed_account_dispatch_queues_;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3432,6 +3432,27 @@ bool ValidateQuery::unpack_dispatch_queue_update() {
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return reject_query("invalid DispatchQueue dictionary in the new state");
|
return reject_query("invalid DispatchQueue dictionary in the new state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_out_msg_queue_size_ <= compute_phase_cfg_.size_limits.defer_out_queue_size_limit) {
|
||||||
|
// Check that at least one message was taken from each AccountDispatchQueue
|
||||||
|
try {
|
||||||
|
have_unprocessed_account_dispatch_queue_ = false;
|
||||||
|
td::uint64 total_account_dispatch_queues = 0;
|
||||||
|
ps_.dispatch_queue_->check_for_each([&](Ref<vm::CellSlice>, td::ConstBitPtr, int n) -> bool {
|
||||||
|
assert(n == 352);
|
||||||
|
++total_account_dispatch_queues;
|
||||||
|
if (total_account_dispatch_queues > processed_account_dispatch_queues_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
have_unprocessed_account_dispatch_queue_ =
|
||||||
|
(total_account_dispatch_queues != processed_account_dispatch_queues_);
|
||||||
|
} catch (vm::VmVirtError&) {
|
||||||
|
// VmVirtError can happen if we have only a proof of ShardState
|
||||||
|
have_unprocessed_account_dispatch_queue_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (vm::VmError& err) {
|
} catch (vm::VmError& err) {
|
||||||
return reject_query("invalid DispatchQueue dictionary difference between the old and the new state: "s +
|
return reject_query("invalid DispatchQueue dictionary difference between the old and the new state: "s +
|
||||||
err.get_msg());
|
err.get_msg());
|
||||||
|
@ -3694,7 +3715,8 @@ bool ValidateQuery::check_in_msg(td::ConstBitPtr key, Ref<vm::CellSlice> in_msg)
|
||||||
}
|
}
|
||||||
if (have_unprocessed_account_dispatch_queue_ && tag != block::gen::InMsg::msg_import_ext &&
|
if (have_unprocessed_account_dispatch_queue_ && tag != block::gen::InMsg::msg_import_ext &&
|
||||||
tag != block::gen::InMsg::msg_import_deferred_tr && tag != block::gen::InMsg::msg_import_deferred_fin) {
|
tag != block::gen::InMsg::msg_import_deferred_tr && tag != block::gen::InMsg::msg_import_deferred_fin) {
|
||||||
// Collator is requeired to take at least one message from each AccountDispatchQueue (unless the block is full)
|
// Collator is requeired to take at least one message from each AccountDispatchQueue
|
||||||
|
// (unless the block is full or unless out_msg_queue_size is big)
|
||||||
// If some AccountDispatchQueue is unporcessed then it's not allowed to import other messages except for externals
|
// If some AccountDispatchQueue is unporcessed then it's not allowed to import other messages except for externals
|
||||||
return reject_query("required DispatchQueue processing is not done, but some other internal messages are imported");
|
return reject_query("required DispatchQueue processing is not done, but some other internal messages are imported");
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,7 @@ class ValidateQuery : public td::actor::Actor {
|
||||||
bool deferring_messages_enabled_ = false;
|
bool deferring_messages_enabled_ = false;
|
||||||
bool store_out_msg_queue_size_ = false;
|
bool store_out_msg_queue_size_ = false;
|
||||||
|
|
||||||
|
td::uint64 processed_account_dispatch_queues_ = 0;
|
||||||
bool have_unprocessed_account_dispatch_queue_ = false;
|
bool have_unprocessed_account_dispatch_queue_ = false;
|
||||||
|
|
||||||
td::PerfWarningTimer perf_timer_;
|
td::PerfWarningTimer perf_timer_;
|
||||||
|
|
|
@ -128,8 +128,8 @@ void ValidatorManagerImpl::sync_complete(td::Promise<td::Unit> promise) {
|
||||||
}
|
}
|
||||||
Ed25519_PublicKey created_by{td::Bits256::zero()};
|
Ed25519_PublicKey created_by{td::Bits256::zero()};
|
||||||
td::as<td::uint32>(created_by.as_bits256().data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
|
td::as<td::uint32>(created_by.as_bits256().data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
|
||||||
run_collate_query(shard_id, 0, last_masterchain_block_id_, prev, created_by, val_set, actor_id(this),
|
run_collate_query(shard_id, 0, last_masterchain_block_id_, prev, created_by, val_set, td::Ref<CollatorOptions>{true},
|
||||||
td::Timestamp::in(10.0), std::move(P));
|
actor_id(this), td::Timestamp::in(10.0), std::move(P));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidatorManagerImpl::validate_fake(BlockCandidate candidate, std::vector<BlockIdExt> prev, BlockIdExt last,
|
void ValidatorManagerImpl::validate_fake(BlockCandidate candidate, std::vector<BlockIdExt> prev, BlockIdExt last,
|
||||||
|
|
|
@ -3133,10 +3133,16 @@ void ValidatorManagerImpl::get_validator_groups_info_for_litequery(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidatorManagerImpl::update_options(td::Ref<ValidatorManagerOptions> opts) {
|
void ValidatorManagerImpl::update_options(td::Ref<ValidatorManagerOptions> opts) {
|
||||||
// Currently options can be updated only to change state_serializer_enabled flag
|
// Currently options can be updated only to change state_serializer_enabled flag and collator_options
|
||||||
if (!serializer_.empty()) {
|
if (!serializer_.empty()) {
|
||||||
td::actor::send_closure(serializer_, &AsyncStateSerializer::update_options, opts);
|
td::actor::send_closure(serializer_, &AsyncStateSerializer::update_options, opts);
|
||||||
}
|
}
|
||||||
|
for (auto &group : validator_groups_) {
|
||||||
|
td::actor::send_closure(group.second.actor, &ValidatorGroup::update_options, opts);
|
||||||
|
}
|
||||||
|
for (auto &group : next_validator_groups_) {
|
||||||
|
td::actor::send_closure(group.second.actor, &ValidatorGroup::update_options, opts);
|
||||||
|
}
|
||||||
opts_ = std::move(opts);
|
opts_ = std::move(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ void ValidatorGroup::generate_block_candidate(
|
||||||
}));
|
}));
|
||||||
run_collate_query(
|
run_collate_query(
|
||||||
shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_,
|
shard_, min_ts_, min_masterchain_block_id_, prev_block_ids_,
|
||||||
Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}, validator_set_, manager_, td::Timestamp::in(10.0),
|
Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}, validator_set_, opts_->get_collator_options(), manager_,
|
||||||
[SelfId = actor_id(this), cache = cached_collated_block_](td::Result<BlockCandidate> R) {
|
td::Timestamp::in(10.0), [SelfId = actor_id(this), cache = cached_collated_block_](td::Result<BlockCandidate> R) {
|
||||||
td::actor::send_closure(SelfId, &ValidatorGroup::generated_block_candidate, std::move(cache), std::move(R));
|
td::actor::send_closure(SelfId, &ValidatorGroup::generated_block_candidate, std::move(cache), std::move(R));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,10 @@ class ValidatorGroup : public td::actor::Actor {
|
||||||
void get_validator_group_info_for_litequery(
|
void get_validator_group_info_for_litequery(
|
||||||
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroupInfo>> promise);
|
td::Promise<tl_object_ptr<lite_api::liteServer_nonfinal_validatorGroupInfo>> promise);
|
||||||
|
|
||||||
|
void update_options(td::Ref<ValidatorManagerOptions> opts) {
|
||||||
|
opts_ = std::move(opts);
|
||||||
|
}
|
||||||
|
|
||||||
ValidatorGroup(ShardIdFull shard, PublicKeyHash local_id, ValidatorSessionId session_id,
|
ValidatorGroup(ShardIdFull shard, PublicKeyHash local_id, ValidatorSessionId session_id,
|
||||||
td::Ref<ValidatorSet> validator_set, validatorsession::ValidatorSessionOptions config,
|
td::Ref<ValidatorSet> validator_set, validatorsession::ValidatorSessionOptions config,
|
||||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||||
|
|
|
@ -144,6 +144,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
bool get_state_serializer_enabled() const override {
|
bool get_state_serializer_enabled() const override {
|
||||||
return state_serializer_enabled_;
|
return state_serializer_enabled_;
|
||||||
}
|
}
|
||||||
|
td::Ref<CollatorOptions> get_collator_options() const override {
|
||||||
|
return collator_options_;
|
||||||
|
}
|
||||||
|
|
||||||
void set_zero_block_id(BlockIdExt block_id) override {
|
void set_zero_block_id(BlockIdExt block_id) override {
|
||||||
zero_block_id_ = block_id;
|
zero_block_id_ = block_id;
|
||||||
|
@ -227,6 +230,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
void set_state_serializer_enabled(bool value) override {
|
void set_state_serializer_enabled(bool value) override {
|
||||||
state_serializer_enabled_ = value;
|
state_serializer_enabled_ = value;
|
||||||
}
|
}
|
||||||
|
void set_collator_options(td::Ref<CollatorOptions> value) override {
|
||||||
|
collator_options_ = std::move(value);
|
||||||
|
}
|
||||||
|
|
||||||
ValidatorManagerOptionsImpl *make_copy() const override {
|
ValidatorManagerOptionsImpl *make_copy() const override {
|
||||||
return new ValidatorManagerOptionsImpl(*this);
|
return new ValidatorManagerOptionsImpl(*this);
|
||||||
|
@ -279,6 +285,7 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
|
||||||
bool celldb_preload_all_ = false;
|
bool celldb_preload_all_ = false;
|
||||||
td::optional<double> catchain_max_block_delay_;
|
td::optional<double> catchain_max_block_delay_;
|
||||||
bool state_serializer_enabled_ = true;
|
bool state_serializer_enabled_ = true;
|
||||||
|
td::Ref<CollatorOptions> collator_options_{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace validator
|
} // namespace validator
|
||||||
|
|
|
@ -51,6 +51,21 @@ struct PerfTimerStats {
|
||||||
std::deque<std::pair<double, double>> stats; // <Time::now(), duration>
|
std::deque<std::pair<double, double>> stats; // <Time::now(), duration>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CollatorOptions : public td::CntObject {
|
||||||
|
bool deferring_enabled = true;
|
||||||
|
|
||||||
|
// Defer messages from account after Xth message in block (excluding first messages from transactions)
|
||||||
|
td::uint32 defer_messages_after = 10;
|
||||||
|
// Defer all messages if out msg queue size is greater than X (excluding first messages from transactions)
|
||||||
|
td::uint64 defer_out_queue_size_limit = 2048;
|
||||||
|
|
||||||
|
// See Collator::process_dispatch_queue
|
||||||
|
td::uint32 dispatch_phase_2_max_total = 150;
|
||||||
|
td::uint32 dispatch_phase_3_max_total = 150;
|
||||||
|
td::uint32 dispatch_phase_2_max_per_initiator = 20;
|
||||||
|
td::optional<td::uint32> dispatch_phase_3_max_per_initiator; // Default - depends on out msg queue size
|
||||||
|
};
|
||||||
|
|
||||||
struct ValidatorManagerOptions : public td::CntObject {
|
struct ValidatorManagerOptions : public td::CntObject {
|
||||||
public:
|
public:
|
||||||
enum class ShardCheckMode { m_monitor, m_validate };
|
enum class ShardCheckMode { m_monitor, m_validate };
|
||||||
|
@ -91,6 +106,7 @@ struct ValidatorManagerOptions : public td::CntObject {
|
||||||
virtual bool get_celldb_preload_all() const = 0;
|
virtual bool get_celldb_preload_all() const = 0;
|
||||||
virtual td::optional<double> get_catchain_max_block_delay() const = 0;
|
virtual td::optional<double> get_catchain_max_block_delay() const = 0;
|
||||||
virtual bool get_state_serializer_enabled() const = 0;
|
virtual bool get_state_serializer_enabled() const = 0;
|
||||||
|
virtual td::Ref<CollatorOptions> get_collator_options() const = 0;
|
||||||
|
|
||||||
virtual void set_zero_block_id(BlockIdExt block_id) = 0;
|
virtual void set_zero_block_id(BlockIdExt block_id) = 0;
|
||||||
virtual void set_init_block_id(BlockIdExt block_id) = 0;
|
virtual void set_init_block_id(BlockIdExt block_id) = 0;
|
||||||
|
@ -120,6 +136,7 @@ struct ValidatorManagerOptions : public td::CntObject {
|
||||||
virtual void set_celldb_preload_all(bool value) = 0;
|
virtual void set_celldb_preload_all(bool value) = 0;
|
||||||
virtual void set_catchain_max_block_delay(double value) = 0;
|
virtual void set_catchain_max_block_delay(double value) = 0;
|
||||||
virtual void set_state_serializer_enabled(bool value) = 0;
|
virtual void set_state_serializer_enabled(bool value) = 0;
|
||||||
|
virtual void set_collator_options(td::Ref<CollatorOptions> value) = 0;
|
||||||
|
|
||||||
static td::Ref<ValidatorManagerOptions> create(
|
static td::Ref<ValidatorManagerOptions> create(
|
||||||
BlockIdExt zero_block_id, BlockIdExt init_block_id,
|
BlockIdExt zero_block_id, BlockIdExt init_block_id,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue