Skip to content

Commit

Permalink
Merge pull request #1405 from birydrad/accelerator
Browse files Browse the repository at this point in the history
optimistic out-msg-queue broadcast
  • Loading branch information
SpyCheese authored Nov 27, 2024
2 parents 6df6f18 + bf572f9 commit 3dce9d1
Show file tree
Hide file tree
Showing 24 changed files with 623 additions and 126 deletions.
15 changes: 15 additions & 0 deletions tdutils/td/utils/StringBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,19 @@ std::enable_if_t<std::is_arithmetic<T>::value, string> to_string(const T &x) {
return sb.as_cslice().str();
}

template <class SB>
struct LambdaPrintHelper {
SB& sb;
};
template <class SB, class F>
SB& operator<<(const LambdaPrintHelper<SB>& helper, F&& f) {
f(helper.sb);
return helper.sb;
}
struct LambdaPrint {};

inline LambdaPrintHelper<td::StringBuilder> operator<<(td::StringBuilder& sb, const LambdaPrint&) {
return LambdaPrintHelper<td::StringBuilder>{sb};
}

} // namespace td
39 changes: 37 additions & 2 deletions tdutils/td/utils/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "td/utils/logging.h"
#include "td/utils/Time.h"

#include <numeric>

namespace td {

Timer::Timer(bool is_paused) : is_paused_(is_paused) {
Expand Down Expand Up @@ -60,12 +62,15 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Timer &timer) {
return string_builder << format::as_time(timer.elapsed());
}

PerfWarningTimer::PerfWarningTimer(string name, double max_duration, std::function<void(double)>&& callback)
PerfWarningTimer::PerfWarningTimer(string name, double max_duration, std::function<void(double)> &&callback)
: name_(std::move(name)), start_at_(Time::now()), max_duration_(max_duration), callback_(std::move(callback)) {
}

PerfWarningTimer::PerfWarningTimer(PerfWarningTimer &&other)
: name_(std::move(other.name_)), start_at_(other.start_at_), max_duration_(other.max_duration_), callback_(std::move(other.callback_)) {
: name_(std::move(other.name_))
, start_at_(other.start_at_)
, max_duration_(other.max_duration_)
, callback_(std::move(other.callback_)) {
other.start_at_ = 0;
}

Expand Down Expand Up @@ -134,4 +139,34 @@ double ThreadCpuTimer::elapsed() const {
return res;
}

PerfLogAction PerfLog::start_action(std::string name) {
auto i = entries_.size();
entries_.push_back({.name = std::move(name), .begin = td::Timestamp::now().at()});
return PerfLogAction{i, std::unique_ptr<PerfLog, EmptyDeleter>(this)};
}
td::StringBuilder &operator<<(StringBuilder &sb, const PerfLog &log) {
sb << "{";
std::vector<size_t> ids(log.entries_.size());
std::iota(ids.begin(), ids.end(), 0);
std::sort(ids.begin(), ids.end(), [&](auto a, auto b) {
return log.entries_[a].end - log.entries_[a].begin > log.entries_[b].end - log.entries_[b].begin;
});
sb << "{";
for (size_t i = 0; i < log.entries_.size(); i++) {
sb << "\n\t";
auto &entry = log.entries_[ids[i]];
sb << "{" << entry.name << ":" << entry.begin << "->" << entry.end << "(" << entry.end - entry.begin << ")"
<< td::format::cond(entry.status.is_error(), entry.status, "") << "}";
}
sb << "\n}";
return sb;
}

double PerfLog::finish_action(size_t i, td::Status status) {
auto &entry = entries_[i];
CHECK(entry.end == 0);
entry.end = td::Timestamp::now().at();
entry.status = std::move(status);
return entry.end - entry.begin;
}
} // namespace td
43 changes: 42 additions & 1 deletion tdutils/td/utils/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "td/utils/StringBuilder.h"
#include "td/utils/Status.h"

#include <functional>

Expand Down Expand Up @@ -46,7 +47,7 @@ class Timer {

class PerfWarningTimer {
public:
explicit PerfWarningTimer(string name, double max_duration = 0.1, std::function<void(double)>&& callback = {});
explicit PerfWarningTimer(string name, double max_duration = 0.1, std::function<void(double)> &&callback = {});
PerfWarningTimer(const PerfWarningTimer &) = delete;
PerfWarningTimer &operator=(const PerfWarningTimer &) = delete;
PerfWarningTimer(PerfWarningTimer &&other);
Expand Down Expand Up @@ -80,4 +81,44 @@ class ThreadCpuTimer {
bool is_paused_{false};
};

class PerfLog;
struct EmptyDeleter {
template <class T>
void operator()(T *) {
}
};
class PerfLogAction {
public:
template <class T>
double finish(const T &result);
size_t i_{0};
std::unique_ptr<PerfLog, EmptyDeleter> perf_log_;
};

class PerfLog {
public:
PerfLogAction start_action(std::string name);
friend td::StringBuilder &operator<<(td::StringBuilder &sb, const PerfLog &log);

private:
struct Entry {
std::string name;
double begin{};
double end{};
td::Status status;
};
std::vector<Entry> entries_;
friend class PerfLogAction;

double finish_action(size_t i, td::Status status);
};
template <class T>
double PerfLogAction::finish(const T &result) {
if (result.is_ok()) {
return perf_log_->finish_action(i_, td::Status::OK());
} else {
return perf_log_->finish_action(i_, result.error().clone());
}
}

} // namespace td
10 changes: 7 additions & 3 deletions tdutils/td/utils/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

#define LOG(level) LOG_IMPL(level, level, true, ::td::Slice())
#define LOG_IF(level, condition) LOG_IMPL(level, level, condition, #condition)
#define FLOG(level) LOG_IMPL(level, level, true, ::td::Slice()) << td::LambdaPrint{} << [&](auto &sb)

#define VLOG(level) LOG_IMPL(DEBUG, level, true, TD_DEFINE_STR(level))
#define VLOG_IF(level, condition) LOG_IMPL(DEBUG, level, condition, TD_DEFINE_STR(level) " " #condition)
Expand All @@ -95,13 +96,13 @@ inline bool no_return_func() {
#define DUMMY_LOG_CHECK(condition) LOG_IF(NEVER, !(condition))

#ifdef TD_DEBUG
#if TD_MSVC
#if TD_MSVC
#define LOG_CHECK(condition) \
__analysis_assume(!!(condition)); \
LOG_IMPL(FATAL, FATAL, !(condition), #condition)
#else
#else
#define LOG_CHECK(condition) LOG_IMPL(FATAL, FATAL, !(condition) && no_return_func(), #condition)
#endif
#endif
#else
#define LOG_CHECK DUMMY_LOG_CHECK
#endif
Expand Down Expand Up @@ -263,6 +264,9 @@ class Logger {
sb_ << other;
return *this;
}
LambdaPrintHelper<td::Logger> operator<<(const LambdaPrint &) {
return LambdaPrintHelper<td::Logger>{*this};
}

MutableCSlice as_cslice() {
return sb_.as_cslice();
Expand Down
6 changes: 5 additions & 1 deletion tl/generate/scheme/ton_api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ tonNode.newBlockCandidateBroadcast id:tonNode.blockIdExt catchain_seqno:int vali
tonNode.newBlockCandidateBroadcastCompressed id:tonNode.blockIdExt catchain_seqno:int validator_set_hash:int
collator_signature:tonNode.blockSignature flags:# compressed:bytes = tonNode.Broadcast;

// optimistic broadcast of response to tonNode.getOutMsgQueueProof with dst_shard, block and limits arguments
tonNode.outMsgQueueProofBroadcast dst_shard:tonNode.shardId block:tonNode.blockIdExt
limits:ImportedMsgQueueLimits proof:tonNode.OutMsgQueueProof = tonNode.Broadcast;

tonNode.shardPublicOverlayId workchain:int shard:long zero_state_file_hash:int256 = tonNode.ShardPublicOverlayId;

tonNode.privateBlockOverlayId zero_state_file_hash:int256 nodes:(vector int256) = tonNode.PrivateBlockOverlayId;
Expand Down Expand Up @@ -924,7 +928,7 @@ validatorSession.endValidatorGroupStats session_id:int256 timestamp:double

---functions---
collatorNode.generateBlock shard:tonNode.shardId cc_seqno:int prev_blocks:(vector tonNode.blockIdExt)
creator:int256 = collatorNode.Candidate;
creator:int256 round:int first_block_round:int priority:int = collatorNode.Candidate;
collatorNode.ping flags:# = collatorNode.Pong;

---types---
Expand Down
Binary file modified tl/generate/scheme/ton_api.tlo
Binary file not shown.
49 changes: 46 additions & 3 deletions ton/ton-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,26 +425,69 @@ struct Ed25519_PublicKey {
};

// represents (the contents of) a block

struct OutMsgQueueProofBroadcast : public td::CntObject {
OutMsgQueueProofBroadcast(ShardIdFull dst_shard, BlockIdExt block_id, td::int32 max_bytes, td::int32 max_msgs,
td::BufferSlice queue_proofs, td::BufferSlice block_state_proofs,
std::vector<std::int32_t> msg_counts)
: dst_shard(std::move(dst_shard))
, block_id(block_id)
, max_bytes(max_bytes)
, max_msgs(max_msgs)
, queue_proofs(std::move(queue_proofs))
, block_state_proofs(std::move(block_state_proofs))
, msg_counts(std::move(msg_counts)) {
}
ShardIdFull dst_shard;
BlockIdExt block_id;

// importedMsgQueueLimits
td::uint32 max_bytes;
td::uint32 max_msgs;

// outMsgQueueProof
td::BufferSlice queue_proofs;
td::BufferSlice block_state_proofs;
std::vector<std::int32_t> msg_counts;

virtual OutMsgQueueProofBroadcast* make_copy() const {
return new OutMsgQueueProofBroadcast(dst_shard, block_id, max_bytes, max_msgs, queue_proofs.clone(),
block_state_proofs.clone(), msg_counts);
}
};

struct BlockCandidate {
BlockCandidate(Ed25519_PublicKey pubkey, BlockIdExt id, FileHash collated_file_hash, td::BufferSlice data,
td::BufferSlice collated_data)
td::BufferSlice collated_data,
std::vector<td::Ref<OutMsgQueueProofBroadcast>> out_msg_queue_broadcasts = {})
: pubkey(pubkey)
, id(id)
, collated_file_hash(collated_file_hash)
, data(std::move(data))
, collated_data(std::move(collated_data)) {
, collated_data(std::move(collated_data))
, out_msg_queue_proof_broadcasts(std::move(out_msg_queue_broadcasts)) {
}
Ed25519_PublicKey pubkey;
BlockIdExt id;
FileHash collated_file_hash;
td::BufferSlice data;
td::BufferSlice collated_data;

// used only locally
std::vector<td::Ref<OutMsgQueueProofBroadcast>> out_msg_queue_proof_broadcasts;

BlockCandidate clone() const {
return BlockCandidate{pubkey, id, collated_file_hash, data.clone(), collated_data.clone()};
return BlockCandidate{
pubkey, id, collated_file_hash, data.clone(), collated_data.clone(), out_msg_queue_proof_broadcasts};
}
};

struct BlockCandidatePriority {
td::uint32 round{};
td::uint32 first_block_round{};
td::int32 priority{};
};

struct ValidatorDescr {
/* ton::validator::ValidatorFullId */ Ed25519_PublicKey key;
ValidatorWeight weight;
Expand Down
11 changes: 7 additions & 4 deletions validator/collation-manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void CollationManager::start_up() {

void CollationManager::collate_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, Ed25519_PublicKey creator,
BlockCandidatePriority priority,
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
td::CancellationToken cancellation_token, td::Promise<BlockCandidate> promise) {
if (shard.is_masterchain()) {
Expand All @@ -41,12 +42,13 @@ void CollationManager::collate_block(ShardIdFull shard, BlockIdExt min_mastercha
std::move(cancellation_token), 0);
return;
}
collate_shard_block(shard, min_masterchain_block_id, std::move(prev), creator, std::move(validator_set),
collate_shard_block(shard, min_masterchain_block_id, std::move(prev), creator, priority, std::move(validator_set),
max_answer_size, std::move(cancellation_token), std::move(promise), td::Timestamp::in(10.0));
}

void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id,
std::vector<BlockIdExt> prev, Ed25519_PublicKey creator,
BlockCandidatePriority priority,
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
td::CancellationToken cancellation_token,
td::Promise<BlockCandidate> promise, td::Timestamp timeout) {
Expand Down Expand Up @@ -133,8 +135,8 @@ void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_mas
delay_action(
[=, promise = std::move(promise)]() mutable {
td::actor::send_closure(SelfId, &CollationManager::collate_shard_block, shard, min_masterchain_block_id, prev,
creator, validator_set, max_answer_size, cancellation_token, std::move(promise),
timeout);
creator, priority, validator_set, max_answer_size, cancellation_token,
std::move(promise), timeout);
},
retry_at);
};
Expand All @@ -145,7 +147,8 @@ void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_mas
}

td::BufferSlice query = create_serialize_tl_object<ton_api::collatorNode_generateBlock>(
create_tl_shard_id(shard), validator_set->get_catchain_seqno(), std::move(prev_blocks), creator.as_bits256());
create_tl_shard_id(shard), validator_set->get_catchain_seqno(), std::move(prev_blocks), creator.as_bits256(),
priority.round, priority.first_block_round, priority.priority);
LOG(INFO) << "sending collate query for " << next_block_id.to_str() << ": send to #" << selected_idx << "("
<< selected_collator << ")";

Expand Down
6 changes: 4 additions & 2 deletions validator/collation-manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class CollationManager : public td::actor::Actor {
void alarm() override;

void collate_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
Ed25519_PublicKey creator, td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
Ed25519_PublicKey creator, BlockCandidatePriority priority,
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
td::CancellationToken cancellation_token, td::Promise<BlockCandidate> promise);

void update_options(td::Ref<ValidatorManagerOptions> opts);
Expand All @@ -52,7 +53,8 @@ class CollationManager : public td::actor::Actor {
td::actor::ActorId<rldp::Rldp> rldp_;

void collate_shard_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
Ed25519_PublicKey creator, td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
Ed25519_PublicKey creator, BlockCandidatePriority priority,
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
td::CancellationToken cancellation_token, td::Promise<BlockCandidate> promise,
td::Timestamp timeout);

Expand Down
Loading

0 comments on commit 3dce9d1

Please sign in to comment.