1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Activate new changes in TVM by version>=5, reduce gas cost for loading libraries (#875)

Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
EmelyanenkoK 2024-01-24 13:05:22 +03:00 committed by GitHub
parent 9f1b370f2c
commit 49d62dc3bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 31 deletions

View file

@ -892,34 +892,37 @@ int exec_load_special_cell(VmState* st, bool quiet) {
Stack& stack = st->get_stack();
VM_LOG(st) << "execute XLOAD" << (quiet ? "Q" : "");
auto cell = stack.pop_cell();
auto r_loaded_cell = cell->load_cell();
if (r_loaded_cell.is_error()) {
if (quiet) {
stack.push_bool(false);
return 0;
} else {
throw VmError{Excno::cell_und, "failed to load cell"};
}
}
auto loaded_cell = r_loaded_cell.move_as_ok();
if (loaded_cell.data_cell->is_special()) {
if (loaded_cell.data_cell->special_type() != CellTraits::SpecialType::Library) {
if (st->get_global_version() >= 5) {
st->register_cell_load(cell->get_hash());
auto r_loaded_cell = cell->load_cell();
if (r_loaded_cell.is_error()) {
if (quiet) {
stack.push_bool(false);
return 0;
} else {
throw VmError{Excno::cell_und, "unexpected special cell"};
throw VmError{Excno::cell_und, "failed to load cell"};
}
}
CellSlice cs(std::move(loaded_cell));
DCHECK(cs.size() == Cell::hash_bits + 8);
cell = st->load_library(cs.data_bits() + 8);
if (cell.is_null()) {
if (quiet) {
stack.push_bool(false);
return 0;
} else {
throw VmError{Excno::cell_und, "failed to load library cell"};
auto loaded_cell = r_loaded_cell.move_as_ok();
if (loaded_cell.data_cell->is_special()) {
if (loaded_cell.data_cell->special_type() != CellTraits::SpecialType::Library) {
if (quiet) {
stack.push_bool(false);
return 0;
} else {
throw VmError{Excno::cell_und, "unexpected special cell"};
}
}
CellSlice cs(std::move(loaded_cell));
DCHECK(cs.size() == Cell::hash_bits + 8);
cell = st->load_library(cs.data_bits() + 8);
if (cell.is_null()) {
if (quiet) {
stack.push_bool(false);
return 0;
} else {
throw VmError{Excno::cell_und, "failed to load library cell"};
}
}
}
}

View file

@ -1056,10 +1056,10 @@ std::ostream& operator<<(std::ostream& os, Ref<CellSlice> cs_ref) {
// If can_be_special is not null, then it is allowed to load special cell
// Flag whether loaded cell is actually special will be stored into can_be_special
VirtualCell::LoadedCell load_cell_slice_impl(Ref<Cell> cell, bool* can_be_special) {
auto* vm_state_interface = VmStateInterface::get();
bool library_loaded = false;
while (true) {
auto* vm_state_interface = VmStateInterface::get();
if (vm_state_interface) {
if (vm_state_interface && !library_loaded) {
vm_state_interface->register_cell_load(cell->get_hash());
}
auto r_loaded_cell = cell->load_cell();
@ -1077,11 +1077,13 @@ VirtualCell::LoadedCell load_cell_slice_impl(Ref<Cell> cell, bool* can_be_specia
*can_be_special = loaded_cell.data_cell->is_special();
} else if (loaded_cell.data_cell->is_special()) {
if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::Library) {
if (library_loaded) {
throw VmError{Excno::cell_und, "failed to load library cell: recursive library cells are not allowed"};
}
library_loaded = true;
if (vm_state_interface) {
if (vm_state_interface->get_global_version() >= 5) {
if (library_loaded) {
throw VmError{Excno::cell_und, "failed to load library cell: recursive library cells are not allowed"};
}
library_loaded = true;
}
CellSlice cs(std::move(loaded_cell));
DCHECK(cs.size() == Cell::hash_bits + 8);
auto library_cell = vm_state_interface->load_library(cs.data_bits() + 8);

View file

@ -340,7 +340,7 @@ class VmState final : public VmStateInterface {
void preclear_cr(const ControlRegs& save) {
cr &= save;
}
int get_global_version() const {
int get_global_version() const override {
return global_version;
}
void set_global_version(int version) {

View file

@ -19,6 +19,7 @@
#pragma once
#include "common/refcnt.hpp"
#include "vm/cells.h"
#include "common/global-version.h"
#include "td/utils/Context.h"
@ -38,6 +39,9 @@ class VmStateInterface : public td::Context<VmStateInterface> {
virtual bool register_op(int op_units = 1) {
return true;
};
virtual int get_global_version() const {
return ton::SUPPORTED_VERSION;
}
};
} // namespace vm

View file

@ -39,11 +39,18 @@ intermediate value before division (e.g. `(xy+w)/z`).
* Unpaid storage fee is now saved to `due_payment`
## Version 5
### Gas limits
Version 5 enables higher gas limits for special contracts.
* Gas limit for all transactions on special contracts is set to `special_gas_limit` from `ConfigParam 20` (which is 35M at the moment of writing).
Previously only ticktock transactions had this limit, while ordinary transactions could use up to `gas_limit` gas (1M).
Previously only ticktock transactions had this limit, while ordinary transactions had a default limit of `gas_limit` gas (1M).
* Gas usage of special contracts is not taken into account when checking block limits. This allows keeping masterchain block limits low
while having high gas limits for elector.
* Gas limit on `EQD_v9j1rlsuHHw2FIhcsCFFSD367ldfDdCKcsNmNpIRzUlu` is increased to `special_gas_limit * 2` until 2024-02-29.
See [this post](https://t.me/tonstatus/88) for details.
See [this post](https://t.me/tonstatus/88) for details.
### Loading libraries
* Loading "nested libraries" (i.e. a library cell that points to another library cell) throws an exception.
* Loading a library consumes gas for cell load only once (for the library cell), not twice (both for the library cell and the cell in the library).
* `XLOAD` now works differently. When it takes a library cell, it returns the cell that it points to. This allows loading "nested libraries", if needed.