mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Limit max number of public libraries on contracts (#808)
This commit is contained in:
parent
909e7dbdfc
commit
31263fb475
7 changed files with 44 additions and 9 deletions
|
@ -715,7 +715,7 @@ td::uint64 BlockLimitStatus::estimate_block_size(const vm::NewCellStorageStat::S
|
|||
sum += *extra;
|
||||
}
|
||||
return 2000 + (sum.bits >> 3) + sum.cells * 12 + sum.internal_refs * 3 + sum.external_refs * 40 + accounts * 200 +
|
||||
transactions * 200 + (extra ? 200 : 0) + extra_out_msgs * 300;
|
||||
transactions * 200 + (extra ? 200 : 0) + extra_out_msgs * 300 + extra_library_diff * 700;
|
||||
}
|
||||
|
||||
int BlockLimitStatus::classify() const {
|
||||
|
|
|
@ -262,6 +262,7 @@ struct BlockLimitStatus {
|
|||
td::uint64 gas_used{};
|
||||
vm::NewCellStorageStat st_stat;
|
||||
unsigned accounts{}, transactions{}, extra_out_msgs{};
|
||||
unsigned extra_library_diff{}; // Number of public libraries in deleted/frozen accounts
|
||||
BlockLimitStatus(const BlockLimits& limits_, ton::LogicalTime lt = 0)
|
||||
: limits(limits_), cur_lt(std::max(limits_.start_lt, lt)) {
|
||||
}
|
||||
|
@ -271,6 +272,7 @@ struct BlockLimitStatus {
|
|||
transactions = accounts = 0;
|
||||
gas_used = 0;
|
||||
extra_out_msgs = 0;
|
||||
extra_library_diff = 0;
|
||||
}
|
||||
td::uint64 estimate_block_size(const vm::NewCellStorageStat::Stat* extra = nullptr) const;
|
||||
int classify() const;
|
||||
|
|
|
@ -780,7 +780,8 @@ _ MisbehaviourPunishmentConfig = ConfigParam 40;
|
|||
size_limits_config#01 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 = SizeLimitsConfig;
|
||||
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 = SizeLimitsConfig;
|
||||
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;
|
||||
_ SizeLimitsConfig = ConfigParam 43;
|
||||
|
||||
// key is [ wc:int32 addr:uint256 ]
|
||||
|
|
|
@ -1934,6 +1934,7 @@ td::Result<SizeLimitsConfig> Config::get_size_limits_config() const {
|
|||
unpack_v1(rec);
|
||||
limits.max_acc_state_bits = rec.max_acc_state_bits;
|
||||
limits.max_acc_state_cells = rec.max_acc_state_cells;
|
||||
limits.max_acc_public_libraries = rec.max_acc_public_libraries;
|
||||
};
|
||||
gen::SizeLimitsConfig::Record_size_limits_config rec_v1;
|
||||
gen::SizeLimitsConfig::Record_size_limits_config_v2 rec_v2;
|
||||
|
|
|
@ -389,6 +389,7 @@ struct SizeLimitsConfig {
|
|||
ExtMsgLimits ext_msg_limits;
|
||||
td::uint32 max_acc_state_cells = 1 << 16;
|
||||
td::uint32 max_acc_state_bits = (1 << 16) * 1023;
|
||||
td::uint32 max_acc_public_libraries = 256;
|
||||
};
|
||||
|
||||
struct CatchainValidatorsConfig {
|
||||
|
|
|
@ -2500,8 +2500,28 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of public libraries in the dictionary.
|
||||
*
|
||||
* @param libraries The dictionary of account libraries.
|
||||
*
|
||||
* @returns The number of public libraries in the dictionary.
|
||||
*/
|
||||
static td::uint32 get_public_libraries_count(const td::Ref<vm::Cell>& libraries) {
|
||||
td::uint32 count = 0;
|
||||
vm::Dictionary dict{libraries, 256};
|
||||
dict.check_for_each([&](td::Ref<vm::CellSlice> value, td::ConstBitPtr key, int) {
|
||||
if (block::is_public_library(key, std::move(value))) {
|
||||
++count;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the new account state fits in the limits.
|
||||
* This function is not called for special accounts.
|
||||
*
|
||||
* @param cfg The configuration for the action phase.
|
||||
*
|
||||
|
@ -2547,10 +2567,15 @@ td::Status Transaction::check_state_limits(const ActionPhaseConfig& cfg) {
|
|||
} else {
|
||||
new_storage_stat.clear();
|
||||
}
|
||||
return new_storage_stat.cells <= cfg.size_limits.max_acc_state_cells &&
|
||||
new_storage_stat.bits <= cfg.size_limits.max_acc_state_bits
|
||||
? td::Status::OK()
|
||||
: td::Status::Error("state too big");
|
||||
if (new_storage_stat.cells > cfg.size_limits.max_acc_state_cells ||
|
||||
new_storage_stat.bits > cfg.size_limits.max_acc_state_bits) {
|
||||
return td::Status::Error("account state is too big");
|
||||
}
|
||||
if (account.is_masterchain() && !cell_equal(account.library, new_library) &&
|
||||
get_public_libraries_count(new_library) > cfg.size_limits.max_acc_public_libraries) {
|
||||
return td::Status::Error("too many public libraries");
|
||||
}
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3135,8 +3160,13 @@ bool Transaction::update_limits(block::BlockLimitStatus& blimst, bool with_size)
|
|||
return false;
|
||||
}
|
||||
if (with_size) {
|
||||
return blimst.add_proof(new_total_state) && blimst.add_cell(root) && blimst.add_transaction() &&
|
||||
blimst.add_account(is_first);
|
||||
if (!(blimst.add_proof(new_total_state) && blimst.add_cell(root) && blimst.add_transaction() &&
|
||||
blimst.add_account(is_first))) {
|
||||
return false;
|
||||
}
|
||||
if (account.is_masterchain() && (was_frozen || was_deleted)) {
|
||||
blimst.extra_library_diff += get_public_libraries_count(account.orig_library);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4310,7 +4310,7 @@ bool Collator::update_public_libraries() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (libraries_changed_ && verbosity >= 2 * 0) {
|
||||
if (libraries_changed_ && verbosity >= 2) {
|
||||
std::cerr << "New public libraries: ";
|
||||
block::gen::t_HashmapE_256_LibDescr.print(std::cerr, shard_libraries_->get_root());
|
||||
shard_libraries_->get_root()->print_rec(std::cerr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue