mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Get neighbors' msg queues from other nodes
This commit is contained in:
		
							parent
							
								
									1869a25062
								
							
						
					
					
						commit
						e43e235143
					
				
					 22 changed files with 658 additions and 68 deletions
				
			
		| 
						 | 
					@ -410,6 +410,9 @@ tonNode.success = tonNode.Success;
 | 
				
			||||||
tonNode.archiveNotFound = tonNode.ArchiveInfo;
 | 
					tonNode.archiveNotFound = tonNode.ArchiveInfo;
 | 
				
			||||||
tonNode.archiveInfo id:long = tonNode.ArchiveInfo;
 | 
					tonNode.archiveInfo id:long = tonNode.ArchiveInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tonNode.outMsgQueueProof queue_proof:bytes block_state_proof:bytes = tonNode.OutMsgQueueProof;
 | 
				
			||||||
 | 
					tonNode.outMsgQueueProofEmpty = tonNode.OutMsgQueueProof;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---functions---
 | 
					---functions---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tonNode.getNextBlockDescription prev_block:tonNode.blockIdExt = tonNode.BlockDescription;
 | 
					tonNode.getNextBlockDescription prev_block:tonNode.blockIdExt = tonNode.BlockDescription;
 | 
				
			||||||
| 
						 | 
					@ -441,6 +444,7 @@ tonNode.downloadBlockProofLinks blocks:(vector tonNode.blockIdExt) = tonNode.Dat
 | 
				
			||||||
tonNode.downloadKeyBlockProofLinks blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
 | 
					tonNode.downloadKeyBlockProofLinks blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
 | 
				
			||||||
tonNode.getArchiveInfo masterchain_seqno:int = tonNode.ArchiveInfo;
 | 
					tonNode.getArchiveInfo masterchain_seqno:int = tonNode.ArchiveInfo;
 | 
				
			||||||
tonNode.getArchiveSlice archive_id:long offset:long max_size:int = tonNode.Data;
 | 
					tonNode.getArchiveSlice archive_id:long offset:long max_size:int = tonNode.Data;
 | 
				
			||||||
 | 
					tonNode.getOutMsgQueueProof block_id:tonNode.blockIdExt dst_workchain:int dst_shard:long = tonNode.OutMsgQueueProof;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tonNode.getCapabilities = tonNode.Capabilities;
 | 
					tonNode.getCapabilities = tonNode.Capabilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -43,6 +43,7 @@ set(VALIDATOR_HEADERS
 | 
				
			||||||
  fabric.h
 | 
					  fabric.h
 | 
				
			||||||
  interfaces/db.h
 | 
					  interfaces/db.h
 | 
				
			||||||
  interfaces/external-message.h
 | 
					  interfaces/external-message.h
 | 
				
			||||||
 | 
					  interfaces/out-msg-queue-proof.h
 | 
				
			||||||
  interfaces/proof.h
 | 
					  interfaces/proof.h
 | 
				
			||||||
  interfaces/shard.h
 | 
					  interfaces/shard.h
 | 
				
			||||||
  interfaces/signature-set.h
 | 
					  interfaces/signature-set.h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
#include "auto/tl/ton_api.h"
 | 
					#include "auto/tl/ton_api.h"
 | 
				
			||||||
#include "overlays.h"
 | 
					#include "overlays.h"
 | 
				
			||||||
#include "td/utils/SharedSlice.h"
 | 
					#include "td/utils/SharedSlice.h"
 | 
				
			||||||
 | 
					#include "td/utils/overloaded.h"
 | 
				
			||||||
#include "full-node-shard.hpp"
 | 
					#include "full-node-shard.hpp"
 | 
				
			||||||
#include "full-node-shard-queries.hpp"
 | 
					#include "full-node-shard-queries.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +35,7 @@
 | 
				
			||||||
#include "net/download-proof.hpp"
 | 
					#include "net/download-proof.hpp"
 | 
				
			||||||
#include "net/get-next-key-blocks.hpp"
 | 
					#include "net/get-next-key-blocks.hpp"
 | 
				
			||||||
#include "net/download-archive-slice.hpp"
 | 
					#include "net/download-archive-slice.hpp"
 | 
				
			||||||
 | 
					#include "impl/out-msg-queue-proof.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "td/utils/Random.h"
 | 
					#include "td/utils/Random.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,6 +576,31 @@ void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNod
 | 
				
			||||||
                          query.offset_, query.max_size_, std::move(promise));
 | 
					                          query.offset_, query.max_size_, std::move(promise));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getOutMsgQueueProof &query,
 | 
				
			||||||
 | 
					                                      td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
 | 
					  BlockIdExt block_id = create_block_id(query.block_id_);
 | 
				
			||||||
 | 
					  ShardIdFull dst_shard(query.dst_workchain_, query.dst_shard_);
 | 
				
			||||||
 | 
					  if (!block_id.is_valid_ext()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error("invalid block_id"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!dst_shard.is_valid_ext()) {
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error("invalid shard"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
 | 
					      [promise = std::move(promise)](td::Result<tl_object_ptr<ton_api::tonNode_outMsgQueueProof>> R) mutable {
 | 
				
			||||||
 | 
					        if (R.is_error()) {
 | 
				
			||||||
 | 
					          promise.set_result(create_serialize_tl_object<ton_api::tonNode_outMsgQueueProofEmpty>());
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          promise.set_result(serialize_tl_object(R.move_as_ok(), true));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  td::actor::create_actor<BuildOutMsgQueueProof>("buildqueueproof", block_id, dst_shard, validator_manager_,
 | 
				
			||||||
 | 
					                                                 std::move(P))
 | 
				
			||||||
 | 
					      .release();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FullNodeShardImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query,
 | 
					void FullNodeShardImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query,
 | 
				
			||||||
                                      td::Promise<td::BufferSlice> promise) {
 | 
					                                      td::Promise<td::BufferSlice> promise) {
 | 
				
			||||||
  if (!active_) {
 | 
					  if (!active_) {
 | 
				
			||||||
| 
						 | 
					@ -791,6 +818,32 @@ void FullNodeShardImpl::download_archive(BlockSeqno masterchain_seqno, std::stri
 | 
				
			||||||
      .release();
 | 
					      .release();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FullNodeShardImpl::download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                                     td::Promise<td::Ref<OutMsgQueueProof>> promise) {
 | 
				
			||||||
 | 
					  // TODO: maybe more complex download (like other requests here)
 | 
				
			||||||
 | 
					  // TODO: estimate max size
 | 
				
			||||||
 | 
					  auto &b = choose_neighbour();
 | 
				
			||||||
 | 
					  auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
 | 
					      [=, promise = create_neighbour_promise(b, std::move(promise))](td::Result<td::BufferSlice> R) mutable {
 | 
				
			||||||
 | 
					        if (R.is_error()) {
 | 
				
			||||||
 | 
					          promise.set_result(R.move_as_error());
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        TRY_RESULT_PROMISE(promise, f, fetch_tl_object<ton_api::tonNode_OutMsgQueueProof>(R.move_as_ok(), true));
 | 
				
			||||||
 | 
					        ton_api::downcast_call(*f, td::overloaded(
 | 
				
			||||||
 | 
					                                       [&](ton_api::tonNode_outMsgQueueProofEmpty &x) {
 | 
				
			||||||
 | 
					                                         promise.set_error(td::Status::Error("node doesn't have this block"));
 | 
				
			||||||
 | 
					                                       },
 | 
				
			||||||
 | 
					                                       [&](ton_api::tonNode_outMsgQueueProof &x) {
 | 
				
			||||||
 | 
					                                         promise.set_result(OutMsgQueueProof::fetch(block_id, dst_shard, x));
 | 
				
			||||||
 | 
					                                       }));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  td::BufferSlice query = create_serialize_tl_object<ton_api::tonNode_getOutMsgQueueProof>(
 | 
				
			||||||
 | 
					      create_tl_block_id(block_id), dst_shard.workchain, dst_shard.shard);
 | 
				
			||||||
 | 
					  td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, b.adnl_id, adnl_id_, overlay_id_,
 | 
				
			||||||
 | 
					                          "get_msg_queue", std::move(P), timeout, std::move(query), 1 << 20, rldp_);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FullNodeShardImpl::set_handle(BlockHandle handle, td::Promise<td::Unit> promise) {
 | 
					void FullNodeShardImpl::set_handle(BlockHandle handle, td::Promise<td::Unit> promise) {
 | 
				
			||||||
  CHECK(!handle_);
 | 
					  CHECK(!handle_);
 | 
				
			||||||
  handle_ = std::move(handle);
 | 
					  handle_ = std::move(handle);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,8 @@ class FullNodeShard : public td::actor::Actor {
 | 
				
			||||||
                                   td::Promise<std::vector<BlockIdExt>> promise) = 0;
 | 
					                                   td::Promise<std::vector<BlockIdExt>> promise) = 0;
 | 
				
			||||||
  virtual void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
					  virtual void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
				
			||||||
                                td::Promise<std::string> promise) = 0;
 | 
					                                td::Promise<std::string> promise) = 0;
 | 
				
			||||||
 | 
					  virtual void download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                            td::Promise<td::Ref<OutMsgQueueProof>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) = 0;
 | 
					  virtual void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,6 +133,8 @@ class FullNodeShardImpl : public FullNodeShard {
 | 
				
			||||||
                     td::Promise<td::BufferSlice> promise);
 | 
					                     td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
  void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getArchiveSlice &query,
 | 
					  void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getArchiveSlice &query,
 | 
				
			||||||
                     td::Promise<td::BufferSlice> promise);
 | 
					                     td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
 | 
					  void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getOutMsgQueueProof &query,
 | 
				
			||||||
 | 
					                     td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
  // void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareNextKeyBlockProof &query,
 | 
					  // void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareNextKeyBlockProof &query,
 | 
				
			||||||
  //                   td::Promise<td::BufferSlice> promise);
 | 
					  //                   td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
  void receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise<td::BufferSlice> promise);
 | 
					  void receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise<td::BufferSlice> promise);
 | 
				
			||||||
| 
						 | 
					@ -164,6 +166,8 @@ class FullNodeShardImpl : public FullNodeShard {
 | 
				
			||||||
                           td::Promise<std::vector<BlockIdExt>> promise) override;
 | 
					                           td::Promise<std::vector<BlockIdExt>> promise) override;
 | 
				
			||||||
  void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
					  void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
				
			||||||
                        td::Promise<std::string> promise) override;
 | 
					                        td::Promise<std::string> promise) override;
 | 
				
			||||||
 | 
					  void download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                    td::Promise<td::Ref<OutMsgQueueProof>> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) override;
 | 
					  void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -356,6 +356,18 @@ void FullNodeImpl::download_archive(BlockSeqno masterchain_seqno, std::string tm
 | 
				
			||||||
                          std::move(promise));
 | 
					                          std::move(promise));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FullNodeImpl::download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                                td::Promise<td::Ref<OutMsgQueueProof>> promise) {
 | 
				
			||||||
 | 
					  auto shard = get_shard(block_id.shard_full());
 | 
				
			||||||
 | 
					  if (shard.empty()) {
 | 
				
			||||||
 | 
					    VLOG(FULL_NODE_WARNING) << "dropping download msg queue query to unknown shard";
 | 
				
			||||||
 | 
					    promise.set_error(td::Status::Error(ErrorCode::notready, "shard not ready"));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  td::actor::send_closure(shard, &FullNodeShard::download_out_msg_queue_proof, block_id, dst_shard, timeout,
 | 
				
			||||||
 | 
					                          std::move(promise));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
td::actor::ActorId<FullNodeShard> FullNodeImpl::get_shard(ShardIdFull shard, bool exact) {
 | 
					td::actor::ActorId<FullNodeShard> FullNodeImpl::get_shard(ShardIdFull shard, bool exact) {
 | 
				
			||||||
  if (!exact) {
 | 
					  if (!exact) {
 | 
				
			||||||
    ShardIdFull s = shard;
 | 
					    ShardIdFull s = shard;
 | 
				
			||||||
| 
						 | 
					@ -546,6 +558,11 @@ void FullNodeImpl::start_up() {
 | 
				
			||||||
      td::actor::send_closure(id_, &FullNodeImpl::download_archive, masterchain_seqno, std::move(tmp_dir), timeout,
 | 
					      td::actor::send_closure(id_, &FullNodeImpl::download_archive, masterchain_seqno, std::move(tmp_dir), timeout,
 | 
				
			||||||
                              std::move(promise));
 | 
					                              std::move(promise));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    void download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                      td::Promise<td::Ref<OutMsgQueueProof>> promise) override {
 | 
				
			||||||
 | 
					      td::actor::send_closure(id_, &FullNodeImpl::download_out_msg_queue_proof, block_id, dst_shard, timeout,
 | 
				
			||||||
 | 
					                              std::move(promise));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void new_key_block(BlockHandle handle) override {
 | 
					    void new_key_block(BlockHandle handle) override {
 | 
				
			||||||
      td::actor::send_closure(id_, &FullNodeImpl::new_key_block, std::move(handle));
 | 
					      td::actor::send_closure(id_, &FullNodeImpl::new_key_block, std::move(handle));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,6 +73,8 @@ class FullNodeImpl : public FullNode {
 | 
				
			||||||
  void get_next_key_blocks(BlockIdExt block_id, td::Timestamp timeout, td::Promise<std::vector<BlockIdExt>> promise);
 | 
					  void get_next_key_blocks(BlockIdExt block_id, td::Timestamp timeout, td::Promise<std::vector<BlockIdExt>> promise);
 | 
				
			||||||
  void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
					  void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
				
			||||||
                        td::Promise<std::string> promise);
 | 
					                        td::Promise<std::string> promise);
 | 
				
			||||||
 | 
					  void download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                    td::Promise<td::Ref<OutMsgQueueProof>> promise);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void got_key_block_proof(td::Ref<ProofLink> proof);
 | 
					  void got_key_block_proof(td::Ref<ProofLink> proof);
 | 
				
			||||||
  void got_zero_block_state(td::Ref<ShardState> state);
 | 
					  void got_zero_block_state(td::Ref<ShardState> state);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ set(TON_VALIDATOR_SOURCE
 | 
				
			||||||
  ihr-message.cpp
 | 
					  ihr-message.cpp
 | 
				
			||||||
  liteserver.cpp
 | 
					  liteserver.cpp
 | 
				
			||||||
  message-queue.cpp
 | 
					  message-queue.cpp
 | 
				
			||||||
 | 
					  out-msg-queue-proof.cpp
 | 
				
			||||||
  proof.cpp
 | 
					  proof.cpp
 | 
				
			||||||
  shard.cpp
 | 
					  shard.cpp
 | 
				
			||||||
  signature-set.cpp
 | 
					  signature-set.cpp
 | 
				
			||||||
| 
						 | 
					@ -32,13 +33,13 @@ set(TON_VALIDATOR_SOURCE
 | 
				
			||||||
  ihr-message.hpp
 | 
					  ihr-message.hpp
 | 
				
			||||||
  liteserver.hpp
 | 
					  liteserver.hpp
 | 
				
			||||||
  message-queue.hpp
 | 
					  message-queue.hpp
 | 
				
			||||||
 | 
					  out-msg-queue-proof.hpp
 | 
				
			||||||
  proof.hpp
 | 
					  proof.hpp
 | 
				
			||||||
  shard.hpp
 | 
					  shard.hpp
 | 
				
			||||||
  signature-set.hpp
 | 
					  signature-set.hpp
 | 
				
			||||||
  top-shard-descr.hpp
 | 
					  top-shard-descr.hpp
 | 
				
			||||||
  validate-query.hpp
 | 
					  validate-query.hpp
 | 
				
			||||||
  validator-set.hpp
 | 
					  validator-set.hpp)
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(ton_validator STATIC ${TON_VALIDATOR_SOURCE})
 | 
					add_library(ton_validator STATIC ${TON_VALIDATOR_SOURCE})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,7 +205,7 @@ class Collator final : public td::actor::Actor {
 | 
				
			||||||
  std::vector<ExtMessage::Hash> bad_ext_msgs_, delay_ext_msgs_;
 | 
					  std::vector<ExtMessage::Hash> bad_ext_msgs_, delay_ext_msgs_;
 | 
				
			||||||
  Ref<vm::Cell> shard_account_blocks_;  // ShardAccountBlocks
 | 
					  Ref<vm::Cell> shard_account_blocks_;  // ShardAccountBlocks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::map<td::Bits256, Ref<BlockData>> blocks_with_state_proofs_;
 | 
					  std::map<td::Bits256, Ref<vm::Cell>> block_state_proofs_;
 | 
				
			||||||
  std::vector<vm::MerkleProofBuilder> neighbor_proof_builders_;
 | 
					  std::vector<vm::MerkleProofBuilder> neighbor_proof_builders_;
 | 
				
			||||||
  std::vector<Ref<vm::Cell>> collated_roots_;
 | 
					  std::vector<Ref<vm::Cell>> collated_roots_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,8 +238,7 @@ class Collator final : public td::actor::Actor {
 | 
				
			||||||
  void after_get_aux_shard_state(ton::BlockIdExt blkid, td::Result<Ref<ShardState>> res);
 | 
					  void after_get_aux_shard_state(ton::BlockIdExt blkid, td::Result<Ref<ShardState>> res);
 | 
				
			||||||
  bool fix_one_processed_upto(block::MsgProcessedUpto& proc, const ton::ShardIdFull& owner);
 | 
					  bool fix_one_processed_upto(block::MsgProcessedUpto& proc, const ton::ShardIdFull& owner);
 | 
				
			||||||
  bool fix_processed_upto(block::MsgProcessedUptoCollection& upto);
 | 
					  bool fix_processed_upto(block::MsgProcessedUptoCollection& upto);
 | 
				
			||||||
  void got_neighbor_block_data(td::Result<Ref<BlockData>> res);
 | 
					  void got_neighbor_msg_queue(unsigned i, td::Result<Ref<OutMsgQueueProof>> R);
 | 
				
			||||||
  void got_neighbor_block_state(int i, td::Result<Ref<ShardState>> res);
 | 
					 | 
				
			||||||
  bool adjust_shard_config();
 | 
					  bool adjust_shard_config();
 | 
				
			||||||
  bool store_shard_fees(ShardIdFull shard, const block::CurrencyCollection& fees,
 | 
					  bool store_shard_fees(ShardIdFull shard, const block::CurrencyCollection& fees,
 | 
				
			||||||
                        const block::CurrencyCollection& created);
 | 
					                        const block::CurrencyCollection& created);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -501,7 +501,13 @@ void Collator::after_get_block_data(int idx, td::Result<Ref<BlockData>> res) {
 | 
				
			||||||
      prev_mc_block = prev_block_data[0];
 | 
					      prev_mc_block = prev_block_data[0];
 | 
				
			||||||
      mc_block_root = prev_mc_block->root_cell();
 | 
					      mc_block_root = prev_mc_block->root_cell();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    blocks_with_state_proofs_[prev_block_data[idx]->root_cell()->get_hash().bits()] = prev_block_data[idx];
 | 
					    Ref<vm::Cell> root = prev_block_data[idx]->root_cell();
 | 
				
			||||||
 | 
					    auto proof = create_block_state_proof(root);
 | 
				
			||||||
 | 
					    if (proof.is_error()) {
 | 
				
			||||||
 | 
					      fatal_error(proof.move_as_error());
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    block_state_proofs_.emplace(root->get_hash().bits(), proof.move_as_ok());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  check_pending();
 | 
					  check_pending();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -613,54 +619,39 @@ bool Collator::request_neighbor_msg_queues() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    neighbors_.emplace_back(*shard_ptr);
 | 
					    neighbors_.emplace_back(*shard_ptr);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  int i = 0;
 | 
					  unsigned i = 0;
 | 
				
			||||||
  neighbor_proof_builders_.resize(neighbors_.size());
 | 
					  neighbor_proof_builders_.resize(neighbors_.size());
 | 
				
			||||||
  for (block::McShardDescr& descr : neighbors_) {
 | 
					  for (block::McShardDescr& descr : neighbors_) {
 | 
				
			||||||
    LOG(DEBUG) << "neighbor #" << i << " : " << descr.blk_.to_str();
 | 
					    LOG(DEBUG) << "neighbor #" << i << " : " << descr.blk_.to_str();
 | 
				
			||||||
    if (descr.blk_.seqno() != 0) {
 | 
					 | 
				
			||||||
      ++pending;
 | 
					 | 
				
			||||||
      send_closure_later(manager, &ValidatorManager::wait_block_data_short, descr.blk_, priority(), timeout,
 | 
					 | 
				
			||||||
                         [self = get_self(), i](td::Result<Ref<BlockData>> res) {
 | 
					 | 
				
			||||||
                           LOG(DEBUG) << "got answer to wait_block_data for neighbor #" << i;
 | 
					 | 
				
			||||||
                           send_closure_later(std::move(self), &Collator::got_neighbor_block_data, std::move(res));
 | 
					 | 
				
			||||||
                         });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ++pending;
 | 
					    ++pending;
 | 
				
			||||||
    send_closure_later(manager, &ValidatorManager::wait_block_state_short, descr.blk_, priority(), timeout,
 | 
					    send_closure_later(manager, &ValidatorManager::wait_out_msg_queue_proof, descr.blk_, shard_, priority(), timeout,
 | 
				
			||||||
                       [self = get_self(), i](td::Result<Ref<ShardState>> res) {
 | 
					                       [self = get_self(), i](td::Result<Ref<OutMsgQueueProof>> res) {
 | 
				
			||||||
                         LOG(DEBUG) << "got answer to wait_block_state for neighbor #" << i;
 | 
					                         LOG(DEBUG) << "got msg queue for neighbor #" << i;
 | 
				
			||||||
                         send_closure_later(std::move(self), &Collator::got_neighbor_block_state, i, std::move(res));
 | 
					                         send_closure_later(std::move(self), &Collator::got_neighbor_msg_queue, i, std::move(res));
 | 
				
			||||||
                       });
 | 
					                       });
 | 
				
			||||||
    ++i;
 | 
					    ++i;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Collator::got_neighbor_block_data(td::Result<Ref<BlockData>> res) {
 | 
					void Collator::got_neighbor_msg_queue(unsigned i, td::Result<Ref<OutMsgQueueProof>> R) {
 | 
				
			||||||
  --pending;
 | 
					  --pending;
 | 
				
			||||||
  if (res.is_error()) {
 | 
					  if (R.is_error()) {
 | 
				
			||||||
    fatal_error(res.move_as_error());
 | 
					    fatal_error(R.move_as_error());
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  auto block_data = res.move_as_ok();
 | 
					  auto res = R.move_as_ok();
 | 
				
			||||||
  blocks_with_state_proofs_[block_data->root_cell()->get_hash().bits()] = block_data;
 | 
					  BlockIdExt block_id = neighbors_.at(i).blk_;
 | 
				
			||||||
  check_pending();
 | 
					  if (res->block_state_proof_.not_null()) {
 | 
				
			||||||
}
 | 
					    block_state_proofs_.emplace(block_id.root_hash, res->block_state_proof_);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
void Collator::got_neighbor_block_state(int i, td::Result<Ref<ShardState>> res) {
 | 
					  neighbor_proof_builders_.at(i) = vm::MerkleProofBuilder{res->state_root_};
 | 
				
			||||||
  --pending;
 | 
					  auto state = ShardStateQ::fetch(block_id, {}, neighbor_proof_builders_.at(i).root());
 | 
				
			||||||
  if (res.is_error()) {
 | 
					  if (state.is_error()) {
 | 
				
			||||||
    fatal_error(res.move_as_error());
 | 
					    fatal_error(state.move_as_error());
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Ref<ShardState> state = res.move_as_ok();
 | 
					  auto outq_descr_res = state.move_as_ok()->message_queue();
 | 
				
			||||||
  neighbor_proof_builders_.at(i) = vm::MerkleProofBuilder{state->root_cell()};
 | 
					 | 
				
			||||||
  auto new_state = ShardStateQ::fetch(state->get_block_id(), {}, neighbor_proof_builders_.at(i).root());
 | 
					 | 
				
			||||||
  if (new_state.is_error()) {
 | 
					 | 
				
			||||||
    fatal_error(new_state.move_as_error());
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  auto outq_descr_res = new_state.move_as_ok()->message_queue();
 | 
					 | 
				
			||||||
  if (outq_descr_res.is_error()) {
 | 
					  if (outq_descr_res.is_error()) {
 | 
				
			||||||
    fatal_error(outq_descr_res.move_as_error());
 | 
					    fatal_error(outq_descr_res.move_as_error());
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
| 
						 | 
					@ -3992,17 +3983,8 @@ bool Collator::create_collated_data() {
 | 
				
			||||||
    collated_roots_.push_back(std::move(cell));
 | 
					    collated_roots_.push_back(std::move(cell));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // 2. Proofs for hashes of states: previous states + neighbors
 | 
					  // 2. Proofs for hashes of states: previous states + neighbors
 | 
				
			||||||
  for (const auto& p : blocks_with_state_proofs_) {
 | 
					  for (const auto& p : block_state_proofs_) {
 | 
				
			||||||
    vm::MerkleProofBuilder mpb{p.second->root_cell()};
 | 
					    collated_roots_.push_back(p.second);
 | 
				
			||||||
    block::gen::Block::Record block;
 | 
					 | 
				
			||||||
    if (!tlb::unpack_cell(mpb.root(), block) || block.state_update->load_cell().is_error()) {
 | 
					 | 
				
			||||||
      return fatal_error("cannot generate Merkle proof for previous block");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ref<vm::Cell> proof = mpb.extract_proof();
 | 
					 | 
				
			||||||
    if (proof.is_null()) {
 | 
					 | 
				
			||||||
      return fatal_error("cannot generate Merkle proof for previous block");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    collated_roots_.push_back(std::move(proof));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // 3. Previous state proof (only shadchains)
 | 
					  // 3. Previous state proof (only shadchains)
 | 
				
			||||||
  std::map<td::Bits256, Ref<vm::Cell>> proofs;
 | 
					  std::map<td::Bits256, Ref<vm::Cell>> proofs;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										245
									
								
								validator/impl/out-msg-queue-proof.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								validator/impl/out-msg-queue-proof.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,245 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include "out-msg-queue-proof.hpp"
 | 
				
			||||||
 | 
					#include "interfaces/proof.h"
 | 
				
			||||||
 | 
					#include "shard.hpp"
 | 
				
			||||||
 | 
					#include "vm/cells/MerkleProof.h"
 | 
				
			||||||
 | 
					#include "common/delay.h"
 | 
				
			||||||
 | 
					#include "interfaces/validator-manager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace validator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<td::Ref<OutMsgQueueProof>> OutMsgQueueProof::fetch(BlockIdExt block_id, ShardIdFull dst_shard,
 | 
				
			||||||
 | 
					                                                              const ton_api::tonNode_outMsgQueueProof &f) {
 | 
				
			||||||
 | 
					  Ref<vm::Cell> block_state_proof;
 | 
				
			||||||
 | 
					  td::Bits256 state_root_hash;
 | 
				
			||||||
 | 
					  if (block_id.seqno() == 0) {
 | 
				
			||||||
 | 
					    if (!f.block_state_proof_.empty()) {
 | 
				
			||||||
 | 
					      return td::Status::Error("expected empty block state proof");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    state_root_hash = block_id.root_hash;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    TRY_RESULT_ASSIGN(block_state_proof, vm::std_boc_deserialize(f.block_state_proof_.as_slice()));
 | 
				
			||||||
 | 
					    TRY_RESULT_ASSIGN(state_root_hash, unpack_block_state_proof(block_id, block_state_proof));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TRY_RESULT(queue_proof, vm::std_boc_deserialize(f.queue_proof_.as_slice()));
 | 
				
			||||||
 | 
					  auto state_root = vm::MerkleProof::virtualize(queue_proof, 1);
 | 
				
			||||||
 | 
					  if (state_root.is_null()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("invalid queue proof");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (state_root->get_hash().as_slice() != state_root_hash.as_slice()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("state root hash mismatch");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TODO: validate
 | 
				
			||||||
 | 
					  return Ref<OutMsgQueueProof>(true, std::move(state_root), std::move(block_state_proof));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<tl_object_ptr<ton_api::tonNode_outMsgQueueProof>> OutMsgQueueProof::serialize(
 | 
				
			||||||
 | 
					    BlockIdExt block_id, ShardIdFull dst_shard, Ref<vm::Cell> state_root, Ref<vm::Cell> block_root) {
 | 
				
			||||||
 | 
					  vm::MerkleProofBuilder mpb{std::move(state_root)};
 | 
				
			||||||
 | 
					  TRY_RESULT(state, ShardStateQ::fetch(block_id, {}, mpb.root()));
 | 
				
			||||||
 | 
					  TRY_RESULT(outq_descr, state->message_queue());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TODO: add only required part of msg queue
 | 
				
			||||||
 | 
					  td::HashSet<vm::Cell::Hash> visited;
 | 
				
			||||||
 | 
					  std::function<void(Ref<vm::Cell>)> dfs = [&](Ref<vm::Cell> cell) {
 | 
				
			||||||
 | 
					    if (!visited.insert(cell->get_hash()).second) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vm::CellSlice cs(vm::NoVm(), cell);
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < cs.size_refs(); i++) {
 | 
				
			||||||
 | 
					      dfs(cs.prefetch_ref(i));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  dfs(outq_descr->root_cell());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TRY_RESULT(queue_proof, vm::std_boc_serialize(mpb.extract_proof()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  td::BufferSlice block_state_proof;
 | 
				
			||||||
 | 
					  if (block_id.seqno() != 0) {
 | 
				
			||||||
 | 
					    TRY_RESULT(proof, create_block_state_proof(std::move(block_root)));
 | 
				
			||||||
 | 
					    TRY_RESULT_ASSIGN(block_state_proof, vm::std_boc_serialize(std::move(proof), 31));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return create_tl_object<ton_api::tonNode_outMsgQueueProof>(std::move(queue_proof), std::move(block_state_proof));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::alarm() {
 | 
				
			||||||
 | 
					  abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::abort_query(td::Status reason) {
 | 
				
			||||||
 | 
					  if (promise_) {
 | 
				
			||||||
 | 
					    if (priority_ > 0 || (reason.code() != ErrorCode::timeout && reason.code() != ErrorCode::notready)) {
 | 
				
			||||||
 | 
					      LOG(WARNING) << "aborting wait msg queue query for " << block_id_.to_str() << " priority=" << priority_ << ": "
 | 
				
			||||||
 | 
					                   << reason;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      LOG(DEBUG) << "aborting wait msg queue query for " << block_id_.to_str() << " priority=" << priority_ << ": "
 | 
				
			||||||
 | 
					                 << reason;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    promise_.set_error(
 | 
				
			||||||
 | 
					        reason.move_as_error_prefix(PSTRING() << "failed to get msg queue for " << block_id_.to_str() << ": "));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::finish_query(Ref<OutMsgQueueProof> result) {
 | 
				
			||||||
 | 
					  promise_.set_result(std::move(result));
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::start_up() {
 | 
				
			||||||
 | 
					  alarm_timestamp() = timeout_;
 | 
				
			||||||
 | 
					  if (local_) {
 | 
				
			||||||
 | 
					    run_local();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    run_net();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::run_local() {
 | 
				
			||||||
 | 
					  ++pending;
 | 
				
			||||||
 | 
					  td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, block_id_, priority_, timeout_,
 | 
				
			||||||
 | 
					                          [SelfId = actor_id(this)](td::Result<Ref<ShardState>> R) {
 | 
				
			||||||
 | 
					                            if (R.is_error()) {
 | 
				
			||||||
 | 
					                              td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::abort_query,
 | 
				
			||||||
 | 
					                                                      R.move_as_error_prefix("failed to get shard state"));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                              td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::got_state_root,
 | 
				
			||||||
 | 
					                                                      R.move_as_ok()->root_cell());
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
 | 
					  if (block_id_.seqno() != 0) {
 | 
				
			||||||
 | 
					    ++pending;
 | 
				
			||||||
 | 
					    td::actor::send_closure(manager_, &ValidatorManager::wait_block_data_short, block_id_, priority_, timeout_,
 | 
				
			||||||
 | 
					                            [SelfId = actor_id(this)](td::Result<Ref<BlockData>> R) {
 | 
				
			||||||
 | 
					                              if (R.is_error()) {
 | 
				
			||||||
 | 
					                                td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::abort_query,
 | 
				
			||||||
 | 
					                                                        R.move_as_error_prefix("failed to get block data"));
 | 
				
			||||||
 | 
					                              } else {
 | 
				
			||||||
 | 
					                                td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::got_block_root,
 | 
				
			||||||
 | 
					                                                        R.move_as_ok()->root_cell());
 | 
				
			||||||
 | 
					                              }
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::got_state_root(Ref<vm::Cell> root) {
 | 
				
			||||||
 | 
					  state_root_ = std::move(root);
 | 
				
			||||||
 | 
					  if (--pending == 0) {
 | 
				
			||||||
 | 
					    run_local_cont();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::got_block_root(Ref<vm::Cell> root) {
 | 
				
			||||||
 | 
					  block_root_ = std::move(root);
 | 
				
			||||||
 | 
					  if (--pending == 0) {
 | 
				
			||||||
 | 
					    run_local_cont();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::run_local_cont() {
 | 
				
			||||||
 | 
					  Ref<vm::Cell> block_state_proof;
 | 
				
			||||||
 | 
					  if (block_id_.seqno() != 0) {
 | 
				
			||||||
 | 
					    auto R = create_block_state_proof(std::move(block_root_));
 | 
				
			||||||
 | 
					    if (R.is_error()) {
 | 
				
			||||||
 | 
					      abort_query(R.move_as_error_prefix("failed to create block state proof"));
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    block_state_proof = R.move_as_ok();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  finish_query(td::Ref<OutMsgQueueProof>(true, std::move(state_root_), std::move(block_state_proof)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WaitOutMsgQueueProof::run_net() {
 | 
				
			||||||
 | 
					  auto P =
 | 
				
			||||||
 | 
					      td::PromiseCreator::lambda([SelfId = actor_id(this), block_id = block_id_](td::Result<Ref<OutMsgQueueProof>> R) {
 | 
				
			||||||
 | 
					        if (R.is_error()) {
 | 
				
			||||||
 | 
					          LOG(DEBUG) << "failed to get msg queue for " << block_id.to_str() << " from net: " << R.move_as_error();
 | 
				
			||||||
 | 
					          delay_action([SelfId]() mutable { td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::run_net); },
 | 
				
			||||||
 | 
					                       td::Timestamp::in(0.1));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          td::actor::send_closure(SelfId, &WaitOutMsgQueueProof::finish_query, R.move_as_ok());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  td::actor::send_closure(manager_, &ValidatorManager::send_get_out_msg_queue_proof_request, block_id_, dst_shard_,
 | 
				
			||||||
 | 
					                          priority_, std::move(P));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BuildOutMsgQueueProof::abort_query(td::Status reason) {
 | 
				
			||||||
 | 
					  if (promise_) {
 | 
				
			||||||
 | 
					    LOG(WARNING) << "failed to build msg queue proof for " << block_id_.to_str() << ": " << reason;
 | 
				
			||||||
 | 
					    promise_.set_error(
 | 
				
			||||||
 | 
					        reason.move_as_error_prefix(PSTRING() << "failed to build msg queue proof for " << block_id_.to_str() << ": "));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BuildOutMsgQueueProof::start_up() {
 | 
				
			||||||
 | 
					  ++pending;
 | 
				
			||||||
 | 
					  td::actor::send_closure(manager_, &ValidatorManagerInterface::get_shard_state_from_db_short, block_id_,
 | 
				
			||||||
 | 
					                          [SelfId = actor_id(this)](td::Result<Ref<ShardState>> R) {
 | 
				
			||||||
 | 
					                            if (R.is_error()) {
 | 
				
			||||||
 | 
					                              td::actor::send_closure(SelfId, &BuildOutMsgQueueProof::abort_query,
 | 
				
			||||||
 | 
					                                                      R.move_as_error_prefix("failed to get shard state"));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                              td::actor::send_closure(SelfId, &BuildOutMsgQueueProof::got_state_root,
 | 
				
			||||||
 | 
					                                                      R.move_as_ok()->root_cell());
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
 | 
					  if (block_id_.seqno() != 0) {
 | 
				
			||||||
 | 
					    ++pending;
 | 
				
			||||||
 | 
					    td::actor::send_closure(manager_, &ValidatorManagerInterface::get_block_data_from_db_short, block_id_,
 | 
				
			||||||
 | 
					                            [SelfId = actor_id(this)](td::Result<Ref<BlockData>> R) {
 | 
				
			||||||
 | 
					                              if (R.is_error()) {
 | 
				
			||||||
 | 
					                                td::actor::send_closure(SelfId, &BuildOutMsgQueueProof::abort_query,
 | 
				
			||||||
 | 
					                                                        R.move_as_error_prefix("failed to get block data"));
 | 
				
			||||||
 | 
					                              } else {
 | 
				
			||||||
 | 
					                                td::actor::send_closure(SelfId, &BuildOutMsgQueueProof::got_block_root,
 | 
				
			||||||
 | 
					                                                        R.move_as_ok()->root_cell());
 | 
				
			||||||
 | 
					                              }
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BuildOutMsgQueueProof::got_state_root(Ref<vm::Cell> root) {
 | 
				
			||||||
 | 
					  state_root_ = std::move(root);
 | 
				
			||||||
 | 
					  if (--pending == 0) {
 | 
				
			||||||
 | 
					    build_proof();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BuildOutMsgQueueProof::got_block_root(Ref<vm::Cell> root) {
 | 
				
			||||||
 | 
					  block_root_ = std::move(root);
 | 
				
			||||||
 | 
					  if (--pending == 0) {
 | 
				
			||||||
 | 
					    build_proof();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BuildOutMsgQueueProof::build_proof() {
 | 
				
			||||||
 | 
					  promise_.set_result(
 | 
				
			||||||
 | 
					      OutMsgQueueProof::serialize(block_id_, dst_shard_, std::move(state_root_), std::move(block_root_)));
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace validator
 | 
				
			||||||
 | 
					}  // namespace ton
 | 
				
			||||||
							
								
								
									
										109
									
								
								validator/impl/out-msg-queue-proof.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								validator/impl/out-msg-queue-proof.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "vm/cells.h"
 | 
				
			||||||
 | 
					#include "ton/ton-types.h"
 | 
				
			||||||
 | 
					#include "auto/tl/ton_api.h"
 | 
				
			||||||
 | 
					#include "interfaces/out-msg-queue-proof.h"
 | 
				
			||||||
 | 
					#include "td/actor/actor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace validator {
 | 
				
			||||||
 | 
					using td::Ref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ValidatorManager;
 | 
				
			||||||
 | 
					class ValidatorManagerInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WaitOutMsgQueueProof : public td::actor::Actor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  WaitOutMsgQueueProof(BlockIdExt block_id, ShardIdFull dst_shard, bool local, td::uint32 priority,
 | 
				
			||||||
 | 
					                       td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                       td::Promise<Ref<OutMsgQueueProof>> promise)
 | 
				
			||||||
 | 
					      : block_id_(std::move(block_id))
 | 
				
			||||||
 | 
					      , dst_shard_(dst_shard)
 | 
				
			||||||
 | 
					      , local_(local)
 | 
				
			||||||
 | 
					      , priority_(priority)
 | 
				
			||||||
 | 
					      , manager_(manager)
 | 
				
			||||||
 | 
					      , timeout_(timeout)
 | 
				
			||||||
 | 
					      , promise_(std::move(promise)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_timeout(td::Timestamp timeout, td::uint32 priority) {
 | 
				
			||||||
 | 
					    timeout_ = timeout;
 | 
				
			||||||
 | 
					    alarm_timestamp() = timeout_;
 | 
				
			||||||
 | 
					    priority_ = priority;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void abort_query(td::Status reason);
 | 
				
			||||||
 | 
					  void finish_query(Ref<OutMsgQueueProof> result);
 | 
				
			||||||
 | 
					  void alarm() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void start_up() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void run_local();
 | 
				
			||||||
 | 
					  void got_state_root(Ref<vm::Cell> root);
 | 
				
			||||||
 | 
					  void got_block_root(Ref<vm::Cell> root);
 | 
				
			||||||
 | 
					  void run_local_cont();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void run_net();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  BlockIdExt block_id_;
 | 
				
			||||||
 | 
					  ShardIdFull dst_shard_;
 | 
				
			||||||
 | 
					  bool local_;
 | 
				
			||||||
 | 
					  td::uint32 priority_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  td::actor::ActorId<ValidatorManager> manager_;
 | 
				
			||||||
 | 
					  td::Timestamp timeout_;
 | 
				
			||||||
 | 
					  td::Promise<Ref<OutMsgQueueProof>> promise_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Ref<vm::Cell> state_root_, block_root_;
 | 
				
			||||||
 | 
					  unsigned pending = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BuildOutMsgQueueProof : public td::actor::Actor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  BuildOutMsgQueueProof(BlockIdExt block_id, ShardIdFull dst_shard,
 | 
				
			||||||
 | 
					      td::actor::ActorId<ValidatorManagerInterface> manager,
 | 
				
			||||||
 | 
					      td::Promise<tl_object_ptr<ton_api::tonNode_outMsgQueueProof>> promise)
 | 
				
			||||||
 | 
					      : block_id_(std::move(block_id))
 | 
				
			||||||
 | 
					      , dst_shard_(dst_shard)
 | 
				
			||||||
 | 
					      , manager_(manager)
 | 
				
			||||||
 | 
					      , promise_(std::move(promise)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void abort_query(td::Status reason);
 | 
				
			||||||
 | 
					  void start_up() override;
 | 
				
			||||||
 | 
					  void got_state_root(Ref<vm::Cell> root);
 | 
				
			||||||
 | 
					  void got_block_root(Ref<vm::Cell> root);
 | 
				
			||||||
 | 
					  void build_proof();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  BlockIdExt block_id_;
 | 
				
			||||||
 | 
					  ShardIdFull dst_shard_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  td::actor::ActorId<ValidatorManagerInterface> manager_;
 | 
				
			||||||
 | 
					  td::Promise<tl_object_ptr<ton_api::tonNode_outMsgQueueProof>> promise_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Ref<vm::Cell> state_root_, block_root_;
 | 
				
			||||||
 | 
					  unsigned pending = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace validator
 | 
				
			||||||
 | 
					}  // namespace ton
 | 
				
			||||||
| 
						 | 
					@ -162,5 +162,40 @@ td::Result<Ref<vm::Cell>> ProofQ::get_signatures_root() const {
 | 
				
			||||||
  return proof.signatures->prefetch_ref();
 | 
					  return proof.signatures->prefetch_ref();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<td::Ref<vm::Cell>> create_block_state_proof(td::Ref<vm::Cell> root) {
 | 
				
			||||||
 | 
					  if (root.is_null()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("root is null");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  vm::MerkleProofBuilder mpb{std::move(root)};
 | 
				
			||||||
 | 
					  block::gen::Block::Record block;
 | 
				
			||||||
 | 
					  if (!tlb::unpack_cell(mpb.root(), block) || block.state_update->load_cell().is_error()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("invalid block");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Ref<vm::Cell> proof = mpb.extract_proof();
 | 
				
			||||||
 | 
					  if (proof.is_null()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("failed to create proof");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return proof;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<RootHash> unpack_block_state_proof(BlockIdExt block_id, td::Ref<vm::Cell> proof) {
 | 
				
			||||||
 | 
					  auto virt_root = vm::MerkleProof::virtualize(proof, 1);
 | 
				
			||||||
 | 
					  if (virt_root.is_null()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("invalid Merkle proof");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (virt_root->get_hash().as_slice() != block_id.root_hash.as_slice()) {
 | 
				
			||||||
 | 
					    return td::Status::Error("hash mismatch");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  block::gen::Block::Record block;
 | 
				
			||||||
 | 
					  if (!tlb::unpack_cell(virt_root, block)) {
 | 
				
			||||||
 | 
					    return td::Status::Error("invalid block");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  vm::CellSlice upd_cs{vm::NoVmSpec(), block.state_update};
 | 
				
			||||||
 | 
					  if (!(upd_cs.is_special() && upd_cs.prefetch_long(8) == 4 && upd_cs.size_ext() == 0x20228)) {
 | 
				
			||||||
 | 
					    return td::Status::Error("invalid Merkle update");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return upd_cs.prefetch_ref(1)->get_hash(0).bits();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace validator
 | 
					}  // namespace validator
 | 
				
			||||||
}  // namespace ton
 | 
					}  // namespace ton
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								validator/interfaces/out-msg-queue-proof.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								validator/interfaces/out-msg-queue-proof.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    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 <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "vm/cells.h"
 | 
				
			||||||
 | 
					#include "ton/ton-types.h"
 | 
				
			||||||
 | 
					#include "auto/tl/ton_api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace validator {
 | 
				
			||||||
 | 
					using td::Ref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct OutMsgQueueProof : public td::CntObject {
 | 
				
			||||||
 | 
					  OutMsgQueueProof(Ref<vm::Cell> state_root, Ref<vm::Cell> block_state_proof)
 | 
				
			||||||
 | 
					      : state_root_(std::move(state_root)), block_state_proof_(std::move(block_state_proof)) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Ref<vm::Cell> state_root_;
 | 
				
			||||||
 | 
					  Ref<vm::Cell> block_state_proof_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static td::Result<td::Ref<OutMsgQueueProof>> fetch(BlockIdExt block_id, ShardIdFull dst_shard,
 | 
				
			||||||
 | 
					                                                     const ton_api::tonNode_outMsgQueueProof &f);
 | 
				
			||||||
 | 
					  static td::Result<tl_object_ptr<ton_api::tonNode_outMsgQueueProof>> serialize(
 | 
				
			||||||
 | 
					      BlockIdExt block_id, ShardIdFull dst_shard, Ref<vm::Cell> state_root, Ref<vm::Cell> block_root);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace validator
 | 
				
			||||||
 | 
					}  // namespace ton
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,9 @@ class Proof : virtual public ProofLink {
 | 
				
			||||||
  virtual td::Result<td::Ref<ProofLink>> export_as_proof_link() const = 0;
 | 
					  virtual td::Result<td::Ref<ProofLink>> export_as_proof_link() const = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					td::Result<td::Ref<vm::Cell>> create_block_state_proof(td::Ref<vm::Cell> root);
 | 
				
			||||||
 | 
					td::Result<RootHash> unpack_block_state_proof(BlockIdExt block_id, td::Ref<vm::Cell> proof);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace validator
 | 
					}  // namespace validator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace ton
 | 
					}  // namespace ton
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
#include "liteserver.h"
 | 
					#include "liteserver.h"
 | 
				
			||||||
#include "crypto/vm/db/DynamicBagOfCellsDb.h"
 | 
					#include "crypto/vm/db/DynamicBagOfCellsDb.h"
 | 
				
			||||||
#include "validator-session/validator-session-types.h"
 | 
					#include "validator-session/validator-session-types.h"
 | 
				
			||||||
 | 
					#include "impl/out-msg-queue-proof.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ton {
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,6 +129,8 @@ class ValidatorManager : public ValidatorManagerInterface {
 | 
				
			||||||
  virtual void send_ihr_message(td::Ref<IhrMessage> message) = 0;
 | 
					  virtual void send_ihr_message(td::Ref<IhrMessage> message) = 0;
 | 
				
			||||||
  virtual void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) = 0;
 | 
					  virtual void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) = 0;
 | 
				
			||||||
  virtual void send_block_broadcast(BlockBroadcast broadcast) = 0;
 | 
					  virtual void send_block_broadcast(BlockBroadcast broadcast) = 0;
 | 
				
			||||||
 | 
					  virtual void send_get_out_msg_queue_proof_request(BlockIdExt id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                                    td::Promise<td::Ref<OutMsgQueueProof>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) = 0;
 | 
					  virtual void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) = 0;
 | 
				
			||||||
  virtual void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) = 0;
 | 
					  virtual void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,6 +152,10 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
					  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
 | 
					  void wait_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                td::Promise<td::Ref<OutMsgQueueProof>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override;
 | 
					  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
  void wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp,
 | 
					  void wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp,
 | 
				
			||||||
| 
						 | 
					@ -250,6 +254,10 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) override;
 | 
					  void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) override;
 | 
				
			||||||
  void send_block_broadcast(BlockBroadcast broadcast) override {
 | 
					  void send_block_broadcast(BlockBroadcast broadcast) override {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  void send_get_out_msg_queue_proof_request(BlockIdExt id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                            td::Promise<td::Ref<OutMsgQueueProof>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override;
 | 
					  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
  void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) override;
 | 
					  void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,6 +182,10 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
					  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
 | 
					  void wait_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                td::Promise<td::Ref<OutMsgQueueProof>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override {
 | 
					  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
| 
						 | 
					@ -314,6 +318,10 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  void send_block_broadcast(BlockBroadcast broadcast) override {
 | 
					  void send_block_broadcast(BlockBroadcast broadcast) override {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  void send_get_out_msg_queue_proof_request(BlockIdExt id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                            td::Promise<td::Ref<OutMsgQueueProof>> promise) override {
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override {
 | 
					  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override {
 | 
				
			||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -453,24 +453,18 @@ void ValidatorManagerImpl::add_shard_block_description(td::Ref<ShardTopBlockDesc
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    shard_blocks_[ShardTopBlockDescriptionId{desc->block_id().shard_full(), desc->catchain_seqno()}] = desc;
 | 
					    shard_blocks_[ShardTopBlockDescriptionId{desc->block_id().shard_full(), desc->catchain_seqno()}] = desc;
 | 
				
			||||||
    VLOG(VALIDATOR_DEBUG) << "new shard block descr for " << desc->block_id();
 | 
					    VLOG(VALIDATOR_DEBUG) << "new shard block descr for " << desc->block_id();
 | 
				
			||||||
    if (opts_->need_monitor(desc->block_id().shard_full()) && last_masterchain_block_handle_ &&
 | 
					    if (opts_->need_monitor(desc->block_id().shard_full())) {
 | 
				
			||||||
        last_masterchain_seqno_ > 0 && desc->generated_at() < last_masterchain_block_handle_->unix_time() + 60) {
 | 
					      auto P = td::PromiseCreator::lambda([](td::Result<td::Ref<ShardState>> R) {
 | 
				
			||||||
        delay_action(
 | 
					        if (R.is_error()) {
 | 
				
			||||||
          [SelfId = actor_id(this), desc]() {
 | 
					          auto S = R.move_as_error();
 | 
				
			||||||
            auto P = td::PromiseCreator::lambda([](td::Result<td::Ref<ShardState>> R) {
 | 
					          if (S.code() != ErrorCode::timeout && S.code() != ErrorCode::notready) {
 | 
				
			||||||
              if (R.is_error()) {
 | 
					            VLOG(VALIDATOR_NOTICE) << "failed to get shard state: " << S;
 | 
				
			||||||
                auto S = R.move_as_error();
 | 
					          } else {
 | 
				
			||||||
                if (S.code() != ErrorCode::timeout && S.code() != ErrorCode::notready) {
 | 
					            VLOG(VALIDATOR_DEBUG) << "failed to get shard state: " << S;
 | 
				
			||||||
                  VLOG(VALIDATOR_NOTICE) << "failed to get shard state: " << S;
 | 
					          }
 | 
				
			||||||
                } else {
 | 
					        }
 | 
				
			||||||
                  VLOG(VALIDATOR_DEBUG) << "failed to get shard state: " << S;
 | 
					      });
 | 
				
			||||||
                }
 | 
					      wait_block_state_short(desc->block_id(), 0, td::Timestamp::in(60.0), std::move(P));
 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            td::actor::send_closure(SelfId, &ValidatorManager::wait_block_state_short, desc->block_id(), 0,
 | 
					 | 
				
			||||||
                                    td::Timestamp::in(60.0), std::move(P));
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          td::Timestamp::in(1.0));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -606,6 +600,30 @@ void ValidatorManagerImpl::wait_block_state_short(BlockIdExt block_id, td::uint3
 | 
				
			||||||
  get_block_handle(block_id, true, std::move(P));
 | 
					  get_block_handle(block_id, true, std::move(P));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::wait_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                                    td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                                    td::Promise<td::Ref<OutMsgQueueProof>> promise) {
 | 
				
			||||||
 | 
					  auto key = std::make_pair(block_id, dst_shard);
 | 
				
			||||||
 | 
					  auto it = wait_out_msg_queue_proof_.find(key);
 | 
				
			||||||
 | 
					  if (it == wait_out_msg_queue_proof_.end()) {
 | 
				
			||||||
 | 
					    auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
 | 
					        [SelfId = actor_id(this), block_id, dst_shard](td::Result<td::Ref<OutMsgQueueProof>> R) {
 | 
				
			||||||
 | 
					          td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_msg_queue, block_id, dst_shard,
 | 
				
			||||||
 | 
					                                  std::move(R));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    auto id = td::actor::create_actor<WaitOutMsgQueueProof>("waitmsgqueue", block_id, dst_shard,
 | 
				
			||||||
 | 
					                                                            opts_->need_monitor(block_id.shard_full()), priority,
 | 
				
			||||||
 | 
					                                                            actor_id(this), td::Timestamp::in(10.0), std::move(P))
 | 
				
			||||||
 | 
					                  .release();
 | 
				
			||||||
 | 
					    wait_out_msg_queue_proof_[key].actor_ = id;
 | 
				
			||||||
 | 
					    it = wait_out_msg_queue_proof_.find(key);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it->second.waiting_.emplace_back(timeout, priority, std::move(promise));
 | 
				
			||||||
 | 
					  auto X = it->second.get_timeout();
 | 
				
			||||||
 | 
					  td::actor::send_closure(it->second.actor_, &WaitOutMsgQueueProof::update_timeout, X.first, X.second);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
 | 
					void ValidatorManagerImpl::wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
                                           td::Promise<td::Ref<BlockData>> promise) {
 | 
					                                           td::Promise<td::Ref<BlockData>> promise) {
 | 
				
			||||||
  auto it = wait_block_data_.find(handle->id());
 | 
					  auto it = wait_block_data_.find(handle->id());
 | 
				
			||||||
| 
						 | 
					@ -1037,6 +1055,40 @@ void ValidatorManagerImpl::finished_wait_data(BlockHandle handle, td::Result<td:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::finished_wait_msg_queue(BlockIdExt block_id, ShardIdFull dst_shard,
 | 
				
			||||||
 | 
					                                                   td::Result<td::Ref<OutMsgQueueProof>> R) {
 | 
				
			||||||
 | 
					  auto it = wait_out_msg_queue_proof_.find({block_id, dst_shard});
 | 
				
			||||||
 | 
					  if (it != wait_out_msg_queue_proof_.end()) {
 | 
				
			||||||
 | 
					    if (R.is_error()) {
 | 
				
			||||||
 | 
					      auto S = R.move_as_error();
 | 
				
			||||||
 | 
					      if (S.code() != ErrorCode::timeout) {
 | 
				
			||||||
 | 
					        for (auto &X : it->second.waiting_) {
 | 
				
			||||||
 | 
					          X.promise.set_error(S.clone());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        auto X = it->second.get_timeout();
 | 
				
			||||||
 | 
					        auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
 | 
					            [SelfId = actor_id(this), block_id, dst_shard](td::Result<td::Ref<OutMsgQueueProof>> R) {
 | 
				
			||||||
 | 
					              td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_msg_queue, block_id, dst_shard,
 | 
				
			||||||
 | 
					                                      std::move(R));
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        auto id = td::actor::create_actor<WaitOutMsgQueueProof>("waitmsgqueue", block_id, dst_shard,
 | 
				
			||||||
 | 
					                                                                opts_->need_monitor(block_id.shard_full()), X.second,
 | 
				
			||||||
 | 
					                                                                actor_id(this), X.first, std::move(P))
 | 
				
			||||||
 | 
					                      .release();
 | 
				
			||||||
 | 
					        it->second.actor_ = id;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      auto r = R.move_as_ok();
 | 
				
			||||||
 | 
					      for (auto &X : it->second.waiting_) {
 | 
				
			||||||
 | 
					        X.promise.set_result(r);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wait_out_msg_queue_proof_.erase(it);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::set_block_state(BlockHandle handle, td::Ref<ShardState> state,
 | 
					void ValidatorManagerImpl::set_block_state(BlockHandle handle, td::Ref<ShardState> state,
 | 
				
			||||||
                                           td::Promise<td::Ref<ShardState>> promise) {
 | 
					                                           td::Promise<td::Ref<ShardState>> promise) {
 | 
				
			||||||
  auto P = td::PromiseCreator::lambda(
 | 
					  auto P = td::PromiseCreator::lambda(
 | 
				
			||||||
| 
						 | 
					@ -1410,6 +1462,12 @@ void ValidatorManagerImpl::send_block_broadcast(BlockBroadcast broadcast) {
 | 
				
			||||||
  callback_->send_broadcast(std::move(broadcast));
 | 
					  callback_->send_broadcast(std::move(broadcast));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValidatorManagerImpl::send_get_out_msg_queue_proof_request(BlockIdExt id, ShardIdFull dst_shard,
 | 
				
			||||||
 | 
					                                                                td::uint32 priority,
 | 
				
			||||||
 | 
					                                                                td::Promise<td::Ref<OutMsgQueueProof>> promise) {
 | 
				
			||||||
 | 
					  callback_->download_out_msg_queue_proof(id, dst_shard, td::Timestamp::in(10.0), std::move(promise));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ValidatorManagerImpl::start_up() {
 | 
					void ValidatorManagerImpl::start_up() {
 | 
				
			||||||
  db_ = create_db_actor(actor_id(this), db_root_);
 | 
					  db_ = create_db_actor(actor_id(this), db_root_);
 | 
				
			||||||
  lite_server_cache_ = create_liteserver_cache_actor(actor_id(this), db_root_);
 | 
					  lite_server_cache_ = create_liteserver_cache_actor(actor_id(this), db_root_);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,6 +183,8 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  std::map<BlockIdExt, WaitList<WaitBlockState, td::Ref<ShardState>>> wait_state_;
 | 
					  std::map<BlockIdExt, WaitList<WaitBlockState, td::Ref<ShardState>>> wait_state_;
 | 
				
			||||||
  std::map<BlockIdExt, WaitList<WaitBlockData, td::Ref<BlockData>>> wait_block_data_;
 | 
					  std::map<BlockIdExt, WaitList<WaitBlockData, td::Ref<BlockData>>> wait_block_data_;
 | 
				
			||||||
 | 
					  std::map<std::pair<BlockIdExt, ShardIdFull>, WaitList<WaitOutMsgQueueProof, td::Ref<OutMsgQueueProof>>>
 | 
				
			||||||
 | 
					      wait_out_msg_queue_proof_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct WaitBlockHandle {
 | 
					  struct WaitBlockHandle {
 | 
				
			||||||
    std::vector<td::Promise<BlockHandle>> waiting_;
 | 
					    std::vector<td::Promise<BlockHandle>> waiting_;
 | 
				
			||||||
| 
						 | 
					@ -357,6 +359,8 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                        td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
					  void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
					                              td::Promise<td::Ref<ShardState>> promise) override;
 | 
				
			||||||
 | 
					  void wait_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                td::Promise<td::Ref<OutMsgQueueProof>> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override;
 | 
					  void set_block_data(BlockHandle handle, td::Ref<BlockData> data, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
  void wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp,
 | 
					  void wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp,
 | 
				
			||||||
| 
						 | 
					@ -444,6 +448,8 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
  void send_ihr_message(td::Ref<IhrMessage> message) override;
 | 
					  void send_ihr_message(td::Ref<IhrMessage> message) override;
 | 
				
			||||||
  void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) override;
 | 
					  void send_top_shard_block_description(td::Ref<ShardTopBlockDescription> desc) override;
 | 
				
			||||||
  void send_block_broadcast(BlockBroadcast broadcast) override;
 | 
					  void send_block_broadcast(BlockBroadcast broadcast) override;
 | 
				
			||||||
 | 
					  void send_get_out_msg_queue_proof_request(BlockIdExt id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                            td::Promise<td::Ref<OutMsgQueueProof>> promise) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override;
 | 
					  void update_shard_client_state(BlockIdExt masterchain_block_id, td::Promise<td::Unit> promise) override;
 | 
				
			||||||
  void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) override;
 | 
					  void get_shard_client_state(bool from_db, td::Promise<BlockIdExt> promise) override;
 | 
				
			||||||
| 
						 | 
					@ -478,6 +484,7 @@ class ValidatorManagerImpl : public ValidatorManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void finished_wait_state(BlockHandle handle, td::Result<td::Ref<ShardState>> R);
 | 
					  void finished_wait_state(BlockHandle handle, td::Result<td::Ref<ShardState>> R);
 | 
				
			||||||
  void finished_wait_data(BlockHandle handle, td::Result<td::Ref<BlockData>> R);
 | 
					  void finished_wait_data(BlockHandle handle, td::Result<td::Ref<BlockData>> R);
 | 
				
			||||||
 | 
					  void finished_wait_msg_queue(BlockIdExt block_id, ShardIdFull dst_shard, td::Result<td::Ref<OutMsgQueueProof>> R);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void start_up() override;
 | 
					  void start_up() override;
 | 
				
			||||||
  void started(ValidatorManagerInitResult result);
 | 
					  void started(ValidatorManagerInitResult result);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
#include "interfaces/proof.h"
 | 
					#include "interfaces/proof.h"
 | 
				
			||||||
#include "interfaces/shard.h"
 | 
					#include "interfaces/shard.h"
 | 
				
			||||||
#include "catchain/catchain-types.h"
 | 
					#include "catchain/catchain-types.h"
 | 
				
			||||||
 | 
					#include "interfaces/out-msg-queue-proof.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ton {
 | 
					namespace ton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,6 +132,8 @@ class ValidatorManagerInterface : public td::actor::Actor {
 | 
				
			||||||
                                     td::Promise<std::vector<BlockIdExt>> promise) = 0;
 | 
					                                     td::Promise<std::vector<BlockIdExt>> promise) = 0;
 | 
				
			||||||
    virtual void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
					    virtual void download_archive(BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
 | 
				
			||||||
                                  td::Promise<std::string> promise) = 0;
 | 
					                                  td::Promise<std::string> promise) = 0;
 | 
				
			||||||
 | 
					    virtual void download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                              td::Promise<td::Ref<OutMsgQueueProof>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void new_key_block(BlockHandle handle) = 0;
 | 
					    virtual void new_key_block(BlockHandle handle) = 0;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					@ -212,6 +215,10 @@ class ValidatorManagerInterface : public td::actor::Actor {
 | 
				
			||||||
  virtual void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
					  virtual void wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
 | 
				
			||||||
                                      td::Promise<td::Ref<ShardState>> promise) = 0;
 | 
					                                      td::Promise<td::Ref<ShardState>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void wait_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull dst_shard, td::uint32 priority,
 | 
				
			||||||
 | 
					                                        td::Timestamp timeout,
 | 
				
			||||||
 | 
					                                        td::Promise<td::Ref<OutMsgQueueProof>> promise) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void get_archive_id(BlockSeqno masterchain_seqno, td::Promise<td::uint64> promise) = 0;
 | 
					  virtual void get_archive_id(BlockSeqno masterchain_seqno, td::Promise<td::uint64> promise) = 0;
 | 
				
			||||||
  virtual void get_archive_slice(td::uint64 archive_id, td::uint64 offset, td::uint32 limit,
 | 
					  virtual void get_archive_slice(td::uint64 archive_id, td::uint64 offset, td::uint32 limit,
 | 
				
			||||||
                                 td::Promise<td::BufferSlice> promise) = 0;
 | 
					                                 td::Promise<td::BufferSlice> promise) = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue