/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "ton/ton-types.h" #include "td/actor/actor.h" #include "td/utils/Time.h" #include "interfaces/block-handle.h" #include "interfaces/validator-manager.h" #include "interfaces/shard.h" #include "block.hpp" #include "shard.hpp" #include "proof.hpp" #include "block/block-auto.h" #include "auto/tl/lite_api.h" namespace ton { namespace validator { using td::Ref; class LiteQuery : public td::actor::Actor { td::BufferSlice query_; td::actor::ActorId manager_; td::actor::ActorId cache_; td::Timestamp timeout_; td::Promise promise_; td::Promise,UnixTime,LogicalTime,std::unique_ptr>> acc_state_promise_; tl_object_ptr query_obj_; bool use_cache_{false}; td::Bits256 cache_key_; int pending_{0}; int mode_{0}; WorkchainId acc_workchain_; StdSmcAddress acc_addr_; LogicalTime trans_lt_; Bits256 trans_hash_; BlockIdExt base_blk_id_, base_blk_id_alt_, blk_id_; Ref mc_state_, mc_state0_; Ref state_; Ref mc_block_, block_; Ref mc_proof_, mc_proof_alt_; Ref proof_link_; td::BufferSlice buffer_; std::function continuation_; bool cont_set_{false}; td::BufferSlice shard_proof_, proof_; std::vector> roots_; std::vector> aux_objs_; std::vector blk_ids_; std::unique_ptr chain_; Ref stack_; td::BufferSlice lookup_header_proof_; td::BufferSlice lookup_prev_header_proof_; public: enum { default_timeout_msec = 4500, // 4.5 seconds max_transaction_count = 16, // fetch at most 16 transactions in one query client_method_gas_limit = 300000 // gas limit for liteServer.runSmcMethod }; enum { ls_version = 0x101, ls_capabilities = 7 }; // version 1.1; +1 = build block proof chains, +2 = masterchainInfoExt, +4 = runSmcMethod LiteQuery(td::BufferSlice data, td::actor::ActorId manager, td::actor::ActorId cache, td::Promise promise); LiteQuery(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId manager, td::Promise,UnixTime,LogicalTime,std::unique_ptr>> promise); static void run_query(td::BufferSlice data, td::actor::ActorId manager, td::actor::ActorId cache, td::Promise promise); static void fetch_account_state(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId manager, td::Promise,UnixTime,LogicalTime,std::unique_ptr>> promise); private: bool fatal_error(td::Status error); bool fatal_error(std::string err_msg, int err_code = -400); bool fatal_error(int err_code, std::string err_msg = ""); void abort_query(td::Status reason); void abort_query_ext(td::Status reason, std::string err_msg); bool finish_query(td::BufferSlice result, bool skip_cache_update = false); void alarm() override; void start_up() override; bool use_cache(); void perform(); void perform_getTime(); void perform_getVersion(); void perform_getMasterchainInfo(int mode); void continue_getMasterchainInfo(Ref mc_state, BlockIdExt blkid, int mode); void gotMasterchainInfoForAccountState(Ref mc_state, BlockIdExt blkid, int mode); void perform_getBlock(BlockIdExt blkid); void continue_getBlock(BlockIdExt blkid, Ref block); void perform_getBlockHeader(BlockIdExt blkid, int mode); void continue_getBlockHeader(BlockIdExt blkid, int mode, Ref block); void perform_getState(BlockIdExt blkid); void continue_getState(BlockIdExt blkid, Ref state); void continue_getZeroState(BlockIdExt blkid, td::BufferSlice state); void perform_sendMessage(td::BufferSlice ext_msg); void perform_getAccountState(BlockIdExt blkid, WorkchainId workchain, StdSmcAddress addr, int mode); void continue_getAccountState_0(Ref mc_state, BlockIdExt blkid); void continue_getAccountState(); void finish_getAccountState(td::BufferSlice shard_proof); void perform_fetchAccountState(); void perform_runSmcMethod(BlockIdExt blkid, WorkchainId workchain, StdSmcAddress addr, int mode, td::int64 method_id, td::BufferSlice params); void finish_runSmcMethod(td::BufferSlice shard_proof, td::BufferSlice state_proof, Ref acc_root, UnixTime gen_utime, LogicalTime gen_lt); void perform_getLibraries(std::vector library_list); void continue_getLibraries(Ref mc_state, BlockIdExt blkid, std::vector library_list); void perform_getLibrariesWithProof(BlockIdExt blkid, int mode, std::vector library_list); void continue_getLibrariesWithProof(std::vector library_list, int mode); void perform_getOneTransaction(BlockIdExt blkid, WorkchainId workchain, StdSmcAddress addr, LogicalTime lt); void continue_getOneTransaction(); void perform_getTransactions(WorkchainId workchain, StdSmcAddress addr, LogicalTime lt, Bits256 hash, unsigned count); void continue_getTransactions(unsigned remaining, bool exact); void continue_getTransactions_2(BlockIdExt blkid, Ref block, unsigned remaining); void abort_getTransactions(td::Status error, ton::BlockIdExt blkid); void finish_getTransactions(); void perform_getShardInfo(BlockIdExt blkid, ShardIdFull shard, bool exact); void perform_getAllShardsInfo(BlockIdExt blkid); void continue_getShardInfo(ShardIdFull shard, bool exact); void continue_getAllShardsInfo(); void perform_getConfigParams(BlockIdExt blkid, int mode, std::vector param_list = {}); void continue_getConfigParams(int mode, std::vector param_list); void perform_lookupBlock(BlockId blkid, int mode, LogicalTime lt, UnixTime utime); void perform_lookupBlockWithProof(BlockId blkid, BlockIdExt client_mc_blkid, int mode, LogicalTime lt, UnixTime utime); void continue_lookupBlockWithProof_getHeaderProof(Ref block, AccountIdPrefixFull req_prefix, BlockSeqno masterchain_ref_seqno); void continue_lookupBlockWithProof_gotPrevBlockData(Ref prev_block, BlockSeqno masterchain_ref_seqno); void continue_lookupBlockWithProof_buildProofLinks(td::Ref cur_block, std::vector>> result); void continue_lookupBlockWithProof_getClientMcBlockDataState(std::vector>> links); void continue_lookupBlockWithProof_getMcBlockPrev(std::vector>> links); void perform_listBlockTransactions(BlockIdExt blkid, int mode, int count, Bits256 account, LogicalTime lt); void finish_listBlockTransactions(int mode, int count); void perform_listBlockTransactionsExt(BlockIdExt blkid, int mode, int count, Bits256 account, LogicalTime lt); void finish_listBlockTransactionsExt(int mode, int count); void perform_getBlockProof(BlockIdExt from, BlockIdExt to, int mode); void continue_getBlockProof(BlockIdExt from, BlockIdExt to, int mode, BlockIdExt baseblk, Ref state); void perform_getValidatorStats(BlockIdExt blkid, int mode, int count, Bits256 start_after, UnixTime min_utime); void continue_getValidatorStats(int mode, int limit, Bits256 start_after, UnixTime min_utime); bool construct_proof_chain(BlockIdExt id); bool construct_proof_link_forward(ton::BlockIdExt cur, ton::BlockIdExt next); bool construct_proof_link_forward_cont(ton::BlockIdExt cur, ton::BlockIdExt next); bool construct_proof_link_back(ton::BlockIdExt cur, ton::BlockIdExt next); bool construct_proof_link_back_cont(ton::BlockIdExt cur, ton::BlockIdExt next); bool adjust_last_proof_link(ton::BlockIdExt cur, Ref block_root); bool finish_proof_chain(ton::BlockIdExt id); void perform_getShardBlockProof(BlockIdExt blkid); void continue_getShardBlockProof(Ref cur_block, std::vector> result); void perform_getOutMsgQueueSizes(td::optional shard); void continue_getOutMsgQueueSizes(td::optional shard, Ref state); void perform_getBlockOutMsgQueueSize(int mode, BlockIdExt blkid); void finish_getBlockOutMsgQueueSize(); void perform_getDispatchQueueInfo(int mode, BlockIdExt blkid, StdSmcAddress after_addr, int max_accounts); void finish_getDispatchQueueInfo(StdSmcAddress after_addr, int max_accounts); void perform_getDispatchQueueMessages(int mode, BlockIdExt blkid, StdSmcAddress addr, LogicalTime lt, int max_messages); void finish_getDispatchQueueMessages(StdSmcAddress addr, LogicalTime lt, int max_messages); void perform_nonfinal_getCandidate(td::Bits256 source, BlockIdExt blkid, td::Bits256 collated_data_hash); void perform_nonfinal_getValidatorGroups(int mode, ShardIdFull shard); void load_prevKeyBlock(ton::BlockIdExt blkid, td::Promise>>); void continue_loadPrevKeyBlock(ton::BlockIdExt blkid, td::Result, BlockIdExt>> res, td::Promise>>); void finish_loadPrevKeyBlock(ton::BlockIdExt blkid, td::Result> res, td::Promise>> promise); void get_block_handle_checked(BlockIdExt blkid, td::Promise promise); bool request_block_data(BlockIdExt blkid); bool request_block_state(BlockIdExt blkid); bool request_block_data_state(BlockIdExt blkid); bool request_proof_link(BlockIdExt blkid); bool request_mc_block_data(BlockIdExt blkid); bool request_mc_block_state(BlockIdExt blkid); bool request_mc_block_data_state(BlockIdExt blkid); bool request_mc_proof(BlockIdExt blkid, int mode = 0); bool request_zero_state(BlockIdExt blkid); void got_block_state(BlockIdExt blkid, Ref state); void got_mc_block_state(BlockIdExt blkid, Ref state); void got_block_data(BlockIdExt blkid, Ref data); void got_mc_block_data(BlockIdExt blkid, Ref data); void got_mc_block_proof(BlockIdExt blkid, int mode, Ref proof); void got_block_proof_link(BlockIdExt blkid, Ref proof_link); void got_zero_state(BlockIdExt blkid, td::BufferSlice zerostate); void dec_pending() { if (!--pending_) { check_pending(); } } void check_pending(); bool set_continuation(std::function&& cont); bool make_mc_state_root_proof(Ref& proof); bool make_state_root_proof(Ref& proof); bool make_state_root_proof(Ref& proof, Ref state, Ref block, const BlockIdExt& blkid); bool make_state_root_proof(Ref& proof, Ref state_root, Ref block_root, const BlockIdExt& blkid); bool make_shard_info_proof(Ref& proof, Ref& info, ShardIdFull shard, ShardIdFull& true_shard, Ref& leaf, bool& found, bool exact = true); bool make_shard_info_proof(Ref& proof, Ref& info, ShardIdFull shard, bool exact = true); bool make_shard_info_proof(Ref& proof, Ref& info, AccountIdPrefixFull prefix); bool make_shard_info_proof(Ref& proof, BlockIdExt& blkid, AccountIdPrefixFull prefix); bool make_ancestor_block_proof(Ref& proof, Ref state_root, const BlockIdExt& old_blkid); }; } // namespace validator } // namespace ton