mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
changed validate broadcast logic, added new queries to
validator-engine-console
This commit is contained in:
parent
47814dca3d
commit
d8244eff53
24 changed files with 695 additions and 84 deletions
|
@ -9,6 +9,7 @@ set(TON_VALIDATOR_SOURCE
|
|||
block.cpp
|
||||
check-proof.cpp
|
||||
collator.cpp
|
||||
config.cpp
|
||||
external-message.cpp
|
||||
fabric.cpp
|
||||
ihr-message.cpp
|
||||
|
@ -27,6 +28,7 @@ set(TON_VALIDATOR_SOURCE
|
|||
collate-query-impl.h
|
||||
collator-impl.h
|
||||
collator.h
|
||||
config.hpp
|
||||
external-message.hpp
|
||||
ihr-message.hpp
|
||||
liteserver.hpp
|
||||
|
|
58
validator/impl/config.cpp
Normal file
58
validator/impl/config.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
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 "config.hpp"
|
||||
#include "block/block-parse.h"
|
||||
#include "block/block-auto.h"
|
||||
#include "vm/boc.h"
|
||||
#include "vm/cells/MerkleProof.h"
|
||||
#include "validator-set.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
td::Ref<ValidatorSet> ConfigHolderQ::get_total_validator_set(int next) const {
|
||||
if (!config_) {
|
||||
LOG(ERROR) << "MasterchainStateQ::get_total_validator_set() : no config";
|
||||
return {};
|
||||
}
|
||||
auto nodes = config_->compute_total_validator_set(next);
|
||||
if (nodes.empty()) {
|
||||
return {};
|
||||
}
|
||||
return Ref<ValidatorSetQ>{true, 0, ton::ShardIdFull{}, std::move(nodes)};
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> ConfigHolderQ::get_validator_set(ShardIdFull shard, UnixTime utime,
|
||||
CatchainSeqno cc_seqno) const {
|
||||
if (!config_) {
|
||||
LOG(ERROR) << "MasterchainStateQ::get_validator_set() : no config";
|
||||
return {};
|
||||
}
|
||||
auto nodes = config_->compute_validator_set(shard, utime, cc_seqno);
|
||||
if (nodes.empty()) {
|
||||
return {};
|
||||
}
|
||||
return Ref<ValidatorSetQ>{true, cc_seqno, shard, std::move(nodes)};
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
50
validator/impl/config.hpp
Normal file
50
validator/impl/config.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
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/config.h"
|
||||
|
||||
namespace ton {
|
||||
namespace validator {
|
||||
using td::Ref;
|
||||
|
||||
class ConfigHolderQ : public ConfigHolder {
|
||||
std::shared_ptr<block::Config> config_;
|
||||
std::shared_ptr<vm::StaticBagOfCellsDb> boc_;
|
||||
|
||||
public:
|
||||
ConfigHolderQ() = default;
|
||||
ConfigHolderQ(std::shared_ptr<block::Config> config, std::shared_ptr<vm::StaticBagOfCellsDb> boc)
|
||||
: config_(std::move(config)), boc_(std::move(boc)) {
|
||||
}
|
||||
ConfigHolderQ(std::shared_ptr<block::Config> config) : config_(std::move(config)) {
|
||||
}
|
||||
const block::Config *get_config() const {
|
||||
return config_.get();
|
||||
}
|
||||
ConfigHolderQ *make_copy() const override {
|
||||
return new ConfigHolderQ(*this);
|
||||
}
|
||||
// if necessary, add more public methods providing interface to config_->...()
|
||||
td::Ref<ValidatorSet> get_total_validator_set(int next) const override; // next = -1 -> prev, next = 0 -> cur
|
||||
td::Ref<ValidatorSet> get_validator_set(ShardIdFull shard, UnixTime utime, CatchainSeqno seqno) const override;
|
||||
};
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -43,10 +43,10 @@ td::Result<Ref<ProofLink>> ProofQ::export_as_proof_link() const {
|
|||
}
|
||||
|
||||
td::Result<BlockSeqno> ProofLinkQ::prev_key_mc_seqno() const {
|
||||
if (!id_.is_masterchain()) {
|
||||
return td::Status::Error(
|
||||
-668, "cannot compute previous key masterchain block from ProofLink of non-masterchain block "s + id_.to_str());
|
||||
}
|
||||
//if (!id_.is_masterchain()) {
|
||||
// return td::Status::Error(
|
||||
// -668, "cannot compute previous key masterchain block from ProofLink of non-masterchain block "s + id_.to_str());
|
||||
//}
|
||||
TRY_RESULT(pair, get_virtual_root(true));
|
||||
try {
|
||||
block::gen::Block::Record blk;
|
||||
|
@ -68,8 +68,7 @@ td::Result<td::Ref<ConfigHolder>> ProofLinkQ::get_key_block_config() const {
|
|||
}
|
||||
TRY_RESULT(pair, get_virtual_root(true));
|
||||
try {
|
||||
TRY_RESULT(cfg, block::Config::extract_from_key_block(
|
||||
std::move(pair.first), block::Config::needValidatorSet | block::Config::needWorkchainInfo));
|
||||
TRY_RESULT(cfg, block::Config::extract_from_key_block(std::move(pair.first), block::Config::needValidatorSet));
|
||||
return td::make_ref<ConfigHolderQ>(std::move(cfg), std::move(pair.second));
|
||||
} catch (vm::VmVirtError &) {
|
||||
return td::Status::Error(-668,
|
||||
|
@ -77,6 +76,26 @@ td::Result<td::Ref<ConfigHolder>> ProofLinkQ::get_key_block_config() const {
|
|||
}
|
||||
}
|
||||
|
||||
td::Result<ProofLink::BasicHeaderInfo> ProofLinkQ::get_basic_header_info() const {
|
||||
BasicHeaderInfo res;
|
||||
TRY_RESULT(pair, get_virtual_root(true));
|
||||
try {
|
||||
block::gen::Block::Record blk;
|
||||
block::gen::BlockInfo::Record info;
|
||||
if (!(tlb::unpack_cell(std::move(pair.first), blk) && tlb::unpack_cell(blk.info, info) && !info.version)) {
|
||||
return td::Status::Error(-668,
|
||||
"cannot unpack block header in the Merkle proof for masterchain block "s + id_.to_str());
|
||||
}
|
||||
res.cc_seqno = info.gen_catchain_seqno;
|
||||
res.utime = info.gen_utime;
|
||||
res.validator_set_hash = info.gen_validator_list_hash_short;
|
||||
res.prev_key_mc_seqno = info.prev_key_block_seqno;
|
||||
return res;
|
||||
} catch (vm::VmVirtError &) {
|
||||
return td::Status::Error(-668, "virtualization error in masterchain block proof for "s + id_.to_str());
|
||||
}
|
||||
}
|
||||
|
||||
td::Result<std::pair<Ref<vm::Cell>, std::shared_ptr<vm::StaticBagOfCellsDb>>> ProofLinkQ::get_virtual_root(
|
||||
bool lazy) const {
|
||||
if (data_.empty()) {
|
||||
|
@ -127,17 +146,5 @@ td::Result<std::pair<Ref<vm::Cell>, std::shared_ptr<vm::StaticBagOfCellsDb>>> Pr
|
|||
return std::make_pair(std::move(virt_root), std::move(boc));
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> ConfigHolderQ::get_total_validator_set(int next) const {
|
||||
if (!config_) {
|
||||
LOG(ERROR) << "MasterchainStateQ::get_total_validator_set() : no config";
|
||||
return {};
|
||||
}
|
||||
auto nodes = config_->compute_total_validator_set(next);
|
||||
if (nodes.empty()) {
|
||||
return {};
|
||||
}
|
||||
return Ref<ValidatorSetQ>{true, 0, ton::ShardIdFull{}, std::move(nodes)};
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
} // namespace ton
|
||||
|
|
|
@ -22,32 +22,12 @@
|
|||
#include "block/block-db.h"
|
||||
#include "block/mc-config.h"
|
||||
#include "vm/db/StaticBagOfCellsDb.h"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace ton {
|
||||
namespace validator {
|
||||
using td::Ref;
|
||||
|
||||
class ConfigHolderQ : public ConfigHolder {
|
||||
std::shared_ptr<block::Config> config_;
|
||||
std::shared_ptr<vm::StaticBagOfCellsDb> boc_;
|
||||
|
||||
public:
|
||||
ConfigHolderQ() = default;
|
||||
ConfigHolderQ(std::shared_ptr<block::Config> config, std::shared_ptr<vm::StaticBagOfCellsDb> boc)
|
||||
: config_(std::move(config)), boc_(std::move(boc)) {
|
||||
}
|
||||
ConfigHolderQ(std::shared_ptr<block::Config> config) : config_(std::move(config)) {
|
||||
}
|
||||
const block::Config *get_config() const {
|
||||
return config_.get();
|
||||
}
|
||||
ConfigHolderQ *make_copy() const override {
|
||||
return new ConfigHolderQ(*this);
|
||||
}
|
||||
// if necessary, add more public methods providing interface to config_->...()
|
||||
td::Ref<ValidatorSet> get_total_validator_set(int next) const override; // next = -1 -> prev, next = 0 -> cur
|
||||
};
|
||||
|
||||
class ProofLinkQ : virtual public ProofLink {
|
||||
protected:
|
||||
BlockIdExt id_;
|
||||
|
@ -67,6 +47,7 @@ class ProofLinkQ : virtual public ProofLink {
|
|||
}
|
||||
td::Result<BlockSeqno> prev_key_mc_seqno() const override;
|
||||
td::Result<td::Ref<ConfigHolder>> get_key_block_config() const override;
|
||||
td::Result<BasicHeaderInfo> get_basic_header_info() const override;
|
||||
|
||||
protected:
|
||||
td::Result<std::pair<Ref<vm::Cell>, std::shared_ptr<vm::StaticBagOfCellsDb>>> get_virtual_root(
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "interfaces/shard.h"
|
||||
#include "vm/db/StaticBagOfCellsDb.h"
|
||||
#include "block/mc-config.h"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -138,6 +139,13 @@ class MasterchainStateQ : public MasterchainState, public ShardStateQ {
|
|||
std::shared_ptr<block::ConfigInfo> get_config() const {
|
||||
return config_;
|
||||
}
|
||||
td::Result<td::Ref<ConfigHolder>> get_key_block_config() const override {
|
||||
if (!config_) {
|
||||
return td::Status::Error(ErrorCode::notready, "config not found");
|
||||
} else {
|
||||
return td::make_ref<ConfigHolderQ>(config_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ZeroStateIdExt zerostate_id_;
|
||||
|
|
|
@ -665,9 +665,7 @@ bool ValidateQuery::try_unpack_mc_state() {
|
|||
}
|
||||
config_ = res.move_as_ok();
|
||||
CHECK(config_);
|
||||
if (mc_seqno_) {
|
||||
config_->set_block_id_ext(mc_blkid_);
|
||||
}
|
||||
config_->set_block_id_ext(mc_blkid_);
|
||||
old_shard_conf_ = std::make_unique<block::ShardConfig>(*config_);
|
||||
if (!is_masterchain()) {
|
||||
new_shard_conf_ = std::make_unique<block::ShardConfig>(*config_);
|
||||
|
@ -684,6 +682,11 @@ bool ValidateQuery::try_unpack_mc_state() {
|
|||
} else {
|
||||
prev_key_block_seqno_ = 0;
|
||||
}
|
||||
if (prev_key_seqno_ != prev_key_block_seqno_) {
|
||||
return reject_query(PSTRING() << "previous key block seqno value in candidate block header is " << prev_key_seqno_
|
||||
<< " while the correct value corresponding to reference masterchain state "
|
||||
<< mc_blkid_.to_str() << " is " << prev_key_block_seqno_);
|
||||
}
|
||||
auto limits = config_->get_block_limits(is_masterchain());
|
||||
if (limits.is_error()) {
|
||||
return fatal_error(limits.move_as_error());
|
||||
|
@ -5002,7 +5005,7 @@ bool ValidateQuery::check_mc_state_extra() {
|
|||
} else if (!new_extra.r1.last_key_block->prefetch_ulong(1)) {
|
||||
return reject_query("last_key_block:(Maybe ExtBlkRef) changed in the new state, but it became a nothing$0");
|
||||
} else {
|
||||
auto& cs = new_extra.r1.last_key_block.write();
|
||||
vm::CellSlice cs = *new_extra.r1.last_key_block;
|
||||
BlockIdExt blkid;
|
||||
LogicalTime lt;
|
||||
CHECK(cs.fetch_ulong(1) == 1 && block::tlb::t_ExtBlkRef.unpack(cs, blkid, <));
|
||||
|
@ -5017,6 +5020,20 @@ bool ValidateQuery::check_mc_state_extra() {
|
|||
", but it is not a key block");
|
||||
}
|
||||
}
|
||||
if (new_extra.r1.last_key_block->prefetch_ulong(1)) {
|
||||
auto& cs = new_extra.r1.last_key_block.write();
|
||||
BlockIdExt blkid;
|
||||
LogicalTime lt;
|
||||
CHECK(cs.fetch_ulong(1) == 1 && block::tlb::t_ExtBlkRef.unpack(cs, blkid, <));
|
||||
if (blkid != prev_key_block_) {
|
||||
return reject_query("new masterchain state declares previous key block to be "s + blkid.to_str() +
|
||||
" but the value computed from previous masterchain state is " + prev_key_block_.to_str());
|
||||
}
|
||||
} else if (prev_key_block_seqno_ > 0) {
|
||||
return reject_query(PSTRING() << "new masterchain state declares no previous key block, but the block header "
|
||||
"announces previous key block seqno "
|
||||
<< prev_key_block_seqno_);
|
||||
}
|
||||
// global_balance:CurrencyCollection
|
||||
block::CurrencyCollection global_balance, old_global_balance;
|
||||
if (!global_balance.validate_unpack(new_extra.global_balance)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue