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

Use partial liteservers in tonlib and lite-client

This commit is contained in:
SpyCheese 2023-01-11 19:14:03 +03:00
parent 1ccf25d6b7
commit 2ea17ec03b
17 changed files with 891 additions and 974 deletions

View file

@ -27,7 +27,6 @@
#include "tonlib/keys/Mnemonic.h"
#include "tonlib/keys/SimpleEncryption.h"
#include "tonlib/TonlibError.h"
#include "tonlib/ExtClientMulti.h"
#include "smc-envelope/GenericAccount.h"
#include "smc-envelope/ManualDns.h"
@ -863,7 +862,9 @@ class Query {
}
return res;
}
td::Result<std::pair<Fee, std::vector<Fee>>> estimate_fees(bool ignore_chksig, std::shared_ptr<const block::Config>& cfg, vm::Dictionary& libraries) {
td::Result<std::pair<Fee, std::vector<Fee>>> estimate_fees(bool ignore_chksig,
std::shared_ptr<const block::Config>& cfg,
vm::Dictionary& libraries) {
// gas fees
bool is_masterchain = raw_.source->get_address().workchain == ton::masterchainId;
TRY_RESULT(gas_limits_prices, cfg->get_gas_limits_prices(is_masterchain));
@ -892,7 +893,8 @@ class Query {
.set_now(raw_.source->get_sync_time())
.set_ignore_chksig(ignore_chksig)
.set_address(raw_.source->get_address())
.set_config(cfg).set_libraries(libraries));
.set_config(cfg)
.set_libraries(libraries));
td::int64 fwd_fee = 0;
if (res.success) {
LOG(DEBUG) << "output actions:\n"
@ -962,8 +964,9 @@ td::Result<td::int64> to_balance(td::Ref<vm::CellSlice> balance_ref) {
class GetTransactionHistory : public td::actor::Actor {
public:
GetTransactionHistory(ExtClientRef ext_client_ref, block::StdAddress address, ton::LogicalTime lt, ton::Bits256 hash, td::int32 count,
td::actor::ActorShared<> parent, td::Promise<block::TransactionList::Info> promise)
GetTransactionHistory(ExtClientRef ext_client_ref, block::StdAddress address, ton::LogicalTime lt, ton::Bits256 hash,
td::int32 count, td::actor::ActorShared<> parent,
td::Promise<block::TransactionList::Info> promise)
: address_(std::move(address))
, lt_(std::move(lt))
, hash_(std::move(hash))
@ -1671,8 +1674,8 @@ void TonlibClient::init_ext_client() {
}
void request(td::int64 id, std::string data, ton::ShardIdFull shard) override {
send_closure(parent_, &TonlibClient::proxy_request, (id << 16) | (config_generation_ & 0xffff),
std::move(data), shard);
send_closure(parent_, &TonlibClient::proxy_request, (id << 16) | (config_generation_ & 0xffff), std::move(data),
shard);
}
private:
@ -1685,34 +1688,17 @@ void TonlibClient::init_ext_client() {
ext_client_outbound_ = client.get();
raw_client_ = std::move(client);
} else {
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers;
for (const auto& s : config_.lite_clients) {
servers.emplace_back(s.adnl_id, s.address);
}
class Callback : public ExtClientLazy::Callback {
public:
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
}
private:
td::actor::ActorShared<> parent_;
};
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> full_servers;
for (const auto& s : config_.lite_clients) {
if (s.is_full) {
full_servers.emplace_back(s.adnl_id, s.address);
}
}
if (!full_servers.empty()) {
raw_client_ =
ExtClientRaw::create(std::move(full_servers), td::make_unique<Callback>(td::actor::actor_shared()));
} else {
CHECK(!config_.lite_clients.empty());
raw_client_ = td::actor::create_actor<ExtClientMulti>("ExtClientMulti", config_.lite_clients,
td::make_unique<Callback>(td::actor::actor_shared()));
}
ext_client_outbound_ = {};
ref_cnt_++;
raw_client_ = ExtClientLazy::create(std::move(servers), td::make_unique<Callback>(td::actor::actor_shared()));
raw_client_ = ExtClientLazy::create(config_.lite_servers, td::make_unique<Callback>(td::actor::actor_shared()));
}
}
@ -2360,7 +2346,7 @@ td::Result<TonlibClient::FullConfig> TonlibClient::validate_config(tonlib_api::o
TRY_RESULT_PREFIX(new_config, Config::parse(std::move(config->config_)),
TonlibError::InvalidConfig("can't parse config"));
if (new_config.lite_clients.empty() && !config->use_callbacks_for_network_) {
if (new_config.lite_servers.empty() && !config->use_callbacks_for_network_) {
return TonlibError::InvalidConfig("no lite clients");
}
td::optional<Config> o_master_config;
@ -2427,8 +2413,7 @@ td::Result<TonlibClient::FullConfig> TonlibClient::validate_config(tonlib_api::o
state.vert_seqno = vert_seqno;
bool user_defined_init_block = false;
if (new_config.init_block_id.is_valid() &&
state.last_key_block_id.id.seqno < new_config.init_block_id.id.seqno) {
if (new_config.init_block_id.is_valid() && state.last_key_block_id.id.seqno < new_config.init_block_id.id.seqno) {
state.last_key_block_id = new_config.init_block_id;
user_defined_init_block = true;
LOG(INFO) << "Use init block from USER config: " << new_config.init_block_id.to_str();
@ -2524,8 +2509,7 @@ td::Result<std::string> to_std_address(td::Ref<vm::CellSlice> cs) {
}
struct ToRawTransactions {
explicit ToRawTransactions(td::optional<td::Ed25519::PrivateKey> private_key, bool try_decode_messages = true)
: private_key_(std::move(private_key))
, try_decode_messages_(try_decode_messages) {
: private_key_(std::move(private_key)), try_decode_messages_(try_decode_messages) {
}
td::optional<td::Ed25519::PrivateKey> private_key_;
@ -2588,7 +2572,8 @@ struct ToRawTransactions {
}
}
if (!data) {
data = tonlib_api::make_object<tonlib_api::msg_dataRaw>(to_bytes(std::move(body_cell)), to_bytes(std::move(init_state_cell)));
data = tonlib_api::make_object<tonlib_api::msg_dataRaw>(to_bytes(std::move(body_cell)),
to_bytes(std::move(init_state_cell)));
}
return data;
};
@ -2636,7 +2621,8 @@ struct ToRawTransactions {
auto created_lt = static_cast<td::int64>(msg_info.created_lt);
return tonlib_api::make_object<tonlib_api::raw_message>(
tonlib_api::make_object<tonlib_api::accountAddress>(src),
tonlib_api::make_object<tonlib_api::accountAddress>(), 0, 0, 0, created_lt, std::move(body_hash), get_data(src));
tonlib_api::make_object<tonlib_api::accountAddress>(), 0, 0, 0, created_lt, std::move(body_hash),
get_data(src));
}
}
@ -2746,10 +2732,9 @@ td::Status TonlibClient::do_request(const tonlib_api::raw_sendMessageReturnHash&
td::Promise<object_ptr<tonlib_api::raw_extMessageInfo>>&& promise) {
TRY_RESULT_PREFIX(body, vm::std_boc_deserialize(request.body_), TonlibError::InvalidBagOfCells("body"));
auto hash = body->get_hash().as_slice().str();
make_request(int_api::SendMessage{std::move(body)},
promise.wrap([hash = std::move(hash)](auto res) {
return tonlib_api::make_object<tonlib_api::raw_extMessageInfo>(std::move(hash));
}));
make_request(int_api::SendMessage{std::move(body)}, promise.wrap([hash = std::move(hash)](auto res) {
return tonlib_api::make_object<tonlib_api::raw_extMessageInfo>(std::move(hash));
}));
return td::Status::OK();
}
@ -2839,7 +2824,7 @@ td::Status TonlibClient::do_request(tonlib_api::raw_getTransactions& request,
}
td::Status TonlibClient::do_request(tonlib_api::raw_getTransactionsV2& request,
td::Promise<object_ptr<tonlib_api::raw_transactions>>&& promise) {
td::Promise<object_ptr<tonlib_api::raw_transactions>>&& promise) {
if (!request.account_address_) {
return TonlibError::EmptyField("account_address");
}
@ -2875,9 +2860,10 @@ td::Status TonlibClient::do_request(tonlib_api::raw_getTransactionsV2& request,
auto actor_id = actor_id_++;
actors_[actor_id] = td::actor::create_actor<GetTransactionHistory>(
"GetTransactionHistory", client_.get_client(), account_address, lt, hash, count, actor_shared(this, actor_id),
promise.wrap([private_key = std::move(private_key), try_decode_messages = request.try_decode_messages_](auto&& x) mutable {
return ToRawTransactions(std::move(private_key), try_decode_messages).to_raw_transactions(std::move(x));
}));
promise.wrap(
[private_key = std::move(private_key), try_decode_messages = request.try_decode_messages_](auto&& x) mutable {
return ToRawTransactions(std::move(private_key), try_decode_messages).to_raw_transactions(std::move(x));
}));
return td::Status::OK();
}
@ -3044,26 +3030,25 @@ class GenericCreateSendGrams : public TonlibQueryActor {
td::Result<ton::ManualDns::Action> to_dns_action(tonlib_api::dns_Action& action) {
using R = td::Result<ton::ManualDns::Action>;
return downcast_call2<R>(action,
td::overloaded(
[&](tonlib_api::dns_actionDeleteAll& del_all) -> R {
return ton::ManualDns::Action{"", td::Bits256::zero(), {}};
},
[&](tonlib_api::dns_actionDelete& del) -> R {
return ton::ManualDns::Action{del.name_, del.category_, {}};
},
[&](tonlib_api::dns_actionSet& set) -> R {
if (!set.entry_) {
return TonlibError::EmptyField("entry");
}
if (!set.entry_->entry_) {
return TonlibError::EmptyField("entry.entry");
}
TRY_RESULT(entry_data, to_dns_entry_data(*set.entry_->entry_));
TRY_RESULT(data_cell, entry_data.as_cell());
return ton::ManualDns::Action{set.entry_->name_, set.entry_->category_,
std::move(data_cell)};
}));
return downcast_call2<R>(
action, td::overloaded(
[&](tonlib_api::dns_actionDeleteAll& del_all) -> R {
return ton::ManualDns::Action{"", td::Bits256::zero(), {}};
},
[&](tonlib_api::dns_actionDelete& del) -> R {
return ton::ManualDns::Action{del.name_, del.category_, {}};
},
[&](tonlib_api::dns_actionSet& set) -> R {
if (!set.entry_) {
return TonlibError::EmptyField("entry");
}
if (!set.entry_->entry_) {
return TonlibError::EmptyField("entry.entry");
}
TRY_RESULT(entry_data, to_dns_entry_data(*set.entry_->entry_));
TRY_RESULT(data_cell, entry_data.as_cell());
return ton::ManualDns::Action{set.entry_->name_, set.entry_->category_, std::move(data_cell)};
}));
}
td::Status parse_action(tonlib_api::Action& action) {
@ -3471,9 +3456,9 @@ class GenericCreateSendGrams : public TonlibQueryActor {
}
}
// if (!o_public_key) { // todo: (tolya-yanot) temporary disable msg comment encryption (The exchanges/payment services needs to read the comment of incoming messages). This will be uncommented when a general standard is developed.
return TonlibError::MessageEncryption("Get public key (in destination)");
// }
// if (!o_public_key) { // todo: (tolya-yanot) temporary disable msg comment encryption (The exchanges/payment services needs to read the comment of incoming messages). This will be uncommented when a general standard is developed.
return TonlibError::MessageEncryption("Get public key (in destination)");
// }
auto addr = source_->get_address();
addr.bounceable = true;
@ -3868,8 +3853,8 @@ td::Result<vm::StackEntry> from_tonlib_api(tonlib_api::tvm_StackEntry& entry) {
}));
}
void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& visited,
vm::Dictionary& libs, td::Ref<vm::Cell> cell, int depth) {
void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& visited, vm::Dictionary& libs,
td::Ref<vm::Cell> cell, int depth) {
if (depth <= 0 || set.size() >= 16 || visited.size() >= 256) {
return;
}
@ -3895,7 +3880,7 @@ void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& v
}
return;
}
for (unsigned int i=0; i<loaded_cell.data_cell->get_refs_cnt(); i++) {
for (unsigned int i = 0; i < loaded_cell.data_cell->get_refs_cnt(); i++) {
deep_library_search(set, visited, libs, loaded_cell.data_cell->get_ref(i), depth - 1);
}
}
@ -3919,36 +3904,38 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_getLibraries& request,
return td::Status::OK();
}
client_.send_query(ton::lite_api::liteServer_getLibraries(std::move(not_cached_hashes)),
promise.wrap([self=this, result_entries = std::move(result_entries)]
(td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable
{
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
} else {
auto libraries = r_libraries.move_as_ok();
bool updated = false;
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
client_.send_query(
ton::lite_api::liteServer_getLibraries(std::move(not_cached_hashes)),
promise.wrap(
[self = this, result_entries = std::move(result_entries)](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
} else {
auto libraries = r_libraries.move_as_ok();
bool updated = false;
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
}
result_entries.push_back(
tonlib_api::make_object<tonlib_api::smc_libraryEntry>(lr->hash_, lr->data_.as_slice().str()));
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
updated = true;
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
}
if (updated) {
self->store_libs_to_disk();
}
}
}
result_entries.push_back(tonlib_api::make_object<tonlib_api::smc_libraryEntry>(lr->hash_, lr->data_.as_slice().str()));
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
updated = true;
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
}
if (updated) {
self->store_libs_to_disk();
}
}
}
return tonlib_api::make_object<tonlib_api::smc_libraryResult>(std::move(result_entries));
}));
return tonlib_api::make_object<tonlib_api::smc_libraryResult>(std::move(result_entries));
}));
return td::Status::OK();
}
@ -3975,8 +3962,8 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
args.set_now(it->second->get_sync_time());
args.set_address(it->second->get_address());
client_.with_last_config([self = this, smc = std::move(smc), args = std::move(args), promise = std::move(promise)
](td::Result<LastConfigState> r_state) mutable {
client_.with_last_config([self = this, smc = std::move(smc), args = std::move(args),
promise = std::move(promise)](td::Result<LastConfigState> r_state) mutable {
TRY_RESULT_PROMISE(promise, state, std::move(r_state));
args.set_config(state.config);
@ -3988,41 +3975,39 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
std::vector<td::Bits256> libraryList{librarySet.begin(), librarySet.end()};
if (libraryList.size() > 0) {
LOG(DEBUG) << "Requesting found libraries in code (" << libraryList.size() << ")";
self->client_.send_query(ton::lite_api::liteServer_getLibraries(std::move(libraryList)),
[self, smc = std::move(smc), args = std::move(args), promise = std::move(promise)]
(td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable
{
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
} else {
auto libraries = r_libraries.move_as_ok();
bool updated = false;
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
}
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
updated = true;
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
self->client_.send_query(
ton::lite_api::liteServer_getLibraries(std::move(libraryList)),
[self, smc = std::move(smc), args = std::move(args), promise = std::move(promise)](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
auto libraries = r_libraries.move_as_ok();
bool updated = false;
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
}
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
updated = true;
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
}
}
if (updated) {
self->store_libs_to_disk();
}
}
}
if (updated) {
self->store_libs_to_disk();
}
}
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
});
}
else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
});
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
}
else {
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
});
@ -4031,7 +4016,6 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::SmartContract::Args args,
td::Promise<object_ptr<tonlib_api::smc_runResult>>&& promise) {
args.set_libraries(libraries);
auto res = smc->run_get_method(args);
@ -4046,45 +4030,46 @@ void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::S
td::Bits256 hash = res.missing_library;
LOG(DEBUG) << "Requesting missing library: " << hash.to_hex();
std::vector<td::Bits256> req = {std::move(hash)};
client_.send_query(ton::lite_api::liteServer_getLibraries(std::move(req)),
[self = this, res = std::move(res), res_stack = std::move(res_stack), hash = std::move(hash),
smc = std::move(smc), args = std::move(args), promise = std::move(promise)]
(td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable
{
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain missing library: " << r_libraries.move_as_error().to_string();
promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
return;
}
bool found = false, updated = false;
auto libraries = r_libraries.move_as_ok();
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
client_.send_query(
ton::lite_api::liteServer_getLibraries(std::move(req)),
[self = this, res = std::move(res), res_stack = std::move(res_stack), hash = std::move(hash),
smc = std::move(smc), args = std::move(args), promise = std::move(promise)](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain missing library: " << r_libraries.move_as_error().to_string();
promise.set_value(
tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
return;
}
found |= (lr->hash_ == hash);
updated = true;
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
}
}
if (updated) {
self->store_libs_to_disk();
}
if (!found) {
LOG(WARNING) << "cannot obtain library " << hash.to_hex() << ", it may not exist";
promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
});
}
else {
bool found = false, updated = false;
auto libraries = r_libraries.move_as_ok();
for (auto& lr : libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue;
}
found |= (lr->hash_ == hash);
updated = true;
self->libraries.set_ref(lr->hash_, contents.move_as_ok());
LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else {
LOG(WARNING) << "failed to deserialize library: " << lr->hash_.to_hex();
}
}
if (updated) {
self->store_libs_to_disk();
}
if (!found) {
LOG(WARNING) << "cannot obtain library " << hash.to_hex() << ", it may not exist";
promise.set_value(
tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
});
} else {
promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
}
}
@ -4160,9 +4145,8 @@ void TonlibClient::do_dns_request(std::string name, td::Bits256 category, td::in
td::optional<ton::BlockIdExt> block_id, block::StdAddress address,
td::Promise<object_ptr<tonlib_api::dns_resolved>>&& promise) {
auto block_id_copy = block_id.copy();
td::Promise<DnsFinishData> new_promise =
promise.send_closure(actor_id(this), &TonlibClient::finish_dns_resolve, name, category, ttl, std::move(block_id),
address);
td::Promise<DnsFinishData> new_promise = promise.send_closure(actor_id(this), &TonlibClient::finish_dns_resolve, name,
category, ttl, std::move(block_id), address);
if (0) {
make_request(int_api::GetAccountState{address, std::move(block_id_copy), {}},
@ -4200,8 +4184,7 @@ td::Status TonlibClient::do_request(const tonlib_api::dns_resolve& request,
name += '.';
}
TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_));
do_dns_request(name, request.category_, request.ttl_, std::move(block_id), account_address,
std::move(promise));
do_dns_request(name, request.category_, request.ttl_, std::move(block_id), account_address, std::move(promise));
return td::Status::OK();
}
@ -4639,15 +4622,15 @@ auto to_tonlib_api(const ton::lite_api::tonNode_blockIdExt& blk) -> tonlib_api_p
auto to_tonlib_api(const ton::lite_api::tonNode_zeroStateIdExt& zeroStateId)
-> tonlib_api_ptr<tonlib_api::ton_blockIdExt> {
return tonlib_api::make_object<tonlib_api::ton_blockIdExt>( //TODO check wether shard indeed 0???
return tonlib_api::make_object<tonlib_api::ton_blockIdExt>( //TODO check wether shard indeed 0???
zeroStateId.workchain_, 0, 0, zeroStateId.root_hash_.as_slice().str(), zeroStateId.file_hash_.as_slice().str());
}
auto to_lite_api(const tonlib_api::ton_blockIdExt& blk) -> td::Result<lite_api_ptr<ton::lite_api::tonNode_blockIdExt>> {
TRY_RESULT(root_hash, to_bits256(blk.root_hash_, "blk.root_hash"))
TRY_RESULT(file_hash, to_bits256(blk.file_hash_, "blk.file_hash"))
return ton::lite_api::make_object<ton::lite_api::tonNode_blockIdExt>(
blk.workchain_, blk.shard_, blk.seqno_, root_hash, file_hash);
return ton::lite_api::make_object<ton::lite_api::tonNode_blockIdExt>(blk.workchain_, blk.shard_, blk.seqno_,
root_hash, file_hash);
}
td::Result<ton::BlockIdExt> to_block_id(const tonlib_api::ton_blockIdExt& blk) {
@ -4657,33 +4640,34 @@ td::Result<ton::BlockIdExt> to_block_id(const tonlib_api::ton_blockIdExt& blk) {
}
td::Status TonlibClient::do_request(const tonlib_api::getConfigParam& request,
td::Promise<object_ptr<tonlib_api::configInfo>>&& promise) {
td::Promise<object_ptr<tonlib_api::configInfo>>&& promise) {
TRY_RESULT(lite_block, to_lite_api(*request.id_))
auto block = create_block_id(std::move(lite_block));
auto param = request.param_;
std::vector<int32_t> params = { param };
std::vector<int32_t> params = {param};
client_.send_query(ton::lite_api::liteServer_getConfigParams(0, std::move(lite_block), std::move(params)),
promise.wrap([block, param](auto r_config) {
auto state = block::check_extract_state_proof(block, r_config->state_proof_.as_slice(),
r_config->config_proof_.as_slice());
if (state.is_error()) {
LOG(ERROR) << "block::check_extract_state_proof failed: " << state.error();
}
auto config = block::Config::extract_from_state(std::move(state.move_as_ok()), 0);
if (config.is_error()) {
LOG(ERROR) << "block::Config::extract_from_state failed: " << config.error();
}
tonlib_api::configInfo config_result;
config_result.config_ = tonlib_api::make_object<tonlib_api::tvm_cell>(to_bytes(config.move_as_ok()->get_config_param(param)));
return tonlib_api::make_object<tonlib_api::configInfo>(std::move(config_result));
}));
auto state = block::check_extract_state_proof(block, r_config->state_proof_.as_slice(),
r_config->config_proof_.as_slice());
if (state.is_error()) {
LOG(ERROR) << "block::check_extract_state_proof failed: " << state.error();
}
auto config = block::Config::extract_from_state(std::move(state.move_as_ok()), 0);
if (config.is_error()) {
LOG(ERROR) << "block::Config::extract_from_state failed: " << config.error();
}
tonlib_api::configInfo config_result;
config_result.config_ = tonlib_api::make_object<tonlib_api::tvm_cell>(
to_bytes(config.move_as_ok()->get_config_param(param)));
return tonlib_api::make_object<tonlib_api::configInfo>(std::move(config_result));
}));
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::blocks_getMasterchainInfo& masterchain_info,
td::Promise<object_ptr<tonlib_api::blocks_masterchainInfo>>&& promise) {
td::Promise<object_ptr<tonlib_api::blocks_masterchainInfo>>&& promise) {
client_.send_query(ton::lite_api::liteServer_getMasterchainInfo(),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_masterchainInfo>&& masterchain_info) {
return tonlib_api::make_object<tonlib_api::blocks_masterchainInfo>(
@ -4728,133 +4712,126 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_getShards& request,
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::blocks_lookupBlock& request,
td::Promise<object_ptr<tonlib_api::ton_blockIdExt>>&& promise) {
td::Promise<object_ptr<tonlib_api::ton_blockIdExt>>&& promise) {
client_.send_query(ton::lite_api::liteServer_lookupBlock(
request.mode_,
ton::lite_api::make_object<ton::lite_api::tonNode_blockId>((*request.id_).workchain_, (*request.id_).shard_, (*request.id_).seqno_),
(td::uint64)(request.lt_),
(td::uint32)(request.utime_)),
request.mode_,
ton::lite_api::make_object<ton::lite_api::tonNode_blockId>(
(*request.id_).workchain_, (*request.id_).shard_, (*request.id_).seqno_),
(td::uint64)(request.lt_), (td::uint32)(request.utime_)),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_blockHeader>&& header) {
const auto& id = header->id_;
return to_tonlib_api(*id);
//tonlib_api::make_object<tonlib_api::ton_blockIdExt>(
// ton::tonlib_api::ton_blockIdExt(id->workchain_, id->)
//);
const auto& id = header->id_;
return to_tonlib_api(*id);
//tonlib_api::make_object<tonlib_api::ton_blockIdExt>(
// ton::tonlib_api::ton_blockIdExt(id->workchain_, id->)
//);
}));
return td::Status::OK();
}
auto to_tonlib_api(const ton::lite_api::liteServer_transactionId& txid)
-> tonlib_api_ptr<tonlib_api::blocks_shortTxId> {
return tonlib_api::make_object<tonlib_api::blocks_shortTxId>(
txid.mode_, txid.account_.as_slice().str(), txid.lt_, txid.hash_.as_slice().str());
return tonlib_api::make_object<tonlib_api::blocks_shortTxId>(txid.mode_, txid.account_.as_slice().str(), txid.lt_,
txid.hash_.as_slice().str());
}
td::Status TonlibClient::do_request(const tonlib_api::blocks_getTransactions& request,
td::Promise<object_ptr<tonlib_api::blocks_transactions>>&& promise) {
td::Promise<object_ptr<tonlib_api::blocks_transactions>>&& promise) {
TRY_RESULT(block, to_lite_api(*request.id_))
TRY_RESULT(account, to_bits256((*request.after_).account_, "account"));
auto after = ton::lite_api::make_object<ton::lite_api::liteServer_transactionId3>(account, (*request.after_).lt_);
client_.send_query(ton::lite_api::liteServer_listBlockTransactions(
std::move(block),
request.mode_,
request.count_,
std::move(after),
false,
false),
client_.send_query(ton::lite_api::liteServer_listBlockTransactions(std::move(block), request.mode_, request.count_,
std::move(after), false, false),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_blockTransactions>&& bTxes) {
const auto& id = bTxes->id_;
//for (auto id : ids) {
tonlib_api::blocks_transactions r;
r.id_ = to_tonlib_api(*id);
r.req_count_ = bTxes->req_count_;
r.incomplete_ = bTxes->incomplete_;
for (auto& id: bTxes->ids_) {
//tonlib_api::blocks_shortTxId txid = tonlib_api::blocks_shortTxId(id->mode_, id->account_.as_slice().str(), id->lt_, id->hash_.as_slice().str());
//r.transactions_.push_back(txid);
r.transactions_.push_back(to_tonlib_api(*id));
}
return tonlib_api::make_object<tonlib_api::blocks_transactions>(std::move(r));
const auto& id = bTxes->id_;
//for (auto id : ids) {
tonlib_api::blocks_transactions r;
r.id_ = to_tonlib_api(*id);
r.req_count_ = bTxes->req_count_;
r.incomplete_ = bTxes->incomplete_;
for (auto& id : bTxes->ids_) {
//tonlib_api::blocks_shortTxId txid = tonlib_api::blocks_shortTxId(id->mode_, id->account_.as_slice().str(), id->lt_, id->hash_.as_slice().str());
//r.transactions_.push_back(txid);
r.transactions_.push_back(to_tonlib_api(*id));
}
return tonlib_api::make_object<tonlib_api::blocks_transactions>(std::move(r));
}));
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::blocks_getBlockHeader& request,
td::Promise<object_ptr<tonlib_api::blocks_header>>&& promise) {
td::Promise<object_ptr<tonlib_api::blocks_header>>&& promise) {
TRY_RESULT(block, to_lite_api(*request.id_))
client_.send_query(ton::lite_api::liteServer_getBlockHeader(
std::move(block),
0xffff),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_blockHeader>&& hdr) {
auto blk_id = ton::create_block_id(hdr->id_);
auto R = vm::std_boc_deserialize(std::move(hdr->header_proof_));
tonlib_api::blocks_header header;
if (R.is_error()) {
LOG(WARNING) << "R.is_error() ";
} else {
auto root = R.move_as_ok();
try {
ton::RootHash vhash{root->get_hash().bits()};
auto virt_root = vm::MerkleProof::virtualize(root, 1);
if (virt_root.is_null()) {
LOG(WARNING) << "virt root is null";
} else {
std::vector<ton::BlockIdExt> prev;
ton::BlockIdExt mc_blkid;
bool after_split;
auto res = block::unpack_block_prev_blk_ext(virt_root, blk_id, prev, mc_blkid, after_split);
if (res.is_error()) {
LOG(WARNING) << "res.is_error() ";
} else {
block::gen::Block::Record blk;
block::gen::BlockInfo::Record info;
if (!(tlb::unpack_cell(virt_root, blk) && tlb::unpack_cell(blk.info, info))) {
LOG(WARNING) << "unpack failed";
} else {
header.id_ = to_tonlib_api(blk_id);
header.global_id_ = blk.global_id;
header.version_ = info.version;
header.flags_ = info.flags;
header.after_merge_ = info.after_merge;
header.after_split_ = info.after_split;
header.before_split_ = info.before_split;
header.want_merge_ = info.want_merge;
header.want_split_ = info.want_split;
header.validator_list_hash_short_ = info.gen_validator_list_hash_short;
header.catchain_seqno_ = info.gen_catchain_seqno;
header.min_ref_mc_seqno_ = info.min_ref_mc_seqno;
header.start_lt_ = info.start_lt;
header.end_lt_ = info.end_lt;
header.gen_utime_ = info.gen_utime;
header.is_key_block_ = info.key_block;
header.vert_seqno_ = info.vert_seq_no;
if(!info.not_master) {
header.prev_key_block_seqno_ = info.prev_key_block_seqno;
}
for (auto id : prev) {
header.prev_blocks_.push_back(to_tonlib_api(id));
}
//if(info.before_split) {
//} else {
//}
return tonlib_api::make_object<tonlib_api::blocks_header>(std::move(header));
}
}
}
} catch (vm::VmError& err) {
auto E = err.as_status(PSLICE() << "error processing header for " << blk_id.to_str() << " :");
LOG(ERROR) << std::move(E);
} catch (vm::VmVirtError& err) {
auto E = err.as_status(PSLICE() << "error processing header for " << blk_id.to_str() << " :");
LOG(ERROR) << std::move(E);
} catch (...) {
LOG(WARNING) << "exception catched ";
}
}
return tonlib_api::make_object<tonlib_api::blocks_header>(std::move(header));
}));
client_.send_query(
ton::lite_api::liteServer_getBlockHeader(std::move(block), 0xffff),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_blockHeader>&& hdr) {
auto blk_id = ton::create_block_id(hdr->id_);
auto R = vm::std_boc_deserialize(std::move(hdr->header_proof_));
tonlib_api::blocks_header header;
if (R.is_error()) {
LOG(WARNING) << "R.is_error() ";
} else {
auto root = R.move_as_ok();
try {
ton::RootHash vhash{root->get_hash().bits()};
auto virt_root = vm::MerkleProof::virtualize(root, 1);
if (virt_root.is_null()) {
LOG(WARNING) << "virt root is null";
} else {
std::vector<ton::BlockIdExt> prev;
ton::BlockIdExt mc_blkid;
bool after_split;
auto res = block::unpack_block_prev_blk_ext(virt_root, blk_id, prev, mc_blkid, after_split);
if (res.is_error()) {
LOG(WARNING) << "res.is_error() ";
} else {
block::gen::Block::Record blk;
block::gen::BlockInfo::Record info;
if (!(tlb::unpack_cell(virt_root, blk) && tlb::unpack_cell(blk.info, info))) {
LOG(WARNING) << "unpack failed";
} else {
header.id_ = to_tonlib_api(blk_id);
header.global_id_ = blk.global_id;
header.version_ = info.version;
header.flags_ = info.flags;
header.after_merge_ = info.after_merge;
header.after_split_ = info.after_split;
header.before_split_ = info.before_split;
header.want_merge_ = info.want_merge;
header.want_split_ = info.want_split;
header.validator_list_hash_short_ = info.gen_validator_list_hash_short;
header.catchain_seqno_ = info.gen_catchain_seqno;
header.min_ref_mc_seqno_ = info.min_ref_mc_seqno;
header.start_lt_ = info.start_lt;
header.end_lt_ = info.end_lt;
header.gen_utime_ = info.gen_utime;
header.is_key_block_ = info.key_block;
header.vert_seqno_ = info.vert_seq_no;
if (!info.not_master) {
header.prev_key_block_seqno_ = info.prev_key_block_seqno;
}
for (auto id : prev) {
header.prev_blocks_.push_back(to_tonlib_api(id));
}
//if(info.before_split) {
//} else {
//}
return tonlib_api::make_object<tonlib_api::blocks_header>(std::move(header));
}
}
}
} catch (vm::VmError& err) {
auto E = err.as_status(PSLICE() << "error processing header for " << blk_id.to_str() << " :");
LOG(ERROR) << std::move(E);
} catch (vm::VmVirtError& err) {
auto E = err.as_status(PSLICE() << "error processing header for " << blk_id.to_str() << " :");
LOG(ERROR) << std::move(E);
} catch (...) {
LOG(WARNING) << "exception catched ";
}
}
return tonlib_api::make_object<tonlib_api::blocks_header>(std::move(header));
}));
return td::Status::OK();
}
@ -4890,15 +4867,17 @@ void TonlibClient::load_libs_from_disk() {
if (r_dict.is_error()) {
return;
}
libraries = vm::Dictionary(vm::load_cell_slice(vm::CellBuilder().append_cellslice(vm::load_cell_slice(
r_dict.move_as_ok())).finalize()), 256);
libraries = vm::Dictionary(
vm::load_cell_slice(vm::CellBuilder().append_cellslice(vm::load_cell_slice(r_dict.move_as_ok())).finalize()),
256);
// int n = 0; for (auto&& lr : libraries) n++;
LOG(DEBUG) << "loaded libraries from disk cache";
}
void TonlibClient::store_libs_to_disk() { // NB: Dictionary.get_root_cell does not compute_root, and it is protected
kv_->set("tonlib.libcache", vm::std_boc_serialize(vm::CellBuilder().append_cellslice(libraries.get_root())
.finalize()).move_as_ok().as_slice());
kv_->set("tonlib.libcache", vm::std_boc_serialize(vm::CellBuilder().append_cellslice(libraries.get_root()).finalize())
.move_as_ok()
.as_slice());
// int n = 0; for (auto&& lr : libraries) n++;
LOG(DEBUG) << "stored libraries to disk cache";
}