mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Deactivate accounts upon destruction in block
This commit is contained in:
parent
1b480e39ba
commit
59fcd7cbd5
4 changed files with 45 additions and 30 deletions
|
@ -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) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
addr_orig = addr;
|
addr_orig = addr;
|
||||||
|
@ -304,15 +304,8 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
|
||||||
total_state = orig_total_state = account;
|
total_state = orig_total_state = account;
|
||||||
auto acc_cs = load_cell_slice(std::move(account));
|
auto acc_cs = load_cell_slice(std::move(account));
|
||||||
if (block::gen::t_Account.get_tag(acc_cs) == block::gen::Account::account_none) {
|
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;
|
is_special = special;
|
||||||
if (workchain != ton::workchainInvalid) {
|
return acc_cs.size_ext() == 1 && init_new(now);
|
||||||
addr_orig = addr;
|
|
||||||
addr_rewrite = addr.cbits();
|
|
||||||
}
|
|
||||||
return compute_my_addr() && acc_cs.size_ext() == 1;
|
|
||||||
}
|
}
|
||||||
block::gen::Account::Record_account acc;
|
block::gen::Account::Record_account acc;
|
||||||
block::gen::AccountStorage::Record storage;
|
block::gen::AccountStorage::Record storage;
|
||||||
|
@ -328,6 +321,7 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
|
||||||
case block::gen::AccountState::account_uninit:
|
case block::gen::AccountState::account_uninit:
|
||||||
status = orig_status = acc_uninit;
|
status = orig_status = acc_uninit;
|
||||||
state_hash = addr;
|
state_hash = addr;
|
||||||
|
forget_split_depth();
|
||||||
break;
|
break;
|
||||||
case block::gen::AccountState::account_frozen:
|
case block::gen::AccountState::account_frozen:
|
||||||
status = orig_status = acc_frozen;
|
status = orig_status = acc_frozen;
|
||||||
|
@ -396,10 +390,42 @@ bool Account::init_new(ton::UnixTime now) {
|
||||||
state_hash = addr_orig;
|
state_hash = addr_orig;
|
||||||
status = orig_status = acc_nonexist;
|
status = orig_status = acc_nonexist;
|
||||||
split_depth_set_ = false;
|
split_depth_set_ = false;
|
||||||
created = true;
|
|
||||||
return 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 {
|
bool Account::belongs_to_shard(ton::ShardIdFull shard) const {
|
||||||
return workchain == shard.workchain && ton::shard_is_ancestor(shard.shard, addr);
|
return workchain == shard.workchain && ton::shard_is_ancestor(shard.shard, addr);
|
||||||
}
|
}
|
||||||
|
@ -2214,7 +2240,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
|
||||||
CHECK((const void*)&acc == (const void*)&account);
|
CHECK((const void*)&acc == (const void*)&account);
|
||||||
// export all fields modified by the Transaction into original account
|
// export all fields modified by the Transaction into original account
|
||||||
// NB: this is the only method that modifies 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) {
|
acc_status == Account::acc_active) {
|
||||||
LOG(DEBUG) << "setting address rewriting info for newly-activated account " << acc.addr.to_hex()
|
LOG(DEBUG) << "setting address rewriting info for newly-activated account " << acc.addr.to_hex()
|
||||||
<< " with split_depth=" << new_split_depth
|
<< " with split_depth=" << new_split_depth
|
||||||
|
@ -2243,9 +2269,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
|
||||||
acc.tick = new_tick;
|
acc.tick = new_tick;
|
||||||
acc.tock = new_tock;
|
acc.tock = new_tock;
|
||||||
} else {
|
} else {
|
||||||
acc.tick = acc.tock = false;
|
CHECK(acc.deactivate());
|
||||||
acc.split_depth_set_ = false;
|
|
||||||
acc.created = true;
|
|
||||||
}
|
}
|
||||||
end_lt = 0;
|
end_lt = 0;
|
||||||
acc.push_transaction(root, start_lt);
|
acc.push_transaction(root, start_lt);
|
||||||
|
|
|
@ -213,17 +213,16 @@ struct Account {
|
||||||
bool is_special{false};
|
bool is_special{false};
|
||||||
bool tick{false};
|
bool tick{false};
|
||||||
bool tock{false};
|
bool tock{false};
|
||||||
bool created{false};
|
|
||||||
bool split_depth_set_{false};
|
bool split_depth_set_{false};
|
||||||
unsigned char split_depth_{0};
|
unsigned char split_depth_{0};
|
||||||
int verbosity{3 * 0};
|
int verbosity{3 * 0};
|
||||||
ton::UnixTime now_{0};
|
ton::UnixTime now_{0};
|
||||||
ton::WorkchainId workchain{ton::workchainInvalid};
|
ton::WorkchainId workchain{ton::workchainInvalid};
|
||||||
td::BitArray<32> addr_rewrite; // rewrite (anycast) data, split_depth bits
|
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; // 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
|
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)
|
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
|
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_end_lt_;
|
||||||
ton::LogicalTime last_trans_lt_;
|
ton::LogicalTime last_trans_lt_;
|
||||||
ton::Bits256 last_trans_hash_;
|
ton::Bits256 last_trans_hash_;
|
||||||
|
@ -250,6 +249,7 @@ struct Account {
|
||||||
bool set_address(ton::WorkchainId wc, td::ConstBitPtr new_addr);
|
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 unpack(Ref<vm::CellSlice> account, Ref<vm::CellSlice> extra, ton::UnixTime now, bool special = false);
|
||||||
bool init_new(ton::UnixTime now);
|
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;
|
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;
|
td::RefInt256 compute_storage_fees(ton::UnixTime now, const std::vector<block::StoragePrices>& pricing) const;
|
||||||
bool is_masterchain() const {
|
bool is_masterchain() const {
|
||||||
|
@ -268,6 +268,7 @@ struct Account {
|
||||||
friend struct Transaction;
|
friend struct Transaction;
|
||||||
bool set_split_depth(int split_depth);
|
bool set_split_depth(int split_depth);
|
||||||
bool check_split_depth(int split_depth) const;
|
bool check_split_depth(int split_depth) const;
|
||||||
|
bool forget_split_depth();
|
||||||
bool init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite);
|
bool init_rewrite_addr(int split_depth, td::ConstBitPtr orig_addr_rewrite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1944,7 +1944,6 @@ std::unique_ptr<block::Account> Collator::make_account_from(td::ConstBitPtr addr
|
||||||
}
|
}
|
||||||
auto ptr = std::make_unique<block::Account>(workchain(), addr);
|
auto ptr = std::make_unique<block::Account>(workchain(), addr);
|
||||||
if (account.is_null()) {
|
if (account.is_null()) {
|
||||||
ptr->created = true;
|
|
||||||
if (!ptr->init_new(now_)) {
|
if (!ptr->init_new(now_)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2273,10 +2272,6 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
||||||
|
|
||||||
register_new_msgs(*trans);
|
register_new_msgs(*trans);
|
||||||
update_max_lt(acc->last_trans_end_lt_);
|
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;
|
return trans_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2495,10 +2490,6 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
|
||||||
if (!insert_out_msg(cb.finalize())) {
|
if (!insert_out_msg(cb.finalize())) {
|
||||||
return -1;
|
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
|
// 7. check whether the block is full now
|
||||||
if (!block_limit_status_->fits(block::ParamLimits::cl_normal)) {
|
if (!block_limit_status_->fits(block::ParamLimits::cl_normal)) {
|
||||||
block_full_ = true;
|
block_full_ = true;
|
||||||
|
|
|
@ -4073,7 +4073,6 @@ std::unique_ptr<block::Account> ValidateQuery::make_account_from(td::ConstBitPtr
|
||||||
Ref<vm::CellSlice> extra) {
|
Ref<vm::CellSlice> extra) {
|
||||||
auto ptr = std::make_unique<block::Account>(workchain(), addr);
|
auto ptr = std::make_unique<block::Account>(workchain(), addr);
|
||||||
if (account.is_null()) {
|
if (account.is_null()) {
|
||||||
ptr->created = true;
|
|
||||||
if (!ptr->init_new(now_)) {
|
if (!ptr->init_new(now_)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -4308,7 +4307,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_first && is_masterchain() && account.is_special && account.tick &&
|
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()
|
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 "
|
<< " is the first transaction for this special tick account in this block, but the "
|
||||||
"transaction is not a tick transaction");
|
"transaction is not a tick transaction");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue