Skip to content

Commit

Permalink
Merge branch 'testnet' into accelerator
Browse files Browse the repository at this point in the history
  • Loading branch information
SpyCheese committed Jan 15, 2025
2 parents 1ee3e5d + 2ebc6d6 commit e8edc60
Show file tree
Hide file tree
Showing 19 changed files with 156 additions and 61 deletions.
8 changes: 4 additions & 4 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Besides the work of the core team, this update is based on the efforts of @krigg
## 2024.08 Update

1. Introduction of dispatch queues, message envelopes with transaction chain metadata, and explicitly stored msg_queue size, which will be activated by `Config8.version >= 8` and new `Config8.capabilities` bits: `capStoreOutMsgQueueSize`, `capMsgMetadata`, `capDeferMessages`.
2. A number of changes to transcation executor which will activated for `Config8.version >= 8`:
2. A number of changes to transaction executor which will activated for `Config8.version >= 8`:
- Check mode on invalid `action_send_msg`. Ignore action if `IGNORE_ERROR` (+2) bit is set, bounce if `BOUNCE_ON_FAIL` (+16) bit is set.
- Slightly change random seed generation to fix mix of `addr_rewrite` and `addr`.
- Fill in `skipped_actions` for both invalid and valid messages with `IGNORE_ERROR` mode that can't be sent.
Expand Down Expand Up @@ -103,7 +103,7 @@ Besides the work of the core team, this update is based on the efforts of @akifo
* Fix error in proof generation for blocks after merge
* Fix most of `block is not applied` issues related to sending too recent block in Proofs
* LS now check external messages till `accept_message` (`set_gas`).
3. Improvements in DHT work and storage, CellDb, config.json ammendment, peer misbehavior detection, validator session stats collection, emulator.
3. Improvements in DHT work and storage, CellDb, config.json amendment, peer misbehavior detection, validator session stats collection, emulator.
4. Change in CTOS and XLOAD behavior activated through setting `version >= 5` in `ConfigParam 8;`:
* 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).
Expand All @@ -114,7 +114,7 @@ Besides the work of the Core team, this update is based on the efforts of @XaBbl
## 2023.12 Update

1. Optimized message queue handling, now queue cleaning speed doesn't depend on total queue size
* Cleaning delivered messages using lt augmentation instead of random search / consequtive walk
* Cleaning delivered messages using lt augmentation instead of random search / consecutive walk
* Keeping root cell of queue message in memory until outdated (caching)
2. Changes to block collation/validation limits
3. Stop accepting new external message if message queue is overloaded
Expand Down Expand Up @@ -206,7 +206,7 @@ Besides the work of the core team, this update is based on the efforts of @vtama
Besides the work of the core team, this update is based on the efforts of @tvorogme (debug improvements), @AlexeyFSL (WASM builds) and third-party security auditors.

## 2022.08 Update
* Blockchain state serialization now works via separate db-handler which simplfies memory clearing after serialization
* Blockchain state serialization now works via separate db-handler which simplifies memory clearing after serialization
* CellDB now works asynchronously which substantially increase database access throughput
* Abseil-cpp and crc32 updated: solve issues with compilation on recent OS distributives
* Fixed a series of UBs and issues for exotic endianness hosts
Expand Down
14 changes: 14 additions & 0 deletions adnl/adnl-peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ void AdnlPeerPairImpl::discover() {
void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
last_received_packet_ = td::Timestamp::now();
try_reinit_at_ = td::Timestamp::never();
drop_addr_list_at_ = td::Timestamp::never();
request_reverse_ping_after_ = td::Timestamp::in(15.0);
auto d = Adnl::adnl_start_time();
if (packet.dst_reinit_date() > d) {
Expand Down Expand Up @@ -415,6 +416,9 @@ void AdnlPeerPairImpl::send_packet_continue(AdnlPacket packet, td::actor::ActorI
if (!try_reinit_at_ && last_received_packet_ < td::Timestamp::in(-5.0)) {
try_reinit_at_ = td::Timestamp::in(10.0);
}
if (!drop_addr_list_at_ && last_received_packet_ < td::Timestamp::in(-60.0 * 9.0)) {
drop_addr_list_at_ = td::Timestamp::in(60.0);
}
packet.run_basic_checks().ensure();
auto B = serialize_tl_object(packet.tl(), true);
if (via_channel) {
Expand Down Expand Up @@ -692,6 +696,16 @@ void AdnlPeerPairImpl::reinit(td::int32 date) {
}

td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> AdnlPeerPairImpl::get_conn() {
if (drop_addr_list_at_ && drop_addr_list_at_.is_in_past()) {
drop_addr_list_at_ = td::Timestamp::never();
priority_addr_list_ = AdnlAddressList{};
priority_conns_.clear();
addr_list_ = AdnlAddressList{};
conns_.clear();
has_reverse_addr_ = false;
return td::Status::Error(ErrorCode::notready, "no active connections");
}

if (!priority_addr_list_.empty() && priority_addr_list_.expire_at() < td::Clocks::system()) {
priority_addr_list_ = AdnlAddressList{};
priority_conns_.clear();
Expand Down
1 change: 1 addition & 0 deletions adnl/adnl-peer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ class AdnlPeerPairImpl : public AdnlPeerPair {

td::Timestamp last_received_packet_ = td::Timestamp::never();
td::Timestamp try_reinit_at_ = td::Timestamp::never();
td::Timestamp drop_addr_list_at_ = td::Timestamp::never();

bool has_reverse_addr_ = false;
td::Timestamp request_reverse_ping_after_ = td::Timestamp::now();
Expand Down
30 changes: 30 additions & 0 deletions crypto/block/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1343,6 +1343,36 @@ CurrencyCollection CurrencyCollection::operator-(td::RefInt256 other_grams) cons
}
}

bool CurrencyCollection::clamp(const CurrencyCollection& other) {
if (!is_valid() || !other.is_valid()) {
return invalidate();
}
grams = std::min(grams, other.grams);
vm::Dictionary dict1{extra, 32}, dict2(other.extra, 32);
bool ok = dict1.check_for_each([&](td::Ref<vm::CellSlice> cs1, td::ConstBitPtr key, int n) {
CHECK(n == 32);
td::Ref<vm::CellSlice> cs2 = dict2.lookup(key, 32);
td::RefInt256 val1 = tlb::t_VarUIntegerPos_32.as_integer(cs1);
if (val1.is_null()) {
return false;
}
td::RefInt256 val2 = cs2.is_null() ? td::zero_refint() : tlb::t_VarUIntegerPos_32.as_integer(cs2);
if (val2.is_null()) {
return false;
}
if (val1 > val2) {
if (val2->sgn() == 0) {
dict1.lookup_delete(key, 32);
} else {
dict1.set(key, 32, cs2);
}
}
return true;
});
extra = dict1.get_root_cell();
return ok || invalidate();
}

bool CurrencyCollection::operator==(const CurrencyCollection& other) const {
return is_valid() && other.is_valid() && !td::cmp(grams, other.grams) &&
(extra.not_null() == other.extra.not_null()) &&
Expand Down
1 change: 1 addition & 0 deletions crypto/block/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ struct CurrencyCollection {
CurrencyCollection operator-(const CurrencyCollection& other) const;
CurrencyCollection operator-(CurrencyCollection&& other) const;
CurrencyCollection operator-(td::RefInt256 other_grams) const;
bool clamp(const CurrencyCollection& other);
bool store(vm::CellBuilder& cb) const;
bool store_or_zero(vm::CellBuilder& cb) const;
bool fetch(vm::CellSlice& cs);
Expand Down
22 changes: 13 additions & 9 deletions crypto/block/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2760,22 +2760,25 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap,
LOG(DEBUG) << "cannot reserve a negative amount: " << reserve.to_str();
return -1;
}
if (reserve.grams > ap.remaining_balance.grams) {
if (mode & 2) {
reserve.grams = ap.remaining_balance.grams;
if (mode & 2) {
if (cfg.reserve_extra_enabled) {
if (!reserve.clamp(ap.remaining_balance)) {
LOG(DEBUG) << "failed to clamp reserve amount" << mode;
return -1;
}
} else {
LOG(DEBUG) << "cannot reserve " << reserve.grams << " nanograms : only " << ap.remaining_balance.grams
<< " available";
return 37; // not enough grams
reserve.grams = std::min(reserve.grams, ap.remaining_balance.grams);
}
}
if (reserve.grams > ap.remaining_balance.grams) {
LOG(DEBUG) << "cannot reserve " << reserve.grams << " nanograms : only " << ap.remaining_balance.grams
<< " available";
return 37; // not enough grams
}
if (!block::sub_extra_currency(ap.remaining_balance.extra, reserve.extra, newc.extra)) {
LOG(DEBUG) << "not enough extra currency to reserve: " << block::CurrencyCollection{0, reserve.extra}.to_str()
<< " required, only " << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str()
<< " available";
if (mode & 2) {
// TODO: process (mode & 2) correctly by setting res_extra := inf (reserve.extra, ap.remaining_balance.extra)
}
return 38; // not enough (extra) funds
}
newc.grams = ap.remaining_balance.grams - reserve.grams;
Expand Down Expand Up @@ -3778,6 +3781,7 @@ td::Status FetchConfigParams::fetch_config_params(
action_phase_cfg->bounce_on_fail_enabled = config.get_global_version() >= 4;
action_phase_cfg->message_skip_enabled = config.get_global_version() >= 8;
action_phase_cfg->disable_custom_fess = config.get_global_version() >= 8;
action_phase_cfg->reserve_extra_enabled = config.get_global_version() >= 9;
action_phase_cfg->mc_blackhole_addr = config.get_burning_config().blackhole_addr;
}
{
Expand Down
1 change: 1 addition & 0 deletions crypto/block/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct ActionPhaseConfig {
bool bounce_on_fail_enabled{false};
bool message_skip_enabled{false};
bool disable_custom_fess{false};
bool reserve_extra_enabled{false};
td::optional<td::Bits256> mc_blackhole_addr;
const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
return is_masterchain ? fwd_mc : fwd_std;
Expand Down
21 changes: 11 additions & 10 deletions crypto/smc-envelope/SmartContract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,17 @@ td::Ref<vm::Tuple> prepare_vm_c7(SmartContract::Args args, td::Ref<vm::Cell> cod
}

std::vector<vm::StackEntry> tuple = {
td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea
td::make_refint(0), // actions:Integer
td::make_refint(0), // msgs_sent:Integer
td::make_refint(now), // unixtime:Integer
td::make_refint(0), //TODO: // block_lt:Integer
td::make_refint(0), //TODO: // trans_lt:Integer
std::move(rand_seed_int), // rand_seed:Integer
block::CurrencyCollection(args.balance).as_vm_tuple(), // balance_remaining:[Integer (Maybe Cell)]
vm::load_cell_slice_ref(address), // myself:MsgAddressInt
vm::StackEntry::maybe(config) // vm::StackEntry::maybe(td::Ref<vm::Cell>())
td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea
td::make_refint(0), // actions:Integer
td::make_refint(0), // msgs_sent:Integer
td::make_refint(now), // unixtime:Integer
td::make_refint(0), // block_lt:Integer (TODO)
td::make_refint(0), // trans_lt:Integer (TODO)
std::move(rand_seed_int), // rand_seed:Integer
block::CurrencyCollection(args.balance, args.extra_currencies)
.as_vm_tuple(), // balance_remaining:[Integer (Maybe Cell)]
vm::load_cell_slice_ref(address), // myself:MsgAddressInt
vm::StackEntry::maybe(config) // vm::StackEntry::maybe(td::Ref<vm::Cell>())
};
if (args.config && args.config.value()->get_global_version() >= 4) {
tuple.push_back(vm::StackEntry::maybe(code)); // code:Cell
Expand Down
5 changes: 5 additions & 0 deletions crypto/smc-envelope/SmartContract.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class SmartContract : public td::CntObject {
bool ignore_chksig{false};
td::uint64 amount{0};
td::uint64 balance{0};
td::Ref<vm::Cell> extra_currencies;
int vm_log_verbosity_level{0};
bool debug_enabled{false};

Expand Down Expand Up @@ -121,6 +122,10 @@ class SmartContract : public td::CntObject {
this->balance = balance;
return std::move(*this);
}
Args&& set_extra_currencies(td::Ref<vm::Cell> extra_currencies) {
this->extra_currencies = std::move(extra_currencies);
return std::move(*this);
}
Args&& set_address(block::StdAddress address) {
this->address = address;
return std::move(*this);
Expand Down
3 changes: 0 additions & 3 deletions crypto/tl/tlbc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1800,9 +1800,6 @@ void Constructor::show(std::ostream& os, int mode) const {
}
for (int i = 0; i < type_arity; i++) {
os << ' ';
if (param_negated.at(i)) {
os << '~';
}
params.at(i)->show(os, this, 100, mode | 1);
}
if (!(mode & 2)) {
Expand Down
17 changes: 12 additions & 5 deletions crypto/vm/db/DynamicBagOfCellsDb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,18 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
return get_cell_info_lazy(level_mask, hash, depth).cell;
}
td::Result<Ref<DataCell>> load_cell(td::Slice hash) override {
TRY_RESULT(loaded_cell, get_cell_info_force(hash).cell->load_cell());
return std::move(loaded_cell.data_cell);
auto info = hash_table_.get_if_exists(hash);
if (info && info->sync_with_db) {
TRY_RESULT(loaded_cell, info->cell->load_cell());
return std::move(loaded_cell.data_cell);
}
TRY_RESULT(res, loader_->load(hash, true, *this));
if (res.status != CellLoader::LoadResult::Ok) {
return td::Status::Error("cell not found");
}
Ref<DataCell> cell = res.cell();
hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_loaded(info, hash, std::move(res)); });
return cell;
}
td::Result<Ref<DataCell>> load_root(td::Slice hash) override {
return load_cell(hash);
Expand Down Expand Up @@ -145,9 +155,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
promise->set_result(std::move(cell));
});
}
CellInfo &get_cell_info_force(td::Slice hash) {
return hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_force(info, hash); });
}
CellInfo &get_cell_info_lazy(Cell::LevelMask level_mask, td::Slice hash, td::Slice depth) {
return hash_table_.apply(hash.substr(hash.size() - Cell::hash_bytes),
[&](CellInfo &info) { update_cell_info_lazy(info, level_mask, hash, depth); });
Expand Down
2 changes: 1 addition & 1 deletion crypto/vm/tonops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ void register_ton_crypto_ops(OpcodeTable& cp0) {
}

int exec_compute_data_size(VmState* st, int mode) {
VM_LOG(st) << (mode & 2 ? 'S' : 'C') << "DATASIZE" << (mode & 1 ? "Q" : "");
VM_LOG(st) << "execute " << (mode & 2 ? 'S' : 'C') << "DATASIZE" << (mode & 1 ? "Q" : "");
Stack& stack = st->get_stack();
stack.check_underflow(2);
auto bound = stack.pop_int();
Expand Down
3 changes: 2 additions & 1 deletion doc/GlobalVersions.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,5 @@ Operations for working with Merkle proofs, where cells can have non-zero level a
### Other changes
- Fix `RAWRESERVE` action with flag `4` (use original balance of the account) by explicitly setting `original_balance` to `balance - msg_balance_remaining`.
- Previously it did not work if storage fee was greater than the original balance.
- Jumps to nested continuations of depth more than 8 consume 1 gas for eact subsequent continuation (this does not affect most of TVM code).
- Jumps to nested continuations of depth more than 8 consume 1 gas for eact subsequent continuation (this does not affect most of TVM code).
- Support extra currencies in reserve action with `+2` mode.
21 changes: 12 additions & 9 deletions tonlib/tonlib/TonlibClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,15 +1050,17 @@ class Query {
}

vm::GasLimits gas_limits = compute_gas_limits(td::make_refint(raw_.source->get_balance()), gas_limits_prices);
auto res = smc.write().send_external_message(raw_.message_body, ton::SmartContract::Args()
.set_limits(gas_limits)
.set_balance(raw_.source->get_balance())
.set_now(raw_.source->get_sync_time())
.set_ignore_chksig(ignore_chksig)
.set_address(raw_.source->get_address())
.set_config(cfg)
.set_prev_blocks_info(state.prev_blocks_info)
.set_libraries(libraries));
auto res = smc.write().send_external_message(raw_.message_body,
ton::SmartContract::Args()
.set_limits(gas_limits)
.set_balance(raw_.source->get_balance())
.set_extra_currencies(raw_.source->get_extra_currencies())
.set_now(raw_.source->get_sync_time())
.set_ignore_chksig(ignore_chksig)
.set_address(raw_.source->get_address())
.set_config(cfg)
.set_prev_blocks_info(state.prev_blocks_info)
.set_libraries(libraries));
td::int64 fwd_fee = 0;
if (res.success) {
LOG(DEBUG) << "output actions:\n"
Expand Down Expand Up @@ -4916,6 +4918,7 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
}
args.set_stack(std::move(stack));
args.set_balance(it->second->get_balance());
args.set_extra_currencies(it->second->get_extra_currencies());
args.set_now(it->second->get_sync_time());
args.set_address(it->second->get_address());

Expand Down
13 changes: 13 additions & 0 deletions utils/generate-random-id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ int main(int argc, char *argv[]) {
TRY_RESULT_PREFIX_ASSIGN(addr_list, ton::adnl::AdnlAddressList::create(addr_list_tl), "bad addr list: ");
return td::Status::OK();
});
p.add_checked_option('f', "path to file with addr-list", "addr list to sign", [&](td::Slice key) {
if (addr_list) {
return td::Status::Error("duplicate '-f' option");
}

td::BufferSlice bs(key);
TRY_RESULT_PREFIX(data, td::read_file(key.str()), "failed to read addr-list: ");
TRY_RESULT_PREFIX(as_json_value, td::json_decode(data.as_slice()), "bad addr list JSON: ");
ton::tl_object_ptr<ton::ton_api::adnl_addressList> addr_list_tl;
TRY_STATUS_PREFIX(td::from_json(addr_list_tl, std::move(as_json_value)), "bad addr list TL: ");
TRY_RESULT_PREFIX_ASSIGN(addr_list, ton::adnl::AdnlAddressList::create(addr_list_tl), "bad addr list: ");
return td::Status::OK();
});
p.add_checked_option('i', "network-id", "dht network id (default: -1)", [&](td::Slice key) {
if (network_id_opt) {
return td::Status::Error("duplicate '-i' option");
Expand Down
5 changes: 3 additions & 2 deletions validator/downloaders/wait-block-state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ void WaitBlockState::start() {
if (reading_from_db_) {
return;
}
if (handle_->received_state()) {
bool inited_proof = handle_->id().is_masterchain() ? handle_->inited_proof() : handle_->inited_proof_link();
if (handle_->received_state() && inited_proof) {
reading_from_db_ = true;

auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
Expand Down Expand Up @@ -107,7 +108,7 @@ void WaitBlockState::start() {
});
td::actor::send_closure(manager_, &ValidatorManager::send_get_zero_state_request, handle_->id(), priority_,
std::move(P));
} else if (check_persistent_state_desc()) {
} else if (check_persistent_state_desc() && !handle_->received_state()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to get persistent state: " << R.move_as_error();
Expand Down
Loading

0 comments on commit e8edc60

Please sign in to comment.