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

Deactivate accounts upon destruction in block #57

Open
wants to merge 2 commits into
base: safer_overlay
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 1 addition & 1 deletion rldp2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ target_include_directories(rldp PUBLIC
${OPENSSL_INCLUDE_DIR}
)
if (GSL_FOUND)
target_link_libraries(rldp2 PRIVATE GSL::gsl)
target_link_libraries(rldp2 PRIVATE gsl)
target_compile_definitions(rldp2 PRIVATE -DTON_HAVE_GSL=1)
endif()
target_link_libraries(rldp2 PUBLIC tdutils tdactor fec adnl tl_api)
Expand Down
9 changes: 0 additions & 9 deletions validator/impl/collator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1920,7 +1920,6 @@ std::unique_ptr<block::Account> Collator::make_account_from(td::ConstBitPtr addr
}
auto ptr = std::make_unique<block::Account>(workchain(), addr);
if (account.is_null()) {
ptr->created = true;
if (!ptr->init_new(now_)) {
return nullptr;
}
Expand Down Expand Up @@ -2298,10 +2297,6 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
}
register_new_msgs(*trans);
update_max_lt(acc->last_trans_end_lt_);
// temporary patch to stop producing dangerous block
if (acc->status == block::Account::acc_nonexist) {
block_full_ = true;
}
return trans_root;
}

Expand Down Expand Up @@ -2451,10 +2446,6 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
if (!insert_out_msg(cb.finalize())) {
return -1;
}
// 6.5. check for temporary patch can be left here
if (block_full_) {
return 3;
}
// 7. check whether the block is full now
if (!block_limit_status_->fits(block::ParamLimits::cl_normal)) {
block_full_ = true;
Expand Down
3 changes: 1 addition & 2 deletions validator/impl/validate-query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,6 @@ std::unique_ptr<block::Account> ValidateQuery::make_account_from(td::ConstBitPtr
Ref<vm::CellSlice> extra) {
auto ptr = std::make_unique<block::Account>(workchain(), addr);
if (account.is_null()) {
ptr->created = true;
if (!ptr->init_new(now_)) {
return nullptr;
}
Expand Down Expand Up @@ -4308,7 +4307,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
}
}
if (is_first && is_masterchain() && account.is_special && account.tick &&
(tag != block::gen::TransactionDescr::trans_tick_tock || (td_cs.prefetch_ulong(4) & 1)) && !account.created) {
(tag != block::gen::TransactionDescr::trans_tick_tock || (td_cs.prefetch_ulong(4) & 1)) && account.orig_status == block::Account::acc_active) {
return reject_query(PSTRING() << "transaction " << lt << " of account " << addr.to_hex()
<< " is the first transaction for this special tick account in this block, but the "
"transaction is not a tick transaction");
Expand Down