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:
parent
9f203890f4
commit
b304b1c7be
7 changed files with 364 additions and 3 deletions
|
@ -974,6 +974,11 @@ bool TestNode::show_help(std::string command) {
|
|||
"into files <filename-pfx><complaint-hash>.boc\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"
|
||||
"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"
|
||||
"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"
|
||||
|
@ -988,9 +993,9 @@ bool TestNode::show_help(std::string command) {
|
|||
bool TestNode::do_parse_line() {
|
||||
ton::WorkchainId workchain = ton::masterchainId; // change to basechain later
|
||||
int addr_ext = 0;
|
||||
ton::StdSmcAddress addr{};
|
||||
ton::StdSmcAddress addr = ton::StdSmcAddress::zero();
|
||||
ton::BlockIdExt blkid{};
|
||||
ton::LogicalTime lt{};
|
||||
ton::LogicalTime lt = 0;
|
||||
ton::Bits256 hash{};
|
||||
ton::ShardIdFull shard{};
|
||||
ton::BlockSeqno seqno{};
|
||||
|
@ -1118,6 +1123,16 @@ bool TestNode::do_parse_line() {
|
|||
set_error(get_complaint_price(expire_in, filename));
|
||||
} else if (word == "msgqueuesizes") {
|
||||
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") {
|
||||
return eoln() && show_new_blkids(true);
|
||||
} 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;
|
||||
}
|
||||
|
||||
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,
|
||||
std::string domain, td::Bits256 cat, int mode) {
|
||||
if (domain.size() >= 2 && domain[0] == '"' && domain.back() == '"') {
|
||||
|
@ -4322,7 +4412,7 @@ int main(int argc, char* argv[]) {
|
|||
});
|
||||
p.add_option('V', "version", "shows lite-client build information", [&]() {
|
||||
std::cout << "lite-client build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n";
|
||||
|
||||
|
||||
std::exit(0);
|
||||
});
|
||||
p.add_option('i', "idx", "set liteserver idx", [&](td::Slice arg) {
|
||||
|
|
|
@ -307,6 +307,13 @@ class TestNode : public td::actor::Actor {
|
|||
unsigned refs, td::Bits256 chash, std::string filename);
|
||||
bool get_msg_queue_sizes();
|
||||
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 list_cached_cells() const;
|
||||
bool dump_cached_cell(td::Slice hash_pfx, td::Slice type_name = {});
|
||||
|
|
|
@ -160,6 +160,8 @@ std::string lite_query_name_by_id(int id) {
|
|||
{lite_api::liteServer_getShardBlockProof::ID, "getShardBlockProof"},
|
||||
{lite_api::liteServer_getOutMsgQueueSizes::ID, "getOutMsgQueueSizes"},
|
||||
{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_getValidatorGroups::ID, "nonfinal.getValidatorGroups"}};
|
||||
auto it = names.find(id);
|
||||
|
|
|
@ -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.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.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;
|
||||
|
||||
|
@ -100,6 +105,9 @@ liteServer.getLibrariesWithProof id:tonNode.blockIdExt mode:# library_list:(vect
|
|||
liteServer.getShardBlockProof id:tonNode.blockIdExt = liteServer.ShardBlockProof;
|
||||
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.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.getCandidate id:liteServer.nonfinal.candidateId = liteServer.nonfinal.Candidate;
|
||||
|
|
Binary file not shown.
|
@ -290,6 +290,13 @@ void LiteQuery::perform() {
|
|||
[&](lite_api::liteServer_getBlockOutMsgQueueSize& q) {
|
||||
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")); }));
|
||||
}
|
||||
|
||||
|
@ -3432,6 +3439,248 @@ void LiteQuery::finish_getBlockOutMsgQueueSize() {
|
|||
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) {
|
||||
LOG(INFO) << "started a nonfinal.getCandidate liteserver query";
|
||||
|
|
|
@ -172,6 +172,11 @@ class LiteQuery : public td::actor::Actor {
|
|||
void continue_getOutMsgQueueSizes(td::optional<ShardIdFull> shard, Ref<MasterchainState> state);
|
||||
void perform_getBlockOutMsgQueueSize(int mode, BlockIdExt blkid);
|
||||
void finish_getBlockOutMsgQueueSize();
|
||||
void perform_getDispatchQueueInfo(int mode, BlockIdExt blkid, StdSmcAddress after_addr, int max_accounts);
|
||||
void finish_getDispatchQueueInfo(StdSmcAddress after_addr, int max_accounts);
|
||||
void perform_getDispatchQueueMessages(int mode, BlockIdExt blkid, StdSmcAddress addr, LogicalTime lt,
|
||||
int max_messages);
|
||||
void finish_getDispatchQueueMessages(StdSmcAddress addr, LogicalTime lt, int max_messages);
|
||||
|
||||
void perform_nonfinal_getCandidate(td::Bits256 source, BlockIdExt blkid, td::Bits256 collated_data_hash);
|
||||
void perform_nonfinal_getValidatorGroups(int mode, ShardIdFull shard);
|
||||
|
|
Loading…
Reference in a new issue