1
0
Fork 0
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:
ton 2020-04-05 13:56:24 +04:00
parent b73b057e08
commit 7efb345e3d
5 changed files with 138 additions and 4 deletions

View file

@ -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);

View file

@ -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_);
}

View file

@ -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;

View file

@ -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) {

View file

@ -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_;