mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'testnet' into block-generation
# Conflicts: # overlay/overlay-fec-broadcast.cpp # overlay/overlay.hpp # tl/generate/scheme/ton_api.tl # tl/generate/scheme/ton_api.tlo # validator-engine-console/validator-engine-console-query.cpp # validator-engine-console/validator-engine-console-query.h # validator-engine-console/validator-engine-console.cpp # validator-engine/validator-engine.cpp # validator-engine/validator-engine.hpp # validator/downloaders/wait-block-state.hpp # validator/impl/validate-query.cpp # validator/validator.h
This commit is contained in:
commit
636348ffc2
110 changed files with 3822 additions and 696 deletions
|
|
@ -54,7 +54,10 @@ AcceptBlockQuery::AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::
|
|||
, send_broadcast_(send_broadcast)
|
||||
, apply_(apply)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
, promise_(std::move(promise))
|
||||
, perf_timer_("acceptblock", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "acceptblock", duration);
|
||||
}) {
|
||||
state_keep_old_hash_.clear();
|
||||
state_old_hash_.clear();
|
||||
state_hash_.clear();
|
||||
|
|
@ -72,7 +75,10 @@ AcceptBlockQuery::AcceptBlockQuery(AcceptBlockQuery::IsFake fake, BlockIdExt id,
|
|||
, is_fork_(false)
|
||||
, send_broadcast_(false)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
, promise_(std::move(promise))
|
||||
, perf_timer_("acceptblock", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "acceptblock", duration);
|
||||
}) {
|
||||
state_keep_old_hash_.clear();
|
||||
state_old_hash_.clear();
|
||||
state_hash_.clear();
|
||||
|
|
@ -87,7 +93,10 @@ AcceptBlockQuery::AcceptBlockQuery(ForceFork ffork, BlockIdExt id, td::Ref<Block
|
|||
, is_fork_(true)
|
||||
, send_broadcast_(false)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
, promise_(std::move(promise))
|
||||
, perf_timer_("acceptblock", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "acceptblock", duration);
|
||||
}) {
|
||||
state_keep_old_hash_.clear();
|
||||
state_old_hash_.clear();
|
||||
state_hash_.clear();
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class AcceptBlockQuery : public td::actor::Actor {
|
|||
td::BufferSlice top_block_descr_data_;
|
||||
Ref<ShardTopBlockDescription> top_block_descr_;
|
||||
|
||||
td::PerfWarningTimer perf_timer_{"acceptblock", 0.1};
|
||||
td::PerfWarningTimer perf_timer_;
|
||||
|
||||
bool fatal_error(std::string msg, int code = -666);
|
||||
static bool check_send_error(td::actor::ActorId<AcceptBlockQuery> SelfId, td::Status error);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ class CheckProof : public td::actor::Actor {
|
|||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise))
|
||||
, skip_check_signatures_(skip_check_signatures) {
|
||||
, skip_check_signatures_(skip_check_signatures)
|
||||
, perf_timer_("checkproof", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "checkproof", duration);
|
||||
}) {
|
||||
}
|
||||
CheckProof(BlockIdExt id, td::Ref<Proof> proof, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockHandle> promise, bool skip_check_signatures, td::Ref<MasterchainState> known_state)
|
||||
|
|
@ -58,7 +61,10 @@ class CheckProof : public td::actor::Actor {
|
|||
, timeout_(timeout)
|
||||
, promise_(std::move(promise))
|
||||
, state_(std::move(known_state))
|
||||
, skip_check_signatures_(skip_check_signatures) {
|
||||
, skip_check_signatures_(skip_check_signatures)
|
||||
, perf_timer_("checkproof", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "checkproof", duration);
|
||||
}) {
|
||||
}
|
||||
CheckProof(BlockIdExt id, td::Ref<ProofLink> proof_link, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise)
|
||||
|
|
@ -67,7 +73,10 @@ class CheckProof : public td::actor::Actor {
|
|||
, proof_(std::move(proof_link))
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
, promise_(std::move(promise))
|
||||
, perf_timer_("checkproof", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "checkproof", duration);
|
||||
}) {
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -114,7 +123,7 @@ class CheckProof : public td::actor::Actor {
|
|||
bool skip_check_signatures_{false};
|
||||
bool sig_ok_{false};
|
||||
|
||||
td::PerfWarningTimer perf_timer_{"checkproof", 0.1};
|
||||
td::PerfWarningTimer perf_timer_;
|
||||
|
||||
static bool check_send_error(td::actor::ActorId<CheckProof> SelfId, td::Status error);
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ class Collator final : public td::actor::Actor {
|
|||
|
||||
std::unique_ptr<ton::BlockCandidate> block_candidate;
|
||||
|
||||
td::PerfWarningTimer perf_timer_{"collate", 0.1};
|
||||
td::PerfWarningTimer perf_timer_;
|
||||
//
|
||||
block::Account* lookup_account(td::ConstBitPtr addr) const;
|
||||
std::unique_ptr<block::Account> make_account_from(td::ConstBitPtr addr, Ref<vm::CellSlice> account,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ Collator::Collator(ShardIdFull shard, bool is_hardfork, BlockIdExt min_mastercha
|
|||
, validator_set_(std::move(validator_set))
|
||||
, manager(manager)
|
||||
, timeout(timeout)
|
||||
, main_promise(std::move(promise)) {
|
||||
, main_promise(std::move(promise))
|
||||
, perf_timer_("collate", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "collate", duration);
|
||||
}) {
|
||||
}
|
||||
|
||||
void Collator::start_up() {
|
||||
|
|
|
|||
|
|
@ -201,6 +201,9 @@ void LiteQuery::start_up() {
|
|||
[&](lite_api::liteServer_getLibraries& q) {
|
||||
this->perform_getLibraries(q.library_list_);
|
||||
},
|
||||
[&](lite_api::liteServer_getShardBlockProof& q) {
|
||||
this->perform_getShardBlockProof(create_block_id(q.id_));
|
||||
},
|
||||
[&](auto& obj) { this->abort_query(td::Status::Error(ErrorCode::protoviolation, "unknown query")); }));
|
||||
}
|
||||
|
||||
|
|
@ -269,15 +272,21 @@ void LiteQuery::perform_getBlock(BlockIdExt blkid) {
|
|||
fatal_error("invalid BlockIdExt");
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(manager_, &ValidatorManager::get_block_data_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<Ref<ton::validator::BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getBlock, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [manager = manager_, Self = actor_id(this), blkid](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_block_data_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<ton::validator::BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getBlock, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void LiteQuery::continue_getBlock(BlockIdExt blkid, Ref<ton::validator::BlockData> block) {
|
||||
|
|
@ -295,15 +304,21 @@ void LiteQuery::perform_getBlockHeader(BlockIdExt blkid, int mode) {
|
|||
fatal_error("invalid BlockIdExt");
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(manager_, &ValidatorManager::get_block_data_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid, mode](td::Result<Ref<ton::validator::BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getBlockHeader, blkid,
|
||||
mode, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_block_data_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<ton::validator::BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getBlockHeader, blkid,
|
||||
mode, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static bool visit(Ref<vm::Cell> cell);
|
||||
|
|
@ -409,27 +424,33 @@ void LiteQuery::perform_getState(BlockIdExt blkid) {
|
|||
fatal_error("cannot request total state: possibly too large");
|
||||
return;
|
||||
}
|
||||
if (blkid.id.seqno) {
|
||||
td::actor::send_closure_later(manager_, &ValidatorManager::get_shard_state_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<Ref<ton::validator::ShardState>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getState, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
td::actor::send_closure_later(manager_, &ValidatorManager::get_zero_state, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<td::BufferSlice> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getZeroState, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
}
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
if (blkid.id.seqno) {
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_shard_state_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<ton::validator::ShardState>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getState, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_zero_state, blkid,
|
||||
[=](td::Result<td::BufferSlice> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getZeroState, blkid,
|
||||
res.move_as_ok());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LiteQuery::continue_getState(BlockIdExt blkid, Ref<ton::validator::ShardState> state) {
|
||||
|
|
@ -481,6 +502,23 @@ void LiteQuery::perform_sendMessage(td::BufferSlice data) {
|
|||
});
|
||||
}
|
||||
|
||||
void LiteQuery::get_block_handle_checked(BlockIdExt blkid, td::Promise<ConstBlockHandle> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error());
|
||||
} else {
|
||||
auto handle = R.move_as_ok();
|
||||
if (handle->is_applied()) {
|
||||
promise.set_result(std::move(handle));
|
||||
} else {
|
||||
promise.set_error(td::Status::Error("block is not applied"));
|
||||
}
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, blkid, false, std::move(P));
|
||||
}
|
||||
|
||||
bool LiteQuery::request_mc_block_data(BlockIdExt blkid) {
|
||||
if (!blkid.is_masterchain() || !blkid.is_valid_full()) {
|
||||
return fatal_error("reference block must belong to the masterchain");
|
||||
|
|
@ -579,16 +617,22 @@ bool LiteQuery::request_block_state(BlockIdExt blkid) {
|
|||
}
|
||||
blk_id_ = blkid;
|
||||
++pending_;
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::get_shard_state_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<Ref<ShardState>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load state for "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_state, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_shard_state_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<ShardState>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load state for "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_state, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -601,16 +645,22 @@ bool LiteQuery::request_block_data(BlockIdExt blkid) {
|
|||
}
|
||||
blk_id_ = blkid;
|
||||
++pending_;
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::get_block_data_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<Ref<BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load block "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_data, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_block_data_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<BlockData>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load block "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_data, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -646,16 +696,23 @@ bool LiteQuery::request_proof_link(BlockIdExt blkid) {
|
|||
});
|
||||
});
|
||||
} else {
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::get_block_proof_link_from_db_short, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<Ref<ProofLink>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load proof link for "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_proof_link, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_block_proof_link_from_db, R.move_as_ok(),
|
||||
[=](td::Result<Ref<ProofLink>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(
|
||||
Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load proof link for "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_block_proof_link, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -672,16 +729,22 @@ bool LiteQuery::request_zero_state(BlockIdExt blkid) {
|
|||
}
|
||||
blk_id_ = blkid;
|
||||
++pending_;
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::get_zero_state, blkid,
|
||||
[Self = actor_id(this), blkid](td::Result<td::BufferSlice> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load zerostate of "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_zero_state, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
get_block_handle_checked(blkid, [=, manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_zero_state, blkid,
|
||||
[=](td::Result<td::BufferSlice> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot load zerostate of "s + blkid.to_str() + " : "));
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::got_zero_state, blkid, res.move_as_ok());
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1397,6 +1460,11 @@ void LiteQuery::continue_getTransactions(unsigned remaining, bool exact) {
|
|||
td::actor::send_closure(Self, &LiteQuery::abort_getTransactions, res.move_as_error(), ton::BlockIdExt{});
|
||||
} else {
|
||||
auto handle = res.move_as_ok();
|
||||
if (!handle->is_applied()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_getTransactions, td::Status::Error("block is not applied"),
|
||||
ton::BlockIdExt{});
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG) << "requesting data for block " << handle->id().to_str();
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_block_data_from_db, handle,
|
||||
[Self, blkid = handle->id(), remaining](td::Result<Ref<BlockData>> res) {
|
||||
|
|
@ -1722,6 +1790,10 @@ void LiteQuery::perform_lookupBlock(BlockId blkid, int mode, LogicalTime lt, Uni
|
|||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
auto handle = res.move_as_ok();
|
||||
if (!handle->is_applied()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, td::Status::Error("block is not applied"));
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG) << "requesting data for block " << handle->id().to_str();
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_block_data_from_db, handle,
|
||||
[Self, blkid = handle->id(), mode](td::Result<Ref<BlockData>> res) {
|
||||
|
|
@ -2363,5 +2435,135 @@ void LiteQuery::continue_getValidatorStats(int mode, int limit, Bits256 start_af
|
|||
finish_query(std::move(b));
|
||||
}
|
||||
|
||||
void LiteQuery::perform_getShardBlockProof(BlockIdExt blkid) {
|
||||
LOG(INFO) << "started a getMasterchainInfo(" << blkid.to_str() << ") liteserver query";
|
||||
if (!blkid.is_valid_ext()) {
|
||||
fatal_error("invalid block id");
|
||||
return;
|
||||
}
|
||||
if (blkid.is_masterchain()) {
|
||||
LOG(INFO) << "getShardBlockProof() query completed";
|
||||
auto b = create_serialize_tl_object<lite_api::liteServer_shardBlockProof>(
|
||||
create_tl_lite_block_id(blkid), std::vector<tl_object_ptr<lite_api::liteServer_shardBlockLink>>());
|
||||
finish_query(std::move(b));
|
||||
return;
|
||||
}
|
||||
blk_id_ = blkid;
|
||||
get_block_handle_checked(blkid, [manager = manager_, Self = actor_id(this)](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
return;
|
||||
}
|
||||
ConstBlockHandle handle = R.move_as_ok();
|
||||
if (!handle->inited_masterchain_ref_block()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, td::Status::Error("block doesn't have masterchain ref"));
|
||||
return;
|
||||
}
|
||||
AccountIdPrefixFull pfx{masterchainId, shardIdAll};
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_block_by_seqno_from_db, pfx, handle->masterchain_ref_block(),
|
||||
[Self, manager](td::Result<ConstBlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
ConstBlockHandle handle = R.move_as_ok();
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_block_data_from_db, handle, [Self](td::Result<Ref<BlockData>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getShardBlockProof, R.move_as_ok(),
|
||||
std::vector<std::pair<BlockIdExt, td::BufferSlice>>());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void LiteQuery::continue_getShardBlockProof(Ref<BlockData> cur_block,
|
||||
std::vector<std::pair<BlockIdExt, td::BufferSlice>> result) {
|
||||
BlockIdExt cur_id = cur_block->block_id();
|
||||
BlockIdExt prev_id;
|
||||
vm::MerkleProofBuilder mpb{cur_block->root_cell()};
|
||||
if (cur_id.is_masterchain()) {
|
||||
base_blk_id_ = cur_id;
|
||||
block::gen::Block::Record blk;
|
||||
block::gen::BlockExtra::Record extra;
|
||||
block::gen::McBlockExtra::Record mc_extra;
|
||||
if (!tlb::unpack_cell(mpb.root(), blk) || !tlb::unpack_cell(blk.extra, extra) || !extra.custom->have_refs() ||
|
||||
!tlb::unpack_cell(extra.custom->prefetch_ref(), mc_extra)) {
|
||||
fatal_error("cannot unpack header of block "s + cur_id.to_str());
|
||||
return;
|
||||
}
|
||||
block::ShardConfig shards(mc_extra.shard_hashes->prefetch_ref());
|
||||
ShardIdFull shard_id = blk_id_.shard_full();
|
||||
shard_id.shard = (shard_id.shard & ~(1 << (63 - shard_id.pfx_len()))) | 1;
|
||||
Ref<block::McShardHash> shard_hash = shards.get_shard_hash(shard_id, false);
|
||||
if (shard_hash.is_null()) {
|
||||
fatal_error("shard not found");
|
||||
return;
|
||||
}
|
||||
prev_id = shard_hash->top_block_id();
|
||||
} else {
|
||||
std::vector<BlockIdExt> prev;
|
||||
BlockIdExt mc_blkid;
|
||||
bool after_split;
|
||||
td::Status S = block::unpack_block_prev_blk_try(mpb.root(), cur_id, prev, mc_blkid, after_split);
|
||||
if (S.is_error()) {
|
||||
fatal_error(std::move(S));
|
||||
return;
|
||||
}
|
||||
bool found = false;
|
||||
for (const BlockIdExt& id : prev) {
|
||||
if (shard_intersects(id.shard_full(), blk_id_.shard_full())) {
|
||||
found = true;
|
||||
prev_id = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fatal_error("failed to find block chain");
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto proof = mpb.extract_proof_boc();
|
||||
if (proof.is_error()) {
|
||||
fatal_error(proof.move_as_error_prefix("cannot serialize Merkle proof : "));
|
||||
return;
|
||||
}
|
||||
result.emplace_back(prev_id, proof.move_as_ok());
|
||||
|
||||
if (prev_id == blk_id_) {
|
||||
CHECK(base_blk_id_.is_masterchain());
|
||||
std::vector<tl_object_ptr<lite_api::liteServer_shardBlockLink>> links;
|
||||
for (auto& p : result) {
|
||||
links.push_back(
|
||||
create_tl_object<lite_api::liteServer_shardBlockLink>(create_tl_lite_block_id(p.first), std::move(p.second)));
|
||||
}
|
||||
LOG(INFO) << "getShardBlockProof() query completed";
|
||||
auto b = create_serialize_tl_object<lite_api::liteServer_shardBlockProof>(create_tl_lite_block_id(base_blk_id_),
|
||||
std::move(links));
|
||||
finish_query(std::move(b));
|
||||
return;
|
||||
}
|
||||
if (result.size() == 8) {
|
||||
// Chains of shardblocks between masterchain blocks can't be longer than 8 (see collator.cpp:991)
|
||||
fatal_error("proof chain is too long");
|
||||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::get_block_data_from_db_short, prev_id,
|
||||
[Self = actor_id(this), result = std::move(result)](td::Result<Ref<BlockData>> R) mutable {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getShardBlockProof, R.move_as_ok(),
|
||||
std::move(result));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
} // namespace ton
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ class LiteQuery : public td::actor::Actor {
|
|||
bool construct_proof_link_back_cont(ton::BlockIdExt cur, ton::BlockIdExt next);
|
||||
bool adjust_last_proof_link(ton::BlockIdExt cur, Ref<vm::Cell> block_root);
|
||||
bool finish_proof_chain(ton::BlockIdExt id);
|
||||
void perform_getShardBlockProof(BlockIdExt blkid);
|
||||
void continue_getShardBlockProof(Ref<BlockData> cur_block,
|
||||
std::vector<std::pair<BlockIdExt, td::BufferSlice>> result);
|
||||
|
||||
void load_prevKeyBlock(ton::BlockIdExt blkid, td::Promise<std::pair<BlockIdExt, Ref<BlockQ>>>);
|
||||
void continue_loadPrevKeyBlock(ton::BlockIdExt blkid, td::Result<std::pair<Ref<MasterchainState>, BlockIdExt>> res,
|
||||
|
|
@ -152,6 +155,7 @@ class LiteQuery : public td::actor::Actor {
|
|||
void finish_loadPrevKeyBlock(ton::BlockIdExt blkid, td::Result<Ref<BlockData>> res,
|
||||
td::Promise<std::pair<BlockIdExt, Ref<BlockQ>>> promise);
|
||||
|
||||
void get_block_handle_checked(BlockIdExt blkid, td::Promise<ConstBlockHandle> promise);
|
||||
bool request_block_data(BlockIdExt blkid);
|
||||
bool request_block_state(BlockIdExt blkid);
|
||||
bool request_block_data_state(BlockIdExt blkid);
|
||||
|
|
|
|||
|
|
@ -59,13 +59,16 @@ ValidateQuery::ValidateQuery(ShardIdFull shard, BlockIdExt min_masterchain_block
|
|||
, prev_blocks(std::move(prev))
|
||||
, block_candidate(std::move(candidate))
|
||||
, validator_set_(std::move(validator_set))
|
||||
, manager(std::move(manager))
|
||||
, manager(manager)
|
||||
, timeout(timeout)
|
||||
, main_promise(std::move(promise))
|
||||
, is_fake_(mode & ValidateMode::fake)
|
||||
, full_collated_data_(mode & ValidateMode::full_collated_data)
|
||||
, shard_pfx_(shard_.shard)
|
||||
, shard_pfx_len_(ton::shard_prefix_length(shard_)) {
|
||||
, shard_pfx_len_(ton::shard_prefix_length(shard_))
|
||||
, perf_timer_("validateblock", 0.1, [manager](double duration) {
|
||||
send_closure(manager, &ValidatorManager::add_perf_timer_stat, "validateblock", duration);
|
||||
}) {
|
||||
}
|
||||
|
||||
void ValidateQuery::alarm() {
|
||||
|
|
@ -2392,10 +2395,6 @@ bool ValidateQuery::precheck_one_account_update(td::ConstBitPtr acc_id, Ref<vm::
|
|||
"AccountBlock for this account");
|
||||
}
|
||||
if (new_value.not_null()) {
|
||||
if (!block::gen::t_ShardAccount.validate_csr(10000, new_value)) {
|
||||
return reject_query("new state of account "s + acc_id.to_hex(256) +
|
||||
" failed to pass automated validity checks for ShardAccount");
|
||||
}
|
||||
if (!block::tlb::t_ShardAccount.validate_csr(10000, new_value)) {
|
||||
return reject_query("new state of account "s + acc_id.to_hex(256) +
|
||||
" failed to pass hand-written validity checks for ShardAccount");
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ class ValidateQuery : public td::actor::Actor {
|
|||
|
||||
std::vector<std::tuple<Bits256, Bits256, bool>> lib_publishers_, lib_publishers2_;
|
||||
|
||||
td::PerfWarningTimer perf_timer_{"validateblock", 0.1};
|
||||
td::PerfWarningTimer perf_timer_;
|
||||
|
||||
static constexpr td::uint32 priority() {
|
||||
return 2;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue