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,6 +892,8 @@ int exec_load_special_cell(VmState* st, bool quiet) {
Stack& stack = st->get_stack(); Stack& stack = st->get_stack();
VM_LOG(st) << "execute XLOAD" << (quiet ? "Q" : ""); VM_LOG(st) << "execute XLOAD" << (quiet ? "Q" : "");
auto cell = stack.pop_cell(); auto cell = stack.pop_cell();
if (st->get_global_version() >= 5) {
st->register_cell_load(cell->get_hash());
auto r_loaded_cell = cell->load_cell(); auto r_loaded_cell = cell->load_cell();
if (r_loaded_cell.is_error()) { if (r_loaded_cell.is_error()) {
if (quiet) { if (quiet) {
@ -923,6 +925,7 @@ int exec_load_special_cell(VmState* st, bool quiet) {
} }
} }
} }
}
stack.push_cell(cell); stack.push_cell(cell);
if (quiet) { if (quiet) {
stack.push_bool(true); stack.push_bool(true);

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 // 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 // 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) { VirtualCell::LoadedCell load_cell_slice_impl(Ref<Cell> cell, bool* can_be_special) {
auto* vm_state_interface = VmStateInterface::get();
bool library_loaded = false; bool library_loaded = false;
while (true) { while (true) {
auto* vm_state_interface = VmStateInterface::get(); if (vm_state_interface && !library_loaded) {
if (vm_state_interface) {
vm_state_interface->register_cell_load(cell->get_hash()); vm_state_interface->register_cell_load(cell->get_hash());
} }
auto r_loaded_cell = cell->load_cell(); 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(); *can_be_special = loaded_cell.data_cell->is_special();
} else if (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 (loaded_cell.data_cell->special_type() == DataCell::SpecialType::Library) {
if (vm_state_interface) {
if (vm_state_interface->get_global_version() >= 5) {
if (library_loaded) { if (library_loaded) {
throw VmError{Excno::cell_und, "failed to load library cell: recursive library cells are not allowed"}; throw VmError{Excno::cell_und, "failed to load library cell: recursive library cells are not allowed"};
} }
library_loaded = true; library_loaded = true;
if (vm_state_interface) { }
CellSlice cs(std::move(loaded_cell)); CellSlice cs(std::move(loaded_cell));
DCHECK(cs.size() == Cell::hash_bits + 8); DCHECK(cs.size() == Cell::hash_bits + 8);
auto library_cell = vm_state_interface->load_library(cs.data_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) { void preclear_cr(const ControlRegs& save) {
cr &= save; cr &= save;
} }
int get_global_version() const { int get_global_version() const override {
return global_version; return global_version;
} }
void set_global_version(int version) { void set_global_version(int version) {

View file

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "common/refcnt.hpp" #include "common/refcnt.hpp"
#include "vm/cells.h" #include "vm/cells.h"
#include "common/global-version.h"
#include "td/utils/Context.h" #include "td/utils/Context.h"
@ -38,6 +39,9 @@ class VmStateInterface : public td::Context<VmStateInterface> {
virtual bool register_op(int op_units = 1) { virtual bool register_op(int op_units = 1) {
return true; return true;
}; };
virtual int get_global_version() const {
return ton::SUPPORTED_VERSION;
}
}; };
} // namespace vm } // 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` * Unpaid storage fee is now saved to `due_payment`
## Version 5 ## Version 5
### Gas limits
Version 5 enables higher gas limits for special contracts. 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). * 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 * 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. while having high gas limits for elector.
* Gas limit on `EQD_v9j1rlsuHHw2FIhcsCFFSD367ldfDdCKcsNmNpIRzUlu` is increased to `special_gas_limit * 2` until 2024-02-29. * 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.