1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

updated vm

- updated func/fift
- additional checks in block validator
- docs
- tunnel prototype in ADNL
This commit is contained in:
ton 2020-03-11 14:19:31 +04:00
parent ba76f1404e
commit 54c7a4dcc3
50 changed files with 972 additions and 300 deletions

View file

@ -20,6 +20,7 @@
#include "block/block.h"
#include "block/block-auto.h"
#include "block/block-parse.h"
#include "block/mc-config.h"
#include "ton/ton-shard.h"
#include "common/bigexp.h"
#include "common/util.h"
@ -1602,33 +1603,46 @@ bool check_one_config_param(Ref<vm::CellSlice> cs_ref, td::ConstBitPtr key, td::
const int mandatory_config_params[] = {18, 20, 21, 22, 23, 24, 25, 28, 34};
bool valid_config_data(Ref<vm::Cell> cell, const td::BitArray<256>& addr, bool catch_errors, bool relax_par0) {
bool valid_config_data(Ref<vm::Cell> cell, const td::BitArray<256>& addr, bool catch_errors, bool relax_par0,
Ref<vm::Cell> old_mparams) {
using namespace std::placeholders;
if (cell.is_null()) {
return false;
}
if (!catch_errors) {
vm::Dictionary dict{std::move(cell), 32};
for (int x : mandatory_config_params) {
if (!dict.int_key_exists(x)) {
LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing";
return false;
}
if (catch_errors) {
try {
return valid_config_data(std::move(cell), addr, false, relax_par0, std::move(old_mparams));
} catch (vm::VmError&) {
return false;
}
return dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0));
}
try {
vm::Dictionary dict{std::move(cell), 32};
for (int x : mandatory_config_params) {
if (!dict.int_key_exists(x)) {
LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing";
return false;
}
}
return dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0));
} catch (vm::VmError&) {
vm::Dictionary dict{std::move(cell), 32};
if (!dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0))) {
return false;
}
for (int x : mandatory_config_params) {
if (!dict.int_key_exists(x)) {
LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing";
return false;
}
}
return config_params_present(dict, dict.lookup_ref(td::BitArray<32>{9})) &&
config_params_present(dict, std::move(old_mparams));
}
bool config_params_present(vm::Dictionary& dict, Ref<vm::Cell> param_dict_root) {
auto res = block::Config::unpack_param_dict(std::move(param_dict_root));
if (res.is_error()) {
return false;
}
for (int x : res.move_as_ok()) {
if (!dict.int_key_exists(x)) {
LOG(ERROR) << "configuration parameter #" << x
<< " (declared as mandatory in configuration parameter #9) is missing";
return false;
}
}
return true;
}
bool add_extra_currency(Ref<vm::Cell> extra1, Ref<vm::Cell> extra2, Ref<vm::Cell>& res) {

View file

@ -606,7 +606,8 @@ bool unpack_CurrencyCollection(Ref<vm::CellSlice> csr, td::RefInt256& value, Ref
bool valid_library_collection(Ref<vm::Cell> cell, bool catch_errors = true);
bool valid_config_data(Ref<vm::Cell> cell, const td::BitArray<256>& addr, bool catch_errors = true,
bool relax_par0 = false);
bool relax_par0 = false, Ref<vm::Cell> old_mparams = {});
bool config_params_present(vm::Dictionary& dict, Ref<vm::Cell> param_dict_root);
bool add_extra_currency(Ref<vm::Cell> extra1, Ref<vm::Cell> extra2, Ref<vm::Cell>& res);
bool sub_extra_currency(Ref<vm::Cell> extra1, Ref<vm::Cell> extra2, Ref<vm::Cell>& res);

View file

@ -572,6 +572,7 @@ _ to_mint:ExtraCurrencyCollection = ConfigParam 7;
capabilities#c4 version:uint32 capabilities:uint64 = GlobalVersion;
_ GlobalVersion = ConfigParam 8; // all zero if absent
_ mandatory_params:(Hashmap 32 True) = ConfigParam 9;
_ critical_params:(Hashmap 32 True) = ConfigParam 10;
wfmt_basic#1 vm_version:int32 vm_mode:uint64 = WorkchainFormat 1;
wfmt_ext#0 min_addr_len:(## 12) max_addr_len:(## 12) addr_len_step:(## 12)

View file

@ -40,6 +40,7 @@
#include <algorithm>
namespace block {
using namespace std::literals::string_literals;
using td::Ref;
Config::Config(Ref<vm::Cell> config_root, const td::Bits256& config_addr, int _mode)
@ -335,6 +336,59 @@ std::unique_ptr<vm::Dictionary> ShardConfig::extract_shard_hashes_dict(Ref<vm::C
}
}
td::Result<std::vector<int>> Config::unpack_param_dict(vm::Dictionary& dict) {
try {
std::vector<int> vect;
if (dict.check_for_each(
[&vect](Ref<vm::CellSlice> value, td::ConstBitPtr key, int key_len) {
bool ok = (key_len == 32 && value->empty_ext());
if (ok) {
vect.push_back((int)key.get_int(32));
}
return ok;
},
true)) {
return std::move(vect);
} else {
return td::Status::Error("invalid parameter list dictionary");
}
} catch (vm::VmError& vme) {
return td::Status::Error("error unpacking parameter list dictionary: "s + vme.get_msg());
}
}
td::Result<std::vector<int>> Config::unpack_param_dict(Ref<vm::Cell> dict_root) {
vm::Dictionary dict{std::move(dict_root), 32};
return unpack_param_dict(dict);
}
std::unique_ptr<vm::Dictionary> Config::get_param_dict(int idx) const {
return std::make_unique<vm::Dictionary>(get_config_param(idx), 32);
}
td::Result<std::vector<int>> Config::unpack_param_list(int idx) const {
return unpack_param_dict(*get_param_dict(idx));
}
bool Config::all_mandatory_params_defined(int* bad_idx_ptr) const {
auto res = get_mandatory_param_list();
if (res.is_error()) {
if (bad_idx_ptr) {
*bad_idx_ptr = -1;
}
return false;
}
for (int x : res.move_as_ok()) {
if (get_config_param(x).is_null()) {
if (bad_idx_ptr) {
*bad_idx_ptr = x;
}
return false;
}
}
return true;
}
std::unique_ptr<vm::AugmentedDictionary> ConfigInfo::create_accounts_dict() const {
if (mode & needAccountsRoot) {
return std::make_unique<vm::AugmentedDictionary>(accounts_root, 256, block::tlb::aug_ShardAccounts);

View file

@ -534,6 +534,21 @@ class Config {
bool create_stats_enabled() const {
return has_capability(ton::capCreateStatsEnabled);
}
std::unique_ptr<vm::Dictionary> get_param_dict(int idx) const;
td::Result<std::vector<int>> unpack_param_list(int idx) const;
std::unique_ptr<vm::Dictionary> get_mandatory_param_dict() const {
return get_param_dict(9);
}
std::unique_ptr<vm::Dictionary> get_critical_param_dict() const {
return get_param_dict(10);
}
td::Result<std::vector<int>> get_mandatory_param_list() const {
return unpack_param_list(9);
}
td::Result<std::vector<int>> get_critical_param_list() const {
return unpack_param_list(10);
}
bool all_mandatory_params_defined(int* bad_idx_ptr = nullptr) const;
td::Result<ton::StdSmcAddress> get_dns_root_addr() const;
bool set_block_id_ext(const ton::BlockIdExt& block_id_ext);
td::Result<std::vector<ton::StdSmcAddress>> get_special_smartcontracts(bool without_config = false) const;
@ -580,6 +595,8 @@ class Config {
static td::Result<std::unique_ptr<Config>> extract_from_state(Ref<vm::Cell> mc_state_root, int mode = 0);
static td::Result<std::unique_ptr<Config>> extract_from_key_block(Ref<vm::Cell> key_block_root, int mode = 0);
static td::Result<std::pair<ton::UnixTime, ton::UnixTime>> unpack_validator_set_start_stop(Ref<vm::Cell> root);
static td::Result<std::vector<int>> unpack_param_dict(vm::Dictionary& dict);
static td::Result<std::vector<int>> unpack_param_dict(Ref<vm::Cell> dict_root);
protected:
Config(int _mode) : mode(_mode) {