1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

validator bugfix + old key blocks download improvement

This commit is contained in:
ton 2020-04-11 18:08:57 +04:00
parent be9c34c62d
commit 16a4566091
13 changed files with 315 additions and 121 deletions

View file

@ -151,8 +151,6 @@ struct ActionPhaseConfig {
struct CreditPhase {
td::RefInt256 due_fees_collected;
block::CurrencyCollection credit;
// td::RefInt256 credit;
// Ref<vm::Cell> credit_extra;
};
struct ComputePhase {
@ -233,8 +231,6 @@ struct Account {
ton::UnixTime last_paid;
vm::CellStorageStat storage_stat;
block::CurrencyCollection balance;
// td::RefInt256 balance;
// Ref<vm::Cell> extra_balance;
td::RefInt256 due_payment;
Ref<vm::Cell> orig_total_state; // ^Account
Ref<vm::Cell> total_state; // ^Account
@ -325,8 +321,6 @@ struct Transaction {
Ref<vm::Cell> root;
Ref<vm::Cell> new_total_state;
Ref<vm::CellSlice> new_inner_state;
// Ref<vm::Cell> extra_balance;
// Ref<vm::Cell> msg_extra;
Ref<vm::Cell> new_code, new_data, new_library;
Ref<vm::Cell> in_msg, in_msg_state;
Ref<vm::CellSlice> in_msg_body;

View file

@ -401,7 +401,9 @@ tonNode.getNextBlockDescription prev_block:tonNode.blockIdExt = tonNode.BlockDes
tonNode.getNextBlocksDescription prev_block:tonNode.blockIdExt limit:int = tonNode.BlocksDescription;
tonNode.getPrevBlocksDescription next_block:tonNode.blockIdExt limit:int cutoff_seqno:int = tonNode.BlocksDescription;
tonNode.prepareBlockProof block:tonNode.blockIdExt allow_partial:Bool = tonNode.PreparedProof;
tonNode.prepareKeyBlockProof block:tonNode.blockIdExt allow_partial:Bool = tonNode.PreparedProof;
tonNode.prepareBlockProofs blocks:(vector tonNode.blockIdExt) allow_partial:Bool = tonNode.PreparedProof;
tonNode.prepareKeyBlockProofs blocks:(vector tonNode.blockIdExt) allow_partial:Bool = tonNode.PreparedProof;
tonNode.prepareBlock block:tonNode.blockIdExt = tonNode.Prepared;
tonNode.prepareBlocks blocks:(vector tonNode.blockIdExt) = tonNode.Prepared;
tonNode.preparePersistentState block:tonNode.blockIdExt masterchain_block:tonNode.blockIdExt = tonNode.PreparedState;
@ -415,9 +417,13 @@ tonNode.downloadPersistentState block:tonNode.blockIdExt masterchain_block:tonNo
tonNode.downloadPersistentStateSlice block:tonNode.blockIdExt masterchain_block:tonNode.blockIdExt offset:long max_size:long = tonNode.Data;
tonNode.downloadZeroState block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadBlockProof block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadKeyBlockProof block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadBlockProofs blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
tonNode.downloadKeyBlockProofs blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
tonNode.downloadBlockProofLink block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadKeyBlockProofLink block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadBlockProofLinks blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
tonNode.downloadKeyBlockProofLinks blocks:(vector tonNode.blockIdExt) = tonNode.DataList;
tonNode.getArchiveInfo masterchain_seqno:int = tonNode.ArchiveInfo;
tonNode.getArchiveSlice archive_id:long offset:long max_size:int = tonNode.Data;

Binary file not shown.

View file

@ -144,6 +144,35 @@ void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNo
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareKeyBlockProof &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda(
[allow_partial = query.allow_partial_, promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
promise.set_value(std::move(x));
} else if (allow_partial) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofLink>();
promise.set_value(std::move(x));
} else {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProof>();
promise.set_value(std::move(x));
}
});
if (query.allow_partial_) {
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof_link,
create_block_id(query.block_), std::move(P));
} else {
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof,
create_block_id(query.block_), std::move(P));
}
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
@ -190,6 +219,42 @@ void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNo
create_block_id(query.block_), false, std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProof &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
} else {
promise.set_value(R.move_as_ok());
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof,
create_block_id(query.block_), std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProofLink &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
} else {
promise.set_value(R.move_as_ok());
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof_link,
create_block_id(query.block_), std::move(P));
}
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
td::Promise<td::BufferSlice> promise) {
auto P =

View file

@ -44,10 +44,16 @@ class FullNodeMasterImpl : public FullNodeMaster {
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareKeyBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProofLink &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,

View file

@ -287,6 +287,35 @@ void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNod
create_block_id(query.block_), false, std::move(P));
}
void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareKeyBlockProof &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda(
[allow_partial = query.allow_partial_, promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
promise.set_value(std::move(x));
} else if (allow_partial) {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofLink>();
promise.set_value(std::move(x));
} else {
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProof>();
promise.set_value(std::move(x));
}
});
if (query.allow_partial_) {
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof_link,
create_block_id(query.block_), std::move(P));
} else {
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof,
create_block_id(query.block_), std::move(P));
}
}
void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise) {
auto P = td::PromiseCreator::lambda(
@ -333,6 +362,42 @@ void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNod
create_block_id(query.block_), false, std::move(P));
}
void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProof &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
} else {
promise.set_value(R.move_as_ok());
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof,
create_block_id(query.block_), std::move(P));
}
void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProofLink &query,
td::Promise<td::BufferSlice> promise) {
if (query.block_->seqno_ == 0) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
return;
}
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
if (R.is_error()) {
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
} else {
promise.set_value(R.move_as_ok());
}
});
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_key_block_proof_link,
create_block_id(query.block_), std::move(P));
}
void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
td::Promise<td::BufferSlice> promise) {
auto P =
@ -639,7 +704,7 @@ void FullNodeShardImpl::download_persistent_state(BlockIdExt id, BlockIdExt mast
void FullNodeShardImpl::download_block_proof(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
td::Promise<td::BufferSlice> promise) {
auto &b = choose_neighbour();
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, adnl_id_, overlay_id_, b.adnl_id,
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, false, adnl_id_, overlay_id_, b.adnl_id,
priority, timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
create_neighbour_promise(b, std::move(promise)))
.release();
@ -648,7 +713,7 @@ void FullNodeShardImpl::download_block_proof(BlockIdExt block_id, td::uint32 pri
void FullNodeShardImpl::download_block_proof_link(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
td::Promise<td::BufferSlice> promise) {
auto &b = choose_neighbour();
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, true, adnl_id_, overlay_id_,
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, true, false, adnl_id_, overlay_id_,
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
overlays_, adnl_, client_, create_neighbour_promise(b, std::move(promise)))
.release();

View file

@ -64,7 +64,7 @@ class FullNodeShardImpl : public FullNodeShard {
return 2;
}
static constexpr td::uint64 proto_capabilities() {
return 0;
return 1;
}
static constexpr td::uint32 max_neighbours() {
return 16;
@ -94,10 +94,16 @@ class FullNodeShardImpl : public FullNodeShard {
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareKeyBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProof &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadKeyBlockProofLink &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
td::Promise<td::BufferSlice> promise);
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,

View file

@ -47,9 +47,9 @@ class Collator final : public td::actor::Actor {
}
using LtCellRef = block::LtCellRef;
using NewOutMsg = block::NewOutMsg;
const ShardIdFull shard;
const ShardIdFull shard_;
ton::BlockId new_id;
bool busy{false};
bool busy_{false};
bool before_split_{false};
bool after_split_{false};
bool after_merge_{false};
@ -69,7 +69,7 @@ class Collator final : public td::actor::Actor {
std::vector<Ref<ShardState>> prev_states;
std::vector<Ref<BlockData>> prev_block_data;
Ed25519_PublicKey created_by_;
Ref<ValidatorSet> validator_set;
Ref<ValidatorSet> validator_set_;
td::actor::ActorId<ValidatorManager> manager;
td::Timestamp timeout;
td::Promise<BlockCandidate> main_promise;
@ -90,13 +90,13 @@ class Collator final : public td::actor::Actor {
td::Timestamp timeout, td::Promise<BlockCandidate> promise);
~Collator() override = default;
bool is_busy() const {
return busy;
return busy_;
}
ShardId get_shard() const {
return shard.shard;
return shard_.shard;
}
WorkchainId workchain() const {
return shard.workchain;
return shard_.workchain;
}
static constexpr td::uint32 priority() {
return 2;
@ -232,6 +232,7 @@ class Collator final : public td::actor::Actor {
bool create_ticktock_transactions(int mask);
bool create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, ton::LogicalTime req_start_lt, int mask);
Ref<vm::Cell> create_ordinary_transaction(Ref<vm::Cell> msg_root);
bool check_cur_validator_set();
bool unpack_last_mc_state();
bool unpack_last_state();
bool unpack_merge_last_state();
@ -248,7 +249,7 @@ class Collator final : public td::actor::Actor {
bool request_neighbor_msg_queues();
void update_max_lt(ton::LogicalTime lt);
bool is_masterchain() const {
return shard.is_masterchain();
return shard_.is_masterchain();
}
bool is_our_address(Ref<vm::CellSlice> addr_ref) const;
bool is_our_address(ton::AccountIdPrefixFull addr_prefix) const;

View file

@ -58,25 +58,25 @@ Collator::Collator(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchai
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set, Ed25519_PublicKey collator_id,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<BlockCandidate> promise)
: shard(shard)
: shard_(shard)
, min_ts(min_ts)
, min_mc_block_id{min_masterchain_block_id}
, prev_blocks(std::move(prev))
, created_by_(collator_id)
, validator_set(std::move(validator_set))
, validator_set_(std::move(validator_set))
, manager(manager)
, timeout(timeout)
, main_promise(std::move(promise)) {
}
void Collator::start_up() {
LOG(DEBUG) << "Collator for shard " << shard.to_str() << " started";
LOG(DEBUG) << "Collator for shard " << shard_.to_str() << " started";
LOG(DEBUG) << "Previous block #1 is " << prev_blocks.at(0).to_str();
if (prev_blocks.size() > 1) {
LOG(DEBUG) << "Previous block #2 is " << prev_blocks.at(1).to_str();
}
// 1. check validity of parameters, especially prev_blocks, shard and min_mc_block_id
if (shard.workchain != ton::masterchainId && shard.workchain != ton::basechainId) {
if (workchain() != ton::masterchainId && workchain() != ton::basechainId) {
fatal_error(-667, "can create block candidates only for masterchain (-1) and base workchain (0)");
return;
}
@ -84,16 +84,16 @@ void Collator::start_up() {
fatal_error(-666, "collator is busy creating another block candidate");
return;
}
if (!shard.is_valid_ext()) {
if (!shard_.is_valid_ext()) {
fatal_error(-666, "requested to generate a block for an invalid shard");
return;
}
td::uint64 x = td::lower_bit64(shard.shard);
td::uint64 x = td::lower_bit64(get_shard());
if (x < 8) {
fatal_error(-666, "cannot split a shard more than 60 times");
return;
}
if (is_masterchain() && !shard.is_masterchain_ext()) {
if (is_masterchain() && !shard_.is_masterchain_ext()) {
fatal_error(-666, "sub-shards cannot exist in the masterchain");
return;
}
@ -114,8 +114,8 @@ void Collator::start_up() {
fatal_error(-666, "cannot merge shards in masterchain");
return;
}
if (!(shard_is_parent(shard, ShardIdFull(prev_blocks[0])) && shard_is_parent(shard, ShardIdFull(prev_blocks[1])) &&
prev_blocks[0].id.shard < prev_blocks[1].id.shard)) {
if (!(shard_is_parent(shard_, ShardIdFull(prev_blocks[0])) &&
shard_is_parent(shard_, ShardIdFull(prev_blocks[1])) && prev_blocks[0].id.shard < prev_blocks[1].id.shard)) {
fatal_error(
-666, "the two previous blocks for a merge operation are not siblings or are not children of current shard");
return;
@ -127,7 +127,7 @@ void Collator::start_up() {
}
}
after_merge_ = true;
LOG(INFO) << "AFTER_MERGE set for the new block of " << shard.to_str();
LOG(INFO) << "AFTER_MERGE set for the new block of " << shard_.to_str();
} else {
CHECK(prev_blocks.size() == 1);
// creating next block
@ -135,12 +135,12 @@ void Collator::start_up() {
fatal_error(-666, "previous block does not have a valid id");
return;
}
if (ShardIdFull(prev_blocks[0]) != shard) {
if (ShardIdFull(prev_blocks[0]) != shard_) {
after_split_ = true;
right_child_ = ton::is_right_child(shard);
LOG(INFO) << "AFTER_SPLIT set for the new block of " << shard.to_str() << " (generating "
right_child_ = ton::is_right_child(shard_);
LOG(INFO) << "AFTER_SPLIT set for the new block of " << shard_.to_str() << " (generating "
<< (right_child_ ? "right" : "left") << " child)";
if (!shard_is_parent(ShardIdFull(prev_blocks[0]), shard)) {
if (!shard_is_parent(ShardIdFull(prev_blocks[0]), shard_)) {
fatal_error(-666, "previous block does not belong to the shard we are generating a new block for");
return;
}
@ -156,7 +156,7 @@ void Collator::start_up() {
return;
}
}
busy = true;
busy_ = true;
step = 1;
if (!is_masterchain()) {
// 2. learn latest masterchain state and block id
@ -198,7 +198,7 @@ void Collator::start_up() {
// 4. load external messages
LOG(DEBUG) << "sending get_external_messages() query to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages, shard,
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages, shard_,
[self = get_self()](td::Result<std::vector<Ref<ExtMessage>>> res) -> void {
LOG(DEBUG) << "got answer to get_external_messages() query";
td::actor::send_closure_later(std::move(self), &Collator::after_get_external_messages,
@ -248,10 +248,10 @@ std::string show_shard(const ton::ShardIdFull blk_id) {
bool Collator::fatal_error(td::Status error) {
error.ensure_error();
LOG(ERROR) << "cannot generate block candidate for " << show_shard(shard) << " : " << error.to_string();
if (busy) {
LOG(ERROR) << "cannot generate block candidate for " << show_shard(shard_) << " : " << error.to_string();
if (busy_) {
main_promise(std::move(error));
busy = false;
busy_ = false;
}
stop();
return false;
@ -548,11 +548,33 @@ bool Collator::unpack_last_mc_state() {
return true;
}
bool Collator::check_cur_validator_set() {
CatchainSeqno cc_seqno = 0;
auto nodes = config_->compute_validator_set_cc(shard_, now_, &cc_seqno);
if (nodes.empty()) {
return fatal_error("cannot compute validator set for shard "s + shard_.to_str() + " from old masterchain state");
}
std::vector<ValidatorDescr> export_nodes;
if (validator_set_.not_null()) {
if (validator_set_->get_catchain_seqno() != cc_seqno) {
return fatal_error(PSTRING() << "current validator set catchain seqno mismatch: this validator set has cc_seqno="
<< validator_set_->get_catchain_seqno() << ", only validator set with cc_seqno="
<< cc_seqno << " is entitled to create block in shardchain " << shard_.to_str());
}
export_nodes = validator_set_->export_vector();
}
if (export_nodes != nodes /* && !is_fake_ */) {
return fatal_error(
"current validator set mismatch: this validator set is not entitled to create block in shardchain "s +
shard_.to_str());
}
return true;
}
bool Collator::request_neighbor_msg_queues() {
assert(config_ && shard_conf_);
auto neighbor_list = shard_conf_->get_neighbor_shard_hash_ids(shard);
LOG(DEBUG) << "got a preliminary list of " << neighbor_list.size() << " neighbors for "
<< block::ShardId{shard}.to_str();
auto neighbor_list = shard_conf_->get_neighbor_shard_hash_ids(shard_);
LOG(DEBUG) << "got a preliminary list of " << neighbor_list.size() << " neighbors for " << shard_.to_str();
for (ton::BlockId blk_id : neighbor_list) {
auto shard_ptr = shard_conf_->get_shard_hash(ton::ShardIdFull(blk_id));
if (shard_ptr.is_null()) {
@ -711,9 +733,9 @@ bool Collator::unpack_one_last_state(block::ShardState& ss, BlockIdExt blkid, Re
}
bool Collator::split_last_state(block::ShardState& ss) {
LOG(INFO) << "Splitting previous state " << ss.id_.to_str() << " to subshard " << shard.to_str();
LOG(INFO) << "Splitting previous state " << ss.id_.to_str() << " to subshard " << shard_.to_str();
CHECK(after_split_);
auto sib_shard = ton::shard_sibling(shard);
auto sib_shard = ton::shard_sibling(shard_);
auto res1 = ss.compute_split_out_msg_queue(sib_shard);
if (res1.is_error()) {
return fatal_error(res1.move_as_error());
@ -724,7 +746,7 @@ bool Collator::split_last_state(block::ShardState& ss) {
return fatal_error(res2.move_as_error());
}
sibling_processed_upto_ = res2.move_as_ok();
auto res3 = ss.split(shard);
auto res3 = ss.split(shard_);
if (res3.is_error()) {
return fatal_error(std::move(res3));
}
@ -763,10 +785,10 @@ bool Collator::add_trivial_neighbor_after_merge() {
std::size_t n = neighbors_.size();
for (std::size_t i = 0; i < n; i++) {
auto& nb = neighbors_.at(i);
if (ton::shard_intersects(nb.shard(), shard)) {
if (ton::shard_intersects(nb.shard(), shard_)) {
++found;
LOG(DEBUG) << "neighbor #" << i << " : " << nb.blk_.to_str() << " intersects our shard " << shard.to_str();
if (!ton::shard_is_parent(shard, nb.shard()) || found > 2) {
LOG(DEBUG) << "neighbor #" << i << " : " << nb.blk_.to_str() << " intersects our shard " << shard_.to_str();
if (!ton::shard_is_parent(shard_, nb.shard()) || found > 2) {
return fatal_error("impossible shard configuration in add_trivial_neighbor_after_merge()");
}
auto prev_shard = prev_blocks.at(found - 1).shard_full();
@ -777,7 +799,7 @@ bool Collator::add_trivial_neighbor_after_merge() {
if (found == 1) {
nb.set_queue_root(out_msg_queue_->get_root_cell());
nb.processed_upto = processed_upto_;
nb.blk_.id.shard = shard.shard;
nb.blk_.id.shard = get_shard();
LOG(DEBUG) << "adjusted neighbor #" << i << " : " << nb.blk_.to_str()
<< " with shard expansion (immediate after-merge adjustment)";
} else {
@ -828,11 +850,11 @@ bool Collator::add_trivial_neighbor() {
std::size_t n = neighbors_.size();
for (std::size_t i = 0; i < n; i++) {
auto& nb = neighbors_.at(i);
if (ton::shard_intersects(nb.shard(), shard)) {
if (ton::shard_intersects(nb.shard(), shard_)) {
++found;
LOG(DEBUG) << "neighbor #" << i << " : " << nb.blk_.to_str() << " intersects our shard " << shard.to_str();
LOG(DEBUG) << "neighbor #" << i << " : " << nb.blk_.to_str() << " intersects our shard " << shard_.to_str();
if (nb.shard() == prev_shard) {
if (prev_shard == shard) {
if (prev_shard == shard_) {
// case 1. Normal.
CHECK(found == 1);
nb = *descr_ref;
@ -840,7 +862,7 @@ bool Collator::add_trivial_neighbor() {
nb.processed_upto = processed_upto_;
LOG(DEBUG) << "adjusted neighbor #" << i << " : " << nb.blk_.to_str() << " (simple replacement)";
cs = 1;
} else if (ton::shard_is_parent(nb.shard(), shard)) {
} else if (ton::shard_is_parent(nb.shard(), shard_)) {
// case 2. Immediate after-split.
CHECK(found == 1);
CHECK(after_split_);
@ -850,20 +872,20 @@ bool Collator::add_trivial_neighbor() {
auto& nb2 = neighbors_.at(i);
nb2.set_queue_root(sibling_out_msg_queue_->get_root_cell());
nb2.processed_upto = sibling_processed_upto_;
nb2.blk_.id.shard = ton::shard_sibling(shard.shard);
nb2.blk_.id.shard = ton::shard_sibling(get_shard());
LOG(DEBUG) << "adjusted neighbor #" << i << " : " << nb2.blk_.to_str()
<< " with shard shrinking to our sibling (immediate after-split adjustment)";
auto& nb1 = neighbors_.at(n);
nb1.set_queue_root(out_msg_queue_->get_root_cell());
nb1.processed_upto = processed_upto_;
nb1.blk_.id.shard = shard.shard;
nb1.blk_.id.shard = get_shard();
LOG(DEBUG) << "created neighbor #" << n << " : " << nb1.blk_.to_str()
<< " with shard shrinking to our (immediate after-split adjustment)";
cs = 2;
} else {
return fatal_error("impossible shard configuration in add_trivial_neighbor()");
}
} else if (ton::shard_is_parent(nb.shard(), shard) && shard == prev_shard) {
} else if (ton::shard_is_parent(nb.shard(), shard_) && shard_ == prev_shard) {
// case 3. Continued after-split
CHECK(found == 1);
CHECK(!after_split_);
@ -871,14 +893,14 @@ bool Collator::add_trivial_neighbor() {
CHECK(!sibling_processed_upto_);
neighbors_.emplace_back(*descr_ref);
auto& nb2 = neighbors_.at(i);
auto sib_shard = ton::shard_sibling(shard);
auto sib_shard = ton::shard_sibling(shard_);
// compute the part of virtual sibling's OutMsgQueue with destinations in our shard
sibling_out_msg_queue_ =
std::make_unique<vm::AugmentedDictionary>(nb2.outmsg_root, 352, block::tlb::aug_OutMsgQueue);
td::BitArray<96> pfx;
pfx.bits().store_int(shard.workchain, 32);
(pfx.bits() + 32).store_uint(shard.shard, 64);
int l = ton::shard_prefix_length(shard);
pfx.bits().store_int(workchain(), 32);
(pfx.bits() + 32).store_uint(get_shard(), 64);
int l = ton::shard_prefix_length(shard_);
CHECK(sibling_out_msg_queue_->cut_prefix_subdict(pfx.bits(), 32 + l));
int res2 = block::filter_out_msg_queue(*sibling_out_msg_queue_, nb2.shard(), sib_shard);
if (res2 < 0) {
@ -888,7 +910,7 @@ bool Collator::add_trivial_neighbor() {
if (!nb2.processed_upto->split(sib_shard)) {
return fatal_error("error splitting ProcessedUpto for our virtual sibling");
}
nb2.blk_.id.shard = ton::shard_sibling(shard.shard);
nb2.blk_.id.shard = ton::shard_sibling(get_shard());
LOG(DEBUG) << "adjusted neighbor #" << i << " : " << nb2.blk_.to_str()
<< " with shard shrinking to our sibling (continued after-split adjustment)";
auto& nb1 = neighbors_.at(n);
@ -897,7 +919,7 @@ bool Collator::add_trivial_neighbor() {
LOG(DEBUG) << "created neighbor #" << n << " : " << nb1.blk_.to_str()
<< " from our preceding state (continued after-split adjustment)";
cs = 3;
} else if (ton::shard_is_parent(shard, nb.shard()) && shard == prev_shard) {
} else if (ton::shard_is_parent(shard_, nb.shard()) && shard_ == prev_shard) {
// case 4. Continued after-merge.
if (found == 1) {
cs = 4;
@ -946,7 +968,7 @@ bool Collator::check_prev_block(const BlockIdExt& listed, const BlockIdExt& prev
bool Collator::check_prev_block_exact(const BlockIdExt& listed, const BlockIdExt& prev) {
if (listed != prev) {
return fatal_error(PSTRING() << "cannot generate shardchain block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot generate shardchain block for shard " << shard_.to_str()
<< " after previous block " << prev.to_str()
<< " because masterchain configuration expects another previous block "
<< listed.to_str() << " and we are immediately after a split/merge event");
@ -982,28 +1004,28 @@ bool Collator::check_this_shard_mc_info() {
<< (prev_blocks.size() ? prev_blocks[0].to_str() : "(null)")
<< " because no shard for this workchain is declared yet");
}
auto left = config_->get_shard_hash(shard - 1, false);
auto left = config_->get_shard_hash(shard_ - 1, false);
if (left.is_null()) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new block for shard " << shard_.to_str()
<< " because there is no similar shard in existing masterchain configuration");
}
if (left->shard() == shard) {
if (left->shard() == shard_) {
// no split/merge
if (after_merge_ || after_split_) {
return fatal_error(
PSTRING() << "cannot generate new shardchain block for " << shard.to_str()
PSTRING() << "cannot generate new shardchain block for " << shard_.to_str()
<< " after a supposed split or merge event because this event is not reflected in the masterchain");
}
if (!check_prev_block(left->blk_, prev_blocks[0])) {
return false;
}
if (left->before_split_) {
return fatal_error(PSTRING() << "cannot generate new unsplit shardchain block for " << shard.to_str()
return fatal_error(PSTRING() << "cannot generate new unsplit shardchain block for " << shard_.to_str()
<< " after previous block " << left->blk_.to_str() << " with before_split set");
}
auto sib = config_->get_shard_hash(shard_sibling(shard));
auto sib = config_->get_shard_hash(shard_sibling(shard_));
if (left->before_merge_ && sib->before_merge_) {
return fatal_error(PSTRING() << "cannot generate new unmerged shardchain block for " << shard.to_str()
return fatal_error(PSTRING() << "cannot generate new unmerged shardchain block for " << shard_.to_str()
<< " after both " << left->blk_.to_str() << " and " << sib->blk_.to_str()
<< " set before_merge flags");
}
@ -1012,35 +1034,35 @@ bool Collator::check_this_shard_mc_info() {
if (shard_splitting_enabled && tmp_now >= left->fsm_utime() && tmp_now + 13 < left->fsm_utime_end()) {
now_upper_limit_ = left->fsm_utime_end() - 11; // ultimate value of now_ must be at most now_upper_limit_
before_split_ = true;
LOG(INFO) << "BEFORE_SPLIT set for the new block of shard " << shard.to_str();
LOG(INFO) << "BEFORE_SPLIT set for the new block of shard " << shard_.to_str();
}
}
} else if (shard_is_parent(shard, left->shard())) {
} else if (shard_is_parent(shard_, left->shard())) {
// after merge
if (!left->before_merge_) {
return fatal_error(PSTRING() << "cannot create new merged block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new merged block for shard " << shard_.to_str()
<< " because its left ancestor " << left->blk_.to_str()
<< " has no before_merge flag");
}
auto right = config_->get_shard_hash(shard + 1, false);
auto right = config_->get_shard_hash(shard_ + 1, false);
if (right.is_null()) {
return fatal_error(
PSTRING()
<< "cannot create new block for shard " << shard.to_str()
<< "cannot create new block for shard " << shard_.to_str()
<< " after a preceding merge because there is no right ancestor shard in existing masterchain configuration");
}
if (!shard_is_parent(shard, right->shard())) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard.to_str()
if (!shard_is_parent(shard_, right->shard())) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard_.to_str()
<< " after a preceding merge because its right ancestor appears to be "
<< right->blk_.to_str());
}
if (!right->before_merge_) {
return fatal_error(PSTRING() << "cannot create new merged block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new merged block for shard " << shard_.to_str()
<< " because its right ancestor " << right->blk_.to_str()
<< " has no before_merge flag");
}
if (after_split_) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new block for shard " << shard_.to_str()
<< " after a purported split because existing shard configuration suggests a merge");
} else if (after_merge_) {
if (!(check_prev_block_exact(left->blk_, prev_blocks[0]) &&
@ -1050,27 +1072,27 @@ bool Collator::check_this_shard_mc_info() {
} else {
auto cseqno = std::max(left->seqno(), right->seqno());
if (prev_blocks[0].seqno() <= cseqno) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new block for shard " << shard_.to_str()
<< " after previous block " << prev_blocks[0].to_str()
<< " because masterchain contains newer possible ancestors " << left->blk_.to_str()
<< " and " << right->blk_.to_str());
}
if (prev_blocks[0].seqno() >= cseqno + 8) {
return fatal_error(
PSTRING() << "cannot create new block for shard " << shard.to_str() << " after previous block "
PSTRING() << "cannot create new block for shard " << shard_.to_str() << " after previous block "
<< prev_blocks[0].to_str()
<< " because this would lead to an unregistered chain of length > 8 (masterchain contains only "
<< left->blk_.to_str() << " and " << right->blk_.to_str() << ")");
}
}
} else if (shard_is_parent(left->shard(), shard)) {
} else if (shard_is_parent(left->shard(), shard_)) {
// after split
if (!left->before_split_) {
return fatal_error(PSTRING() << "cannot generate new split shardchain block for " << shard.to_str()
return fatal_error(PSTRING() << "cannot generate new split shardchain block for " << shard_.to_str()
<< " after previous block " << left->blk_.to_str() << " without before_split");
}
if (after_merge_) {
return fatal_error(PSTRING() << "cannot create new block for shard " << shard.to_str()
return fatal_error(PSTRING() << "cannot create new block for shard " << shard_.to_str()
<< " after a purported merge because existing shard configuration suggests a split");
} else if (after_split_) {
if (!(check_prev_block_exact(left->blk_, prev_blocks[0]))) {
@ -1083,7 +1105,7 @@ bool Collator::check_this_shard_mc_info() {
}
} else {
return fatal_error(PSTRING() << "masterchain configuration contains only block " << left->blk_.to_str()
<< " which belongs to a different shard from ours " << shard.to_str());
<< " which belongs to a different shard from ours " << shard_.to_str());
}
return true;
}
@ -1109,7 +1131,7 @@ bool Collator::do_preinit() {
last_block_seqno = prev_blocks[1].seqno();
}
new_block_seqno = last_block_seqno + 1;
new_id = ton::BlockId{shard, new_block_seqno};
new_id = ton::BlockId{shard_, new_block_seqno};
CHECK(!config_);
CHECK(mc_state_root.not_null());
LOG(INFO) << "unpacking most recent masterchain state";
@ -1123,6 +1145,9 @@ bool Collator::do_preinit() {
if (!is_masterchain() && !check_this_shard_mc_info()) {
return fatal_error("fatal error while checking masterchain configuration of the current shard");
}
if (!check_cur_validator_set()) {
return fatal_error("this validator set is not entitled to create a block for this shardchain");
}
CHECK(!prev_mc_block_seqno || mc_block_root.not_null());
if (!unpack_last_state()) {
return fatal_error("cannot unpack previous state of current shardchain");
@ -1642,7 +1667,7 @@ bool Collator::init_value_create() {
value_flow_.minted.set_zero();
}
} else if (workchain() == basechainId) {
value_flow_.created = block::CurrencyCollection{basechain_create_fee_ >> ton::shard_prefix_length(shard)};
value_flow_.created = block::CurrencyCollection{basechain_create_fee_ >> ton::shard_prefix_length(shard_)};
}
value_flow_.fees_collected += value_flow_.created;
return true;
@ -1672,7 +1697,7 @@ bool Collator::do_collate() {
// 1.3. create OutputQueueMerger from adjusted neighbors
CHECK(!nb_out_msgs_);
LOG(DEBUG) << "creating OutputQueueMerger";
nb_out_msgs_ = std::make_unique<block::OutputQueueMerger>(shard, neighbors_);
nb_out_msgs_ = std::make_unique<block::OutputQueueMerger>(shard_, neighbors_);
// 1.4. compute created / minted / recovered
if (!init_value_create()) {
return fatal_error("cannot compute the value to be created / minted / recovered");
@ -1866,7 +1891,7 @@ std::unique_ptr<block::Account> Collator::make_account_from(td::ConstBitPtr addr
if (account.is_null() && !force_create) {
return nullptr;
}
auto ptr = std::make_unique<block::Account>(shard.workchain, addr);
auto ptr = std::make_unique<block::Account>(workchain(), addr);
if (account.is_null()) {
ptr->created = true;
if (!ptr->init_new(now_)) {
@ -1900,8 +1925,9 @@ td::Result<block::Account*> Collator::make_account(td::ConstBitPtr addr, bool fo
if (!new_acc) {
return td::Status::Error(PSTRING() << "cannot load account " << addr.to_hex(256) << " from previous state");
}
if (!new_acc->belongs_to_shard(shard)) {
return td::Status::Error(PSTRING() << "account " << addr.to_hex(256) << " does not really belong to current shard");
if (!new_acc->belongs_to_shard(shard_)) {
return td::Status::Error(PSTRING() << "account " << addr.to_hex(256) << " does not really belong to current shard "
<< shard_.to_str());
}
auto ins = accounts.emplace(addr, std::move(new_acc));
if (!ins.second) {
@ -1920,7 +1946,7 @@ bool Collator::combine_account_transactions() {
// have transactions for this account
vm::CellBuilder cb;
if (!acc.create_account_block(cb)) {
return fatal_error(std::string{"cannot create AccountBlock for account "} + z.first.to_hex());
return fatal_error("cannot create AccountBlock for account "s + z.first.to_hex());
}
auto cell = cb.finalize();
auto csr = vm::load_cell_slice_ref(cell);
@ -2084,8 +2110,8 @@ bool Collator::create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, t
req_start_lt = std::max(req_start_lt, start_lt + 1);
if (acc->last_trans_end_lt_ >= start_lt && acc->transactions.empty()) {
return fatal_error(td::Status::Error(-666, PSTRING()
<< "last transaction time in the state of account "
<< shard.workchain << ":" << smc_addr.to_hex() << " is too large"));
<< "last transaction time in the state of account " << workchain()
<< ":" << smc_addr.to_hex() << " is too large"));
}
std::unique_ptr<block::Transaction> trans = std::make_unique<block::Transaction>(
*acc, mask == 2 ? block::Transaction::tr_tick : block::Transaction::tr_tock, req_start_lt, now_);
@ -2154,7 +2180,7 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
return {};
}
ton::WorkchainId wc;
if (!block::tlb::t_MsgAddressInt.extract_std_address(dest, wc, addr) || wc != shard.workchain) {
if (!block::tlb::t_MsgAddressInt.extract_std_address(dest, wc, addr) || wc != workchain()) {
return {};
}
LOG(DEBUG) << "inbound message to our smart contract " << addr.to_hex();
@ -2166,7 +2192,7 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
block::Account* acc = acc_res.move_as_ok();
assert(acc);
if (acc->last_trans_end_lt_ >= start_lt && acc->transactions.empty()) {
fatal_error(PSTRING() << "last transaction time in the state of account " << shard.workchain << ":" << addr.to_hex()
fatal_error(PSTRING() << "last transaction time in the state of account " << workchain() << ":" << addr.to_hex()
<< " is too large");
return {};
}
@ -2288,11 +2314,11 @@ bool Collator::is_our_address(Ref<vm::CellSlice> addr_ref) const {
}
bool Collator::is_our_address(ton::AccountIdPrefixFull addr_pfx) const {
return ton::shard_contains(shard, addr_pfx);
return ton::shard_contains(shard_, addr_pfx);
}
bool Collator::is_our_address(const ton::StdSmcAddress& addr) const {
return ton::shard_contains(shard.shard, addr);
return ton::shard_contains(get_shard(), addr);
}
// 1 = processed, 0 = enqueued, 3 = processed, all future messages must be enqueued
@ -2410,7 +2436,7 @@ bool Collator::enqueue_transit_message(Ref<vm::Cell> msg, Ref<vm::Cell> old_msg_
LOG(DEBUG) << "enqueueing transit message " << msg->get_hash().bits().to_hex(256);
bool requeue = is_our_address(prev_prefix);
// 1. perform hypercube routing
auto route_info = block::perform_hypercube_routing(cur_prefix, dest_prefix, shard);
auto route_info = block::perform_hypercube_routing(cur_prefix, dest_prefix, shard_);
if ((unsigned)route_info.first > 96 || (unsigned)route_info.second > 96) {
return fatal_error("cannot perform hypercube routing for a transit message");
}
@ -2572,7 +2598,7 @@ bool Collator::process_inbound_message(Ref<vm::CellSlice> enq_msg, ton::LogicalT
return false;
}
// 5.2. next_prefix must belong to our shard
if (!ton::shard_contains(shard, next_prefix)) {
if (!ton::shard_contains(shard_, next_prefix)) {
LOG(ERROR) << "inbound internal message does not have next hop address in our shard";
return false;
}
@ -2594,8 +2620,8 @@ bool Collator::process_inbound_message(Ref<vm::CellSlice> enq_msg, ton::LogicalT
}
// 6. check whether we have already processed this message before using ProcessedUpTo (processed_upto)
// (then silently ignore this message; NB: it can be ours after merge)
bool our = ton::shard_contains(shard, cur_prefix);
bool to_us = ton::shard_contains(shard, dest_prefix);
bool our = ton::shard_contains(shard_, cur_prefix);
bool to_us = ton::shard_contains(shard_, dest_prefix);
block::EnqueuedMsgDescr enq_msg_descr{cur_prefix, next_prefix, info.created_lt, enqueued_lt,
env.msg->get_hash().bits()};
@ -2734,7 +2760,7 @@ int Collator::process_external_message(Ref<vm::Cell> msg) {
// 1. create a Transaction processing this Message
auto trans_root = create_ordinary_transaction(msg);
if (trans_root.is_null()) {
if (busy) {
if (busy_) {
// transaction rejected by account
LOG(DEBUG) << "external message rejected by account, skipping";
return 0;
@ -2846,7 +2872,7 @@ bool Collator::enqueue_message(block::NewOutMsg msg, td::RefInt256 fwd_fees_rema
return fatal_error("cannot enqueue a new message because its destination shard is invalid");
}
// 1. perform hypercube routing
auto route_info = block::perform_hypercube_routing(src_prefix, dest_prefix, shard);
auto route_info = block::perform_hypercube_routing(src_prefix, dest_prefix, shard_);
if ((unsigned)route_info.first > 96 || (unsigned)route_info.second > 96) {
return fatal_error("cannot perform hypercube routing for a new outbound message");
}
@ -3155,10 +3181,10 @@ bool Collator::create_mc_state_extra() {
cc_updated = true;
LOG(INFO) << "increased masterchain catchain seqno to " << val_info.catchain_seqno;
}
auto nodes = block::Config::do_compute_validator_set(ccvc, shard, *cur_validators, now_, val_info.catchain_seqno);
auto nodes = block::Config::do_compute_validator_set(ccvc, shard_, *cur_validators, now_, val_info.catchain_seqno);
LOG_CHECK(!nodes.empty()) << "validator node list in unpacked validator set is empty";
auto vlist_hash = block::compute_validator_set_hash(/* val_info.catchain_seqno */ 0, shard, std::move(nodes));
auto vlist_hash = block::compute_validator_set_hash(/* val_info.catchain_seqno */ 0, shard_, std::move(nodes));
LOG(INFO) << "masterchain validator set hash changed from " << val_info.validator_list_hash_short << " to "
<< vlist_hash;
val_info.nx_cc_updated = cc_updated & update_shard_cc;
@ -3542,7 +3568,7 @@ bool Collator::create_shard_state() {
if (!(cb.store_long_bool(0x9023afe2, 32) // shard_state#9023afe2
&& cb.store_long_bool(global_id_, 32) // global_id:int32
&& global_id_ // { global_id != 0 }
&& block::ShardId{shard}.serialize(cb) // shard_id:ShardIdent
&& block::ShardId{shard_}.serialize(cb) // shard_id:ShardIdent
&& cb.store_long_bool(new_block_seqno, 32) // seq_no:uint32
&& cb.store_long_bool(vert_seqno_, 32) // vert_seq_no:#
&& cb.store_long_bool(now_, 32) // gen_utime:uint32
@ -3668,8 +3694,8 @@ bool Collator::compute_total_balance() {
bool Collator::create_block_info(Ref<vm::Cell>& block_info) {
vm::CellBuilder cb, cb2;
bool mc = is_masterchain();
td::uint32 val_hash = validator_set->get_validator_set_hash();
CatchainSeqno cc_seqno = validator_set->get_catchain_seqno();
td::uint32 val_hash = validator_set_->get_validator_set_hash();
CatchainSeqno cc_seqno = validator_set_->get_catchain_seqno();
return cb.store_long_bool(0x9bc7a987, 32) // block_info#9bc7a987
&& cb.store_long_bool(0, 32) // version:uint32
&& cb.store_bool_bool(!mc) // not_master:(## 1)
@ -3682,7 +3708,7 @@ bool Collator::create_block_info(Ref<vm::Cell>& block_info) {
&& cb.store_long_bool((int)report_version_, 9) // vert_seqno_incr:(## 1) flags:(## 8)
&& cb.store_long_bool(new_block_seqno, 32) // seq_no:#
&& cb.store_long_bool(vert_seqno_, 32) // vert_seq_no:#
&& block::ShardId{shard}.serialize(cb) // shard:ShardIdent
&& block::ShardId{shard_}.serialize(cb) // shard:ShardIdent
&& cb.store_long_bool(now_, 32) // gen_utime:uint32
&& cb.store_long_bool(start_lt, 64) // start_lt:uint64
&& cb.store_long_bool(max_lt, 64) // end_lt:uint64
@ -3891,7 +3917,7 @@ bool Collator::create_block_candidate() {
// 3. create a BlockCandidate
block_candidate = std::make_unique<BlockCandidate>(
created_by_,
ton::BlockIdExt{ton::BlockId{shard, new_block_seqno}, new_block->get_hash().bits(),
ton::BlockIdExt{ton::BlockId{shard_, new_block_seqno}, new_block->get_hash().bits(),
block::compute_file_hash(blk_slice.as_slice())},
block::compute_file_hash(cdata_slice.as_slice()), blk_slice.clone(), cdata_slice.clone());
// 4. save block candidate
@ -3921,7 +3947,7 @@ void Collator::return_block_candidate(td::Result<td::Unit> saved) {
CHECK(block_candidate);
LOG(INFO) << "sending new BlockCandidate to Promise";
main_promise(block_candidate->clone());
busy = false;
busy_ = false;
stop();
}
}
@ -3965,7 +3991,7 @@ td::Result<bool> Collator::register_external_message_cell(Ref<vm::Cell> ext_msg,
return td::Status::Error("destination of an inbound external message is an invalid blockchain address");
}
// NB: previous checks are quite general and can be done at an outer level before multiplexing to correct Collator
if (!ton::shard_contains(shard, dest_prefix)) {
if (!ton::shard_contains(shard_, dest_prefix)) {
return td::Status::Error("inbound external message has destination address not in this shard");
}
if (verbosity > 2) {

View file

@ -1737,14 +1737,20 @@ bool ValidateQuery::register_shard_block_creators(std::vector<td::Bits256> creat
return true;
}
// similar to Collator::check_cur_validator_set()
bool ValidateQuery::check_cur_validator_set() {
CatchainSeqno cc_seqno = 0;
auto nodes = config_->compute_validator_set_cc(shard_, now_, &cc_seqno);
if (nodes.empty()) {
return reject_query("cannot compute masterchain validator set from old masterchain state");
return reject_query("cannot compute validator set for shard "s + shard_.to_str() + " from old masterchain state");
}
std::vector<ValidatorDescr> export_nodes;
if (validator_set_.not_null()) {
if (validator_set_->get_catchain_seqno() != cc_seqno) {
return reject_query(PSTRING() << "current validator set catchain seqno mismatch: this validator set has cc_seqno="
<< validator_set_->get_catchain_seqno() << ", only validator set with cc_seqno="
<< cc_seqno << " is entitled to create block " << id_.to_str());
}
export_nodes = validator_set_->export_vector();
}
if (export_nodes != nodes /* && !is_fake_ */) {

View file

@ -30,15 +30,16 @@ namespace validator {
namespace fullnode {
DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl::AdnlNodeIdShort local_id,
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from,
td::uint32 priority, td::Timestamp timeout,
DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, bool is_key_block,
adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id,
adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
td::Promise<td::BufferSlice> promise)
: block_id_(block_id)
, allow_partial_proof_(allow_partial_proof)
, is_key_block_(is_key_block)
, local_id_(local_id)
, overlay_id_(overlay_id)
, download_from_(download_from)
@ -155,8 +156,14 @@ void DownloadProof::got_node_to_download(adnl::AdnlNodeIdShort node) {
}
});
auto query = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
td::BufferSlice query;
if (!is_key_block_) {
query = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_);
} else {
query = create_serialize_tl_object<ton_api::tonNode_prepareKeyBlockProof>(create_tl_block_id(block_id_),
allow_partial_proof_);
}
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
@ -190,7 +197,12 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
auto query = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
td::BufferSlice query;
if (!is_key_block_) {
query = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
} else {
query = create_serialize_tl_object<ton_api::tonNode_downloadKeyBlockProof>(create_tl_block_id(block_id_));
}
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download block proof", std::move(P), td::Timestamp::in(3.0),
@ -214,8 +226,14 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
}
});
auto query =
td::BufferSlice query;
if (!is_key_block_) {
query =
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_));
} else {
query =
create_serialize_tl_object<ton_api::tonNode_downloadKeyBlockProofLink>(create_tl_block_id(block_id_));
}
if (client_.empty()) {
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
overlay_id_, "download block proof link", std::move(P), td::Timestamp::in(3.0),

View file

@ -32,7 +32,7 @@ namespace fullnode {
class DownloadProof : public td::actor::Actor {
public:
DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl::AdnlNodeIdShort local_id,
DownloadProof(BlockIdExt block_id, bool allow_partial_proof, bool is_key_block, adnl::AdnlNodeIdShort local_id,
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
@ -54,6 +54,7 @@ class DownloadProof : public td::actor::Actor {
private:
BlockIdExt block_id_;
bool allow_partial_proof_;
bool is_key_block_;
adnl::AdnlNodeIdShort local_id_;
overlay::OverlayIdShort overlay_id_;

View file

@ -178,9 +178,9 @@ void GetNextKeyBlocks::download_next_proof() {
}
});
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, local_id_, overlay_id_, download_from_,
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, client_,
std::move(P))
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, true, local_id_, overlay_id_,
download_from_, priority_, timeout_, validator_manager_, rldp_, overlays_,
adnl_, client_, std::move(P))
.release();
}