From 13b9f460af73ebc1616e77904dc2e63f5f34d071 Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Mon, 9 Jan 2023 20:37:58 +0300 Subject: [PATCH] SuspendedAddressList config param (#585) * SuspendedAddressList config param * Change tag for cskip_suspended --- crypto/block/block-parse.h | 12 ++++++++---- crypto/block/block.tlb | 5 +++++ crypto/block/mc-config.cpp | 9 +++++++++ crypto/block/mc-config.h | 1 + crypto/block/transaction.cpp | 21 +++++++++++++++++++++ crypto/block/transaction.h | 4 +++- validator/impl/collator-impl.h | 2 +- validator/impl/collator.cpp | 5 +++-- validator/impl/external-message.cpp | 2 +- validator/impl/validate-query.cpp | 1 + 10 files changed, 53 insertions(+), 9 deletions(-) diff --git a/crypto/block/block-parse.h b/crypto/block/block-parse.h index 3e2ff81a..25476a64 100644 --- a/crypto/block/block-parse.h +++ b/crypto/block/block-parse.h @@ -653,16 +653,20 @@ struct TrComputeInternal1 final : TLB_Complex { }; struct ComputeSkipReason final : TLB { - enum { cskip_no_state = 0, cskip_bad_state = 1, cskip_no_gas = 2 }; + enum { cskip_no_state = 0, cskip_bad_state = 1, cskip_no_gas = 2, cskip_suspended = 3 }; int get_size(const vm::CellSlice& cs) const override { - return 2; + return cs.prefetch_ulong(2) == 3 ? 3 : 2; } bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override { - return get_tag(cs) >= 0 && cs.advance(2); + int tag = get_tag(cs); + return tag >= 0 && cs.advance(tag == 3 ? 3 : 2); } int get_tag(const vm::CellSlice& cs) const override { int t = (int)cs.prefetch_ulong(2); - return t < 3 ? t : -1; + if (t == 3 && cs.prefetch_ulong(3) != 0b110) { + return -1; + } + return t; } }; diff --git a/crypto/block/block.tlb b/crypto/block/block.tlb index 902669e8..8d98197f 100644 --- a/crypto/block/block.tlb +++ b/crypto/block/block.tlb @@ -309,6 +309,7 @@ tr_phase_compute_vm$1 success:Bool msg_state_used:Bool cskip_no_state$00 = ComputeSkipReason; cskip_bad_state$01 = ComputeSkipReason; cskip_no_gas$10 = ComputeSkipReason; +cskip_suspended$110 = ComputeSkipReason; tr_phase_action$_ success:Bool valid:Bool no_funds:Bool status_change:AccStatusChange @@ -757,6 +758,10 @@ size_limits_config_v2#02 max_msg_bits:uint32 max_msg_cells:uint32 max_library_ce max_ext_msg_size:uint32 max_ext_msg_depth:uint16 max_acc_state_cells:uint32 max_acc_state_bits:uint32 = SizeLimitsConfig; _ SizeLimitsConfig = ConfigParam 43; +// key is [ wc:int32 addr:uint256 ] +suspended_address_list#00 addresses:(HashmapE 288 Unit) suspended_until:uint32 = SuspendedAddressList; +_ SuspendedAddressList = ConfigParam 44; + oracle_bridge_params#_ bridge_address:bits256 oracle_mutlisig_address:bits256 oracles:(HashmapE 256 uint256) external_chain_address:bits256 = OracleBridgeParams; _ OracleBridgeParams = ConfigParam 71; // Ethereum bridge _ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge diff --git a/crypto/block/mc-config.cpp b/crypto/block/mc-config.cpp index 41fc9a5f..9b43075a 100644 --- a/crypto/block/mc-config.cpp +++ b/crypto/block/mc-config.cpp @@ -1945,6 +1945,15 @@ td::Result Config::get_size_limits_config() const { return limits; } +std::unique_ptr Config::get_suspended_addresses(ton::UnixTime now) const { + td::Ref param = get_config_param(44); + gen::SuspendedAddressList::Record rec; + if (param.is_null() || !tlb::unpack_cell(param, rec) || rec.suspended_until <= now) { + return {}; + } + return std::make_unique(rec.addresses->prefetch_ref(), 288); +} + td::Result> Config::unpack_validator_set_start_stop(Ref vset_root) { if (vset_root.is_null()) { return td::Status::Error("validator set absent"); diff --git a/crypto/block/mc-config.h b/crypto/block/mc-config.h index 4525e336..ad5999e5 100644 --- a/crypto/block/mc-config.h +++ b/crypto/block/mc-config.h @@ -616,6 +616,7 @@ class Config { ton::CatchainSeqno cc_seqno) const; std::vector compute_total_validator_set(int next) const; td::Result get_size_limits_config() const; + std::unique_ptr get_suspended_addresses(ton::UnixTime now) const; static std::vector do_compute_validator_set(const block::CatchainValidatorsConfig& ccv_conf, ton::ShardIdFull shard, const block::ValidatorSet& vset, ton::UnixTime time, diff --git a/crypto/block/transaction.cpp b/crypto/block/transaction.cpp index 293677ca..adda48a5 100644 --- a/crypto/block/transaction.cpp +++ b/crypto/block/transaction.cpp @@ -794,6 +794,20 @@ bool ComputePhaseConfig::parse_GasLimitsPrices_internal(Ref cs, t return true; } +bool ComputePhaseConfig::is_address_suspended(ton::WorkchainId wc, td::Bits256 addr) const { + if (!suspended_addresses) { + return false; + } + try { + vm::CellBuilder key; + key.store_long_bool(wc, 32); + key.store_bits_bool(addr); + return !suspended_addresses->lookup(key.data_bits(), 288).is_null(); + } catch (vm::VmError) { + return false; + } +} + void ComputePhaseConfig::compute_threshold() { gas_price256 = td::make_refint(gas_price); if (gas_limit > flat_gas_limit) { @@ -1006,6 +1020,11 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) { if (in_msg_state.not_null() && (acc_status == Account::acc_uninit || (acc_status == Account::acc_frozen && account.state_hash == in_msg_state->get_hash().bits()))) { + if (acc_status == Account::acc_uninit && cfg.is_address_suspended(account.workchain, account.addr)) { + LOG(DEBUG) << "address is suspended, skipping compute phase"; + cp.skip_reason = ComputePhase::sk_suspended; + return true; + } use_msg_state = true; if (!(unpack_msg_state() && account.check_split_depth(new_split_depth))) { LOG(DEBUG) << "cannot unpack in_msg_state, or it has bad split_depth; cannot init account state"; @@ -2263,6 +2282,8 @@ bool Transaction::serialize_compute_phase(vm::CellBuilder& cb) { return cb.store_long_bool(1, 3); // cskip_bad_state$01 = ComputeSkipReason; case ComputePhase::sk_no_gas: return cb.store_long_bool(2, 3); // cskip_no_gas$10 = ComputeSkipReason; + case ComputePhase::sk_suspended: + return cb.store_long_bool(0b0110, 4); // cskip_suspended$110 = ComputeSkipReason; case ComputePhase::sk_none: break; default: diff --git a/crypto/block/transaction.h b/crypto/block/transaction.h index 6a171418..2560c010 100644 --- a/crypto/block/transaction.h +++ b/crypto/block/transaction.h @@ -108,6 +108,7 @@ struct ComputePhaseConfig { td::BitArray<256> block_rand_seed; bool with_vm_log{false}; td::uint16 max_vm_data_depth = 512; + std::unique_ptr suspended_addresses; ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0) : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) { compute_threshold(); @@ -132,6 +133,7 @@ struct ComputePhaseConfig { } bool parse_GasLimitsPrices(Ref cs, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit); bool parse_GasLimitsPrices(Ref cell, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit); + bool is_address_suspended(ton::WorkchainId wc, td::Bits256 addr) const; private: bool parse_GasLimitsPrices_internal(Ref cs, td::RefInt256& freeze_due_limit, @@ -157,7 +159,7 @@ struct CreditPhase { }; struct ComputePhase { - enum { sk_none, sk_no_state, sk_bad_state, sk_no_gas }; + enum { sk_none, sk_no_state, sk_bad_state, sk_no_gas, sk_suspended }; int skip_reason{sk_none}; bool success{false}; bool msg_state_used{false}; diff --git a/validator/impl/collator-impl.h b/validator/impl/collator-impl.h index c13049cf..8fd8dc0c 100644 --- a/validator/impl/collator-impl.h +++ b/validator/impl/collator-impl.h @@ -114,7 +114,7 @@ class Collator final : public td::actor::Actor { block::ActionPhaseConfig* action_phase_cfg, td::RefInt256* masterchain_create_fee, td::RefInt256* basechain_create_fee, - WorkchainId wc); + WorkchainId wc, UnixTime now); static td::Result> impl_create_ordinary_transaction(Ref msg_root, diff --git a/validator/impl/collator.cpp b/validator/impl/collator.cpp index 91ff17a2..fb18d8be 100644 --- a/validator/impl/collator.cpp +++ b/validator/impl/collator.cpp @@ -1563,7 +1563,7 @@ bool Collator::init_lt() { bool Collator::fetch_config_params() { auto res = impl_fetch_config_params(std::move(config_), &old_mparams_, &storage_prices_, &storage_phase_cfg_, &rand_seed_, &compute_phase_cfg_, &action_phase_cfg_, &masterchain_create_fee_, - &basechain_create_fee_, workchain()); + &basechain_create_fee_, workchain(), now_); if (res.is_error()) { return fatal_error(res.move_as_error()); } @@ -1576,7 +1576,7 @@ td::Result> Collator::impl_fetch_config_param std::vector* storage_prices, block::StoragePhaseConfig* storage_phase_cfg, td::BitArray<256>* rand_seed, block::ComputePhaseConfig* compute_phase_cfg, block::ActionPhaseConfig* action_phase_cfg, td::RefInt256* masterchain_create_fee, - td::RefInt256* basechain_create_fee, WorkchainId wc) { + td::RefInt256* basechain_create_fee, WorkchainId wc, UnixTime now) { *old_mparams = config->get_config_param(9); { auto res = config->get_storage_prices(); @@ -1605,6 +1605,7 @@ td::Result> Collator::impl_fetch_config_param compute_phase_cfg->libraries = std::make_unique(config->get_libraries_root(), 256); compute_phase_cfg->max_vm_data_depth = size_limits.max_vm_data_depth; compute_phase_cfg->global_config = config->get_root_cell(); + compute_phase_cfg->suspended_addresses = config->get_suspended_addresses(now); } { // compute action_phase_cfg diff --git a/validator/impl/external-message.cpp b/validator/impl/external-message.cpp index ca8e6e48..5d3028db 100644 --- a/validator/impl/external-message.cpp +++ b/validator/impl/external-message.cpp @@ -147,7 +147,7 @@ td::Status ExtMessageQ::run_message_on_account(ton::WorkchainId wc, &storage_prices_, &storage_phase_cfg_, &rand_seed_, &compute_phase_cfg_, &action_phase_cfg_, &masterchain_create_fee, - &basechain_create_fee, wc); + &basechain_create_fee, wc, utime); if(fetch_res.is_error()) { auto error = fetch_res.move_as_error(); LOG(DEBUG) << "Cannot fetch config params: " << error.message(); diff --git a/validator/impl/validate-query.cpp b/validator/impl/validate-query.cpp index d8ba17fe..4d751f33 100644 --- a/validator/impl/validate-query.cpp +++ b/validator/impl/validate-query.cpp @@ -786,6 +786,7 @@ bool ValidateQuery::fetch_config_params() { compute_phase_cfg_.libraries = std::make_unique(config_->get_libraries_root(), 256); compute_phase_cfg_.max_vm_data_depth = size_limits.max_vm_data_depth; compute_phase_cfg_.global_config = config_->get_root_cell(); + compute_phase_cfg_.suspended_addresses = config_->get_suspended_addresses(now_); } { // compute action_phase_cfg