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

Commit dbb6660

Browse files
committed
Deactivate accounts upon destruction in block
1 parent 4280b5a commit dbb6660

File tree

4 files changed

+45
-30
lines changed

4 files changed

+45
-30
lines changed

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:

validator/impl/collator.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,7 +1944,6 @@ std::unique_ptr<block::Account> Collator::make_account_from(td::ConstBitPtr addr
19441944
}
19451945
auto ptr = std::make_unique<block::Account>(workchain(), addr);
19461946
if (account.is_null()) {
1947-
ptr->created = true;
19481947
if (!ptr->init_new(now_)) {
19491948
return nullptr;
19501949
}
@@ -2273,10 +2272,6 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
22732272

22742273
register_new_msgs(*trans);
22752274
update_max_lt(acc->last_trans_end_lt_);
2276-
// temporary patch to stop producing dangerous block
2277-
if (acc->status == block::Account::acc_nonexist) {
2278-
block_full_ = true;
2279-
}
22802275
return trans_root;
22812276
}
22822277

@@ -2495,10 +2490,6 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
24952490
if (!insert_out_msg(cb.finalize())) {
24962491
return -1;
24972492
}
2498-
// 6.5. check for temporary patch can be left here
2499-
if (block_full_) {
2500-
return 3;
2501-
}
25022493
// 7. check whether the block is full now
25032494
if (!block_limit_status_->fits(block::ParamLimits::cl_normal)) {
25042495
block_full_ = true;

validator/impl/validate-query.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4073,7 +4073,6 @@ std::unique_ptr<block::Account> ValidateQuery::make_account_from(td::ConstBitPtr
40734073
Ref<vm::CellSlice> extra) {
40744074
auto ptr = std::make_unique<block::Account>(workchain(), addr);
40754075
if (account.is_null()) {
4076-
ptr->created = true;
40774076
if (!ptr->init_new(now_)) {
40784077
return nullptr;
40794078
}
@@ -4308,7 +4307,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
43084307
}
43094308
}
43104309
if (is_first && is_masterchain() && account.is_special && account.tick &&
4311-
(tag != block::gen::TransactionDescr::trans_tick_tock || (td_cs.prefetch_ulong(4) & 1)) && !account.created) {
4310+
(tag != block::gen::TransactionDescr::trans_tick_tock || (td_cs.prefetch_ulong(4) & 1)) && account.orig_status == block::Account::acc_active) {
43124311
return reject_query(PSTRING() << "transaction " << lt << " of account " << addr.to_hex()
43134312
<< " is the first transaction for this special tick account in this block, but the "
43144313
"transaction is not a tick transaction");

0 commit comments

Comments
 (0)