Skip to content

Commit

Permalink
Merge pull request #19 from disintar/feature-getParsedBlock
Browse files Browse the repository at this point in the history
Feature: get parsed block
  • Loading branch information
tvorogme authored Oct 1, 2024
2 parents 858dec9 + 99760e8 commit 4829a19
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 4 deletions.
2 changes: 2 additions & 0 deletions tl/generate/scheme/lite_api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ liteServer.masterchainInfoExt mode:# version:int capabilities:long last:tonNode.
liteServer.currentTime now:int = liteServer.CurrentTime;
liteServer.version mode:# version:int capabilities:long now:int = liteServer.Version;
liteServer.blockData id:tonNode.blockIdExt data:bytes = liteServer.BlockData;
liteServer.parsedBlockData json_data:string = liteServer.ParsedBlockData;
liteServer.blockState id:tonNode.blockIdExt root_hash:int256 file_hash:int256 data:bytes = liteServer.BlockState;
liteServer.blockHeader id:tonNode.blockIdExt mode:# header_proof:bytes = liteServer.BlockHeader;
liteServer.sendMsgStatus status:int = liteServer.SendMsgStatus;
Expand Down Expand Up @@ -121,6 +122,7 @@ liteServer.nonfinal.getCandidate id:liteServer.nonfinal.candidateId = liteServer
liteServer.addUser key:int256 valid_until:int64 ratelimit:int = liteServer.NewUser;
liteServer.getStatData = liteServer.Stats;
liteServer.checkItemPublished key:int256 category:int64 = liteServer.ItemPublished;
liteServer.getParsedBlock id:tonNode.blockId = liteServer.ParsedBlockData;

liteServer.queryPrefix = Object;
liteServer.query data:bytes = Object;
Expand Down
Binary file modified tl/generate/scheme/lite_api.tlo
Binary file not shown.
24 changes: 23 additions & 1 deletion tvm-python/PyLiteClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ namespace pylite {
});
}

void LiteClientActorEngine::get_ParsedBlockInfo(ton::BlockId block){
auto q = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getParsedBlock>(
ton::create_tl_lite_block_id_simple(block)), true);
qprocess(std::move(q));
};

void LiteClientActorEngine::admin_qprocess(td::BufferSlice q) {
td::actor::send_closure(
client, &ton::adnl::AdnlExtClient::send_query, "adminquery",
Expand Down Expand Up @@ -791,9 +797,25 @@ namespace pylite {
}
};

PyCell PyLiteClient::get_Block(ton::BlockIdExt req_blkid) {
std::string PyLiteClient::get_ParsedBlockInfo(ton::BlockId blkid) {
scheduler_.run_in_context_external([&] { send_closure(engine, &LiteClientActorEngine::get_ParsedBlockInfo, blkid); });

auto response = wait_response();
if (response->success) {
SuccessBufferSlice *rdata = dynamic_cast<SuccessBufferSlice *>(response.get());
auto R =
ton::fetch_tl_object < ton::lite_api::liteServer_parsedBlockData> (std::move(rdata->obj->clone()), true);
if (R.is_error()) {
throw_lite_error(rdata->obj->clone());
}

return std::move(R.move_as_ok()->json_data_);
} else {
throw std::logic_error(response->error_message);
}
}

PyCell PyLiteClient::get_Block(ton::BlockIdExt req_blkid) {
scheduler_.run_in_context_external([&] { send_closure(engine, &LiteClientActorEngine::get_Block, req_blkid); });

auto response = wait_response();
Expand Down
6 changes: 4 additions & 2 deletions tvm-python/PyLiteClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ namespace pylite {

void lookupBlock(int mode, ton::BlockId block, long long lt, long long time);

void get_ParsedBlockInfo(ton::BlockId block);

void ready();

void wait_connected(double wait);
Expand Down Expand Up @@ -250,14 +252,14 @@ namespace pylite {
block::TransactionList::Info get_Transactions(int count, int workchain, std::string address_string,
unsigned long long lt, std::string hash_int_string);

PyCell
get_OneTransaction(ton::BlockIdExt blkid, int workchain, std::string address_string, unsigned long long lt);
PyCell get_OneTransaction(ton::BlockIdExt blkid, int workchain, std::string address_string, unsigned long long lt);

TestNode::BlockHdrInfo get_BlockHeader(ton::BlockIdExt blkid, int mode);

TestNode::BlockHdrInfo lookupBlock(int mode, ton::BlockId block, long long lt, long long time);

PyCell get_Block(ton::BlockIdExt blkid);
std::string get_ParsedBlockInfo(ton::BlockId blkid);

PyDict get_Libraries(std::vector<std::string> libs);

Expand Down
1 change: 1 addition & 0 deletions tvm-python/python_ton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ PYBIND11_MODULE(python_ton, m) {
py::arg("address"), py::arg("lt"))
.def("stop", &pylite::PyLiteClient::stop)
.def("dummy_wait", &pylite::PyLiteClient::dummy_wait)
.def("get_ParsedBlockInfo", &pylite::PyLiteClient::get_ParsedBlockInfo, py::arg("block_id"))
.def("get_Block", &pylite::PyLiteClient::get_Block, py::arg("block_id"))
.def("admin_AddUser", &pylite::PyLiteClient::admin_AddUser, py::arg("pubkey"), py::arg("validuntil"),
py::arg("ratelimit"))
Expand Down
1 change: 1 addition & 0 deletions validator/impl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(TON_VALIDATOR_SOURCE
fabric.cpp
ihr-message.cpp
liteserver.cpp
liteserver-extra.cpp
message-queue.cpp
proof.cpp
shard.cpp
Expand Down
132 changes: 132 additions & 0 deletions validator/impl/liteserver-extra.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "liteserver.hpp"
#include "validator/interfaces/validator-manager.h"
#include "td/actor/actor.h"
#include "td/actor/ActorId.h"
#include "validator-engine/BlockParserAsync.hpp"
#include "auto/tl/lite_api.h"
#include "auto/tl/lite_api.hpp"
#include "ton/lite-tl.hpp"
#include "tl-utils/lite-utils.hpp"

namespace ton {
std::string blkid_to_text(BlockId id) {
return "(" + std::to_string(id.workchain) + ":" + std::to_string(id.shard) + ":" + std::to_string(id.seqno) + ")";
}

std::string blkid_to_text(BlockIdExt id) {
return blkid_to_text(id.id) + " root_hash: " + id.root_hash.to_hex() + " file_hash: " + id.file_hash.to_hex();
}

namespace validator {
void LiteQuery::perform_getParsedBlock(BlockId blkid) {
LOG(INFO) << "Perform getParsedBlock: " << blkid_to_text(blkid);

timeout_ = td::Timestamp::in(default_timeout_msec);

auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<ConstBlockHandle> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &LiteQuery::abort_query, td::Status::Error(
"Can't get handle from db: " + R.move_as_error().to_string()));
} else {
auto handle = R.move_as_ok();
auto prev_block = handle->prev();
td::actor::send_closure_later(SelfId, &LiteQuery::set_handle, handle);

td::actor::send_closure(SelfId, &LiteQuery::set_continuation,
[SelfId, prev_block = std::move(prev_block)]() -> void {
td::actor::send_closure_later(SelfId, &LiteQuery::continue_getParsedBlock,
prev_block);
});

td::actor::send_closure_later(SelfId, &LiteQuery::request_block_data, handle->id());
td::actor::send_closure_later(SelfId, &LiteQuery::request_block_state, handle->id());
}
});

ton::AccountIdPrefixFull pfx{blkid.workchain, blkid.shard};
td::actor::send_closure(manager_, &ValidatorManagerInterface::get_block_by_seqno_from_db, pfx,
blkid.seqno, std::move(P));
}

void LiteQuery::set_handle(ConstBlockHandle handle) {
parse_handle_ = handle;
}

void LiteQuery::continue_getParsedBlock(std::vector<BlockIdExt> blkids_prev) {
// todo: seqno:0
current_state_ = std::move(state_);
auto SelfId = actor_id(this);

if (blkids_prev.size() > 1) {
prev_accounts_left_shard = blkids_prev[0].id.shard;
prev_accounts_right_shard = blkids_prev[1].id.shard;

td::actor::send_closure(SelfId, &LiteQuery::set_continuation,
[SelfId, right_state_id = blkids_prev[1]]() -> void {
td::actor::send_closure_later(SelfId, &LiteQuery::continue_prev_getParsedBlock,
right_state_id);
});
} else {
prev_accounts_left_shard = blkids_prev[0].id.shard;

td::actor::send_closure(SelfId, &LiteQuery::set_continuation, [SelfId]() -> void {
td::actor::send_closure_later(SelfId, &LiteQuery::finish_getParsedBlock, false);
});
}

LOG(INFO) << "Perform getParsedBlock, get left prev state: " << blkid_to_text(blkids_prev[0]);
td::actor::send_closure_later(actor_id(this), &LiteQuery::request_block_state, blkids_prev[0]);
}

void LiteQuery::continue_prev_getParsedBlock(BlockIdExt blkid_prev_right) {
LOG(INFO) << "Perform getParsedBlock, get right prev state: " << blkid_to_text(blkid_prev_right);
left_prev_state_ = std::move(state_);

td::actor::send_closure(actor_id(this), &LiteQuery::set_continuation, [SelfId = actor_id(this)]() -> void {
td::actor::send_closure_later(SelfId, &LiteQuery::finish_getParsedBlock, true);
});
}

void LiteQuery::finish_getParsedBlock(bool after_merge) {
LOG(INFO) << "Perform getParsedBlock, run index";
if (!after_merge) {
left_prev_state_ = std::move(state_);
}

auto P0 = td::PromiseCreator::lambda(
[](td::Result<std::tuple<td::vector<json>, td::Bits256, unsigned long long, int>> R) {});
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this)](td::Result<std::tuple<td::Bits256, td::string, td::string>> R) mutable {
if (R.is_ok()) {
auto result = R.move_as_ok();

std::string block = std::get<1>(result);
std::string state = std::get<2>(result);

std::string data =
"{\"root_hash\": \"" + std::get<0>(result).to_hex() + "\", \"block\": " + block +
", \"state\": " + state + "}";

td::actor::send_closure(SelfId, &LiteQuery::send_getParsedBlock, std::move(data));
} else {
td::actor::send_closure(SelfId, &LiteQuery::abort_query, R.move_as_error());
}
});

td::actor::create_actor<BlockParserAsync>("BlockParserAsync",
parse_handle_->id(),
parse_handle_,
block_,
current_state_->root_cell(),
left_prev_state_->root_cell(),
std::move(P),
std::move(P0))
.release();
}

void LiteQuery::send_getParsedBlock(std::string data) {
auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_parsedBlockData>(std::move(data));
finish_query(std::move(b));
}
}
}
8 changes: 8 additions & 0 deletions validator/impl/liteserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,12 +528,20 @@ namespace ton {
this->perform_getBlockOutMsgQueueSize(q.mode_, create_block_id(q.id_));
},
[&](lite_api::liteServer_getDispatchQueueInfo& q) {
query_compiled = " Query: getDispatchQueueInfo(block_id: " + string_block_id(q.id_) +
", after_addr: " + q.after_addr_.to_hex() + ", max_accounts: " + std::to_string(q.max_accounts_) + ")";
this->perform_getDispatchQueueInfo(q.mode_, create_block_id(q.id_), q.after_addr_, q.max_accounts_);
},
[&](lite_api::liteServer_getDispatchQueueMessages& q) {
query_compiled = " Query: getDispatchQueueInfo(block_id: " + string_block_id(q.id_) +
", addr: " + q.addr_.to_hex() + ", after_lt: " + std::to_string(q.after_lt_)
+ ", max_messages: " + std::to_string(q.max_messages_) + ")";
this->perform_getDispatchQueueMessages(q.mode_, create_block_id(q.id_), q.addr_,
std::max<td::int64>(q.after_lt_, 0), q.max_messages_);
},
[&](lite_api::liteServer_getParsedBlock& q){
this->perform_getParsedBlock(create_block_id_simple(q.id_));
},
[&](auto &obj) {
this->abort_query(td::Status::Error(ErrorCode::protoviolation, "unknown query"));
}));
Expand Down
12 changes: 11 additions & 1 deletion validator/impl/liteserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ class LiteQuery : public td::actor::Actor {
LogicalTime trans_lt_;
Bits256 trans_hash_;
BlockIdExt base_blk_id_, base_blk_id_alt_, blk_id_;
ConstBlockHandle parse_handle_;
Ref<MasterchainStateQ> mc_state_, mc_state0_;
Ref<ShardStateQ> state_;

ShardId prev_accounts_left_shard, prev_accounts_right_shard;
// If we perform getParsedBlockInfo - get prev state in state_ and current state in current_state_
Ref<ShardStateQ> state_, left_prev_state_, current_state_;
Ref<BlockQ> mc_block_, block_;
Ref<ProofQ> mc_proof_, mc_proof_alt_;
Ref<ProofLinkQ> proof_link_;
Expand Down Expand Up @@ -186,6 +190,11 @@ class LiteQuery : public td::actor::Actor {
void perform_getBlockOutMsgQueueSize(int mode, BlockIdExt blkid);
void finish_getBlockOutMsgQueueSize();
void perform_getDispatchQueueInfo(int mode, BlockIdExt blkid, StdSmcAddress after_addr, int max_accounts);
void perform_getParsedBlock(BlockId blkid);
void continue_getParsedBlock(std::vector<BlockIdExt> blkids_prev);
void continue_prev_getParsedBlock(BlockIdExt blkid_prev_right);
void finish_getParsedBlock(bool after_merge);
void send_getParsedBlock(std::string data);
void finish_getDispatchQueueInfo(StdSmcAddress after_addr, int max_accounts);
void perform_getDispatchQueueMessages(int mode, BlockIdExt blkid, StdSmcAddress addr, LogicalTime lt,
int max_messages);
Expand Down Expand Up @@ -216,6 +225,7 @@ class LiteQuery : public td::actor::Actor {
void got_mc_block_data(BlockIdExt blkid, Ref<BlockData> data);
void got_mc_block_proof(BlockIdExt blkid, int mode, Ref<Proof> proof);
void got_block_proof_link(BlockIdExt blkid, Ref<ProofLink> proof_link);
void set_handle(ConstBlockHandle handle);
void got_zero_state(BlockIdExt blkid, td::BufferSlice zerostate);
void dec_pending() {
if (!--pending_) {
Expand Down

0 comments on commit 4829a19

Please sign in to comment.