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

Commit

Permalink
Merge pull request #62 from newton-blockchain/safer_overlay
Browse files Browse the repository at this point in the history
Safer overlay
  • Loading branch information
EmelyanenkoK authored Jan 17, 2022
2 parents 159cd8a + dbb6660 commit a93c913
Show file tree
Hide file tree
Showing 55 changed files with 3,392 additions and 274 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ target_link_libraries(test-vm PRIVATE ton_crypto fift-lib)
add_executable(test-smartcont test/test-td-main.cpp ${SMARTCONT_TEST_SOURCE})
target_link_libraries(test-smartcont PRIVATE smc-envelope fift-lib ton_db)

add_executable(test-bigint ${BIGINT_TEST_SOURCE})
target_link_libraries(test-bigint PRIVATE ton_crypto)

add_executable(test-cells test/test-td-main.cpp ${CELLS_TEST_SOURCE})
target_link_libraries(test-cells PRIVATE ton_crypto)

Expand Down Expand Up @@ -523,6 +526,7 @@ if (HAS_PARENT)
${FEC_TEST_SOURCE}
${ED25519_TEST_SOURCE}
${TONDB_TEST_SOURCE}
${BIGNUM_TEST_SOURCE}
${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE}
PARENT_SCOPE)
endif()
Expand All @@ -536,6 +540,7 @@ set(TEST_OPTIONS "--regression ${CMAKE_CURRENT_SOURCE_DIR}/test/regression-tests
separate_arguments(TEST_OPTIONS)
add_test(test-ed25519-crypto crypto/test-ed25519-crypto)
add_test(test-ed25519 test-ed25519)
add_test(test-bigint test-bigint)
add_test(test-vm test-vm ${TEST_OPTIONS})
add_test(test-fift test-fift ${TEST_OPTIONS})
add_test(test-cells test-cells ${TEST_OPTIONS})
Expand Down
2 changes: 1 addition & 1 deletion catchain/catchain-receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ void CatChainReceiverImpl::start_up() {
}
td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay,
get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids),
make_callback(), overlay::OverlayPrivacyRules{0, std::move(root_keys)});
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)});

CHECK(root_block_);

Expand Down
5 changes: 5 additions & 0 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ set(FIFT_TEST_SOURCE
PARENT_SCOPE
)

set(BIGINT_TEST_SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/test/test-bigint.cpp
PARENT_SCOPE
)


add_library(ton_crypto STATIC ${TON_CRYPTO_SOURCE})
target_include_directories(ton_crypto PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
Expand Down
52 changes: 38 additions & 14 deletions crypto/block/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ bool Account::recompute_tmp_addr(Ref<vm::CellSlice>& tmp_addr, int split_depth,
}

bool Account::init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite) {
if (split_depth_set_ || !created || !set_split_depth(split_depth)) {
if (split_depth_set_ || !set_split_depth(split_depth)) {
return false;
}
addr_orig = addr;
Expand Down Expand Up @@ -304,15 +304,8 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
total_state = orig_total_state = account;
auto acc_cs = load_cell_slice(std::move(account));
if (block::gen::t_Account.get_tag(acc_cs) == block::gen::Account::account_none) {
status = acc_nonexist;
last_paid = 0;
last_trans_end_lt_ = 0;
is_special = special;
if (workchain != ton::workchainInvalid) {
addr_orig = addr;
addr_rewrite = addr.cbits();
}
return compute_my_addr() && acc_cs.size_ext() == 1;
return acc_cs.size_ext() == 1 && init_new(now);
}
block::gen::Account::Record_account acc;
block::gen::AccountStorage::Record storage;
Expand All @@ -328,6 +321,7 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
case block::gen::AccountState::account_uninit:
status = orig_status = acc_uninit;
state_hash = addr;
forget_split_depth();
break;
case block::gen::AccountState::account_frozen:
status = orig_status = acc_frozen;
Expand Down Expand Up @@ -396,10 +390,42 @@ bool Account::init_new(ton::UnixTime now) {
state_hash = addr_orig;
status = orig_status = acc_nonexist;
split_depth_set_ = false;
created = true;
return true;
}

bool Account::forget_split_depth() {
split_depth_set_ = false;
split_depth_ = 0;
addr_orig = addr;
my_addr = my_addr_exact;
addr_rewrite = addr.bits();
return true;
}

bool Account::deactivate() {
if (status == acc_active) {
return false;
}
// forget special (tick/tock) info
tick = tock = false;
if (status == acc_nonexist || status == acc_uninit) {
// forget split depth and address rewriting info
forget_split_depth();
// forget specific state hash for deleted or uninitialized accounts (revert to addr)
state_hash = addr;
}
// forget code and data (only active accounts remember these)
code.clear();
data.clear();
library.clear();
// if deleted, balance must be zero
if (status == acc_nonexist && !balance.is_zero()) {
return false;
}
return true;
}


bool Account::belongs_to_shard(ton::ShardIdFull shard) const {
return workchain == shard.workchain && ton::shard_is_ancestor(shard.shard, addr);
}
Expand Down Expand Up @@ -2214,7 +2240,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
CHECK((const void*)&acc == (const void*)&account);
// export all fields modified by the Transaction into original account
// NB: this is the only method that modifies account
if (orig_addr_rewrite_set && new_split_depth >= 0 && acc.status == Account::acc_nonexist &&
if (orig_addr_rewrite_set && new_split_depth >= 0 && acc.status != Account::acc_active &&
acc_status == Account::acc_active) {
LOG(DEBUG) << "setting address rewriting info for newly-activated account " << acc.addr.to_hex()
<< " with split_depth=" << new_split_depth
Expand Down Expand Up @@ -2243,9 +2269,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
acc.tick = new_tick;
acc.tock = new_tock;
} else {
acc.tick = acc.tock = false;
acc.split_depth_set_ = false;
acc.created = true;
CHECK(acc.deactivate());
}
end_lt = 0;
acc.push_transaction(root, start_lt);
Expand Down
11 changes: 6 additions & 5 deletions crypto/block/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,16 @@ struct Account {
bool is_special{false};
bool tick{false};
bool tock{false};
bool created{false};
bool split_depth_set_{false};
unsigned char split_depth_{0};
int verbosity{3 * 0};
ton::UnixTime now_{0};
ton::WorkchainId workchain{ton::workchainInvalid};
td::BitArray<32> addr_rewrite; // rewrite (anycast) data, split_depth bits
ton::StdSmcAddress addr; // rewritten address (by replacing a prefix of `addr_orig` with `addr_rewrite`)
ton::StdSmcAddress addr_orig; // address indicated in smart-contract data
Ref<vm::CellSlice> my_addr; // address as stored in the smart contract (MsgAddressInt)
Ref<vm::CellSlice> my_addr_exact; // exact address without anycast info
ton::StdSmcAddress addr; // rewritten address (by replacing a prefix of `addr_orig` with `addr_rewrite`); it is the key in ShardAccounts
ton::StdSmcAddress addr_orig; // address indicated in smart-contract data (must coincide with hash of StateInit)
Ref<vm::CellSlice> my_addr; // address as stored in the smart contract (MsgAddressInt); corresponds to `addr_orig` + anycast info
Ref<vm::CellSlice> my_addr_exact; // exact address without anycast info; corresponds to `addr` and has no anycast (rewrite) info
ton::LogicalTime last_trans_end_lt_;
ton::LogicalTime last_trans_lt_;
ton::Bits256 last_trans_hash_;
Expand All @@ -250,6 +249,7 @@ struct Account {
bool set_address(ton::WorkchainId wc, td::ConstBitPtr new_addr);
bool unpack(Ref<vm::CellSlice> account, Ref<vm::CellSlice> extra, ton::UnixTime now, bool special = false);
bool init_new(ton::UnixTime now);
bool deactivate();
bool recompute_tmp_addr(Ref<vm::CellSlice>& tmp_addr, int split_depth, td::ConstBitPtr orig_addr_rewrite) const;
td::RefInt256 compute_storage_fees(ton::UnixTime now, const std::vector<block::StoragePrices>& pricing) const;
bool is_masterchain() const {
Expand All @@ -268,6 +268,7 @@ struct Account {
friend struct Transaction;
bool set_split_depth(int split_depth);
bool check_split_depth(int split_depth) const;
bool forget_split_depth();
bool init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite);

private:
Expand Down
69 changes: 38 additions & 31 deletions crypto/common/bigint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ class AnyIntView {
return digits[size() - 1];
}
double top_double() const {
return size() > 1 ? (double)digits[size() - 1] + (double)digits[size() - 2] * (1.0 / Tr::Base)
return size() > 1 ? (double)digits[size() - 1] + (double)digits[size() - 2] * Tr::InvBase
: (double)digits[size() - 1];
}
bool is_odd_any() const {
Expand Down Expand Up @@ -314,8 +314,15 @@ class BigIntG {
digits[0] = x;
}
BigIntG(Normalize, word_t x) : n(1) {
digits[0] = x;
normalize_bool();
if (x >= -Tr::Half && x < Tr::Half) {
digits[0] = x;
} else if (len <= 1) {
digits[0] = x;
normalize_bool();
} else {
digits[0] = ((x + Tr::Half) & (Tr::Base - 1)) - Tr::Half;
digits[n++] = (x >> Tr::word_shift) + (digits[0] < 0);
}
}
BigIntG(const BigIntG& x) : n(x.n) {
std::memcpy(digits, x.digits, n * sizeof(word_t));
Expand Down Expand Up @@ -757,7 +764,7 @@ bool AnyIntView<Tr>::add_pow2_any(int exponent, int factor) {
while (size() <= k) {
digits[inc_size()] = 0;
}
digits[k] += (factor << dm.rem);
digits[k] += ((word_t)factor << dm.rem);
return true;
}

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

template <class Tr>
int AnyIntView<Tr>::cmp_any(word_t y) const {
if (size() > 1) {
return top_word() < 0 ? -1 : 1;
} else if (size() == 1) {
if (size() == 1) {
return digits[0] < y ? -1 : (digits[0] > y ? 1 : 0);
} else {
} else if (!size()) {
return 0x80000000;
} else if (size() == 2 && (y >= Tr::Half || y < -Tr::Half)) {
word_t x0 = digits[0] & (Tr::Base - 1), y0 = y & (Tr::Base - 1);
word_t x1 = digits[1] + (digits[0] >> Tr::word_shift), y1 = (y >> Tr::word_shift);
return x1 < y1 ? -1 : (x1 > y1 ? 1 : (x0 < y0 ? -1 : (x0 > y0 ? 1 : 0)));
} else {
return top_word() < 0 ? -1 : 1;
}
}

Expand Down Expand Up @@ -1312,17 +1323,14 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
if (k > quot.max_size()) {
return invalidate_bool();
}
quot.set_size(max(k,1));
for(int qi=0; qi< max(k,1); qi++) {
quot.digits[qi]=0;
}
quot.set_size(std::max(k, 1));
quot.digits[0] = 0;
} else {
if (k >= quot.max_size()) {
return invalidate_bool();
}
quot.set_size(k + 1);
double x_top = top_double();
word_t q = std::llrint(x_top * y_inv * Tr::InvBase);
word_t q = std::llrint(top_double() * y_inv * Tr::InvBase);
quot.digits[k] = q;
int i = yp.size() - 1;
word_t hi = 0;
Expand All @@ -1337,24 +1345,26 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
quot.digits[0] = 0;
}
while (--k >= 0) {
double x_top = top_double();
word_t q = std::llrint(x_top * y_inv);
word_t q = std::llrint(top_double() * y_inv);
quot.digits[k] = q;
for (int i = yp.size() - 1; i >= 0; --i) {
Tr::sub_mul(&digits[k + i + 1], &digits[k + i], q, yp.digits[i]);
}
dec_size();
digits[size() - 1] += (digits[size()] << word_shift);
}
if (size() >= yp.size()) {
assert(size() == yp.size());
double x_top = top_double();
double t = x_top * y_inv * Tr::InvBase;
if (size() >= yp.size() - 1) {
assert(size() <= yp.size());
bool grow = (size() < yp.size());
double t = top_double() * y_inv * (grow ? Tr::InvBase * Tr::InvBase : Tr::InvBase);
if (round_mode >= 0) {
t += (round_mode ? 1 : 0.5);
}
word_t q = std::llrint(std::floor(t));
if (q) {
if (grow) {
digits[inc_size()] = 0;
}
for (int i = 0; i < size(); i++) {
digits[i] -= q * yp.digits[i];
}
Expand Down Expand Up @@ -1411,6 +1421,7 @@ bool AnyIntView<Tr>::mod_div_any(const AnyIntView<Tr>& yp, AnyIntView<Tr>& quot,
return normalize_bool_any();
}

// works for almost-normalized numbers (digits -Base+1 .. Base-1, top non-zero), result also almost-normalized
template <class Tr>
bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
if (!is_valid()) {
Expand Down Expand Up @@ -1462,25 +1473,21 @@ bool AnyIntView<Tr>::mod_pow2_any(int exponent) {
if (exponent >= max_size() * word_shift) {
return invalidate_bool();
}
if (q - word_shift >= 0) {
if (q - word_shift >= 0) { // original top digit was a non-zero multiple of Base, impossible(?)
digits[size() - 1] = 0;
digits[inc_size()] = ((word_t)1 << (q - word_shift));
}
if (q - word_shift == -1 && size() < max_size() - 1) {
} else if (q - word_shift == -1 && size() < max_size()) {
digits[size() - 1] = -Tr::Half;
digits[inc_size()] = 1;
} else {
digits[size() - 1] = pow;
}
return true;
} else if (v >= Tr::Half) {
if (size() == max_size() - 1) {
return invalidate_bool();
} else {
digits[size() - 1] = v | -Tr::Half;
digits[inc_size()] = ((word_t)1 << (q - word_shift));
return true;
}
} else if (v >= Tr::Half && size() < max_size()) {
word_t w = (((v >> (word_shift - 1)) + 1) >> 1);
digits[size() - 1] = v - (w << word_shift);
digits[inc_size()] = w;
return true;
} else {
digits[size() - 1] = v;
return true;
Expand Down
8 changes: 3 additions & 5 deletions crypto/common/refint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,10 @@ RefInt256 muldiv(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) {
}

std::pair<RefInt256, RefInt256> muldivmod(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) {
typename td::BigInt256::DoubleInt tmp{0};
typename td::BigInt256::DoubleInt tmp{0}, quot;
tmp.add_mul(*x, *y);
RefInt256 quot{true};
tmp.mod_div(*z, quot.unique_write(), round_mode);
quot.write().normalize();
return std::make_pair(std::move(quot), td::make_refint(tmp));
tmp.mod_div(*z, quot, round_mode);
return std::make_pair(td::make_refint(quot.normalize()), td::make_refint(tmp));
}

RefInt256 operator&(RefInt256 x, RefInt256 y) {
Expand Down
5 changes: 5 additions & 0 deletions crypto/fift/lib/Asm.fif
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,14 @@ x{A926} @Defop RSHIFTC
x{A935} @Defop(8u+1) RSHIFTR#
x{A936} @Defop(8u+1) RSHIFTC#
x{A938} @Defop(8u+1) MODPOW2#
x{A939} @Defop(8u+1) MODPOW2R#
x{A93A} @Defop(8u+1) MODPOW2C#
x{A984} @Defop MULDIV
x{A985} @Defop MULDIVR
x{A988} @Defop MULMOD
x{A98C} @Defop MULDIVMOD
x{A98D} @Defop MULDIVMODR
x{A98E} @Defop MULDIVMODC
x{A9A4} @Defop MULRSHIFT
x{A9A5} @Defop MULRSHIFTR
x{A9A6} @Defop MULRSHIFTC
Expand Down
2 changes: 1 addition & 1 deletion crypto/smc-envelope/SmartContract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ SmartContract::Answer SmartContract::run_get_method(Args args) const {
args.c7 = prepare_vm_c7(now, args.balance);
}
if (!args.limits) {
args.limits = vm::GasLimits{1000000};
args.limits = vm::GasLimits{1000000, 1000000};
}
if (!args.stack) {
args.stack = td::Ref<vm::Stack>(true);
Expand Down
Loading

0 comments on commit a93c913

Please sign in to comment.