mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	* Bugfixes in TVM and node * Upgrade to C++17 * Improve GitHub builds * Fix existing tests and partially integrate them into builds --------- Co-authored-by: neodiX42 <namlem@gmail.com> Co-authored-by: EmelyanenkoK <emelyanenko.kirill@gmail.com>
		
			
				
	
	
		
			409 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			409 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* 
 | |
|     This file is part of TON Blockchain source code.
 | |
| 
 | |
|     TON Blockchain is free software; you can redistribute it and/or
 | |
|     modify it under the terms of the GNU General Public License
 | |
|     as published by the Free Software Foundation; either version 2
 | |
|     of the License, or (at your option) any later version.
 | |
| 
 | |
|     TON Blockchain is distributed in the hope that it will be useful,
 | |
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|     GNU General Public License for more details.
 | |
| 
 | |
|     You should have received a copy of the GNU General Public License
 | |
|     along with TON Blockchain.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
|     In addition, as a special exception, the copyright holders give permission 
 | |
|     to link the code of portions of this program with the OpenSSL library. 
 | |
|     You must obey the GNU General Public License in all respects for all 
 | |
|     of the code used other than OpenSSL. If you modify file(s) with this 
 | |
|     exception, you may extend this exception to your version of the file(s), 
 | |
|     but you are not obligated to do so. If you do not wish to do so, delete this 
 | |
|     exception statement from your version. If you delete this exception statement 
 | |
|     from all source files in the program, then also delete it here.
 | |
| 
 | |
|     Copyright 2017-2020 Telegram Systems LLP
 | |
| */
 | |
| #include "adnl/adnl-network-manager.h"
 | |
| #include "adnl/adnl-test-loopback-implementation.h"
 | |
| #include "adnl/adnl.h"
 | |
| #include "dht/dht.h"
 | |
| #include "dht/dht.hpp"
 | |
| 
 | |
| #include "td/utils/port/signals.h"
 | |
| #include "td/utils/port/path.h"
 | |
| #include "td/utils/Random.h"
 | |
| 
 | |
| #include <memory>
 | |
| #include <set>
 | |
| 
 | |
| int main() {
 | |
|   SET_VERBOSITY_LEVEL(verbosity_INFO);
 | |
| 
 | |
|   std::string db_root_ = "tmp-dir-test-dht";
 | |
|   td::rmrf(db_root_).ignore();
 | |
|   td::mkdir(db_root_).ensure();
 | |
| 
 | |
|   td::set_default_failure_signal_handler().ensure();
 | |
| 
 | |
|   td::actor::ActorOwn<ton::keyring::Keyring> keyring;
 | |
|   td::actor::ActorOwn<ton::adnl::TestLoopbackNetworkManager> network_manager;
 | |
|   td::actor::ActorOwn<ton::adnl::Adnl> adnl;
 | |
|   std::vector<td::actor::ActorOwn<ton::dht::Dht>> dht;
 | |
|   std::shared_ptr<ton::dht::DhtGlobalConfig> dht_config;
 | |
| 
 | |
|   td::actor::Scheduler scheduler({7});
 | |
| 
 | |
|   std::vector<ton::adnl::AdnlNodeIdFull> dht_ids;
 | |
|   td::uint32 total_nodes = 11;
 | |
|   std::atomic<td::uint32> remaining{0};
 | |
| 
 | |
|   scheduler.run_in_context([&] {
 | |
|     keyring = ton::keyring::Keyring::create(db_root_);
 | |
|     network_manager = td::actor::create_actor<ton::adnl::TestLoopbackNetworkManager>("test net");
 | |
|     adnl = ton::adnl::Adnl::create(db_root_, keyring.get());
 | |
|     td::actor::send_closure(adnl, &ton::adnl::Adnl::register_network_manager, network_manager.get());
 | |
| 
 | |
|     auto addr0 = ton::adnl::TestLoopbackNetworkManager::generate_dummy_addr_list(true);
 | |
|     auto addr = ton::adnl::TestLoopbackNetworkManager::generate_dummy_addr_list();
 | |
| 
 | |
|     for (td::uint32 i = 0; i < total_nodes; i++) {
 | |
|       auto pk1 = ton::PrivateKey{ton::privkeys::Ed25519::random()};
 | |
|       auto pub1 = pk1.compute_public_key();
 | |
|       auto src = ton::adnl::AdnlNodeIdShort{pub1.compute_short_id()};
 | |
| 
 | |
|       if (i == 0) {
 | |
|         auto obj = ton::create_tl_object<ton::ton_api::dht_node>(pub1.tl(), addr0.tl(), -1, td::BufferSlice());
 | |
|         auto d = pk1.create_decryptor().move_as_ok();
 | |
|         obj->signature_ = d->sign(serialize_tl_object(obj, true)).move_as_ok();
 | |
| 
 | |
|         std::vector<ton::tl_object_ptr<ton::ton_api::dht_node>> vec;
 | |
|         vec.push_back(std::move(obj));
 | |
|         auto nodes = ton::create_tl_object<ton::ton_api::dht_nodes>(std::move(vec));
 | |
|         auto conf = ton::create_tl_object<ton::ton_api::dht_config_global>(std::move(nodes), 6, 3);
 | |
|         auto dht_configR = ton::dht::Dht::create_global_config(std::move(conf));
 | |
|         dht_configR.ensure();
 | |
|         dht_config = dht_configR.move_as_ok();
 | |
|       }
 | |
|       td::actor::send_closure(keyring, &ton::keyring::Keyring::add_key, std::move(pk1), true, [](td::Unit) {});
 | |
|       td::actor::send_closure(adnl, &ton::adnl::Adnl::add_id, ton::adnl::AdnlNodeIdFull{pub1}, addr,
 | |
|                               static_cast<td::uint8>(0));
 | |
|       td::actor::send_closure(network_manager, &ton::adnl::TestLoopbackNetworkManager::add_node_id, src, true, true);
 | |
| 
 | |
|       dht.push_back(ton::dht::Dht::create(src, db_root_, dht_config, keyring.get(), adnl.get()).move_as_ok());
 | |
|       dht_ids.push_back(ton::adnl::AdnlNodeIdFull{pub1});
 | |
|     }
 | |
|     for (auto &n1 : dht_ids) {
 | |
|       td::actor::send_closure(adnl, &ton::adnl::Adnl::add_peer, n1.compute_short_id(), dht_ids[0], addr);
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   LOG(ERROR) << "testing different values";
 | |
|   auto key_pk = ton::PrivateKey{ton::privkeys::Ed25519::random()};
 | |
|   auto key_pub = key_pk.compute_public_key();
 | |
|   auto key_short_id = key_pub.compute_short_id();
 | |
|   auto key_dec = key_pk.create_decryptor().move_as_ok();
 | |
|   {
 | |
|     for (td::uint32 idx = 0; idx <= ton::dht::DhtKey::max_index() + 1; idx++) {
 | |
|       ton::dht::DhtKey dht_key{key_short_id, "test", idx};
 | |
|       if (idx <= ton::dht::DhtKey::max_index()) {
 | |
|         dht_key.check().ensure();
 | |
|       } else {
 | |
|         dht_key.check().ensure_error();
 | |
|       }
 | |
|     }
 | |
|     {
 | |
|       ton::dht::DhtKey dht_key{key_short_id, "test", 0};
 | |
|       dht_key.check().ensure();
 | |
|       dht_key = ton::dht::DhtKey{key_short_id, "", 0};
 | |
|       dht_key.check().ensure_error();
 | |
|       dht_key =
 | |
|           ton::dht::DhtKey{key_short_id, td::BufferSlice{ton::dht::DhtKey::max_name_length()}.as_slice().str(), 0};
 | |
|       dht_key.check().ensure();
 | |
|       dht_key =
 | |
|           ton::dht::DhtKey{key_short_id, td::BufferSlice{ton::dht::DhtKey::max_name_length() + 1}.as_slice().str(), 0};
 | |
|       dht_key.check().ensure_error();
 | |
|     }
 | |
|     {
 | |
|       ton::dht::DhtKey dht_key{key_short_id, "test", 0};
 | |
|       auto dht_update_rule = ton::dht::DhtUpdateRuleSignature::create().move_as_ok();
 | |
|       ton::dht::DhtKeyDescription dht_key_description{dht_key.clone(), key_pub, dht_update_rule, td::BufferSlice()};
 | |
|       dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
|       dht_key_description.check().ensure();
 | |
|       dht_key_description = ton::dht::DhtKeyDescription{dht_key.clone(), key_pub, dht_update_rule, td::BufferSlice(64)};
 | |
|       dht_key_description.check().ensure_error();
 | |
|       dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
|       dht_key_description.check().ensure();
 | |
| 
 | |
|       auto pk = ton::PrivateKey{ton::privkeys::Ed25519::random()};
 | |
|       auto pub = pk.compute_public_key();
 | |
|       dht_key_description = ton::dht::DhtKeyDescription{dht_key.clone(), pub, dht_update_rule, td::BufferSlice(64)};
 | |
|       dht_key_description.update_signature(
 | |
|           pk.create_decryptor().move_as_ok()->sign(dht_key_description.to_sign()).move_as_ok());
 | |
|       dht_key_description.check().ensure_error();
 | |
|     }
 | |
|   }
 | |
|   {
 | |
|     ton::dht::DhtKey dht_key{key_short_id, "test", 0};
 | |
|     auto dht_update_rule = ton::dht::DhtUpdateRuleSignature::create().move_as_ok();
 | |
|     ton::dht::DhtKeyDescription dht_key_description{std::move(dht_key), key_pub, std::move(dht_update_rule),
 | |
|                                                     td::BufferSlice()};
 | |
|     dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
| 
 | |
|     auto ttl = static_cast<td::uint32>(td::Clocks::system() + 3600);
 | |
|     ton::dht::DhtValue dht_value{dht_key_description.clone(), td::BufferSlice("value"), ttl, td::BufferSlice("")};
 | |
|     dht_value.check().ensure_error();
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure();
 | |
|     CHECK(!dht_value.expired());
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice(""), ttl, td::BufferSlice("")};
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice(""),
 | |
|                                    static_cast<td::uint32>(td::Clocks::system() - 1), td::BufferSlice("")};
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure();
 | |
|     CHECK(dht_value.expired());
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice("value"), ttl, td::BufferSlice("")};
 | |
|     dht_value.update_signature(td::BufferSlice{64});
 | |
|     dht_value.check().ensure_error();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice(ton::dht::DhtValue::max_value_size()),
 | |
|                                    ttl, td::BufferSlice("")};
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(),
 | |
|                                    td::BufferSlice(ton::dht::DhtValue::max_value_size() + 1), ttl, td::BufferSlice("")};
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure_error();
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     ton::dht::DhtKey dht_key{key_short_id, "test", 0};
 | |
|     auto dht_update_rule = ton::dht::DhtUpdateRuleAnybody::create().move_as_ok();
 | |
|     ton::dht::DhtKeyDescription dht_key_description{std::move(dht_key), key_pub, std::move(dht_update_rule),
 | |
|                                                     td::BufferSlice()};
 | |
|     dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
| 
 | |
|     auto ttl = static_cast<td::uint32>(td::Clocks::system() + 3600);
 | |
|     ton::dht::DhtValue dht_value{dht_key_description.clone(), td::BufferSlice("value"), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
|     CHECK(!dht_value.expired());
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
|     dht_value.check().ensure_error();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice(), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(), td::BufferSlice(ton::dht::DhtValue::max_value_size()),
 | |
|                                    ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     dht_value = ton::dht::DhtValue{dht_key_description.clone(),
 | |
|                                    td::BufferSlice(ton::dht::DhtValue::max_value_size() + 1), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure_error();
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     ton::dht::DhtKey dht_key{key_short_id, "test", 0};
 | |
|     auto dht_update_rule = ton::dht::DhtUpdateRuleOverlayNodes::create().move_as_ok();
 | |
|     ton::dht::DhtKeyDescription dht_key_description{std::move(dht_key), key_pub, std::move(dht_update_rule),
 | |
|                                                     td::BufferSlice()};
 | |
|     dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
| 
 | |
|     auto ttl = static_cast<td::uint32>(td::Clocks::system() + 3600);
 | |
|     ton::dht::DhtValue dht_value{dht_key_description.clone(), td::BufferSlice(""), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure_error();
 | |
| 
 | |
|     auto obj = ton::create_tl_object<ton::ton_api::overlay_nodes>();
 | |
|     dht_value =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     for (td::uint32 i = 0; i < 100; i++) {
 | |
|       auto pk = ton::PrivateKey{ton::privkeys::Ed25519::random()};
 | |
|       auto pub = pk.compute_public_key();
 | |
| 
 | |
|       auto date = static_cast<td::int32>(td::Clocks::system() - 10);
 | |
|       //overlay.node.toSign id:adnl.id.short overlay:int256 version:int = overlay.node.ToSign;
 | |
|       //overlay.node id:PublicKey overlay:int256 version:int signature:bytes = overlay.Node;
 | |
|       auto to_sign = ton::create_serialize_tl_object<ton::ton_api::overlay_node_toSign>(
 | |
|           ton::adnl::AdnlNodeIdShort{pub.compute_short_id()}.tl(), key_short_id.tl(), date);
 | |
|       auto n = ton::create_tl_object<ton::ton_api::overlay_node>(
 | |
|           pub.tl(), key_short_id.tl(), date, pk.create_decryptor().move_as_ok()->sign(to_sign.as_slice()).move_as_ok());
 | |
|       obj->nodes_.push_back(std::move(n));
 | |
|       dht_value =
 | |
|           ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|       auto size = ton::serialize_tl_object(obj, true).size();
 | |
|       if (size <= ton::dht::DhtValue::max_value_size()) {
 | |
|         dht_value.check().ensure();
 | |
|       } else {
 | |
|         dht_value.check().ensure_error();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     obj->nodes_.clear();
 | |
|     auto pk = ton::PrivateKey{ton::privkeys::Ed25519::random()};
 | |
|     auto pub = pk.compute_public_key();
 | |
| 
 | |
|     auto date = static_cast<td::int32>(td::Clocks::system() - 10);
 | |
|     //overlay.node.toSign id:adnl.id.short overlay:int256 version:int = overlay.node.ToSign;
 | |
|     //overlay.node id:PublicKey overlay:int256 version:int signature:bytes = overlay.Node;
 | |
|     auto to_sign = ton::create_serialize_tl_object<ton::ton_api::overlay_node_toSign>(
 | |
|         ton::adnl::AdnlNodeIdShort{pub.compute_short_id()}.tl(), key_short_id.tl() ^ td::Bits256::ones(), date);
 | |
|     auto n = ton::create_tl_object<ton::ton_api::overlay_node>(
 | |
|         pub.tl(), key_short_id.tl() ^ td::Bits256::ones(), date,
 | |
|         pk.create_decryptor().move_as_ok()->sign(to_sign.as_slice()).move_as_ok());
 | |
|     obj->nodes_.push_back(std::move(n));
 | |
|     dht_value =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure_error();
 | |
| 
 | |
|     obj->nodes_.clear();
 | |
|     to_sign = ton::create_serialize_tl_object<ton::ton_api::overlay_node_toSign>(
 | |
|         ton::adnl::AdnlNodeIdShort{pub.compute_short_id()}.tl(), key_short_id.tl(), date);
 | |
|     n = ton::create_tl_object<ton::ton_api::overlay_node>(
 | |
|         pub.tl(), key_short_id.tl(), date, pk.create_decryptor().move_as_ok()->sign(to_sign.as_slice()).move_as_ok());
 | |
|     obj->nodes_.push_back(std::move(n));
 | |
|     dht_value =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     obj->nodes_.clear();
 | |
|     //to_sign = ton::create_serialize_tl_object<ton::ton_api::overlay_node_toSign>(
 | |
|     //    ton::adnl::AdnlNodeIdShort{pub.compute_short_id()}.tl(), key_short_id.tl(), date);
 | |
|     n = ton::create_tl_object<ton::ton_api::overlay_node>(pub.tl(), key_short_id.tl(), date, td::BufferSlice{64});
 | |
|     obj->nodes_.push_back(std::move(n));
 | |
|     dht_value =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure_error();
 | |
| 
 | |
|     obj->nodes_.clear();
 | |
|     to_sign = ton::create_serialize_tl_object<ton::ton_api::overlay_node_toSign>(
 | |
|         ton::adnl::AdnlNodeIdShort{pub.compute_short_id()}.tl(), key_short_id.tl(), date);
 | |
|     n = ton::create_tl_object<ton::ton_api::overlay_node>(
 | |
|         pub.tl(), key_short_id.tl(), date, pk.create_decryptor().move_as_ok()->sign(to_sign.as_slice()).move_as_ok());
 | |
|     obj->nodes_.push_back(std::move(n));
 | |
|     dht_value =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value.check().ensure();
 | |
| 
 | |
|     auto dht_value2 =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value2.check().ensure();
 | |
|     dht_value.update(std::move(dht_value2)).ensure();
 | |
|     CHECK(ton::fetch_tl_object<ton::ton_api::overlay_nodes>(dht_value.value().as_slice(), true)
 | |
|               .move_as_ok()
 | |
|               ->nodes_.size() == 1);
 | |
| 
 | |
|     obj->nodes_.clear();
 | |
|     {
 | |
|       td::BufferSlice x{64};
 | |
|       td::Random::secure_bytes(x.as_slice());
 | |
|       auto pk2 = ton::PrivateKey{ton::privkeys::Unenc{x.clone()}};
 | |
|       n = ton::create_tl_object<ton::ton_api::overlay_node>(
 | |
|           pk2.compute_public_key().tl(), key_short_id.tl(), date,
 | |
|           pk2.create_decryptor().move_as_ok()->sign(to_sign.as_slice()).move_as_ok());
 | |
|       obj->nodes_.push_back(std::move(n));
 | |
|     }
 | |
|     dht_value2 =
 | |
|         ton::dht::DhtValue{dht_key_description.clone(), ton::serialize_tl_object(obj, true), ttl, td::BufferSlice()};
 | |
|     dht_value2.check().ensure();
 | |
|     dht_value.update(std::move(dht_value2)).ensure();
 | |
|     CHECK(ton::fetch_tl_object<ton::ton_api::overlay_nodes>(dht_value.value().as_slice(), true)
 | |
|               .move_as_ok()
 | |
|               ->nodes_.size() == 2);
 | |
|   }
 | |
|   LOG(ERROR) << "success";
 | |
| 
 | |
|   LOG(ERROR) << "empty run";
 | |
|   auto t = td::Timestamp::in(10.0);
 | |
|   while (scheduler.run(1)) {
 | |
|     if (t.is_in_past()) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   LOG(ERROR) << "success";
 | |
| 
 | |
|   for (td::uint32 x = 0; x < 100; x++) {
 | |
|     ton::dht::DhtKey dht_key{key_short_id, PSTRING() << "test-" << x, x % 8};
 | |
|     auto dht_update_rule = ton::dht::DhtUpdateRuleSignature::create().move_as_ok();
 | |
|     ton::dht::DhtKeyDescription dht_key_description{std::move(dht_key), key_pub, std::move(dht_update_rule),
 | |
|                                                     td::BufferSlice()};
 | |
|     dht_key_description.update_signature(key_dec->sign(dht_key_description.to_sign()).move_as_ok());
 | |
| 
 | |
|     auto ttl = static_cast<td::uint32>(td::Clocks::system() + 3600);
 | |
|     td::uint8 v[1];
 | |
|     v[0] = static_cast<td::uint8>(x);
 | |
|     ton::dht::DhtValue dht_value{std::move(dht_key_description), td::BufferSlice(td::Slice(v, 1)), ttl,
 | |
|                                  td::BufferSlice("")};
 | |
|     dht_value.update_signature(key_dec->sign(dht_value.to_sign()).move_as_ok());
 | |
| 
 | |
|     remaining++;
 | |
|     auto P = td::PromiseCreator::lambda([&](td::Result<td::Unit> R) {
 | |
|       R.ensure();
 | |
|       remaining--;
 | |
|     });
 | |
| 
 | |
|     scheduler.run_in_context([&] {
 | |
|       td::actor::send_closure(dht[td::Random::fast(0, total_nodes - 1)], &ton::dht::Dht::set_value,
 | |
|                               std::move(dht_value), std::move(P));
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   LOG(ERROR) << "stores";
 | |
|   t = td::Timestamp::in(60.0);
 | |
|   while (scheduler.run(1)) {
 | |
|     if (!remaining) {
 | |
|       break;
 | |
|     }
 | |
|     if (t.is_in_past()) {
 | |
|       LOG(FATAL) << "failed: remaining = " << remaining;
 | |
|     }
 | |
|   }
 | |
|   LOG(ERROR) << "success";
 | |
| 
 | |
|   for (td::uint32 x = 0; x < 100; x++) {
 | |
|     ton::dht::DhtKey dht_key{key_short_id, PSTRING() << "test-" << x, x % 8};
 | |
| 
 | |
|     remaining++;
 | |
|     auto P = td::PromiseCreator::lambda([&, idx = x](td::Result<ton::dht::DhtValue> R) {
 | |
|       R.ensure();
 | |
|       auto v = R.move_as_ok();
 | |
|       CHECK(v.key().key().public_key_hash() == key_short_id);
 | |
|       CHECK(v.key().key().name() == (PSTRING() << "test-" << idx));
 | |
|       CHECK(v.key().key().idx() == idx % 8);
 | |
|       td::uint8 buf[1];
 | |
|       buf[0] = static_cast<td::uint8>(idx);
 | |
|       CHECK(v.value().as_slice() == td::Slice(buf, 1));
 | |
|       remaining--;
 | |
|     });
 | |
| 
 | |
|     scheduler.run_in_context([&] {
 | |
|       td::actor::send_closure(dht[td::Random::fast(0, total_nodes - 1)], &ton::dht::Dht::get_value, dht_key,
 | |
|                               std::move(P));
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   LOG(ERROR) << "gets";
 | |
|   t = td::Timestamp::in(60.0);
 | |
|   while (scheduler.run(1)) {
 | |
|     if (!remaining) {
 | |
|       break;
 | |
|     }
 | |
|     if (t.is_in_past()) {
 | |
|       LOG(FATAL) << "failed: remaining = " << remaining;
 | |
|     }
 | |
|   }
 | |
|   LOG(ERROR) << "success";
 | |
| 
 | |
|   td::rmrf(db_root_).ensure();
 | |
|   std::_Exit(0);
 | |
|   return 0;
 | |
| }
 |