Skip to content

Commit db3619e

Browse files
authored
Merge pull request #371 from ton-blockchain/release-candidate
Merge updates
2 parents 15088bb + b9481fb commit db3619e

File tree

107 files changed

+4959
-496
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+4959
-496
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ target_link_libraries(test-vm PRIVATE ton_crypto fift-lib)
423423
add_executable(test-smartcont test/test-td-main.cpp ${SMARTCONT_TEST_SOURCE})
424424
target_link_libraries(test-smartcont PRIVATE smc-envelope fift-lib ton_db)
425425

426+
add_executable(test-bigint ${BIGINT_TEST_SOURCE})
427+
target_link_libraries(test-bigint PRIVATE ton_crypto)
428+
426429
add_executable(test-cells test/test-td-main.cpp ${CELLS_TEST_SOURCE})
427430
target_link_libraries(test-cells PRIVATE ton_crypto)
428431

@@ -523,6 +526,7 @@ if (HAS_PARENT)
523526
${FEC_TEST_SOURCE}
524527
${ED25519_TEST_SOURCE}
525528
${TONDB_TEST_SOURCE}
529+
${BIGNUM_TEST_SOURCE}
526530
${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE}
527531
PARENT_SCOPE)
528532
endif()
@@ -536,6 +540,7 @@ set(TEST_OPTIONS "--regression ${CMAKE_CURRENT_SOURCE_DIR}/test/regression-tests
536540
separate_arguments(TEST_OPTIONS)
537541
add_test(test-ed25519-crypto crypto/test-ed25519-crypto)
538542
add_test(test-ed25519 test-ed25519)
543+
add_test(test-bigint test-bigint)
539544
add_test(test-vm test-vm ${TEST_OPTIONS})
540545
add_test(test-fift test-fift ${TEST_OPTIONS})
541546
add_test(test-cells test-cells ${TEST_OPTIONS})

Changelog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## 05.2022 Update
2+
* Initial synchronization improved: adjusted timeouts for state download and the way of choosing which state to download. Nodes with low network speed and/or bad connectivity will synchronize faster and consistently.
3+
* Improved peer-to-peer network stability and DDoS resistance: now peers will only relay valid messages to the network. Large messages, which require splitting for relaying, will be retranslated as well, but only after the node gets all parts, and reassembles and checks them. Validators may sign certificates for network peers, which allow relaying large messages by parts without checks. It is used now by validators to faster relay new blocks. Sign and import certificate commands are exposed via `validator-engine-console`.
4+
* Fixed some rare edge cases in TVM arithmetic operations related to big numbers (`2**63+`)
5+
* Improved fixes used to combat wrong activate-destruct-activate contract behavior last November.
6+
* Improved tonlib: support libraries (with client-side caching), getmethods completely fill c7 register, getmethods support slice arguments, improved messages listing for transactions, added extended block header params, added getConfig method.
7+
* RocksDB updated to a newer version.
8+
* Improved persistent state serialization: memory usage during serialization was optimized; the start of serialization on different nodes was sparsed.
9+
* FunC update: support for string literals and constants (including precompiled constant expressions), semver, `include` expressions.
10+
* Fixed rarely manifested bugs in `Asm.fif`.
11+
* LiteClient supports key as cli parameter.
12+
* Improved Liteserver DoS resistance for running getmethods.
13+
14+
Besides the work of the core team, this update is based on the efforts of @tvorogme (added support for slice arguments and noted bugs in Asm.fif), @akifoq (fixed bug in Asm.fif), @cryshado (noted strange behavior of LS, which, upon inspection, turned out to be a vector of DoS attack).

catchain/catchain-receiver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ void CatChainReceiverImpl::start_up() {
486486
}
487487
td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay,
488488
get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids),
489-
make_callback(), overlay::OverlayPrivacyRules{0, std::move(root_keys)});
489+
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)});
490490

491491
CHECK(root_block_);
492492

crypto/CMakeLists.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,11 @@ set(FIFT_TEST_SOURCE
259259
PARENT_SCOPE
260260
)
261261

262+
set(BIGINT_TEST_SOURCE
263+
${CMAKE_CURRENT_SOURCE_DIR}/test/test-bigint.cpp
264+
PARENT_SCOPE
265+
)
266+
262267

263268
add_library(ton_crypto STATIC ${TON_CRYPTO_SOURCE})
264269
target_include_directories(ton_crypto PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
@@ -293,9 +298,14 @@ add_library(src_parser ${PARSER_SOURCE})
293298
target_include_directories(src_parser PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
294299
target_link_libraries(src_parser PUBLIC ton_crypto)
295300

301+
add_library(ton_block ${BLOCK_SOURCE})
302+
target_include_directories(ton_block PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
303+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/block> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
304+
target_link_libraries(ton_block PUBLIC ton_crypto tdutils tdactor tl_api)
305+
296306
add_executable(func func/func.cpp ${FUNC_LIB_SOURCE})
297307
target_include_directories(func PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
298-
target_link_libraries(func PUBLIC ton_crypto src_parser git)
308+
target_link_libraries(func PUBLIC ton_crypto src_parser git ton_block)
299309
if (WINGETOPT_FOUND)
300310
target_link_libraries_system(func wingetopt)
301311
endif()
@@ -319,11 +329,6 @@ if (WINGETOPT_FOUND)
319329
target_link_libraries_system(pow-miner wingetopt)
320330
endif()
321331

322-
add_library(ton_block ${BLOCK_SOURCE})
323-
target_include_directories(ton_block PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
324-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/block> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
325-
target_link_libraries(ton_block PUBLIC ton_crypto tdutils tdactor tl_api)
326-
327332
set(TURN_OFF_LSAN cd .)
328333
if (TON_USE_ASAN AND NOT WIN32)
329334
set(TURN_OFF_LSAN export LSAN_OPTIONS=detect_leaks=0)

crypto/block/mc-config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,7 @@ Ref<vm::Cell> ConfigInfo::lookup_library(td::ConstBitPtr root_hash) const {
21002100
return {};
21012101
}
21022102
auto csr = libraries_dict_->lookup(root_hash, 256);
2103-
if (csr.is_null() || csr->prefetch_ulong(8) != 0 || !csr->have_refs()) { // shared_lib_descr$00 lib:^Cell
2103+
if (csr.is_null() || csr->prefetch_ulong(2) != 0 || !csr->have_refs()) { // shared_lib_descr$00 lib:^Cell
21042104
return {};
21052105
}
21062106
auto lib = csr->prefetch_ref();

crypto/block/transaction.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ bool Account::recompute_tmp_addr(Ref<vm::CellSlice>& tmp_addr, int split_depth,
271271
}
272272

273273
bool Account::init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite) {
274-
if (split_depth_set_ || !created || !set_split_depth(split_depth)) {
274+
if (split_depth_set_ || !set_split_depth(split_depth)) {
275275
return false;
276276
}
277277
addr_orig = addr;
@@ -304,15 +304,8 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
304304
total_state = orig_total_state = account;
305305
auto acc_cs = load_cell_slice(std::move(account));
306306
if (block::gen::t_Account.get_tag(acc_cs) == block::gen::Account::account_none) {
307-
status = acc_nonexist;
308-
last_paid = 0;
309-
last_trans_end_lt_ = 0;
310307
is_special = special;
311-
if (workchain != ton::workchainInvalid) {
312-
addr_orig = addr;
313-
addr_rewrite = addr.cbits();
314-
}
315-
return compute_my_addr() && acc_cs.size_ext() == 1;
308+
return acc_cs.size_ext() == 1 && init_new(now);
316309
}
317310
block::gen::Account::Record_account acc;
318311
block::gen::AccountStorage::Record storage;
@@ -328,6 +321,7 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
328321
case block::gen::AccountState::account_uninit:
329322
status = orig_status = acc_uninit;
330323
state_hash = addr;
324+
forget_split_depth();
331325
break;
332326
case block::gen::AccountState::account_frozen:
333327
status = orig_status = acc_frozen;
@@ -396,10 +390,42 @@ bool Account::init_new(ton::UnixTime now) {
396390
state_hash = addr_orig;
397391
status = orig_status = acc_nonexist;
398392
split_depth_set_ = false;
399-
created = true;
400393
return true;
401394
}
402395

396+
bool Account::forget_split_depth() {
397+
split_depth_set_ = false;
398+
split_depth_ = 0;
399+
addr_orig = addr;
400+
my_addr = my_addr_exact;
401+
addr_rewrite = addr.bits();
402+
return true;
403+
}
404+
405+
bool Account::deactivate() {
406+
if (status == acc_active) {
407+
return false;
408+
}
409+
// forget special (tick/tock) info
410+
tick = tock = false;
411+
if (status == acc_nonexist || status == acc_uninit) {
412+
// forget split depth and address rewriting info
413+
forget_split_depth();
414+
// forget specific state hash for deleted or uninitialized accounts (revert to addr)
415+
state_hash = addr;
416+
}
417+
// forget code and data (only active accounts remember these)
418+
code.clear();
419+
data.clear();
420+
library.clear();
421+
// if deleted, balance must be zero
422+
if (status == acc_nonexist && !balance.is_zero()) {
423+
return false;
424+
}
425+
return true;
426+
}
427+
428+
403429
bool Account::belongs_to_shard(ton::ShardIdFull shard) const {
404430
return workchain == shard.workchain && ton::shard_is_ancestor(shard.shard, addr);
405431
}
@@ -2214,7 +2240,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
22142240
CHECK((const void*)&acc == (const void*)&account);
22152241
// export all fields modified by the Transaction into original account
22162242
// NB: this is the only method that modifies account
2217-
if (orig_addr_rewrite_set && new_split_depth >= 0 && acc.status == Account::acc_nonexist &&
2243+
if (orig_addr_rewrite_set && new_split_depth >= 0 && acc.status != Account::acc_active &&
22182244
acc_status == Account::acc_active) {
22192245
LOG(DEBUG) << "setting address rewriting info for newly-activated account " << acc.addr.to_hex()
22202246
<< " with split_depth=" << new_split_depth
@@ -2243,9 +2269,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
22432269
acc.tick = new_tick;
22442270
acc.tock = new_tock;
22452271
} else {
2246-
acc.tick = acc.tock = false;
2247-
acc.split_depth_set_ = false;
2248-
acc.created = true;
2272+
CHECK(acc.deactivate());
22492273
}
22502274
end_lt = 0;
22512275
acc.push_transaction(root, start_lt);

crypto/block/transaction.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,16 @@ struct Account {
213213
bool is_special{false};
214214
bool tick{false};
215215
bool tock{false};
216-
bool created{false};
217216
bool split_depth_set_{false};
218217
unsigned char split_depth_{0};
219218
int verbosity{3 * 0};
220219
ton::UnixTime now_{0};
221220
ton::WorkchainId workchain{ton::workchainInvalid};
222221
td::BitArray<32> addr_rewrite; // rewrite (anycast) data, split_depth bits
223-
ton::StdSmcAddress addr; // rewritten address (by replacing a prefix of `addr_orig` with `addr_rewrite`)
224-
ton::StdSmcAddress addr_orig; // address indicated in smart-contract data
225-
Ref<vm::CellSlice> my_addr; // address as stored in the smart contract (MsgAddressInt)
226-
Ref<vm::CellSlice> my_addr_exact; // exact address without anycast info
222+
ton::StdSmcAddress addr; // rewritten address (by replacing a prefix of `addr_orig` with `addr_rewrite`); it is the key in ShardAccounts
223+
ton::StdSmcAddress addr_orig; // address indicated in smart-contract data (must coincide with hash of StateInit)
224+
Ref<vm::CellSlice> my_addr; // address as stored in the smart contract (MsgAddressInt); corresponds to `addr_orig` + anycast info
225+
Ref<vm::CellSlice> my_addr_exact; // exact address without anycast info; corresponds to `addr` and has no anycast (rewrite) info
227226
ton::LogicalTime last_trans_end_lt_;
228227
ton::LogicalTime last_trans_lt_;
229228
ton::Bits256 last_trans_hash_;
@@ -250,6 +249,7 @@ struct Account {
250249
bool set_address(ton::WorkchainId wc, td::ConstBitPtr new_addr);
251250
bool unpack(Ref<vm::CellSlice> account, Ref<vm::CellSlice> extra, ton::UnixTime now, bool special = false);
252251
bool init_new(ton::UnixTime now);
252+
bool deactivate();
253253
bool recompute_tmp_addr(Ref<vm::CellSlice>& tmp_addr, int split_depth, td::ConstBitPtr orig_addr_rewrite) const;
254254
td::RefInt256 compute_storage_fees(ton::UnixTime now, const std::vector<block::StoragePrices>& pricing) const;
255255
bool is_masterchain() const {
@@ -268,6 +268,7 @@ struct Account {
268268
friend struct Transaction;
269269
bool set_split_depth(int split_depth);
270270
bool check_split_depth(int split_depth) const;
271+
bool forget_split_depth();
271272
bool init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite);
272273

273274
private:

crypto/common/bigint.hpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class AnyIntView {
264264
return digits[size() - 1];
265265
}
266266
double top_double() const {
267-
return size() > 1 ? (double)digits[size() - 1] + (double)digits[size() - 2] * (1.0 / Tr::Base)
267+
return size() > 1 ? (double)digits[size() - 1] + (double)digits[size() - 2] * Tr::InvBase
268268
: (double)digits[size() - 1];
269269
}
270270
bool is_odd_any() const {
@@ -314,8 +314,15 @@ class BigIntG {
314314
digits[0] = x;
315315
}
316316
BigIntG(Normalize, word_t x) : n(1) {
317-
digits[0] = x;
318-
normalize_bool();
317+
if (x >= -Tr::Half && x < Tr::Half) {
318+
digits[0] = x;
319+
} else if (len <= 1) {
320+
digits[0] = x;
321+
normalize_bool();
322+
} else {
323+
digits[0] = ((x + Tr::Half) & (Tr::Base - 1)) - Tr::Half;
324+
digits[n++] = (x >> Tr::word_shift) + (digits[0] < 0);
325+
}
319326
}
320327
BigIntG(const BigIntG& x) : n(x.n) {
321328
std::memcpy(digits, x.digits, n * sizeof(word_t));
@@ -757,7 +764,7 @@ bool AnyIntView<Tr>::add_pow2_any(int exponent, int factor) {
757764
while (size() <= k) {
758765
digits[inc_size()] = 0;
759766
}
760-
digits[k] += (factor << dm.rem);
767+
digits[k] += ((word_t)factor << dm.rem);
761768
return true;
762769
}
763770

@@ -1087,12 +1094,16 @@ int AnyIntView<Tr>::cmp_any(const AnyIntView<Tr>& yp) const {
10871094

10881095
template <class Tr>
10891096
int AnyIntView<Tr>::cmp_any(word_t y) const {
1090-
if (size() > 1) {
1091-
return top_word() < 0 ? -1 : 1;
1092-
} else if (size() == 1) {
1097+
if (size() == 1) {
10931098
return digits[0] < y ? -1 : (digits[0] > y ? 1 : 0);
1094-
} else {
1099+
} else if (!size()) {
10951100
return 0x80000000;
1101+
} else if (size() == 2 && (y >= Tr::Half || y < -Tr::Half)) {
1102+
word_t x0 = digits[0] & (Tr::Base - 1), y0 = y & (Tr::Base - 1);
1103+
word_t x1 = digits[1] + (digits[0] >> Tr::word_shift), y1 = (y >> Tr::word_shift);
1104+
return x1 < y1 ? -1 : (x1 > y1 ? 1 : (x0 < y0 ? -1 : (x0 > y0 ? 1 : 0)));
1105+
} else {
1106+
return top_word() < 0 ? -1 : 1;
10961107
}
10971108
}
10981109

@@ -1312,17 +1323,14 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
13121323
if (k > quot.max_size()) {
13131324
return invalidate_bool();
13141325
}
1315-
quot.set_size(max(k,1));
1316-
for(int qi=0; qi< max(k,1); qi++) {
1317-
quot.digits[qi]=0;
1318-
}
1326+
quot.set_size(std::max(k, 1));
1327+
quot.digits[0] = 0;
13191328
} else {
13201329
if (k >= quot.max_size()) {
13211330
return invalidate_bool();
13221331
}
13231332
quot.set_size(k + 1);
1324-
double x_top = top_double();
1325-
word_t q = std::llrint(x_top * y_inv * Tr::InvBase);
1333+
word_t q = std::llrint(top_double() * y_inv * Tr::InvBase);
13261334
quot.digits[k] = q;
13271335
int i = yp.size() - 1;
13281336
word_t hi = 0;
@@ -1337,24 +1345,26 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
13371345
quot.digits[0] = 0;
13381346
}
13391347
while (--k >= 0) {
1340-
double x_top = top_double();
1341-
word_t q = std::llrint(x_top * y_inv);
1348+
word_t q = std::llrint(top_double() * y_inv);
13421349
quot.digits[k] = q;
13431350
for (int i = yp.size() - 1; i >= 0; --i) {
13441351
Tr::sub_mul(&digits[k + i + 1], &digits[k + i], q, yp.digits[i]);
13451352
}
13461353
dec_size();
13471354
digits[size() - 1] += (digits[size()] << word_shift);
13481355
}
1349-
if (size() >= yp.size()) {
1350-
assert(size() == yp.size());
1351-
double x_top = top_double();
1352-
double t = x_top * y_inv * Tr::InvBase;
1356+
if (size() >= yp.size() - 1) {
1357+
assert(size() <= yp.size());
1358+
bool grow = (size() < yp.size());
1359+
double t = top_double() * y_inv * (grow ? Tr::InvBase * Tr::InvBase : Tr::InvBase);
13531360
if (round_mode >= 0) {
13541361
t += (round_mode ? 1 : 0.5);
13551362
}
13561363
word_t q = std::llrint(std::floor(t));
13571364
if (q) {
1365+
if (grow) {
1366+
digits[inc_size()] = 0;
1367+
}
13581368
for (int i = 0; i < size(); i++) {
13591369
digits[i] -= q * yp.digits[i];
13601370
}
@@ -1411,6 +1421,7 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
14111421
return normalize_bool_any();
14121422
}
14131423

1424+
// works for almost-normalized numbers (digits -Base+1 .. Base-1, top non-zero), result also almost-normalized
14141425
template <class Tr>
14151426
bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
14161427
if (!is_valid()) {
@@ -1462,25 +1473,21 @@ bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
14621473
if (exponent >= max_size() * word_shift) {
14631474
return invalidate_bool();
14641475
}
1465-
if (q - word_shift >= 0) {
1476+
if (q - word_shift >= 0) { // original top digit was a non-zero multiple of Base, impossible(?)
14661477
digits[size() - 1] = 0;
14671478
digits[inc_size()] = ((word_t)1 << (q - word_shift));
1468-
}
1469-
if (q - word_shift == -1 && size() < max_size() - 1) {
1479+
} else if (q - word_shift == -1 && size() < max_size()) {
14701480
digits[size() - 1] = -Tr::Half;
14711481
digits[inc_size()] = 1;
14721482
} else {
14731483
digits[size() - 1] = pow;
14741484
}
14751485
return true;
1476-
} else if (v >= Tr::Half) {
1477-
if (size() == max_size() - 1) {
1478-
return invalidate_bool();
1479-
} else {
1480-
digits[size() - 1] = v | -Tr::Half;
1481-
digits[inc_size()] = ((word_t)1 << (q - word_shift));
1482-
return true;
1483-
}
1486+
} else if (v >= Tr::Half && size() < max_size()) {
1487+
word_t w = (((v >> (word_shift - 1)) + 1) >> 1);
1488+
digits[size() - 1] = v - (w << word_shift);
1489+
digits[inc_size()] = w;
1490+
return true;
14841491
} else {
14851492
digits[size() - 1] = v;
14861493
return true;

0 commit comments

Comments
 (0)