Skip to content

Commit

Permalink
Limit max number of public libraries on contracts (#808)
Browse files Browse the repository at this point in the history
  • Loading branch information
SpyCheese authored Nov 22, 2023
1 parent 909e7db commit 31263fb
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 9 deletions.
2 changes: 1 addition & 1 deletion crypto/block/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions crypto/block/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
}
Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion crypto/block/block.tlb
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
Expand Down
1 change: 1 addition & 0 deletions crypto/block/mc-config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions crypto/block/mc-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
42 changes: 36 additions & 6 deletions crypto/block/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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();
}

/**
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion validator/impl/collator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 31263fb

Please sign in to comment.