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:
parent
9f1b370f2c
commit
49d62dc3bb
5 changed files with 47 additions and 31 deletions
|
@ -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"};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue