mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'testnet' into block-generation
This commit is contained in:
commit
a745f6f679
16 changed files with 453 additions and 126 deletions
|
@ -25,6 +25,8 @@ set(VALIDATOR_DB_SOURCE
|
|||
db/statedb.cpp
|
||||
db/staticfilesdb.cpp
|
||||
db/staticfilesdb.hpp
|
||||
db/db-utils.cpp
|
||||
db/db-utils.h
|
||||
|
||||
db/package.hpp
|
||||
db/package.cpp
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "td/utils/port/path.h"
|
||||
#include "common/delay.h"
|
||||
#include "files-async.hpp"
|
||||
#include "db-utils.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -41,16 +42,14 @@ class PackageStatistics {
|
|||
|
||||
void record_read(double time, uint64_t bytes) {
|
||||
read_bytes.fetch_add(bytes, std::memory_order_relaxed);
|
||||
std::lock_guard<std::mutex> guard(read_mutex);
|
||||
std::lock_guard guard(read_mutex);
|
||||
read_time.insert(time);
|
||||
read_time_sum += time;
|
||||
}
|
||||
|
||||
void record_write(double time, uint64_t bytes) {
|
||||
write_bytes.fetch_add(bytes, std::memory_order_relaxed);
|
||||
std::lock_guard<std::mutex> guard(write_mutex);
|
||||
std::lock_guard guard(write_mutex);
|
||||
write_time.insert(time);
|
||||
write_time_sum += time;
|
||||
}
|
||||
|
||||
std::string to_string_and_reset() {
|
||||
|
@ -64,68 +63,35 @@ class PackageStatistics {
|
|||
ss << "ton.pack.read.bytes COUNT : " << read_bytes.exchange(0, std::memory_order_relaxed) << "\n";
|
||||
ss << "ton.pack.write.bytes COUNT : " << write_bytes.exchange(0, std::memory_order_relaxed) << "\n";
|
||||
|
||||
std::multiset<double> temp_read_time;
|
||||
double temp_read_time_sum;
|
||||
PercentileStats temp_read_time;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(read_mutex);
|
||||
std::lock_guard guard(read_mutex);
|
||||
temp_read_time = std::move(read_time);
|
||||
read_time.clear();
|
||||
temp_read_time_sum = read_time_sum;
|
||||
read_time_sum = 0;
|
||||
}
|
||||
auto read_stats = calculate_statistics(temp_read_time);
|
||||
ss << "ton.pack.read.micros P50 : " << read_stats[0] <<
|
||||
" P95 : " << read_stats[1] <<
|
||||
" P99 : " << read_stats[2] <<
|
||||
" P100 : " << read_stats[3] <<
|
||||
" COUNT : " << temp_read_time.size() <<
|
||||
" SUM : " << temp_read_time_sum << "\n";
|
||||
ss << "ton.pack.read.micros " << temp_read_time.to_string() << "\n";
|
||||
|
||||
std::multiset<double> temp_write_time;
|
||||
double temp_write_time_sum;
|
||||
PercentileStats temp_write_time;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(write_mutex);
|
||||
std::lock_guard guard(write_mutex);
|
||||
temp_write_time = std::move(write_time);
|
||||
write_time.clear();
|
||||
temp_write_time_sum = write_time_sum;
|
||||
write_time_sum = 0;
|
||||
}
|
||||
auto write_stats = calculate_statistics(temp_write_time);
|
||||
ss << "ton.pack.write.micros P50 : " << write_stats[0] <<
|
||||
" P95 : " << write_stats[1] <<
|
||||
" P99 : " << write_stats[2] <<
|
||||
" P100 : " << write_stats[3] <<
|
||||
" COUNT : " << temp_write_time.size() <<
|
||||
" SUM : " << temp_write_time_sum << "\n";
|
||||
ss << "ton.pack.write.micros " << temp_write_time.to_string() << "\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_uint64_t open_count;
|
||||
std::atomic_uint64_t close_count;
|
||||
std::multiset<double> read_time;
|
||||
std::atomic_uint64_t read_bytes;
|
||||
std::multiset<double> write_time;
|
||||
std::atomic_uint64_t write_bytes;
|
||||
double read_time_sum;
|
||||
double write_time_sum;
|
||||
std::atomic_uint64_t open_count{0};
|
||||
std::atomic_uint64_t close_count{0};
|
||||
PercentileStats read_time;
|
||||
std::atomic_uint64_t read_bytes{0};
|
||||
PercentileStats write_time;
|
||||
std::atomic_uint64_t write_bytes{0};
|
||||
|
||||
mutable std::mutex read_mutex;
|
||||
mutable std::mutex write_mutex;
|
||||
|
||||
std::vector<double> calculate_statistics(const std::multiset<double>& data) const {
|
||||
if (data.empty()) return {0, 0, 0, 0};
|
||||
|
||||
auto size = data.size();
|
||||
auto calc_percentile = [&](double p) -> double {
|
||||
auto it = data.begin();
|
||||
std::advance(it, static_cast<int>(std::ceil(p * double(size)) - 1));
|
||||
return *it;
|
||||
};
|
||||
|
||||
return {calc_percentile(0.5), calc_percentile(0.95), calc_percentile(0.99), *data.rbegin()};
|
||||
}
|
||||
};
|
||||
|
||||
void DbStatistics::init() {
|
||||
|
|
|
@ -89,7 +89,7 @@ void CellDbIn::start_up() {
|
|||
statistics_flush_at_ = td::Timestamp::in(60.0);
|
||||
}
|
||||
cell_db_ = std::make_shared<td::RocksDb>(td::RocksDb::open(path_, statistics_).move_as_ok());
|
||||
|
||||
|
||||
|
||||
boc_ = vm::DynamicBagOfCellsDb::create();
|
||||
boc_->set_celldb_compress_depth(opts_->get_celldb_compress_depth());
|
||||
|
@ -155,6 +155,9 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promi
|
|||
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
|
||||
|
||||
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
|
||||
if (!opts_->get_disable_rocksdb_stats()) {
|
||||
cell_db_statistics_.store_cell_time_.insert(timer.elapsed() * 1e6);
|
||||
}
|
||||
}
|
||||
|
||||
void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
|
||||
|
@ -162,8 +165,9 @@ void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>>
|
|||
}
|
||||
|
||||
void CellDbIn::flush_db_stats() {
|
||||
auto stats = td::RocksDb::statistics_to_string(statistics_);
|
||||
auto to_file_r = td::FileFd::open(path_ + "/db_stats.txt", td::FileFd::Truncate | td::FileFd::Create | td::FileFd::Write, 0644);
|
||||
auto stats = td::RocksDb::statistics_to_string(statistics_) + cell_db_statistics_.to_string();
|
||||
auto to_file_r =
|
||||
td::FileFd::open(path_ + "/db_stats.txt", td::FileFd::Truncate | td::FileFd::Create | td::FileFd::Write, 0644);
|
||||
if (to_file_r.is_error()) {
|
||||
LOG(ERROR) << "Failed to open db_stats.txt: " << to_file_r.move_as_error();
|
||||
return;
|
||||
|
@ -176,6 +180,7 @@ void CellDbIn::flush_db_stats() {
|
|||
return;
|
||||
}
|
||||
td::RocksDb::reset_statistics(statistics_);
|
||||
cell_db_statistics_.clear();
|
||||
}
|
||||
|
||||
void CellDbIn::alarm() {
|
||||
|
@ -278,6 +283,9 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
|
|||
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
|
||||
|
||||
DCHECK(get_block(key_hash).is_error());
|
||||
if (!opts_->get_disable_rocksdb_stats()) {
|
||||
cell_db_statistics_.gc_cell_time_.insert(timer.elapsed() * 1e6);
|
||||
}
|
||||
}
|
||||
|
||||
void CellDbIn::skip_gc() {
|
||||
|
@ -441,6 +449,14 @@ td::BufferSlice CellDbIn::DbEntry::release() {
|
|||
return create_serialize_tl_object<ton_api::db_celldb_value>(create_tl_block_id(block_id), prev, next, root_hash);
|
||||
}
|
||||
|
||||
std::string CellDbIn::CellDbStatistics::to_string() {
|
||||
td::StringBuilder ss;
|
||||
ss << "ton.celldb.store_cell.micros " << store_cell_time_.to_string() << "\n";
|
||||
ss << "ton.celldb.gc_cell.micros " << gc_cell_time_.to_string() << "\n";
|
||||
ss << "ton.celldb.total_time.micros : " << (td::Timestamp::now().at() - stats_start_time_.at()) * 1e6 << "\n";
|
||||
return ss.as_cslice().str();
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "interfaces/block-handle.h"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "validator.h"
|
||||
#include "db-utils.h"
|
||||
|
||||
namespace rocksdb {
|
||||
class Statistics;
|
||||
|
@ -42,9 +43,11 @@ class CellDbAsyncExecutor;
|
|||
|
||||
class CellDbBase : public td::actor::Actor {
|
||||
public:
|
||||
virtual void start_up();
|
||||
void start_up() override;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<vm::DynamicBagOfCellsDb::AsyncExecutor> async_executor;
|
||||
|
||||
private:
|
||||
void execute_sync(std::function<void()> f);
|
||||
friend CellDbAsyncExecutor;
|
||||
|
@ -76,8 +79,7 @@ class CellDbIn : public CellDbBase {
|
|||
RootHash root_hash;
|
||||
|
||||
DbEntry(tl_object_ptr<ton_api::db_celldb_value> entry);
|
||||
DbEntry() {
|
||||
}
|
||||
DbEntry() = default;
|
||||
DbEntry(BlockIdExt block_id, KeyHash prev, KeyHash next, RootHash root_hash)
|
||||
: block_id(block_id), prev(prev), next(next), root_hash(root_hash) {
|
||||
}
|
||||
|
@ -109,8 +111,6 @@ class CellDbIn : public CellDbBase {
|
|||
|
||||
std::unique_ptr<vm::DynamicBagOfCellsDb> boc_;
|
||||
std::shared_ptr<vm::KeyValue> cell_db_;
|
||||
std::shared_ptr<rocksdb::Statistics> statistics_;
|
||||
td::Timestamp statistics_flush_at_ = td::Timestamp::never();
|
||||
|
||||
std::function<void(const vm::CellLoader::LoadResult&)> on_load_callback_;
|
||||
std::set<td::Bits256> cells_to_migrate_;
|
||||
|
@ -127,6 +127,21 @@ class CellDbIn : public CellDbBase {
|
|||
};
|
||||
std::unique_ptr<MigrationStats> migration_stats_;
|
||||
|
||||
struct CellDbStatistics {
|
||||
PercentileStats store_cell_time_;
|
||||
PercentileStats gc_cell_time_;
|
||||
td::Timestamp stats_start_time_ = td::Timestamp::now();
|
||||
|
||||
std::string to_string();
|
||||
void clear() {
|
||||
*this = CellDbStatistics{};
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<rocksdb::Statistics> statistics_;
|
||||
CellDbStatistics cell_db_statistics_;
|
||||
td::Timestamp statistics_flush_at_ = td::Timestamp::never();
|
||||
|
||||
public:
|
||||
class MigrationProxy : public td::actor::Actor {
|
||||
public:
|
||||
|
|
54
validator/db/db-utils.cpp
Normal file
54
validator/db/db-utils.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#include "db-utils.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace ton::validator {
|
||||
|
||||
void PercentileStats::insert(double value) {
|
||||
values_.insert(value);
|
||||
}
|
||||
|
||||
std::string PercentileStats::to_string() const {
|
||||
double percentiles[4] = {0.0, 0.0, 0.0, 0.0};
|
||||
double sum = 0.0;
|
||||
size_t size = values_.size();
|
||||
if (!values_.empty()) {
|
||||
size_t indices[4] = {(size_t)std::ceil(0.5 * (double)size) - 1, (size_t)std::ceil(0.95 * (double)size) - 1,
|
||||
(size_t)std::ceil(0.99 * (double)size) - 1, size - 1};
|
||||
size_t i = 0;
|
||||
for (auto it = values_.begin(); it != values_.end(); ++it, ++i) {
|
||||
for (size_t j = 0; j < 4; ++j) {
|
||||
if (indices[j] == i) {
|
||||
percentiles[j] = *it;
|
||||
}
|
||||
}
|
||||
sum += *it;
|
||||
}
|
||||
}
|
||||
return PSTRING() << "P50 : " << percentiles[0] << " P95 : " << percentiles[1] << " P99 : " << percentiles[2]
|
||||
<< " P100 : " << percentiles[3] << " COUNT : " << size << " SUM : " << sum;
|
||||
}
|
||||
|
||||
void PercentileStats::clear() {
|
||||
values_.clear();
|
||||
}
|
||||
|
||||
} // namespace ton::validator
|
33
validator/db/db-utils.h
Normal file
33
validator/db/db-utils.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace ton::validator {
|
||||
|
||||
class PercentileStats {
|
||||
public:
|
||||
void insert(double value);
|
||||
std::string to_string() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::multiset<double> values_;
|
||||
};
|
||||
|
||||
} // namespace ton::validator
|
|
@ -2913,8 +2913,12 @@ void ValidatorManagerImpl::log_validator_session_stats(BlockIdExt block_id,
|
|||
std::vector<tl_object_ptr<ton_api::validatorSession_statsProducer>> producers;
|
||||
for (const auto &producer : round.producers) {
|
||||
producers.push_back(create_tl_object<ton_api::validatorSession_statsProducer>(
|
||||
producer.id.bits256_value(), producer.candidate_id, producer.block_status, producer.block_timestamp,
|
||||
producer.comment));
|
||||
producer.id.bits256_value(), producer.candidate_id, producer.block_status, producer.comment,
|
||||
producer.block_timestamp, producer.is_accepted, producer.is_ours, producer.got_submit_at,
|
||||
producer.collation_time, producer.collated_at, producer.collation_cached, producer.validation_time,
|
||||
producer.validated_at, producer.validation_cached, producer.gen_utime, producer.approved_weight,
|
||||
producer.approved_33pct_at, producer.approved_66pct_at, producer.signed_weight, producer.signed_33pct_at,
|
||||
producer.signed_66pct_at, producer.serialize_time, producer.deserialize_time, producer.serialized_size));
|
||||
}
|
||||
rounds.push_back(create_tl_object<ton_api::validatorSession_statsRound>(round.timestamp, std::move(producers)));
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace ton {
|
|||
|
||||
namespace validator {
|
||||
|
||||
void ValidatorGroup::generate_block_candidate(td::uint32 round_id, td::Promise<BlockCandidate> promise) {
|
||||
void ValidatorGroup::generate_block_candidate(
|
||||
td::uint32 round_id, td::Promise<validatorsession::ValidatorSession::GeneratedCandidate> promise) {
|
||||
if (round_id > last_known_round_id_) {
|
||||
last_known_round_id_ = round_id;
|
||||
}
|
||||
|
@ -40,14 +41,18 @@ void ValidatorGroup::generate_block_candidate(td::uint32 round_id, td::Promise<B
|
|||
}
|
||||
if (cached_collated_block_) {
|
||||
if (cached_collated_block_->result) {
|
||||
promise.set_result(cached_collated_block_->result.value().clone());
|
||||
promise.set_value({cached_collated_block_->result.value().clone(), true});
|
||||
} else {
|
||||
cached_collated_block_->promises.push_back(std::move(promise));
|
||||
cached_collated_block_->promises.push_back(promise.wrap([](BlockCandidate &&res) {
|
||||
return validatorsession::ValidatorSession::GeneratedCandidate{std::move(res), true};
|
||||
}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
cached_collated_block_ = std::make_shared<CachedCollatedBlock>();
|
||||
cached_collated_block_->promises.push_back(std::move(promise));
|
||||
cached_collated_block_->promises.push_back(promise.wrap([](BlockCandidate &&res) {
|
||||
return validatorsession::ValidatorSession::GeneratedCandidate{std::move(res), false};
|
||||
}));
|
||||
td::Promise<BlockCandidate> P = [SelfId = actor_id(this),
|
||||
cache = cached_collated_block_](td::Result<BlockCandidate> R) {
|
||||
td::actor::send_closure(SelfId, &ValidatorGroup::generated_block_candidate, std::move(cache), std::move(R));
|
||||
|
@ -83,7 +88,7 @@ void ValidatorGroup::generated_block_candidate(std::shared_ptr<CachedCollatedBlo
|
|||
}
|
||||
|
||||
void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidate block,
|
||||
td::Promise<UnixTime> promise) {
|
||||
td::Promise<std::pair<UnixTime, bool>> promise) {
|
||||
if (round_id > last_known_round_id_) {
|
||||
last_known_round_id_ = round_id;
|
||||
}
|
||||
|
@ -98,7 +103,7 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat
|
|||
CacheKey cache_key = block_to_cache_key(block);
|
||||
auto it = approved_candidates_cache_.find(cache_key);
|
||||
if (it != approved_candidates_cache_.end()) {
|
||||
promise.set_result(it->second);
|
||||
promise.set_value({it->second, true});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,7 +128,7 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat
|
|||
ts);
|
||||
td::actor::send_closure(SelfId, &ValidatorGroup::add_available_block_candidate, block.pubkey.as_bits256(),
|
||||
block.id, block.collated_file_hash);
|
||||
promise.set_result(ts);
|
||||
promise.set_value({ts, false});
|
||||
},
|
||||
[&](CandidateReject reject) {
|
||||
promise.set_error(
|
||||
|
@ -241,15 +246,18 @@ std::unique_ptr<validatorsession::ValidatorSession::Callback> ValidatorGroup::ma
|
|||
void on_candidate(td::uint32 round, PublicKey source, validatorsession::ValidatorSessionRootHash root_hash,
|
||||
td::BufferSlice data, td::BufferSlice collated_data,
|
||||
td::Promise<validatorsession::ValidatorSession::CandidateDecision> promise) override {
|
||||
auto P = td::PromiseCreator::lambda([id = id_, promise = std::move(promise)](td::Result<td::uint32> R) mutable {
|
||||
if (R.is_ok()) {
|
||||
promise.set_value(validatorsession::ValidatorSession::CandidateDecision{R.move_as_ok()});
|
||||
} else {
|
||||
auto S = R.move_as_error();
|
||||
promise.set_value(
|
||||
validatorsession::ValidatorSession::CandidateDecision{S.message().c_str(), td::BufferSlice()});
|
||||
}
|
||||
});
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<std::pair<td::uint32, bool>> R) mutable {
|
||||
if (R.is_ok()) {
|
||||
validatorsession::ValidatorSession::CandidateDecision decision(R.ok().first);
|
||||
decision.set_is_cached(R.ok().second);
|
||||
promise.set_value(std::move(decision));
|
||||
} else {
|
||||
auto S = R.move_as_error();
|
||||
promise.set_value(
|
||||
validatorsession::ValidatorSession::CandidateDecision{S.message().c_str(), td::BufferSlice()});
|
||||
}
|
||||
});
|
||||
|
||||
BlockCandidate candidate{Ed25519_PublicKey{source.ed25519_value().raw()},
|
||||
BlockIdExt{0, 0, 0, root_hash, sha256_bits256(data.as_slice())},
|
||||
|
@ -258,7 +266,8 @@ std::unique_ptr<validatorsession::ValidatorSession::Callback> ValidatorGroup::ma
|
|||
td::actor::send_closure(id_, &ValidatorGroup::validate_block_candidate, round, std::move(candidate),
|
||||
std::move(P));
|
||||
}
|
||||
void on_generate_slot(td::uint32 round, td::Promise<BlockCandidate> promise) override {
|
||||
void on_generate_slot(td::uint32 round,
|
||||
td::Promise<validatorsession::ValidatorSession::GeneratedCandidate> promise) override {
|
||||
td::actor::send_closure(id_, &ValidatorGroup::generate_block_candidate, round, std::move(promise));
|
||||
}
|
||||
void on_block_committed(td::uint32 round, PublicKey source, validatorsession::ValidatorSessionRootHash root_hash,
|
||||
|
@ -543,7 +552,7 @@ void ValidatorGroup::receive_collate_query_response(td::uint32 round_id, td::Buf
|
|||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[candidate = candidate.clone(), promise = std::move(promise)](td::Result<UnixTime> R) mutable {
|
||||
[candidate = candidate.clone(), promise = std::move(promise)](td::Result<std::pair<UnixTime, bool>> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error_prefix("validate received block error: "));
|
||||
return;
|
||||
|
|
|
@ -34,8 +34,10 @@ class ValidatorManager;
|
|||
|
||||
class ValidatorGroup : public td::actor::Actor {
|
||||
public:
|
||||
void generate_block_candidate(td::uint32 round_id, td::Promise<BlockCandidate> promise);
|
||||
void validate_block_candidate(td::uint32 round_id, BlockCandidate block, td::Promise<td::uint32> promise);
|
||||
void generate_block_candidate(td::uint32 round_id,
|
||||
td::Promise<validatorsession::ValidatorSession::GeneratedCandidate> promise);
|
||||
void validate_block_candidate(td::uint32 round_id, BlockCandidate block,
|
||||
td::Promise<std::pair<UnixTime, bool>> promise);
|
||||
void accept_block_candidate(td::uint32 round_id, PublicKeyHash src, td::BufferSlice block, RootHash root_hash,
|
||||
FileHash file_hash, std::vector<BlockSignature> signatures,
|
||||
std::vector<BlockSignature> approve_signatures,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue