mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Accelerator: partial fullnodes (#1393)
* Accelerator: partial fullnodes 1) Node can monitor a subset of shards 2) New archive slice format (sharded) 3) Validators are still required to have all shards 4) Support partial liteservers in lite-client, blockchain explorer, tonlib 5) Proxy liteserver * Fix compilation error
This commit is contained in:
		
							parent
							
								
									62444100f5
								
							
						
					
					
						commit
						954a96a077
					
				
					 83 changed files with 3213 additions and 1113 deletions
				
			
		|  | @ -29,22 +29,16 @@ | |||
| 
 | ||||
| #include "lite-client-common.h" | ||||
| 
 | ||||
| #include "adnl/adnl-ext-client.h" | ||||
| #include "tl-utils/lite-utils.hpp" | ||||
| #include "auto/tl/ton_api_json.h" | ||||
| #include "auto/tl/lite_api.hpp" | ||||
| #include "td/utils/OptionParser.h" | ||||
| #include "td/utils/Time.h" | ||||
| #include "td/utils/filesystem.h" | ||||
| #include "td/utils/format.h" | ||||
| #include "td/utils/Random.h" | ||||
| #include "td/utils/crypto.h" | ||||
| #include "td/utils/overloaded.h" | ||||
| #include "td/utils/port/signals.h" | ||||
| #include "td/utils/port/stacktrace.h" | ||||
| #include "td/utils/port/StdStreams.h" | ||||
| #include "td/utils/port/FileFd.h" | ||||
| #include "terminal/terminal.h" | ||||
| #include "ton/lite-tl.hpp" | ||||
| #include "block/block-db.h" | ||||
| #include "block/block.h" | ||||
|  | @ -58,18 +52,14 @@ | |||
| #include "vm/vm.h" | ||||
| #include "vm/cp0.h" | ||||
| #include "vm/memo.h" | ||||
| #include "ton/ton-shard.h" | ||||
| #include "openssl/rand.hpp" | ||||
| #include "crypto/vm/utils.h" | ||||
| #include "crypto/common/util.h" | ||||
| #include "common/checksum.h" | ||||
| 
 | ||||
| #if TD_DARWIN || TD_LINUX | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #endif | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include "git.h" | ||||
| 
 | ||||
| using namespace std::literals::string_literals; | ||||
|  | @ -77,24 +67,6 @@ using td::Ref; | |||
| 
 | ||||
| int verbosity; | ||||
| 
 | ||||
| std::unique_ptr<ton::adnl::AdnlExtClient::Callback> TestNode::make_callback() { | ||||
|   class Callback : public ton::adnl::AdnlExtClient::Callback { | ||||
|    public: | ||||
|     void on_ready() override { | ||||
|       td::actor::send_closure(id_, &TestNode::conn_ready); | ||||
|     } | ||||
|     void on_stop_ready() override { | ||||
|       td::actor::send_closure(id_, &TestNode::conn_closed); | ||||
|     } | ||||
|     Callback(td::actor::ActorId<TestNode> id) : id_(std::move(id)) { | ||||
|     } | ||||
| 
 | ||||
|    private: | ||||
|     td::actor::ActorId<TestNode> id_; | ||||
|   }; | ||||
|   return std::make_unique<Callback>(actor_id(this)); | ||||
| } | ||||
| 
 | ||||
| void TestNode::run() { | ||||
|   class Cb : public td::TerminalIO::Callback { | ||||
|    public: | ||||
|  | @ -110,19 +82,20 @@ void TestNode::run() { | |||
|   io_ = td::TerminalIO::create("> ", readline_enabled_, ex_mode_, std::make_unique<Cb>(actor_id(this))); | ||||
|   td::actor::send_closure(io_, &td::TerminalIO::set_log_interface); | ||||
| 
 | ||||
|   if (remote_public_key_.empty()) { | ||||
|   std::vector<liteclient::LiteServerConfig> servers; | ||||
|   if (!single_remote_public_key_.empty()) {  // Use single provided liteserver
 | ||||
|     servers.push_back( | ||||
|         liteclient::LiteServerConfig{ton::adnl::AdnlNodeIdFull{single_remote_public_key_}, single_remote_addr_}); | ||||
|     td::TerminalIO::out() << "using liteserver " << single_remote_addr_ << "\n"; | ||||
|   } else { | ||||
|     auto G = td::read_file(global_config_).move_as_ok(); | ||||
|     auto gc_j = td::json_decode(G.as_slice()).move_as_ok(); | ||||
|     ton::ton_api::liteclient_config_global gc; | ||||
|     ton::ton_api::from_json(gc, gc_j.get_object()).ensure(); | ||||
|     CHECK(gc.liteservers_.size() > 0); | ||||
|     auto idx = liteserver_idx_ >= 0 ? liteserver_idx_ | ||||
|                                     : td::Random::fast(0, static_cast<td::uint32>(gc.liteservers_.size() - 1)); | ||||
|     CHECK(idx >= 0 && static_cast<td::uint32>(idx) <= gc.liteservers_.size()); | ||||
|     auto& cli = gc.liteservers_[idx]; | ||||
|     remote_addr_.init_host_port(td::IPAddress::ipv4_to_str(cli->ip_), cli->port_).ensure(); | ||||
|     remote_public_key_ = ton::PublicKey{cli->id_}; | ||||
|     td::TerminalIO::out() << "using liteserver " << idx << " with addr " << remote_addr_ << "\n"; | ||||
|     auto r_servers = liteclient::LiteServerConfig::parse_global_config(gc); | ||||
|     r_servers.ensure(); | ||||
|     servers = r_servers.move_as_ok(); | ||||
| 
 | ||||
|     if (gc.validator_ && gc.validator_->zero_state_) { | ||||
|       zstate_id_.workchain = gc.validator_->zero_state_->workchain_; | ||||
|       if (zstate_id_.workchain != ton::workchainInvalid) { | ||||
|  | @ -131,10 +104,19 @@ void TestNode::run() { | |||
|         td::TerminalIO::out() << "zerostate set to " << zstate_id_.to_str() << "\n"; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   client_ = | ||||
|       ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{remote_public_key_}, remote_addr_, make_callback()); | ||||
|     if (single_liteserver_idx_ != -1) {  // Use single liteserver from config
 | ||||
|       CHECK(single_liteserver_idx_ >= 0 && (size_t)single_liteserver_idx_ < servers.size()); | ||||
|       td::TerminalIO::out() << "using liteserver #" << single_liteserver_idx_ << " with addr " | ||||
|                             << servers[single_liteserver_idx_].addr << "\n"; | ||||
|       servers = {servers[single_liteserver_idx_]}; | ||||
|     } | ||||
|   } | ||||
|   CHECK(!servers.empty()); | ||||
|   client_ = liteclient::ExtClient::create(std::move(servers), nullptr); | ||||
|   ready_ = true; | ||||
| 
 | ||||
|   run_init_queries(); | ||||
| } | ||||
| 
 | ||||
| void TestNode::got_result(td::Result<td::BufferSlice> R, td::Promise<td::BufferSlice> promise) { | ||||
|  | @ -191,8 +173,8 @@ bool TestNode::envelope_send_query(td::BufferSlice query, td::Promise<td::Buffer | |||
|       }); | ||||
|   td::BufferSlice b = | ||||
|       ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_query>(std::move(query)), true); | ||||
|   td::actor::send_closure(client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(b), | ||||
|                           td::Timestamp::in(10.0), std::move(P)); | ||||
|   td::actor::send_closure(client_, &liteclient::ExtClient::send_query, "query", std::move(b), td::Timestamp::in(10.0), | ||||
|                           std::move(P)); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
|  | @ -319,9 +301,10 @@ bool TestNode::get_server_time() { | |||
|       if (F.is_error()) { | ||||
|         LOG(ERROR) << "cannot parse answer to liteServer.getTime"; | ||||
|       } else { | ||||
|         server_time_ = F.move_as_ok()->now_; | ||||
|         server_time_got_at_ = now(); | ||||
|         LOG(INFO) << "server time is " << server_time_ << " (delta " << server_time_ - server_time_got_at_ << ")"; | ||||
|         mc_server_time_ = F.move_as_ok()->now_; | ||||
|         mc_server_time_got_at_ = now(); | ||||
|         LOG(INFO) << "server time is " << mc_server_time_ << " (delta " << mc_server_time_ - mc_server_time_got_at_ | ||||
|                   << ")"; | ||||
|       } | ||||
|     } | ||||
|   }); | ||||
|  | @ -335,7 +318,7 @@ bool TestNode::get_server_version(int mode) { | |||
| }; | ||||
| 
 | ||||
| void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) { | ||||
|   server_ok_ = false; | ||||
|   mc_server_ok_ = false; | ||||
|   if (res.is_error()) { | ||||
|     LOG(ERROR) << "cannot get server version and time (server too old?)"; | ||||
|   } else { | ||||
|  | @ -344,11 +327,11 @@ void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) { | |||
|       LOG(ERROR) << "cannot parse answer to liteServer.getVersion"; | ||||
|     } else { | ||||
|       auto a = F.move_as_ok(); | ||||
|       set_server_version(a->version_, a->capabilities_); | ||||
|       set_server_time(a->now_); | ||||
|       set_mc_server_version(a->version_, a->capabilities_); | ||||
|       set_mc_server_time(a->now_); | ||||
|     } | ||||
|   } | ||||
|   if (!server_ok_) { | ||||
|   if (!mc_server_ok_) { | ||||
|     LOG(ERROR) << "server version is too old (at least " << (min_ls_version >> 8) << "." << (min_ls_version & 0xff) | ||||
|                << " with capabilities " << min_ls_capabilities << " required), some queries are unavailable"; | ||||
|   } | ||||
|  | @ -357,24 +340,24 @@ void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void TestNode::set_server_version(td::int32 version, td::int64 capabilities) { | ||||
|   if (server_version_ != version || server_capabilities_ != capabilities) { | ||||
|     server_version_ = version; | ||||
|     server_capabilities_ = capabilities; | ||||
|     LOG(WARNING) << "server version is " << (server_version_ >> 8) << "." << (server_version_ & 0xff) | ||||
|                  << ", capabilities " << server_capabilities_; | ||||
| void TestNode::set_mc_server_version(td::int32 version, td::int64 capabilities) { | ||||
|   if (mc_server_version_ != version || mc_server_capabilities_ != capabilities) { | ||||
|     mc_server_version_ = version; | ||||
|     mc_server_capabilities_ = capabilities; | ||||
|     LOG(WARNING) << "server version is " << (mc_server_version_ >> 8) << "." << (mc_server_version_ & 0xff) | ||||
|                  << ", capabilities " << mc_server_capabilities_; | ||||
|   } | ||||
|   server_ok_ = (server_version_ >= min_ls_version) && !(~server_capabilities_ & min_ls_capabilities); | ||||
|   mc_server_ok_ = (mc_server_version_ >= min_ls_version) && !(~mc_server_capabilities_ & min_ls_capabilities); | ||||
| } | ||||
| 
 | ||||
| void TestNode::set_server_time(int server_utime) { | ||||
|   server_time_ = server_utime; | ||||
|   server_time_got_at_ = now(); | ||||
|   LOG(INFO) << "server time is " << server_time_ << " (delta " << server_time_ - server_time_got_at_ << ")"; | ||||
| void TestNode::set_mc_server_time(int server_utime) { | ||||
|   mc_server_time_ = server_utime; | ||||
|   mc_server_time_got_at_ = now(); | ||||
|   LOG(INFO) << "server time is " << mc_server_time_ << " (delta " << mc_server_time_ - mc_server_time_got_at_ << ")"; | ||||
| } | ||||
| 
 | ||||
| bool TestNode::get_server_mc_block_id() { | ||||
|   int mode = (server_capabilities_ & 2) ? 0 : -1; | ||||
|   int mode = (mc_server_capabilities_ & 2) ? 0 : -1; | ||||
|   if (mode < 0) { | ||||
|     auto b = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getMasterchainInfo>(), true); | ||||
|     return envelope_send_query(std::move(b), [Self = actor_id(this)](td::Result<td::BufferSlice> res) -> void { | ||||
|  | @ -448,8 +431,8 @@ void TestNode::got_server_mc_block_id(ton::BlockIdExt blkid, ton::ZeroStateIdExt | |||
| 
 | ||||
| void TestNode::got_server_mc_block_id_ext(ton::BlockIdExt blkid, ton::ZeroStateIdExt zstateid, int mode, int version, | ||||
|                                           long long capabilities, int last_utime, int server_now) { | ||||
|   set_server_version(version, capabilities); | ||||
|   set_server_time(server_now); | ||||
|   set_mc_server_version(version, capabilities); | ||||
|   set_mc_server_time(server_now); | ||||
|   if (last_utime > server_now) { | ||||
|     LOG(WARNING) << "server claims to have a masterchain block " << blkid.to_str() << " created at " << last_utime | ||||
|                  << " (" << last_utime - server_now << " seconds in the future)"; | ||||
|  | @ -457,10 +440,10 @@ void TestNode::got_server_mc_block_id_ext(ton::BlockIdExt blkid, ton::ZeroStateI | |||
|     LOG(WARNING) << "server appears to be out of sync: its newest masterchain block is " << blkid.to_str() | ||||
|                  << " created at " << last_utime << " (" << server_now - last_utime | ||||
|                  << " seconds ago according to the server's clock)"; | ||||
|   } else if (last_utime < server_time_got_at_ - 60) { | ||||
|   } else if (last_utime < mc_server_time_got_at_ - 60) { | ||||
|     LOG(WARNING) << "either the server is out of sync, or the local clock is set incorrectly: the newest masterchain " | ||||
|                     "block known to server is " | ||||
|                  << blkid.to_str() << " created at " << last_utime << " (" << server_now - server_time_got_at_ | ||||
|                  << blkid.to_str() << " created at " << last_utime << " (" << server_now - mc_server_time_got_at_ | ||||
|                  << " seconds ago according to the local clock)"; | ||||
|   } | ||||
|   got_server_mc_block_id(blkid, zstateid, last_utime); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue