Skip to content

Commit eb86234

Browse files
authored
Merge pull request #413 from ton-blockchain/temp-master
Update DNS resolver in liteclient and tonlib
2 parents 7e3df93 + 7e207dc commit eb86234

File tree

14 files changed

+278
-237
lines changed

14 files changed

+278
-237
lines changed

crypto/block/block.tlb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ vmc_pushint$1111 value:int32 next:^VmCont = VmCont;
807807
//
808808
// DNS RECORDS
809809
//
810-
_ (HashmapE 16 ^DNSRecord) = DNS_RecordSet;
810+
_ (HashmapE 256 DNSRecord) = DNS_RecordSet;
811811

812812
chunk_ref$_ {n:#} ref:^(TextChunks (n + 1)) = TextChunkRef (n + 1);
813813
chunk_ref_empty$_ = TextChunkRef 0;

crypto/smc-envelope/ManualDns.cpp

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -146,35 +146,43 @@ td::Result<DnsInterface::EntryData> DnsInterface::EntryData::from_cellslice(vm::
146146
return td::Status::Error("Unknown entry data");
147147
}
148148

149-
SmartContract::Args DnsInterface::resolve_args_raw(td::Slice encoded_name, td::int16 category) {
149+
SmartContract::Args DnsInterface::resolve_args_raw(td::Slice encoded_name, td::Bits256 category,
150+
block::StdAddress address) {
150151
SmartContract::Args res;
151152
res.set_method_id("dnsresolve");
152153
res.set_stack(
153-
{vm::load_cell_slice_ref(vm::CellBuilder().store_bytes(encoded_name).finalize()), td::make_refint(category)});
154+
{vm::load_cell_slice_ref(vm::CellBuilder().store_bytes(encoded_name).finalize()),
155+
td::bits_to_refint(category.cbits(), 256, false)});
156+
res.set_address(std::move(address));
154157
return res;
155158
}
156159

157-
td::Result<SmartContract::Args> DnsInterface::resolve_args(td::Slice name, td::int32 category_big) {
158-
TRY_RESULT(category, td::narrow_cast_safe<td::int16>(category_big));
160+
td::Result<SmartContract::Args> DnsInterface::resolve_args(td::Slice name, td::Bits256 category,
161+
block::StdAddress address) {
159162
if (name.size() > get_default_max_name_size()) {
160163
return td::Status::Error("Name is too long");
161164
}
162165
auto encoded_name = encode_name(name);
163-
return resolve_args_raw(encoded_name, category);
166+
return resolve_args_raw(encoded_name, category, std::move(address));
164167
}
165168

166-
td::Result<std::vector<DnsInterface::Entry>> DnsInterface::resolve(td::Slice name, td::int32 category) const {
169+
td::Result<std::vector<DnsInterface::Entry>> DnsInterface::resolve(td::Slice name, td::Bits256 category) const {
167170
TRY_RESULT(raw_entries, resolve_raw(name, category));
168171
std::vector<Entry> entries;
169172
entries.reserve(raw_entries.size());
170173
for (auto& raw_entry : raw_entries) {
171174
Entry entry;
172175
entry.name = std::move(raw_entry.name);
173176
entry.category = raw_entry.category;
174-
auto cs = vm::load_cell_slice(raw_entry.data);
175-
TRY_RESULT(data, EntryData::from_cellslice(cs));
176-
entry.data = std::move(data);
177-
entries.push_back(std::move(entry));
177+
entry.partially_resolved = raw_entry.partially_resolved;
178+
auto cs = *raw_entry.data;
179+
auto data = EntryData::from_cellslice(cs);
180+
if (data.is_error()) {
181+
LOG(INFO) << "Failed to parse DNS entry: " << data.move_as_error();
182+
} else {
183+
entry.data = data.move_as_ok();
184+
entries.push_back(std::move(entry));
185+
}
178186
}
179187
return entries;
180188
}
@@ -188,9 +196,9 @@ td::Result<std::vector<DnsInterface::Entry>> DnsInterface::resolve(td::Slice nam
188196
Inline [Name] structure: [UInt<6b>:length] [Bytes<lengthB>:data]
189197
Operations (continuation of message):
190198
00 Contract initialization message (only if seqno = 0) (x=-)
191-
31 TSet: replace ENTIRE DOMAIN TABLE with the provided tree root cell (x=-)
199+
31 TSet: replace ENTIRE DOMAIN TABLE with the provided tree root cell (x=-)
192200
[Cell<1r>:new_domains_table]
193-
51 OSet: replace owner public key with a new one (x=-)
201+
51 OSet: replace owner public key with a new one (x=-)
194202
[UInt<256b>:new_public_key]
195203
*/
196204
// creation
@@ -233,37 +241,37 @@ td::Result<td::uint32> ManualDns::get_wallet_id_or_throw() const {
233241
return static_cast<td::uint32>(vm::load_cell_slice(state_.data).fetch_ulong(32));
234242
}
235243

236-
td::Result<td::Ref<vm::Cell>> ManualDns::create_set_value_unsigned(td::int16 category, td::Slice name,
244+
td::Result<td::Ref<vm::Cell>> ManualDns::create_set_value_unsigned(td::Bits256 category, td::Slice name,
237245
td::Ref<vm::Cell> data) const {
238246
//11 VSet: set specified value to specified subdomain->category (x=2)
239-
//[Int<16b>:category] [Name<?>:subdomain] [Cell<1r>:value]
247+
//[Int<256b>:category] [Name<?>:subdomain] [Cell<1r>:value]
240248
vm::CellBuilder cb;
241249
cb.store_long(11, 6);
242-
if (name.size() <= 58 - 2) {
243-
cb.store_long(category, 16);
250+
if (name.size() <= 58 - 32) {
251+
cb.store_bytes(category.as_slice());
244252
cb.store_long(0, 1);
245253
cb.store_long(name.size(), 6);
246254
cb.store_bytes(name);
247255
} else {
248-
cb.store_long(category, 16);
256+
cb.store_bytes(category.as_slice());
249257
cb.store_long(1, 1);
250258
cb.store_ref(vm::CellBuilder().store_bytes(name).finalize());
251259
}
252260
cb.store_maybe_ref(std::move(data));
253261
return cb.finalize();
254262
}
255-
td::Result<td::Ref<vm::Cell>> ManualDns::create_delete_value_unsigned(td::int16 category, td::Slice name) const {
263+
td::Result<td::Ref<vm::Cell>> ManualDns::create_delete_value_unsigned(td::Bits256 category, td::Slice name) const {
256264
//12 VDel: delete specified subdomain->category (x=2)
257-
//[Int<16b>:category] [Name<?>:subdomain]
265+
//[Int<256b>:category] [Name<?>:subdomain]
258266
vm::CellBuilder cb;
259267
cb.store_long(12, 6);
260-
if (name.size() <= 58 - 2) {
261-
cb.store_long(category, 16);
268+
if (name.size() <= 58 - 32) {
269+
cb.store_bytes(category.as_slice());
262270
cb.store_long(0, 1);
263271
cb.store_long(name.size(), 6);
264272
cb.store_bytes(name);
265273
} else {
266-
cb.store_long(category, 16);
274+
cb.store_bytes(category.as_slice());
267275
cb.store_long(1, 1);
268276
cb.store_ref(vm::CellBuilder().store_bytes(name).finalize());
269277
}
@@ -295,10 +303,9 @@ td::Result<td::Ref<vm::Cell>> ManualDns::create_set_all_unsigned(td::Span<Action
295303
if (o_dict.not_null()) {
296304
o_dict->prefetch_maybe_ref(dict_root);
297305
}
298-
vm::Dictionary dict(dict_root, 16);
306+
vm::Dictionary dict(dict_root, 256);
299307
if (!action.data.value().is_null()) {
300-
auto key = dict.integer_key(td::make_refint(action.category), 16);
301-
dict.set_ref(key.bits(), 16, action.data.value());
308+
dict.set_ref(action.category.bits(), 256, action.data.value());
302309
}
303310
pdict.set(ptr, ptr_size, dict.get_root());
304311
}
@@ -340,14 +347,13 @@ td::Result<td::Ref<vm::Cell>> ManualDns::create_set_name_unsigned(td::Slice name
340347
cb.store_ref(vm::CellBuilder().store_bytes(name).finalize());
341348
}
342349

343-
vm::Dictionary dict(16);
350+
vm::Dictionary dict(256);
344351

345352
for (auto& action : entries) {
346353
if (action.data.value().is_null()) {
347354
continue;
348355
}
349-
auto key = dict.integer_key(td::make_refint(action.category), 16);
350-
dict.set_ref(key.bits(), 16, action.data.value());
356+
dict.set_ref(action.category.cbits(), 256, action.data.value());
351357
}
352358
cb.store_maybe_ref(dict.get_root_cell());
353359

@@ -395,17 +401,16 @@ size_t ManualDns::get_max_name_size() const {
395401
return get_default_max_name_size();
396402
}
397403

398-
td::Result<std::vector<ManualDns::RawEntry>> ManualDns::resolve_raw(td::Slice name, td::int32 category_big) const {
399-
return TRY_VM(resolve_raw_or_throw(name, category_big));
404+
td::Result<std::vector<ManualDns::RawEntry>> ManualDns::resolve_raw(td::Slice name, td::Bits256 category) const {
405+
return TRY_VM(resolve_raw_or_throw(name, category));
400406
}
401407
td::Result<std::vector<ManualDns::RawEntry>> ManualDns::resolve_raw_or_throw(td::Slice name,
402-
td::int32 category_big) const {
403-
TRY_RESULT(category, td::narrow_cast_safe<td::int16>(category_big));
408+
td::Bits256 category) const {
404409
if (name.size() > get_max_name_size()) {
405410
return td::Status::Error("Name is too long");
406411
}
407412
auto encoded_name = encode_name(name);
408-
auto res = run_get_method(resolve_args_raw(encoded_name, category));
413+
auto res = run_get_method(resolve_args_raw(encoded_name, category, address_));
409414
if (!res.success) {
410415
return td::Status::Error("get method failed");
411416
}
@@ -419,19 +424,22 @@ td::Result<std::vector<ManualDns::RawEntry>> ManualDns::resolve_raw_or_throw(td:
419424
return td::Status::Error("Prefix size is not divisible by 8");
420425
}
421426
prefix_size /= 8;
427+
if (prefix_size == 0) {
428+
return vec;
429+
}
422430
if (prefix_size < encoded_name.size()) {
423-
vec.push_back({decode_name(td::Slice(encoded_name).substr(0, prefix_size)), -1, data});
431+
vec.push_back({decode_name(td::Slice(encoded_name).substr(0, prefix_size)), DNS_NEXT_RESOLVER_CATEGORY,
432+
vm::load_cell_slice_ref(data), true});
424433
} else {
425-
if (category == 0) {
426-
vm::Dictionary dict(std::move(data), 16);
427-
dict.check_for_each([&](auto cs, auto x, auto y) {
428-
td::BigInt256 cat;
429-
cat.import_bits(x, y, true);
430-
vec.push_back({name.str(), td::narrow_cast<td::int16>(cat.to_long()), cs->prefetch_ref()});
434+
if (category.is_zero()) {
435+
vm::Dictionary dict(std::move(data), 256);
436+
dict.check_for_each([&](auto cs, td::ConstBitPtr key, int n) {
437+
CHECK(n == 256);
438+
vec.push_back({name.str(), td::Bits256(key), cs});
431439
return true;
432440
});
433441
} else {
434-
vec.push_back({name.str(), category, data});
442+
vec.push_back({name.str(), category, vm::load_cell_slice_ref(data)});
435443
}
436444
}
437445

@@ -445,7 +453,7 @@ td::Result<td::Ref<vm::Cell>> ManualDns::create_update_query(CombinedActions<Act
445453
}
446454
return create_set_all_unsigned(combined.actions.value());
447455
}
448-
if (combined.category == 0) {
456+
if (combined.category.is_zero()) {
449457
if (!combined.actions) {
450458
return create_delete_name_unsigned(encode_name(combined.name));
451459
}
@@ -488,9 +496,13 @@ td::Result<td::Ref<vm::Cell>> ManualDns::create_update_query(td::Ed25519::Privat
488496

489497
std::string DnsInterface::encode_name(td::Slice name) {
490498
std::string res;
499+
if (name.empty() || name == ".") {
500+
res += '\0';
501+
return res;
502+
}
491503
while (!name.empty()) {
492504
auto pos = name.rfind('.');
493-
if (pos == name.npos) {
505+
if (pos == td::Slice::npos) {
494506
res += name.str();
495507
name = td::Slice();
496508
} else {
@@ -504,20 +516,15 @@ std::string DnsInterface::encode_name(td::Slice name) {
504516

505517
std::string DnsInterface::decode_name(td::Slice name) {
506518
std::string res;
507-
if (!name.empty() && name.back() == 0) {
508-
name.remove_suffix(1);
509-
}
510519
while (!name.empty()) {
511520
auto pos = name.rfind('\0');
512-
if (!res.empty()) {
513-
res += '.';
514-
}
515-
if (pos == name.npos) {
521+
if (pos == td::Slice::npos) {
516522
res += name.str();
517523
name = td::Slice();
518524
} else {
519525
res += name.substr(pos + 1).str();
520526
name.truncate(pos);
527+
res += '.';
521528
}
522529
}
523530
return res;
@@ -570,17 +577,16 @@ td::Result<ManualDns::ActionExt> ManualDns::parse_line(td::Slice cmd) {
570577
if (type == "set") {
571578
auto name = parser.read_word();
572579
auto category_str = parser.read_word();
573-
TRY_RESULT(category, td::to_integer_safe<td::int16>(category_str));
574580
TRY_RESULT(data, parse_data(parser.read_all()));
575-
return ManualDns::ActionExt{name.str(), category, std::move(data)};
581+
return ManualDns::ActionExt{name.str(), td::sha256_bits256(td::as_slice(category_str)), std::move(data)};
576582
} else if (type == "delete.name") {
577583
auto name = parser.read_word();
578584
if (name.empty()) {
579585
return td::Status::Error("name is empty");
580586
}
581-
return ManualDns::ActionExt{name.str(), 0, {}};
587+
return ManualDns::ActionExt{name.str(), td::Bits256::zero(), {}};
582588
} else if (type == "delete.all") {
583-
return ManualDns::ActionExt{"", 0, {}};
589+
return ManualDns::ActionExt{"", td::Bits256::zero(), {}};
584590
}
585591
return td::Status::Error(PSLICE() << "Unknown command: " << type);
586592
}

0 commit comments

Comments
 (0)