Skip to content
This repository was archived by the owner on May 16, 2024. It is now read-only.

Commit a93c913

Browse files
authored
Merge pull request #62 from newton-blockchain/safer_overlay
Safer overlay
2 parents 159cd8a + dbb6660 commit a93c913

Some content is hidden

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

55 files changed

+3392
-274
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})

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: 5 additions & 0 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}>

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;

crypto/common/refint.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,10 @@ RefInt256 muldiv(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) {
128128
}
129129

130130
std::pair<RefInt256, RefInt256> muldivmod(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) {
131-
typename td::BigInt256::DoubleInt tmp{0};
131+
typename td::BigInt256::DoubleInt tmp{0}, quot;
132132
tmp.add_mul(*x, *y);
133-
RefInt256 quot{true};
134-
tmp.mod_div(*z, quot.unique_write(), round_mode);
135-
quot.write().normalize();
136-
return std::make_pair(std::move(quot), td::make_refint(tmp));
133+
tmp.mod_div(*z, quot, round_mode);
134+
return std::make_pair(td::make_refint(quot.normalize()), td::make_refint(tmp));
137135
}
138136

139137
RefInt256 operator&(RefInt256 x, RefInt256 y) {

crypto/fift/lib/Asm.fif

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,14 @@ x{A926} @Defop RSHIFTC
334334
x{A935} @Defop(8u+1) RSHIFTR#
335335
x{A936} @Defop(8u+1) RSHIFTC#
336336
x{A938} @Defop(8u+1) MODPOW2#
337+
x{A939} @Defop(8u+1) MODPOW2R#
338+
x{A93A} @Defop(8u+1) MODPOW2C#
337339
x{A984} @Defop MULDIV
338340
x{A985} @Defop MULDIVR
341+
x{A988} @Defop MULMOD
339342
x{A98C} @Defop MULDIVMOD
343+
x{A98D} @Defop MULDIVMODR
344+
x{A98E} @Defop MULDIVMODC
340345
x{A9A4} @Defop MULRSHIFT
341346
x{A9A5} @Defop MULRSHIFTR
342347
x{A9A6} @Defop MULRSHIFTC

crypto/smc-envelope/SmartContract.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ SmartContract::Answer SmartContract::run_get_method(Args args) const {
207207
args.c7 = prepare_vm_c7(now, args.balance);
208208
}
209209
if (!args.limits) {
210-
args.limits = vm::GasLimits{1000000};
210+
args.limits = vm::GasLimits{1000000, 1000000};
211211
}
212212
if (!args.stack) {
213213
args.stack = td::Ref<vm::Stack>(true);

0 commit comments

Comments
 (0)