1
0
Fork 0
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:
ton 2019-09-10 12:30:35 +04:00
parent 2b734e170c
commit 47814dca3d
44 changed files with 175 additions and 4196 deletions

View file

@ -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);
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()