Skip to content

Commit

Permalink
Add TON Storage to Proxy via storage gateway (ton-blockchain#577)
Browse files Browse the repository at this point in the history
* Access ton storage from proxy, resolve "dns_storage_address" in tonlib

* Set storage gateway address in proxy args

Co-authored-by: SpyCheese <[email protected]>
  • Loading branch information
EmelyanenkoK and SpyCheese authored Dec 29, 2022
1 parent ad736c6 commit 7347ec0
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 71 deletions.
2 changes: 2 additions & 0 deletions crypto/block/block.tlb
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,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
//
Expand Down
28 changes: 24 additions & 4 deletions crypto/smc-envelope/ManualDns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>";
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -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 {};
}
Expand Down
17 changes: 15 additions & 2 deletions crypto/smc-envelope/ManualDns.h
Original file line number Diff line number Diff line change
Expand Up @@ -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}};
Expand All @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions lite-client/lite-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1749,6 +1749,13 @@ bool TestNode::show_dns_record(std::ostream& os, td::Bits256 cat, Ref<vm::CellSl
}
break;
}
case block::gen::DNSRecord::dns_storage_address: {
block::gen::DNSRecord::Record_dns_storage_address rec;
if (tlb::unpack_exact(cs, rec)) {
os << "\tstorage address " << rec.bag_id.to_hex();
}
break;
}
case block::gen::DNSRecord::dns_next_resolver: {
block::gen::DNSRecord::Record_dns_next_resolver rec;
if (tlb::unpack_exact(cs, rec) && block::tlb::t_MsgAddressInt.extract_std_address(rec.resolver, wc, addr)) {
Expand Down
62 changes: 31 additions & 31 deletions rldp-http-proxy/DNSResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ void DNSResolver::sync() {
std::move(P));
}

void DNSResolver::resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdShort> promise) {
void DNSResolver::resolve(std::string host, td::Promise<std::string> promise) {
auto it = cache_.find(host);
if (it != cache_.end()) {
const CacheEntry &entry = it->second;
double now = td::Time::now();
if (now < entry.created_at_ + CACHE_TIMEOUT_HARD) {
promise.set_result(entry.id_);
promise.set_result(entry.address_);
promise.reset();
if (now < entry.created_at_ + CACHE_TIMEOUT_SOFT) {
return;
Expand All @@ -73,42 +73,42 @@ void DNSResolver::resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdSho
if (promise) {
promise.set_result(R.move_as_error());
}
} else {
auto obj = R.move_as_ok();
ton::adnl::AdnlNodeIdShort id;
td::uint32 cnt = 0;
for (auto &e : obj->entries_) {
tonlib_api::downcast_call(*e->entry_.get(),
td::overloaded(
[&](tonlib_api::dns_entryDataAdnlAddress &x) {
if (td::Random::fast(0, cnt) == 0) {
auto R = ton::adnl::AdnlNodeIdShort::parse(x.adnl_address_->adnl_address_);
if (R.is_ok()) {
id = R.move_as_ok();
cnt++;
}
}
},
[&](auto &x) {}));
}
if (cnt == 0) {
if (promise) {
promise.set_error(td::Status::Error("no DNS entries"));
}
} else {
td::actor::send_closure(SelfId, &DNSResolver::save_to_cache, std::move(host), id);
if (promise) {
promise.set_result(id);
}
return;
}
auto obj = R.move_as_ok();
std::string result;
if (!obj->entries_.empty()) {
tonlib_api::downcast_call(*obj->entries_[0]->entry_,
td::overloaded(
[&](tonlib_api::dns_entryDataAdnlAddress &x) {
auto R = ton::adnl::AdnlNodeIdShort::parse(x.adnl_address_->adnl_address_);
if (R.is_ok()) {
ton::adnl::AdnlNodeIdShort id = R.move_as_ok();
result = id.serialize() + ".adnl";
}
},
[&](tonlib_api::dns_entryDataStorageAddress &x) {
result = td::to_lower(x.bag_id_.to_hex()) + ".bag";
},
[&](auto &x) {}));
}
if (result.empty()) {
if (promise) {
promise.set_error(td::Status::Error("no DNS entries"));
}
return;
}
td::actor::send_closure(SelfId, &DNSResolver::save_to_cache, std::move(host), result);
if (promise) {
promise.set_result(std::move(result));
}
});
td::actor::send_closure(tonlib_client_, &tonlib::TonlibClientWrapper::send_request<tonlib_api::dns_resolve>,
std::move(obj), std::move(P));
}

void DNSResolver::save_to_cache(std::string host, ton::adnl::AdnlNodeIdShort id) {
void DNSResolver::save_to_cache(std::string host, std::string address) {
CacheEntry &entry = cache_[host];
entry.id_ = id;
entry.address_ = address;
entry.created_at_ = td::Time::now();
}
6 changes: 3 additions & 3 deletions rldp-http-proxy/DNSResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ class DNSResolver : public td::actor::Actor {
explicit DNSResolver(td::actor::ActorId<tonlib::TonlibClientWrapper> tonlib_client);

void start_up() override;
void resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdShort> promise);
void resolve(std::string host, td::Promise<std::string> promise);

private:
void sync();
void save_to_cache(std::string host, ton::adnl::AdnlNodeIdShort id);
void save_to_cache(std::string host, std::string address);

td::actor::ActorId<tonlib::TonlibClientWrapper> tonlib_client_;

struct CacheEntry {
ton::adnl::AdnlNodeIdShort id_;
std::string address_;
double created_at_;
};
std::map<std::string, CacheEntry> cache_;
Expand Down
Loading

0 comments on commit 7347ec0

Please sign in to comment.