1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-12 11:12:16 +00:00

LS getDispatchQueueInfo and getDispatchQueueMessages methods (#1161)

* liteServer.getDispatchQueueInfo query

* Fix getting min/max lt

* LS getDispatchQueueMessages method
This commit is contained in:
SpyCheese 2024-09-13 20:47:30 +03:00 committed by GitHub
parent 9f203890f4
commit b304b1c7be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 364 additions and 3 deletions

View file

@ -974,6 +974,11 @@ bool TestNode::show_help(std::string command) {
"into files <filename-pfx><complaint-hash>.boc\n" "into files <filename-pfx><complaint-hash>.boc\n"
"complaintprice <expires-in> <complaint-boc>\tComputes the price (in nanograms) for creating a complaint\n" "complaintprice <expires-in> <complaint-boc>\tComputes the price (in nanograms) for creating a complaint\n"
"msgqueuesizes\tShows current sizes of outbound message queues in all shards\n" "msgqueuesizes\tShows current sizes of outbound message queues in all shards\n"
"dispatchqueueinfo <block-id>\tShows list of account dispatch queue of a block\n"
"dispatchqueuemessages <block-id> <addr> [<after-lt>]\tShows deferred messages from account <addr>, lt > "
"<after_lt>\n"
"dispatchqueuemessagesall <block-id> [<after-addr> [<after-lt>]]\tShows messages from dispatch queue of a "
"block, starting after <after_addr>, <after-lt>\n"
"known\tShows the list of all known block ids\n" "known\tShows the list of all known block ids\n"
"knowncells\tShows the list of hashes of all known (cached) cells\n" "knowncells\tShows the list of hashes of all known (cached) cells\n"
"dumpcell <hex-hash-pfx>\nDumps a cached cell by a prefix of its hash\n" "dumpcell <hex-hash-pfx>\nDumps a cached cell by a prefix of its hash\n"
@ -988,9 +993,9 @@ bool TestNode::show_help(std::string command) {
bool TestNode::do_parse_line() { bool TestNode::do_parse_line() {
ton::WorkchainId workchain = ton::masterchainId; // change to basechain later ton::WorkchainId workchain = ton::masterchainId; // change to basechain later
int addr_ext = 0; int addr_ext = 0;
ton::StdSmcAddress addr{}; ton::StdSmcAddress addr = ton::StdSmcAddress::zero();
ton::BlockIdExt blkid{}; ton::BlockIdExt blkid{};
ton::LogicalTime lt{}; ton::LogicalTime lt = 0;
ton::Bits256 hash{}; ton::Bits256 hash{};
ton::ShardIdFull shard{}; ton::ShardIdFull shard{};
ton::BlockSeqno seqno{}; ton::BlockSeqno seqno{};
@ -1118,6 +1123,16 @@ bool TestNode::do_parse_line() {
set_error(get_complaint_price(expire_in, filename)); set_error(get_complaint_price(expire_in, filename));
} else if (word == "msgqueuesizes") { } else if (word == "msgqueuesizes") {
return get_msg_queue_sizes(); return get_msg_queue_sizes();
} else if (word == "dispatchqueueinfo") {
return parse_block_id_ext(blkid) && seekeoln() && get_dispatch_queue_info(blkid);
} else if (word == "dispatchqueuemessages" || word == "dispatchqueuemessagesall") {
bool one_account = word == "dispatchqueuemessages";
if (!parse_block_id_ext(blkid)) {
return false;
}
workchain = blkid.id.workchain;
return ((!one_account && seekeoln()) || parse_account_addr(workchain, addr)) && (seekeoln() || parse_lt(lt)) &&
seekeoln() && get_dispatch_queue_messages(blkid, workchain, addr, lt, one_account);
} else if (word == "known") { } else if (word == "known") {
return eoln() && show_new_blkids(true); return eoln() && show_new_blkids(true);
} else if (word == "knowncells") { } else if (word == "knowncells") {
@ -1645,6 +1660,81 @@ void TestNode::got_msg_queue_sizes(ton::tl_object_ptr<ton::lite_api::liteServer_
td::TerminalIO::out() << "External message queue size limit: " << f->ext_msg_queue_size_limit_ << std::endl; td::TerminalIO::out() << "External message queue size limit: " << f->ext_msg_queue_size_limit_ << std::endl;
} }
bool TestNode::get_dispatch_queue_info(ton::BlockIdExt block_id) {
td::TerminalIO::out() << "Dispatch queue in block: " << block_id.id.to_str() << std::endl;
return get_dispatch_queue_info_cont(block_id, true, td::Bits256::zero());
}
bool TestNode::get_dispatch_queue_info_cont(ton::BlockIdExt block_id, bool first, td::Bits256 after_addr) {
auto q = ton::create_serialize_tl_object<ton::lite_api::liteServer_getDispatchQueueInfo>(
first ? 0 : 2, ton::create_tl_lite_block_id(block_id), after_addr, 32, false);
return envelope_send_query(std::move(q), [=, Self = actor_id(this)](td::Result<td::BufferSlice> res) -> void {
if (res.is_error()) {
LOG(ERROR) << "liteServer.getDispatchQueueInfo error: " << res.move_as_error();
return;
}
auto F = ton::fetch_tl_object<ton::lite_api::liteServer_dispatchQueueInfo>(res.move_as_ok(), true);
if (F.is_error()) {
LOG(ERROR) << "cannot parse answer to liteServer.getDispatchQueueInfo";
return;
}
td::actor::send_closure_later(Self, &TestNode::got_dispatch_queue_info, block_id, F.move_as_ok());
});
}
void TestNode::got_dispatch_queue_info(ton::BlockIdExt block_id,
ton::tl_object_ptr<ton::lite_api::liteServer_dispatchQueueInfo> info) {
for (auto& acc : info->account_dispatch_queues_) {
td::TerminalIO::out() << block_id.id.workchain << ":" << acc->addr_.to_hex() << " : size=" << acc->size_
<< " lt=" << acc->min_lt_ << ".." << acc->max_lt_ << std::endl;
}
if (info->complete_) {
td::TerminalIO::out() << "Done" << std::endl;
return;
}
get_dispatch_queue_info_cont(block_id, false, info->account_dispatch_queues_.back()->addr_);
}
bool TestNode::get_dispatch_queue_messages(ton::BlockIdExt block_id, ton::WorkchainId wc, ton::StdSmcAddress addr,
ton::LogicalTime lt, bool one_account) {
if (wc != block_id.id.workchain) {
return set_error("workchain mismatch");
}
auto q = ton::create_serialize_tl_object<ton::lite_api::liteServer_getDispatchQueueMessages>(
one_account ? 2 : 0, ton::create_tl_lite_block_id(block_id), addr, lt, 64, false, one_account, false);
return envelope_send_query(std::move(q), [=, Self = actor_id(this)](td::Result<td::BufferSlice> res) -> void {
if (res.is_error()) {
LOG(ERROR) << "liteServer.getDispatchQueueMessages error: " << res.move_as_error();
return;
}
auto F = ton::fetch_tl_object<ton::lite_api::liteServer_dispatchQueueMessages>(res.move_as_ok(), true);
if (F.is_error()) {
LOG(ERROR) << "cannot parse answer to liteServer.getDispatchQueueMessages";
return;
}
td::actor::send_closure_later(Self, &TestNode::got_dispatch_queue_messages, F.move_as_ok());
});
}
void TestNode::got_dispatch_queue_messages(ton::tl_object_ptr<ton::lite_api::liteServer_dispatchQueueMessages> msgs) {
td::TerminalIO::out() << "Dispatch queue messages (" << msgs->messages_.size() << "):\n";
int count = 0;
for (auto& m : msgs->messages_) {
auto& meta = m->metadata_;
td::TerminalIO::out() << "Msg #" << ++count << ": " << msgs->id_->workchain_ << ":" << m->addr_.to_hex() << " "
<< m->lt_ << " : "
<< (meta->initiator_->workchain_ == ton::workchainInvalid
? "[ no metadata ]"
: block::MsgMetadata{(td::uint32)meta->depth_, meta->initiator_->workchain_,
meta->initiator_->id_, (ton::LogicalTime)meta->initiator_lt_}
.to_str())
<< "\n";
}
if (!msgs->complete_) {
td::TerminalIO::out() << "(incomplete list)\n";
}
}
bool TestNode::dns_resolve_start(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt blkid, bool TestNode::dns_resolve_start(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt blkid,
std::string domain, td::Bits256 cat, int mode) { std::string domain, td::Bits256 cat, int mode) {
if (domain.size() >= 2 && domain[0] == '"' && domain.back() == '"') { if (domain.size() >= 2 && domain[0] == '"' && domain.back() == '"') {

View file

@ -307,6 +307,13 @@ class TestNode : public td::actor::Actor {
unsigned refs, td::Bits256 chash, std::string filename); unsigned refs, td::Bits256 chash, std::string filename);
bool get_msg_queue_sizes(); bool get_msg_queue_sizes();
void got_msg_queue_sizes(ton::tl_object_ptr<ton::lite_api::liteServer_outMsgQueueSizes> f); void got_msg_queue_sizes(ton::tl_object_ptr<ton::lite_api::liteServer_outMsgQueueSizes> f);
bool get_dispatch_queue_info(ton::BlockIdExt block_id);
bool get_dispatch_queue_info_cont(ton::BlockIdExt block_id, bool first, td::Bits256 after_addr);
void got_dispatch_queue_info(ton::BlockIdExt block_id,
ton::tl_object_ptr<ton::lite_api::liteServer_dispatchQueueInfo> info);
bool get_dispatch_queue_messages(ton::BlockIdExt block_id, ton::WorkchainId wc, ton::StdSmcAddress addr,
ton::LogicalTime lt, bool one_account);
void got_dispatch_queue_messages(ton::tl_object_ptr<ton::lite_api::liteServer_dispatchQueueMessages> msgs);
bool cache_cell(Ref<vm::Cell> cell); bool cache_cell(Ref<vm::Cell> cell);
bool list_cached_cells() const; bool list_cached_cells() const;
bool dump_cached_cell(td::Slice hash_pfx, td::Slice type_name = {}); bool dump_cached_cell(td::Slice hash_pfx, td::Slice type_name = {});

View file

@ -160,6 +160,8 @@ std::string lite_query_name_by_id(int id) {
{lite_api::liteServer_getShardBlockProof::ID, "getShardBlockProof"}, {lite_api::liteServer_getShardBlockProof::ID, "getShardBlockProof"},
{lite_api::liteServer_getOutMsgQueueSizes::ID, "getOutMsgQueueSizes"}, {lite_api::liteServer_getOutMsgQueueSizes::ID, "getOutMsgQueueSizes"},
{lite_api::liteServer_getBlockOutMsgQueueSize::ID, "getBlockOutMsgQueueSize"}, {lite_api::liteServer_getBlockOutMsgQueueSize::ID, "getBlockOutMsgQueueSize"},
{lite_api::liteServer_getDispatchQueueInfo::ID, "getDispatchQueueInfo"},
{lite_api::liteServer_getDispatchQueueMessages::ID, "getDispatchQueueMessages"},
{lite_api::liteServer_nonfinal_getCandidate::ID, "nonfinal.getCandidate"}, {lite_api::liteServer_nonfinal_getCandidate::ID, "nonfinal.getCandidate"},
{lite_api::liteServer_nonfinal_getValidatorGroups::ID, "nonfinal.getValidatorGroups"}}; {lite_api::liteServer_nonfinal_getValidatorGroups::ID, "nonfinal.getValidatorGroups"}};
auto it = names.find(id); auto it = names.find(id);

View file

@ -61,6 +61,11 @@ liteServer.lookupBlockResult id:tonNode.blockIdExt mode:# mc_block_id:tonNode.bl
liteServer.outMsgQueueSize id:tonNode.blockIdExt size:int = liteServer.OutMsgQueueSize; liteServer.outMsgQueueSize id:tonNode.blockIdExt size:int = liteServer.OutMsgQueueSize;
liteServer.outMsgQueueSizes shards:(vector liteServer.outMsgQueueSize) ext_msg_queue_size_limit:int = liteServer.OutMsgQueueSizes; liteServer.outMsgQueueSizes shards:(vector liteServer.outMsgQueueSize) ext_msg_queue_size_limit:int = liteServer.OutMsgQueueSizes;
liteServer.blockOutMsgQueueSize mode:# id:tonNode.blockIdExt size:long proof:mode.0?bytes = liteServer.BlockOutMsgQueueSize; liteServer.blockOutMsgQueueSize mode:# id:tonNode.blockIdExt size:long proof:mode.0?bytes = liteServer.BlockOutMsgQueueSize;
liteServer.accountDispatchQueueInfo addr:int256 size:long min_lt:long max_lt:long = liteServer.AccountDispatchQueueInfo;
liteServer.dispatchQueueInfo mode:# id:tonNode.blockIdExt account_dispatch_queues:(vector liteServer.accountDispatchQueueInfo) complete:Bool proof:mode.0?bytes = liteServer.DispatchQueueInfo;
liteServer.dispatchQueueMessage addr:int256 lt:long hash:int256 metadata:liteServer.transactionMetadata = liteServer.DispatchQueueMessage;
liteServer.dispatchQueueMessages mode:# id:tonNode.blockIdExt messages:(vector liteServer.dispatchQueueMessage) complete:Bool
proof:mode.0?bytes messages_boc:mode.2?bytes = liteServer.DispatchQueueMessages;
liteServer.debug.verbosity value:int = liteServer.debug.Verbosity; liteServer.debug.verbosity value:int = liteServer.debug.Verbosity;
@ -100,6 +105,9 @@ liteServer.getLibrariesWithProof id:tonNode.blockIdExt mode:# library_list:(vect
liteServer.getShardBlockProof id:tonNode.blockIdExt = liteServer.ShardBlockProof; liteServer.getShardBlockProof id:tonNode.blockIdExt = liteServer.ShardBlockProof;
liteServer.getOutMsgQueueSizes mode:# wc:mode.0?int shard:mode.0?long = liteServer.OutMsgQueueSizes; liteServer.getOutMsgQueueSizes mode:# wc:mode.0?int shard:mode.0?long = liteServer.OutMsgQueueSizes;
liteServer.getBlockOutMsgQueueSize mode:# id:tonNode.blockIdExt want_proof:mode.0?true = liteServer.BlockOutMsgQueueSize; liteServer.getBlockOutMsgQueueSize mode:# id:tonNode.blockIdExt want_proof:mode.0?true = liteServer.BlockOutMsgQueueSize;
liteServer.getDispatchQueueInfo mode:# id:tonNode.blockIdExt after_addr:mode.1?int256 max_accounts:int want_proof:mode.0?true = liteServer.DispatchQueueInfo;
liteServer.getDispatchQueueMessages mode:# id:tonNode.blockIdExt addr:int256 after_lt:long max_messages:int
want_proof:mode.0?true one_account:mode.1?true messages_boc:mode.2?true = liteServer.DispatchQueueMessages;
liteServer.nonfinal.getValidatorGroups mode:# wc:mode.0?int shard:mode.0?long = liteServer.nonfinal.ValidatorGroups; liteServer.nonfinal.getValidatorGroups mode:# wc:mode.0?int shard:mode.0?long = liteServer.nonfinal.ValidatorGroups;
liteServer.nonfinal.getCandidate id:liteServer.nonfinal.candidateId = liteServer.nonfinal.Candidate; liteServer.nonfinal.getCandidate id:liteServer.nonfinal.candidateId = liteServer.nonfinal.Candidate;

Binary file not shown.

View file

@ -290,6 +290,13 @@ void LiteQuery::perform() {
[&](lite_api::liteServer_getBlockOutMsgQueueSize& q) { [&](lite_api::liteServer_getBlockOutMsgQueueSize& q) {
this->perform_getBlockOutMsgQueueSize(q.mode_, create_block_id(q.id_)); this->perform_getBlockOutMsgQueueSize(q.mode_, create_block_id(q.id_));
}, },
[&](lite_api::liteServer_getDispatchQueueInfo& q) {
this->perform_getDispatchQueueInfo(q.mode_, create_block_id(q.id_), q.after_addr_, q.max_accounts_);
},
[&](lite_api::liteServer_getDispatchQueueMessages& q) {
this->perform_getDispatchQueueMessages(q.mode_, create_block_id(q.id_), q.addr_,
std::max<td::int64>(q.after_lt_, 0), q.max_messages_);
},
[&](auto& obj) { this->abort_query(td::Status::Error(ErrorCode::protoviolation, "unknown query")); })); [&](auto& obj) { this->abort_query(td::Status::Error(ErrorCode::protoviolation, "unknown query")); }));
} }
@ -3432,6 +3439,248 @@ void LiteQuery::finish_getBlockOutMsgQueueSize() {
finish_query(std::move(b)); finish_query(std::move(b));
} }
void LiteQuery::perform_getDispatchQueueInfo(int mode, BlockIdExt blkid, StdSmcAddress after_addr, int max_accounts) {
LOG(INFO) << "started a getDispatchQueueInfo(" << blkid.to_str() << ", " << mode << ") liteserver query";
mode_ = mode;
if (!blkid.is_valid_full()) {
fatal_error("invalid BlockIdExt");
return;
}
if (max_accounts <= 0) {
fatal_error("invalid max_accounts");
return;
}
set_continuation([=]() -> void { finish_getDispatchQueueInfo(after_addr, max_accounts); });
request_block_data_state(blkid);
}
void LiteQuery::finish_getDispatchQueueInfo(StdSmcAddress after_addr, int max_accounts) {
LOG(INFO) << "completing getDispatchQueueInfo() query";
bool with_proof = mode_ & 1;
Ref<vm::Cell> state_root = state_->root_cell();
vm::MerkleProofBuilder pb;
if (with_proof) {
pb = vm::MerkleProofBuilder{state_root};
state_root = pb.root();
}
std::unique_ptr<vm::AugmentedDictionary> dispatch_queue;
block::gen::ShardStateUnsplit::Record sstate;
block::gen::OutMsgQueueInfo::Record out_msg_queue_info;
block::gen::OutMsgQueueExtra::Record out_msg_queue_extra;
if (!tlb::unpack_cell(state_root, sstate) || !tlb::unpack_cell(sstate.out_msg_queue_info, out_msg_queue_info)) {
fatal_error("cannot unpack shard state");
return;
}
vm::CellSlice& extra_slice = out_msg_queue_info.extra.write();
if (extra_slice.fetch_long(1)) {
if (!tlb::unpack(extra_slice, out_msg_queue_extra)) {
fatal_error("cannot unpack OutMsgQueueExtra");
return;
}
dispatch_queue = std::make_unique<vm::AugmentedDictionary>(out_msg_queue_extra.dispatch_queue, 256,
block::tlb::aug_DispatchQueue);
} else {
dispatch_queue = std::make_unique<vm::AugmentedDictionary>(256, block::tlb::aug_DispatchQueue);
}
int remaining = std::min(max_accounts, 64);
bool complete = false;
std::vector<tl_object_ptr<lite_api::liteServer_accountDispatchQueueInfo>> result;
bool allow_eq;
if (mode_ & 2) {
allow_eq = false;
} else {
allow_eq = true;
after_addr = td::Bits256::zero();
}
while (true) {
auto value = dispatch_queue->extract_value(dispatch_queue->lookup_nearest_key(after_addr, true, allow_eq));
allow_eq = false;
if (value.is_null()) {
complete = true;
break;
}
if (remaining == 0) {
break;
}
--remaining;
StdSmcAddress addr = after_addr;
vm::Dictionary dict{64};
td::uint64 dict_size;
if (!block::unpack_account_dispatch_queue(value, dict, dict_size)) {
fatal_error(PSTRING() << "invalid account dispatch queue for account " << addr.to_hex());
return;
}
CHECK(dict_size > 0);
td::BitArray<64> min_lt, max_lt;
dict.get_minmax_key(min_lt.bits(), 64, false, false);
dict.get_minmax_key(max_lt.bits(), 64, true, false);
result.push_back(create_tl_object<lite_api::liteServer_accountDispatchQueueInfo>(addr, dict_size, min_lt.to_ulong(),
max_lt.to_ulong()));
}
td::BufferSlice proof;
if (with_proof) {
Ref<vm::Cell> proof1, proof2;
if (!make_state_root_proof(proof1)) {
return;
}
if (!pb.extract_proof_to(proof2)) {
fatal_error("unknown error creating Merkle proof");
return;
}
auto r_proof = vm::std_boc_serialize_multi({std::move(proof1), std::move(proof2)});
if (r_proof.is_error()) {
fatal_error(r_proof.move_as_error());
return;
}
proof = r_proof.move_as_ok();
}
LOG(INFO) << "getDispatchQueueInfo(" << blk_id_.to_str() << ", " << mode_ << ") query completed";
auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_dispatchQueueInfo>(
mode_, ton::create_tl_lite_block_id(blk_id_), std::move(result), complete, std::move(proof));
finish_query(std::move(b));
}
void LiteQuery::perform_getDispatchQueueMessages(int mode, BlockIdExt blkid, StdSmcAddress addr, LogicalTime lt,
int max_messages) {
LOG(INFO) << "started a getDispatchQueueMessages(" << blkid.to_str() << ", " << mode << ") liteserver query";
mode_ = mode;
if (!blkid.is_valid_full()) {
fatal_error("invalid BlockIdExt");
return;
}
if (max_messages <= 0) {
fatal_error("invalid max_messages");
return;
}
set_continuation([=]() -> void { finish_getDispatchQueueMessages(addr, lt, max_messages); });
request_block_data_state(blkid);
}
void LiteQuery::finish_getDispatchQueueMessages(StdSmcAddress addr, LogicalTime lt, int max_messages) {
LOG(INFO) << "completing getDispatchQueueMessages() query";
bool with_proof = mode_ & lite_api::liteServer_getDispatchQueueMessages::WANT_PROOF_MASK;
bool one_account = mode_ & lite_api::liteServer_getDispatchQueueMessages::ONE_ACCOUNT_MASK;
bool with_messages_boc = mode_ & lite_api::liteServer_getDispatchQueueMessages::MESSAGES_BOC_MASK;
Ref<vm::Cell> state_root = state_->root_cell();
vm::MerkleProofBuilder pb;
if (with_proof) {
pb = vm::MerkleProofBuilder{state_root};
state_root = pb.root();
}
std::unique_ptr<vm::AugmentedDictionary> dispatch_queue;
block::gen::ShardStateUnsplit::Record sstate;
block::gen::OutMsgQueueInfo::Record out_msg_queue_info;
block::gen::OutMsgQueueExtra::Record out_msg_queue_extra;
if (!tlb::unpack_cell(state_root, sstate) || !tlb::unpack_cell(sstate.out_msg_queue_info, out_msg_queue_info)) {
fatal_error("cannot unpack shard state");
return;
}
vm::CellSlice& extra_slice = out_msg_queue_info.extra.write();
if (extra_slice.fetch_long(1)) {
if (!tlb::unpack(extra_slice, out_msg_queue_extra)) {
fatal_error("cannot unpack OutMsgQueueExtra");
return;
}
dispatch_queue = std::make_unique<vm::AugmentedDictionary>(out_msg_queue_extra.dispatch_queue, 256,
block::tlb::aug_DispatchQueue);
} else {
dispatch_queue = std::make_unique<vm::AugmentedDictionary>(256, block::tlb::aug_DispatchQueue);
}
int remaining = std::min(max_messages, with_messages_boc ? 16 : 64);
bool complete = false;
std::vector<tl_object_ptr<lite_api::liteServer_dispatchQueueMessage>> result;
std::vector<td::Ref<vm::Cell>> message_roots;
td::Bits256 orig_addr = addr;
bool first = true;
while (remaining > 0) {
auto value = dispatch_queue->extract_value(dispatch_queue->lookup_nearest_key(addr, true, first));
if (value.is_null() || (one_account && addr != orig_addr)) {
complete = true;
break;
}
vm::Dictionary account_queue{64};
td::uint64 dict_size;
if (!block::unpack_account_dispatch_queue(value, account_queue, dict_size)) {
fatal_error(PSTRING() << "invalid account dispatch queue for account " << addr.to_hex());
return;
}
CHECK(dict_size > 0);
while (true) {
td::BitArray<64> lt_key;
lt_key.store_ulong(lt);
auto value2 = account_queue.lookup_nearest_key(lt_key, true, false);
if (value2.is_null()) {
break;
}
lt = lt_key.to_ulong();
if (remaining == 0) {
break;
}
--remaining;
auto msg_env = value2->prefetch_ref();
block::tlb::MsgEnvelope::Record_std env;
if (msg_env.is_null() || !tlb::unpack_cell(msg_env, env)) {
fatal_error(PSTRING() << "invalid message in dispatch queue for account " << addr.to_hex() << ", lt " << lt);
return;
}
message_roots.push_back(env.msg);
tl_object_ptr<lite_api::liteServer_transactionMetadata> metadata_tl;
if (env.metadata) {
auto& metadata = env.metadata.value();
metadata_tl = create_tl_object<lite_api::liteServer_transactionMetadata>(
0, metadata.depth,
create_tl_object<lite_api::liteServer_accountId>(metadata.initiator_wc, metadata.initiator_addr),
metadata.initiator_lt);
} else {
metadata_tl = create_tl_object<lite_api::liteServer_transactionMetadata>(
0, -1, create_tl_object<lite_api::liteServer_accountId>(workchainInvalid, td::Bits256::zero()), -1);
}
result.push_back(create_tl_object<lite_api::liteServer_dispatchQueueMessage>(addr, lt, env.msg->get_hash().bits(),
std::move(metadata_tl)));
}
first = false;
lt = 0;
}
td::BufferSlice proof;
if (with_proof) {
Ref<vm::Cell> proof1, proof2;
if (!make_state_root_proof(proof1)) {
return;
}
if (!pb.extract_proof_to(proof2)) {
fatal_error("unknown error creating Merkle proof");
return;
}
auto r_proof = vm::std_boc_serialize_multi({std::move(proof1), std::move(proof2)});
if (r_proof.is_error()) {
fatal_error(r_proof.move_as_error());
return;
}
proof = r_proof.move_as_ok();
}
td::BufferSlice messages_boc;
if (with_messages_boc) {
auto r_messages_boc = vm::std_boc_serialize_multi(std::move(message_roots));
if (r_messages_boc.is_error()) {
fatal_error(r_messages_boc.move_as_error());
return;
}
messages_boc = std::move(messages_boc);
}
LOG(INFO) << "getDispatchQueueMessages(" << blk_id_.to_str() << ", " << mode_ << ") query completed";
auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_dispatchQueueMessages>(
mode_, ton::create_tl_lite_block_id(blk_id_), std::move(result), complete, std::move(proof),
std::move(messages_boc));
finish_query(std::move(b));
}
void LiteQuery::perform_nonfinal_getCandidate(td::Bits256 source, BlockIdExt blkid, td::Bits256 collated_data_hash) { void LiteQuery::perform_nonfinal_getCandidate(td::Bits256 source, BlockIdExt blkid, td::Bits256 collated_data_hash) {
LOG(INFO) << "started a nonfinal.getCandidate liteserver query"; LOG(INFO) << "started a nonfinal.getCandidate liteserver query";

View file

@ -172,6 +172,11 @@ class LiteQuery : public td::actor::Actor {
void continue_getOutMsgQueueSizes(td::optional<ShardIdFull> shard, Ref<MasterchainState> state); void continue_getOutMsgQueueSizes(td::optional<ShardIdFull> shard, Ref<MasterchainState> state);
void perform_getBlockOutMsgQueueSize(int mode, BlockIdExt blkid); void perform_getBlockOutMsgQueueSize(int mode, BlockIdExt blkid);
void finish_getBlockOutMsgQueueSize(); 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_getCandidate(td::Bits256 source, BlockIdExt blkid, td::Bits256 collated_data_hash);
void perform_nonfinal_getValidatorGroups(int mode, ShardIdFull shard); void perform_nonfinal_getValidatorGroups(int mode, ShardIdFull shard);