mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'testnet' into block-generation
This commit is contained in:
commit
1ccf25d6b7
60 changed files with 706 additions and 236 deletions
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -762,6 +763,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
|
||||
|
@ -883,6 +888,8 @@ cap_method_pubkey#71f4 = SmcCapability;
|
|||
cap_is_wallet#2177 = SmcCapability;
|
||||
cap_name#ff name:Text = SmcCapability;
|
||||
|
||||
dns_storage_address#7473 bag_id:bits256 = DNSRecord;
|
||||
|
||||
//
|
||||
// PAYMENT CHANNELS
|
||||
//
|
||||
|
|
|
@ -1945,6 +1945,15 @@ td::Result<SizeLimitsConfig> Config::get_size_limits_config() const {
|
|||
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) {
|
||||
if (vset_root.is_null()) {
|
||||
return td::Status::Error("validator set absent");
|
||||
|
|
|
@ -628,6 +628,7 @@ class Config {
|
|||
std::vector<ton::ValidatorDescr> compute_total_validator_set(int next) const;
|
||||
CollatorConfig get_collator_config(bool need_collator_nodes) 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,
|
||||
ton::ShardIdFull shard,
|
||||
const block::ValidatorSet& vset, ton::UnixTime time,
|
||||
|
|
|
@ -794,6 +794,20 @@ bool ComputePhaseConfig::parse_GasLimitsPrices_internal(Ref<vm::CellSlice> 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:
|
||||
|
|
|
@ -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<vm::Dictionary> 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<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 is_address_suspended(ton::WorkchainId wc, td::Bits256 addr) const;
|
||||
|
||||
private:
|
||||
bool parse_GasLimitsPrices_internal(Ref<vm::CellSlice> 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};
|
||||
|
|
|
@ -810,6 +810,7 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
|
|||
break;
|
||||
}
|
||||
case _While: {
|
||||
auto values0 = values;
|
||||
values = block0->fwd_analyze(values);
|
||||
if (values[left[0]] && values[left[0]]->always_false()) {
|
||||
// block1 never executed
|
||||
|
@ -817,7 +818,7 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
|
|||
break;
|
||||
}
|
||||
while (true) {
|
||||
VarDescrList next_values = values | block0->fwd_analyze(block1->fwd_analyze(values));
|
||||
VarDescrList next_values = values | block0->fwd_analyze(values0 | block1->fwd_analyze(values));
|
||||
if (same_values(next_values, values)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -137,13 +137,20 @@ class CodeRepeat(Code):
|
|||
self.c.write(f, indent + 1)
|
||||
print(" " * (indent + 1) + "%s += 1;" % var, file=f)
|
||||
print(" " * indent + "}", file=f)
|
||||
else:
|
||||
elif self.loop_type == 2:
|
||||
var = gen_var_name()
|
||||
print(" " * indent + "int %s = 0;" % var, file=f)
|
||||
print(" " * indent + "do {", file=f)
|
||||
self.c.write(f, indent + 1)
|
||||
print(" " * (indent + 1) + "%s += 1;" % var, file=f)
|
||||
print(" " * indent + "} until (%s >= %d);" % (var, self.n), file=f)
|
||||
else:
|
||||
var = gen_var_name()
|
||||
print(" " * indent + "int %s = %d;" % (var, self.n - 1), file=f)
|
||||
print(" " * indent + "while (%s >= 0) {" % var, file=f)
|
||||
self.c.write(f, indent + 1)
|
||||
print(" " * (indent + 1) + "%s -= 1;" % var, file=f)
|
||||
print(" " * indent + "}", file=f)
|
||||
|
||||
class CodeThrow(Code):
|
||||
def __init__(self):
|
||||
|
@ -199,7 +206,7 @@ def gen_code(xl, xr, with_return, loop_depth=0, try_catch_depth=0, can_throw=Fal
|
|||
for _ in range(random.randint(0, 2)):
|
||||
if random.randint(0, 3) == 0 and loop_depth < 3:
|
||||
c = gen_code(xl, xr, False, loop_depth + 1, try_catch_depth, can_throw)
|
||||
code.append(CodeRepeat(random.randint(0, 3), c, random.randint(0, 2)))
|
||||
code.append(CodeRepeat(random.randint(0, 3), c, random.randint(0, 3)))
|
||||
elif xr - xl > 1:
|
||||
xmid = random.randrange(xl + 1, xr)
|
||||
ret = random.choice((0, 0, 0, 0, 0, 1, 2))
|
||||
|
|
|
@ -39,7 +39,7 @@ extern std::string generated_from;
|
|||
|
||||
constexpr int optimize_depth = 20;
|
||||
|
||||
const std::string func_version{"0.3.0"};
|
||||
const std::string func_version{"0.4.0"};
|
||||
|
||||
enum Keyword {
|
||||
_Eof = -1,
|
||||
|
@ -306,10 +306,16 @@ struct TmpVar {
|
|||
sym_idx_t name;
|
||||
int coord;
|
||||
std::unique_ptr<SrcLocation> where;
|
||||
size_t modify_forbidden = 0;
|
||||
TmpVar(var_idx_t _idx, int _cls, TypeExpr* _type = 0, SymDef* sym = 0, const SrcLocation* loc = 0);
|
||||
void show(std::ostream& os, int omit_idx = 0) const;
|
||||
void dump(std::ostream& os) const;
|
||||
void set_location(const SrcLocation& loc);
|
||||
std::string to_string() const {
|
||||
std::ostringstream s;
|
||||
show(s, 2);
|
||||
return s.str();
|
||||
}
|
||||
};
|
||||
|
||||
struct VarDescr {
|
||||
|
@ -722,6 +728,22 @@ struct CodeBlob {
|
|||
void mark_noreturn();
|
||||
void generate_code(AsmOpList& out_list, int mode = 0);
|
||||
void generate_code(std::ostream& os, int mode = 0, int indent = 0);
|
||||
|
||||
void mark_modify_forbidden(var_idx_t idx) {
|
||||
++vars.at(idx).modify_forbidden;
|
||||
}
|
||||
|
||||
void unmark_modify_forbidden(var_idx_t idx) {
|
||||
assert(vars.at(idx).modify_forbidden > 0);
|
||||
--vars.at(idx).modify_forbidden;
|
||||
}
|
||||
|
||||
void check_modify_forbidden(var_idx_t idx, const SrcLocation& here) const {
|
||||
if (vars.at(idx).modify_forbidden) {
|
||||
throw src::ParseError{here, PSTRING() << "Modifying local variable " << vars[idx].to_string()
|
||||
<< " after using it in the same expression"};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -925,7 +947,7 @@ struct Expr {
|
|||
}
|
||||
int define_new_vars(CodeBlob& code);
|
||||
int predefine_vars();
|
||||
std::vector<var_idx_t> pre_compile(CodeBlob& code, bool lval = false) const;
|
||||
std::vector<var_idx_t> pre_compile(CodeBlob& code, std::vector<std::pair<SymDef*, var_idx_t>>* lval_globs = nullptr) const;
|
||||
static std::vector<var_idx_t> pre_compile_let(CodeBlob& code, Expr* lhs, Expr* rhs, const SrcLocation& here);
|
||||
var_idx_t new_tmp(CodeBlob& code) const;
|
||||
std::vector<var_idx_t> new_tmp_vect(CodeBlob& code) const {
|
||||
|
|
|
@ -221,6 +221,13 @@ var_idx_t Expr::new_tmp(CodeBlob& code) const {
|
|||
return code.create_tmp_var(e_type, &here);
|
||||
}
|
||||
|
||||
void add_set_globs(CodeBlob& code, std::vector<std::pair<SymDef*, var_idx_t>>& globs, const SrcLocation& here) {
|
||||
for (const auto& p : globs) {
|
||||
auto& op = code.emplace_back(here, Op::_SetGlob, std::vector<var_idx_t>{}, std::vector<var_idx_t>{ p.second }, p.first);
|
||||
op.flags |= Op::_Impure;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<var_idx_t> Expr::pre_compile_let(CodeBlob& code, Expr* lhs, Expr* rhs, const SrcLocation& here) {
|
||||
while (lhs->is_type_apply()) {
|
||||
lhs = lhs->args.at(0);
|
||||
|
@ -245,19 +252,18 @@ std::vector<var_idx_t> Expr::pre_compile_let(CodeBlob& code, Expr* lhs, Expr* rh
|
|||
return tmp;
|
||||
}
|
||||
auto right = rhs->pre_compile(code);
|
||||
if (lhs->cls == Expr::_GlobVar) {
|
||||
assert(lhs->sym);
|
||||
auto& op = code.emplace_back(here, Op::_SetGlob, std::vector<var_idx_t>{}, right, lhs->sym);
|
||||
op.flags |= Op::_Impure;
|
||||
} else {
|
||||
auto left = lhs->pre_compile(code, true);
|
||||
code.emplace_back(here, Op::_Let, std::move(left), right);
|
||||
std::vector<std::pair<SymDef*, var_idx_t>> globs;
|
||||
auto left = lhs->pre_compile(code, &globs);
|
||||
for (var_idx_t v : left) {
|
||||
code.check_modify_forbidden(v, here);
|
||||
}
|
||||
code.emplace_back(here, Op::_Let, std::move(left), right);
|
||||
add_set_globs(code, globs, here);
|
||||
return right;
|
||||
}
|
||||
|
||||
std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
||||
if (lval && !(cls == _Tensor || cls == _Var || cls == _Hole || cls == _TypeApply)) {
|
||||
std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, std::vector<std::pair<SymDef*, var_idx_t>>* lval_globs) const {
|
||||
if (lval_globs && !(cls == _Tensor || cls == _Var || cls == _Hole || cls == _TypeApply || cls == _GlobVar)) {
|
||||
std::cerr << "lvalue expression constructor is " << cls << std::endl;
|
||||
throw src::Fatal{"cannot compile lvalue expression with unknown constructor"};
|
||||
}
|
||||
|
@ -265,9 +271,15 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
case _Tensor: {
|
||||
std::vector<var_idx_t> res;
|
||||
for (const auto& x : args) {
|
||||
auto add = x->pre_compile(code, lval);
|
||||
auto add = x->pre_compile(code, lval_globs);
|
||||
for (var_idx_t v : add) {
|
||||
code.mark_modify_forbidden(v);
|
||||
}
|
||||
res.insert(res.end(), add.cbegin(), add.cend());
|
||||
}
|
||||
for (var_idx_t v : res) {
|
||||
code.unmark_modify_forbidden(v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
case _Apply: {
|
||||
|
@ -279,6 +291,9 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
std::vector<std::vector<var_idx_t>> add_list(args.size());
|
||||
for (int i : func->arg_order) {
|
||||
add_list[i] = args[i]->pre_compile(code);
|
||||
for (var_idx_t v : add_list[i]) {
|
||||
code.mark_modify_forbidden(v);
|
||||
}
|
||||
}
|
||||
for (const auto& add : add_list) {
|
||||
res.insert(res.end(), add.cbegin(), add.cend());
|
||||
|
@ -286,9 +301,15 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
} else {
|
||||
for (const auto& x : args) {
|
||||
auto add = x->pre_compile(code);
|
||||
for (var_idx_t v : add) {
|
||||
code.mark_modify_forbidden(v);
|
||||
}
|
||||
res.insert(res.end(), add.cbegin(), add.cend());
|
||||
}
|
||||
}
|
||||
for (var_idx_t v : res) {
|
||||
code.unmark_modify_forbidden(v);
|
||||
}
|
||||
auto rvect = new_tmp_vect(code);
|
||||
auto& op = code.emplace_back(here, Op::_Call, rvect, std::move(res), sym);
|
||||
if (flags & _IsImpure) {
|
||||
|
@ -297,7 +318,7 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
return rvect;
|
||||
}
|
||||
case _TypeApply:
|
||||
return args[0]->pre_compile(code, lval);
|
||||
return args[0]->pre_compile(code, lval_globs);
|
||||
case _Var:
|
||||
case _Hole:
|
||||
return {val};
|
||||
|
@ -329,8 +350,13 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
case _Glob:
|
||||
case _GlobVar: {
|
||||
auto rvect = new_tmp_vect(code);
|
||||
code.emplace_back(here, Op::_GlobVar, rvect, std::vector<var_idx_t>{}, sym);
|
||||
return rvect;
|
||||
if (lval_globs) {
|
||||
lval_globs->push_back({ sym, rvect[0] });
|
||||
return rvect;
|
||||
} else {
|
||||
code.emplace_back(here, Op::_GlobVar, rvect, std::vector<var_idx_t>{}, sym);
|
||||
return rvect;
|
||||
}
|
||||
}
|
||||
case _Letop: {
|
||||
return pre_compile_let(code, args.at(0), args.at(1), here);
|
||||
|
@ -338,9 +364,17 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
|
|||
case _LetFirst: {
|
||||
auto rvect = new_tmp_vect(code);
|
||||
auto right = args[1]->pre_compile(code);
|
||||
auto left = args[0]->pre_compile(code, true);
|
||||
std::vector<std::pair<SymDef*, var_idx_t>> local_globs;
|
||||
if (!lval_globs) {
|
||||
lval_globs = &local_globs;
|
||||
}
|
||||
auto left = args[0]->pre_compile(code, lval_globs);
|
||||
left.push_back(rvect[0]);
|
||||
for (var_idx_t v : left) {
|
||||
code.check_modify_forbidden(v, here);
|
||||
}
|
||||
code.emplace_back(here, Op::_Let, std::move(left), std::move(right));
|
||||
add_set_globs(code, local_globs, here);
|
||||
return rvect;
|
||||
}
|
||||
case _MkTuple: {
|
||||
|
|
|
@ -47,6 +47,8 @@ td::StringBuilder& operator<<(td::StringBuilder& sb, const ManualDns::EntryData&
|
|||
.move_as_ok();
|
||||
case ManualDns::EntryData::Type::SmcAddress:
|
||||
return sb << "SMC:" << data.data.get<ManualDns::EntryDataSmcAddress>().smc_address.rserialize();
|
||||
case ManualDns::EntryData::Type::StorageAddress:
|
||||
return sb << "STORAGE:" << data.data.get<ManualDns::EntryDataStorageAddress>().bag_id.to_hex();
|
||||
}
|
||||
return sb << "<unknown>";
|
||||
}
|
||||
|
@ -93,6 +95,11 @@ td::Result<td::Ref<vm::Cell>> DnsInterface::EntryData::as_cell() const {
|
|||
smc_address.smc_address.addr);
|
||||
dns.smc_addr = vm::load_cell_slice_ref(cb.finalize());
|
||||
tlb::pack_cell(res, dns);
|
||||
},
|
||||
[&](const EntryDataStorageAddress& storage_address) {
|
||||
block::gen::DNSRecord::Record_dns_storage_address dns;
|
||||
dns.bag_id = storage_address.bag_id;
|
||||
tlb::pack_cell(res, dns);
|
||||
}));
|
||||
if (error.is_error()) {
|
||||
return error;
|
||||
|
@ -142,6 +149,11 @@ td::Result<DnsInterface::EntryData> DnsInterface::EntryData::from_cellslice(vm::
|
|||
}
|
||||
return EntryData::smc_address(block::StdAddress(wc, addr));
|
||||
}
|
||||
case block::gen::DNSRecord::dns_storage_address: {
|
||||
block::gen::DNSRecord::Record_dns_storage_address dns;
|
||||
tlb::unpack(cs, dns);
|
||||
return EntryData::storage_address(dns.bag_id);
|
||||
}
|
||||
}
|
||||
return td::Status::Error("Unknown entry data");
|
||||
}
|
||||
|
@ -536,10 +548,12 @@ std::string DnsInterface::decode_name(td::Slice name) {
|
|||
|
||||
std::string ManualDns::serialize_data(const EntryData& data) {
|
||||
std::string res;
|
||||
data.data.visit(td::overloaded([&](const ton::ManualDns::EntryDataText& text) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataNextResolver& resolver) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataAdnlAddress& adnl_address) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataSmcAddress& text) { res = "UNSUPPORTED"; }));
|
||||
data.data.visit(
|
||||
td::overloaded([&](const ton::ManualDns::EntryDataText& text) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataNextResolver& resolver) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataAdnlAddress& adnl_address) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataSmcAddress& text) { res = "UNSUPPORTED"; },
|
||||
[&](const ton::ManualDns::EntryDataStorageAddress& storage_address) { res = "UNSUPPORTED"; }));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -559,6 +573,12 @@ td::Result<td::optional<ManualDns::EntryData>> ManualDns::parse_data(td::Slice c
|
|||
} else if (type == "NEXT") {
|
||||
TRY_RESULT(address, block::StdAddress::parse(parser.read_all()));
|
||||
return ManualDns::EntryData::next_resolver(address);
|
||||
} else if (type == "STORAGE") {
|
||||
td::Bits256 bag_id;
|
||||
if (bag_id.from_hex(parser.read_all(), false) != 256) {
|
||||
return td::Status::Error("failed to parse bag id");
|
||||
}
|
||||
return ManualDns::EntryData::storage_address(bag_id);
|
||||
} else if (parser.data() == "DELETED") {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -66,9 +66,19 @@ class DnsInterface {
|
|||
// TODO: capability
|
||||
};
|
||||
|
||||
struct EntryDataStorageAddress {
|
||||
ton::Bits256 bag_id;
|
||||
// TODO: proto
|
||||
bool operator==(const EntryDataStorageAddress& other) const {
|
||||
return bag_id == other.bag_id;
|
||||
}
|
||||
};
|
||||
|
||||
struct EntryData {
|
||||
enum Type { Empty, Text, NextResolver, AdnlAddress, SmcAddress } type{Empty};
|
||||
td::Variant<EntryDataText, EntryDataNextResolver, EntryDataAdnlAddress, EntryDataSmcAddress> data;
|
||||
enum Type { Empty, Text, NextResolver, AdnlAddress, SmcAddress, StorageAddress } type{Empty};
|
||||
td::Variant<EntryDataText, EntryDataNextResolver, EntryDataAdnlAddress, EntryDataSmcAddress,
|
||||
EntryDataStorageAddress>
|
||||
data;
|
||||
|
||||
static EntryData text(std::string text) {
|
||||
return {Text, EntryDataText{text}};
|
||||
|
@ -82,6 +92,9 @@ class DnsInterface {
|
|||
static EntryData smc_address(block::StdAddress smc_address) {
|
||||
return {SmcAddress, EntryDataSmcAddress{smc_address}};
|
||||
}
|
||||
static EntryData storage_address(ton::Bits256 bag_id) {
|
||||
return {StorageAddress, EntryDataStorageAddress{bag_id}};
|
||||
}
|
||||
|
||||
bool operator==(const EntryData& other) const {
|
||||
return data == other.data;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue