mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
remove debug checks to improve performance under load on weak validators
This commit is contained in:
parent
b73b057e08
commit
7efb345e3d
5 changed files with 138 additions and 4 deletions
|
@ -119,6 +119,36 @@ builder pack_complaint(int validator_pubkey, cell description, int severity, int
|
|||
return (cs~load_int(32), cs~load_int(32), cs~load_int(32), cs.preload_int(32));
|
||||
}
|
||||
|
||||
;; next three functions return information about current validator set (config param #34)
|
||||
;; they are borrowed from config-code.fc
|
||||
(cell, int, cell) get_current_vset() inline_ref {
|
||||
var vset = config_param(34);
|
||||
var cs = begin_parse(vset);
|
||||
;; validators_ext#12 utime_since:uint32 utime_until:uint32
|
||||
;; total:(## 16) main:(## 16) { main <= total } { main >= 1 }
|
||||
;; total_weight:uint64
|
||||
throw_unless(40, cs~load_uint(8) == 0x12);
|
||||
cs~skip_bits(32 + 32 + 16 + 16);
|
||||
var (total_weight, dict) = (cs~load_uint(64), cs~load_dict());
|
||||
cs.end_parse();
|
||||
return (vset, total_weight, dict);
|
||||
}
|
||||
|
||||
(slice, int) get_validator_descr(int idx) inline_ref {
|
||||
var (vset, total_weight, dict) = get_current_vset();
|
||||
var (value, _) = dict.udict_get?(16, idx);
|
||||
return (value, total_weight);
|
||||
}
|
||||
|
||||
(int, int) unpack_validator_descr(slice cs) inline {
|
||||
;; ed25519_pubkey#8e81278a pubkey:bits256 = SigPubKey;
|
||||
;; validator#53 public_key:SigPubKey weight:uint64 = ValidatorDescr;
|
||||
;; validator_addr#73 public_key:SigPubKey weight:uint64 adnl_addr:bits256 = ValidatorDescr;
|
||||
throw_unless(41, (cs~load_uint(8) & ~ 0x20) == 0x53);
|
||||
throw_unless(41, cs~load_uint(32) == 0x8e81278a);
|
||||
return (cs~load_uint(256), cs~load_uint(64));
|
||||
}
|
||||
|
||||
() send_message_back(addr, ans_tag, query_id, body, grams, mode) impure inline_ref {
|
||||
;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000
|
||||
var msg = begin_cell()
|
||||
|
@ -446,6 +476,7 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
ifnot (f) { ;; no such validator, cannot complain
|
||||
return -6;
|
||||
}
|
||||
fs~skip_bits(256 + 64); ;; addr weight
|
||||
var validator_stake = fs~load_grams();
|
||||
int fine = suggested_fine + muldiv(validator_stake, suggested_fine_part, 1 << 32);
|
||||
if (fine > validator_stake) { ;; validator's stake is less than suggested fine
|
||||
|
@ -467,7 +498,84 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
;; next line can be commented, but it saves a lot of stack manipulations
|
||||
var (elect, credits, _, grams, active_id, active_hash) = load_data();
|
||||
store_data(elect, credits, past_elections, grams, active_id, active_hash);
|
||||
return 0;
|
||||
return paid;
|
||||
}
|
||||
|
||||
(cell, cell, int) punish(credits, frozen, complaint) inline_ref {
|
||||
var (validator_pubkey, description, severity, reward_addr, paid, suggested_fine, suggested_fine_part) = complaint.begin_parse().unpack_complaint();
|
||||
var (cs, f) = frozen.udict_get?(256, validator_pubkey);
|
||||
ifnot (f) {
|
||||
;; no validator to punish
|
||||
return (credits, frozen, 0);
|
||||
}
|
||||
var (addr, weight, stake, banned) = (cs~load_uint(256), cs~load_uint(64), cs~load_grams(), cs~load_int(1));
|
||||
cs.end_parse();
|
||||
int fine = min(stake, suggested_fine + muldiv(stake, suggested_fine_part, 1 << 32));
|
||||
stake -= fine;
|
||||
frozen~udict_set_builder(256, validator_pubkey, begin_cell()
|
||||
.store_uint(addr, 256)
|
||||
.store_uint(weight, 64)
|
||||
.store_grams(stake)
|
||||
.store_int(banned, 1));
|
||||
int reward = min(fine >> 3, paid * 8);
|
||||
fine -= reward;
|
||||
credits~credit_to(reward_addr, reward);
|
||||
return (credits, frozen, fine);
|
||||
}
|
||||
|
||||
(cell, cell, int) register_vote(complaints, chash, idx, weight) inline_ref {
|
||||
var (cstatus, found?) = complaints.udict_get?(256, chash);
|
||||
ifnot (found?) {
|
||||
;; complaint not found
|
||||
return (complaints, null(), -1);
|
||||
}
|
||||
var (cur_vset, total_weight, _) = get_current_vset();
|
||||
int cur_vset_id = cur_vset.cell_hash();
|
||||
var (complaint, voters, vset_id, weight_remaining) = unpack_complaint_status(cstatus);
|
||||
if (vset_id != cur_vset_id) {
|
||||
;; complaint votes belong to a previous validator set, reset voting
|
||||
vset_id = cur_vset_id;
|
||||
voters = null();
|
||||
weight_remaining = muldiv(total_weight, 2, 3);
|
||||
}
|
||||
var (_, found?) = voters.udict_get?(16, idx);
|
||||
if (found?) {
|
||||
;; already voted for this proposal, ignore vote
|
||||
return (complaints, null(), 0);
|
||||
}
|
||||
;; register vote
|
||||
voters~udict_set_builder(16, idx, begin_cell().store_uint(now(), 32));
|
||||
int old_wr = weight_remaining;
|
||||
weight_remaining -= weight;
|
||||
old_wr ^= weight_remaining;
|
||||
;; save voters and weight_remaining
|
||||
complaints~udict_set_builder(256, chash, pack_complaint_status(complaint, voters, vset_id, weight_remaining));
|
||||
if (old_wr >= 0) {
|
||||
;; not enough votes or already accepted
|
||||
return (complaints, null(), 1);
|
||||
}
|
||||
;; complaint wins, prepare punishment
|
||||
return (complaints, complaint, 2);
|
||||
}
|
||||
|
||||
int proceed_register_vote(election_id, chash, idx, weight) impure inline_ref {
|
||||
var (elect, credits, past_elections, grams, active_id, active_hash) = load_data();
|
||||
var (fs, f) = past_elections.udict_get?(32, election_id);
|
||||
ifnot (f) { ;; election not found
|
||||
return -2;
|
||||
}
|
||||
var (unfreeze_at, stake_held, vset_hash, frozen_dict, total_stake, bonuses, complaints) = unpack_past_election(fs);
|
||||
(complaints, var accepted_complaint, var status) = register_vote(complaints, chash, idx, weight);
|
||||
if (status <= 0) {
|
||||
return status;
|
||||
}
|
||||
ifnot (accepted_complaint.null?()) {
|
||||
(credits, frozen_dict, int fine) = punish(credits, frozen_dict, accepted_complaint);
|
||||
grams += fine;
|
||||
}
|
||||
past_elections.udict_set_builder(32, election_id, pack_past_election(unfreeze_at, stake_held, vset_hash, frozen_dict, total_stake, bonuses, complaints));
|
||||
store_data(elect, credits, past_elections, grams, active_id, active_hash);
|
||||
return status;
|
||||
}
|
||||
|
||||
() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure {
|
||||
|
@ -520,6 +628,20 @@ int register_complaint(s_addr, complaint, msg_value) {
|
|||
}
|
||||
return send_message_back(s_addr, ans_tag + 0xf2676350, query_id, op, 0, mode);
|
||||
}
|
||||
if (op == 0x56744370) {
|
||||
;; vote for a complaint
|
||||
var signature = in_msg~load_bits(512);
|
||||
var msg_body = in_msg;
|
||||
var (sign_tag, idx, elect_id, chash) = (in_msg~load_uint(32), in_msg~load_uint(16), in_msg~load_uint(32), in_msg~load_uint(256));
|
||||
in_msg.end_parse();
|
||||
throw_unless(37, sign_tag == 0x56744350);
|
||||
var (vdescr, total_weight) = get_validator_descr(idx);
|
||||
var (val_pubkey, weight) = unpack_validator_descr(vdescr);
|
||||
throw_unless(34, check_data_signature(msg_body, signature, val_pubkey));
|
||||
int res = proceed_register_vote(elect_id, chash, idx, weight);
|
||||
return send_message_back(s_addr, res + 0xd6745240, query_id, op, 0, 64);
|
||||
}
|
||||
|
||||
ifnot (op & (1 << 31)) {
|
||||
;; unknown query, return error
|
||||
return send_message_back(s_addr, 0xffffffff, query_id, op, 0, 64);
|
||||
|
|
|
@ -1171,6 +1171,15 @@ td::Status ValidatorEngine::load_global_config() {
|
|||
}
|
||||
|
||||
validator_options_ = ton::validator::ValidatorManagerOptions::create(zero_state, init_block);
|
||||
validator_options_.write().set_shard_check_function(
|
||||
[](ton::ShardIdFull shard, ton::validator::ValidatorManagerOptions::ShardCheckMode mode) -> bool {
|
||||
if (mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_monitor) {
|
||||
return true;
|
||||
}
|
||||
CHECK(mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_validate);
|
||||
//return shard.is_masterchain();
|
||||
return true;
|
||||
});
|
||||
if (state_ttl_ != 0) {
|
||||
validator_options_.write().set_state_ttl(state_ttl_);
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ class ValidatorSessionDescriptionImpl : public ValidatorSessionDescription {
|
|||
td::uint32 src_idx, td::Slice signature) const override;
|
||||
double get_delay(td::uint32 priority) const override;
|
||||
double get_empty_block_delay() const override {
|
||||
return get_delay(get_max_priority() + 1);
|
||||
return std::max(get_delay(get_max_priority() + 1), 1.0);
|
||||
}
|
||||
td::uint32 get_vote_for_author(td::uint32 attempt_seqno) const override;
|
||||
std::vector<PublicKeyHash> export_nodes() const;
|
||||
|
|
|
@ -1250,8 +1250,10 @@ void ValidateQuery::got_neighbor_out_queue(int i, td::Result<Ref<MessageQueue>>
|
|||
descr.set_queue_root(qinfo.out_queue->prefetch_ref(0));
|
||||
// TODO: comment the next two lines in the future when the output queues become huge
|
||||
// (do this carefully)
|
||||
CHECK(block::gen::t_OutMsgQueueInfo.validate_ref(1000000, outq_descr->root_cell()));
|
||||
CHECK(block::tlb::t_OutMsgQueueInfo.validate_ref(1000000, outq_descr->root_cell()));
|
||||
if (debug_checks_) {
|
||||
CHECK(block::gen::t_OutMsgQueueInfo.validate_ref(1000000, outq_descr->root_cell()));
|
||||
CHECK(block::tlb::t_OutMsgQueueInfo.validate_ref(1000000, outq_descr->root_cell()));
|
||||
}
|
||||
// unpack ProcessedUpto
|
||||
LOG(DEBUG) << "unpacking ProcessedUpto of neighbor " << descr.blk_.to_str();
|
||||
if (verbosity >= 2) {
|
||||
|
|
|
@ -143,6 +143,7 @@ class ValidateQuery : public td::actor::Actor {
|
|||
bool update_shard_cc_{false};
|
||||
bool is_fake_{false};
|
||||
bool prev_key_block_exists_{false};
|
||||
bool debug_checks_{false};
|
||||
BlockSeqno prev_key_seqno_{~0u};
|
||||
int stage_{0};
|
||||
td::BitArray<64> shard_pfx_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue