mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
deleted unused code, support for logrotate, update in block validation code
This commit is contained in:
parent
2b734e170c
commit
47814dca3d
44 changed files with 175 additions and 4196 deletions
|
@ -480,7 +480,7 @@ struct BlockHandleImpl : public BlockHandleInterface {
|
|||
}
|
||||
BlockHandleImpl(td::BufferSlice data);
|
||||
~BlockHandleImpl() {
|
||||
CHECK(!need_flush());
|
||||
LOG_CHECK(!need_flush()) << "flags=" << flags_;
|
||||
get_thread_safe_counter().add(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
if (NOT OPENSSL_FOUND)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
|
||||
set(DUMMY_VALIDATOR_SOURCE
|
||||
accept-block.cpp
|
||||
fake-accept-block.cpp
|
||||
check-proof.cpp
|
||||
collate-query.cpp
|
||||
fabric.cpp
|
||||
shard.cpp
|
||||
signature-set.cpp
|
||||
top-shard-description.cpp
|
||||
validate-query.cpp
|
||||
validator-set.cpp
|
||||
|
||||
check-proof.hpp
|
||||
collate-query.hpp
|
||||
external-message.hpp
|
||||
proof.hpp
|
||||
shard.hpp
|
||||
signature-set.hpp
|
||||
top-shard-description.hpp
|
||||
validate-query.hpp
|
||||
validator-set.hpp
|
||||
)
|
||||
|
||||
add_library(dummy_validator STATIC ${DUMMY_VALIDATOR_SOURCE})
|
||||
|
||||
target_include_directories(dummy_validator PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/..
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/../crypto
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(dummy_validator PRIVATE tdutils tdactor adnl tl_api dht tdfec
|
||||
overlay catchain validatorsession ton_crypto ton_block)
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "accept-block.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
|
||||
#include "validator/fabric.h"
|
||||
#include "validator/invariants.hpp"
|
||||
|
||||
#include "top-shard-description.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void AcceptBlockQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting accept block " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::finish_query() {
|
||||
ValidatorInvariants::check_post_accept(handle_);
|
||||
if (promise_) {
|
||||
promise_.set_value(td::Unit());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
if (handle_->processed() && handle_->received() && handle_->received_state() && handle_->inited_signatures() &&
|
||||
handle_->inited_split_after() && handle_->inited_merge_before() && handle_->inited_prev() &&
|
||||
(id_.is_masterchain() ? handle_->inited_proof() : handle_->inited_proof_link())) {
|
||||
send_block_description();
|
||||
return;
|
||||
}
|
||||
if (data_.not_null() && !handle_->received()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
} else {
|
||||
written_block_data();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_data() {
|
||||
if (handle_->inited_signatures()) {
|
||||
written_block_signatures();
|
||||
return;
|
||||
}
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_signatures);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_signatures, handle_, signatures_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_signatures() {
|
||||
if (prev_.size() == 2) {
|
||||
handle_->set_merge(true);
|
||||
} else {
|
||||
handle_->set_merge(false);
|
||||
}
|
||||
|
||||
for (auto &p : prev_) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_info);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_info() {
|
||||
LOG(WARNING) << "written block info";
|
||||
if (data_.not_null()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
CHECK(prev_.size() <= 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_prev_block_state, handle_, timeout_, std::move(P));
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<BlockData>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::failed_to_get_block_candidate);
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_candidate_data_from_db, id_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::failed_to_get_block_candidate() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<BlockData>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_data, handle_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_block_data(td::Ref<BlockData> data) {
|
||||
data_ = std::move(data);
|
||||
if (handle_->received()) {
|
||||
written_block_info();
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_prev_state(td::Ref<ShardState> state) {
|
||||
LOG(WARNING) << "got prev state";
|
||||
state_ = std::move(state);
|
||||
|
||||
state_.write().apply_block(id_, data_).ensure();
|
||||
|
||||
handle_->set_split(state_->before_split());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_state);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_state, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_state() {
|
||||
LOG(WARNING) << "written state";
|
||||
|
||||
// generate proof
|
||||
|
||||
CHECK(prev_.size() == 1);
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto &p : prev_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
auto proof_link = create_tl_object<ton_api::test0_proofLink>(
|
||||
create_tl_block_id(id_), std::move(prev), Bits256_2_UInt256(state_->root_hash()), handle_->split_after());
|
||||
proof_link_ = create_proof_link(serialize_tl_object(proof_link, true)).move_as_ok();
|
||||
|
||||
if (id_.is_masterchain()) {
|
||||
auto proof = create_tl_object<ton_api::test0_proof>(
|
||||
std::move(proof_link), catchain_seqno_, validator_set_hash_,
|
||||
fetch_tl_object<ton_api::test0_blockSignatures>(signatures_->serialize(), true).move_as_ok());
|
||||
proof_ = create_proof(prev_[0], serialize_tl_object(proof, true)).move_as_ok();
|
||||
}
|
||||
|
||||
if (handle_->id().is_masterchain()) {
|
||||
CHECK(prev_.size() == 1);
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_next);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, prev_[0], id_, std::move(P));
|
||||
} else {
|
||||
written_block_next();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_next() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_proof);
|
||||
}
|
||||
});
|
||||
|
||||
if (id_.is_masterchain()) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
} else {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof_link, handle_, proof_link_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_proof() {
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_info_2);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info_2();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_info_2() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::send_block_description);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::new_block, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::send_block_description() {
|
||||
if (!handle_->id().is_masterchain()) {
|
||||
bool after_split = prev_.size() == 1 && handle_->id().id.shard != prev_[0].id.shard;
|
||||
if (after_split) {
|
||||
CHECK(shard_parent(handle_->id().shard_full()) == prev_[0].shard_full());
|
||||
}
|
||||
bool after_merge = prev_.size() == 2;
|
||||
|
||||
auto desc = td::Ref<ShardTopBlockDescriptionImpl>{true,
|
||||
handle_->id(),
|
||||
after_split,
|
||||
after_merge,
|
||||
handle_->split_after(),
|
||||
catchain_seqno_,
|
||||
validator_set_hash_,
|
||||
signatures_->serialize()};
|
||||
td::actor::send_closure(manager_, &ValidatorManager::send_top_shard_block_description, std::move(desc));
|
||||
}
|
||||
finish_query();
|
||||
}
|
||||
|
||||
AcceptBlockQuery::AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
UnixTime catchain_seqno, td::uint32 validator_set_hash,
|
||||
td::Ref<BlockSignatureSet> signatures, bool send_broadcast,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
|
||||
: id_(id)
|
||||
, data_(std::move(data))
|
||||
, prev_(std::move(prev))
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures))
|
||||
, send_broadcast_(send_broadcast)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
CHECK(prev_.size() > 0);
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
/*
|
||||
*
|
||||
* block data (if not given) can be obtained from:
|
||||
* db as part of collated block
|
||||
* db as block
|
||||
* net
|
||||
* must write block data, block signatures and block state
|
||||
* initialize prev, before_split, after_merge
|
||||
* for masterchain write block proof and set next for prev block
|
||||
* for masterchain run new_block callback
|
||||
*
|
||||
*/
|
||||
|
||||
class AcceptBlockQuery : public td::actor::Actor {
|
||||
public:
|
||||
AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev, CatchainSeqno catchain_seqno,
|
||||
td::uint32 validator_set_hash, td::Ref<BlockSignatureSet> signatures, bool send_broadcast,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void written_block_data();
|
||||
void written_block_signatures();
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void written_block_info();
|
||||
void failed_to_get_block_candidate();
|
||||
void got_block_data(td::Ref<BlockData> data);
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void written_state();
|
||||
void written_block_proof();
|
||||
void written_block_next();
|
||||
void written_block_info_2();
|
||||
void applied();
|
||||
void send_block_description();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<BlockData> data_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::Ref<BlockSignatureSet> signatures_;
|
||||
bool send_broadcast_;
|
||||
td::Timestamp timeout_ = td::Timestamp::in(600);
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Promise<td::Unit> promise_;
|
||||
|
||||
FileHash signatures_hash_;
|
||||
BlockHandle handle_;
|
||||
td::Ref<Proof> proof_;
|
||||
td::Ref<ProofLink> proof_link_;
|
||||
|
||||
td::Ref<ShardState> state_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/block.h"
|
||||
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
#include "ton/ton-types.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class Block : public BlockData {
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
BlockIdExt id_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return id_.file_hash;
|
||||
}
|
||||
BlockIdExt block_id() const override {
|
||||
return id_;
|
||||
}
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
return {};
|
||||
}
|
||||
Block *make_copy() const override {
|
||||
return new Block(id_, data_.clone());
|
||||
}
|
||||
Block(BlockIdExt id, td::BufferSlice data) : data_(std::move(data)), id_(id) {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "check-proof.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "validator/fabric.h"
|
||||
#include "validator/invariants.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void CheckProofLink::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CheckProofLink::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting check proof link for " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProofLink::finish_query() {
|
||||
ValidatorInvariants::check_post_check_proof_link(handle_);
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "checked proof link for " << handle_->id();
|
||||
promise_.set_result(handle_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProofLink::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_proofLink>(proof_->data(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
unserialized_proof_ = F.move_as_ok();
|
||||
if (create_block_id(unserialized_proof_->id_) != id_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "proof for wrong block"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void CheckProofLink::got_block_handle(BlockHandle handle) {
|
||||
// RUN CHECKS
|
||||
// SHOULD ONLY BE SOME MERKLE PROOFS
|
||||
// DUMMY0 DOES NOT DO IT
|
||||
|
||||
handle_ = std::move(handle);
|
||||
|
||||
std::vector<BlockIdExt> prev;
|
||||
for (auto &p : unserialized_proof_->prev_) {
|
||||
prev.push_back(create_block_id(p));
|
||||
}
|
||||
for (auto &p : prev) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
handle_->set_merge(prev.size() == 2);
|
||||
handle_->set_split(unserialized_proof_->split_);
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::finish_query);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof_link, handle_, proof_, std::move(P));
|
||||
}
|
||||
void CheckProof::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CheckProof::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting check proof for " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProof::finish_query() {
|
||||
ValidatorInvariants::check_post_check_proof(handle_);
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "checked proof for " << handle_->id();
|
||||
promise_.set_result(handle_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProof::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_proof>(proof_->data(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
unserialized_proof_ = F.move_as_ok();
|
||||
|
||||
auto proof_link_R = create_proof_link(serialize_tl_object(unserialized_proof_->link_, true));
|
||||
if (proof_link_R.is_error()) {
|
||||
abort_query(proof_link_R.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
run_check_proof_link_query(id_, proof_link_R.move_as_ok(), manager_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
if (handle_ && handle_->inited_proof()) {
|
||||
finish_query();
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::got_masterchain_state, td::Ref<MasterchainState>{R.move_as_ok()});
|
||||
}
|
||||
});
|
||||
CHECK(!handle_->merge_before());
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, handle_->one_prev(true), timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::got_masterchain_state(td::Ref<MasterchainState> state) {
|
||||
state_ = std::move(state);
|
||||
|
||||
auto s = state_->get_validator_set(id_.shard_full());
|
||||
if (s->get_catchain_seqno() != static_cast<CatchainSeqno>(unserialized_proof_->catchain_seqno_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (s->get_validator_set_hash() != static_cast<td::uint32>(unserialized_proof_->validator_set_hash_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<BlockSignature> vec;
|
||||
for (auto &v : unserialized_proof_->signatures_->signatures_) {
|
||||
vec.emplace_back(BlockSignature{UInt256_2_Bits256(v->who_), std::move(v->signature_)});
|
||||
}
|
||||
|
||||
auto sigs = create_signature_set(std::move(vec));
|
||||
|
||||
auto S = s->check_signatures(id_.root_hash, id_.file_hash, sigs);
|
||||
if (S.is_error()) {
|
||||
abort_query(S.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::set_next);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, handle_->one_prev(true), handle_->id(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::set_next() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::finish_query);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/interfaces/block-handle.h"
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
/*
|
||||
*
|
||||
* check block proof
|
||||
* write proof
|
||||
* initialize prev, before_split, after_merge
|
||||
* initialize prev's next
|
||||
*
|
||||
*/
|
||||
|
||||
class CheckProofLink : public td::actor::Actor {
|
||||
public:
|
||||
CheckProofLink(BlockIdExt id, td::Ref<ProofLink> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise)
|
||||
: id_(id), proof_(std::move(proof)), manager_(manager), timeout_(timeout), promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_block_handle(BlockHandle handle);
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<ProofLink> proof_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockHandle> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
tl_object_ptr<ton_api::test0_proofLink> unserialized_proof_;
|
||||
};
|
||||
|
||||
class CheckProof : public td::actor::Actor {
|
||||
public:
|
||||
CheckProof(BlockIdExt id, td::Ref<Proof> proof, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockHandle> promise)
|
||||
: id_(id), proof_(std::move(proof)), manager_(manager), timeout_(timeout), promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void got_masterchain_state(td::Ref<MasterchainState> state);
|
||||
void set_next();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<Proof> proof_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockHandle> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
td::Ref<MasterchainState> state_;
|
||||
tl_object_ptr<ton_api::test0_proof> unserialized_proof_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "collate-query.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "td/utils/Random.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "shard.hpp"
|
||||
#include "validator/fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void CollateQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting collate query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
void CollateQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(std::move(candidate_));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CollateQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CollateQuery::start_up() {
|
||||
//CHECK(shard_.workchain == masterchainId);
|
||||
//CHECK(shard_.shard == shardIdAll);
|
||||
LOG(WARNING) << "collate query: prev=" << prev_.size() << " ts=" << validator_set_->get_catchain_seqno();
|
||||
|
||||
alarm_timestamp() = timeout_;
|
||||
ts_ = static_cast<UnixTime>(td::Clocks::system());
|
||||
if (ts_ < min_ts_) {
|
||||
ts_ = min_ts_;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
if (prev_.size() == 1) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, prev_[0], timeout_, std::move(P));
|
||||
} else {
|
||||
CHECK(prev_.size() == 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_merge, prev_[0], prev_[1], timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void CollateQuery::got_prev_state(td::Ref<ShardState> recv_state) {
|
||||
prev_state_ = td::Ref<ShardStateImpl>{std::move(recv_state)};
|
||||
CHECK(prev_state_.not_null());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<MasterchainState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_masterchain_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_top_masterchain_state, std::move(P));
|
||||
}
|
||||
|
||||
void CollateQuery::got_masterchain_state(td::Ref<MasterchainState> state) {
|
||||
masterchain_state_ = std::move(state);
|
||||
|
||||
if (masterchain_state_->get_block_id() < min_masterchain_block_id_) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_masterchain_state,
|
||||
td::Ref<MasterchainState>{R.move_as_ok()});
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, min_masterchain_block_id_, timeout_,
|
||||
std::move(P));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shard_.is_masterchain()) {
|
||||
generate();
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[SelfId = actor_id(this)](td::Result<std::vector<td::Ref<ShardTopBlockDescription>>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_shard_messages, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_shard_blocks, prev_[0], std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void CollateQuery::generate() {
|
||||
BlockSeqno seqno;
|
||||
if (prev_.size() == 1) {
|
||||
seqno = prev_[0].id.seqno + 1;
|
||||
} else {
|
||||
CHECK(prev_.size() == 2);
|
||||
seqno = std::max(prev_[0].id.seqno, prev_[1].id.seqno) + 1;
|
||||
}
|
||||
|
||||
if (shard_.is_masterchain()) {
|
||||
if (seqno <= masterchain_state_->get_seqno()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "generating block, but newer already accepted"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto v = masterchain_state_->get_validator_set(shard_);
|
||||
if (v->get_catchain_seqno() != validator_set_->get_catchain_seqno()) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set"));
|
||||
return;
|
||||
}
|
||||
CHECK(v->get_validator_set_hash() == validator_set_->get_validator_set_hash());
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto& p : prev_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
auto data = td::BufferSlice{10000};
|
||||
td::Random::secure_bytes(data.as_slice());
|
||||
|
||||
auto block = create_tl_object<ton_api::test0_shardchain_block>(
|
||||
shard_.workchain, shard_.shard, seqno, std::move(prev), false, ts_, td::UInt256::zero(),
|
||||
validator_set_->get_catchain_seqno(), validator_set_->get_validator_set_hash(), std::move(data),
|
||||
create_tl_object<ton_api::test0_masterchainBlockExtra_empty>());
|
||||
|
||||
if (shard_.is_masterchain()) {
|
||||
auto m_state = td::Ref<MasterchainStateImpl>{prev_state_};
|
||||
|
||||
bool rotate = ts_ >= m_state->next_validator_rotate_at();
|
||||
|
||||
auto x = create_tl_object<ton_api::test0_masterchainBlockExtra_extra>(td::Random::fast_uint32(), rotate,
|
||||
std::move(shards_));
|
||||
block->extra_ = std::move(x);
|
||||
}
|
||||
|
||||
Bits256 x;
|
||||
x.set_zero();
|
||||
auto block_R =
|
||||
create_block(BlockIdExt{shard_.workchain, shard_.shard, seqno, x, x}, serialize_tl_object(block, true));
|
||||
if (block_R.is_error()) {
|
||||
abort_query(block_R.move_as_error());
|
||||
return;
|
||||
}
|
||||
auto s =
|
||||
prev_state_.write().apply_block(BlockIdExt{shard_.workchain, shard_.shard, seqno, x, x}, block_R.move_as_ok());
|
||||
if (s.is_error()) {
|
||||
abort_query(std::move(s));
|
||||
return;
|
||||
}
|
||||
block->state_ = Bits256_2_UInt256(prev_state_->root_hash());
|
||||
|
||||
auto B = serialize_tl_object(block, true);
|
||||
auto file_hash = UInt256_2_Bits256(sha256_uint256(B.as_slice()));
|
||||
auto root_hash = file_hash;
|
||||
|
||||
auto collated_data = td::BufferSlice{10000};
|
||||
td::Random::secure_bytes(collated_data.as_slice());
|
||||
auto collated_data_file_hash = UInt256_2_Bits256(sha256_uint256(collated_data.as_slice()));
|
||||
|
||||
candidate_.collated_data = std::move(collated_data);
|
||||
candidate_.collated_file_hash = collated_data_file_hash;
|
||||
candidate_.data = std::move(B);
|
||||
candidate_.id = BlockIdExt{BlockId{shard_.workchain, shard_.shard, seqno}, root_hash, file_hash};
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::finish_query);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_candidate, candidate_.id, candidate_.clone(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CollateQuery::got_shard_messages(std::vector<td::Ref<ShardTopBlockDescription>> shards) {
|
||||
for (auto& s : shards) {
|
||||
// TODO validate
|
||||
shards_.emplace_back(create_tl_object<ton_api::test0_masterchain_shardInfo>(
|
||||
create_tl_block_id(s->block_id()), false, s->before_split(), false, false));
|
||||
}
|
||||
generate();
|
||||
}
|
||||
|
||||
CollateQuery::CollateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise)
|
||||
: shard_(shard)
|
||||
, min_ts_(min_ts)
|
||||
, min_masterchain_block_id_{min_masterchain_block_id}
|
||||
, prev_(std::move(prev))
|
||||
, validator_set_(std::move(validator_set))
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
#include "shard.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class CollateQuery : public td::actor::Actor {
|
||||
public:
|
||||
CollateQuery(ShardIdFull shard, td::uint32 min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise);
|
||||
|
||||
void alarm() override;
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
|
||||
void start_up() override;
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void got_masterchain_state(td::Ref<MasterchainState> state);
|
||||
void got_shard_messages(std::vector<td::Ref<ShardTopBlockDescription>> shards);
|
||||
void generate();
|
||||
void written_block_data();
|
||||
void written_block_collated_data();
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
UnixTime min_ts_;
|
||||
BlockIdExt min_masterchain_block_id_;
|
||||
|
||||
std::vector<BlockIdExt> prev_;
|
||||
td::Ref<ValidatorSet> validator_set_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockCandidate> promise_;
|
||||
|
||||
td::Ref<MasterchainState> masterchain_state_;
|
||||
td::Ref<ShardStateImpl> prev_state_;
|
||||
|
||||
BlockCandidate candidate_;
|
||||
UnixTime ts_;
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_masterchain_shardInfo>> shards_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/external-message.h"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ExtMessageImpl : public ExtMessage {
|
||||
public:
|
||||
AccountIdPrefixFull shard() const override {
|
||||
return shard_;
|
||||
}
|
||||
td::BufferSlice serialize() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
Hash hash() const override {
|
||||
return hash_;
|
||||
}
|
||||
|
||||
ExtMessageImpl *make_copy() const override {
|
||||
return new ExtMessageImpl{shard_, data_.clone(), hash_};
|
||||
}
|
||||
|
||||
ExtMessageImpl(AccountIdPrefixFull shard, td::BufferSlice data, Hash hash)
|
||||
: shard_(shard), data_(std::move(data)), hash_(hash) {
|
||||
}
|
||||
|
||||
ExtMessageImpl(tl_object_ptr<ton_api::test0_extMessage> data) {
|
||||
data_ = serialize_tl_object(data, true);
|
||||
hash_ = UInt256_2_Bits256(get_tl_object_sha256(data));
|
||||
shard_ = AccountIdPrefixFull{data->workchain_, static_cast<AccountIdPrefix>(data->shard_)};
|
||||
}
|
||||
|
||||
private:
|
||||
AccountIdPrefixFull shard_;
|
||||
td::BufferSlice data_;
|
||||
Hash hash_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validator/fabric.h"
|
||||
#include "block.hpp"
|
||||
#include "external-message.hpp"
|
||||
#include "proof.hpp"
|
||||
#include "signature-set.hpp"
|
||||
#include "shard.hpp"
|
||||
#include "accept-block.hpp"
|
||||
#include "fake-accept-block.hpp"
|
||||
#include "check-proof.hpp"
|
||||
#include "collate-query.hpp"
|
||||
#include "validate-query.hpp"
|
||||
#include "top-shard-description.hpp"
|
||||
|
||||
#include "validator/db/rootdb.hpp"
|
||||
#include "validator/block-handle.hpp"
|
||||
#include "validator/apply-block.hpp"
|
||||
|
||||
#include "td/utils/Random.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
td::actor::ActorOwn<Db> create_db_actor(td::actor::ActorId<ValidatorManager> manager, std::string db_root_) {
|
||||
return td::actor::create_actor<RootDb>("db", manager, db_root_);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockData>> create_block(BlockIdExt block_id, td::BufferSlice data) {
|
||||
return td::Ref<dummy0::Block>{true, block_id, std::move(data)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockData>> create_block(ReceivedBlock data) {
|
||||
return td::Ref<dummy0::Block>{true, data.id, std::move(data.data)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<Proof>> create_proof(BlockIdExt masterchain_block_id, td::BufferSlice proof) {
|
||||
return td::Ref<dummy0::ProofImpl>{true, masterchain_block_id, std::move(proof)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ProofLink>> create_proof_link(td::BufferSlice proof) {
|
||||
return td::Ref<dummy0::ProofLinkImpl>{true, std::move(proof)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockSignatureSet>> create_signature_set(td::BufferSlice sig_set) {
|
||||
return dummy0::BlockSignatureSetImpl::fetch(std::move(sig_set));
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> create_shard_state(BlockIdExt block_id, td::BufferSlice data) {
|
||||
return dummy0::ShardStateImpl::fetch(block_id, std::move(data));
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> create_shard_state(BlockIdExt block_id, td::Ref<vm::DataCell> root_cell) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
td::Result<BlockHandle> create_block_handle(td::BufferSlice data) {
|
||||
return ton::validator::BlockHandleImpl::create(std::move(data));
|
||||
}
|
||||
|
||||
BlockHandle create_empty_block_handle(BlockIdExt id) {
|
||||
return ton::validator::BlockHandleImpl::create_empty(id);
|
||||
}
|
||||
|
||||
//td::Ref<McShardHash> create_mc_shard(ShardIdFull id, ZeroStateIdExt zero_top_block) {
|
||||
// return td::Ref<dummy0::McShardHashImpl>{true, zero_top_block};
|
||||
//}
|
||||
|
||||
td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_set) {
|
||||
return td::Ref<dummy0::BlockSignatureSetImpl>{true, std::move(sig_set)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data) {
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_extMessage>(std::move(data), true));
|
||||
return td::Ref<dummy0::ExtMessageImpl>{true, std::move(B)};
|
||||
}
|
||||
|
||||
void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
bool send_broadcast, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<dummy0::AcceptBlockQuery>(
|
||||
"accept", id, std::move(data), prev, validator_set->get_catchain_seqno(), validator_set->get_validator_set_hash(),
|
||||
std::move(signatures), send_broadcast, manager, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_fake_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<FakeAcceptBlockQuery>("fakeaccept", id, std::move(data), std::move(prev), 0, 0,
|
||||
td::Ref<BlockSignatureSet>{}, std::move(manager), std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<ApplyBlock>("apply", id, std::move(block), manager, timeout, std::move(promise)).release();
|
||||
}
|
||||
|
||||
void run_check_proof_query(BlockIdExt id, td::Ref<Proof> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise) {
|
||||
td::actor::create_actor<dummy0::CheckProof>("checkproof", id, std::move(proof), manager, timeout, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_check_proof_link_query(BlockIdExt id, td::Ref<ProofLink> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise) {
|
||||
td::actor::create_actor<dummy0::CheckProofLink>("checkprooflink", id, std::move(proof), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, BlockCandidate candidate, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<ValidateCandidateResult> promise) {
|
||||
td::actor::create_actor<dummy0::ValidateQuery>(
|
||||
"validateblock", shard, min_ts, min_masterchain_block_id, std::move(prev), std::move(candidate),
|
||||
validator_set->get_catchain_seqno(), validator_set->get_validator_set_hash(), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise) {
|
||||
td::actor::create_actor<dummy0::CollateQuery>("collator", shard, min_ts, min_masterchain_block_id, std::move(prev),
|
||||
std::move(validator_set), manager, timeout, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_liteserver_query(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
LOG(ERROR) << "answering";
|
||||
promise.set_value(serialize_tl_object(create_tl_object<ton_api::testInt>(td::Random::fast_uint32()), true));
|
||||
}
|
||||
|
||||
void run_validate_shard_block_description(td::BufferSlice data, BlockHandle masterchain_block,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise, bool is_fake) {
|
||||
td::actor::create_actor<dummy0::ValidateShardTopBlockDescription>(
|
||||
"topshardfetch", std::move(data), std::move(masterchain_block), std::move(masterchain_state), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "fake-accept-block.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "interfaces/validator-manager.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
#include "fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
void FakeAcceptBlockQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting accept block query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(td::Unit());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
CHECK(!handle_->received());
|
||||
CHECK(data_.not_null());
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_data() {
|
||||
written_block_signatures();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_signatures() {
|
||||
if (prev_.size() == 2) {
|
||||
handle_->set_merge(true);
|
||||
} else {
|
||||
handle_->set_merge(false);
|
||||
}
|
||||
|
||||
for (auto &p : prev_) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_info);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info();
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_info() {
|
||||
LOG(WARNING) << "written block info";
|
||||
CHECK(handle_->received());
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
CHECK(prev_.size() <= 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_prev_block_state, handle_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::got_prev_state(td::Ref<ShardState> state) {
|
||||
LOG(WARNING) << "got prev state";
|
||||
state_ = std::move(state);
|
||||
|
||||
state_.write().apply_block(id_, data_).ensure();
|
||||
|
||||
handle_->set_split(state_->before_split());
|
||||
|
||||
handle_->set_state_root_hash(state_->root_hash());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_state);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_state, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_state() {
|
||||
LOG(WARNING) << "written state";
|
||||
if (!id_.id.is_masterchain()) {
|
||||
finish_query();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate proof
|
||||
|
||||
CHECK(prev_.size() == 1);
|
||||
proof_ = create_proof(prev_[0], td::BufferSlice()).move_as_ok();
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_proof);
|
||||
}
|
||||
});
|
||||
//handle_->set_masterchain_block(prev_[0]);
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_proof() {
|
||||
CHECK(prev_.size() <= 1);
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_next);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, prev_[0], id_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_next() {
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_info_2);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info_2();
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_info_2() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::finish_query);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::new_block, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
FakeAcceptBlockQuery::FakeAcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
UnixTime validator_set_ts, td::uint32 validator_set_hash,
|
||||
td::Ref<BlockSignatureSet> signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
|
||||
: id_(id)
|
||||
, data_(std::move(data))
|
||||
, prev_(std::move(prev))
|
||||
, validator_set_ts_(validator_set_ts)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures))
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
CHECK(prev_.size() > 0);
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
/*
|
||||
*
|
||||
* block data (if not given) can be obtained from:
|
||||
* db as part of collated block
|
||||
* db as block
|
||||
* net
|
||||
* must write block data, block signatures and block state
|
||||
* initialize prev, before_split, after_merge
|
||||
* for masterchain write block proof and set next for prev block
|
||||
* for masterchain run new_block callback
|
||||
*
|
||||
*/
|
||||
|
||||
class FakeAcceptBlockQuery : public td::actor::Actor {
|
||||
public:
|
||||
FakeAcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev, UnixTime validator_set_ts,
|
||||
td::uint32 validator_set_hash, td::Ref<BlockSignatureSet> signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void written_block_data();
|
||||
void written_block_signatures();
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void written_block_info();
|
||||
void failed_to_get_block_candidate();
|
||||
void got_block_data(td::Ref<BlockData> data);
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void written_state();
|
||||
void written_block_proof();
|
||||
void written_block_next();
|
||||
void written_block_info_2();
|
||||
void applied();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<BlockData> data_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
UnixTime validator_set_ts_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::Ref<BlockSignatureSet> signatures_;
|
||||
td::Timestamp timeout_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Promise<td::Unit> promise_;
|
||||
|
||||
FileHash signatures_hash_;
|
||||
BlockHandle handle_;
|
||||
FileHash proof_hash_;
|
||||
td::Ref<Proof> proof_;
|
||||
|
||||
td::Ref<ShardState> state_;
|
||||
};
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/proof.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ProofImpl : public ton::validator::Proof {
|
||||
private:
|
||||
BlockIdExt masterchain_block_id_;
|
||||
td::BufferSlice data_;
|
||||
FileHash file_hash_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return file_hash_;
|
||||
}
|
||||
BlockIdExt masterchain_block_id() const override {
|
||||
return masterchain_block_id_;
|
||||
}
|
||||
|
||||
ProofImpl *make_copy() const override {
|
||||
return new ProofImpl(masterchain_block_id_, data_.clone(), file_hash_);
|
||||
}
|
||||
ProofImpl(BlockIdExt masterchain_block_id, td::BufferSlice data, FileHash file_hash)
|
||||
: masterchain_block_id_(masterchain_block_id), data_(std::move(data)), file_hash_(file_hash) {
|
||||
}
|
||||
ProofImpl(BlockIdExt masterchain_block_id, td::BufferSlice data)
|
||||
: masterchain_block_id_(masterchain_block_id), data_(std::move(data)) {
|
||||
file_hash_ = UInt256_2_Bits256(sha256_uint256(data_.as_slice()));
|
||||
}
|
||||
};
|
||||
|
||||
class ProofLinkImpl : public ton::validator::ProofLink {
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
FileHash file_hash_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return file_hash_;
|
||||
}
|
||||
ProofLinkImpl *make_copy() const override {
|
||||
return new ProofLinkImpl(data_.clone(), file_hash_);
|
||||
}
|
||||
ProofLinkImpl(td::BufferSlice data, FileHash file_hash) : data_(std::move(data)), file_hash_(file_hash) {
|
||||
}
|
||||
ProofLinkImpl(td::BufferSlice data) : data_(std::move(data)) {
|
||||
file_hash_ = UInt256_2_Bits256(sha256_uint256(data_.as_slice()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,324 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "shard.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "validator-set.hpp"
|
||||
#include "validator/interfaces/block.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
td::Ref<ton::validator::ValidatorSet> MasterchainStateImpl::calculate_validator_set(ShardIdFull shard, td::uint32 cnt,
|
||||
UnixTime ts,
|
||||
td::uint32 randseed) const {
|
||||
auto hash = ts ^ randseed;
|
||||
auto hash2 = 1000000007;
|
||||
|
||||
auto idx = hash % validators_.size();
|
||||
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> vec;
|
||||
std::map<NodeIdShort, size_t> m;
|
||||
while (cnt-- > 0) {
|
||||
auto &d = validators_[idx];
|
||||
auto id = d.short_id();
|
||||
auto it = m.find(id);
|
||||
if (it != m.end()) {
|
||||
vec[it->second].second++;
|
||||
} else {
|
||||
vec.emplace_back(d, 1);
|
||||
m[id] = vec.size() - 1;
|
||||
}
|
||||
idx = (idx + hash2) % validators_.size();
|
||||
}
|
||||
|
||||
return td::Ref<ValidatorSetImpl>{true, ts, shard.shard, std::move(vec)};
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_validator_set(ShardIdFull shard) const {
|
||||
//CHECK(shard.is_masterchain());
|
||||
return calculate_validator_set(shard, 200, cur_validator_ts_, cur_randseed_);
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_next_validator_set(ShardIdFull shard) const {
|
||||
//CHECK(shard.is_masterchain());
|
||||
return calculate_validator_set(shard, 200, cur_validator_ts_ + 1, next_randseed_);
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_validator_set(ShardIdFull shard, UnixTime ts) const {
|
||||
if (ts == cur_validator_ts_) {
|
||||
return get_validator_set(shard);
|
||||
} else if (ts == cur_validator_ts_ + 1) {
|
||||
return get_next_validator_set(shard);
|
||||
} else {
|
||||
return td::Ref<ValidatorSet>{};
|
||||
}
|
||||
}
|
||||
|
||||
td::Status MasterchainStateImpl::apply_block(BlockIdExt id, td::Ref<BlockData> block) {
|
||||
TRY_STATUS(ShardStateImpl::apply_block(id, block));
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_shardchain_block>(block->data(), true));
|
||||
|
||||
if (B->extra_->get_id() != ton_api::test0_masterchainBlockExtra_extra::ID) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad block extra");
|
||||
}
|
||||
auto E = static_cast<const ton_api::test0_masterchainBlockExtra_extra *>(B->extra_.get());
|
||||
|
||||
if (B->prev_.size() != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad prev size");
|
||||
}
|
||||
auto prev = create_block_id(B->prev_[0]);
|
||||
CHECK(prev.id.seqno == prev_blocks_.size());
|
||||
prev_blocks_.push_back(prev);
|
||||
|
||||
if (E->rotate_) {
|
||||
CHECK(static_cast<UnixTime>(B->ts_) >= next_validator_rotate_at_);
|
||||
next_validator_rotate_at_ = B->ts_ + 300;
|
||||
cur_validator_ts_++;
|
||||
cur_randseed_ = next_randseed_;
|
||||
next_randseed_ = E->randseed_;
|
||||
} else {
|
||||
CHECK(static_cast<UnixTime>(B->ts_) < next_validator_rotate_at_);
|
||||
}
|
||||
|
||||
for (auto &shard : E->shards_) {
|
||||
ShardDescr S{shard};
|
||||
auto shard_B = S.top_block;
|
||||
if (shard_B.id.seqno == 0) {
|
||||
for (auto &X : shards_) {
|
||||
if (X.top_block.id.workchain == shard_B.id.workchain) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad new block: duplicate zero block");
|
||||
}
|
||||
}
|
||||
shards_.emplace(std::move(S));
|
||||
} else {
|
||||
if (S.after_split) {
|
||||
if (S.top_block.id.shard == shardIdAll) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "cannot merge fullshard");
|
||||
}
|
||||
auto L = S;
|
||||
L.top_block.id.shard = shard_parent(S.top_block.id.shard);
|
||||
if (shards_.count(L) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown parent shard");
|
||||
}
|
||||
shards_.erase(L);
|
||||
shards_.emplace(std::move(S));
|
||||
} else if (S.after_merge) {
|
||||
auto L = S;
|
||||
L.top_block.id.shard = shard_child(S.top_block.id.shard, true);
|
||||
if (shards_.count(L) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown child L shard");
|
||||
}
|
||||
auto R = S;
|
||||
R.top_block.id.shard = shard_child(S.top_block.id.shard, false);
|
||||
if (shards_.count(R) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown child R shard");
|
||||
}
|
||||
shards_.erase(L);
|
||||
shards_.erase(R);
|
||||
shards_.emplace(std::move(S));
|
||||
} else {
|
||||
if (shards_.count(S) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown shard");
|
||||
}
|
||||
shards_.erase(S);
|
||||
shards_.emplace(std::move(S));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Result<td::BufferSlice> MasterchainStateImpl::serialize() const {
|
||||
TRY_RESULT(B, ShardStateImpl::serialize());
|
||||
auto F = fetch_tl_object<ton_api::test0_shardchain_state>(std::move(B), true).move_as_ok();
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::PublicKey>> pool;
|
||||
for (auto &v : validators_) {
|
||||
pool.emplace_back(v.tl());
|
||||
}
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto &p : prev_blocks_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_masterchain_shardInfo>> shards;
|
||||
for (auto &shard : shards_) {
|
||||
shards.emplace_back(shard.tl());
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::test0_masterchainStateExtra_extra>(
|
||||
cur_validator_ts_, cur_randseed_, next_randseed_, next_validator_rotate_at_, std::move(prev), std::move(shards),
|
||||
std::move(pool));
|
||||
F->extra_ = std::move(obj);
|
||||
return serialize_tl_object(F, true);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<MasterchainState>> MasterchainStateImpl::fetch(BlockIdExt block_id, td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_shardchain_state>(std::move(data), true));
|
||||
|
||||
return td::Ref<MasterchainStateImpl>{true, F, block_id};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> ShardStateImpl::fetch(BlockIdExt block_id, td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_shardchain_state>(std::move(data), true));
|
||||
|
||||
if (block_id.id.workchain == masterchainId) {
|
||||
return td::Ref<MasterchainStateImpl>{true, F, block_id};
|
||||
} else {
|
||||
return td::Ref<ShardStateImpl>{true, F, block_id};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<td::Ref<McShardHash>> MasterchainStateImpl::get_shards() const {
|
||||
std::vector<td::Ref<McShardHash>> shards;
|
||||
for (auto &shard : shards_) {
|
||||
shards.emplace_back(shard.mc_shard());
|
||||
}
|
||||
return shards;
|
||||
}
|
||||
|
||||
MasterchainStateImpl::MasterchainStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state,
|
||||
BlockIdExt block_id)
|
||||
: ShardStateImpl{state, block_id} {
|
||||
CHECK(state->extra_->get_id() == ton_api::test0_masterchainStateExtra_extra::ID);
|
||||
auto E = static_cast<const ton_api::test0_masterchainStateExtra_extra *>(state->extra_.get());
|
||||
|
||||
cur_validator_ts_ = E->validator_ts_;
|
||||
cur_randseed_ = E->validator_randseed_;
|
||||
next_randseed_ = E->next_randseed_;
|
||||
next_validator_rotate_at_ = E->next_rotate_at_;
|
||||
|
||||
for (auto &v : E->pool_) {
|
||||
validators_.emplace_back(PublicKey{v});
|
||||
}
|
||||
|
||||
for (auto &p : E->prev_blocks_) {
|
||||
prev_blocks_.push_back(create_block_id(p));
|
||||
}
|
||||
|
||||
for (auto &shard : E->shards_) {
|
||||
shards_.emplace(shard);
|
||||
}
|
||||
}
|
||||
|
||||
bool MasterchainStateImpl::ancestor_is_valid(BlockIdExt id) const {
|
||||
if (id.id.seqno > get_seqno()) {
|
||||
return false;
|
||||
}
|
||||
if (id.id.seqno == get_seqno()) {
|
||||
return get_block_id() == id;
|
||||
}
|
||||
return prev_blocks_[id.id.seqno] == id;
|
||||
}
|
||||
|
||||
MasterchainStateImpl::ShardDescr::ShardDescr(const tl_object_ptr<ton_api::test0_masterchain_shardInfo> &from) {
|
||||
top_block = create_block_id(from->last_block_);
|
||||
before_merge = from->before_merge_;
|
||||
before_split = from->before_split_;
|
||||
after_merge = from->after_merge_;
|
||||
after_split = from->after_split_;
|
||||
}
|
||||
tl_object_ptr<ton_api::test0_masterchain_shardInfo> MasterchainStateImpl::ShardDescr::tl() const {
|
||||
return create_tl_object<ton_api::test0_masterchain_shardInfo>(create_tl_block_id(top_block), before_merge,
|
||||
before_split, after_merge, after_split);
|
||||
}
|
||||
td::Ref<McShardHash> MasterchainStateImpl::ShardDescr::mc_shard() const {
|
||||
return td::Ref<McShardHashImpl>{true, top_block, before_split, before_merge};
|
||||
}
|
||||
|
||||
RootHash ShardStateImpl::root_hash() const {
|
||||
auto h = sha256_uint256(serialize().move_as_ok());
|
||||
return UInt256_2_Bits256(h);
|
||||
}
|
||||
|
||||
td::Result<td::BufferSlice> ShardStateImpl::serialize() const {
|
||||
auto obj =
|
||||
create_tl_object<ton_api::test0_shardchain_state>(shard_.workchain, shard_.shard, seqno_, ts_, before_split_,
|
||||
create_tl_object<ton_api::test0_masterchainStateExtra_empty>());
|
||||
return serialize_tl_object(obj, true);
|
||||
}
|
||||
|
||||
td::Status ShardStateImpl::apply_block(BlockIdExt id, td::Ref<BlockData> block) {
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_shardchain_block>(block->data(), true));
|
||||
if (static_cast<BlockSeqno>(B->seqno_) != seqno_ + 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad seqno");
|
||||
}
|
||||
if (static_cast<UnixTime>(B->ts_) <= ts_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "time goes back");
|
||||
}
|
||||
if (B->workchain_ != shard_.workchain) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad workchain");
|
||||
}
|
||||
if (static_cast<ShardId>(B->shard_) != shard_.shard) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad shard");
|
||||
}
|
||||
seqno_++;
|
||||
ts_ = B->ts_;
|
||||
before_split_ = B->split_;
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
ShardStateImpl::ShardStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id) {
|
||||
blocks_id_ = {block_id};
|
||||
shard_ = ShardIdFull{state->workchain_, static_cast<ShardId>(state->shard_)};
|
||||
seqno_ = state->seqno_;
|
||||
ts_ = state->ts_;
|
||||
|
||||
before_split_ = state->split_;
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> ShardStateImpl::merge_with(const ShardState &with) const {
|
||||
auto &x = dynamic_cast<const ShardStateImpl &>(with);
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
CHECK(x.blocks_id_.size() == 1);
|
||||
|
||||
return td::Ref<ShardStateImpl>{true,
|
||||
shard_parent(shard_),
|
||||
std::max(seqno_, x.seqno_),
|
||||
std::max(ts_, x.ts_),
|
||||
false,
|
||||
std::vector<BlockIdExt>{blocks_id_[0], x.blocks_id_[0]}};
|
||||
}
|
||||
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> ShardStateImpl::split() const {
|
||||
if (!before_split_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "split flag not raised");
|
||||
}
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
|
||||
auto L = td::Ref<ShardStateImpl>{
|
||||
true, shard_child(shard_, true), seqno_, ts_, false, std::vector<BlockIdExt>{blocks_id_[0]}};
|
||||
auto R = td::Ref<ShardStateImpl>{
|
||||
true, shard_child(shard_, false), seqno_, ts_, false, std::vector<BlockIdExt>{blocks_id_[0]}};
|
||||
|
||||
return std::pair<td::Ref<ShardState>, td::Ref<ShardState>>{L, R};
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class McShardHashImpl : public McShardHash {
|
||||
public:
|
||||
BlockIdExt top_block_id() const override {
|
||||
return id_;
|
||||
}
|
||||
LogicalTime start_lt() const override {
|
||||
return 0;
|
||||
}
|
||||
LogicalTime end_lt() const override {
|
||||
return 0;
|
||||
}
|
||||
UnixTime fsm_utime() const override {
|
||||
return 0;
|
||||
}
|
||||
FsmState fsm_state() const override {
|
||||
return split_ ? FsmState::fsm_split : merge_ ? FsmState::fsm_merge : FsmState::fsm_none;
|
||||
}
|
||||
bool before_split() const override {
|
||||
return split_;
|
||||
}
|
||||
bool before_merge() const override {
|
||||
return merge_;
|
||||
}
|
||||
ShardIdFull shard() const override {
|
||||
return id_.shard_full();
|
||||
}
|
||||
|
||||
McShardHashImpl(BlockIdExt id, bool split, bool merge) : id_{id}, split_(split), merge_(merge) {
|
||||
}
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
bool split_;
|
||||
bool merge_;
|
||||
};
|
||||
|
||||
class ShardStateImpl : virtual public ShardState {
|
||||
public:
|
||||
virtual ~ShardStateImpl() = default;
|
||||
static td::Result<td::Ref<ShardState>> fetch(BlockIdExt block_id, td::BufferSlice data);
|
||||
|
||||
bool disable_boc() const override {
|
||||
return true;
|
||||
}
|
||||
UnixTime get_unix_time() const override {
|
||||
return ts_;
|
||||
}
|
||||
LogicalTime get_logical_time() const override {
|
||||
return lt_;
|
||||
}
|
||||
ShardIdFull get_shard() const override {
|
||||
return shard_;
|
||||
}
|
||||
BlockSeqno get_seqno() const override {
|
||||
return seqno_;
|
||||
}
|
||||
BlockIdExt get_block_id() const override {
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
return blocks_id_[0];
|
||||
}
|
||||
bool before_split() const override {
|
||||
return before_split_;
|
||||
}
|
||||
RootHash root_hash() const override;
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Result<td::Ref<MessageQueue>> message_queue() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Status apply_block(BlockIdExt id, td::Ref<BlockData> block) override;
|
||||
td::Result<td::Ref<ShardState>> merge_with(const ShardState &with) const override;
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> split() const override;
|
||||
td::Status validate_deep() const override {
|
||||
return td::Status::OK();
|
||||
}
|
||||
td::Result<td::BufferSlice> serialize() const override;
|
||||
ShardStateImpl *make_copy() const override {
|
||||
return new ShardStateImpl{shard_, seqno_, ts_, before_split_, blocks_id_};
|
||||
}
|
||||
|
||||
ShardStateImpl(ShardIdFull shard, BlockSeqno seqno, UnixTime ts, bool split, std::vector<BlockIdExt> block_id)
|
||||
: shard_(shard), seqno_(seqno), ts_(ts), before_split_(split), blocks_id_(block_id) {
|
||||
}
|
||||
ShardStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id);
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
BlockSeqno seqno_;
|
||||
UnixTime ts_;
|
||||
LogicalTime lt_ = 0;
|
||||
|
||||
bool before_split_;
|
||||
|
||||
std::vector<BlockIdExt> blocks_id_;
|
||||
};
|
||||
|
||||
class MasterchainStateImpl : public MasterchainState, public ShardStateImpl {
|
||||
public:
|
||||
struct ShardDescr {
|
||||
BlockIdExt top_block;
|
||||
bool before_split;
|
||||
bool before_merge;
|
||||
bool after_split;
|
||||
bool after_merge;
|
||||
ShardDescr(const tl_object_ptr<ton_api::test0_masterchain_shardInfo> &from);
|
||||
tl_object_ptr<ton_api::test0_masterchain_shardInfo> tl() const;
|
||||
td::Ref<McShardHash> mc_shard() const;
|
||||
bool operator<(const ShardDescr &with) const {
|
||||
return top_block.shard_full() < with.top_block.shard_full();
|
||||
}
|
||||
};
|
||||
|
||||
td::Ref<ValidatorSet> get_validator_set(ShardIdFull shard) const override;
|
||||
td::Ref<ValidatorSet> get_next_validator_set(ShardIdFull shard) const override;
|
||||
td::Ref<ValidatorSet> get_validator_set(ShardIdFull shard, UnixTime ts) const;
|
||||
bool rotated_all_shards() const override {
|
||||
return get_seqno() == 0;
|
||||
}
|
||||
UnixTime next_validator_rotate_at() const {
|
||||
return next_validator_rotate_at_;
|
||||
}
|
||||
std::vector<td::Ref<McShardHash>> get_shards() const override;
|
||||
bool ancestor_is_valid(BlockIdExt id) const override;
|
||||
|
||||
td::Status apply_block(BlockIdExt id, td::Ref<BlockData> block) override;
|
||||
td::Result<td::Ref<ShardState>> merge_with(const ShardState &with) const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> split() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Status validate_deep() const override {
|
||||
return td::Status::OK();
|
||||
}
|
||||
td::Ref<McShardHash> get_shard_from_config(ShardIdFull shard) const override {
|
||||
auto v = get_shards();
|
||||
for (auto &x : v) {
|
||||
if (x->shard() == shard) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return td::Ref<McShardHash>{};
|
||||
}
|
||||
td::Result<td::BufferSlice> serialize() const override;
|
||||
MasterchainStateImpl *make_copy() const override {
|
||||
return new MasterchainStateImpl{get_shard(),
|
||||
get_seqno(),
|
||||
get_unix_time(),
|
||||
cur_validator_ts_,
|
||||
cur_randseed_,
|
||||
next_randseed_,
|
||||
next_validator_rotate_at_,
|
||||
validators_,
|
||||
prev_blocks_,
|
||||
shards_,
|
||||
get_block_id()};
|
||||
}
|
||||
static td::Result<td::Ref<MasterchainState>> fetch(BlockIdExt block_id, td::BufferSlice data);
|
||||
|
||||
MasterchainStateImpl(ShardIdFull shard, BlockSeqno seqno, UnixTime ts, UnixTime cur_validator_ts,
|
||||
td::uint32 cur_randseed, td::uint32 next_randseed, UnixTime next_validator_rotate_at,
|
||||
std::vector<ValidatorFullId> validators, std::vector<BlockIdExt> prev_blocks,
|
||||
std::set<ShardDescr> shards, BlockIdExt block_id)
|
||||
: ShardStateImpl{shard, seqno, ts, false, {block_id}}
|
||||
, cur_validator_ts_(cur_validator_ts)
|
||||
, cur_randseed_(cur_randseed)
|
||||
, next_randseed_(next_randseed)
|
||||
, next_validator_rotate_at_(next_validator_rotate_at)
|
||||
, validators_(std::move(validators))
|
||||
, prev_blocks_(std::move(prev_blocks))
|
||||
, shards_(std::move(shards)) {
|
||||
}
|
||||
MasterchainStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id);
|
||||
|
||||
private:
|
||||
td::Ref<ValidatorSet> calculate_validator_set(ShardIdFull shard, td::uint32 cnt, UnixTime ts,
|
||||
td::uint32 randseed) const;
|
||||
|
||||
UnixTime cur_validator_ts_;
|
||||
td::uint32 cur_randseed_;
|
||||
td::uint32 next_randseed_;
|
||||
UnixTime next_validator_rotate_at_;
|
||||
|
||||
std::vector<ValidatorFullId> validators_;
|
||||
std::vector<BlockIdExt> prev_blocks_;
|
||||
std::set<ShardDescr> shards_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "signature-set.hpp"
|
||||
#include "auto/tl/ton_api.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
td::BufferSlice BlockSignatureSetImpl::serialize() const {
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockSignature>> sigs;
|
||||
for (auto &s : signatures()) {
|
||||
sigs.emplace_back(
|
||||
create_tl_object<ton_api::tonNode_blockSignature>(Bits256_2_UInt256(s.node), s.signature.clone()));
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::test0_blockSignatures>(std::move(sigs));
|
||||
return serialize_tl_object(obj, true);
|
||||
}
|
||||
|
||||
td::Ref<BlockSignatureSet> BlockSignatureSetImpl::fetch(td::BufferSlice data) {
|
||||
auto F = fetch_tl_object<ton_api::test0_blockSignatures>(std::move(data), true);
|
||||
auto obj = F.move_as_ok();
|
||||
|
||||
std::vector<BlockSignature> sigs;
|
||||
for (auto &s : obj->signatures_) {
|
||||
sigs.emplace_back(BlockSignature{UInt256_2_Bits256(s->who_), std::move(s->signature_)});
|
||||
}
|
||||
|
||||
return td::Ref<BlockSignatureSetImpl>{true, std::move(sigs)};
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/interfaces/signature-set.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class BlockSignatureSetImpl : public BlockSignatureSet {
|
||||
public:
|
||||
BlockSignatureSetImpl(std::vector<BlockSignature> signatures) : BlockSignatureSet{std::move(signatures)} {
|
||||
}
|
||||
|
||||
BlockSignatureSetImpl *make_copy() const override {
|
||||
std::vector<BlockSignature> vec;
|
||||
auto &sigs = signatures();
|
||||
for (auto &s : sigs) {
|
||||
vec.emplace_back(BlockSignature{s.node, s.signature.clone()});
|
||||
}
|
||||
|
||||
return new BlockSignatureSetImpl{std::move(vec)};
|
||||
}
|
||||
|
||||
td::BufferSlice serialize() const override;
|
||||
static td::Ref<BlockSignatureSet> fetch(td::BufferSlice data);
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "top-shard-description.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "tl-utils/tl-utils.hpp"
|
||||
#include "common/errorcode.h"
|
||||
#include "validator/fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
bool ShardTopBlockDescriptionImpl::may_be_valid(BlockHandle last_masterchain_block_handle,
|
||||
td::Ref<MasterchainState> last_masterchain_block_state) const {
|
||||
if (after_split_ && after_merge_) {
|
||||
return false;
|
||||
}
|
||||
if (!after_split_ && !after_merge_) {
|
||||
auto s = last_masterchain_block_state->get_shard_from_config(block_id_.shard_full());
|
||||
if (s.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->fsm_state() != McShardHash::FsmState::fsm_none) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->top_block_id().id.seqno >= block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
} else if (after_split_) {
|
||||
auto s = last_masterchain_block_state->get_shard_from_config(shard_parent(block_id_.shard_full()));
|
||||
if (s.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->fsm_state() != McShardHash::FsmState::fsm_split) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->top_block_id().id.seqno + 1 != block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
auto s1 = last_masterchain_block_state->get_shard_from_config(shard_child(block_id_.shard_full(), true));
|
||||
if (s1.is_null()) {
|
||||
return false;
|
||||
}
|
||||
auto s2 = last_masterchain_block_state->get_shard_from_config(shard_child(block_id_.shard_full(), false));
|
||||
if (s2.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s1->fsm_state() != McShardHash::FsmState::fsm_merge || s2->fsm_state() != McShardHash::FsmState::fsm_merge) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (std::max(s1->top_block_id().id.seqno, s2->top_block_id().id.seqno) + 1 != block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto val_set = last_masterchain_block_state->get_validator_set(block_id_.shard_full());
|
||||
if (val_set->get_catchain_seqno() != catchain_seqno_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
td::BufferSlice ShardTopBlockDescriptionImpl::serialize() const {
|
||||
return serialize_tl_object(create_tl_object<ton_api::test0_topShardBlockDescription>(
|
||||
create_tl_block_id(block_id_), after_split_, after_merge_, before_split_,
|
||||
catchain_seqno_, validator_set_hash_, signatures_.clone()),
|
||||
true);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardTopBlockDescription>> ShardTopBlockDescriptionImpl::fetch(td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_topShardBlockDescription>(std::move(data), true));
|
||||
|
||||
return td::Ref<ShardTopBlockDescriptionImpl>{true,
|
||||
create_block_id(F->block_id_),
|
||||
F->after_split_,
|
||||
F->after_merge_,
|
||||
F->before_split_,
|
||||
F->catchain_seqno_,
|
||||
F->validator_set_hash_,
|
||||
F->signatures_.clone()};
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(ShardTopBlockDescriptionImpl::fetch(data_.clone()).move_as_ok());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_topShardBlockDescription>(data_.clone(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
unserialized_ = F.move_as_ok();
|
||||
|
||||
auto id = create_block_id(unserialized_->block_id_);
|
||||
|
||||
auto val_set = state_->get_validator_set(id.shard_full());
|
||||
if (val_set->get_catchain_seqno() != static_cast<CatchainSeqno>(unserialized_->catchain_seqno_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (val_set->get_validator_set_hash() != static_cast<td::uint32>(unserialized_->validator_set_hash_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto sig_setR = create_signature_set(unserialized_->signatures_.clone());
|
||||
if (sig_setR.is_error()) {
|
||||
abort_query(sig_setR.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto S = val_set->check_signatures(id.root_hash, id.file_hash, sig_setR.move_as_ok());
|
||||
if (S.is_error()) {
|
||||
abort_query(S.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
finish_query();
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/shard-block.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ShardTopBlockDescriptionImpl : public ShardTopBlockDescription {
|
||||
public:
|
||||
ShardIdFull shard() const override {
|
||||
return block_id_.shard_full();
|
||||
}
|
||||
BlockIdExt block_id() const override {
|
||||
return block_id_;
|
||||
}
|
||||
|
||||
bool may_be_valid(BlockHandle last_masterchain_block_handle,
|
||||
td::Ref<MasterchainState> last_masterchain_block_state) const override;
|
||||
|
||||
td::BufferSlice serialize() const override;
|
||||
|
||||
bool before_split() const override {
|
||||
return before_split_;
|
||||
}
|
||||
bool after_split() const override {
|
||||
return after_split_;
|
||||
}
|
||||
bool after_merge() const override {
|
||||
return after_merge_;
|
||||
}
|
||||
|
||||
ShardTopBlockDescriptionImpl(BlockIdExt block_id, bool after_split, bool after_merge, bool before_split,
|
||||
CatchainSeqno catchain_seqno, td::uint32 validator_set_hash, td::BufferSlice signatures)
|
||||
: block_id_(block_id)
|
||||
, after_split_(after_split)
|
||||
, after_merge_(after_merge)
|
||||
, before_split_(before_split)
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures)) {
|
||||
}
|
||||
|
||||
ShardTopBlockDescriptionImpl *make_copy() const override {
|
||||
return new ShardTopBlockDescriptionImpl{block_id_, after_split_, after_merge_, before_split_,
|
||||
catchain_seqno_, validator_set_hash_, signatures_.clone()};
|
||||
}
|
||||
|
||||
static td::Result<td::Ref<ShardTopBlockDescription>> fetch(td::BufferSlice data);
|
||||
|
||||
private:
|
||||
BlockIdExt block_id_;
|
||||
bool after_split_;
|
||||
bool after_merge_;
|
||||
bool before_split_;
|
||||
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::BufferSlice signatures_;
|
||||
};
|
||||
|
||||
class ValidateShardTopBlockDescription : public td::actor::Actor {
|
||||
public:
|
||||
ValidateShardTopBlockDescription(td::BufferSlice data, BlockHandle masterchain_handle,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise)
|
||||
: data_(std::move(data))
|
||||
, handle_(std::move(masterchain_handle))
|
||||
, state_(std::move(masterchain_state))
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void finish_query();
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
tl_object_ptr<ton_api::test0_topShardBlockDescription> unserialized_;
|
||||
|
||||
BlockHandle handle_;
|
||||
td::Ref<MasterchainState> state_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validate-query.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void ValidateQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void ValidateQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting validate block candidate query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::reject_query(std::string reason, td::BufferSlice proof) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "rejecting validate block candidate query: " << reason;
|
||||
promise_.set_value(CandidateReject{std::move(reason), std::move(proof)});
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_result(block_ts_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_shardchain_block>(candidate_.data.clone(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
unserialized_block_ = F.move_as_ok();
|
||||
block_ts_ = unserialized_block_->ts_;
|
||||
|
||||
if (unserialized_block_->workchain_ != shard_.workchain) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad workchain"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<ShardId>(unserialized_block_->shard_) != shard_.shard) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad shard"));
|
||||
return;
|
||||
}
|
||||
|
||||
BlockSeqno max_seqno = 0;
|
||||
if (prev_.size() != unserialized_block_->prev_.size()) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong prev block count"));
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < prev_.size(); i++) {
|
||||
if (prev_[i].id.seqno > max_seqno) {
|
||||
max_seqno = prev_[i].id.seqno;
|
||||
}
|
||||
auto p = create_block_id(unserialized_block_->prev_[i]);
|
||||
if (p != prev_[i]) {
|
||||
LOG(WARNING) << p << " " << prev_[i];
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong prev block"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (static_cast<BlockSeqno>(unserialized_block_->seqno_) != max_seqno + 1) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong block seqno"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<CatchainSeqno>(unserialized_block_->catchain_seqno_) != catchain_seqno_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<td::uint32>(unserialized_block_->validator_set_hash_) != validator_set_hash_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
if (prev_.size() == 1) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, prev_[0], timeout_, std::move(P));
|
||||
} else {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_merge, prev_[0], prev_[1], timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void ValidateQuery::got_prev_state(td::Ref<ShardState> R) {
|
||||
if (R->get_unix_time() >= static_cast<UnixTime>(unserialized_block_->ts_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "too small ts"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::written_candidate);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_candidate, candidate_.id, candidate_.clone(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void ValidateQuery::written_candidate() {
|
||||
finish_query();
|
||||
}
|
||||
|
||||
ValidateQuery::ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, BlockCandidate candidate, CatchainSeqno catchain_seqno,
|
||||
td::uint32 validator_set_hash, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<ValidateCandidateResult> promise)
|
||||
: shard_(shard)
|
||||
, min_ts_(min_ts)
|
||||
, min_masterchain_block_id_(min_masterchain_block_id)
|
||||
, prev_(std::move(prev))
|
||||
, candidate_(std::move(candidate))
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ValidateQuery : public td::actor::Actor {
|
||||
public:
|
||||
ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||
BlockCandidate candidate, CatchainSeqno catchain_seqno, td::uint32 validator_set_hash,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<ValidateCandidateResult> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void reject_query(std::string reason, td::BufferSlice proof);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void got_masterchain_handle(BlockHandle masterchain_handle);
|
||||
void got_masterchain_state(td::Ref<ShardState> masterchain_state);
|
||||
void written_candidate();
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
UnixTime min_ts_;
|
||||
BlockIdExt min_masterchain_block_id_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
BlockCandidate candidate_;
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<ValidateCandidateResult> promise_;
|
||||
|
||||
UnixTime block_ts_;
|
||||
tl_object_ptr<ton_api::test0_shardchain_block> unserialized_block_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validator-set.hpp"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
bool ValidatorSetImpl::is_validator(NodeIdShort id) const {
|
||||
return ids_map_.count(id) > 0;
|
||||
}
|
||||
|
||||
td::Result<ValidatorWeight> ValidatorSetImpl::check_signatures(RootHash root_hash, FileHash file_hash,
|
||||
td::Ref<BlockSignatureSet> signatures) const {
|
||||
auto &sigs = signatures->signatures();
|
||||
|
||||
auto b = create_tl_object<ton_api::ton_blockId>(Bits256_2_UInt256(root_hash), Bits256_2_UInt256(file_hash));
|
||||
auto block = serialize_tl_object(b, true);
|
||||
|
||||
ValidatorWeight weight = 0;
|
||||
|
||||
std::set<NodeIdShort> nodes;
|
||||
for (auto &sig : sigs) {
|
||||
if (nodes.count(sig.node) == 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "duplicate node to sign");
|
||||
}
|
||||
nodes.insert(sig.node);
|
||||
|
||||
auto it = ids_map_.find(sig.node);
|
||||
if (it == ids_map_.end()) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown node to sign");
|
||||
}
|
||||
|
||||
auto idx = it->second;
|
||||
TRY_STATUS(ids_[idx].encryptor->check_signature(block.as_slice(), sig.signature.as_slice()));
|
||||
weight += ids_[idx].weight;
|
||||
}
|
||||
|
||||
if (weight * 3 <= total_weight_ * 2) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too small sig weight");
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
ValidatorSetImpl::ValidatorSetImpl(CatchainSeqno cc_seqno, ShardId from,
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> nodes)
|
||||
: cc_seqno_(cc_seqno), from_(from) {
|
||||
total_weight_ = 0;
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_validatorSetItem>> s_vec;
|
||||
|
||||
for (auto &n : nodes) {
|
||||
auto idx = ids_.size();
|
||||
auto id = n.first.short_id();
|
||||
s_vec.emplace_back(create_tl_object<ton_api::test0_validatorSetItem>(Bits256_2_UInt256(id), n.second));
|
||||
CHECK(ids_map_.count(id) == 0);
|
||||
total_weight_ += n.second;
|
||||
auto E = n.first.create_encryptor().move_as_ok();
|
||||
ids_.emplace_back(ValidatorSetMember{n.first, n.second, std::move(E)});
|
||||
ids_map_.emplace(id, idx);
|
||||
}
|
||||
|
||||
auto obj = create_tl_object<ton_api::test0_validatorSet>(cc_seqno_, std::move(s_vec));
|
||||
auto B = serialize_tl_object(obj, true);
|
||||
hash_ = td::crc32c(B.as_slice());
|
||||
}
|
||||
|
||||
ValidatorSetImpl *ValidatorSetImpl::make_copy() const {
|
||||
return new ValidatorSetImpl{cc_seqno_, from_, export_vector()};
|
||||
}
|
||||
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> ValidatorSetImpl::export_tl_vector() const {
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> vec;
|
||||
for (auto &v : ids_) {
|
||||
vec.emplace_back(v.id, v.weight);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> ValidatorSetImpl::export_vector() const {
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> vec;
|
||||
for (auto &v : ids_) {
|
||||
vec.emplace_back(v.id, v.weight);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
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/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/validator-set.h"
|
||||
#include "validator/interfaces/signature-set.h"
|
||||
#include "keys/encryptor.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ValidatorSetImpl : public ValidatorSet {
|
||||
private:
|
||||
struct ValidatorSetMember {
|
||||
ValidatorFullId id;
|
||||
ValidatorWeight weight;
|
||||
std::unique_ptr<Encryptor> encryptor;
|
||||
};
|
||||
|
||||
public:
|
||||
bool is_validator(NodeIdShort id) const override;
|
||||
CatchainSeqno get_catchain_seqno() const override {
|
||||
return cc_seqno_;
|
||||
}
|
||||
td::uint32 get_validator_set_hash() const override {
|
||||
return hash_;
|
||||
}
|
||||
ShardId get_validator_set_from() const override {
|
||||
return from_;
|
||||
}
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> export_vector() const override;
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> export_tl_vector() const override;
|
||||
td::Result<ValidatorWeight> check_signatures(RootHash root_hash, FileHash file_hash,
|
||||
td::Ref<BlockSignatureSet> signatures) const override;
|
||||
|
||||
ValidatorSetImpl *make_copy() const override;
|
||||
|
||||
ValidatorSetImpl(UnixTime ts, ShardId from_, std::vector<std::pair<ValidatorFullId, ValidatorWeight>> nodes);
|
||||
|
||||
private:
|
||||
CatchainSeqno cc_seqno_;
|
||||
ShardId from_;
|
||||
td::uint32 hash_;
|
||||
ValidatorWeight total_weight_;
|
||||
std::vector<ValidatorSetMember> ids_;
|
||||
std::map<NodeIdShort, size_t> ids_map_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -3782,11 +3782,9 @@ bool ValidateQuery::check_neighbor_outbound_message(Ref<vm::CellSlice> enq_msg,
|
|||
return reject_query("unpack ext_message_deq OutMsg record for already processed EnqueuedMsg with key "s +
|
||||
key.to_hex(352) + " of old outbound queue contains a different MsgEnvelope");
|
||||
}
|
||||
} else if (out_entry.not_null()) {
|
||||
return reject_query(
|
||||
"have an OutMsg entry for exporting (or even dequeuing) already processed EnqueuedMsg with key "s +
|
||||
key.to_hex(352) + " of neighbor " + nb.blk_.to_str());
|
||||
}
|
||||
// NB. we might have a non-trivial dequeueing out_entry with this message hash, but another envelope (for transit messages)
|
||||
// (so we cannot assert that out_entry is null)
|
||||
if (claimed_proc_lt_ && (claimed_proc_lt_ < lt || (claimed_proc_lt_ == lt && claimed_proc_hash_ < enq.hash_))) {
|
||||
LOG(FATAL) << "internal inconsistency: new ProcessedInfo claims to have processed all messages up to ("
|
||||
<< claimed_proc_lt_ << "," << claimed_proc_hash_.to_hex()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue