diff --git a/crypto/block/block.tlb b/crypto/block/block.tlb index 04c59951..b0d96235 100644 --- a/crypto/block/block.tlb +++ b/crypto/block/block.tlb @@ -720,10 +720,10 @@ _ (HashmapE 256 ValidatorSignedTempKey) = ConfigParam 39; misbehaviour_punishment_config_v1#01 default_flat_fine:Grams default_proportional_fine:uint32 - severity_multiplicator:uint8 + severity_flat_mult:uint8 severity_proportional_mult:uint8 unpunishable_interval:uint16 - long_interval:uint16 long_mult:uint8 - medium_interval:uint16 medium_mult:uint8 + long_interval:uint16 long_flat_mult:uint8 long_proportional_mult:uint8 + medium_interval:uint16 medium_flat_mult:uint8 medium_proportional_mult:uint8 = MisbehaviourPunishmentConfig; _ MisbehaviourPunishmentConfig = ConfigParam 40; diff --git a/lite-client/lite-client.cpp b/lite-client/lite-client.cpp index 3571bafb..f50c118c 100644 --- a/lite-client/lite-client.cpp +++ b/lite-client/lite-client.cpp @@ -3675,7 +3675,7 @@ void TestNode::continue_check_validator_load3(std::unique_ptr punishment_params) { + if(punishment_params.is_null()) { + return compute_punishment_default(interval, severe, fine, fine_part); + } + block::gen::MisbehaviourPunishmentConfig::Record rec; + if (!tlb::unpack_cell(punishment_params, rec)) { + return false; + } + + if(interval <= rec.unpunishable_interval) { + return false; + } + + fine = block::tlb::t_Grams.as_integer(rec.default_flat_fine); + fine_part = rec.default_proportional_fine; + + if (severe) { + fine = fine * rec.severity_flat_mult; + fine_part = fine_part * rec.severity_proportional_mult; + } + + if (interval >= rec.long_interval) { + fine = fine * rec.long_flat_mult; + fine_part = fine_part * rec.long_proportional_mult; + return true; + } + if (interval >= rec.medium_interval) { + fine = fine * rec.medium_flat_mult; + fine_part = fine_part * rec.medium_proportional_mult; + return true; + } + return true; +} + +bool check_punishment(int interval, bool severe, td::RefInt256 fine, unsigned fine_part, Ref punishment_params) { td::RefInt256 computed_fine; unsigned computed_fine_part; - return compute_punishment(interval, severe, computed_fine, computed_fine_part) && + return compute_punishment(interval, severe, computed_fine, computed_fine_part, punishment_params) && std::llabs((long long)fine_part - (long long)computed_fine_part) <= (std::max(fine_part, computed_fine_part) >> 3) && fine * 7 <= computed_fine * 8 && computed_fine * 7 <= fine * 8; @@ -3736,10 +3770,13 @@ td::Status TestNode::write_val_create_proof(TestNode::ValidatorLoadInfo& info1, if (interval <= 0) { return td::Status::Error("non-positive time interval"); } + + auto punishment_params = info2.config->get_config_param(40); + int severity = (severe ? 2 : 1); td::RefInt256 fine = td::make_refint(101000000000); unsigned fine_part = 0; // todo: (tolya-yanot) temporary reduction of fine // 0xffffffff / 16; // 1/16 - if (!compute_punishment(interval, severe, fine, fine_part)) { + if (!compute_punishment(interval, severe, fine, fine_part, punishment_params)) { return td::Status::Error("cannot compute adequate punishment"); } Ref cpl_descr, complaint; @@ -4053,7 +4090,7 @@ td::Status TestNode::continue_check_validator_load_proof(std::unique_ptrconfig->get_config_param(40))) { LOG(ERROR) << "proposed punishment (fine " << td::dec_string(suggested_fine) << ", fine_part=" << (double)rec.suggested_fine_part / (1LL << 32) << " is too harsh"; show_vote(root->get_hash().bits(), false);