mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-15 04:32:21 +00:00
SuspendedAddressList config param (#585)
* SuspendedAddressList config param * Change tag for cskip_suspended
This commit is contained in:
parent
41ea3ef5b7
commit
13b9f460af
10 changed files with 53 additions and 9 deletions
|
@ -653,16 +653,20 @@ struct TrComputeInternal1 final : TLB_Complex {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComputeSkipReason final : TLB {
|
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 {
|
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 {
|
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 get_tag(const vm::CellSlice& cs) const override {
|
||||||
int t = (int)cs.prefetch_ulong(2);
|
int t = (int)cs.prefetch_ulong(2);
|
||||||
return t < 3 ? t : -1;
|
if (t == 3 && cs.prefetch_ulong(3) != 0b110) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -309,6 +309,7 @@ tr_phase_compute_vm$1 success:Bool msg_state_used:Bool
|
||||||
cskip_no_state$00 = ComputeSkipReason;
|
cskip_no_state$00 = ComputeSkipReason;
|
||||||
cskip_bad_state$01 = ComputeSkipReason;
|
cskip_bad_state$01 = ComputeSkipReason;
|
||||||
cskip_no_gas$10 = ComputeSkipReason;
|
cskip_no_gas$10 = ComputeSkipReason;
|
||||||
|
cskip_suspended$110 = ComputeSkipReason;
|
||||||
|
|
||||||
tr_phase_action$_ success:Bool valid:Bool no_funds:Bool
|
tr_phase_action$_ success:Bool valid:Bool no_funds:Bool
|
||||||
status_change:AccStatusChange
|
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;
|
max_ext_msg_size:uint32 max_ext_msg_depth:uint16 max_acc_state_cells:uint32 max_acc_state_bits:uint32 = SizeLimitsConfig;
|
||||||
_ SizeLimitsConfig = ConfigParam 43;
|
_ 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;
|
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 71; // Ethereum bridge
|
||||||
_ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge
|
_ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge
|
||||||
|
|
|
@ -1945,6 +1945,15 @@ td::Result<SizeLimitsConfig> Config::get_size_limits_config() const {
|
||||||
return limits;
|
return limits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<vm::Dictionary> Config::get_suspended_addresses(ton::UnixTime now) const {
|
||||||
|
td::Ref<vm::Cell> 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<vm::Dictionary>(rec.addresses->prefetch_ref(), 288);
|
||||||
|
}
|
||||||
|
|
||||||
td::Result<std::pair<ton::UnixTime, ton::UnixTime>> Config::unpack_validator_set_start_stop(Ref<vm::Cell> vset_root) {
|
td::Result<std::pair<ton::UnixTime, ton::UnixTime>> Config::unpack_validator_set_start_stop(Ref<vm::Cell> vset_root) {
|
||||||
if (vset_root.is_null()) {
|
if (vset_root.is_null()) {
|
||||||
return td::Status::Error("validator set absent");
|
return td::Status::Error("validator set absent");
|
||||||
|
|
|
@ -616,6 +616,7 @@ class Config {
|
||||||
ton::CatchainSeqno cc_seqno) const;
|
ton::CatchainSeqno cc_seqno) const;
|
||||||
std::vector<ton::ValidatorDescr> compute_total_validator_set(int next) const;
|
std::vector<ton::ValidatorDescr> compute_total_validator_set(int next) const;
|
||||||
td::Result<SizeLimitsConfig> get_size_limits_config() const;
|
td::Result<SizeLimitsConfig> get_size_limits_config() const;
|
||||||
|
std::unique_ptr<vm::Dictionary> get_suspended_addresses(ton::UnixTime now) const;
|
||||||
static std::vector<ton::ValidatorDescr> do_compute_validator_set(const block::CatchainValidatorsConfig& ccv_conf,
|
static std::vector<ton::ValidatorDescr> do_compute_validator_set(const block::CatchainValidatorsConfig& ccv_conf,
|
||||||
ton::ShardIdFull shard,
|
ton::ShardIdFull shard,
|
||||||
const block::ValidatorSet& vset, ton::UnixTime time,
|
const block::ValidatorSet& vset, ton::UnixTime time,
|
||||||
|
|
|
@ -794,6 +794,20 @@ bool ComputePhaseConfig::parse_GasLimitsPrices_internal(Ref<vm::CellSlice> cs, t
|
||||||
return true;
|
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() {
|
void ComputePhaseConfig::compute_threshold() {
|
||||||
gas_price256 = td::make_refint(gas_price);
|
gas_price256 = td::make_refint(gas_price);
|
||||||
if (gas_limit > flat_gas_limit) {
|
if (gas_limit > flat_gas_limit) {
|
||||||
|
@ -1006,6 +1020,11 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
||||||
if (in_msg_state.not_null() &&
|
if (in_msg_state.not_null() &&
|
||||||
(acc_status == Account::acc_uninit ||
|
(acc_status == Account::acc_uninit ||
|
||||||
(acc_status == Account::acc_frozen && account.state_hash == in_msg_state->get_hash().bits()))) {
|
(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;
|
use_msg_state = true;
|
||||||
if (!(unpack_msg_state() && account.check_split_depth(new_split_depth))) {
|
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";
|
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;
|
return cb.store_long_bool(1, 3); // cskip_bad_state$01 = ComputeSkipReason;
|
||||||
case ComputePhase::sk_no_gas:
|
case ComputePhase::sk_no_gas:
|
||||||
return cb.store_long_bool(2, 3); // cskip_no_gas$10 = ComputeSkipReason;
|
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:
|
case ComputePhase::sk_none:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -108,6 +108,7 @@ struct ComputePhaseConfig {
|
||||||
td::BitArray<256> block_rand_seed;
|
td::BitArray<256> block_rand_seed;
|
||||||
bool with_vm_log{false};
|
bool with_vm_log{false};
|
||||||
td::uint16 max_vm_data_depth = 512;
|
td::uint16 max_vm_data_depth = 512;
|
||||||
|
std::unique_ptr<vm::Dictionary> suspended_addresses;
|
||||||
ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0)
|
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) {
|
: gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) {
|
||||||
compute_threshold();
|
compute_threshold();
|
||||||
|
@ -132,6 +133,7 @@ struct ComputePhaseConfig {
|
||||||
}
|
}
|
||||||
bool parse_GasLimitsPrices(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
bool parse_GasLimitsPrices(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
||||||
bool parse_GasLimitsPrices(Ref<vm::Cell> cell, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
bool parse_GasLimitsPrices(Ref<vm::Cell> cell, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
||||||
|
bool is_address_suspended(ton::WorkchainId wc, td::Bits256 addr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parse_GasLimitsPrices_internal(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit,
|
bool parse_GasLimitsPrices_internal(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit,
|
||||||
|
@ -157,7 +159,7 @@ struct CreditPhase {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComputePhase {
|
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};
|
int skip_reason{sk_none};
|
||||||
bool success{false};
|
bool success{false};
|
||||||
bool msg_state_used{false};
|
bool msg_state_used{false};
|
||||||
|
|
|
@ -114,7 +114,7 @@ class Collator final : public td::actor::Actor {
|
||||||
block::ActionPhaseConfig* action_phase_cfg,
|
block::ActionPhaseConfig* action_phase_cfg,
|
||||||
td::RefInt256* masterchain_create_fee,
|
td::RefInt256* masterchain_create_fee,
|
||||||
td::RefInt256* basechain_create_fee,
|
td::RefInt256* basechain_create_fee,
|
||||||
WorkchainId wc);
|
WorkchainId wc, UnixTime now);
|
||||||
|
|
||||||
static td::Result<std::unique_ptr<block::Transaction>>
|
static td::Result<std::unique_ptr<block::Transaction>>
|
||||||
impl_create_ordinary_transaction(Ref<vm::Cell> msg_root,
|
impl_create_ordinary_transaction(Ref<vm::Cell> msg_root,
|
||||||
|
|
|
@ -1563,7 +1563,7 @@ bool Collator::init_lt() {
|
||||||
bool Collator::fetch_config_params() {
|
bool Collator::fetch_config_params() {
|
||||||
auto res = impl_fetch_config_params(std::move(config_), &old_mparams_, &storage_prices_, &storage_phase_cfg_,
|
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_,
|
&rand_seed_, &compute_phase_cfg_, &action_phase_cfg_, &masterchain_create_fee_,
|
||||||
&basechain_create_fee_, workchain());
|
&basechain_create_fee_, workchain(), now_);
|
||||||
if (res.is_error()) {
|
if (res.is_error()) {
|
||||||
return fatal_error(res.move_as_error());
|
return fatal_error(res.move_as_error());
|
||||||
}
|
}
|
||||||
|
@ -1576,7 +1576,7 @@ td::Result<std::unique_ptr<block::ConfigInfo>> Collator::impl_fetch_config_param
|
||||||
std::vector<block::StoragePrices>* storage_prices, block::StoragePhaseConfig* storage_phase_cfg,
|
std::vector<block::StoragePrices>* storage_prices, block::StoragePhaseConfig* storage_phase_cfg,
|
||||||
td::BitArray<256>* rand_seed, block::ComputePhaseConfig* compute_phase_cfg,
|
td::BitArray<256>* rand_seed, block::ComputePhaseConfig* compute_phase_cfg,
|
||||||
block::ActionPhaseConfig* action_phase_cfg, td::RefInt256* masterchain_create_fee,
|
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);
|
*old_mparams = config->get_config_param(9);
|
||||||
{
|
{
|
||||||
auto res = config->get_storage_prices();
|
auto res = config->get_storage_prices();
|
||||||
|
@ -1605,6 +1605,7 @@ td::Result<std::unique_ptr<block::ConfigInfo>> Collator::impl_fetch_config_param
|
||||||
compute_phase_cfg->libraries = std::make_unique<vm::Dictionary>(config->get_libraries_root(), 256);
|
compute_phase_cfg->libraries = std::make_unique<vm::Dictionary>(config->get_libraries_root(), 256);
|
||||||
compute_phase_cfg->max_vm_data_depth = size_limits.max_vm_data_depth;
|
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->global_config = config->get_root_cell();
|
||||||
|
compute_phase_cfg->suspended_addresses = config->get_suspended_addresses(now);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// compute action_phase_cfg
|
// compute action_phase_cfg
|
||||||
|
|
|
@ -147,7 +147,7 @@ td::Status ExtMessageQ::run_message_on_account(ton::WorkchainId wc,
|
||||||
&storage_prices_, &storage_phase_cfg_,
|
&storage_prices_, &storage_phase_cfg_,
|
||||||
&rand_seed_, &compute_phase_cfg_,
|
&rand_seed_, &compute_phase_cfg_,
|
||||||
&action_phase_cfg_, &masterchain_create_fee,
|
&action_phase_cfg_, &masterchain_create_fee,
|
||||||
&basechain_create_fee, wc);
|
&basechain_create_fee, wc, utime);
|
||||||
if(fetch_res.is_error()) {
|
if(fetch_res.is_error()) {
|
||||||
auto error = fetch_res.move_as_error();
|
auto error = fetch_res.move_as_error();
|
||||||
LOG(DEBUG) << "Cannot fetch config params: " << error.message();
|
LOG(DEBUG) << "Cannot fetch config params: " << error.message();
|
||||||
|
|
|
@ -786,6 +786,7 @@ bool ValidateQuery::fetch_config_params() {
|
||||||
compute_phase_cfg_.libraries = std::make_unique<vm::Dictionary>(config_->get_libraries_root(), 256);
|
compute_phase_cfg_.libraries = std::make_unique<vm::Dictionary>(config_->get_libraries_root(), 256);
|
||||||
compute_phase_cfg_.max_vm_data_depth = size_limits.max_vm_data_depth;
|
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_.global_config = config_->get_root_cell();
|
||||||
|
compute_phase_cfg_.suspended_addresses = config_->get_suspended_addresses(now_);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// compute action_phase_cfg
|
// compute action_phase_cfg
|
||||||
|
|
Loading…
Reference in a new issue